Leonard's Leonardo

Posted on December 5, 2015 by Brian Jaress
Tags: code, c, hardware

Way back in June, Leonard Young handed me an Arduino Leonardo and said, “Borrow this and play with it.” I kept promising him I’d share the results online, and here I’ve finally done it. You can go straight to the full code or read on for a story with code excerpts.

I usually focus on software, but even I’ve heard of the Arduino boards, which are all the rage among hobbyists. People are using them to build clocks, express their love, and even brush their teeth. Unfortunately, all of that requires attaching things like motors, sensors, and displays to the Arduino. Without anything connected to the board, there’s no way for the software running on it to get input and no way to give output except blinking the built-in light.

Blinking a light does have it’s uses, though. The suggested way to check that you’re able to load code on the board and run it is to load and run a program that blinks the light on and off at regular intervals.

That helped me discover that the Leonardo has an odd quirk, where you sometimes have to press the big red button right before you try to load software, or it won’t take.

For something a tiny bit more interesting, I wrote another program to blink in a counting pattern: once, pause, twice, pause, three times, pause, etc.

unsigned int flash_count = 0;
void loop () {
    flash(flash_count++);
    delay (500);
}

void
flash (unsigned int count)
{
    while (count--)
      {
          digitalWrite (13, HIGH);
          delay (500);
          digitalWrite (13, LOW);
          delay (500);
      }
}

It will eventually overflow the counter, but that would take nearly seventy years.1

The structure of the code is a bit unusual because of how the Arduino programming environment works. The Arduino IDE uses a dialect of C++ that expects to supply its own main() function that repeatedly calls a loop() function you write.

The repeated calls to loop() make it work like a while loop, so the code above is using a global variable to make it work like a for loop.2 It’s possible3 to skip the IDE and write your own main() that loops using a real for loop with a counter:

int
main (void)
{
    setup ();

    for (unsigned int count = 0;; count++)
      {
          flash (count);
          delay (500);
      }

    return 0;
}

A few days later, Leonard handed Katie an Iduino Yun Shield and said, “Tell Brian to play with this, too.”

With the Yun shield attached, code running on the Arduino can access data from a network, including WiFi. It could, for example, transmit sensor data over the Internet or receive instructions on how to move an actuator.

Except I still didn’t have any sensors or actuators, just the blinking light, so I wrote code to blink data received over a network. This final program accepts text over the network, blinks it in Morse Code, then echoes each character back over the network when it finishes blinking it.

The code is mostly a big switch with cases like:

    switch (symbol) {
        case  'a':   blink(".-");       break;
        case  'b':   blink("-...");     break;
        case  'c':   blink("-.-.");     break;
        case  'd':   blink("-..");      break;
        //etc.
    }

And a translator function:

void
blink(const char * encoding)
{
    while (*encoding) {
        switch (*encoding++) {
            case '-' : dash();
            break;
            case '.' : dot();
            break;
        }
    }
    gap();  //extend final inter-dot gap into an inter-letter gap
}

One slight oddity is that you have to ssh to the Yun, and from there telnet to the Leonardo:

ssh root@192.168.240.1 'telnet localhost 6571'

The Yun Shield runs off the Leonardo’s power, but needs the Leonardo to be powered by the DC jack (7-12 V). Unfortunately, the only suitable power supply I had was from my router, so the wireless connection was a direct one between the computer and device, but in general the Yun Shield can get on a network4 and share data with everyone. Leonard did exactly that later, but I hear it caused some problems with the university network admins.

What prompted me to finally post all this was learning that someone else did something similar: the excellent Science Friday does listener-participation challenges, and their recent message sending challenge had an entry using an arduino lamp to blink Morse Code.


  1. It’s a 16-bit chip, so by my count it’s \(\sum_{n=0}^{2^{16}-1} n\) seconds of delay in flash(), plus \(\frac{1}{2} 2^{16}\) seconds total delay in the outer loop.↩︎

  2. You could also just put a for loop inside loop().↩︎

  3. The problem with skipping the IDE and writing your own main() is that the official libraries are distributed through the IDE and some of them only compile with the specific compiler version included in the IDE. So once you start plugging in supported hardware, it’s worth it to hold your nose and use loop().↩︎

  4. Basically, you get your computer on the wireless network that the Yun creates by default, then open http://192.168.240.1, which will be served by the Yun over that network. You can fill out a form on that page (under Wireless Parameters) to give the Yun the information it needs to get on your regular network instead of creating its own.↩︎