Jan 232017

Currently I’m the main maintainer of node-hid, the Node.js package that lets you talk to USB HID devices like blink(1).  I recently cribbed automated build config from node-serialport so now node-hid is automatically built for Mac, Linux, & Windows and Node 4.x,6.x,7.x.   It’s pretty cool to have these robots doing my bidding.  But did you know you can do automated builds of Arduino sketches too?  I didn’t until last night and it’s AMAZING.

For instance, that CrashSpace BigButton Arduino sketch I mentioned previously, is now getting automatically recompiled for the Wemos D1 mini ESP8266 board every time I check in. See?

How is this magic done?

Continue reading »

 Posted by at 3:56 pm
Jan 122017

At CrashSpace we have a publicly-viewable “sign” at https://crashspacela.com/sign/ to let members know when the space is open. This sign page is updated by a big button in the front room. Press it, the sign page updates, and you’ve promised to be in the space for an hour.

But last month, the button broke. So I made a new one based on an ESP8266 WiFi module, WS2812/Neopixel LEDs, and a custom PCB fabbed on an Othermill. Schematics, PCB & firmware at: github/todbot/crashspace-bigbutton.

See below for:

  • construction details
  • PCB techniques for Othermill
  • “sacrificial Neopixels” for 3v3 to 5V level conversion


Some history

The first version of the BigButton I did back in 2010 consisted of an Arduino in a taplight tethered to a netbook running a Perl script. Last year it was upgraded by a member to a Spark.io SparkButton (early version of the Particle Photon Internet Button kit but not using the better chip of the Photon) with a custom 3d-printed case. That upgrade resulted in a much simpler and smaller Button than my original. It was great. But occasionally it would drop its connection and need a reboot. Then a month or so ago it just stopped working entirely. I ended up recreating the functionality with a Photon but found the environment limiting, particularly the near-requirement of an online compiler.

The New BigButton

For the new BigButton I went with the Wemos D1 Mini ESP8266 WiFi board. This is essentially a tiny version of the standard NodeMCU board that contains a USB-to-serial interface and the necessary support circuitry to control and reprogram the ESP8266 module. It’s easy-to-use, stable, and great. Instead of programming it directly, I figured I’d try the ESP8266 Arduino core and write an Arduino sketch.

The sketch uses the wonderful ArduinoJson library. It’s pretty memory efficient and uses clever C++ operator-overloading to let you write JSON parsing code like this:

// jsonstr = '{"is_open":false,"minutes_left":-920.45,"button_presses":[]}'
JsonObject& root = jsonBuffer.parseObject(jsonstr);
bool is_open = root["is_open"];
double minutes_left = root["minutes_left"];

Custom PCB Carrier Board

The first BigButton used flexible LED strip hot glued into a repurposed tap light. That worked but I wanted an excuse to do another Othermill-based PCB, so I created a carrier board that had 12 WS2812 LEDs and a socket for the D1 Mini board. There are breakouts for testing the WS2812s and the button inputs. It also has footprints for buttons and mounting holes for either standoffs or guide rails.

Otherwise the schematic is pretty straightforward.

Sacrificial Neopixels: Converting ESP8266 output for WS2812  LEDs

One interesting thing about the schematic how the ESP8266 (a 3v3 device) manages to control 5V WS2812/Neopixel LEDs. Some WS2812s can be driven by 3v3 logic HIGH, but it’s iffy. The standard solution is a level-shifter buffer to convert 3v3 HIGH to 5V HIGH.

The technique used on the BigButton board, however, is to create a “sacrificial” LED powered not by 5V directly but via a stepped-down voltage from a standard signal diode (with its 0.7V voltage drop). This creates an approximately 4.3V power source that is high enough to drive the LED but brings its concept of logic HIGH (>70% of Vcc) down to what a 3v3 device will output. Basically, we’re building a fakey intermediary power supply for a single LED. The rest of the WS2812 LEDs are driven by 5V.

Here’s a diagram perhaps making the idea more clear:


Othermill design considerations

I wanted the PCB to be millable on an Othermill, so that meant modifying my standard PCB design techniques. There are a few reasons for this. For instance, since this board has no soldermask, I want to maximize spacing between copper traces to avoid solder bridges. Also, I want to minimize the use of endmills smaller than 1/32″ because they are fragile and take a long time to mill.

Thus, the techniques I use are:

  • Increase trace width 16 mil (0.016″)
  • Add ground plane, set its Polygon->Isolate value to 32 mil (0.032″)
  • Single-sided only design (or minimize back-side traces)
  • Space components out to enable easy soldering

The result is below. The Wemos D1 Mini board is mounted on the backside of the board so it doesn’t affect light output.

For the enclosure I reused the original 2010 BigButton taplight enclosure because its diffuser is really pretty good.  Plus my Fusion360 skills weren’t up to making a custom 3D printed enclosure.
The PCB is mounted on standoffs that are then screwed into the modified taplight. The taplight’s switch is reused as the button input.


The final result is flashed with WiFi credentials, wired for power, and installed on the wall.

CrashSpace BigButton w/ ESP8266, WS2812/Neopixel, using Othermill


 Posted by at 11:40 am
Sep 232015

Atmel AVR portable dev kit

Recently a CrashSpace member asked about my little portable AVR dev platform. It’s small, compatible without avrdude hacks, and cheap enough to not worry about. Though it’s a gaffer-taped together setup, it’s served me well for about 10 years.  It’s in a go-bag about the size of my laptop’s power supply, so it’s often with me.  But people do sometimes look at me strangely when I whip this out at coffee shops. (but then I blink LEDs and all is forgiven)

The kit consists of:

  • AVRISP mkII programmer (w/ custom +5V switch on VTG (power to target))
  • USB hub, travel size 4-port
  • USB extension cable, 1 foot
  • Generic 3.3V/5V USB-to-serial adapter
  • Enough gaffers tape to bodge it all together

Just plug it all together and go.  The AVR ISP mkII is an official one from Atmel and is about $30. It looks like it may not be made any more, but there are many clones out there. The nice thing about the official one is that it works at 5V & 3V and has short-circuit protection.  I do wish the ISP protocol was faster though.  Compared to bootloaders, it’s around 5x slower. That adds up.

AVR Programmer VTG power

The VTG +5V switch add-on is super useful.  Normally ISP programmers don’t supply power to the target. (and shouldn’t, you don’t have to have a power supply fight)  But when doing exploratory development, having the programmer providing the power is really handy.  if you don’t want to mod your programmer, you could take an old USB cable, cut it up and run the +5V to your board.  If I were to do it again, I’d add some sort of current-limiting for those just-in-case oopses.


You don’t always need a serial port but when you do, you really do.  I usually keep this plugged in just in case, sort of like how I always keep a few LEDs & 1k resistors on hand.  Both are great for on-the-go debugging.

Programming adapter cables

For working with the strange, small boards I make, I have a collection adapters made from male-to-{male,female} jumpers that go from the AVRISP 6-pin connector to whatever I’m working on:

Atmel AVR portable dev kit


And when I work on PIC USB projects, I have a similar one for PIC.


 Posted by at 4:53 pm
Dec 102013

[originally posted on the ThingM blog]

The theme for the Caltech Entrepreneurs Forum’s November event was “The Internet of Things, Arduinos and the ‘Maker Entrepreneur’“.


My talk “Intro to the Arduino Entrepreneurial System” touched on all these topics. The entire event was a blast, including a wonderful talk about commercial making with open source by Quinn of QtechKnow.

Slides with notes and MP3 audio of the entire event are below.

Download MP3 of the entire Forum proceedings, including Tod’s talk.

 Posted by at 1:39 pm
Apr 292013

In late 2006 I wrote “arduino-serial“, mostly for myself, to help with stuff I was working on at the time. It was a very simple & small, cross-platform tool written in basic C for reading/writing serial ports.

Now nearly seven years later I still get regular questions and frustrations about it. Part of this is due to how Arduinos have changed over time. You used to have to hand-reset an Arduino board, now the act of opening the serial port resets it. This has its plusses and minuses, but it really made my original use-case of arduino-serial fail. Then there were just all the minor deficiencies of the program.

To address some of these issues, but still keep things small & light, I’ve done a bit of fix-up of arduino-serial. It’s now hosted on Github at:

Changes & Improvements

Some changes that I recently made to arduino-serial:

  • Separation of the application (arduino-serial.c) from the library (arduino-serial-lib.{c,h})
  • Fixed probable --read bug
  • Fixed --port open to allow re-opens
  • Added --sendline command to send a string followed by a newline
  • Added --flush command to clear out receive buffer
  • Added --eolchar option to let you specify your own end-of-line character if ‘\n’ isn’t appropriate
  • Added --timeout option to specify a read timeout (reads no longer block infinitely)
  • Added --quiet flag to make output more terse/machine-readable

Here’s what the new usage help screen looks like:

laptop% ./arduino-serial
Usage: arduino-serial -b <bps> -p <serialport> [OPTIONS]

  -h, --help                 Print this help message
  -b, --baud=baudrate        Baudrate (bps) of Arduino (default 9600)
  -p, --port=serialport      Serial port Arduino is connected to
  -s, --send=string          Send string to Arduino
  -S, --sendline=string      Send string with newline to Arduino
  -r, --receive              Receive string from Arduino & print it out
  -n  --num=num              Send a number as a single byte
  -F  --flush                Flush serial port buffers for fresh reading
  -d  --delay=millis         Delay for specified milliseconds
  -e  --eolchar=char         Specify EOL char for reads (default '\n')
  -t  --timeout=millis       Timeout for reads in millisecs (default 5000)
  -q  --quiet                Don't print out as much info

Note: Order is important. Set '-b' baudrate before opening port'-p'.
      Used to make series of actions: '-d 2000 -s hello -d 100 -r'
      means 'wait 2secs, send 'hello', wait 100msec, get reply'

Using arduino-serial

arduino-serial has always been designed so you can “pipeline” commands/options, but it wasn’t implemented very consistently. It’s a bit better now. You can do multiple send/read pairs, even use multiple serial ports, all from a single command-line invocation.

For example, if you have the “SerialCallResponseASCII” sketch from the Communications examples loaded onto your Arduino, you can run commands to take multiple data readings. In the example below, the order of operations are:

  1. serial port is opened (at 9600)
  2. the string “A” is sent (a single-byte)
  3. the first line is read
  4. sleep for 1000 milliseconds
  5. send “A” again
  6. read second data line
  7. flush read buffer (just to show we can)
  8. send “A” a third time
  9. and take a final reading
laptop% ./arduino-serial -b 9600 -p /dev/tty.usbmodemfd131 \
            -s "A" -r  -d 1000  -s "A" -r  -F  -s "A" -r
send string:A
read string:465,396,0

sleep 1000 millisecs
send string:A
read string:358,352,0

flushing receive buffer
send string:A
read string:307,305,0

The flush was put in there to demonstrate that you could flush the receive buffer mid-command if you wanted. It’s not required, but might help some situations.

To use multiple serial ports, you can do something like the below, which opens up one serial port at 9600 bps, does a send & receive, then opens another at 57600 bps and does a send & receive on it:

laptop% ./arduino-serial -b 9600 -p /dev/tty.usbmodemfd131 \
        -s "A" -r \
        -b 57600 -p /dev/tty.usbserial-A800f8ib \
        -s "hello" -r 
 Posted by at 5:43 pm
Mar 022012

Did you know each Arduino has a unique serial number in its USB interface that you can use to distinguish one Arduino from another? If you deal with multiple Arduinos, knowing exactly which one is plugged into your computer can be a real time-saver. But actually getting at this serial number and mapping it to COM ports can be challenging.

For Windows computers, here’s “listComPorts”, implemented both in GCC C code and in VBScript, both available from my usbSearch github repository.

It gives the COM port number, the manufacturer name, the USB Vendor ID and Product ID (VID & PID) and the serial number. The result is a concatenation of the VID, PID, and serial number that Windows calls a “PnPDeviceID”. You can use the whole thing, or pick off the parts you need using simple string processing libraries. In the example above, the Arduino Diecimila has a VID/PID pair of 0403/6001 and the Teensy has a VID/PID of 16C0/0483.

Arduino Serial Numbers

In the above example, the Arduino Diecimila (which has an FTDI chip) has the serial number with a “+”-sign after the PID. So, the serial number is “A6004CCF”. The Teensy can have a programmable serial number and by default it’s set to “12345”.

With Arduino UNOs and future Arduinos, the Arduino team has their own VID/PID pair, which let’s them assign different PIDs for different classes of Arduinos. The UNO also has a much longer unique serial number than older Arduinos using the FTDI chip.

Here’s an example with two Arduino UNOs:

The serial numbers are separated by the VID/PID pair with a backslash. So my two UNOs have the serial numbers “64936333936351408161” and “6493234373835191F1F1”. Using this info, I can be sure exactly which Arduino I’m dealing with.

How it works

The C and the VBS versions both utilize the WMI infrastructure that’s been around since Windows 2000 to query the machine about its configured PnP devices. The WMI is a huge data structure of just about any information in Windows. Except, it seems, good information about COM ports. While there is a “Win32_SerialPort” table in WMI, that only contains information about hardware serial ports, not USB-to-serial adapters. Instead, these two tools look at the “Win32_PnPEntity” table. While this table does list USB-to-serial adapters, it does not contain a proper mapping of the adapter’s USB or PnP ID to COM port. Instead, these tools do a string search on the “Caption” field for the string “(COMn)” where “n” is a number. It’s an incredible hack but seems to work.

Other operating systems

On Mac OS X and pre-UNO Arduinos, knowing exactly which Arduino you were dealing with was easy because the FTDI driver put its serial number as part of the name of the serial port. For example, the port name created by the FTDI driver was “/dev/tty.usbserial-A6004ccf” and the serial number was “A6004ccf”.

With the UNO, the Arduino team used a reprogrammable ATmega8/16u USB chip using standard CDC USB-to-serial interface, which all OSes support natively. Unfortunately, on Mac OS X, the OS’s CDC driver creates a serial port for the UNO based on USB port location, not Arduino serial number.

Thus where you plug in the UNO into determines its serial port name. For instance, on my Mac, plugging in an UNO with serial number “64936333936351408161” gives a serial port with the name of either “/dev/tty.usbmodemfd131” or “/dev/tty.usbmodemfa141” depending on which USB jack is used. Even if you plug in a different UNO in the same jack, you’ll get the same serial port name. This is useful for some applications, but not if you need to know exactly which UNO you’re dealing with.

For Mac OS X, I use a tool I wrote called listArduinos.pl. It tries to determine the serial port names of every Arduino Uno. It’s out looks like:

bokbok% ./listArduinos.pl         
Finding Arduino UNOs...
/dev/tty.usbmodemfd131 - 0x2341/0x0001 - 6493234373835191F1F1
/dev/tty.usbmodemfa141 - 0x2341/0x0001 - 64936333936351400000
Found 2 Arduino UNOs
 Posted by at 1:55 am
May 292011

For Maker Faire this year I made a second version of my BlinkM Cylon: BlinkM Cylon mkII. This is not a very cost-effective way of getting a Cylon effect. It however is a good way of showing how to wire up multiple BlinkMs with a long cable, using our new WireM cabling kit for BlinkM. And unlike normal Cylon circuits, this has full RGB color effects and gradual fading.

BlinkM Cylon mkII

Here’s a quick video showing it in action.

BlinkM Cylon mkII consists of:
– 13 BlinkMs (one for each of the tribes of Kobol)
– one WireM cabling kit for BlinkM, consisting of IDC connectors and ribbon cable
– an Arduino
– two 4.7k resistors
– a single push-button
– 9VDC wall wart to power it all.
– laser cut acrylic enclosure

Below are all the files needed to recreate your own BlinkM Cylon. Click any of the images for larger versions.

Continue reading »

 Posted by at 11:32 pm