You want to exchange data with an Arduino by using the serial interfaces of both devices, without using PyFirmata.
Use a level converter or pair of resistors to connect the RXD pin of the Raspberry Pi to the Tx pin of the Arduino, and the TXD pin of the Raspberry Pi to the Rx pin of the Arduino.
To make this recipe, you will need:
• Arduino Uno (see “Modules” on page 381)
• Breadboard and jumper wires (see “Prototyping Equipment” on page 380)
• 270Ω and 470Ω resistors (see “Resistors and Capacitors” on page 380) or a four-way bidirectional level converter (see “Modules” on page 381)
• 10kΩ trimpot (see “Resistors and Capacitors” on page 380)
If you are using the level converter module, then connect the breadboard as shown in Figure 14-14.
If, on the other hand, you are using the pair of resistors, then connect the breadboard as shown in Figure 14-15.
The Arduino Rx input is fine with just 3.3V from the Raspberry Pi TXD pin; however, the 5V coming from the Arduino Tx pin must be dropped to the 3V expected by the Raspberry Pi.
You will need to disable serial port logging and install PySerial by following Recipes 8.7 and 8.8.
The following Python script (ardu_pi_serial.py) will prompt you to enter a command of either l or r. If you enter l, then the built-in Arduino LED will toggle on and off. If, on the other hand, you enter r, the Arduino will read the analog value from its analog input A0 and send back a number between 0 and 1023 as the reading.
Open an editor (nano or IDLE) and paste in the following code. As with all the program examples in this book, you can also download the program from the Code section of http://www.raspberrypicookbook.com, where it is called ardu_pi_serial.py.
import serial ser = serial.Serial(‘/dev/ttyAMA0’, 9600) while True: command = raw_input(“Enter command: l – toggle LED, r – read A0 “) if command == ‘l’ : ser.write(‘l’) elif command == ‘r’ : ser.write(‘r’) print(ser.readline()) |
You also need to upload the following sketch, ArduinoSerial, onto your Arduino Uno. You can paste it into a new sketch window, and it is available with the rest of this book’s programs for download.
#include “SoftwareSerial.h” int ledPin = 13; int analogPin = A0; SoftwareSerial ser(8, 9); // RX, TX boolean ledOn = false; void setup() { ser.begin(9600); pinMode(ledPin, OUTPUT); } void loop() |
Run the program and test that the built-in L LED on the Arduino toggles on and off using the l command. Then try setting the trimpot to different positions and take analog readings by sending the r command.
$ sudo python ardu_pi_serial.py Enter command: l – toggle LED, r – read A0 l Enter command: l – toggle LED, r – read A0 l Enter command: l – toggle LED, r – read A0 r 0 Enter command: l – toggle LED, r – read A0 r 540 Enter command: l – toggle LED, r – read A0 r 1023 |
Discussion
The code in the Python program uses the PySerial library to open a connection onto the serial port. The main program loop then repeatedly asks for commands and processes them, in both cases by writing the single character command to the serial port.
In the case of the r command, it also reads a line from the serial connection and then prints it.
Note that, despite appearances, here the result of serial.readline is a string. If you need to convert this into a number, you can use the function int to convert it. For example:
line = ser.readline() value = int(line) |
The Arduino sketch is a little more complicated. The example sketch provided can easily be modified to add more inputs or outputs and respond to more commands.
This sketch does not use the Arduino’s hardware serial port, as this is generally used by its USB connection. Instead, an Arduino library called SoftwareSerial is used to allow pins 8 and 9 to be used as Rx and Tx, respectively.
As with all Arduino sketches, there must be a setup function that is called one time when the Arduino starts up and a loop function that is called repeatedly.
The setup function begins serial communication and sets the pin for the built-in LED (on Arduino pin 13) to be an output.
The loop function first checks to see if any serial messages have arrived by using the ser.available function call. If there is a message to process, it reads the character, and the following if clauses call the appropriate helper function to process the command.
See Also
For more information about the SoftwareSerial library, see http://arduino.cc/en/Reference/SoftwareSerial.
The alternative to writing your own custom code for communication is to use PyFirmata (Recipe 14.3).
As well as communicating over serial, you can communicate with the Arduino using I2C (Recipe 14.11).
Table A-8. Modules | |
Raspberry Pi camera module | Adafruit: 1367, MCM: 28-17733, CPC: SC13023 |
Arduino Uno | SparkFun: DEV-11021, Adafruit: 50, CPC: A000066 |
Level converter, four-way | SparkFun: BOB-11978, Adafruit: 757 |
Level converter eight-way | Adafruit: 395 |
LiPo boost converter/charger | SparkFun: PRT-11231 |
PowerSwitch tail | Adafruit: 268 |
16-channel servo controller | Adafruit: 815 |
Motor driver 1A dual | SparkFun: ROB-09457 |
RaspiRobot board | Sparkfun: KIT-11561, raspirobot.com |
PiFace digital interface board | MCM: 83-14472, CPC: SC12827 |
Humble Pi | MCM: 83-14637, CPC: SC12871 |
Pi Plate | Adafruit: 801 |
Gertboard | MCM: 83-14460, CPC: SC12828 |
Breakout board with paddle terminals | MCM: 83-14876, CPC: SC12885 |
PIR motion detector | Adafruit: 189 |
Venus GPS module | SparkFun: GPS-11058 |
Methane sensor | SparkFun: SEN-09404 |
Gas sensor breakout board | SparkFun: BOB-08891 |
ADXL335 triple-axis accelerometer | Adafruit: 163 |
4×7-segment LED with I2C backpack | Adafruit: 878 |
Bicolor LED square-pixel matrix with I2C backpack | Adafruit: 902 |
PiLite interface board | Ciseco, CPC: SC13018 |
aLaMode interface board | Makershed: MKWY1, Seeedstudio: ARD10251P |
Freetronics Arduino LCD shield | www.freetronics.com |
RTC module | Adafruit: 264 |
16 x 2 HD44780 compatible LCD module | SparkFun: LCD-00255, Adafruit: 181 |
Table A-3. Prototyping equipment | |
Description | Suppliers |
M-M jumper wires | SparkFun: PRT-08431, Adafruit: 759 |
M-F jumper wires | SparkFun: PRT-09140, Adafruit: 825 |
F-F jumper wires | SparkFun: PRT-08430, Adafruit: 794 |
Half-sized breadboard | SparkFun: PRT-09567 Adafruit: 64 |
Pi Cobbler | Adafruit: 1105 |
Table A-4. Resistors and capacitors | |
270Ω 0.25W resistor | Mouser: 293-270-RC |
470Ω 0.25W resistor | Mouser: 293-470-RC |
1kΩ 0.25W resistor | Mouser: 293-1k-RC |
3.3kΩ 0.25W resistor | Mouser: 293-3.3k-RC |
4.7kΩ 0.25W resistor | Mouser: 293-4.7k-RC |
10 kΩ trimpot | Adafruit: 356, SparkFun: COM-09806, Mouser: 652-3362F-1-103LF |
Photoresistor | Adafruit: 161, SparkFun: SEN-09088 |
220nF capacitor | MCM: 31-0610, Mouser: 80-C322C224M5U5HA |