Monday, September 3, 2012

Quick diversion: how to use ngx-queue

In my last blog post, I noted that I was working on Reflecta which is a communications protocol for talking from a PC to an Arduino.  I also alluded to the fact that I was using Reflecta from nodejs.  When I controlled RocketBot during Maker Faire, the logic was half Arduino and half C#.  A Windows app was running on a netbook receiving input from an XBox controller and the Arduino, making decisions, and sending commands down to the Arduino.  Since then I've been rewriting this logic in Javascript on the nodejs platform principally so I can move my control app from a netbook to low power computer such as a BeagleBone, Raspberry Pi, or Nexus 7 tablet.  Nodejs is a great choice because it's a functional/reactive programming environment that suites robotics well and it is small, efficient, and portable.

Nodejs is a combination of a few different technologies.  At its core is the V8 Javascript engine supplemented by a series of libraries written in C/C++ which access OS APIs such as sockets, filesystems, etc. to give you the power to talk to hardware directly and escape the javascript sandbox.  The C/C++ libraries are written in a style similar to what you see in other high reliability OS development which means no exceptions, no class hierarchies, and a lot of 'Use the Source, Luke'.

Lately I've been hammering on Reflecta, working out bugs and ensuring I have rock solid communications between the host and the Arduino.  One issue I recently ran into is when nodejs talks to the Serial Port (AKA Arduino) via the node-serialport library, occasionally it will send the data out of order.  Fixing this required me to learn the details of how nodejs buffers data for asynchronous, in order sending.  Nodejs leverages part of the nginx source code for handling queues of data in this case -- coded up in ngx-queue.h.  ngx-queue.h is a little strange compared to other queues in that you don't 'add your data to the queue entry'.  Instead you create a struct containing your data and the queue entry and then add the struct's queue entry to the queue.  This is an effective way to make a 'generic' or 'templated' queuing API using simple pointer logic.

Since it took me a few hours to figure out from the source code and example usages inside of nodejs, I figured someone else might benefit from the sample I created while learning so I created a Github Gist of it.  To compile, you'll need nodejs, npm, and node-gyp installed since that is the C++ build environment the sample uses.  Run 'node-gyp configure' and 'node-gyp build' to compile.