IoT Prototyping: Building an Easy to Use Development Kit
When we set out to build an IoT Development Kit (Dev Kit), we wanted to build something realistic - something that we, as developers of embedded hardware and firmware, would find both effective and useful. Part of being realistic was understanding what we could make easier and what things are hard regardless of how we present them. The hardware available for the kind of sensing we wanted to enable all existed, but we weren’t comfortable with how much effort was required to enable features like digital bus interaction, wireless communication, low power operation, and data logging. We also thought there were less confusing ways to expose hardware interfaces than to expose every single pin the processor has available.
The Sensor Bus
One of the first things we decided to use is something we call the sensor bus. It standardizes the hardware interfaces all sensors have and essentially allows us to manage a narrow interface while still supporting hundreds (if not thousands!) of sensors This meant less software to write, hardware designs that are more simple, and that users need to learn fewer interfaces.
We designed the Sensor Bus around the I2C bus standard (Inter-Integrated Circuit). I2C allows us to connect all our sensors to the same set of wires. To use other bus types (such as SPI), we’d likely have to use a more complicated set of wires. I2C is not the fastest bus available, but it’s satisfactory for most of the sensors the DevKit is likely to be used with. I2C needs 4 wires to work: clock, data, power, and ground. The Dev Kit also provides 3 interrupt pins that can be used by I2C sensors. These interrupt pins allow the Dev Kit to remain in a low power state until something occurs inside the sensor that the Lua script needs to know about.
When designing hardware, we thought about the experiences of software and hardware developers to build a kit that was most likely to address pain points. We built in a large non-volatile flash chip that can keep months of data around in case of uplink outages (assuming a reasonable rate of storage). We included a processor with enough power to quickly execute Lua code and enough RAM to house Lua scripts of moderate complexity. The radio is one we manufacture ourselves with good range and good power consumption metrics. We included a battery charging circuit so that it’s easy to use common LiPo batteries.
The interface we expose to the hardware was designed in a way that we can swap out things like the flash chip or the processor to better meet the needs of a customer building out a large scale operation, but in general, we chose a more capable part that we could cost optimize later.
We settled on Lua as the language we run inside the Dev Kit. Lua is a dynamically typed, byte-code interpreted, simple language. We’ve been able to fit it in a relatively small amount of RAM (compared to many dynamic languages), we’ve been able to extend it with the features we need, and we’re able to rely on a sizable volume of good documentation. One reason these things are true is because Lua was designed out of the box as an embeddable, extendable, language.
There are a few stylistic oddities to the language, but they aren’t hard to learn.
The Development Cycle
In my experience, the development cycle around embedded software is aggravating. I’ve taken some serious strides to try and do my development outside of my embedded hardware whenever possible. There are lots of reasons for this, but the large ones are that the debugging output from the chip I’m working on is normally limited to a serial port, a buggy debugger, and a logic analyzer hooked up to some output pins (I love my Saleae Logic Analyzer, by the way).
The sorts of software I can build out of the chip can only be built if I can reliably simulate my hardware inputs and outputs. In my longer-term projects, this is reasonable. If I’m trying to get up and running with a kit quickly, this will be a huge pain point.
To alleviate this, we built up our own sort of semi-hosting (a mechanism where hardware debuggers are able to facilitate input and output requests from a host computer). However, instead of servicing a C API, we expose our lowest-level Lua APIs over our USB connection. A Lua process running on a PC with a DevKit attached is able to interact with the hardware in the same way as a script running inside the DevKit itself.
What this means is access to better debugging features and more memory while developing your Lua script without having to make many (if any!) modifications to your code to work in this debugging environment.
In order to build the Dev Kit’s semi-hosting features, we built the firmware to use message passing APIs rather than typical C APIs. This allows us to pass these messages over the USB port instead of the normal route. This design lets us extend the messages with new features without having to modify any of our core USB code.
The Dev Kit is designed to take a lot of the guess work out of the specific implementations required to achieve wireless communication, data caching, and low power consumption without sacrificing too much flexibility.
Order a Helium Development Kit and get started today!