<jupyter_start><jupyter_text>How to connect to an Arduino board for extended IO The Raspberry Pi does not have analogue inputs. We can use an Arduino board to add analogue readings to the Raspberry Pi. The Arduino needs to run standard **Firmata** firmware. You find the Firmata sketch in the Arduino IDE under *File -> Examples -> Firmata -> StandardFirmata*. Just upload the sketch to the Arduino and connect it to your Raspberry Pi via USB cable.Firmata let's you talk to the Arduino board using serial communication over the USB cable. We use the Python module **pyFirmata2** manage this serial communication.Connect an LED in series with a 330 Ohm resistor on the Arduino's pin 9 and a potentiometer on analogue pin A0.![](resources/rpi_arduino_Steckplatine.png)  Initialization<jupyter_code>from time import sleep
from pyfirmata2 import Arduino

# init Arduino connection
board = Arduino(Arduino.AUTODETECT) 
print(board)

# turn on sampling, default sampling interval is 19ms
# change sampling interval by providing the new value
# a input parameter in ms (50ms here). Minimum is 10ms
# Analogue values are sampled continuously and sent to
# your Raspberry Pi. Watch the TX (transmit) LED on the 
# Arduino blink with different rates for different sampling
# interval values
board.samplingOn(50)

# get handles on pins: watch the pin patterns 'X:Y:Z'
# X must be 'a' for analogue or 'd' for digital pin
# Y is the decimal pin number
# Z must be 'i' for input or 'o' for output 
#   (there is also an option PWM, please refer to the pyFirmata2 API)
pinA0 = board.get_pin('a:0:i')   # analogue pin A0
pin9 = board.get_pin('d:9:o')    # digital pin 9
pin13 = board.get_pin('d:13:o')  # digital pin 13, also connected to an on-board LED<jupyter_output>Arduino /dev/ttyACM0 on /dev/ttyACM0<jupyter_text>Digital write<jupyter_code># blink LEDs 10 times
for i in range(10):

    pin9.write(1)
    pin13.write(0)
    sleep(0.2)
    
    pin9.write(0)
    pin13.write(1)
    sleep(0.2)<jupyter_output><empty_output><jupyter_text>Analogue read<jupyter_code># read analogue value on pin A0, returns value from 0.0 to 1.0
# In fact, just returns the last value from automatic sampling 
# (see the comment above on samplingOn())
val = pinA0.read()

print(val)<jupyter_output>0.4252<jupyter_text>Clean up<jupyter_code># close connection to arduino
board.exit()<jupyter_output><empty_output><jupyter_text>Video scrubbingUse a potentiometer at analogue pin A0 to select the displayed frame.<jupyter_code>import cv2
import numpy as np
from pyfirmata2 import Arduino

# init Arduino connection
board = Arduino(Arduino.AUTODETECT) 
print(board)
board.samplingOn(20)
pinA0 = board.get_pin('a:0:i')   # analogue pin A0

 
# Create a VideoCapture object and read from input file
# If the input is the camera, pass 0 instead of the video file name
cap = cv2.VideoCapture('resources/vid.mp4')

# if video init fails, clean up and exit
if not cap.isOpened():
    print("Error: Could not open video.")
    board.exit()
    exit()
    
    
# create fullscreen window for display
window_name = "mywindow"
cv2.namedWindow(window_name, cv2.WND_PROP_FULLSCREEN)
cv2.setWindowProperty(window_name, cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
  
# get the number of frames of the video
numFrames = cap.get(cv2.CAP_PROP_FRAME_COUNT)
print("number of frames: {}".format(numFrames))

frameIdx = 0  # frame index
 
# run until Q is pressed
while(True):
 
    # Exit when key Q is pressed on keyboard (wait for 5ms on key press)
    if cv2.waitKey(20) & 0xFF == ord('q'):
        break
    
    # read analogue value from Arduino's pin A0
    val = pinA0.read()
    
    # compute new frame index
    frameIdxNew = int((val-0.0001)*numFrames)
    
    # if frame idx has changed, display the new frame
    if frameIdx != frameIdxNew:

        # change frameIdx variable
        frameIdx = frameIdxNew
        print("selected frame: {}".format(frameIdx))

        # set the frame idx of the VideoCapture object to read
        cap.set(cv2.CAP_PROP_POS_FRAMES, frameIdx)

        # read the frame at frameIdx
        ret, frame = cap.read()

        if ret == True:

            # display frame
            cv2.imshow(window_name,frame)
 

 
# release the video capture object and quit connection to arduino board
cv2.destroyAllWindows()
cap.release()
board.exit()<jupyter_output>Arduino /dev/ttyACM0 on /dev/ttyACM0
number of frames: 43.0
selected frame: 1
selected frame: 6
selected frame: 9
selected frame: 11
selected frame: 14
selected frame: 19
selected frame: 24
selected frame: 27
selected frame: 26
selected frame: 22
selected frame: 21
selected frame: 17
selected frame: 8
selected frame: 5
selected frame: 2
selected frame: 0
selected frame: 1
selected frame: 8
selected frame: 13
selected frame: 19
selected frame: 22
selected frame: 27
selected frame: 32
selected frame: 35
selected frame: 39
selected frame: 42
selected frame: 41
selected frame: 36
selected frame: 32
selected frame: 28
selected frame: 27
selected frame: 26
selected frame: 24
selected frame: 25
selected frame: 28
selected frame: 31
selected frame: 33
selected frame: 35
selected frame: 37
selected frame: 39
selected frame: 41
selected frame: 42
selected frame: 41
selected frame: 33
selected frame: 27
selected frame: 24
selected frame: 22
selected frame: 21
selected frame: 18
selected frame: 13[...]
{'fraction_non_alphanumeric': 0.07728206085495613, 'fraction_numerical': 0.03509426918051148, 'mean_word_length': 4.132183908045977, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '149196', 'license': 'BSD-2-Clause', 'n_tokens_mistral': 1836, 'n_tokens_neox': 1637, 'n_words': 673, 'path': '04_connect_to_arduino_for_extended_IO.ipynb', 'repo_name': '0may/RaspiHowtos', 'size': '5357'}