Archive for March 2009

As described in this post on an Arduino forum, I’ve suggested some small changes to the delay() and delayMicroseconds() code in the Arduino/Wiring libraries:

(rest of delayMicroseconds unchanged)

Note that both changes only add new code, no lines have been removed or changed (the comments need to be adjusted, though).

The above changes only affect microsecond delays > 500 us and millisecond delays < 50 ms. In that range, a loop is used which should be accurate in the couple-of-microsecond scale and which does not lock out interrupts.

It should lead to a more accurate millis() value since interrupts can be serviced more often, and to a far more accurate delay for low-millisecond values. I hope something like this makes it into a future release of the Arduino IDE – timing capabilities are still a bit limited on the Arduino, IMO.

Here’s the first prototype of what I plan to install in several places around the house:

It looks a lot like the last post because it’s the same setup, with an SHT11 temperature/humidity sensor added on port 2. The current plan is to support the following hookups:

Either an ePIR via software serial or a PIR on DIO plus an LDR on AIO.

The SHT11 sensor, which requires a dedicated port.

Two pins for either 2 contact sensors or more I/O via I2C I/O expanders.

Up to ten DS18B20’s via a 1-wire interface.

This leaves one spare pin – for a status LED or to monitor the voltage.

Am still looking for alternatives for the SHT11 sensor – it’s more expensive than the rest of the components combined! Maybe I’ll fall back to a 1-wire DS18B20 sensor for just temperature and skip the humidity measurements in some rooms.

The software for the Pulse is mostly a matter of cobbling together existing bits and pieces. But first, the hub needs to be extended to better deal with packets coming from different nodes. Right now, I’m not logging the name and type of the originating node – whoops!

As for constructing actual nodes, I’m exploring some ideas for a daughterboard PCB that snaps onto a JeeNode. It should accommodate a few types of sensors, any of which can be omitted. But the tricky part is not the electrical aspect but the physical one: how is the end result mounted? what type of enclosure should I aim for? what sort of power brick / hookup to use? Lots of loose ends…

Here is an “ePIR” sensor (google it), connected to port 1 of a JeeNode (along with an LDR light sensor):

A simple Arduino sketch to read it once per second:

Sample output:

Where “Y” means motion detected and the number after it is the current light level. As you can see, I first shielded the light from the LDR and then waved in front of the passive-infrared sensor. Note that the LDR is connected to the ePIR, not the JeeNode.

This little application recovers the individual streams from the multiplexed data coming in over USB. Screens 1..5 show what is coming from each slave channel. Screen 6 displays what came in before the multiplexer was started.

Here’s a more interesting example with 5 RFM12B receivers (you won’t be able to read the text because I had to reduce the screenshot to fit this blog). The antennas are way too short, to force weak transmissions and bad reception. As you can probably glimpse, each of the slaves has trouble with the data, but in very different ways:

This application is written in Tcl/Tk, the script is available here. I’ll tweak it further over time to fit my needs.

It’s nice when things come together. The MuxShield is now able to re-program up to 5 attached slaves and then act as multiplexer for serial output from each of them.

Here’s how it works in practice:

Connect the MuxShield and plug a few slaves into it.

Make sure the switch is set to “PROG”.

Program a sample sketch for the slaves into it, e.g.:

Connect to the MuxShield with a terminal:
(that’s 3x two lines of output, every 3 seconds)

Sample output with the switch set to “RUN”:

In the “RUN” position, programming changes the MuxShield code of the ATmega328 itself.

I often forgot to put the switch in the right position while developing the MuxShield code, but once that is done it should no longer be an issue. Since the slave code is for an ATmega168, sending it to the MuxShield with the switch set to “RUN” will fail (the 328 bootstrap rejects the 168 re-programming request).

Note that the MuxShield also makes a fine stand-alone re-flash unit: just connect a slave and press reset with the switch set to “PROG”. Here’s a MuxShield with 5 slaves, all trying to say “Hi!” at the same time:

I’ve made good progress on the MuxShield – only some minor changes to the bootstrap were needed, here is a diff:

These extensions still fit in the current 2K boot loader area, but only just!

To summarize: the bootstrap watches the switch connected to pin 7. If it is high (which is also the case if the MuxShield is not connected), then nothing changes. But if it’s low, the following happens:

Change the bootstrap baudrate back to 19200.

Respond as if this is an ATmega168 (different signature bytes).

Store all incoming flash data at an offset of 0x3800.

The end effect is really, really simple: if the switch is in the RUN position, nothing changes and the Arduino behaves just like an ordinary ATmega328 board. If the switch is in the PROG position, the board looks like an ATmega168 board while programming. After that, it resumes its ATmega328 program as before.

One more step is needed to make this truly plug-and-play for re-flashing up to 5 connected FTDI slave boards: on startup, the MuxShield code must check if the switch is in the PROG position. If so, it must program each of the slaves with the data loaded in flash memory starting at offset 0x3800. Then finish off by starting the serial multiplexing logic.

Anyway – 2 out of 3 steps are done, this is going a lot smoother than expected!

Here is an extract of the code to multiplex 5 serial ports in software on an Arduino Duemilanove:

It’s a big bag of tricks, really. There is a timer running at 3x the baudrate, which detects start bits and then picks out data bits every three ticks. The crucial issue for the receivers is that the work is done in parallel for 5 input streams, but that these events are not happening at the same time. There are in fact 5 little state machine, each with their own independent state.

For the output, it’s slightly simpler: a buffer with all the 5 transmit bit states is scanned and sent out. The trick here is to fill that buffer with the proper bit patterns. When nothing is sent on a channel, its corresponding bit remains high in all values in the buffer. The transmit buffer has 30 entries, 3 per bit plus the start and stop bits. A simplification here is that all bytes are sent at the same time, i.e. start and stop bits occur at the same time on all active transmit channels.

The idea of multiplexing is that all received data is collected and sent out to the main (hardware) serial port, running at 57600 baud. Extra character codes 0x01 .. 0x05 are inserted into the multiplexed data stream to identify from which channel the data is coming. On the transmit / de-multiplexing side, the character codes 0x01 .. 0x05 are filtered out and used to indicate to which channel to send out the next characters.

If you connect two of these multiplexing shields back-to-back, you can send 5 independent bi-directional serial streams over a single 3-wire cable. Come to think of it, the following setup would make a great test for these multiplexing shields:

The full source code for the multiplexing sketch can be found here. It has been tested at 9600 baud (all receivers must run at the same speed). It probably works at higher speeds even, but this hasn’t been tested. At some point, the Atmega chip is going to get swamped while handling the barrage of timer 1 interrupts. I haven’t really tested the transmit part yet, i.e. the de-multiplexing side of things.

One of these days, I’d like to push the RFM12B radios a bit further, to see how they behave in high-traffic and high-noise situations. What I need really, is a convenient way to re-flash and monitor multiple JeeNodes. Here’s what I’ve come up with:

It’s an Arduino Duemilanove with a proto shield, containing 5 FTDI sockets for connecting slave boards. I’d like this new “MuxShield” to perform two tasks:

A serial line multiplexer which can send out commands to any connected board, as well as receive and report incoming data from all connected boards, at the same time.

A boot flash repeater which can reprogram the flash memory of each board, using the standard FTDI serial protocol.

The multiplexer makes it possible to collect data while running a multi-board send-receive test, while the repeater simplifies the development cycle when frequently altering the software. With the combination of both, I won’t need to constantly unplug boards or adjust IDE settings.

The idea for the repeater is to use a larger ATmega328 on the Duemilanove, and to reserve half its flash memory for the data which needs to be programmed into the slave boards (which for now will remain ATmega168’s).

A few more hardware details: 4 of the 5 FTDI connectors are jumpered to supply either +5V or +3.3V from an on-board regulator. And there’s a small slide switch (visible in the picture above) which determines whether the incoming flash program is intended for the Arduino or for the slave boards. I’ll add two status LEDs later, to make it easier to see what’s going on.

This setup is not limited to JeeNodes or to testing wireless radios, it works with other FTDI-based Arduino’ish systems such as the RBBB by Modern Devices or the DC Boarduino by Adafruit – there are no doubt several more.

Anyway, on the software side it’s going to be a challenge to make all of this work. And I’ll need to customize the Arduino bootstrap code.

The PCB’s arrived and again it looks like everything is working as intended. Here is the bare board:

Changes are really minor. But at least now this thing has a name on it, and all connectors have (tiny) texts next to them so it’s easier to remember what goes where and in which orientation.

Even with just two versions in existence so far, I’m already starting to get confused about pinouts, header orientation, etc. so I’ve started documenting this latest JeeNode board here (PDF).

The next steps will be to decide on a useful sensor setup, to decide on how to best power these units, and to distribute lots of them all over the house as part of my own DIY “Home WSN“. This is going to be fun!

(I’ve got a few extra boards and parts this time – let me know if you’re interested in tinkering with this stuff)

The point of several projects here is to monitor energy consumption, and probably also some weather data because it’s so easy to add. Where “monitoring” means logging as well as keeping measurement data in a database for quick access. But how do you make sure that all “readings” get logged, yet still retain the ability to adjust and extend the underlying database and software? It would be awful if each non-trivial change required conversion.

Here are a few basic design decisions I took for JeeMon:

Readings come in as text from the attached JeeNode, one line per reading.

All readings are time-stamped and appended to a logfile, in text format.

To keep things manageable, logfiles roll over to a new one on 0:00 GMT each day.

The first entry in a new logfile is the name and size of the previous one.

The database is treated as a cache: it can be reconstructed from the logs at any time.

And here’s a requirement I want to meet:

It must be possible to restart JeeMon at any time without losing readings.

The idea then is to “catch up” with the logs on each restart where possible, and to clear the cache db and reload it from scratch when the software changes are more substantial.

So what does it take to not lose any readings? Keeping in mind that JeeMon will run either on a little embedded Linux module right next to the central JeeNode, or on a personal Mac, Windows, or Linux computer. Well, first of all, this is why the central JeeNode has a backup battery and dataflash memory: it stays on at all times, and continues to receive and collect packets from all the other JeeNodes even when there is no JeeMon running. The duration of this autonomous operation will be fairly modest: a few hours or perhaps one day. Enough to handle brief power loss, to mess around with configurations, and to re-connect things occasionally.

This means there are now three places where data gets added and must be kept in sync with the rest:

(Four places if you also count the final destination: dynamically updating browser windows)

The dataflash memory gets a copy of each reading collected by the central JeeNode.

And lastly, the browser(s) present more or less detailed results, summaries, and derived info.

JeeMon will start up in logfile “catch up” mode: the current content of the dataflash memory will be checked against the last logfile entry. The first task is then to request old data from the JeeNode to bring the log files up to date. During this time, the JeeNode continues to add new incoming data to the dataflash.

Once all missed data has been transferred, the JeeNode switches to “real-time” mode, saving new readings to dataflash and sending them out to JeeMon at the same time. In real-time mode, the log files will track all readings as soon as they come in.

That’s just part of the story, though. Now JeeMon enters “db sync” mode. With information from the cache db, new entries and new log files are scanned and processed, with new readings added to the database. Once that is done, JeeMon switches to normal real-time operation.

All log files are kept online. Rebuilding a database from scratch is as simple as deleting the current one and restarting JeeMon. Since a full rebuild might take quite some time, the internal JeeMon webserver always starts up in a “please-wait” mode and switches to the real server after real-time operation has been enabled.

Part of the above logic has now been implemented. JeeMon resumes its logs, syncs / rebuilds its database as needed, and processes new readings while running. The firmware in the JeeNode to save and replay readings to and from dataflash is still work-in-progress, however.

So while the JeeHub / JeeNode needs to stay powered up, I can now restart JeeMon at will. Which is great, because that streamlines development.

If you follow this weblog regularly, you may have noticed that there is now one post per day, day-in-day-out and always at 0:01 CET. This is not because my working days and hours are so regular – far from it – or necessarily always late, but because this self-imposed daily schedule helps me stay focused.

It’s all supported by a bit of automation in WordPress – I simply try to keep a handful of posts scheduled “in the pipeline”, so that these writings aren’t driven by some sort of daily deadline panic. On some days I have nothing to say – and I don’t – while on others I’m pleased to find that I can touch on a couple of topics, some of which are hopefully of interest to you, dear reader.

Speaking of whom… it’s always nice to hear from you. I’d love to read about what interests you in this “Computing Stuff Tied to the Physical World” as the title of this weblog says, as well as your suggestions on how to further improve this weblog.

So much for the intermezzo on this first day of spring (for the northern hemisphere that is). Tomorrow’s post will resume with a photo, graphic, or sketch – as always.

Enjoy your reading!

PS. FYI, I recently added a bit more background info about me on the About page.

Not to worry: I’m not going to go crazy on the Jee<blah> naming used so far…

But I do need to give the different pieces some name. To be able to refer to them in these posts, but more importantly as names for the software for all this. I also need to introduce a basic structure (and some limits).

Here goes:

A JeeNode is this ATmega-with-4-ports-and-RFM12B thing. There may be lots of JeeNodes for various purposes. They can communicate with each other via wireless.

I use the Ports and RF12 libraries with JeeNodes, although this is not a hard requirement – both the JeeNodes and the libraries can be used in numerous other ways.

Each JeeNode has a letter ‘A’ to ‘Z’ assigned to it as node ID. Nodes are usually given a unique ID to avoid mixups, but this is not strictly required.

There can be up to 250 separate groups of JeeNodes. Nodes can only communicate with other nodes in the same group. Gateways between groups could be implemented later, if needed.

Most nodes will be pulse JeeNodes, i.e. running a specific piece of software called – you guessed it – “pulse”, which continuously monitors some attached sensors and reports the readings via wireless.

The JeeHub is either a JeeNode by itself connected to a Mac, Windows, or Linux PC via USB, or a JeeNode connected to Ethernet via a small dedicated Linux module.

This JeeNode-as-part-of-a-JeeHub is called the central node from now on. It runs a specific software configuration, also called “central”. There should always be exactly one central node.

The software running on the Mac, Windows, or Linux machine(s) is called the server from now on (how original, eh?). It consists of a system-dependent executable runtime called JeeMon plus the code and data for the application itself.

It probably doesn’t hurt to reiterate that “JeeNode” and “JeeHub” are hardware, whereas “JeeMon” and the Ports / RF12 libraries are software.

A light reflectance sensor detects the revolutions of the electricity meter. It is hooked up to a JeeNode, which counts the revolutions and sends its counter value to the central JeeHub node every 10 seconds.

For basic tracking of total electricity consumption, that’s all you need. Occasional packet loss has no influence on aggregated results since the counts are tracked near the sensor. The same works for gas and water consumption.

However, I also want to get a good estimate of the consumption rates in real time. This can be done by timing the rotation period, at millisecond resolution preferably. So the first improvement a while back was to let the sensor JeeNode send packets the moment a revolution is detected, and not just every 10 seconds. That way the central node can do millisecond-resolution timing, which is easy with a stable clock and Linux.

This works reasonably well, but only if reception is nearly perfect. Any lost packet messes up the preceding and the following timing estimate. Only with two packets sent right after a counter change can the period be measured. I kept the periodic 10-second sends enabled as fail-safe, but these late packets are useless for real-time rate calculations.

The next improvement was to let the sensor node do the millisecond timing. It wasn’t obvious how, though, as sensor nodes do not have a very accurate clock: a ceramic resonator has around 0.5% accuracy and probably also some temperature sensitivity. Turns out that it doesn’t really matter: as long as these real-time estimates are not summed together, errors won’t propagate any further.

So now the sensor node sends both the counter value and the last rotation period in milliseconds. The counter value is perfect for long term energy consumption monitoring – after all, it’s exactly the same as what the power company will use to charge me later. The millisecond period is a good estimate of current electricity use, and probably fairly stable from one measurement to the next. Absolute accuracy and drift are not so important here, because the main use of the real-time estimate is to see small changes as they occur.

Here’s an example of the entries logged on the JeeHub:

All log entries have the format “T [time] [millis] [type] …”. Where “time” is the time on the Linux module of the JeeHub in YYYYMMDD.HHMMSS format and “millis” is the current millisecond counter on the JeeNode inside the JeeHub. This might seem redundant, but keep in mind that the Linux module is not always on – it can pull data off the JeeNode when started up again. Additional timing data will come from the on-board DCF77 receiver once that is fully operational. So there are three sources of timing information inside the JeeHub: Linux, JeeNode, and the DCF77 atomic-clock reception. Each have different levels of accuracy and drift, but because all of them are logged, this can be fully determined later.

The raw text log files grow by around 0.5 Mbyte/day right now. Gzip compresses them to roughly 20% of that, so they can easily be kept around: the MMnet1001’s flash memory will hold several years of these full-detail logs.

Back to the actual log entries now.

The “HM2″ packets are from the electricity & gas metering node. Packets 56, 57, 58, 60, 61, 62, 63, 0, and 1 were lost (more on that later). The electricity revolutions went from 132 to 136 in this time frame, and the gas counter stayed at 139. The rotation time for the electricity meter in packet 54 was 74*256+209 = 19,153 ms. There is a third slot of four 0’s in each packet for measuring water consumption, currently waiting for a new sensor-enabled flow meter to be installed.

Looking at some calculated results, I think this setup will be able to track real-time power consumption with a resolution of under 1 Watt. The resolution actually improves with lower energy consumption rates – precisely what you’d want.

The VOLT and BARO entries are from sensors within the JeeHub. The ALT entry is weather data from a remote sensor and comes from another system for now.

A further improvement with the energy data was to switch to the latest RF12 library code and to use acknowledgements. Every time a packet has been properly acknowledged, the sensor node stops sending data until one of the counters changes. When no ack is received, data is resent every 3 seconds. With good reception most of the time, the number of packets sent (and logged) willl be quite small. And with packet loss, the data will usually arrive 3 or 6 seconds later anyway. Note how in the above log file excerpt each counter value from 132 through 136 was recorded, but retransmits were needed to get counts 134 and 135 to the JeeHub.

Final point: the wireless communication speed was raised from 38400 to 57600 baud – and reception appears to be at least as good as before.

Packet loss – I’ve been seeing long stretches of fairly bad reception at times. Until I realized that these coincided with our wireless headphone set being turned on. I don’t know what that thing is sending out into the ether, but it’s clearly interfering with the 868 MHz communication between JeeNodes. Oh well – it’s a good test for dealing with missed packets…

Ok, so I wanted to wrap the JeeHub prototype into some sort of enclosure…

Yeah, why not, a cardboard box.

Got a couple of these from SparkFun, from whom I’ve ordered a few times. The fit is very tight:

And all connectors come out on one side:

From left to right:

Access to the FTDI connector of the JeeNode

The ethernet port of the MMnet1001 Linux module

A mini USB plug, only used to supply power

DC power, has to be between 5 and 6 volt

In normal use, only the Ethernet and USB ports are hooked up. But even without anything connected, the JeeNode will continue to receive and log data packets (once I finish the dataflash code, that is).

The NAS in there is used as gateway to pass 868 MHz OOK data from a CUL receiver, which decodes signals from my KS300 weather station plus a couple of S300 temperature/humidity sensors. This will one day be replaced by on-board reception on the JeeHub, so that only the JeeHub needs to stay powered up at all times. All other sensors are hooked up to a couple of JeeNodes which transmit the readings wirelessly.

The Mac, Windows, Linux, and the JeeHub all run identical copies of the software, which is called “JeeMon”. It has a built-in web server, an embedded database, and a flexible set of network functions.

Each JeeMon instance will automatically self-update to the latest version on startup. During development on the Mac the JeeHub acts as transparent proxy, as if the different sensors were connected directly to the Mac (through a little Tcl-based system called “Tequila”). Once ready, the latest JeeMon release is wrapped into one file and placed on the internet. Finally, a restart of the JeeHub completes the upgrade.

That first screen dump above is a small test app on my Mac which bypasses JeeMon and connects directly to the JeeHub as Tequila client. I keep it open to check that data is coming in and gets saved on the JeeHub.

So this is the big picture for collecting energy/gas/water and environmental data in the house. The software can run on practically anything, can be accessed with a browser anywhere, and with proper security in place the various pieces can be connected and used across any network topology.

All of the above is working this very moment. The major task ahead is the full-scale processing, presentation, and interaction of it all. But that can now conveniently be done on my development machine, with HTML, CSS, JavaScript, etc.

Anyway, IMO this is a very flexible foundation for a 1-watt home monitoring server.

It needs just a 10 KΩ resistor, a 100 nF capacitor, and a wire jumper. The IC socket is optional :)

The jumper replaces the voltage regulator. If you later add the RFM12B module, use an FTDI interface which supplies 3.3V to this configuration, not 5V.

To make this work from the Arduino IDE, choose “Lilypad Arduino” as board – it’s set up to run off the internal 8 MHz RC clock. Then burn the corresponding bootloader to the chip (I use a USBtinyISP). Once that is done, you can upload and try out sketches.

This setup requires the modified “avrdude” software which is part of the Arduino-0013 IDE (version “5.4-arduino”). See this comment for why and how it confused me.

Update – All gcc/avrdude issues have been resolved in the Arduino-0014 IDE.

Well, I’m quite pleased with how the software on the AVR side of the JeeHub is working out. When you look at the collapsed version of the current 270 lines of C++ code, you get this:

You can see the full source code here.

Everything becomes a DataSource, i.e. an object which is polled periodically and which can then submit readings for further storage or processing. It’s trivial to add more data sources without affecting any existing code.

On startup each data source is created and registers itself automatically. For example, the “power” object is set up to get polled/measured every 10 seconds. When polled, it takes a few ADC voltage readings, puts these into a struct, and hands it to the DataSource::newReading() method.

Currently, newReading() does nothing more than turn around and call the show() method of that same data source, which then sends a plain text version of the data out over the serial line. For unattended operation, readings will need to be saved in dataflash memory for retrieval at some later moment.

The above code compiles to 8104 bytes on an ATmega168 so far. Lots of room remaining!

All the pieces work, at least in isolation. But the Linux board and the JeeNode haven’t been connected together yet (I need to figure out which serial port to use on the MMnet1001) and there is some strange interaction between the different interrupt-driven pieces on the JeeNode. Looks like both hardware and software troubles at this stage.

Here’s some output:

So it’s picking up RFM12B packets, reading external power and battery voltage levels, reading out temperature and barometric pressure, and decoding both the KlikAanKlikUit remote controls and the DCF77 clock signal. But there’s some stuff here which is definitely not kosher – could be interrupt handling issues.

Update – looks like gcc 4.3.0 has trouble with interrupt code. When I changed to 4.3.2, everything started working as expected.

There are also a few hardware glitches in this early prototype, such as the switching regulator interfering with the DCF77 receiver (will change to a linear one) and the 433 MHz radio interfering with the RFM12B (could add some decoupling or shielding).

This first version of the code has been added to the subversion repository.

I’m going to try and fit all the components of the prototype JeeHub onto an 8.5 x 11.5 cm board to match a little enclosure that’s been lying around here:

It looks like everything fits – though it’s a bit tight:

There are two subsystems: the MMnet1001 Linux module and the rest, based on a JeeNode. The “rest” is actually the core of the system since it will run day-in day-out, whereas Linux could be shut down when no ethernet access or fancy reporting is needed.

The remaining components on this set-up are:

a DCF77 receiver for accurate time tracking

a BMP085 barometric pressure sensor

a 433 MHz OOK receiver to pick up remote control commands

a 8 Mbit dataflash memory as piggy-back on the JeeNode

a status LED

Furthermore, the RFM12B wireless on the JeeNode can control standard 433 & 868 MHz radio-frequency units such as power switches.

Everything can be powered from a USB port or a 5..6V DC wall plug. The automatic battery back-up allows running the JeeNode core off-the-grid. It’s not a priority but I want to see to what extent a JeeHub can function on its own power. The Linux module will be powered by a 5 -> 3.3V regulator, with a shutdown-pin controlled from the JeeNode.

Much of the basic software for the JeeNode core has already been written. But that’s of course just the tip of this “home-monitoring and -control” iceberg…

The following interrupt-driven code will pick up signals from a “KlikAanKlikUit” remote control:

It should be relatively easy to adapt this to other units. Signals in different protocols can be decoded at the same time, since all decoding state is maintained in a separate state machine.

Sample output:

The KAKU units use a very crude signalling protocol, with no error checking other than sending a distinct bit pattern for 0’s and 1’s. The sample output has errors, in fact: the B7 after the B6 should have been a B6. It is probably best to only accept commands when they come in more than once in quick succession.

There can be quite a bit of noise from the receiver, in the form of random pulses. These will be ignored, but it may use up some CPU power to service all the corresponding interrupts.

Ok, so I tried to get the on-board 4 Mb dataflash of the MMnet1001 working, just out of curiosity…

That was a bad idea. Nothing went wrong for a while, but then I rebooted:

And then nothing. Whoops, I messed with the boot partition instead of the dataflash chip! Thankfully, tech support at Propox helped me out quickly. It’s actually quite easy to re-flash the MMnet1001: connect a USB cable to the USB device (not host) port pins, and then simply jump through a few basic software hoops. Neat – well done.

Ah, that looks better:

And so on.

So the 4 Mb dataflash remains a mystery for now. No problem, the 1 Gb NAND flash is the main deal, and it works just fine. I’ve added about 7 Mb of my own so far, but that still leaves plenty of free space:

The hardware clock works fine, but it needs to be set once before reading it out to get rid of an error message. IOW, set the time zone in “/etc/config/system” (I used “CET-1″), then set the proper date and time with “date”, then finish with “busybox hwclock -w -u”. Note that the “/sbin/hwclock” version doesn’t work for setting the clock (it seems to be ok for readout).

On the software side, I now have a Tclkit build cross-compiled via the OpenWrt SDK and working on the MMnet1001, so the rest of the work can be done on my development system and then copied to this amazing little Linux, eh… box? plug? chip?

The MMnet1001 is an interesting little setup, based on the AT91 ARM chip. Here’s a close-up image, as provided by Propox:

The ethernet connector is about the only hint you get on how small this thing actually is. It’s shorter than a JeeNode (and it has a lot more hardware!).

I did not order the development board with this, given that I only need minimal hardware interfacing. So my first try was to simply hook up 3.3V power to J2-1 and J2-2 and plug in an Ethernet cable.

Hmm, nothing happens. No new device shows up on the LAN. It turns out that the bootstrap uses a debug serial line, and unfortunately in this revision the internal pull-up on the RX pin is not enabled. So the bootstrap picks up something on the line, and then waits for a complete command.

A 10 KΩ pull-up resistor on J1-13 fixes it. The user LED is flashing!

Now I can see a network device, but it won’t let me in via SSH and I don’t see an HTTPD server on port 80 either.

Ok, time to hook up the serial port @ 115200 baud via an FTDI cable. Aha!

(actually, this is the text I get after editing out some cruft from “/etc/issue”, not a first-time hookup)

Great. I’m in. And there’s a “dropbear” SSH. Ok, turns out the root password hasn’t been set – that’s easy to fix.

Yes! Now I can connect over ethernet at last:

Perfect. The serial line is no longer needed. This thing now boots up and lets me in via SSH without further tweaking.

Power consumption @ 3.3V is about 250 mA idle and 350 mA when running the CPU at full load. Here are some more system specs:

Meet the JeeHub, a self-contained server and gateway between networked JeeNodes and an Ethernet network:

On the right is a Propox MMnet1001 module with an AT91 ARM processor, 64 Mb RAM, and 1 Gb flash, running Linux. On the left is a JeeNode, to be used as receiver and central node in the 868 MHz wireless connection with all other JeeNodes. It hasn’t been hooked up yet – this was just a mock-up to make a pretty picture.

The software on the JeeHub is portable, the same code also runs on Windows, Mac OS X, and Linux x86. The benefit of a JeeHub is that you don’t have to leave a PC on to collect / process / present all measurement data, or to control devices around the house. The JeeHub draws less than 1 watt of power and can be left on to provide all these functions around the clock. It has a built-in web server and database, and can connect to other systems on the local network as well as the internet to perform both interactive and unattended tasks.

The basic JeeHub hardware and software is working here now, with automatic self-updates for completely maintenance-free use, but things are still changing far too quickly to document them and turn this loose.

Major changes were the swapping of pins 1 + 6 on each port and flipping around the FTDI connector so plugin adapters no longer end up being upside-down (doh!).

Plus lots of relatively minor changes, such as tiny connector pin markings in the top copper layer, moving ports 1 + 4 an extra 0.1″ towards the radio, making all power traces thicker, and making the board slightly narrower. I didn’t want to dive into silkscreens yet, though in hindsight even the default one would have been workable.

Some cosmetic changes too: added a descriptive “JeeNode v2″ text on the bottom layer and a ground plane fill.

It’s quite easy to talk to this device. Here’s the sample output of reading and writing 100 blocks:

It looks like reading takes about 1.1 msec per block and writing 8.6 msec. A scan over all 4096 blocks while reading only 8 bytes from each takes less than half a second, so it’s definitely feasible to scan the full memory when starting up.

Although the RFM12B was designed for FSK (frequency-shift keying), it can also be used for OOK (on-off keying) transmissions. The trick is simply to turn its transmitter on and off via the SPI interface.

This can be used to control simple RF-controlled devices such as the FS20 power control units by Conrad and ELV in Germany. Here’s a sketch which turns a remote device (lamp, etc) on and off:

It turns out that the 868 MHz version of the RFM12B can even transmit 433 MHz signals, at least for simple OOK. The following example turns a device on and off via the low-cost KlikAanKlikUit units sold in the Netherlands, using the same 868 MHz radio module as above:

Both demo’s have been added to the RF12 source code library. Other slow-rate bit-stream protocols similar to the above could easily be added.

No attempt has been made to receive OOK signals right now, though one could imagine reading out the RSSI bit to determine the presence of a carrier…

The Ports library described in recent posts works fine with any type of Arduino, Freeduino, etc – not just JeeNodes. It merely uses some conventions for the “DIO” and “AIO” pins of each of the 4 ports.

Here is an example using a HM55B compass module from Parallax, using an Arduino Duemilanove with a Proto Shield from AdaFruit:

There are actually two sensors in the above setup – the bigger sensor is a Parallax H48C 3-axis accelerometer (more on that below). Both need +5V to operate, so they won’t work with simple 4-pin ports on a JeeNode.

Ports are mapped to the Arduino pins as follows:

Port 1 DIO = Arduino digital pin 4 (PD4)

Port 1 AIO = Arduino analog pin 0 (PC0)

Port 2 DIO = Arduino digital pin 5 (PD5)

Port 2 AIO = Arduino analog pin 1 (PC1)

Port 3 DIO = Arduino digital pin 6 (PD6)

Port 3 AIO = Arduino analog pin 2 (PC2)

Port 4 DIO = Arduino digital pin 7 (PD7)

Port 4 AIO = Arduino analog pin 3 (PC3)

The ATmega register bits are listed in parentheses.

Here is the full code of the HM55B driver plus demo:

Sample output:

The H48C 3-axis accelerometer demo is very similar, source code can be found here. Sample output:

These two hookups both use some new utility code in the Ports library to shift a specified number of bits in and out of the DIO line while clocking the AIO line. Note also that these sensors needs two ports each, since they both use 3 IO lines for their SPI-like interface.