Developers Blog

Blog > Arduino Uno as a connected event trigger

on Feb 28, 2011

In the beginning, there was a need

One of our customer asked us for a hardware solution to create events in the pigebox without having to access the web form. He said the members of the radio are not always familiar with the interface and must have something trivial, a kind of big red button, on which they may push at the beginning of their program, to create a temporal marker, and on which they push again at the end, so that the extract can be made very easily, if not automagically !
Indeed, this need could be shared by many customers, and several solutions already sketched up in our heads. We decided to accept the challenge.

First option, a USB button

What looks most to this red button was a keyboard with only one key, and one LED. We decided to investigate a bit in this way, since such a very simple keyboard could be easily derivated to GPIOs or sound pannel for Rivendell Radio Automation software. After a quick look on the microcontrollers available on the market today, we’ve chosen a PIC 18F4550 from Microchip, which has great features and a pretty simple programming model. The only thing which can be argued against it is the lack of support by GCC (a variant of this compiler may be used with PIC32 chips anyway).

There are plenty of sample source codes around the web to support the USB-HID functionality with this component, and Microchip also provides users with libraries to ease application development.

Second option, an Ethernet button

The problem with the USB approach is that it requires a host PC to run a client program on. We cannot make any asumption on the OS our customers are using (even if we strongly recommand using GNU/Linux). Consequently, we may have to develop a client program for Linux, Windows (XP and 7), and MacOS (9 and X). This represents an extra work we cannot aford at this time (didn’t you notice, we constantly are in a hurry :) ) Even if we could use a pretty cross platform language, such as Python or Ruby (should we talk about Java ?), deployment may require installers, which complicates quite a lot the problem.

Fortunately, alternatives exist with Ethernet enabled microcontrollers, either fully integrated, or by combination of a traditionnal controler with an external Ethernet controler. The latter has a great example in the Open Source community named Arduino Uno, a small kit based on Atmel microcontroller, with USB connectivity and a “standard” form factor PCB, accepting a whole bunch of “shields”, adding external stuff to the main core. We were particularly interested in the Arduino Ethernet Shield. Both of them are available on Hackable Devices website.

Tux Bless Open Source Community

Arduino project has a very active community, which has developed a lot of useful resources, especially libraries for using the kit. Arduino designers have developed an open source IDE for fast development of “sketches” (programs) to be run on the Uno. There are examples included inside the IDE, which allow picking pieces all around and combine them into our own project. This is precisely what we did for our button. First, we took the “debounce” and “WebClient” examples.
The first one is useful because even if you think you are fast enough, anytime you press on a button, it’s internal mechanics is creating bounces, which may trigger glitches in your program during a very short period (some milliseconds). A debounce system detects the first change on the input (button press or release), then samples the input after a while (some milliseconds) in order to let the mechanics reach a stable state.
The second example originally performs an HTTP GET request to a webserver. This usecase is close to the pigebox, since labels are created through an HTTP POST request on the web application. So we tried to modify the example in order to make a POST request.

Let the tricks enter the place

Honestly, this was the first time we played with Arduino and we found it very exciting. But anyway, life would be boring if we hadn’t to make our brains work a little. So Computer Scientists introduced side effects…

Rails protection

We were not able to simply mimic the HTML form because Ruby on Rails protection against forgery attacks includes an Authenticity Token into forms, which is generated by the previous GET request of the form. Too bad for us, this is precisely forgery we are doing ! This would have forced the button to first perform a GET request, parse the result, then perform the POST with the correct Authenticity Token. Simply not acceptable in term of latency. Never mind, we switched to JSON API, which allows a direct POST of label resource. The request then looks like this :

POST /sources/1/labels.json HTTP/1.1
User-Agent: TryphonRedButton/1.0
Host: 192.168.15.170:3000
Accept: */*
Content-Type: application/json
Content-Length: 32
Connection: Close

{label: {name: program_started}}

HTTP/TCP/IP Latency

For a reason we cannot figure out at the time of this article, this simple request required 10s to be processed and answered by the Rails “Pige” program when issued by the Arduino board. If we mimic the same request performed by a computer with Curl, it is processed in less than 100ms. A deeper analysis with Wireshark network protocol analyser showed a very fragmented stream when the request is issued by the Arduino, but the packets are well grouped in a small amount of time. Therefore, the answer takes 10s to be sent. Rails claims 30ms processing time.

With no more clue on this, we’ve chosen to switch to UDP, and develop a minimalist UDP server, in charge of receiving the UDP events from the button, and relay them in HTTP to the pige program. This small server will be included in the Pigebox itself, and will be able to receive events from other sources such as Rivendell Now&Next. We’ve developed this small daemon in Python. Its code is available in the PigeBox repository. We plan to integrate this code in Ruby with Event Machine directly in the Pige project.

Arduino hardware and software resets…

After the arduino firmware has been stabilized and tested, we tried the real usecase of plugging the Red Button on an external power supply and on the network, and try the functionnality… #FAIL ! It looked like the Ethernet controler does not answers well either to Arduino sollicitations, nor the ones from the network. Looking closer to the schematics from the Arduino Uno board, and the one from the Ethernet Shield, the reset circuitery looks funny.

On the Arduino Uno board, there are 2 main components : the ATmega328, on which sketches are executed, and the ATmega8U2, configured as a USB-serial translator. In order to trigger the flash reconfiguration of the ATmega328, a bootloader is included in the very first part on its memory. This bootloader is executed everytime this component comes out of RESET state, which mainly occurs in two cases : the first one is the “power ON reset”, in other words, when the power supply is applied on the component, internal reset is maintained active for a while in order to let the circuitry reach a stable state and all the internal supplies to setup. The second case is when the user triggers a reconfiguration in the IDE on the host computer, and the Arduino is plugged on the USB. The small ATmega8U2 receives the reset order, and applies a low level on one of it’s outputs, connected to the RESET/ input of the ATmega328 via a serial capacitor. It results in a short spike applied on the RESET pin, which is pulled up to 5V by a resistor. This spike is supposed to be sufficient for resetting the chip. Why is that RESET pin connected through a capacitor ! Why not connect it directly to the output of the ATmega8U2 ? We’ll propose a patch to this in a future post, but it will probably break backward compatibility.

Anyway, trouble occurs only when the ethernet shield is coupled with the Arduino board, and with Power On Reset. It is not written anywhere in the W5100 datasheet that this chip has a Power On Reset circuitry, so it’s not reasonable to rely in this. Some users on the net recommand putting a capacitor between RESET pin and GND, in order to fake the P.O.R. In general, this is the way things are usually done and it should work pretty well. But here it doesn’t. Instead, it seems to cause an infinite looping in the ATmega328 bootloader (L Led is flashing 3 times). Well, something very, very tricky.

Our solution to get rid of this is to workaround the problem : If reseting the ethernet chip causes problem on power on, let’s do it later ! Of course, later means “in the sketch”. But as you noticed, the RESET pin of the ethernet controler is connected on the RESET connector, which is only usable from the ATmega8U2. Never mind again, let’s disconnect this pin and route it to a GPIO controlled by the ATmega328 ! We just bended the pin and solder a wire between this pin and GPIO8.

Then we modified our sketch in order to reset the ethernet controler during the setup phase. Et Voila ! Our Red Button now boots correctly right after applying power on the DC IN connector, and correctly sends orders to the PigeBox.