I have Arduino IDE installed on my laptop and I'd like to program a remote Arduino (Uno) that is connected to a remote machine in the same network, say, for instance, a Raspberry Pi (to which the Arduino Uno would be plugged with the USB cable) connected to my wireless network. What would I need to set up to do that?

Note: I don't mean to use the Arduino as a SSH client. What I'd like to do is some kind of tunnelling, preferably SSH, between Arduino IDE on my laptop and the Raspberry PI, to which the Arduino board is connected with the USB cable.

Ideally what would happen when I press the Upload button is that the firmware, compiled locally would then be sent to the remote Arduino through the tunnel. Also I would use the serial monitor to remotely connect to the /dev/ttyACM0 device node on the remote Pi.

  • 1
    Can you install avrdude on the rpi? – thrig Jan 30 '17 at 21:21
  • You might look at usbip to make the remote usb device appear local to your laptop. – meuh Jan 31 '17 at 17:16
  • @thrig Didn't mention it but sure, I can install avrdude on it. – user86969 Feb 1 '17 at 17:20
  • @meuh I didn't know about usbip, definitely worth taking a look! Thanks. – user86969 Feb 1 '17 at 17:21

Lacking a usb device proxy (usbip as of Feb 2016 does not appear to be very portable) another method is to install avrdude on the Arduino-connected system (REMOTE). If this is possible, then the Arduino IDE running system (CLIENT) can be instructed to call a program that connects to avrdude on REMOTE. Downsides: requires fiddling around in the Arduino IDE configuration files, probably fragile, will require additional work to support things like arduinoOTA and so on...

CLIENT (Arduino IDE) -> ssh -> REMOTE (avrdude) -> usb -> arduino

The Arduino IDE should contain programmers.txt and platform.txt configuration files (located for example under Arduino.app/Contents/Java/hardware/arduino/avr on the mac version). What we need in these files is a new programmer that will make a connection to REMOTE and pass along the data to upload, and then on REMOTE to issue the actual avrdude programmer command using the data passed from the CLIENT system.

CLIENT programmer

In Java/hardware/arduino/avr/programmers.txt add something like

avrrelay.name=AVR RELAY

More complicatedly, in Java/hardware/arduino/avr/platform.txt duplicate all the tools.avrdude. containing lines and adjust these to instead be named tools.avrrelay. and where necessary instead call avrrelay-client (most of these lines are not necessary but it's probably easier to sub all of them than to figure out which are necessary):

... many more of these not shown, e.g. the verbose one ...
tools.avrrelay.upload.pattern="{cmd.path}" "{build.path}/{build.project_name}.hex"
tools.avrrelay.program.pattern="{cmd.path}" "{build.path}/{build.project_name}.hex"

Then in the Java/hardware/tools/avr/bin directory (which should be identical to the runtime.tools.avrdude.path config option) create avrrelay-client and make it executable:

# send the only argument (which should be the *.hex file) to avrrelay-remote
# this will need to use public key auth, or expect to automatically fill
# in any password promptes
ssh theremotehost avrrelay-remote < "$1"

REMOTE script

The Arduino IDE has a preference option to show verbose output during the upload, which will reveal the command that is run.

/Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/avrdude \
-C/Applications/Arduino.app/Contents/Java/hardware/tools/avr/etc/avrdude.conf \
-v -patmega328p -cstk500v2 -Pusb \

This command can be copied and adapted for the code on REMOTE, though avrdude(1) indicates that a filename must be specified, so the copied data will need to be placed in a tmp file, and that fed to avrdude; this is the avrrelay-remote program called by the CLIENT; it will need to be chmod +x and called by full path or located in a SSH-available PATH directory.

FLASH=`mktemp /tmp/avrrelay.XXXXXXXXXX` || exit 1
# assume data passed via standard input
cat > "$FLASH"
# these flags will vary depending on programmer, etc
avrdude -C /path/to/avrdude.conf -v -patmega328p -cstk500v2 -Pusb \

In theory, restart the Arduino IDE and try using the new "AVR RELAY" programmer. Use your mad debugging skills to figure out where it breaks down, repeat.

remote serial monitor

For the serial monitor to work remotely, a likely option would be to forward that via socat:

Unbuffered socat command to connect serial ports in remote machines and log the data

  • Thanks a lot for this detailed procedure. I'll test it and report my findings. – user86969 Feb 4 '17 at 12:08

If the underlying goal is to program the Arduino without having to disconnect it from a pre-existing USB connection (e.g. perhaps its a node on a ROS system), but you are physically close enough to it to run a cable, you could just use an in-system programmer (I use an Olimex AVI-ISP-MK2) on the ICSP port.

In the Arduino IDE it's Sketch > Upload Using Programmer, or Ctrl+Shift+U. It's even easier doing it this way than over USB because the /dev assignment for the USB port that the ISP's connected to never needs to be set.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy