Connecting Microcontrollers: Direct Serial Connection
Tags: microcontrollers, raspberrypi, arduino, cpp
Published: 2021-09-20 05:35:20

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](https://admantium.com/blog/micro11_tutorial_usb_serial_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.

```c++
#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.

```c++
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](https://github.com/pyserial/pyserial).

First of all, we install the library with the `pip3` tool.

```bash
> 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.

```python
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 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:

```bash
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:

```python
print(str(arduino.readline(), 'utf-8').rstrip('\r\n'))
```

And now the output is:

```bash
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.