Skip to content

Connecting Microcontrollers: Direct Serial Connection

By Sebastian Günther

Posted in Microcontrollers, Arduino, Raspberry_pi_sbc, Uart, C++, Python

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.

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('/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 library time
  • 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.