Arduino Leonardo – A Design Change

Pardon the delay! The past three months have been hectic with school and work. I’m finally taking some time over the holidays to get this project wrapped up.

I’m leaning towards implementing an Arduino Leonardo in place of a Pro Mini for two main reasons. The first is that the Leonardo has built-in USB support which frees up the UART for use with a Bluetooth module. The second major advantage is that the Leonardo actually has two 16-bit timers. While at first this may seem trivial, it in effect allows me precise control over the vibratory pump as well as boiler. Because the Crydom relay used to control both pump and boiler is a ‘zero-crossing’ relay, the relay can be toggled at 60Hz without the vibratory pump ‘stuttering’ – a full sinusoidal wave-form is allowed to pass through the relay before it latches on or off.

I can effectively control the pressure at the brew head by controlling the flow rate of water through the pump. Any standard duty cycle will work here (number of 60Hz cycles on to the number of 60Hz cycles off) allowing for precise control of pump activity. While the prescaler doesn’t allow for coincident timing at exactly 60Hz, the frequency discrepancy is so low (0.0961538 Hz) that a switching error (ie the Arduino pin would toggle at the zero crossing point, missing the step) almost never occurs in practice.

Timer (PWM) based control of the pump (Timer3), boiler (Timer1), and pin-change interrupts for the Brew (Pin 10 / PCINT6), Hot Water (Pin 11 / PCINT7) and Steam (Pin 8 / PCINT4) switches means that basic control over Silvia can be driven by interrupts instead of actively polling in the main loop. Additionally, the RTC interrupt pin on the DS3231 can drive Pin 7 / INT.6 allowing for a real-time clock based alarm / wakeup.

In short, the main body of code then will simply be to passively update the PID and Display module.

Rebuilding the Arduino IDE to Support Sprintf with Floats

One of the biggest limitations within the Arduino IDE is the inability to render float types using sprintf() or some other print() family function. For the sake of sketch size, these functions were largely stripped down of their ability to handle float types in favour of a float-to-string conversion function for those who needed it. Anyone who does use sprintf() with a float type will be met with a '?' in place of their float. However this is not to say that the Arduino IDE cannot generate sketches capable of handling floats! In fact, the AVR compiler that the Arduino IDE uses supports floats in sprintf() – just not by default. So we need to instruct it to do so.

I’ve written up some (pretty simple) instructions that you can follow to prepare your own Arduino IDE that will support float types with sprintf():

  1. Navigate to: http://code.google.com/p/arduino/wiki/BuildingArduino and prepare your build environment so that you’ll be able to compile everything okay. Proceed with the build instructions up until Step 3.
  2. Navigate to the following file and open it using your favourite text editor (you might have a slightly different file structure depending on your operating system): /app/app/src/processing/app/debug/Compiler.java
  3. Search for the following line of code: "-Wl, --gc-sections"+optRelax,
  4. Replace that line of code with: "-Wl,-u,vfscanf,-lscanf_flt,-u,vfprintf,-lprintf_flt,--gc-sections"+optRelax,
  5. Save the file and continue with the rest of the build process.

If all goes well, you should now have a fresh Arduino IDE built from the latest source code that supports floats in sprintf(). No more nasty ‘?’ :). You’ll notice however that even basic sketches are rather large in size (~10kb). However this is a tradeoff that you must be willing to make if you want sprintf() with float support.

I hope this helps everyone – I know I certainly appreciate having float support.