If you know me at all, you know I have an ongoing love/hate relationship with Arduino. I like that it has launched a whole ecosystem of inexpensive and readily available peripherals. I don't like the clunky IDE, the bizarre terms (like sketch), and the fan boy culture surrounding it. Perhaps part of what I don't like is the lack of innovation. At the core, the Arduino is nothing more than an Atmel chip, a bootloader, and the GNU C compiler. There's also a very simple (and hardly necessary) C language framework and a truly bad Java-based IDE that's only good feature is the way it integrates libraries (well, until you look at how it does it under the covers, but that's another topic).
White PapersMore >>
- Simple, Effective Patch Management: From Dilemma to Done Deed
- OpenStack: Blueprint for Deployment Success
All that applies to the traditional Arduino. However, I recently picked up an Arduino Leonardo board. It still suffers from the horrible IDE (and I talked about how to avoid the IDE before). It does, however, add something very powerful. USB support.
It is true that some Arduino boards — maybe even most — have a USB port. But that USB port essentially was a serial-to-USB adapter built on the board, not an integral part of the Arduino. The Leonardo's USB port is a real USB port accessible by the CPU. It still looks like a serial port for downloading and debugging your software. It can also look like a keyboard or a mouse! It can even look like all three devices at the same time.
As usual, the Arduino provides a clean library that's easy to use, so building an alternate keyboard or mouse becomes drop-dead simple. I've talked about building HID devices before and it wasn't that simple. Actually, it wasn't simple at all.
In the past, when I've used an Arduino it has been because they are readily available, but it wouldn't be my first choice for a project. However, if I were building a custom HID device, I would not hesitate for a second to select the Leonardo (or a similar USB-integrated Arduino). The ease of use is amazing.
How easy it is? Here's how to send Dr. Dobb's to your PC as though it were typed from the keyboard. This is the function that drives the sensor board (you can also download the entire file):
Keyboard.begin(); Keyboard.print("Dr. Dobb's"); Keyboard.end();
If you need to press modifier keys, you can use
Keyboard.release, so the system is pretty flexible. The mouse is just as easy to use.
Compare that to how much code it takes to stand up an HID device without using a library (and yes, I know there are other libraries). In addition, having the serial port through the same line for debugging is very convenient (although, if you were writing a serious HID device, you might want to use the second serial port for printing debugging messages).
So what were the three things I learned?
1. How to get the IDE to work on Linux
The Leonardo's serial port shows up on Linux as /dev/ttyACMx (where x is some number like 0 or 1). That didn't throw me, but the IDE couldn't find it. I had read that the IDE actually figures out where the board is by putting the board through a reset. Because the serial port is software running on the Leonardo, the port disappears and then reappears. The IDE assumes any port that suddenly appears is probably the Leonardo and downloads to it. I just couldn't get this to work at all.
I tried to download the latest Arduino IDE but it still couldn't see the ACM port. I know the Java-based Arduino IDE uses the RXTX library for serial ports, so I tried removing the ones that come with the Arduino IDE and let the software use my default ones. That didn't work.
It turns out, you really do need to use the supplied RXTX libraries. You also need to modify the arduino executable (don't worry; it is just a shell script). The very last line is a Java command line that starts the actual IDE. You need to add –Dgnu.io.rxtx.SerialPorts=/dev/ttyACM0 to the arguments on that line (of course, use the right number if your Leonardo doesn't show up as port 0). While you are there, you might take out the swing option that sets the GTK look and feel — I hear some machines run the IDE faster without that option, although I didn't notice much difference.
2. !Serial really waits for the PC to open the port, not just connect.
Because the serial port disappears on every reset, it is common to see Leonardo programs use this idiom to wait for the serial port:
This doesn't hurt anything on other Arduinos, so you see it in a lot of example code. I always thought this code would just wait for the serial port enumeration to complete (which takes a fair amount of time, by the way). However, it actually waits for something to open the port on the PC. So if you don't open the serial monitor, this will hang your program forever.
In the past, I've peppered my code with serial output statements for debugging and just left them in when I was done. You can still do that, but you better comment out that
while statement, or your program won't run without an open terminal on the Leonardo's com port.
3. The IDE doesn't save before it compiles.
I actually ran into this before, but it bit me again this week. If the IDE crashes, any unsaved changes you made are gone. That might seem obvious, but most IDEs I've used save your code on each compile. So the most you lose is what you've done since the last build. The Arduino IDE does not do this. If you never saved your code then you'll get an empty file after a crash no matter how many times you've built your project.
Of course, the IDE has to save your code somewhere. It actually mixes it in with a bunch of other things and saves it in a temporary directory. In my case, I found the code in /tmp/build6606660780136176668.tmp (you can do a directory listing in /tmp sorted by date and find the most likely candidates). My program was called ranger, so the ranger.cpp file had my code in it, interspersed with extra stuff added by the IDE (#include and #line directives, mostly). It just took a minute to remove the extra lines and recover my file. Another reason I don't care for the IDE.
What could you do with the USB capability of the Leonardo? A host of custom keyboard ideas come to mind. Foot pedals for common input sequences. A detector that sends keys when an infrared beam breaks, or a temperature is too hot. Sure, you don't need to do this through a keyboard, but (as you'll see next time) you don't need any software on the computer to make it work. Most computers have some way to translate keystrokes into actions (AutoHotKey on Windows, for example; many different ways on Linux either built-in or using something like xdotool). So starting a video, for example, when someone breaks an infrared beam should require no custom software on the PC at all. It is easy to imagine a Leonardo and an accelerometer becoming a customized mouse. Again, the PC already knows how to read the mouse input, so you don't need any special software.
Next time, I'll show you a quick project that uses a cheap ultrasonic sensor and makes use of these ideas. I still won't say I'm a rabid Arduino fan, but I'm getting a lot of ideas related to custom HID devices that take minutes to create instead of days.