This page describes an experiment in using PyMata Express to communicate (using [Firmata]) between a [Raspberry Pi] and an [Arduino] microcontroller using a __serial connection__. To see how to intercommunicate over I2C, see [Raspberry Pi to Arduino over I2C|RaspberryPiToArduinoOverI2C]. !! Installing PyMata Express on Linux/Raspberry Pi To install Pymata Express on Linux (including Raspberry Pi) and macOS computers, open a terminal window and type: {{{ sudo pip3 install pymata-express }}} !! Installing Firmata Express on an Arduino The [FirmataExpress|https://mryslab.github.io/pymata-express/firmata_express/] page describes how to install it on an Arduino, using the Arduino IDE. In a nutshell, this is not too difficult: # [install the Arduino IDE|https://www.arduino.cc/en/main/software], and set your IDE to the type of Arduino you have from the {{Tools:Board}} menu # using the {{Tools:Manage Libraries...}} command, install "FirmataExpress" and Erick Simoes' "Ultrasonic" libraries # open up the {{File:Examples:FirmataExpress:FirmataExpress}} sketch, and use {{Sketch:Upload}} to upload the FirmataExpress sketch to your Arduino Then your Raspberry Pi can communicate with it using Python scripts, an example of which is shown below. !! Example Code Here is an example demonstrating using a callback to monitor the state changes of a digital input pin. {{{ import asyncio import time import sys from pymata_express import pymata_express """ Setup a pin for digital input and monitor its changes using a callback. """ # Setup a pin for analog input and monitor its changes DIGITAL_PIN = 12 # arduino pin number IDLE_TIME = .001 # number of seconds for idle loop to sleep # Callback data indices # Callback data indices CB_PIN_MODE = 0 CB_PIN = 1 CB_VALUE = 2 CB_TIME = 3 async def the_callback(data): """ A callback function to report data changes. This will print the pin number, its reported value and the date and time when the change occurred :param data: [[pin, current reported value, pin_mode, timestamp] """ date = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(data[[CB_TIME])) print(f'Pin: {data[[CB_PIN]} Value: {data[[CB_VALUE]} Time Stamp: {date}') async def digital_in(my_board, pin): """ This function establishes the pin as a digital input. Any changes on this pin will be reported through the call back function. :param my_board: a pymata_express instance :param pin: Arduino pin number """ # set the pin mode await my_board.set_pin_mode_digital_input(pin, callback=the_callback) while True: try: await asyncio.sleep(IDLE_TIME) except KeyboardInterrupt: await board.shutdown() sys.exit(0) # get the event loop loop = asyncio.get_event_loop() # instantiate pymata_express board = pymata_express.PymataExpress() try: # start the main function loop.run_until_complete(digital_in(board, 12)) except (KeyboardInterrupt, RuntimeError) as e: loop.run_until_complete(board.shutdown()) sys.exit(0) }}} !! References * [Introducing ItsyBitsy|https://learn.adafruit.com/introducing-adafruit-itsybitsy-m4] on Adafruit * [ItsyBitsy M4 Pinout|https://learn.adafruit.com/introducing-adafruit-itsybitsy-m4/pinouts] * [Arduino Uno/Nano/Mega as I2C Slave for an Raspberry Pi|https://forum.arduino.cc/index.php?topic=378528.0] (Arduino forum) ---- [{Tag RaspberryPi Arduino}]