In complex projects, you will need to connect multiple microcontrollers with each other. This connection can be made with different protocols and libraries. This article explores available options and presents easy to follow code examples.
Specifically, you will learn how to connect an Arduino Uno to a Raspberry Pi using a USB connection.
This article originally appeared at my blog admantium.com.
Arduino
We start with a simple example. On starting, the Arduino will open a serial connection and blink an LED to show that it is alive.
#include <Arduino.h>
#define LED 4
void setup()
{
Serial.begin(9600);
pinMode(LED, OUTPUT);
}
void blink() {
digitalWrite(LED, HIGH);
delay(200);
digitalWrite(LED, LOW);
}
void loop()
{
delay(1000);
blink();
}
Then, inside the loop()
function, we will use the Serial
object to check if some data has been provided. If yes, the data will be read byte by byte, and printed to the serial console as well.
void checkAndProcessSerialData() {
if (Serial.available()) {
char ch = Serial.read();
if (ch > 0) {
Serial.print(ch);
}
}
}
// ...
void loop()
{
delay(1000);
blink();
checkAndProcessSerialData()
}
The Arduino Source Code is finished - now let’s take a look the Raspberry Pi.
Raspberry Pi
The code that runs on the Raspberry Pi needs to listen for incoming data over the serial connection. Several libraries exist, we will choose the Python library pyserial.
First of all, we install the library with the pip3
tool.
> pip3 install pyserial
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Collecting pyserial
Downloading https://files.pythonhosted.org/packages/07/bc/587a445451b253b285629263eb51c2d8e9bcea4fc97826266d186f96f558/pyserial-3.5-py2.py3-none-any.whl (90kB)
100% |████████████████████████████████| 92kB 1.3MB/s
Installing collected packages: pyserial
Successfully installed pyserial-3.5
Using this library, we create a Python script - see the following code listing.
from serial import Serial
from time import sleep
arduino = serial.Serial('/dev/ttyACM0', 9600, timeout=1)
while True:
arduino.write(("Hello!").encode())
print(str(arduino.readline()))
sleep(2)
Let’s go through this script with mire detail:
- Line 1 & 2: Import the required libraries, the just now installed
serial
and the core librarytime
- Line 4: Using the imports
Serial
class, we create an instance that connects to the attached Arduino - check whether its/dev/ttyACM0
or/dev/ttyUSB0
- sets the baud rate, and a timeout value to control when the connection should be recreated again. - Line 6: Similar to an Arduino code, we start a loop that never terminates...
- Line 7: We send the message "Hello" to the Serial connection and
encode
it so that the characters are send as bytes - Line 8: We read from the serial connection and print it to the console
- Line 9: Wait for 2 seconds.
From the console, we can simply start the program and then see the output:
python3 01_write_serial.py
b''
b'Echo\r\n'
b'Echo\r\n'
b'Echo\r\n'
Reading Serial Data Correctly
However, the output shows a flaw: It prints the byte representation instead of the strings. Therefore, we need to typecast the bytes to a string, and also remove carriage returns and newline symbols. Change the print
statement to this line:
print(str(arduino.readline(), 'utf-8').rstrip('\r\n'))
And now the output is:
python3 01_write_serial.py
Echo
Echo
Echo
Conclusion
In this short article, I showed how to connect an Arduino to a Raspberry Pi via USB, and read data via USB-To-Serial connection. The Python3 library pyserial
is very easy to setup and use. This is just the first method to exchange information between two microcontrollers. In the next article, we will explore how to setup the connection by using the I2C protocol.