Friday, August 15, 2014

API Endpoints for Arduinos

As part of my home automation system, I need to connect "high-level" systems (such as the primary Linux server) down into the underlying hardware systems around the house. The PIC16F688 microcontrollers that run those systems are seriously low-level. Thus, I've chosen to place all of them onto an I2C bus(*) driven by an Arduino. Why? ... the Arduino has enough capability to mount an Ethernet port on the "high" side, and has built-in I2C support for the "low" side. It is a great mapping device between the complex systems, and the hardware systems.

With the hardware selected, and the wiring selected, it came down to protocol. How can that Linux server talk to the Arduino, as a proxy to the individual microcontroller critters splattered across the household? ... Naturally, HTTP was my first choice, as it allows all kinds of languages, libraries, and scripts to perform the work, and even some basic interaction via a full-on browser.

Digging into HTTP servers for the Arduino... Ugh. The landscape is very disappointing. Much of the code is poorly engineered, or the code is designed for serving web pages. During my search, I ran into a colleague's TinyWebServer. I'd call it the best out there for web serving (well-designed and well-coded), but is still overpowered for my purpose: mapping a protocol down to simple hardware interactions.

As a result, I designed a small library to construct a simple API endpoint on the Arduino. The application can register dozens of endpoints to process different types of client requests (62 endpoints are easy, more if you want to seek out the critical edges of allowed-characters in URIs). Each endpoint can accept a number of bytes as parameters, and can return zero, or an unlimited set of bytes to the client.

I have yet to "package" the Endpoint system, so any requests and changes are most welcome! I've got some documentation to write, along with incorporating feedback from others' and my own usage.

Would love to get some feedback! ==>

(*) and yes, I know an I2C bus is designed for 0.5m meter runs, rather than a whole house; bus accelerators, speed compensation, and other approaches "should" manage it. I'll report on my success/failure in a future post.


ovidiu said...

Very cool stuff!

I'm currently building some hardware control system, and the Arduino seems a bit underpowered. For this project I decided to try out BeagleBone Black, which has a full Linux stack running on. I'm able to write code in Python to control various GPIOs, and everything is accessible over a web server using Tornado.

Scott Johnson said...

I think if you look at the simplicity of programming model that an arduino offers as well as the cheapness that an arduino min pro (reportedly $2.50 each on ebay) and then the performance predictability that a microcontroller offers, I think this is a great plan. Not so sure about using i2c at the house level (I'd think more in terms of a polling or push architecture where each device is regularly sending status over http to a local central server).

Haven't had the time yet to look at your http work but I'd be certain that its solid.