Programming my Arduino over WiFi

Posted on Jan 2, 2012 in Arduino, Electronics, PHP, Programming, UberFridge | 8 comments

My Arduino is embedded in my fridge, so having to take it out every time I want to change something in the software would be very annoying. But luckily the Arduino is plugged into a router, which is running Linux.

I set out to get avrdude running on the router, so that I could upload new firmware to the router and have the router reprogram the Arduino. This article gives a step-by-step guide to set this up.

Compiling avrdude for DD-WRT linux

Edit: You can download the files I compiled on my router here. If you add those to the bin directory on your router, you can probably save yourself the trouble of getting the toolchain working.

To get avrdude running on the router, I first had to compile avrdude for my system. But to be able to do that I first had to install the needed tool chain. This tool chain can be installed through the Optware package manager.

The following commands install the optware-devel package and the buildroot package (which includes gcc). The buildroot package is 39 MB, so it will take a while to download. I had to restart the install multiple times, because the router crashed. The installer continued where it had crashed, so after a few times everything was installed.

ipkg-opt update
ipkg-opt install optware-devel
ipkg-opt install buildroot

DD-WRT sets LD_LIBRARY_PATH in /etc/profile, which can cause a library loading clash.  You have to unset this variable, otherwise running ./configure will fail.  I have added this line to the startup commands of my router and I run it each time before I run avrdude.

unset LD_LIBRARY_PATH

Now that the tool chain is ready, download avrdude:

wget http://download.savannah.gnu.org/releases/avrdude/avrdude-5.11.tar.gz

Unpack avrdude:

gunzip -c avrdude-5.11.tar.gz | tar xf -

And compile and install avrdude:

cd avrdude-5.11
./configure --build=mips-linux
make
make install DESTDIR=/opt

This installed it in /opt/usr/local, so I had to move the files manually afterwards to /opt/bin, /opt/etc and /opt/share.

I got a tip from Justin Meyer that the following commands will install the files in the right directory, so you won’t have to move them.

./configure --build=mips-linux --prefix=/opt
make
make install

I had to edit avrdude.conf manually, because it was empty. This is the file I use:
avrdude.conf

It is a slimmed down version with only the configurations for the Atmega’s used on the Arduino boards.

Running avrdude from the command line

I uploaded a HEX file to the router to try programming the Arduino from an SSH session on the router. The serial port of the arduino is /dev/usb/tts/0. I could program the Aduino using the following command:

avrdude -p m328p -c arduino -b 57600 -P /dev/usb/tts/0 -C /opt/etc/avrdude.conf -U flash:w:Blink.cpp.hex

LED’s started blinking, Hooray!

Programming the Arduino from a web browser

Being able to program the Arduino from an SSH session is a step forward from having to sit next to the fridge, but it is still a bit cumbersome. So the logical next step was to write a small piece of PHP to upload a file to the router and execute avrdude.

The following code snippets let you throw a Hex file on the Arduino from any web browser:

On one of the tabs on my maintenance panel in the UberFridge web interface I have the following div:

screenshot of div to upload hex to arduino

<div id="reprogram-arduino">
	<div id="script-warning" class="ui-widget-content ui-corner-all" style="padding:5px;">
		<p>Verify that script is not running before uploading new firmware!</p>
		<div style="padding: 15px 0;">
			<form action="program_arduino.php" method="post" enctype="multipart/form-data">
				<label for="file">Filename:</label>
				<input type="file" name="file" id="file" />
				<input type="submit" name="Program" value="Program" />
			</form>
		</div>
	</div>
</div>

The form executes program_arduino.php, which runs a shell command that passes the uploaded file to avrdude. The output (stdout and stdrr) are returned to the browser. On success the output looks like this:

avrdude output sent to PHP

The page displayed after succesfully programming the Arduino from the browser

<!DOCTYPE html>
<head>
  &lt;title&gt;<strong>UberFridge</strong> programming arduino!&lt;/title&gt;
&lt;/head&gt;
&lt;body style="font-family: Arial;border: 0 none;"&gt; 
 
&lt;?php
if ($_FILES["file"]["error"] &gt; 0)
  {
  echo "Error: " . $_FILES["file"]["error"] . "&lt;br /&gt;";
  }
else
  {
  echo "Uploaded &lt;b&gt;" . $_FILES["file"]["name"] . "&lt;/b&gt; to the Arduino with avrdude";
  echo " (size: " . ($_FILES["file"]["size"] / 1024) . " Kb)&lt;br /&gt;";
  }
?&gt;
 
&lt;br /&gt;
&lt;h3&gt; avrdude output: &lt;h3&gt;
&lt;?php
$filename = $_FILES["file"]["tmp_name"];
$file = escapeshellcmd($filename);
$output = shell_exec("LD_LIBRARY_PATH=\"\" avrdude -p m328p -c arduino -b 57600 -P /dev/usb/tts/0 -C /opt/etc/avrdude.conf -U flash:w:".trim($file)." 2&gt;&amp;1");
?&gt;
&lt;div style="background-color:black; color:white; border-color:#ADD6FF; border-style:ridge; border-width:5px; padding: 10px 10px"&gt;
&lt;?php
echo "&lt;pre&gt;$output&lt;/pre&gt;";
?&gt;
&lt;/div&gt;
 
&lt;/body&gt;
&lt;/html&gt;

The HEX file is put in a temporary directory by Arduino when you compile. On Windows its in C:\Users\username\AppData\Local\Temp\build1234long_number6789.tmp

8 Comments

  1. Awesome, was looking for a way to do this for my project too.

    Thanks!

  2. Elco,
    My router isn’t seeing my arduino… any ideas? I’ve got it hooked up to a USB-powered four port hub. The memory stick is in one of the ports and the arduino is in another. When I SSH into the router and type dmesg | grep -i usb I get a bunch of stuff… some stating it’s found the hub, and it initializes a “Mass storage device” (the memory stick probably), but nothing for the arduino or assigning it to something I can access later. Thanks for your help,

    Matt

    • Hi Matt,
      It’s been a while since I have installed it myself. Did you install the drivers as instructed in this article?
      http://www.elcojacobs.com/installing-dd-wrt-and-optware-on-the-asus-wl-520gu/
      You could also try OpenWRT. The stability of DD-WRT has been disappointing. When I get my raspberry pi I will get rid of the router altogether.

      This is my dmesg | grep -i usb output:


      usb.c: registered new driver usbdevfs
      usb.c: registered new driver hub
      USB20H fcr: 0x64
      USB20H shim cr: 0x8f7
      USB20H syn01 register : 0xfe00fe
      USB20H syn03 register : 0x1
      usb.c: new USB bus registered, assigned bus number 1
      ehci_hcd 00:03.1: USB 0.0 enabled, EHCI 1.00, driver 2003-Dec-29/2.4
      hub.c: USB hub found
      usb-uhci.c: $Revision: 1.275 $ time 15:10:54 May 17 2011
      usb-uhci.c: High bandwidth mode enabled
      usb-uhci.c: v1.275:USB Universal Host Controller Interface driver
      USB20H fcr: 0x64
      USB20H shim cr: 0x8f7
      USB20H syn01 register : 0xfe00fe
      USB20H syn03 register : 0x1
      usb-ohci.c: USB OHCI at membase 0xb8003000, IRQ 6
      usb-ohci.c: usb-00:03.0, PCI device 14e4:471a
      usb.c: new USB bus registered, assigned bus number 2
      hub.c: USB hub found
      hub.c: new USB device 00:03.1-1, assigned address 2
      hub.c: USB hub found
      Initializing USB Mass Storage driver...
      usb.c: registered new driver usb-storage
      USB Mass Storage support registered.
      hub.c: new USB device 00:03.1-1.1, assigned address 3
      scsi0 : SCSI emulation for USB Mass Storage devices
      Vendor: Model: USB DISK 2.0 Rev: PMAP
      WARNING: USB Mass Storage data integrity not assured
      USB Mass Storage device found at 3
      hub.c: new USB device 00:03.1-1.3, assigned address 4
      usb.c: USB device 4 (vend/prod 0x403/0x6001) is not claimed by any active driver.
      usb.c: registered new driver serial
      usbserial.c: USB Serial support registered for Generic
      usbserial.c: USB Serial Driver core v1.4
      usbserial.c: USB Serial support registered for FTDI SIO
      usbserial.c: USB Serial support registered for FTDI 8U232AM Compatible
      usbserial.c: USB Serial support registered for FTDI FT232BM Compatible
      usbserial.c: FTDI FT232BM Compatible converter detected
      usbserial.c: FTDI FT232BM Compatible converter now attached to ttyUSB0 (or usb/tts/0 for devfs)
      usbserial.c: USB Serial support registered for USB-UIRT Infrared Tranceiver
      usbserial.c: USB Serial support registered for Home-Electronics TIRA-1 IR Transceiver
      ftdi_sio.c: v1.3.5:USB FTDI Serial Converters Driver
      usb.c: registered new driver acm
      acm.c: v0.21:USB Abstract Control Model driver for USB modems and ISDN adapters

  3. hi Elco, could you please post a correct link to avrdude.conf? now it seems to be broken. thanks.

    • Thanks for notifying me. It should work now.

  4. Hey, I’ve been following this and your other guide on installing optware onto a wl-520gu router. When I type “make” to make avrdude I get make: *** [config_gram.c] Error 1 I’ve done some basic debugging and it seems as though this file doesn’t exist and fails when its being created. Any ideas? Thanks

    • Config_gram.c seems to be a part of avrdude. It should come with it.
      I don’t recommend using a WL-520 anymore if you are building UberFridge/BrewPi. I am almost ready for my first test run with BrewPi. The Arduino code has improved a lot already and the Python and PHP will improve a lot after the first release. On a Raspberry Pi its as easy as ‘sudo apt-get install arduino-core’.

      • Hey Elco, Thanks for the quick response. The 520 was for another project and I”m just trying to add this functionality to it. The tar.gz file I downloaded contains a config_gram.y but not a .c . maybe I’ll look into a raspberry pi or try your precompiled binaries.

Leave a Reply

Your email address will not be published. Required fields are marked *