Computing stuff tied to the physical world

Archive for January 2010

Room node – last

In Hardware on Jan 31, 2010 at 00:01

Here’s a last post about mounting a room node in a ceiling corner.

The enclosure and support struts were cut out of an A4 sheet of foam board, according to the template PDF on the wiki:

DSC_0993.jpg

Unfortunately, the JeeNode doesn’t quite fit with the FTDI pins sticking out, so I had to cut away a bit of the support material. As you can see, everything is glued together with hot glue, even the room board. The battery pack is stuck on the top part with double-side tape.

The motion sensor sticks out in the middle, at the cross-point of two diagonals on that slanted surface, to be precise. The holes for the LDR and SHT11 have not yet been made:

DSC_0994.jpg

Here’s how everything sits in the completed unit:

DSC_0995.jpg

There’s still some leeway to move the JeeNode up a notch, but I’ll leave it at that.

Enough of all this mechanical tinkering!

Room node mount

In Hardware on Jan 30, 2010 at 00:01

It’s time to finish that room node ceiling mount, at least the prototype.

At first, I thought I’d use the new 3D printer for some sort of nifty mounting bracket:

Screen shot 2010-01-29 at 20.48.04.png

… but it turns out that there’ a much simpler solution:

DSC_0977.jpg

This pushes the top of the mount against the ceiling, right under the battery pack, which is by far the heaviest part anyway:

DSC_0978.jpg

I don’t like the look of the paper sheet wrapped around the foamboard, but whatever – it works!

There’s a new wiki page with the description and a PDF with the outline of the pieces required to make a ceiling mount. Haven’t quite accounted for the thickness of the foam, since it depends a bit on which way it’s cut and folded, but the PDF should be usable as starting point.

One more 3D post

In Hardware on Jan 29, 2010 at 00:01

Ok, one last post on the CupCake CNC trials before I get back to JeeNode stuff.

The raft is now very solidly stuck to the base:

DSC_0968.jpg

This thing really sticks well, with plastic pushed down into the criss-cross grooves of the acrylic base. The trick is to place a plain paper sheet between the extruder head and the base, and to lower the Z axis until the paper slides away with just a tad of friction.

Unfortunately, the next problem comes up – as seen in this first Geneva Wheel trial:

DSC_0967.jpg

It turns out that the next layer of the raft doesn’t stick well to the first one. I solved this by raising the default 230° setting to 240° for the raft.

Another serious problem was that there is a lot of plastic on the right end of the raft as the print nozzle paused (!) on each turn. And the second layer of the raft doesn’t extend all the way to the end. This was solved by adding three noise-suppressing 0.1 µF caps to the extruder motor and disconnecting all the end-stop optocouplers.

The object itself seems to come out fairly well, though there were some blobs of plastic around the nozzle during printing which clearly interfered with the X-Y motion at times.

Here are over a dozen more parts, printed using black ABS for a change:

DSC_0975.jpg

These all came out ok, but note that even these small parts take 10..15 minutes to print – each.

The biggest remaining problem is “warping” – it’s causing over half my trials to fail:

DSC_0976.jpg

This part failed to build (should have been 20 mm high), it slowly came off the base and started interfering more and more with the extruder nozzle. At some point the nozzle got stuck in fact. Note how the thickness of the part is completely uneven. This is caused by the ABS cooling down and shrinking a bit – slowly pulling itself off the raft (with considerable force). A heated baseplate seems to be the hack to solve this – but that will require a lot more tinkering.

Oh well. We’ll get there… eventually :)

Update – upgraded to ReplicatorG 0012 with Extruder firmware v1.8 and switched to Zach Hoeken’s thermistor settings (raft setting reverted to original 230°). The last change was to shine a halogen light on the platform and object, to heat it up a bit – this seems to get rid of just about all the warping, yeay!

More 3D trials

In Hardware on Jan 28, 2010 at 00:01

It’s not as simple as it seems…

Well, the CupCake worked straight out of the box, which is of course fantastic. But printing does seem to have two tricky bits, called “extrusion” and “rafts”.

Here’s the printer making its third part:

DSC_0963.jpg

What’s about to happen, is that the “raft” (that woven mat laid out on the bottom to hold the rest of the construction) is about to come off the base. In the above picture you can see two other problems: the raft itself coming apart, and a blob of plastic (front right) when the printer decided to pause for a few seconds, while the extruder kept pushing out plastic…

The problem seems to be that when the plastic cools down fully it becomes quite springy and rigid. Which is great for the final object, but causes trouble in keeping it stuck to the acrylic base. I suspect that the heated platform which people are experimenting with is to overcome this problem, by keeping the base slightly sticky for the duration of the build.

Or maybe a few wires extending further out from the raft would help, by “tacking down” the whole thing.

The other purpose of the raft is to even out the surface. In my case there is a slight difference in height across the base. I should probably try to get rid of that first.

Anyway, here are the objects made so far:

DSC_0964.jpg

The meandering plastic retains its shape – that’s probably part of the magic behind all this.

PS. The stepper motors are noisy. I don’t think the software I’m using is micro-stepping right now.

CupCake #361 is alive!

In Hardware on Jan 27, 2010 at 00:01

Just got the missing part for the CupCake CNC 3D-printer in from MakerBot – partly their mistake, partly my mistake, long story… anyway – in the end they were extremely helpful in coming up with a good solution.

Which I had to try right away, of course ;)

After a bit of head scratching w.r.t. firmware versions and uploading, everything came together at last.

Here’s the first object getting printed at Jee Labs – whee this is fun:

DSC_0959.jpg

After 8 minutes, it’s done and steps aside:

DSC_0960.jpg

Mystery object…

DSC_0961.jpg

After removing the “raft” and cutting off some loose ends:

DSC_0962.jpg

So what is it? Oh, nothing spectacular really – it’s a Z-endstop for the machine itself. I figured that after us people doing so much to get it going, this machine might as well start working on improving itself right away…

I’m astonished by how well this first part came out. Very clean, very plastic’y, much sturdier than I expected.

All that’s left is to give this new beast a name – Jee3D? JeeCup? JeeCake? CuppaJeeno?

Ceiling mount – sliding part

In Hardware on Jan 26, 2010 at 00:01

Ok, here’s the sliding part of the room node mount:

DSC_0953.jpg

Totally hacky for now, the reinforcement bits are all glued in and cut to shape.

What totally surprised me, is that the JeeNode itself barely fits, even though there seems to be so much empty space in there. The tricky bit is that it can’t stick out on either side – in the end I could only make it fit by turning it a little, and moving the battery pack out of the way to make room for that orientation:

DSC_0955.jpg

This thing is larger than I expected it to be – the big triangle against the ceiling is 14 cm on both sides and ≈ 20 cm on the long diagonal side.

Last step will to to figure out a way to mount this concoction. Oh, and then redo it all from scratch to create a decent printable DIY template.

Ceiling mount – first step

In Hardware on Jan 25, 2010 at 00:01

As promised, the foam board construction – well, a first step anyway:

DSC_0950.jpg

The “folds” are a bit ugly this way, I’ll hide them on the inside using V-cuts in the next version.

Room node and battery pack included for size comparison. You’d think they fit easily inside, but the battery pack is surprisingly tricky, given that the room node needs to stick through the slanted side facing outwards.

The “walls” are also a foam mockup I’m using to avoid having to use an actual ceiling corner :)

DSC_0951.jpg

Here’s how I intend to to place everything inside:

DSC_0952.jpg

The battery pack will be attached to the top, i.e. flat against the ceiling. The room node will be mounted such that the PIR sensor sits in the middle, sticking out.

Onwards!

Room node ceiling mount

In Hardware on Jan 24, 2010 at 00:01

Been pondering a lot lately on how to mount all those room nodes around the house…

Without an enclosure the room nodes look very “hacky”. And what’s even worse: there is no way to mount them! The problem is that you want to point the PIR sensors at least approximately into the center of the rooms they are overseeing. The least conspicuous place for them is probably in the corner, near the ceiling.

Our house has white walls, so naturally I’d like to have something white up there, not some black or metal box!

Here’s an idea:

Screen shot 2010-01-22 at 14.12.54.png

To be made of – wait for it – foam board!

It’s probably a bit hard to visualize, but the idea is to attach a triangular “corner plate” to the wall (using glue / nails / screws / telekinesis / whatever). Then you slide this assembly with JeeNode and battery pack onto it.

Here’s a paper mockup of the sliding part:

DSC_0946.jpg

With one or two “struts” to reinforce it, this ought to be fairly sturdy and easy to slide in and out (will probably have to do that often in the beginning!). Perhaps a few needle pins will be enough to keep it fixed in place.

Laid flat, the sliding part looks like this:

DSC_0947.jpg

Needs some holes in the middle section, for the PIR, SHT11, and LDR sensors.

The geometry of this thing is quite simple, once you wrap your mind around what it really is – an equilateral triangle placed against the top corner with horizontal cross sections on top and cutting off the bottom part:

Screen shot 2010-01-23 at 13.46.52.png

The trick will be to get the sizes right. The paper mockup shown here is about 12 cm on each side, enough for a JeeNode, but too small to also hold a 3x AA battery pack behind it. It also shouldn’t be too hard to make some extra templates pointing off-center – so that you’d essentially aim the PIR by picking the most suitable enclosure variant.

I’m going to try a version using foam board next. Never a dull moment :)

P.S. If you qualify for a 10% discount in the shop, please note that there are 7 days left.

Lithium node

In Hardware on Jan 23, 2010 at 00:01

The 3.6 long-life / low-current OmniCel lithium batteries just came in.

Say hello to the latest room node at Jee Labs:

DSC_0944.jpg

Colorful, eh? ;)

The battery is connected directly to +3V and GND, i.e. after the voltage regulator, since its operating voltage is an excellent match for the ATmega and RFM12B.

No motion sensor was needed for where this node is going (and I didn’t have any left anyway), so that reduces the current draw by some 40 µA. Average should be somewhere around 200 µA – as mentioned before, this can no doubt be optimized further.

Since there are no motion triggers, this node will only send one or two packets per minute – the battery should last well into 2011, according to the specs.

Unless the receiver is turned off and this thing starts re-transmitting all the time. I really need to fix that flaw…

For a fun enclosure, check out the Airwick post by Szymon Kobalczyk on the Jee Labs discussion forum.

Temperature plots

In Software on Jan 22, 2010 at 00:01

With over a dozen nodes now active, JeeMon is finally starting to collect a bit more useful data to work with:

Screen shot 2010-01-22 at 12.03.23.png

Looks like some temperatures have a granularity of 1°C – might be a few cheap DS1820 units I had…

The Mason-like templating code in “try-temps.html” to generate this plot is still far from obvious:

Screen shot 2010-01-20 at 01.52.42.png

Once I get to spend some real time on all this, it’ll look totally different. JeeMon as a whole is going to change completely in fact – until then, you can find some technical background information in an older post.

Let’s just say that it gets the job done right now…

Single AA room node

In AVR, Hardware on Jan 21, 2010 at 00:01

The range of things to try is just endless…

Here is a (v2) JeeNode with a (prototype) room board and a 1-cell battery:

DSC_0942.jpg

Note that this prototype board is turned 180° w.r.t. the official Room Board, to match the Rooms sketch.

This node uses a 1.5 => 5V converter from SparkFun, which I had lying around. It’s far from optimal, with one third of the energy eaten up by the 3.3V voltage regulator, but it’ll have to do for now. Let’s see how long it lasts…

The whole thing is mounted on a little piece of foam board with dual-sided adhesive tape. Just to try it out.

To give you an idea of what’s flying around over the 868 MHz airwaves around here:

Screen shot 2010-01-20 at 00.18.35.png

That’s some 10 room nodes, the OOK relay with a bunch of sensors, and the energy/gas metering packets. Note how the Linux system time is exactly in sync with the DCF77 atomic clock receiver (using UCT i.s.o. CET). Note also that the OOK relay data is currently reported twice: once through a direct USB connection, once over the air.

Lots of fun! And that’s just the beginning, as far as I’m concerned :)

On a related note: I’m investigating whether it would be feasible to bring out a complete kit for the Room Board – with motion, light, temperature, and humidity sensors all included. If I can find the right distributors and order in sufficient quantity, it might be possible to get such a kit in the shop for €39, incl. VAT. Let me just say that if it can be done, you’ll be the first to know!

Sleep mode fix

In AVR, Software on Jan 20, 2010 at 00:01

The Rooms sketch (latest code here) had problems with the sleep mode added about a month ago:

Screen shot 2010-01-17 at 14.05.55.png

The first value is the current consumption in µA.

For some reason or other, the node would stop working and enter a permanent-on mode, drawing over 7 mA and draining the battery in a matter of days. Not good.

It seems to be related to the way the power down mode was implemented. To get absolutely rock bottom power draw, I was using the RF12’s watchdog timer. The ATmega watchdog time draws slightly more current and isn’t quite as configurable.

I’ve now reverted to using the ATmega watchdog anyway. Here is the modified logic:

Screen shot 2010-01-18 at 12.09.39.png

The watchdog is set to interrupt every 16 milliseconds, constantly. When the node is powered down, this will wake it up again. What the new loseSomeTime() code does, is simply to power down a couple of times, until the target delay time has been reached. There is some inaccuracy in these timings since the watchdog timer is free-running, but this should not matter too much when waiting for a second or so.

The new code has been running fine for over a day on six nodes. Here’s a sample from my power tracker:

Screen shot 2010-01-19 at 16.56.22.png

That’s 110 µA right now, 265 µA in the last minute, and 230 µA in the last hour.

At around 250 µA average, the power consumption is a bit higher than before, but my main concern is first to get the nodes running reliably. Even @ 250 µA, the AA batteries should last several months.

The average power down current draw is 110 µA/sec, 40 µA of which is due to the PIR sensor. The total current draw while transmitting is around 29 mA – during reception it’s about half, i.e. 14 mA. Still, due to the very brief on-times, this current consumption averages to only about 400 µA during 1 second for a normal send + ack sequence. Under optimal RF conditions, the long-term average consumption of a node will be under 150 µA. I’m confident that further optimizations could reduce this to well under 100 µA.

But there is one known flaw, which can be observed to happen once in a while: the nodes always wait for an ack in full-power mode, i.e. with the receiver on. This will normally be within milliseconds, but if the connection is flakey or if the central node is unresponsive, then nodes can spend a great deal of time in full-power mode. This needs to be fixed one day.

I’ve started re-flashing all the room nodes and replacing their dead batteries, here at Jee Labs – let’s see how it goes this time around.

Interesting battery option

In Hardware on Jan 19, 2010 at 00:01

Found an interesting (one-time, i.e. disposable) battery cell the other day at Farnell:

Screen shot 2010-01-17 at 21.03.13.png

These have the size of an AA cell, but they deliver 3.6V, so they can effectively replace 3 AA cells at once. The voltage is just right – this battery could be used with or without the JeeNode’s 3.3V voltage regulator.

The discharge graph is as follows:

Screen shot 2010-01-19 at 16.47.29.png

I’ve ordered a few with wires attached to them, so they could be tied directly to the PWR & GND pins of the FTDI connector. Will report back once some “field tests” have been done.

Update – better discharge graph, see comments below.

More C++ template trials

In AVR, Software on Jan 18, 2010 at 00:01

Here are some more results in trying to use templates for embedded software on JeeNodes. This time, it’s about using Jee Plugs with bit-banged I2C on one of the 4 ports and with built-in TWI hardware on pins A4/A5.

Let’s start with an extract of the Latest JeeLib.h header:

Screen shot 2010-01-17 at 11.50.27.png

I’ve omitted all the actual code, for brevity in this example. The full code is here. The previous version of JeeLib has been moved to the avr-jeelib-first branch in subversion.

The Port<N> class is essentially the same as in an earlier post. It generates efficient code for raw pin access, given fixed pin assignments known at compile time.

The above code adds a templatized PortI2C<N,W> class, where N is again the port number (1..4) and W is a constant which determines the bus speed. As with Port<N> class, this leads to a class definition which requires no state and which can therefore consist entirely of inlined static members.

A HardwareI2C<W> is also defined, with the same API as PortI2C<N,W>, but using the hardware TWI logic in the ATmega. The point is that in use, PortI2C<N,W> and HardwareI2C<W> objects are interchangeable.

You can see how all this templating stuff complicates the naming of even simple classes such as these.

The final class implemented above is DeviceI2C<P,A> – it does the same as DeviceI2C in the original Ports library, but again using templates to “bring in” the underlying port classes and the device I2C address.

Here is an example sketch built with all this new code:

Screen shot 2010-01-17 at 12.48.05.png

It supports two bit-banged I2C devices on ports 1 and 2, respectively, as well as a third I2C device driven by the built-in TWI hardware.

This compiles to 980 bytes (using Arduino IDE 0017).

The good news is that this generates pretty efficient code. It’s not 100% inlined – but quite a bit is, especially at the lower levels, so the result looks like a pretty good implementation of a high-level I2C driver which can be used for both bit-banged and hardware-supported I2C, all by changing one declaration at the top of the sketch.

But there are quite a few inconveniences with this approach…

First of all, note that the declarations at the top are fairly obscure. I did my best to simplify, but all this template mumbo-jumbo means you have to understand pretty well how to declare a port, and how to declare an I2C device object for that port. The “typeof” keyword in there is a GCC extension, without which these declarations would have looked even more complex.

The major trade-off is that the above example essentially generates separate code for each of these three I2C devices. There is virtually no code sharing. This can lead to code bloat, despite the fact that each version generates pretty good code. In practice this might not be so important – it is not likely after all that you’ll need all three types of I2C buses in the same sketch. Just keep in mind that you’re trading off efficient hard-wired coding against the need to generate such code for each type of I2C access you might need.

So would this be a good foundation to build on? I don’t know yet…

C++ templates do seem to get a lot more of the logic “into” the compiler. Instead of passing say an I2C device address as constant to an object, we generate a highly customized class which is special-cased to implement just one device at just one address. With the result that the compiler can perform quite impressive optimizations. In the above example, there are lots of cbi and sbi instructions in the generated code, just as if you were to dig in and hand-craft an optimized implementation for exactly what you need. All from a small general-purpose library!

But it comes at a price. There is no (non-template) “DeviceI2C” class anymore. Writing a class on top to implement access to the UART Plug for example, means this class has to use templates as well. It’s a bit like “const” – once you start on the path of templates, they will start to permeate all your your code. Yikes!

The other “cost” is that all templates have to end up in header files. The size and complexity of the “JeeLib.h” header file is going to increase immensely. Not so great if you want to get to grips with it and just use the darn stuff. On the plus side, I was pleasantly surprised that error messages are fairly good now.

These drawbacks may be acceptable if all the template code can indeed remain inside the library – I sure wouldn’t want to impose the need for all library users to learn the intricacies of templates. So maybe it’s all doable – but this approach has major implications.

Is it all worth it? Hm, big decision. I do not like big decisions, not at this stage…

Fun board

In Hardware on Jan 17, 2010 at 00:01

Here’s a fun project:

DSC_0938.jpg

This is an A4-sized foam board with four “indicators”. Each of the colored vane pointers can rotate 90°. The idea is to place a sheet of A4 paper underneath them with some sort of scale, so that you can see 4 status values at a glance. Energy consumption, number of pending emails, whatever.

Here’s the back side:

DSC_0939.jpg

That’s an old v2 JeeNode with an ATmega168 and 4 cheap micro-servos strapped to it. The extra capacitors reduce the voltage ripple while these servos move, since they seem to generate quite a lot of noise.

The whole thing is held together by zip-lock straps:

DSC_0940.jpg

The servo axes pass through holes in the bottom, which is in the fact the front plate.

Here is a test sketch to move each of the servos via commands given to the serial port:

Screen shot 2010-01-16 at 10.55.46.png

The basic range for each servo is 45 to 135 degrees, and the h/j/k/l keys control each individual servo, so this lets me position each one with commands such as “45h”, “90j”, “135k”, “75l” etc. There are also commands to move all servos, or to return each one of them to the middle position. These positions are only approximate, each servo will need slightly different values for their end ranges.

It turns out that these servos can’t all be moved at the same time reliably. I’m guessing that they generate too much noise or pull down the 3.3V regulator too far. So all actions involving multiple servos need to be staggered. Another problem is that these low-cost servos sometimes get “stuck” and keep jittering around the target position – this can be prevented by detaching them, since each servo will stay at its last position.

Next step will be to drive these indicators from wireless. I’m going to postpone that for now, because this status display really needs a “switchboard” type application running on the central PC to manage real-time updates.

This thing can’t run off batteries, unfortunately, because the servos draw too much current. I’d be interested to make a display in the future which does run wirelessly – maybe something with solenoids or tiny DC motors.

Sheeva – powering up

In Uncategorized on Jan 16, 2010 at 00:01

Yesterday, I mentioned the SheevaPlug. Today, I tried it out:

  • Plug in Ethernet, plug in power, done.
  • The box registers via DHCP.
  • Figure out its IP address, and follow the New Plugger instructions.
  • That’s it. Ubuntu 9.04, running on a pretty amazing little box. Effortless!

Here are some system details, once you log into it via SSH:

Screen shot 2010-01-15 at 01.23.35.png

Upgrading to the latest software packages went flawlessly, using the normal Debian/Ubuntu apt-get update/dist-upgrade/autoremove commands. Once done, there is still plenty of room left on the internal flash ROM:

Screen shot 2010-01-15 at 01.50.09.png

According to this post, power consumption is really low:

Screen shot 2010-01-15 at 01.38.07.png

I’m seeing about 3.5 W, doing nothing and hooked up to 100 Mbit ethernet. Close enough.

Mighty impressive for a 1.2 GHz processor with 512 Mb RAM. Here’s a brief review of it.

This could make a pretty nifty “home monitoring and control center”. I’m not going to limit my options to this, the plan is to support a wide range of platforms – but still, this ShevaPlug sure is a comfy unit, almost like a desktop!

One of the JeeHubs?

In Hardware on Jan 15, 2010 at 00:01

Just got this thing in:

DSC_0936.jpg

It’s a SheevaPlug with 512 Mb RAM, 512 Mb flash, Gb ethernet, and a USB host port.

As you can see, I plugged a JeeLink into it, along with a 2 Gb memory card.

This is just one of several configurations I am going to look into. One of the design criteria for the server side is that it needs to be portable to a fairly wide range of hardware, from desktop PC’s, to some really small embedded Linux boards. This SheevaPlug sits somewhere in between, with a lot more oomph than needed just for JeeMon, yet an idle consumptions of only a few watts.

Haven’t turned it on, let alone adapted the JeeMon software for it, but that’s only a matter of time.

Time? Man, that’s such a scarce resource around here!

New library experiments

In AVR, Software on Jan 14, 2010 at 00:01

Encouraged by the previous post, I started writing a bit more code based on C++ features such as templates and namespaces, in the form of an Arduino library (compatible with it, not depending on it):

Screen shot 2010-01-09 at 02.08.27.png

Things to point out:

Less #defines (none so far), I turned bitRead() and bitWrite() into template functions (getBit and setBit), so that they can be used with 1..4 byte ints, just as the macros.

The Port class is inside a new “Jee” namespace, so there is no conflict with the existing Ports library.

Atomic access hasn’t been solved. Some of this won’t work if I/O pins get changed by interrupt code. I’m hoping to solve that at a higher level.

There are compatibility definitions for pinMode(), digitalRead(), and digitalWrite() using the normal Arduino pin numbering conventions (only Duemilanove so far). These are in their own namespace, but can also be used without any qualifiers by adding “using namespace Jee::Arduino;” to the sketch.

Totally incomplete stuff, untested, and not 100% compatible with Arduino in fact.

The other thing I want to explore, is to treat the choice of what a pin does as a pin initialization mode. Hence the enum with Mode_IN .. Mode_PWM definitions. The underlying code is PortBase::modeSetter(), but it hasn’t been written yet. It’s all steamy hot vapor for now.

Update – I’ve placed the code in subversion, but the API is going to be in flux for a long time.

Update #2 – Atomic access is actually better than I thought. With constant pin numbers, setBit() will use the cbi/sbi instructions, which are atomic.

Meet Roomie

In Hardware on Jan 13, 2010 at 00:01

It may not be the prettiest gadget in the home …

DSC_0931.jpg

… but I find it mighty convenient. I think I’m going to call it a “Roomie”.

The battery pack shown here is an older green one, the ones currently in the shop are black.

It’s nothing but a JeeNode with a battery pack and a Room Board on top. This example is not optimal, it uses a power hungry ePIR. But you get the idea.

The battery pack is tied to the dedicated connection for it – going through the strain relief holes and around the other side to the solder pads:

DSC_0932.jpg

And the whole thing is glued together with hot glue:

DSC_0935.jpg

Nice thing is that this doesn’t restrict the uses of a JeeNode. When switching the battery off, you can hook it up to a USB interface via the FTDI header.

In fact this will even work upside down on a foam board, as used with POFs:

DSC_0934.jpg

Just think of it as a JeeNode with a power pack sitting on its back :)

C++ templates

In AVR, Software on Jan 12, 2010 at 00:01

A recent post described the performance loss in the Arduino’s digitalRead() and digitalWrite() functions, compared to raw pin access.

Can we do better – i.e. hide the details, yet still get the benefits of raw I/O? Sure.

If you’ve used JeeNodes and in particular the “Ports” library, you’ll have noticed that there is a C++ class which hides the details of each port (i.e. JeeNode port, not ATmega port). Let’s look at that first:

Screen shot 2010-01-06 at 12.40.09.png

I’ve omitted the implementation, but there are still lots of secondary details.

The main point is that this is now C++, and uses a “Port” object as central mechanism. Each object has one byte of data, containing the port number (1..4).

Due to heavy inlining, there is almost no additional overhead for using the Port class over using digitalRead() and digitalWrite(), on which they are based. I verified it by running similar tests as in the recent post about pin I/O:

Screen shot 2010-01-06 at 12.48.50.png

Using the definition “Port orig (1);” – and sure enough the results are nearly the same.

There are two issues which make this approach sub-optimal: using the slow digital read/write calls, and storing the port number in a memory location which needs to be accessed at run time. There is no way for the compiler to optimize such calls, even “orig.digiRead()” should be the same as writing “bitRead(PORTD, 4)” in this example.

That’s where C++ templates come in. Check out this definition of a new “XPort” class (named that way to avoid a name conflict) and an example of use for port 1:

Screen shot 2010-01-06 at 12.54.02.png

(As you can see, I’m switching to a different, and hopefully clearer, API along the way)

There’s some funky <…> stuff going on. We’re in fact not declaring one class, but a whole family of classes, parametrized by the integer included in the <…> notation on the last line.

The big difference, is that each class now has that integer value “built-in”, so to speak. So we can define member functions which directly pass that value on to the corresponding bitRead() and bitWrite() macros. And then all of a sudden, all the overhead vanishes: since the member needs no access to object state, it can be made static, and since all the info is known in the header, it can be made inline as well.

So the above template is C++’s modern way of doing far more at compile time, allowing the optimizer to generate much better code.

Note that templates come with some pitfalls: first of all, it’s very easy to inadvertently generate huge amounts of code, so very careful inlining and base class derivation is essential. The second problem is that templates tend to be “instantiated” as late as possible by the compiler, which can lead to confusing error messages when the templates are wrong or used wrongly.

I’m still just exploring this approach for embedded use. The potential performance gains are substantial enough to give it a serious try. My hope is that the hard work can be done in a library, so that everyone else can just use it and benefit from these gains without having to think much about templates, let alone implement new ones. The “one” object declared above acts like any other C++ object, so using it will be just as easy as non-template objects.

Does the above lead to fast code? You bet. Here’s a test sketch:

Screen shot 2010-01-06 at 13.05.29.png

And here’s some sample output:

Screen shot 2010-01-06 at 13.06.14.png

As you can see, values 5 and 6 are virtually the same as values 7 and 8. We’ve obtained the performance of direct pin access while using a high-level port-style notation to access those pins. This is why templates are so attractive for embedded use.

The timings are different from the previous post because the loops are coded differently. In this case, only the relative comparisons are relevant.

Open – Some notes (5/5)

In Musings on Jan 11, 2010 at 00:01

(This is the last part of a 5-part series on open source – parts 1, 2, 3, 4, 5)

JeeLabs134x55.png

Jee Labs is an open source shop – both open source hardware and open source software.

Nothing earth-shattering: I’m exploring what’s possible in the domain of physical computing, and have been focusing on simple ATmega-based wireless sensor networks for in and around the house. A simple variation on the Arduino theme, really. In fact, it’s pretty hard not to be compatible with an Arduino when your stuff is based on the same Atmel AVR chips. Because in terms of basic functions and software, an Arduino is (at least right now) essentially simply an ATmega on a board. Plus a serial port boot loader.

This “computing stuff tied to the physical world” is a lot of fun. And a lot of work.

There’s a substantial amount of software required for all this, from dealing with wireless to collecting, storing, and presenting measurement data. And that’s just going one way – to also robustly (and securely) control things in the house, there’s also this whole field of domotics to go into.

I love doing software development. I spend most of my time on it.

And with Jee Labs involved in both OSH and OSS, there is finally a way to dedicate all my time to this stuff.

It’s a very simple mechanism: the hardware side funds the software side.

Does that make Jee Labs a commercial undertaking? Yep. Small shop, but it’s about as direct as it gets:

Stuff sold => food on the table => hunger gone => happy coding.

So I’m hired by the shop to do the hardware and software side of things. As long as there is funding, I get to spend all my time on this stuff. All of it in the open, described on a public weblog, and with all designs usable by anyone to do whatever they like with it. Try it out, hack it, extend it, rip it apart, get rich with it, or ignore it – it’s all up to you. There’s nothing to steal, because your gain is not my loss. On the contrary.

Quite a few people have already done things like take the RF12 driver (software) and use it with their own hardware designs. Many others are taking some sensors (hardware) and tying it into their stuff with their own software. Cool – way cool, in fact. Hardly a day goes by without something encouraging or rewarding happening on some front.

The trick is sustainable funding. Which means I need to stay on the ball, and figure out what others would like to see from me. That’s good – normal market economics, really. There’s a lot of uncharted terrain, still waiting to be discovered, explored, and turned into projects and products. Just gotta look, listen, and keep moving. Which is a lot easier when everything is out in the “open” – hardware, software, … and ideas.

This concludes my mini-series on Open Source. It’s time to return to the techy stuff again!

Open? Really? (4/5)

In Musings on Jan 10, 2010 at 00:01

(This is part 4 of a 5-part series on open source – parts 1, 2, 3, 4, 5)

Screen shot 2010-01-06 at 00.06.41.png

For OSS (S as in software), “open” is all about collaboration. Yeah, sure, there’s a lot of re-invention and not everyone is willing to share when it matters (i.e. real innovation), but even just the collaboration of developers (producers) and users (consumers) is fruitful in the sense that bugs get exposed, investigated, and fixed. Even if asymmetric, this leads to faster evolution and better software.

And even if not always, OSS projects do tend to attract a lot of talent, and talent breeds creative solutions and excellence. Because of the low barrier to entry, the potential talent pool is huge. It doesn’t take a lot of talented / motivated people to make exceptional software. Collaboration among developers is the norm, not the exception – and the visibility helps, even if only by attributing status to the team participants.

With OSH (H as in hardware), things are a bit different. Sure, there too the exchange between producers and consumers helps create better products, no matter how asymmetric the groups are. Got a problem? Submit it to the forum, and it’ll be out for all to see so the producer(s) better get his/her/their act together.

But the numbers are different. Very different. The barriers to entry are a lot higher – designing hardware and actually building working “stuff” is hard and requires specific skills. It’s error prone, time-consuming, and above all it costs real money. You need equipment and inventory, the prototype turnaround times take ages when you’re doing this on a budget, and serious testing can be extremely difficult. Not to mention getting production QA up to scratch and the QC yield high enough.

Want some examples? Try “Chumby” or “Adafruit”, each driven by amazingly talented and dedicated people. Exercise for the reader: find out how many people are behind each of these OSH shops…

What about the Arduino boards? Well, to be honest, I have no idea who designed them, nor what discussion is going on about them for future developments. The Arduino “Mega” sort of dropped out of the sky once it was on the shelf.

Because, you see, selling hardware generates income. And any income, say N dollars, divided by anything but 1 would be less than N. What seems to be happening right now, is that OSH producers are indeed “open”, but only after the designs have been created, tested, and manufactured. All the hardware work has been done, all the choices and decisions have been made, and all the time-consuming steps have already been taken.

So OSH “shops” are in fact putting a fairly large distance between themselves and any potential contributors (and competitors). Want to see, use, or even alter what they do? Fine – but not before they’ve got their revenue streams set up.

Don’t get me wrong. This is absolutely everybody’s full right. To be an entrepreneur means you get to take the initiative and you get to make all the choices you want. That’s the whole point. It’s just not really open.

I’m not even sure it could be done any differently. At some point, as producer, you’ve got to have an advantage over others to be able to justify the time, effort, and money spent on whatever it is you do. And given that most supermarkets want money to hand over the ingredients for your meals, incentives tend to work best if they too are in terms of money…

But there’s preciously little collaboration going on. Ideas aren’t flowing freely, far from it. And as with OSS, some people are waiting on the sidelines, trying to soak up as much info as they can, and keeping ideas to themselves to try and create their own revenue source when the time is ripe.

There’s nothing inherently “wrong” with that.

I’m the same – ask me about what my plans are, how I solved some tricky issues, and I might give you an evasive answer… because I’m afraid someone might “beat me to the punch”, or become a competitor.

It looks like OSH is being treated as a zero-sum game, i.e. “your gain is my loss” and vice-versa. I’m not sure it actually is, even w.r.t. money. In fact, as far as ideas go, I’m convinced that it definitely isn’t – ideas breed more ideas, infinitely so. We just need to figure out and implement the mechanisms which encourage the flow of ideas. Right now, neither OSS nor – especially – OSH are quite there yet.

In the first part of this series I started out by saying that there is hypocrisy involved. Whoa, that’s a big word. Let me explain…

First, allow me to summarize: with OSS there is usually no money involved – it all runs on voluntary contributions and team participation. With OSH, on the other hand, there is always money in the equation, because “stuff” is involved, i.e. real atoms, not just bits. And once money flows, normal / healthy economics will lead to revenues, profits, and income, no matter how modest or at what scale. Fine. Cool, even.

Except… with physical computing, there is always both hardware and software (call it “firmware” if you like). The hardware makes things possible, the software makes things happen. Either one is useless without the other. Yin and yang. Yet hardware and software are quite different beasts, and require quite distinct skill sets, so the people doing (“good at”) the hardware are often not the same as the people doing (“good at”) the software.

If I were involved in the hardware side of physical computing, and wanted to get rich (a real possibility, since there is money involved), I’d work like crazy on the hardware, and then kick it out into the world (i.e. sell it) with the minimum amount of software I can get away with. I wouldn’t put it that way of course, but I’d say “hey, I did my part, now someone else kick in to finish the other part”.

Then I’d sit back, or rather: participate just enough to keep up appearances. Build a community, take the lead, create the infrastructure for (software-only!) collaboration, and – pardon the bluntness – rake in the money…

If I were involved in the software side of physical computing, I’d design my own hardware and set up a shop to generate a revenue stream, so that I’d have at least a chance of funding some of my software efforts. Because I wouldn’t know how to sustain the necessary Open Source Software development for it in any other way.

I’ll leave it to the reader to be the judge as to what extent the above is happening today, and I urge you to look well beyond what I am doing with my little Jee Labs setup…

All I’ll add to conclude with, is that Open Source Hardware is not nearly as open and collaborative on the hardware side and in the design phase at it could be, and that the Open Source Software efforts which need to take place to make such hardware tick are not funded nearly as well as they should be to become truly attractive / sustainable.

And that’s a crying shame. Because somewhere along the way, we lost the ability to freely exchange ideas and benefit as a whole community from the potential of absolutely explosive creative growth. As it stands today, OSS and OSH are fine at spreading and even democratizing technology, but in effect stifling innovation. Open? How?

In tomorrow’s last episode – my feeble attempt to come clean, with Jee Labs. No climax. No grand finale.

Open Source Hardware (3/5)

In Musings on Jan 9, 2010 at 00:01

(This is part 3 of a 5-part series on open source – parts 1, 2, 3, 4, 5)

Screen shot 2010-01-06 at 00.04.22.png

On the side of open source hardware (OSH), the situation is less rosy.

The tricky part with OSH is that it’s about “stuff”. And stuff costs money right from the outset – to collect, to manufacture, to move around, to keep in stock, to use, to dispose of (OSS also has costs, btw – but indirectly, in the form of invested time, effort, and expertise).

There’s absolutely nothing wrong with money. Once money enters the picture, you can do things like add a margin to cover the costs. Or add a fat margin to cover more than the costs. Or pay others to get involved and bring in specific expertise. Which is way cool. Now we’re talking economy. And sustainability. And incentive. And of course: bread-on-the-table, i.e. income.

Oh yes, this is potent stuff. Markets. Resources. Competition. Profits. Investments. Capitalism!

The reason I’m pointing it out is that it’s a fundamental difference between OSH and OSS. And it’s obvious – everyone knows that to use software, you just gotta go to the proper site and download it. And to use stuff, you gotta purchase it and wait for it to be delivered on your doorstep (or go shopping and take it home, whatever).

We’ve all just been through the Christmas season. Shop ’til you drop. Pay and get.

But wait a minute… that’s for any kind of stuff. What’s “open source” hardware got to do with this? Well, you see, that’s where it gets a bit unusual.

Open source hardware means that the producers “open up” about what they are doing. In the electronics / physical computing / kits domain, the idea is to make the designs for the products openly available, often in the form of schematics and printed circuit board designs.

What’s the point? Well, you’re not locked-in, presumably. If you don’t like the design, you could take it and modify it according to your own wishes. Amazingly, this doesn’t seem to happen a lot. I can think of three reasons: economies of scale, interface conventions, and tools/skills.

The production of printed circuits is very much driven by economies of scale. It’s relatively expensive to create all the masks to produce good 2-layer PCB’s, with silk screens, via’s, solder masks, etc. So it makes a lot of sense for a supplier to have a certain number of PCBs made at once, and then sell individual boards at a cost lower than one-off production could. This is the traditional manufacturer’s sweet spot – it just happens to apply to tiny shops as well now, instead of just car manufacturers.

And hey, you know what? It’s great: all these manufacturers do us a service, by producing tons of goods of which we only need one, at fantastically attractive prices.

Another reason for not just starting from what there is and inventing tons of variations, is that an important aspect of a design is its interface with the rest of the world. This is particularly obvious with physical computing. Once you change interfaces (whether electrical, mechanical, or logical), you risk reducing inter-operability. This doesn’t apply just to OSH – think of all the “after-market” accessories in numerous domains. Many product choices end up affecting a lot more than that product itself over time.

The third reason why OSH isn’t spurring as much collaboration and innovation is that there’s often a fairly steep learning curve involved. It took me quite a lot of time and effort to learn how to design printed circuits, and how to have them manufactured. In fact, I made a ridiculous number of mistakes along the way, and had to throw away lots of failed trials. That’s not just wasted time and effort – that’s wasted “stuff”, and real money.

So it’s not surprising that not everyone grabs OSH designs and starts tinkering with them and producing their own boards. The process is non-trivial, takes time, and wastes money. We’d much rather buy ready-made products, or at least partially-made (including kits), with all the errors resolved so we can avoid them.

Again, this is great. Some people out there are willing to do the hard work, and others pick the fruits of their labor and compensate them for it.

Just keep in mind that here too, OSH is totally different from OSS. In a way, OSH solved the problem which OSS was never able to: to create a natural mechanism for rewarding time and effort spent.

So in a way, OSH could be called a success story. OSH seems to be picking up steam like crazy these days. Need an example? Try “Arduino”.

But wait, not so fast…

To be continued tomorrow – Open? Really?

Open Source Software (2/5)

In Musings on Jan 8, 2010 at 00:01

(This is part 2 of a 5-part series on open source – parts 1, 2, 3, 4, 5)

Screen shot 2010-01-06 at 00.05.56.png

With open source software (OSS), the immediate costs are generally very low. Get a computer and an internet connection (which you probably would anyway), and you’ve got all the expenses covered to benefit from OSS – and participate in its development. Infinite audience, negligible variable costs, very low barrier to entry. Other than your own time, skills, and effort.

The result? Explosive growth – SourceForge lists some 160,000 projects (or 380,000, depending where you look). Its two top projects (file sharing), have been downloaded half a billion times each.

Is it good? Sure, let a thousand OSS projects bloom, or more, why not.

But there’s also a lot of wheel re-invention going on (I should know, I’m an expert on that!). Some of it, and I fear quite a bit more than most people would be inclined to acknowledge, is extremely unfortunate: “hey, feature/app X in language Y is neat, let’s redo it in language Z!”

Is OSS leading to innovation? I’m not so sure. I suspect that when people stumble upon a potentially truly great idea, they will be tempted to re-consider whether they really want to share that idea with the world, and risk diluting it – by others adding more ideas (in the best scenario), or by others adopting it and succeeding at drawing more attention and claiming credit for it.

Another major hurdle is that turning an innovative idea into an innovative solution requires a lot of hard work. For “big” innovations, you’ll need to get all the right volunteers involved and motivated, have excellent people skills, and show true leadership. It’s easy to hit a wall somewhere along the road and lose interest before the product is finished (I should know, I’ve been there far too often).

It wouldn’t surprise me if for all the people sharing their ideas and working on them in public, there were at least as many others soaking up everything they can find and thinking “hey, maybe I can do something with this and become famous” – or even rich, by switching to a closed source software model. Even the GPL can’t fully prevent that, as long as you keep your software secret (and don’t get caught by having “similar bugs”!). The mere prospect of that happening can drain all motivation from an open source developer (see also: Prisoner’s Dilemma).

So all in all, my impression is that OSS isn’t all that innovative and collaborative as it’s often cracked up to be. Do you need an example? How about “Google”, which was built on the shoulders of open source. Sure, they do give back a lot, also in the form of open source. In fact, they provide what is arguably the greatest free service on the internet. But genuine collaboration w.r.t. their core innovations? No way.

There’s nothing “wrong” at all with this, btw. It’s just not really open.

To be continued tomorrow… Open Source Hardware

Open Source (1/5)

In Musings on Jan 7, 2010 at 00:01

(This is the first part of a 5-part series on open source – parts 1, 2, 3, 4, 5)

Jee Labs is an open source shop – both open source hardware and open source software.

There is money involved in open source. And there is hypocrisy. Let me explain…

The basic idea of open source, is literally to make the source of things freely available – and more or less allow reuse. With software, it usually comes down to making the source code publicly available to anyone. With hardware, the common approach is to make all design files publicly available to anyone.

40bsd.png 88x31.png 40gnugpl.gif

Depending on the model, you’re either allowed to do anything you like with it (all the way to hiding it inside your own for-sale stuff), or you have to at least maintain the proper attribution to the original author(s), or you restrict the use to projects which accept to be bound by the same rules as yours – preventing anyone from running away (and perhaps getting rich) with the original stuff and not letting anyone know they did so.

The “do anything you like with it” approach basically says: you can’t really steal it, because the author treats his/her work more as a form of self-expression than as promotion of something which deserves to be rewarded (whether monetary of in terms of fame). The latter “only on my terms” approach says “hey, as author I’m entitled to benefit at least as much as anyone else if there is any commercial value”.

I am (thank goodness) not a lawyer, so please treat all of the above as no more than my personal attempt to summarize what this is all about.

Newsgroups have overflowed and probably even been shut down because of debates on the differences between all the “licensing” approaches – (flame) wars have been waged about all this, and probably still do. Been there, done that. Yawn.

But in my view, all the open source approaches are minor variations of the same basic concept. The term “open source” itself is actually an amazing success, in that it manages to capture the essence despite all the factions and disagreements. It’s about volunteer effort, the power of gifts, competence, creativity, and the freedom of choice and re-use this approach offers.

Above all, open source is about enabling collaboration. Because, you see, the big differentiator of open source is that all ideas can be out in the open. When there is no need to protect ideas, there is also no need to restrict the flow of information. And, well… we’ve got this thing called the internet which happens to be friggin’ good at shuttling information (and ideas) around the globe.

So far so good. But there are a couple of weird things going on…

To be continued tomorrow… Open Source Software

Pin I/O performance

In AVR, Hardware, Software on Jan 6, 2010 at 00:01

There was a discussion on the Arduino developer’s mailing list about the impact of a small change to the digitalWrite() function, and for some time I’ve been hearing that digitalWrite() has a huge amount of overhead.

Time to find out.

Here is the sketch I used to measure how often a pin I/O command can be issued using various mechanisms:

Screen shot 2010-01-05 at 11.42.53.png

The logic is that I’m counting how often the same command can be called between timer overflows, i.e. every 1024 µs (one byte, incrementing @ 16 MHz / 64), before the timer tick count changes again.

And here’s the sample output:

Screen shot 2010-01-05 at 11.42.14.png

There’s a small amount of jitter, which tells me the loops are syncing up almost exactly on the timer ticks. Interrupts have not been disabled, so the timer interrupt is indeed being serviced – once for each loop.

What these values tell me, is that we can do about:

  • 10 analog 10-bit readings per millisecond with analogRead()
  • 128 pwm settings per millisecond with analogWrite()
  • 220 pin reads per millisecond with digitalRead()
  • 224 pin writes per millisecond with digitalWrite()
  • 1056 pin reads per millisecond with direct port reads
  • 1059 pin writes per millisecond with direct port writes

(I’ve corrected the counts by 1000/1024 to arrive at these millisecond values)

So the Arduino’s digital I/O in IDE version 0017 can do roughly 1/5th the speed of direct port access on a 16 MHz ATmega328.

But WAIT! – There’s a large systematic error in the above calculations, due to the loop overhead. It looks like the loop takes 1024000/1251 = 819 ns overhead, so the actual values are quite different: digitalRead() -> 3712 ns, direct port read -> 151 ns. Now the values are more like 1/25th!

So let’s redo this with more I/O in each loop iteration (all 4 ports):

Screen shot 2010-01-05 at 11.55.31.png

The sample output now becomes:

Screen shot 2010-01-05 at 11.56.59.png

With these results we get: one digitalRead() takes 4134 ns, one direct port read takes 83 ns (again correcting for 819 ns loop overhead). The conclusion being that digitalRead() is 50x as slow as direct port reads.

Which one is correct? I don’t know for sure. I retried the direct port read with 16 entries per loop, and got 67 ns, which seems to indicate that a direct port read takes one processor cycle (62.5 ns), as I would indeed expect.

Conclusion: if performance is the goal, then we may need to ditch the Arduino approach.

Update – Based on JimS’s timing code (see comments): digitalRead() = 58 cycles and direct pin read = 1 cycle.

Update #2 – The “1 cycle” mentioned above is indeed what I measured, but incorrect. The bit extraction was probably optimized away. So it looks like direct pin access can’t be more than 29x faster than digitalRead(). As pointed out by WestfW in the comments, digitalRead() and digitalWrite() have predictable performance across all use cases, including when the pin number is variable. In some cases that may matter more than raw speed.

Update #3 – Another caveat – Lies, damn lies, and statistics! – is that the register allocations for the above loops make it extremely difficult to draw exact conclusions. Let me just conclude with: there are order-of-magnitude performance implications, depending on how you do things. As long as you keep that in mind, you’ll be fine.

Merci, Paris

In News on Jan 5, 2010 at 00:01

Just got back from a couple of very relaxing days in Paris.

Here’s a quick impression of the 1680’s Comédie-Française (on the right):

IMG_5375.jpg

IMG_5384.jpg

IMG_5396.jpg

We went there to see a nice French theater piece. And although I’m not even remotely as culturally enlightened as such a remark might suggest, I did have a great time.

Normal transmissions to resume tomorrow…

JeeMon – one year later

In Software on Jan 4, 2010 at 00:01

JeeMon is a little web server / database / reporting tool I wrote a while back. It has been in use at Jee Labs for over a year now. Here is the electricity use for 2009:

Screen shot 2009-12-31 at 17.27.15.png

Couple of glitches, such as incorrect readouts when power failed and the sending node got reset to zero counts.

Here’s the gas consumption for 2009:

Screen shot 2009-12-31 at 17.28.06.png

Gas consumption (heating and hot water) is relatively high for this house, which is an open split-level design with lots of windows. Well isolated, but there’s simply no way to keep heat from rising up through the open stairways.

Here are the temperature and humidity readings for the past month:

Screen shot 2009-12-31 at 17.38.39.png

These are commercial S300 and KS300 sensors, and they seem to have frequent glitches. It looks like those could easily be filtered out, though.

Still, we managed to get €600 back on the 2009 energy bill, and with about 3000 kWh and 2000 m3 we’re 30% below the average consumption in this residential neighborhood, for both electricity and gas.

Being aware of what’s going on makes a difference, IMO. It has become a habit to turn off all the lights when I leave a room, and closing curtains right away when it gets dark. When we go out, we turn down the thermostat. Who needs high tech, when common sense is all you need? It’s so obvious, yet so effective …

The JeeMon database for all of 2009 is 26 Mb, i.e. tiny when considering that this includes every reading and some aggregated series as well. In fact, it contains a lot more data than what’s shown in the above graphs.

I’ve got several ideas and plans for JeeMon in 2010. I want to make it far more modular, so that nearly all its current functionality becomes available as easy-to-extend plug-ins. And it needs to be fullly configurable – as it is, JeeMon is still little more than a one-off implementation. But it has served its purpose very nicely already.

Better UART code and GPS

In Software on Jan 3, 2010 at 00:01

The UartPlug class which was recently implemented used per-byte access via I2C to retrieve each received character.

This isn’t terribly efficient, since it requires sending several bytes back and forth for each received character: first we address the UART to check its status, then we access it again to get one character from the FIFO. That’s six bytes of data for each received character.

It didn’t work well enough at 38400 baud, so I added a small buffer as optimization. The UartClass API hasn’t changed. The code which does this is:

Screen shot 2009-12-29 at 15.36.49.png

Nothing fancy, just a small buffer (10 bytes currently) to speed things up. The essence is that when lots of data is coming in, we get 10 bytes at a time, for a total I2C overhead of 15 bytes. That’s a 4-fold reduction in bandwidth.

The setup I’m experimenting with is this FV-M8 GPS receiver:

DSC_0928.jpg

The hookup looks daunting, but that’s because the connector is a bit small so I made a little breakout board for it:

Screen shot 2009-12-29 at 15.44.56.png

Here’s some sample output:

Screen shot 2009-12-29 at 16.05.09.png

The “gpsdemo” sketch is simply a serial pass-through, converting 38400 baud to 57600 along the way:

Screen shot 2009-12-29 at 15.46.40.png

But it still loses character along the way, as seen in this snippet:

Screen shot 2009-12-29 at 15.17.26.png

The RMC line has a partial line at the end, after the “*7B” checksum.

My guess is that this isn’t the UARTs fault, nor the I2C bus. What seems to be happening is that the Serial class does not buffer its output, so all output causes the sketch to become unresponsive for input. In theory the 57600 baud link should be able to get data out fast enough, but I suspect that in practice there is an occasional hickup.

If this is indeed the cause, then it’s another example of how wasting time can lead to problems.

Back to the GPS. After a few minutes it finds its position in 3D. The following info comes in 5 x per second:

Screen shot 2009-12-30 at 01.54.08.png

Some additional details are reported once a second:

Screen shot 2009-12-30 at 01.53.35.png

(ignore the last few garbled lines, I really need to lower that baud rate a bit)

Here’s an even more accurate fix I found in the data stream:

$GPGSA,A,3,12,22,09,28,18,26,17,27,,,,,1.32,1.02,0.85*02

So that’s up to 8 satellites – indoors, with stone/concrete walls and coated double-glazing windows. Impressive… older units I tried never even got a fix indoors!

To interpret this GPS data, check out Mikal Hart’s TinyGPS library, it can easily be hooked up to the UART plug – just use this code at the top of his test_with_gps example:

Screen shot 2009-12-31 at 00.58.36.png

… and init nss to match the baud rate of your GPS unit.

Wasting time

In Software on Jan 2, 2010 at 00:01

No, not your time or mine… the topic I want to go into here is how to let a micro-controller deal with things that happen over time.

The way an Arduino sketch works is as follows:

Screen shot 2009-12-28 at 14.59.53.png

The little slashes represent real code, where “stuff happens” so to speak. You can see that there is a clear flow of control, from the start of the code to the end, with delays and calls to other bits of code.

The trouble with this is that it can’t deal with multiple events. You can’t count pulses on an input pin and keep a LED blinking at the same time, for example.

In the old days, interactive computer interfaces were written in this same way. You’d enter a couple of values and then you got some results back. If you made a mistake halfway in the sequence, you had to restart and enter everything all over again.

Then “command menus” were invented: elaborate decision trees of the form “do you want to do X, Y, or Z?” – now at least it was possible to go back just one step. Today, user interfaces are event driven, responding to whatever interaction the user initiates instead of presenting choices. The user is in control, not the computer.

The traditional event-driven logic uses a dispatch / switchboard approach:

Screen shot 2009-12-28 at 15.00.03.png

The more modern approach is to use callbacks and closures. Fancier still is to use coroutines or continuations.

Could we use something similar for micro-controllers? Sure.

Callbacks are not that convenient in C, since it does not support the closures concept which would make it convenient (nor coroutines or continuations). Also, callbacks would have to be represented by pointers to C functions (2 bytes), whereas dispatch codes can probably be represented as a single byte (as long as we don’t have more than 256 of them). Efficiency and memory space matters on small 8-bit chips such as the ATmega.

This requires a change in mindset when writing sketches. A good way to get into such an event-oriented style is to imagine that there is no delay() function. In event-oriented code, you’re not allowed to wait for time to pass.

So how can we blink a LED if we can’t wait to switch it on and off? Well, instead of delays, we have timers. We’re still not allowed to loop until the timer expires, but we can tell this new type of timer to generate an event when its time has come.

For a low-end implementation, an event can simply be a small integer dispatch code.

So instead of waiting until we can turn the LED on or off again, we tell the system to wake us up again at the right time. This approach is also a perfect match for low-power nodes, by the way: sleep and wake-up on events can be taken literally to enter power-down mode and start up again.

The code might look something like this:

Screen shot 2009-12-28 at 16.00.55.png

Sure, it takes some more work than this delay-based code:

Screen shot 2009-12-28 at 16.03.06.png

… but it has the huge benefit that it’s now fairly simple to deal with other activities at the same time. What you need to do is turn each of those activities into one ore more events as well. They can then be added right next to the blink event code, as additional case(s) in the above “switch” statement.

An event-based dispatch mechanism adds a lot of flexibility. Tasks such as counting pulses, blinking LEDs, serial communication, wireless packet reception and transmission – these can all be processed as they occur. With as nice bonus that low-power sleep modes can become fully automatic: when there are no events, go to sleep!

The trick is to ban all uses of “delay()” and “delayMicroseconds()” and to never use “busy loops” to wait for something to happen. This has far-reaching implications, because all libraries must also play by these rules.

I’m going to explore this approach further. Maybe one of the existing nanokernels could be used as foundation. To qualify, it must be truly minimal (and I’m picky!) – i.e. it has to fit into an ATmega328 without claiming too much flash or RAM memory space.

Update – here’s a web page by “inthebitz” which illustrates the problems described above. It’s an absolutely genuine attempt to help people get started, and it no doubt does a very fine job at that, but it also shows how everything gets serialized time-wise. For slow things, it’ll be just fine of course.

Happy New Year!

In News on Jan 1, 2010 at 00:01

Here’s my little thank you for everyone who has supported Jee Labs in 2009 – in one way or another …

discount2010.png

No need to hurry, January has 31 days. I’m away now, will reply and send out discount codes on Monday.