Let us RAP…

Raspberry pi controls Arduino using Python (RAP)

The Raspberry Pi is sometimes seen as competition to micro controllers like the Arduino. However the Raspberry Pi has a different sweet spot and can easily be combined with an Arduino to accomplish a wider range of tasks than otherwise possible. For example the missing Analog inputs.

arduino

Setting up your Arduino for Firmata

Firmata control of the Arduino requires loading an Arduino with the special Firmata sketch. You can download the Arduino software from the Arduino website. After opening the Arduino IDE, follow these steps to install Firmata on your Arduino:
1. Click File->Examples->Firmata->StandardFirmata
2. From the Tools->Board menu, select the type of Arduino you are using.
3. From the Tools->Serial Port menu, choose the USB port to which your Arduino is connected.
4. Click the upload button (it looks like a right arrow, just next to the checkmark) and wait for your sketch to upload. A message in the bottom black window will indicate success or failure
5. Once the Firmata sketch is loaded on your Arduino, you can test it out with the Firmata Test Program. (http://www.firmata.org/wiki/Main_Page)

Controlling your Arduino from Python

Next, your Raspberry Pi must be setup with the python firmata libraries. Run the following commands:

sudo apt-get install python-pip python-serial
sudo pip install pyfirmata

Use a USB cable to connect the Arduino with the Raspberry Pi (remember to use the big USB Standard A connector and not the smaller Micro B power connector). You can now find the USB name of the Arduino by running ‘ls -lrt /dev/tty*’. On my Raspberry Pi, it was listed as /dev/ttyUSB0. Remember this value for later.
Connecting to an Arduino
To control an Arduino from a Python script on your Raspberry Pi, you must first import the Arduino and util classes from the pyfirmata module. Then, create an object using the USB address you found in the previous step

>>> from pyfirmata import Arduino, util
>>> board = Arduino('/dev/ttyUSB0')

Controlling Arduino GPIO
The Arduino’s digital input and output ports can be controlled using the board.digital[] list. Calling write() can set the pin values high or low (1 and 0 respectively). The read() method returns the current value of the pin.

>>> board.digital[2].write(1)
>>> print board.digital[2].read()

If you’d like to use a pin repeatedly, its cumbersome to keep referring to it as board.digital[2]. Instead, you can get a reference to a pin with the board.get_pin() function. To this function, you pass a string of the format “[a|d]:[pin#]:[i:o:p:s]”. It is split by colons into three sections. The first section determines if the pin will be used in analog or digital mode. The second section is the number of the pin you would like to use. The third section selects the pin mode between input, output, pwm, and servo. The returned pin can be assigned to a variable and then later used to call read() and write() methods.

>>> pin2 = board.getpin('d:2:o')
>>> pin2.write(1)

Controlling Analog Pins
To read the value on an analog pin, you have to first turn on the analog value reporting on that pin. However, this continuously sends the analog value from the Arduino to the Raspberry Pi. If not continuously read, this will clog up the serial connection and prevent the rest of your script from running properly. To read the values, it is helpful to use an iterator thread.

>>> it = util.Iterator(board)
>>> it.start()
>>> board.analog[0].enable_reporting()
>>> board.analog[0].read()
>>> it.start()

To turn off the reporting of analog values, call disable_reporting() on the pin object

Sample code

Read LM35 temperature  from AI0 pin and store in CSV

# Python27
import csv
import pyfirmata
import time
from time import sleep


port = '/dev/cu.usbmodemfa1331' #'COM3' for Windows
board = pyfirmata.Arduino(port)
#pin =[0]
it = pyfirmata.util.Iterator(board)
it.start()
a0 = board.get_pin('a:0:i')
#a0.enable_reporting()
with open('SensorDataStore.csv', 'w') as f:
    w = csv.writer(f)
    w.writerow(["Number","Temperature"])
    i = 0
    while i < 25:
        Temperature = a0.read()
        if (Temperature != None):
            Temperature = Temperature*100 # to read value in decimal
        sleep(1)
        i += 1
        row = [i, Temperature]
        w.writerow(row)
        print (Temperature)
    print ("Done. CSV file is ready!")
board.exit()

 

2 comments

  1. Very helpful. I’m working on an autonomous quadcopter but the Pi’s PWM isn’t stable enough with everything else going on so I was thinking of using a Nano to handle the ESC’s. This should make the comms a lot easier.

    Like

Leave a reply to nanda.dash Cancel reply