Arduinos usually appear as USB serial devices. The current boards use the USB serial driver built into the main microprocessor, but older Arduinos (and clones) used separate third-party USB-serial chips.
To simply receive Serial.print
data on the Raspberry Pi from the Arduino, I use the GNU Screen program as a basic terminal: screen [serial-port] [baud-rate]
(for instance screen /dev/ttyACM0 9600
).
I tested three different Arduinos, and one rather different clone. The newer variants all appeared as /dev/ttyACM0
ports, and the older ones /dev/ttyUSB0
. This is what I found, under Raspbian:
The Raspberry Pi may not provide enough power to drive an Arduino, so you might need external power. For completeness, I also tested a Prolific PL2303, even although it's not on any Arduino I know of. It appeared quite happily as /dev/ttyUSB0
.
For more complex communications with sensors, you might consider Firmata, "a generic protocol for communicating with microcontrollers from software on a host computer". It has implementations for Arduino, and Python libraries to run on the Raspberry Pi side.
Here's a small example using pyFirmata to read an LM35 and change the brightness of an LED:
#!/usr/bin/python
# -*- coding: utf-8 -*-
# simple test of pyfirmata and Arduino; read from an LM35 on A0,
# brighten an LED on D3 using PWM
# scruss, 2012-08-14 - tested on Arduino Uno & Raspberry Pi (Raspbian)
import pyfirmata
# Create a new board, specifying serial port
board = pyfirmata.Arduino('/dev/ttyACM0')
# start an iterator thread so that serial buffer doesn't overflow
it = pyfirmata.util.Iterator(board)
it.start()
# set up pins
pin0=board.get_pin('a:0:i') # A0 Input (LM35)
pin3=board.get_pin('d:3:p') # D3 PWM Output (LED)
# IMPORTANT! discard first reads until A0 gets something valid
while pin0.read() is None:
pass
for i in range(10):
pin3.write(i/10.0) # set D3 to 0, 10%, 20%, ... brightness
print "PWM: %d %% Temperature %.1f °C" % (i * 10, pin0.read() * 5 * 100)
board.pass_time(1) # pause 1 second
pin3.write(0) # turn LED back off
board.exit()
There are some caveats when using pyFirmata:
- Analogue reads and PWM writes are normalized to a 0 .. 1 range, and not the standard Arduino 0 .. 255 and 0 .. 1023.
- You really need to start a separate iterator thread to stop old readings overflowing the serial buffer
- Since the Arduino is read asynchronously, make sure that the pyFirmata connection is fully initialized before reading from ports. Otherwise,
None
values ensue.