Computing stuff tied to the physical world

Archive for February 2010

A real-time status GUI

In Software on Feb 28, 2010 at 00:01

One more post about setting up a GUI with JeeMon…

I wanted to have a basic real-time display of all the readings coming in, sorted by source. Like this:

Screen shot 2010-02-25 at 15.48.08.png

(the size of this screen shot was reduced to fit this post)

Everything in this window is dynamic: rows get added when new sources start reporting their data, and columns get added when new parameter types are reported. I’m not storing any information persistently yet, which is why this status window looks as follows right after starting up JeeMon:

Screen shot 2010-02-23 at 21.31.15.png

Not very exciting, but all you have to do is wait …

Let’s see what it took to create this GUI. First, I added a generic “Notifier” rig to JeeMon, and a “Reading” method for all sketches to use. The rooms sketch, for example, now reports its incoming results as follows:

Screen shot 2010-02-23 at 22.06.04.png

Similar changes were made to the ookRelay and RF12demo “host.tcl” sources.

The rest of the GUI code is in “statusWindow.tcl”:

Screen shot 2010-02-24 at 01.16.42.png

The tabular display is based on a very nice Tcl/Tk open source package called Tablelist by Csaba Nemethi, which has been added to the JeeMon core library.

The coupling with the rest of the system is accomplished by the “Notifier attach readings * …” call at the end of the setup code. This registers a callback which will be invoked when anything in the “readings” notification group changes. Notifiers are going to be used a lot in JeeMon because they provide such a manageable way to glue independent parts of an application together.

And lastly, adding the following line to the main application starts the ball rolling:

Screen shot 2010-02-23 at 21.42.16.png

There’s quite a bit going on here which I won’t go into. I just wanted to illustrate how little code it takes to create a basic, fully dynamic, cross-platform, self-updating status display window. There – how’s that for adjectives!

Voltmeter with GUI

In Software on Feb 27, 2010 at 00:01

Let’s make a 5-digit voltmeter with a JeeNode, an Analog plug, and JeeMon. But instead of a readout on an LCD screen, I’m going to show the results on the desktop. To start with that last part, here’s my little display on a Mac:

Screen shot 2010-02-23 at 20.23.25.png

You’re looking at my feeble attempt to create a good-looking / souped-up GUI, btw :)

Anyway. Here’s the sketch I’m running on the JeeNode, with an Analog plug inserted into port 3:

Screen shot 2010-02-23 at 11.01.16.png

Trivial stuff. It sends out lines with “VOLT <value>” readings twice per second.

The important part is that this sketch starts up with “[analogPlug]” as greeting. To hook up to this sketch, all we need to do is create a directory called “analogPlug”, with a file called “host.tcl” in it.

This new “analogPlug” directory is a sub-directory of “JeeMon-sketches”. This directory, in turn, has been registered as being used for sketches – with this command in my main application code:

Screen shot 2010-02-23 at 12.21.51.png

Back to the “JeeMon-sketches/analogPlug/host.tcl” file. Here’s its contents:

Screen shot 2010-02-23 at 11.40.34.png

That’s the whole kaboodle.

Now, whenever I plug in a JeeNode running the above “analogPlug.pde” sketch, a window pops up showing readings in real-time. When I unplug the JeeNode, the window is closed again. It’s all automatic, as long as JeeMon is kept running.

This mechanism is not limited to JeeNodes or Analog plugs, of course.

OOK remote control

In Software on Feb 26, 2010 at 00:01

The JeeMon story continues. Here’s a fun little panel for controlling some switches around the house:

Screen shot 2010-02-22 at 21.42.14.png Screen shot 2010-02-22 at 23.31.35.png

Screen shot 2010-02-23 at 20.19.28.png Screen shot 2010-02-22 at 21.51.23.png

These screen shots show Windows (7 and 2K), Mac OS X, and Linux Ubuntu, respectively – long live diversity!

This GUI was created with these configuration settings:

Screen shot 2010-02-26 at 02.09.33.png

Those settings were loaded by adding this line to the main application code:

Screen shot 2010-02-26 at 02.09.16.png

Which in turn loaded the following “ookRemote.tcl” source file I wrote, as module / rig:

Screen shot 2010-02-26 at 02.08.48.png

That’s the entire app. Adding lipstick (i.e. a fancier visual design) is left as exercise for the reader.

Note how the design is split in a configuration section and a source code file – I’m probably going to use this approach often in JeeMon. The idea is that people who don’t care about the code behind all this stuff can just adjust the configuration file (using a visual interface, hopefully, one day). While those who like to tinker can view the full source code, and explore and extend it at will, and more importantly: ad infinitum.

It’s called open source for a reason!

PS. There’s another major reason for the split between configuration settings and source code files: turnkey deployment. You can put all the source code files in a ZIP archive called “JeeMon-rigs.zip”, so that all you need for a new installation with JeeMon, is: 1) your archive, 2) the proper JeeMon runtime, and 3) a config file to match the target setup. The config file is optional, btw – more on that another time…

Output and Expander plug fixes

In Software on Feb 25, 2010 at 00:01

While testing an Output Plug, I found a little mess-up: the documentation pinout is wrong, all even and odd I/O pins on the 2×6 output connector were swapped. Here is the correct pinout:

op1-pinout.png

I’ve updated the documentation.

The “expander” sketch is also very confusing, it was still for the PCA8574A, whereas the current Expander Plug uses an MCP23008.

Here’s an improved sketch, with a little running-light demo:

Screen shot 2010-02-22 at 12.38.18.png

This code has been checked in to replace the “expander.pde” sketch in the Ports examples.

Fabrications

In Hardware on Feb 24, 2010 at 00:01

Several hours of work, and this sort of stuff is born… 16 new JeeNode USB’s:

DSC_1203.jpg

It looks pretty, but I’m not going to show you the high resolution picture… even on this one you can probably spot one or two problems :)

The fact is that hand-assembly of SMD takes a lot of patience. By now, I think it’s absolutely doable for one-offs, such as to assemble one board with some parts. But larger quantities do tend to bring out the trouble spots.

Usually, on a run this size, I’ll expect to see 3 or 4 boards not working right away, and ending up with perhaps one board which I can’t fix quickly. I’ve got a box with a bunch of units by now, which don’t seem to want to be cured. Oh well, their loss – that means they get to wither away in a dark box, waiting for better times :)

Secure transmissions

In Software on Feb 23, 2010 at 00:01

For some time, I’ve been thinking about adding optional encryption to the RF12 wireless driver. I’ll leave it to the cryptography experts to give hard guarantees about the resulting security of such a system…

The basic goal is to provide a mechanism which lets me get messages across with a high level of confidence that an outsider cannot successfully do the same.

The main weakness which most home automation systems such as FS20 and KAKU completely fail to address is message replay. The “house code” used by FS20 has 16 bits and the address has 8 bits, with the naive conclusion being that it takes millions of attempts to send out messages to which my devices respond. Unfortunately, that’s a huge fallacy: all you have to do is sit outside the house for a while, eaves-dropping on the radio packets, and once you’ve got them, you’ve figured out the house code(s) and adresses in use…

I don’t care too much about people picking up signals which turn the lights on or close the curtains. You don’t need technology to see those events from outside the house anyway. I do care about controlling more important things, such as a server or a door opener.

Here are my design choices for optional encryption in the RF12 driver:

  • The cipher used is David Wheeler’s XXTEA, which takes under 2 Kb of code.
  • The keys are 128 bits, they have to be stored in EEPROM on all nodes involved.
  • All nodes in the same net group will use either no encryption or a shared encryption key.
  • A sequence number of 6, 14, 22, or 30 bits is added to each packet.

To start with the latter: XXTEA requires padding of packets to a multiple of 4 bytes. What I’ve done is add the sequence number at the end, using as many bytes as needed to pad to the proper length, with 2 bits to indicate the sequence number size. Encrypted packets must be 4..62 bytes long. It’s up to the sender to decide what size packets to send out, and implicitly how many bits of the sequence number to include. Each new transmission bumps the sequence number.

To enable encryption, call the new rf12_encrypt() function with a pointer to the 16-byte key (in EEPROM):

Screen shot 2010-02-21 at 18.37.36.png

Encryption will then be transparently applied to both sending and receiving sides. This mechanism also works in combination with the easy transmission functions. To disable encryption, pass a null pointer instead.

The received sequence number is available as a new “rf12_seq” global variable. It is up to the receiver (or in the case of acks: the originator) to ascertain that the sequence number is in the proper range. Bogus transmissions will decrypt to an inappropriate sequence number. To make absolutely certain that the packet is from a trusted source, include some known / fixed bytes – these will only be correct if the proper encryption key was used.

This new functionality has been implemented in such a way that the extra code is only included in your sketch if you actually have a call to rf12_encrypt(). Without it, the RF12 driver still adds less than 3 Kb overhead.

I’ve added two sample sketches called “crypSend” and “crypRecv” to the RF12 library. The test code sends packets with 4..14 bytes of data, containing “ABC 0123456789” (truncated to the proper length). The receiving end alternates between receiving in encrypted mode for 10 packets, then plaintext for another 10, etc:

Screen shot 2010-02-21 at 22.42.27.png

As expected, the encrypted packets look like gibberish and are always padded to multiples of 4 bytes. Note also that the received sequence number is only 6 bits on every 4th packet, when the packet size allows for only one byte padding. The strongest protection against replay attacks will be obtained by sending packets which are precisely a multiple of 4 bytes (with a 30-bit sequence number included in the 4 bytes added for padding).

So this should provide a fair amount of protection for scenarios that need it. Onwards!

Declarative configuration

In Software on Feb 22, 2010 at 00:01

Things are starting to come together quite nicely with JeeMon – all in less than 1000 lines of Tcl code so far. That’s not to say that it’s perfect yet – I’m still massively rearranging some of these code structures – but there is already some functionality to play with, which helps expose the strengths and weaknesses so far.

The basic approach is declarative in nature: specifying what should happen, but not necessarily in the same place as when or how all the work should be done.

Here’s my first tentative configuration file:

Screen shot 2010-02-21 at 14.31.44.png

For each serial interface, an action is specified when that interface comes on-line. For example I can now plug in my A8007Up6 device (a USB-BUB with a JeeNode) and JeeMon will open a terminal window showing the output stream. Unplugging closes the window again (and automatically cleans everything up).

Right now, I’m editing this config file by hand, but at some point that could be augmented with a set of GUI or web-based configuration panels (even remotely).

There are a lot of challenges ahead. One of them is decoupling things so that code and data end up organized in the most convenient, logical, and flexible way. I’m trying very hard to avoid any calls to the “Config” module from generic JeeMon code. This allows you to set up the configuration file structure and hierarchy in any way you like.

My application file currently looks as follows:

Screen shot 2010-02-21 at 15.42.58.png

As you can see, I’m setting up a periodic port scanner and supplying a “SerialEvent” callback to decide what to do when serial ports get added or removed. In those decisions, most of the logic is driven from the “config.txt” configuration file. I’m about to implement a similar callback for radio events, i.e. RF12 nodes coming online and dropping off again.

In a way, the above two files are the entire application.

The rest is utility code to make the above convenient and concise. That rest might well be 99% of the code, but it’s all structured as loosely-coupled “rigs” (modules), which can be used / overridden / ignored at will.

The way I see it, there can be three sources for such utility code: your own code, plug-ins from others, and a couple of rigs included in the JeeMon core itself. The above two files require just the core, using the built-in rigs (Config, Gui, JeeSketch, Log, Serial, and SysDep).

Serial USB devices

In Software on Feb 21, 2010 at 00:01

For JeeMon, I’d like to be able to auto-detect USB device insertions and to identify FTDI serial numbers (with names like “FTE54GKC” and “A9007CNE”).

Cross-platform… i.e. on Windows, Mac, and Linux!

It looks like it can be done.

On Windows, we can browse the good ol’ registry, as follows:

Screen shot 2010-02-20 at 15.24.16.png

Sample output:

Screen shot 2010-02-20 at 15.24.41.png

This was tested on Win2000 and Windows 7, in the hope that everything in between works the same.

On Mac OS X, it’s easiest (for a change):

Screen shot 2010-02-20 at 15.26.02.png

Sample output:

Screen shot 2010-02-20 at 15.26.37.png

On Linux, it’s a bit messy because there are so many different distributions:

Screen shot 2010-02-20 at 15.27.43.png

Sample output:

Screen shot 2010-02-20 at 15.28.01.png

Tested on Debian 5 (Lenny), Ubuntu 9.10 (Karmic), and Gentoo.

The above code can be found in the subversion repository, i.e. here.

I’m testing this all at once on a single machine btw, courtesy of VMware Fusion. And using JeeMon’s built-in self-update mechanism to quickly get new versions across while debugging and tweaking things.

By calling “SysDep listSerialPorts” periodically, we can automatically detect a change and see which plug was inserted (FTDI only for now). Without depending on any external libs or executables.

Onwards!

RF transport independence

In Software on Feb 20, 2010 at 00:01

With the basic serial interface access and dispatch in place in JeeMon, it’s time to move on to JeeNode / JeeLink packet processing.

What I want is to be able to forget all about how readings got to JeeMon. It shouldn’t make a difference whether I’m using a directly connected Room Node and grabbing the readings off its serial USB connection, or whether they came in through the air via the RF12 wireless driver – or by any other means. Take a snapshot with your cell phone, send the picture to EverNote, have it OCR’d, and then grab the readings off the web … whatever!

The way I’ve tied this into JeeMon, is to let the interface to RF12DEMO act as de-multiplexer. This is purely a decision at the RF12DEMO listener level. Each incoming packet is examined to determine which node it came from. Then we need a way to map from nodes to listener class – i.e. find out what sketch is running on the remote node. This is hard-coded for now:

Screen shot 2010-02-18 at 22.57.41.png

What this does is actually a bit more elaborate: a RF12DEMO listener will set up and manage a bunch of extra “RF12_PacketStream” listeners, one for each node. When packets come in, they will simply be dispatched to the corresponding stream. Each packet stream can process its packets in a different way.

The fun part is that these packet streams can use the same listener classes as with direct serial interfaces. All they need is an extra “decode_RF12” method:

Screen shot 2010-02-18 at 23.02.04.png

The task of decode_RF12 is to re-cast the incoming packet as messages of the same structure as what would come in over a serial connection.

Here’s the “rooms” listener as example:

Screen shot 2010-02-18 at 23.04.34.png

This one class encapsulates all the protocol details of room nodes, both serial and via RF12. When a 4-byte data packet comes in via RF12 (as $a..$d), the bits are decoded and an “onMessage” call is generated with a “ROOM” message id and the 5 decoded readings.

Here is a log of this code in action, one message per line:

Screen shot 2010-02-18 at 22.37.15.png

The way to read these messages is as key-value pairs, i.e. id = OK, type = RF12, name = usb-A900ad5m, etc.

The first two lines show an incoming OK message from node 21 (53=21+32), which is then turned into a ROOM message, tagged as coming from the “rf12-868.5.23” packet listener.

The next 3 lines are more involved: first an EM10 message came in over USB, then an OK message came in which got dispatched again, as the same EM10 message. That’s because I’m running JeeMon with a direct connection to the ookRelay board, even though it transmits all its information over RF12. So everything from the ookRelay comes in twice (great for debugging).

The point is that the two EM10 messages have the same info. It no longer matters how the message got here (but it is traceable, using the remaining details). And all the code to accomplish this is in a single source file, right next to the sketch running on the ookRelay board.

This design makes it possible to develop an application using only the serial USB connection, and then later add logic to send the information via RF12 (or not). Infrared, XBee, Twitter, anything: transport independence!

Note that nothing is done with these decoded messages at this stage. This messaging framework is independent of higher-level application decisions, such as where to store / send / show msgs, or even when to process them.

Serial port encapsulation

In Software on Feb 19, 2010 at 00:01

This post continues to look a bit into the new JeeMon design.

Let’s focus on serial interfaces first, mostly USB. There’s a “Serial” module which does all the basics. On the Mac, if I want to open device /dev/tty.usbserial-A900ad5l, then the following call with do everything:

Serial connect usb-A900ad5l 57600
The name of the device would be different on Windows and Linux (COM5, or USB1), but that’s all.

By default, this creates a new Serial object, which logs all incoming text to stdout. To send a command out, we need to keep a handle to this object:

set conn [Serial connect usb-A900ad5l 57600]
$conn send "some text"
Nice, but not very exciting…

Let’s take it one step further. The “JeeSketch” module does the automation described in the previous post, i.e. detect the running sketch, associate it with a class, instantiate an object for it, and call the methods of that object whenever text lines come in over that serial port. Here’s a complete JeeMon custom “application.tcl” program:

Screen shot 2010-02-18 at 14.44.59.png

First, all the sketch drivers are made available with one or more “register” calls. This lets the appropriate classes take over for each new serial connection – depending on what sketch is running. That’s all it takes. Servicing such serial ports now becomes an event-driven background activity.

The listeners are defined in separate files, one for each type of sketch:

Screen shot 2010-02-18 at 15.05.58.png

The ookRelay/host.tcl file looks like this, for example:

Screen shot 2010-02-18 at 14.51.58.png

This structure makes it easy to manage stuff that belongs together. Projects can be exchanged (or archived, or revision-controlled), with all the pieces needed to use them in one place. And as far as I’m concerned, it won’t be limited to JeeNodes etc, or Tcl, or a specific platform. This has to remain general enough to hook up to any hardware and use with any language (via networking, files, and direct launching of executables/scripts). My goal for JeeMon is not to limit anyone’s options, but to create a simple switchboard between whatever is needed.

(I’m still mucking around with the organization and naming of code and files, as you can see)

Nice, but still not very practical…

The problem with the above is that it doesn’t deal with devices getting plugged in or unplugged. Well, unplugging is the easy bit – the above code will automatically clean up after itself on connection loss, so that part is covered.

Wouldn’t it be nice if we could just plug in new devices and get them to automatically start doing something?

I implemented such a mechanism in a recent revision of the code, but I’m hesitant to add it again – because it was Mac OS X specific, where USB devices connected via the FTDI driver include a unique code. On Windows and Linux, you just get COM<n> and USB<n> devices, where “n” seems to be related to the order and number of device insertions.

I haven’t looked into “libusb” yet. Should I? Will it help for Windows too? Do I need to start learning about USB enumeration? What OSS-compatible tools and libs are there?

Update – on Linux, it looks like /sys/bus/usb/devices/* has all the info needed to identify USB devices. So that only leaves Windows – good: at most one lib or dll to deal with.

In the kitchen

In Software on Feb 18, 2010 at 00:01

Ok, so maybe it’s time to start describing some of the new stuff cooking in the kitchen lab.

I’ve been exploring software designs to use as basis for JeeMon, that new switchboard-type application for physical computing devices. The idea is to treat the system as one big message-passing machine – a bit like Message-Oriented-Middleware (MOM), which has been around for ages, but without getting sucked into any heavy-weight conventions.

Messages can be passed around, queued, stored, duplicated, filtered, transmitted, returned, ignored, sorted, etc. After all, living organisms do nothing but send chemical messages around, so why not do the same for an infra-structure focused on physical computing (sensors, displays, actuators) and home automation?

If you’ve been following this weblog for a while, you’ll have noticed that almost all the output I generate in sketches is of the form “identifier arg1 arg2 …”. So for example, packets received by RF12demo look like:

OK 61 9 2 8 79 243 87 13 0 15 0
A barometric reading from the BMP085 sensor on the pressure plug may get reported as:
BMP 233 10019
And so on. One or more upper case letters, optionally followed by digits. Then the payload (which may also include floating point and string values, not just ints).

Another convention I’ve been sticking with is to report the name of the sketch on the serial port during startup:

[ookRelay]
Or an identifier plus the current configuration settings:
[RF12DEMO] W i23 g5 @ 868 MHz
These two conventions can be used for an object-oriented design. With a bit of preparation, the name of such sketches can be automatically associated with a class, and each line treated as a method call.

Here’s the skeleton of the first level of code I use for decoding RF12demo.pde output:

Screen shot 2010-02-16 at 00.15.27.png

Another class definition, for the ookRelay.pde sketch:

Screen shot 2010-02-16 at 00.16.11.png

Or to put it differently: with JeeMon running, you can hook up a device (JeeLink, JeeNode, Arduino, etc) containing some sketch and the matching class will automatically be associated with that serial port, once the sketch has been identified. A new object is then created, and its methods will be called whenever the device sends new output (messages?) over the serial line.

Simple!

What I would like to do, is manage the sketch (C/C++) and the class (Tcl) together, perhaps as two files in a common development directory for that project. That way the interface between the two pieces of hardware essentially vanishes into the background. The point being that each class can then do all sorts of things, such as storing results in a database, sending it to another system over the network, updating web server pages, popping up a GUI window to show incoming data in real-time, etc.

This mechanism is very simple, even under the hood. This matters, because it has to work even when JeeMon is running on low-end embedded Linux hardware. But at the same time, such a MOM + OO design will allow considerable flexibility for abstract / high-end use later.

PS. If you’re familiar with Tcl, you might be surprised to see all this “oo” stuff in here. That’s because JeeMon uses Tcl 8.6 with built-in object system. Multiple inheritance, mixins, filters, dynamic class change support, delegation, prototypes / per-object methods, it’s all in there. I’m also using ensembles and there’s an interesting coroutine-based web server waiting in the wings (called wibble).

For the record: nothing ever gets added just to be buzz-word compliant. If a feature simplifies application-level concepts and leads to a cleaner implementation in JeeMon, it’ll be used, else I’ll pass. Life’s too short to jump on bandwagons.

New Dimmer Plug

In Hardware on Feb 17, 2010 at 00:01

One last plug… who knows, with a bit of luck, some of them might just work on first try?

The Dimmer Plug controls up to 16 LEDs or other lamps, and is based on the PCA9635 chip:

Screen shot 2010-02-16 at 21.29.21.png

It’s driven from the I2C bus, with a couple of jumpers to allow daisy-chaining up to 8 plugs on a single port:

Screen shot 2010-02-16 at 21.46.19.png

Here’s an extract of the datasheet, showing the different ways to hook up LEDs:

Screen shot 2010-02-16 at 02.04.23.png

Basically, you can drive one LED directly per pin, or add a transistor to drive many more in parallel or in series. The chip just does the PWM part, with various blinking options and more, all from an I2C bus.

To drive high-power displays, the outputs can be tied to darlington arrays such as the ULN2803, or to MOSFETs. There are no drivers on the plug because there are too many different usage scenarios. It all depends!

Originally, I wanted to make this plug also fit on a the back of a display such as this one:

DSC_1205.jpg

That pressure plug on the photo was added for size comparison. It’s the same size as this Dimmer Plug, which happens to allow daisy-chaining two such displays tightly next to each other when you include the headers.

But I can’t make it fit without widening the plug and mounting components on both sides. So I’ll leave it as is – it could still be mounted on the back by adding lots of little wires and 16 resistors, but it will take some more work. Or one could add a little board to sit in between, with 16 resistors and pins to stick into the 3×6 headers.

Now I’ll stop with this plug madness. Need to finalize all the layouts and traces, send the designs off, and then the waiting starts. Luckily, there’s still enough other stuff left to do around here :)

Update – there are some errors in the schematic. I’ll fix them before sending off this board.

New Input Plug

In Hardware on Feb 16, 2010 at 00:01

The plug rage continues. Sixteen inputs, analog and digital in any mix:

Screen shot 2010-02-15 at 12.58.04.png

I haven’t routed the connections yet so the layout and dimensions might still need to change.

This plug is an experiment. It does not use I2C, so it will need a dedicated port. The trick is that an on-board ATTiny45 is used to decode a pulse train of four pin selection bits from just the DIO pin.

Here’s the schematic:

Screen shot 2010-02-15 at 13.08.55.png

The 16 inputs are multiplexed into the AIO pin. By defining this as an analog input, you can have up to 16 analog pins, using the 10-bit ADC built into the ATmega. But defining AIO as a digital input, you can use it as a digital pin. Even works with pull-up, but the pull-up will only be active as long as the same input remains selected. Unselected inputs return to a high-impedance state.

Needs some more work though, including some firmware for the ATtiny.

New Proximity Plug

In Hardware on Feb 15, 2010 at 00:01

Yet another plug! This time it’s a proximity capacitive sensor based on the MPR084:

Screen shot 2010-02-14 at 22.01.08.png

This one has 8 inputs which can be connected to various surfaces to create capacitive touch sensors. There’s also a pin for a piezo sound unit to produce key clicks.

Slightly more elaborate schematic this time, with an extra 8-resistor array for pull-up:

Screen shot 2010-02-14 at 12.05.27.png

Yet again: connected via I2C, and supports no more than 3.6V as power source. There’s a solder jumper to choose between two I2C addresses, so you can use two of these for a total of 16 inputs on one port (or Plug Shield).

Haven’t tried this chip out yet, but it will be fun to see what it can do – once I get some prototype boards ready.

New Gravity Plug

In Hardware on Feb 14, 2010 at 00:01

Another plug coming up – based on the BMA020? 3-axis accelerometer:

Screen shot 2010-02-12 at 23.07.28.png

Again an awfully tiny chip, with even smaller pads. This chip has a programmable ±2g/4g/8g range with 10 bit resolution. As with yesterday’s plug, this chip communicates over I2C and supports up to 3.6V.

The schematic is obviously very simple again:

Screen shot 2010-02-12 at 23.07.59.png

The Gravity Plug will also work with an Arduino, through the Plug Shield.

It’ll take at least a few weeks before I can test these new plugs and make them available.

Onwards!

New Lux Plug

In Hardware on Feb 13, 2010 at 00:01

There’s a new plug in the works, with a really neat TSL2561 light sensor:

Screen shot 2010-02-12 at 21.06.49.png

The chip is even smaller than what I’ve been working with until now. The nice thing about the TSL2561 is that it has six orders of magnitude dynamic range and that it’s interfaced via I2C.

The JeePlug port headers are in fact perfect for sensor chips like these, which often only tolerate up to 3.6V:

Screen shot 2010-02-12 at 21.08.28.png

The Lux Plug will also work with an Arduino, through the Plug Shield.

Stay tuned. There’s more coming…

Improved bracket

In Hardware on Feb 12, 2010 at 00:01

Encouraged by some comments on yesterday’s post, I printed the same bracket again, laying on its side:

DSC_1188.jpg

The horizontal base comes out ok (I cleaned up the hole):

DSC_1189.jpg

Interestingly, the top of the bracket isn’t filled in, which is actually better:

DSC_1190.jpg

The sides look much better as well:

DSC_1191.jpg

(the Skeinforge settings aren’t perfect yet, layers could be mashed smoother together)

But wow – what a difference this makes! Thanks for the tip!

Here’s another object, a Geneva Wheel from Thingiverse:

DSC_1192.jpg

Turning is not very smooth, had to cut off some plastic from the round shafts, but hey: it works!

PS. Don’t worry, I’m working most of my time on JeeNode stuff, hardware and software that is… ;)

JeeNode bracket experiment

In Hardware on Feb 11, 2010 at 00:01

I just had to try making a little mounting bracket for JeeNodes…

Here’s the design:

Screen shot 2010-02-08 at 11.13.51.png

The design dimensions are 25 x 12 x 10.5 mm. It was created with OpenSCAD, which takes a description of the object and generates the solid model shown above:

Screen shot 2010-02-08 at 11.14.06.png

Does it work? Can it be printed? Can it be used? Yeah, sort of…

DSC_1180.jpg

Works for JeePlugs too, since all the boards have the same 21.1 mm width:

DSC_1182.jpg

Took me three tries to get the sizes and the little ridge right (the middle one):

DSC_1179.jpg

Pretty ugly stuff, when seen up close. But hey, that’s what pioneering looks like!

The ridge which holds the board doesn’t come out very clearly – the features are not yet a match for what the JeeCake 3D printer can do (or should it be the other way around?):

DSC_1181.jpg

But despite appearances, this bracket is already surprisingly functional. Apart from the awful surface and rough shape, it’s a springy and very robust little piece of ABS plastic. It could easily be screwed down, and it would hold the board quite well.

Fascinating, it’ll be fun to see how this evolves over the next few years.

Wireless works, sort of…

In Software on Feb 10, 2010 at 00:01

Ah, now we’re getting somewhere!

This is my current test setup:

Screen shot 2010-02-07 at 21.23.55.png

The JeeNode on the printer side implements a packet pass-through system, receiving command packets from the JeeLink and sending back response packets. Here is the sketch which does all the work:

Screen shot 2010-02-08 at 01.02.16.png

On the Mac/PC side, some Tcl code was added to go through the RF12demo text-mode protocol to send and receive arbitrary data, using the “a” command. Still work in progress, but the basic transport encapsulation works.

The tricky part is timing … it always is with this sort of real-time control stuff. Unfortunately, the current G3 software on the CupCake isn’t quite as responsive as defined in the specs. Some responses take way over 80 milliseconds to come back from the motherboard. This is the case when scanning the SD card, as well as when stopping the extruder motor.

So what this sketch does is wait up to 500 ms for a reply to come in. Even if there isn’t one, an acknowledgement packet will be sent back. The new code on the Mac in turn waits up to 1 second for that ack to come back.

If no ack came back, then there was an error in the wireless connection (this can happen either during the request or during the ack, there is no way to tell!). Probably best thing to do would be to resend the command.

If an empty ack came back, then the response packet did not arrive within 500 ms. In this case, we could send an empty command and wait for its ack. This hasn’t been implemented yet, but it will allow dealing with even the slowest responses, simply by polling a few more times with an “empty command”.

But hey – it works, and the output is the same as before:

Screen shot 2010-02-07 at 21.26.39.png

This is probably the first wirelessly controllable CupCake in the world :)

What I should mention though is that this doesn’t yet work reliably due to those very loose timing behaviors and the fact that packet errors are not yet dealt with. Test runs fail occasionally – mostly in the SD card access code, i.e. while grabbing all the filenames with NEXT_FILENAME.

Connecting to a CupCake

In Software on Feb 9, 2010 at 00:01

To follow up on yesterday’s post, I wrote some test code to request the extruder nozzle temperature from the JeeCake and send the results out over wireless. Here is the full “jeeStatus.pde” sketch:

Screen shot 2010-02-07 at 16.19.43.png

And sure enough, it works:

Screen shot 2010-02-07 at 16.08.55.png

You’re seeing the nozzle cool down, after heating it up via ReplicatorG. The connected JeeNode has been given node ID 19, and it’s transmitting in group 5 of the 868 MHz band, so I can simply track these incoming packets through the JeeLink which is already collecting all sorts of data anyway.

So much for the easy part – the real software will be more work!

Wireless CupCake

In Hardware on Feb 8, 2010 at 00:01

JeeCake, the CupCake 3D printer here, is an interesting mix of machine, electronics, and software.

The RepRap Motherboard is the main on-board controller, based on an ATmega644. It drives 3 stepper motors, communicates with the Extruder board, and talks to a desktop computer via its FTDI interface and a USB cable.

On the PC side (which can be Windows, Mac, or Linux), there is a Processing-/Arduino-like package called ReplicatorG to control the machine. It takes G-code, which is not related to Google in any way, but rather an ancient CNC control language from the 60’s.

ReplicatorG then converts this to a binary RepRap 3G protocol, as documented here and then uses that to drive the CupCake. Everything from moving the axes, adjusting the nozzle temperature, controlling the extruder motor, to writing settings in the machine’s EEPROM memory.

The neat part is that the v1.2 motherboard has an SD card adapter on board, and that the CupCake can run unattended by getting its detailed build instructions from files stored on an SD card.

Except for one little detail: there are no controls or displays on the CupCake, other than a few LEDs. This is not enough to select which file to print, adjust the zero position, or start a build. It looks like a new “Generation 4” design is on the way, including an interface board with an LCD screen and some push buttons.

Right now, you have to connect the machine via USB, start everything up via ReplicatorG, and then you can yank the USB plug and it’ll happily continue printing what it started, right to the end (well, except that on Mac OS X 10.6, yanking USB cables can lead to kernel panics – looks like a serious bug in the FTDI USB driver).

Anyway, I don’t really care for controls, or even displays on the CupCake. All I want is some way to control a unit sitting on the other side of the room, or in a nearby room. It can be fairly noisy due to some sort of occasional wood panel resonance, and having it printing right next to me is not really my idea of fun.

Which is where JeeNodes come in: wouldn’t it be nice to be able to control the CupCake via wireless? The protocol is already perfectly suited for it, since it uses packets of max 32 bytes – well within the 66-byte limit of the RF12 driver. And if the object being printed is already on the SD card, then only a few packets need to be exchanged to get going. During printing, some status info could be sent back – again very low rate stuff, easily within the JeeNode’s wireless constraints.

Here’s the idea:

DSC_1177.jpg

Hook up a JeeNode to take the place of the USB cable, and let it behave as a RecpicatorG control program.

The interface needs to swap RX and TX for this, and because the CupCake’s signal levels are at 5V, two 1 kΩ resistors need to be inserted to prevent excessive current. One more detail is that the power pin on the FTDI connector is not connected, since the motherboard is powered off its own PC supply. So a separate wire needs to be added to power the JeeNode off the ISP connector right under the FTDI connector:

DSC_1178.jpg

The one wire not shown here is the ground wire, running from top right to bottom left on the other side of this little custom interface board.

It turns out that the motherboard is actually powered from the 5V standby supply pin, so it’s always powered, even when the power supply is in standby mode.

I’ve started writing some code on the PC/Mac side to control the CupCake without using ReplicatorG. Here’s some sample code in Tcl which works when connected directly through USB:

Screen shot 2010-02-07 at 15.05.08.png

And here’s the corresponding output:

Screen shot 2010-02-07 at 15.04.35.png

As you can see, it can access all sorts of status info, read the file names on the SD card, and control the machine. This is part of a larger project, the beginnings of which are now in the subversion code repository.

It takes a lot of work to make hookups like these work, because there are so many different bits and pieces (literally) involved. The next step is to see if the JeeNode can indeed communicate with – and control – the JeeCake, and then code needs to be written to replace the current direct-USB connection by a packet-based wireless hookup through a JeeLink + JeeNode.

Oh, and then I need to create some sort of little on-screen control panel to adjust the nozzle temperature, jog the Z axis up and down, pick a file to print, and start the print job! Not to mention making it robust and secure…

Plug shield on Arduino Mega

In AVR, Hardware on Feb 7, 2010 at 00:01

The Plug Shield can also be used on an Arduino Mega:

DSC_1175.jpg

Note the two extra wire jumpers, since the I2C interface is on pins 20 and 21 on the Mega board.

The above has an RTC plug and an LCD plug hooked up, so let’s to set up a simple clock with this – and use it to demonstrate the brand-new RTClib along the way:

Screen shot 2010-02-05 at 17.22.01.png

I’ve omitted the details of the Wire coding, but you can get the full sketch here.

Custom object

In Hardware on Feb 6, 2010 at 00:01

This is not what you might think it is:

DSC_1169.jpg

I’ve been placing my headphone next to me on my desk for ages. There is of course never enough room on top, but plenty of spare room underneath:

DSC_1170.jpg

So here’s my home-made headphone bracket:

DSC_1172.jpg

Here’s the design, made with Sketchup:

Screen shot 2010-02-03 at 14.22.47.png

I just picked a “2” in a suitable font, re-sized it, “drilled” some holes in the base, and then “printed” it.

Piece of JeeCake!

PS. Given that CNC and 3D printing is not really the main focus of this weblog, I’ve set up a page on the wiki.

Update – design files added to Thingiverse.

New date / time / RTC library

In AVR, Software on Feb 5, 2010 at 00:01

Not so long ago, I had the opportunity to work a bit on something which has bugged me for a long time – the lack of date and time handling in connection with RTC chips. There are a few libraries out there, but I think I could do better – i.e. make it simpler, smaller, yet sufficiently powerful for real day-to-day use.

Seeing where this was going on the Arduino developer mailing list (and disagreeing with just about everything that happens over there), I decided to put my money time where my mouth is, and build my own library.

Here’s the header file of the new RTClib Arduino-compatible library:

Screen shot 2010-02-04 at 13.52.13.png

This lets you do date / time calculations, and it provides two different ways to implement a clock: via a hardware chip or using the built-in millis() timer.

RTClib has been checked into subversion, see the CODE page for details on how to get it.

It includes four example sketches:

  • datecalc illustrates how to do calculate with dates and times
  • ds1307 interfaces with a DS1307 RTC chip, connected via the Wire library
  • plugrtc interfaces with the RTC Plug, connected via the Ports library
  • softrtc demonstrates how to do the same with just software

One fun trick I added, inspired by a comment from Limor Fried, is to allow initializing a DateTime object from the DATE and TIME strings generated by the C compiler. That means you can run that “softrtc” sketch without hardware support, and it’ll automatically have its clock set to the compilation date of the sketch, i.e. fairly close to correct. Not good enough for general use, but great during quick debug cycles when you’re re-compiling your sketch all the time anyway.

Note that to use RTClib, you need to include the “Wire.h” library – even if you don’t use it!

The inability to properly deal with libraries, particularly in a resource-constrained embedded processor context, is one of the aspects of the current Arduino direction which irritates me – see an older post for more details.

Fascinating concurrency

In AVR, Software on Feb 4, 2010 at 00:01

There is a new language for the Arduino / JeeNode / ATmega328, called Occam-π.

I found out about it yesterday, at http://concurrency.cc/ – it’s high level, and it supports parallel programming. The current development environment release is for Mac OS X, with Windows and Linux coming soon.

Here is a complete program with 4 blinking LED’s, one on each DIO pin of the JeeNode ports:

Screen shot 2010-02-03 at 01.13.19.png

That’s it. Compiles to roughly 2 Kb. Each extra blink adds just 20 bytes, btw.

And yes, it really makes four LEDs blink at an independent rate:

DSC_1167.jpg

There is slightly more to it than that, but this is mind-blowing stuff. The “parallelism” is simulated, of course. Looks like the ATmega can do around 6000 context switches per second (i.e. parallel task switches).

There is a roughly 20 Kb interpreter part that needs to be uploaded once (which is why this requires at least an ATmega328). After that, the IDE will upload just the bytecode for your program, i.e. 2 Kb in the above case.

B R I L L I A N T .

Imagine hooking up the RF12 driver to this – there’s plenty of room for the extra 3 Kb or so. And for doing all sorts of things… in parallel! My earlier complaint post about how awful it is to do several things at once on an ATmega board might just have been wiped off the table.

Looks like I’ve got some very serious learning ahead of me to try and get to grips with all this.

JeeNode USB v2 error!

In Hardware on Feb 3, 2010 at 00:01

Yikes… there is a major bug in the current JeeNode USB v2 board!

The on-board MCP1703 3.3V has been connected with Vin and Vout reversed!

The effect is that the +3V pins on all the port headers will have approx. 4.7V instead of the intended 3.3V. This in turn means that all plugs connected to these headers will have a higher voltage than should be.

The on-board logic is not powered by this regulator but gets its power from the 3.3V pin on the FTDI chip, so the JeeNode USB v2 itself works just fine (my weak excuse for why I didn’t catch this problem earlier…).

Here is the schematic – with the problem staring me in the face, now that I know about it:

Screen shot 2010-02-02 at 13.51.39.png

Here are the printed circuit board traces:

Screen shot 2010-02-02 at 14.39.16.png

And here is the board with the voltage regulator connected the wrong way around, as it has been shipped until yesterday, i.e. Feb 1st 2010:

DSC_0737.jpg

If you have a faulty unit, there are a number of ways to fix this:

  1. Send it back and I’ll fix the voltage regulator for you.
  2. Remove the voltage regulator and add your own from a PWR pin to a +3V pin.
  3. Unsolder and re-solder the VR flipped, as described below.

To reiterate: this bug only affects plugs connected to the JeeNode USB, not the JeeNode USB itself. If you don’t use the ports, or don’t mind having a higher voltage on the +3V pins, then you could just ignore the issue.

Here’s how I’ve fixed this on existing JeeNode USB’s, including ones still in stock. First, I used solder wick to remove the regulator (careful not to lift the pads):

JU2 no VR.png

The next step is to mount the VR back on its side. The pins which need to be exchanged are:

MCP flip.png

One way to do this, is to turn the VR on its side and solder pins 1 and 2 back on pads 1 and 3:

DSC_1164.jpg

As last step, I added a thin wire from what used to be pad 2, to the pin now sticking out on top (was pad 3):

DSC_1162.jpg

As I said, I’ll be happy to do all this fixing for you if you send me your JeeNode USB v2.

It ain’t pretty (real bugs never are) – but it’ll at least let you continue to use the JeeNode USB v2 as intended.

All JeeNode USB v2’s shipped from now on will have this fix, until an improved “v3” is ready. As always, “new copper” (i.e. a new PCB) will take a few weeks – it’s at the top of my list to fix and resolve this for good.

With many thanks to castello for drawing my attention to this bug on the forum.

Room Board assembly

In Hardware on Feb 2, 2010 at 00:01

As announced recently, I’ve now added a full kit for the Room Board in the shop, containing:

  • The room board PCB.
  • SHT11 temperature + humidity sensor.
  • An LDR light sensor.
  • The ELV PIR motion sensor.
  • Two 6-pin male headers.

Here is the kit (oops, forgot the two 6-pin headers):

DSC_0980.jpg

From top left to bottom right: PIR lens, PIR sensor, 3-pin header, SHT11, LDR, Room Board PCB, pre-assembled PIR sensor board.

The hardest part to solder is the SHT11 sensor. It has 10 gold pads on the side, of which only 8 are connected. Make sure you place the sensor in the right orientation. With the text on the pcb readable, the round part is pointing down:

DSC_0981.jpg

Next, solder in the LDR light sensor. Be sure to place it in the LDR1 position:

DSC_0982.jpg

The wires of the LDR may be a bit more difficult to solder than ordinary components, so be sure to use enough flux:

DSC_0983.jpg

Next, we need to prepare the ELV PIR sensor board – the board itse;f already has all the SMD’s soldered on, just the PIR sensor itself.

Careful – do NOT touch the surface of the PIR sensor, as any traces of oil will reduce its sensitivity:

DSC_0984.jpg

The sensor has to be pushed through the bottom side of the lens holder, into the board – from the non-component side:

DSC_0985.jpg

Solder the three wires and snip them off. Don’t use too much solder or you’ll risk shorting out the pads with the nearby components:

DSC_0986.jpg

Then turn the board around and click the fresnel lens onto the base (it has three different-sized notches):

DSC_0987.jpg

Next, we need to connect the boards together:

DSC_0988.jpg

The pins go through the room board and should be snipped off once soldered:

DSC_0990.jpg

Almost there – the last step is to solder the two 6-pin male headers onto the room board. To hold them in the right position, I just push them into a JeeNode:

DSC_0991.jpg

… then place the room board on top and solder both headers, all 12 pins. Leave the 8 holes on the side of the PCB free (these are for another type of PIR sensor):

DSC_0992.jpg

That’s it – you’re done!

For more info on uploading the “rooms.pde” sketch firmware to the JeeNode, go back to the docs page.

Update – for the Room Board v2, see this weblog post.

RTC battery fix

In Hardware on Feb 1, 2010 at 00:01

I’ve been getting some email about the RTC Plugs not retaining their clock. It turns out that there is a problem:

DSC_1154.jpg

The center contact of the battery “holder” is the PCB itself, and being gold-plated, I thought it’d be best to keep it as is.

The problem is that the solder mask layer can be slightly thicker than the gold-plated pad, causing the battery to not make contact – despite the pressure of the metal clip.

This can be fixed by adding a small dab of solder:

DSC_1155.jpg

This will cause the coin cell to press more against both contacts, so a good connection is virtually guaranteed.

Needless to say, I’ve updated all RTC plugs here and will ship this improved version from now on.