Delving the depths of computing,
hoping not to get eaten by a wumpus

By Timm Murray

Arduino/RaspberryPi--UART (Serial) Communication

2013-10-17


NOTE: This post was moved over from WumpusUAV.com. The Indiegogo campaign was not successful, so I’m copying some key posts from there to over here and shutting the site down.

UART/Serial is an old way of doing things, but also handy because you can do it without complicated wiring. Any USB port will do.

We do need to deal with a bunch of esoteric stuff like “parity bits” and “stop bits”. But it’s a simple matter of ensuring these things are set the same on each side.

Hardware Setup

If you don’t want to use USB, a voltage level converter is required, or else the Raspberry Pi’s 3.3V won’t meet the threshold for the Arduino’s 5V. Here’s an article with the details:

http://blog.oscarliang.net/raspberry-pi-and-arduino-connected-serial-gpio/

Otherwise, just plug the two in.

Arduino

In the sketch, we set the baud rate to 115,200. That’s bits-per-second. That might not sound very fast, but if you’re talking plaintext documents, it’s much, much faster than you can read. For UAV purposes, you wouldn’t transfer camera images over that line for processing, but for sending movement commands of a binary protocol, it’s more than enough.

The loop will then check if there’s anything waiting for us to read, and if so, sends it back.

#define SERIAL_BAUD 115200


void setup()
{
    Serial.begin( SERIAL_BAUD );

    while(! Serial) {
        // Wait for serial port to connect
    }
}

void loop()
{
    char next;

    if( Serial.available() > 0 ) {
        next = Serial.read();
        Serial.print( next );
    }
}

Raspberry Pi

We’ll use the Device::SerialPort module. This sets all the stopbits and such for us for clean communication with Arduino. The loop will wait for us to type something with a newline at the end, send it over the serial port, and then read back the response. There tends to be a slight delay before the string comes back, so we sleep a bit after sending.

Run it with serial_example.pl /dev/ttyUSB0. You probably don’t have anything else plugged in to a Raspberry Pi as a USB serial device, so the Arduino is almost certainly on /dev/ttyUSB0. In case it isn’t, check the output of dmesg.

#!/usr/bin/perl
use v5.14;
use warnings;
use Device::SerialPort;

use constant {
    BAUD     => 115_200,
    PARITY   => 'none',
    DATABITS => 8,
    STOPBITS => 1,
    BYTE_BUF => 255,
};


my $PORT = shift || die "Need serial port\n";


my $tty = Device::SerialPort->new( $PORT )
        or die "Can't open $PORT: $!\n";
$tty->baudrate( BAUD );
$tty->parity( PARITY );
$tty->databits( DATABITS );
$tty->stopbits( STOPBITS );

while( my $line = <> ) {
    $tty->write( $line );
    $tty->write_drain;

    sleep 1; # Wait for data to be processed

    my ($count_in, $string_in) = $tty->read( BYTE_BUF );
    if( $count_in ) {
        print '>' . $string_in;
    }
}


Copyright © 2024 Timm Murray
CC BY-NC

Opinions expressed are solely my own and do not express the views or opinions of my employer.