Programming Arduino from Raspberry Pi Remotely

RoboFoundry
5 min readJan 28, 2024

Recently, I started working on a new robot project and first time I’m using a combination of Raspberry Pi and Arduino together. I have used other micro-controllers like ESP32 and Teensy with RPi before but first time for Arduino. As I was going through the setup I realized that its fairly different setup and if you have Ubuntu Server running on RPi, you really don’t have any UI to work with something like Arduino IDE. So you have to use remote tools to get the same thing accomplished. I have done this a few times with different micro-controllers so I figured it may be useful for someone to have this described and may save some time.

The steps for getting this done are fairly straightforward. Here are some pre-requisites/assumptions that I had in my setup:

  1. Raspberry Pi 4 running Ubuntu of some flavor — I’m running Ubuntu 22.04 server [not desktop]. The RPi is also on same wifi network as I’m remoting from laptop using ssh. The ssh setup is beyond the scope of this article and there are so many good articles on this topic on web, just google if you are interested or I may link some articles in references.
  2. I have Arduino Uno connected to RPi simply using standard USB cable that comes with Arduino Uno.
  3. To run a simple program to prove this works we will run an example program that blinks the LED onboard the Arduino. However, you can do many complex things — for example I’m using Arduino from RPi to control L298N motor driver to control two DC motors.

The basics of the process are exactly same for uploading and testing the code for all micro-controllers.

In terms of software we will installing PlatformIO command line version on the RPi [Linorobot project also uses the same technique] and also some additional Ubuntu packages to talk to Arduino and monitoring serial port.

Step 1 — Update Ubuntu and install additional packages

sudo apt update && sudo apt upgrade
sudo apt install arduino

Step 2 — Install PlatformIO command line

# You may need to install python env manager package if your system doesn't already have it
sudo apt install python3.10-venv

# install platformio command line
curl -fsSL -o get-platformio.py https://raw.githubusercontent.com/platformio/platformio-core-installer/master/get-platformio.py
python3 get-platformio.py

# add to path so you can run pio command from anywhere on RPi
echo "PATH=\"\$PATH:\$HOME/.platformio/penv/bin\"" >> $HOME/.bashrc
source $HOME/.bashrc

# test it by running
pio --help

Last step would be to make sure to install udev rules file for linux for supported boards, follow instructions here.

curl -fsSL https://raw.githubusercontent.com/platformio/platformio-core/develop/platformio/assets/system/99-platformio-udev.rules | sudo tee /etc/udev/rules.d/99-platformio-udev.rules


sudo cp 99-platformio-udev.rules /etc/udev/rules.d/99-platformio-udev.rules

sudo service udev restart

# or

sudo udevadm control --reload-rules
sudo udevadm trigger

sudo usermod -a -G dialout $USER
sudo usermod -a -G plugdev $USER

Step 3 — Install serial port monitor [Optional]

This is an optional step as you can also use the PlatformIO’s built in serial monitor to do the same.

sudo apt install minicom

# you can setup serial speed and other setup by going into minicom setup
# and follow the menus to select appropriate values
# [make sure to select a serial speed that will match the speed used by arduino example code you want to run
minicom -s

# finally you can launch minicom to monitor the port on which arduino is detected when ready using
minicom -D /dev/ttyACM0 [or your port address]

# alternatively, you can simply run pio device monitor like this by specifying port and baudrate for speed
pio device monitor -p /dev/ttyACM0 -b 115200

That’s all that is needed for setup. If you have not connected Arduino Uno with RPi, at this time connect it using USB cable with any USB port on RPi.

Create Example PlatformIO project to test

Here are the steps to create and test the project. First ssh into your RPi that is running Ubuntu server. And follow this step to first create an empty directory and then initialize a new platformIO project for Arduino Uno.

# create an empty directory and change to that directory
mkdir ~/pio_example
cd ~/pio_example

# initialize a new platform io project for uno
pio project init --board uno

In our platformio project initialization command we only specified Uno as a supported board for project but you can add more boards either during project initialization on command line or later by editing platformio.ini file

Add simple blink program main.cpp file to src folder.

The project init command would have created following files and directories:

include  lib  platformio.ini  src  test

Change to src directory and first create an empty main.cpp file using touch command and then add the contents from this example using nano or your choice of editor.

cd src
touch main.cpp

nano main.cpp

# copy past the example code from link above

At this point you are ready to build and upload your blink program to Uno.

# build/compile the program
cd ~/pio_example
pio run

# if no errors then you can just run the next command to upload/flash to Uno
pio run --target upload -e uno

As the upload is happening, you’ll see the upload led flashing on Arduino Uno and at the end of process you’ll see sucess message. Sometimes you might get an error saying device is busy if you had some other program using the Arduino so just unplug and plug it back in and it should work.

And once the upload completes you’ll see the program starts to execute immediately and shows the blinking LED.

Few more things you can do at this time are:

  1. Set the serial monitor speed in platformio.ini file

You can add monitor_speed parameter at the end of your Uno env section in platformio.ini file that looks like this

; Environment for Arduino Uno.
[env:uno]
extends = base_atmelavr, base_build
board = uno
monitor_speed = 57600

2. Start the serial monitor included with platformio

# check the port number at which Arduino Uno is connected to linux
pio device list

# it will output something like this [in my case /dev/ttyACM0 is arduino uno]
/dev/ttyACM0
------------
Hardware ID: USB VID:PID=2341:0043 SER=7503330313435160C161 LOCATION=1-1.1:1.0
Description: ttyACM0

/dev/ttyAMA0
------------
Hardware ID: fe201000.serial
Description: ttyAMA0

# you can then connect to arduino uno serial port [match the baud rate with your arduino code]
pio device monitor -p /dev/ttyACM0 -b 115200

# you can start seeing any debug commands you may have added to your code
# or if your program is waiting for input, you can type the command
# keep in mind this is a very basic serial monitor
# and it does not echo back what you type unlike Arduino IDE serial monitor which does

That’s pretty much it!!! Hope this helps in your future projects when you are trying to interface RPi with any micro-controller. All these steps will work same except for the command line for initializing the platformIO project where you can supply additional list of boards that you can support in project like esp32 or Teensy and so on.

References

PlatformIO installer instructions

https://docs.platformio.org/en/stable/core/installation/methods/installer-script.html#super-quick-macos-linux

Udev Rules file installation steps

https://docs.platformio.org/en/stable/core/installation/udev-rules.html

PlatformIO project initialization steps and example code for Blink

https://docs.platformio.org/en/stable/core/quickstart.html#setting-up-the-project

Serial Monitor

https://docs.platformio.org/en/latest/core/userguide/device/cmd_monitor.html

--

--