Arduino programming using Ruby, Cucumber & rSpec

The project

This project serves as a sanity check that all is in order with the hardware, without the need to write on-board code using the IDE nor use the avr toolchain. What better tool than Ruby to do so?

The first thing we’ll do is to assure that the board and its built-in LED are responsive. Let’s define the behviour we would like, and implement it using Cucumber, in true BDD fashion:

  Assure board led is responsive

    Given the board is connected

  Scenario: Turn led on
    When I issue the led "On" command
    Then the led is "On"

  Scenario: Turn led off
    When I issue the led "Off" command
    Then the led is "Off"

The step implementation follows:

require 'driver'

Given(/^the board is connected$/) do
  @driver ||=

When(/^I issue the led "([^"]*)" command$/) do |command|
  value = string_to_val command
  expect(@driver.set_led_state value).to be value

Then(/^the led is "([^"]*)"$/) do |state|
  expect(@driver.get_led_state).to eq string_to_val state

def string_to_val state
  case state.downcase
    when 'on'
      my_state = ON
    when 'off'
      my_state = OFF

Some things to note:

  • We don’t have an assertion on @driver ||= because the driver will simulate a connection in case the phyical board is disconnected or unavailable due to disrupted communications.
  • The user communicates using the words “on” and “off”, which are translated to ON and OFF for internal use.

This test will fail, of course, as we have yet to define the Driver class and we drop to rSpec, in TDD fashion:

require 'driver'

describe "led functions" do
  before(:each) do
    @driver =

  it "turns the led on" do
    expect(@driver.set_led_state ON).to eq ON

  it "turns the led off" do
    expect(@driver.set_led_state OFF).to eq OFF

  it "blinks" do
    @driver.blink 3

This too fails, of course, and we implement Driver thus:

class Driver
  def initialize 
    @arduino ||= ArduinoFirmata.connect nil, :bps => 57600 
  rescue Exception => ex 
    puts "Simulating. #{ex.message}" if @arduino.nil?
  def set_led_state state 
    result = @arduino.digital_write(LED_PIN, state)
  rescue Exception => ex 
    @state = state 

  def get_led_state 
  rescue Exception => ex 

  def blink num 
    (0..num).each do 
      set_led_state ON 
      sleep 0.5 
      set_led_state OFF 
      sleep 0.5 


Some things to note:

  • I am using the arduino_firmata gem, please see the Gemfile for details.
  • The initialize method catches the exception thrown when the Arduino is not connected, as the other methods do, in order to simulate the board in such circumstances. The simulation is always succeeds, by the way, and was coded to allow development without the board connected.
  • arduino.output_digital_read is a monkey-patch to the gem, as I could not find a way to query the board if an output pin was on or off:
module ArduinoFirmata
  class Arduino
    def output_digital_read(pin)
      raise ArgumentError, "invalid pin number (#{pin})" if pin.class != Fixnum or pin < 0
      (@digital_output_data[pin >> 3] >> (pin & 0x07)) & 0x01 > 0 ? ON : OFF

All green

Having implemented the code, the tests should now pass and running rake again will run both Cucumber and rSpec, yielding:

~/Documents/projects/arduino (master)$ rake
/Users/ThoughtWorks/.rvm/rubies/ruby-2.2.1/bin/ruby -I/Users/ThoughtWorks/.rvm/gems/ruby-2.2.1/gems/rspec-support-3.3.0/lib:/Users/ThoughtWorks/.rvm/gems/ruby-2.2.1/gems/rspec-core-3.3.1/lib /Users/ThoughtWorks/.rvm/gems/ruby-2.2.1/gems/rspec-core-3.3.1/exe/rspec --pattern spec/\*\*\{,/\*/\*\*\}/\*_spec.rb

Finished in 7.56 seconds (files took 0.27749 seconds to load)
3 examples, 0 failures

/Users/ThoughtWorks/.rvm/rubies/ruby-2.2.1/bin/ruby -S bundle exec cucumber 
  Assure board led is responsive

  Background:                    # features/initial.feature:4
    Given the board is connected # features/step_definitions/initial_steps.rb:3

  Scenario: Turn led on               # features/initial.feature:7
    When I issue the led "On" command # features/step_definitions/initial_steps.rb:7
    Then the led is "On"              # features/step_definitions/initial_steps.rb:12

  Scenario: Turn led off               # features/initial.feature:11
    When I issue the led "Off" command # features/step_definitions/initial_steps.rb:7
    Then the led is "Off"              # features/step_definitions/initial_steps.rb:12

2 scenarios (2 passed)
6 steps (6 passed)


Make this better!

The project is here. Please feel free to fork and contribute.


How much is “good enough”? If you notice, the assertions are implemented using the data structure exposed by arduino_firmata, not with a call to the board itself. This is always a tradeoff in testing. How far should we go? For this project, testing via data structure is “good enough”. For a medical application, or something that flies a plane, it’s obviously not good enough and we would have to assert on an electric current flowing to the LED. And again, who is to assure us that the LED is actually emitting light?

There’s not much else we can do with a standalone Arduino without any periferals connected, but it’s enough to make sure that everything is set up correctly for future development.


This installment was to show a quick-and-dirty sanity check without bothering to flash the device.


The testing and writing of this installment were made while flying to Barcelona, hoping that fellow passengers would not freak out seeing wires and blinking lights mid-flight.

Happy Arduinoing!

How to reconnect to a database when its connection was lost

One of my projects has a long-running task that constantly needs information from the database. I needed a mechanism to assure that the task will automatically reconnect to the database if and when that connection was broken.

I came up with this scheme using a trick with rescue blocks (code abbreviated for clarity) in this gist.

def my_task

    while(true) do
      rescue Exception => ex
          sleep 10
          retry # will retry the reconnect
          retry # will retry the database_access_here call

Here’s a line-by-line explanation:

Line 4: This is where your application’s database access logic would be.

Line 5: Catch a database access exception here

Here is where it gets interesting:

Line 7: Open a new block and retry the connection.

Line 10: This retry will retry the reconnect method and will loop as long as the database connection is still down.

Line 11: The else clause will execute if _no_ exception happened in line 10, and will retry the original database call in line 4.

In my case and example, I am not counting retries because I don’t care that I’ve failed – I must continue to retry. You may want to use “retry if retries < 3” as a break mechanism.

I have also removed some mailer code that notifies me when the reconnect fails so I can (manually) see what happened to the connection. The moment the connection is re-established, life goes on as normal within the infinite while loop.

Weekend warrior – MacRuby and rSpec, Mac OS X Lion, Xcode V4.3.2

Inspired by the recent buzz over RubyMotion, of which I am a proud licensee, I wanted to play a little with MacRuby just to get into the swing of things.

After deciding that doing so was more worthwhile than to mow the lawn, I set out to see what it took to start a project in MacRuby with rSpec support as a basis to start work.

MacRuby’s article got me started, but did not work because the test target could not find the framework that I wanted tested. I don’t know why, since I (sort of) follwed the instructions there. I say “sort of” since the article shows screen-shots of an older Xcode, and even though I thought I set things correctly in my version (Xcode V4.3.2), it still would not build. Also, I am on Mac OS X Lion and that may have had something to do with it.

After realising that if I did not continue trying, a certain member of the household would make me mow that lawn, Google found another article here by Steve Madsen.

It too looked promising, but again, needed tweaking to get working in my environment. It’s thanks to Steve’s post that I managed to get it working.

Here were my steps:
a. Create a new project in Xcode (or use an existing one that you want to rSpec)
b. Install MacRuby
c. Follow Steve Madsen’s instructions

At that stage it still did not work for me, but that was because of a misunderstaning that was clarified quickly enough:

Steve’s screen-shot for the scheme settings on the Specs framework is cut off and does not show the “Expand Variables Based On” setting, so $(SRCROOT) was never expanded for me. I replaced it with an absolute path (ugh) and it worked, so I knew something was not picking up that macro. The solution was to give a value to that drop-down, as shown in the screen-shot below.

If, like me, you’re on Xcode V4.3.2, you might find the following screen-shots useful (just refer to them as you follow Steve’s post):

a. Build settings:

b. Scheme settings:


You cannot imagine the joy of seeing Ruby code drive an Objective-C framework testing session using rSpec in Xcode.

Now to that mower…

Oh, the places you’ll go…

Inspired from the Practicing Ruby entry, I somewhat clarified the code a little (for my taste) and learned that the call stack in Ruby is:

0) Undefined method resolution
1) Methods defined in the object’s singleton class (i.e. the object itself)
2) Modules mixed into the singleton class in reverse order of inclusion
3) Methods defined by the object’s class
4) Modules included into the object’s class in reverse order of inclusion
5) Methods defined by the object’s superclass, i.e. inherited methods

module ModuleA
 def foo
   "- Mixed in method defined by ModuleA\n" + super
module ModuleB
  def foo
   "- Mixed in method defined by ModuleB\n" + super
module ModuleC
  def foo
   "- Extended in method defined by ModuleC\n" + super
module ModuleD
  def foo
   "- Extended in method defined by ModuleD\n" + super
class A
 def foo
   "- Instance method defined by A\n"
class B < A
 include ModuleA
 include ModuleB
 def foo
    "- Instance method defined by B\n" + super
  def method_missing(method)
   puts "- method_missing (#{method}) on b. Redeirecting to\n"
b =
 "- Method defined directly on an instance of B\n" + super
def b.method_missing(method)
 "- method_missing (#{method}) on b. Calling super\n" + super
puts "Calling 'bar' on b of type #{b.class}:\n"

Which gives:

~/projects/ita/ruby$ ruby test.rb

Calling ‘bar’ on b of type B:

– method_missing (bar) on b. Redeirecting to
– method_missing (bar) on b. Calling super
– Method defined directly on an instance of B
– Extended in method defined by ModuleD
– Extended in method defined by ModuleC
– Instance method defined by B
– Mixed in method defined by ModuleB
– Mixed in method defined by ModuleA
– Instance method defined by A

Follow the conversation on Stack Overflow.