Computing stuff tied to the physical world

Posts Tagged ‘JeeNode’

Sharing Node ID’s

In Software on Mar 30, 2013 at 00:01

The RF12 driver has a 5-bit slot in its header byte to identify either the sender or the destination of a packet. That translates to 32 distinct values, of which node ID “0” and “31” are special (for OOK and catch-all use, respectively).

So within a netgroup (of which there can be over 250), you get at most 30 different nodes to use. Multiple netgroups are available to extend this, of course, but then you need to set up one central node “listener” for each netgroup, as you can’t listen to multiple netgroups with a single radio.

I’m using JeeNodes all over the place here at JeeLabs, and several of them have been in use for several years now, running on their own node ID. In fact, many have never been reflashed / updated since the day they were put into operation. So node ID’s are starting to become a bit scarce here…

For testing purposes, I use a different netgroup, which nicely keeps the packets out of the central HouseMon setup used for, eh… production. Very convenient.

But with the new JeeNode Micro, I actually would like to get lots more nodes going permanently. Especially if the coin cell version can be made to run for a long time, then it would be great to use them as door sensors, lots more room nodes, and also stuff outside the house, such as the mailbox, humidity sensors, and who knows what else…

Now the nice thing about send-only nodes such as door sensors, is that it is actually possible to re-use the same node ID. All we need is a “secondary ID” inside the packet.

I’ve started doing this with the radioBlip2 nodes I’m using to run my battery lifetime tests:

Screen Shot 2013-03-26 at 10.11.14

(BATT-0 is this unit, BATT-1 is a JNµ w/ coin cell, BATT-2 is a JNµ w/ booster on 1x AA)

This is very easy to do: add the extra unique secondary ID in the payload and have the decoder pick up that byte as a way to name the node as “BATT-<N>”. In this case, it’s even compatible with the original radioBlip node which does not have the ID + battery levels.

Here is the payload structure from radioBlip2, with secondary ID and two battery levels:

struct {
  long ping;      // 32-bit counter
  byte id :7;     // identity, should be different for each node
  byte boost :1;  // whether compiled for boost chip or not
  byte vcc1;      // VCC before transmit, 1.0V = 0 .. 6.0V = 250
  byte vcc2;      // battery voltage (BOOST=1), or VCC after transmit (BOOST=0)
} payload;

And here’s the relevant code snippet from the radioBlip.coffee decoder in HouseMon:

  decode: (raw, cb) ->
    count = raw.readUInt32LE(1)
    result =
      tag: 'BATT-0'
      ping: count
      age: count / (86400 / 64) | 0
    if raw.length >= 8
      result.tag = "BATT-#{raw[5]&0x7F}"
      result.vpre = 50 + raw[6]
      if raw[5] & 0x80
        # if high bit of id is set, this is a boost node reporting its battery
        # this is ratiometric (proportional) w.r.t. the "vpre" just measured
        result.vbatt = result.vpre * raw[7] / 255 | 0
      else
        # in the non-boost case, the second value is vcc after last transmit
        # this is always set, except in the first transmission after power-up
        result.vpost = 50 + raw[7] if raw[7]
    cb result

In case you’re wondering: the battery voltage is encoded as 20 mV steps above 1.0V, allowing a single byte to represent values from 1.0 to 6.1V (drat, it’ll wrap when the boost version drops under 1.0V, oh well…).

Note that this trick works fine for send-only nodes, but it would need some additional logic in nodes which expect an ACK, since the ACK will be addressed to all nodes with the same ID. In many cases, that won’t matter, since presumably all the other nodes will be sound asleep, but for precise single-node ACKs, the reply will also need to include the extra secondary ID, and all the nodes will then have to check and compare it.

So now it’s possible to re-use a node ID for an entire “family” of nodes:

  • over 250 different netgroups are available for use
  • each netgroup can have a maximum of 30 different node ID’s
  • each node ID can be shared with over 250 send-only nodes

That’s over 1.8 million nodes supported by the RF12 driver. More than enough, I’d say :)

JN Micro v3 reference

In AVR on Mar 23, 2013 at 00:01

As promised, here is the reference card for the JeeNode Micro v3:

qrc-jm-v3-part

(Click on the image to see the full-size version)

Note: the definitions in Ports.h were incorrect for the JeeNode Micro. Please make sure you update to the latest version of JeeLib if you intend to use the Port or PortI2C classes with the ATtiny84 on the JeeNode Micro!

The thing with diagrams such as these, is that they are hampered by file format wars, with all full-featured drawing apps going out of their way to lock people in. In this case, the diagrams where created by Marco Bakker in Visio on Windows – which I don’t have – so I imported it into OmniGraffle for Mac – which is in turn useless on other platforms.

Luckily, PNG and PDF have become de-facto standards which every browser knows how to display – so rendering the diagrams at least produces results everyone can use.

Maybe one day, we’ll all be using SVG editors. There’s a web-based one called SVG-edit, but it doesn’t seem to be quite there yet w.r.t. importing the SVG from OmniGraffle. There is also the multi-platform Inkscape, which does import the SVG very nicely (just one minor font size issue, as far as I can tell). But the UI is a bit quirky on the Mac, since it has to conform to the XQuartz conventions of the X.Org X Window System (aka X11).

I’ve updated the Pinouts page on the Hardware wiki to include these new Quick Reference Cards, and have attached the design and output files in different formats.

JeeNode v6 reference

In AVR on Mar 22, 2013 at 00:01

What started out as a great initiative on the forum has now become a complete “Quick Reference Card” for the JeeNode v6. With many many thanks to @mars for working out all the details and tweaks and for sharing his design files:

qrc-jn-v6-part

(Click on the image to see the full-size version)

Here is the legend and the Creative Commons attribution:

legend   attribution

Tomorrow, I’ll post the other reference card for the JeeNode Micro (after a bit more checking), along with links to the final version in several formats on the wiki.

Meet the JeeNode Micro v3

In AVR, Hardware on Mar 2, 2013 at 00:01

There’s a new kid in town, the JeeNode Micro v3 with ATtiny84 + optional boost converter:

DSC_4392

(Can you spot the differences? That’s without and with buck/boost converter…)

It’s even shorter than the v2, and has all the components on one side again:

DSC_4385

The main reason for the reduced size is the reduced number of header pins. One of the biggest changes in that regard, is that v3 no longer has a full 2×3 ISP header – just the 4 data pins. The idea is that GND and +3V can be connected to the 8-pin “port+” header.

As it so happens, there’s a fifth pad on the bottom side of the PCB which connects to GND. This can be put to good use for experimentation, by connecting some headers as follows:

DSC_4393

Note that the 6th pin was removed from the female header – this is very easy to do: just pull on the pin from the bottom with some pliers and it’ll slide out.

That leaves just power to be connected up for SPI programming. More details tomorrow…

Dive Into JeeNodes

In AVR, Hardware, Software, Linux on Feb 1, 2013 at 00:01

Welcome to a new series of limited-edition posts from JeeLabs! Read ’em while they last!

Heh… just kidding. They’ll last forever of course, as does everything on this thing called internet. But what I’m going to describe in probably a dozen posts or so is the following:

dijn-essence

Hm, that doesn’t quite explain it, I guess. Let me try again:

JC's Grid, page 63

So this is to announce a new “DIJN” series of weblog posts, describing how to set up your own Wireless Sensor Network with JeeNodes, as well as the infrastructure to report a measured light-level somewhere in your house, in real time. The end result will be fully automated and autonomous – you could take your mobile phone, point it to your web server via WiFi, and see the light level as it is that very moment, adjusting as it changes.

This is a far cry from a full-fledged home monitoring or home automation system, clearly – but on the other hand, it’ll have all the key pieces in place to explore whatever direction interests you: ready-made sensors, DIY sensors, your own firmware on the remote nodes, your own web pages and automation logic on the central server… it’s up to you!

Everything is open source, which in this context matters a lot, because that also means that you can really dive into any aspect of this to learn and explore the truly magical world of Physical Computing, Wireless Sensor Networks, environmental sensing and control, as well as state-of-the art web technologies.

The focus will be on describing every step needed to implement this from scratch. I’ll cover setting up all the necessary software and hardware, in such a way that if you know next to nothing about any of the domains involved, you can still follow along and try it out – whether your background is in software, electronics, wireless, or none of these.

If technology interests you, and if I can bring across even a small fraction of the fun there is in tinkering with this stuff and making new things up as you g(r)o(w) along, then that would be a very nice reward for everyone involved, as far as I’m concerned.

PS. “Dijn” is also old-Dutch for “your” (thy, to be precise). Quite a fitting name in my opinion, as this sort of knowledge is really yours for the taking – if you want it…

PPS. For reference: here is the first post in the series, and here is the overview.

Bad LiPo charge chip

In Hardware on Jan 26, 2013 at 00:01

(Not planned this way, but still a nice follow-up on yesterday’s Junk USB post…)

While thinking about some minor tweaks for the JeeNode USB board, I wanted to try out a different LiPo charger chip – mostly to reduce costs, given than not everyone using the JN USB would be interested in the LiPo charge capability (it’s also fine as a JeeNode-with-built-in-USB-BUB after all).

So I had a look at the MCP73832T – in fact, Paul Badger and I went ahead and had a new board made with it:

DSC 3220

The good news: as a LiPo charger, it works absolutely fine.

The bad news: without an attached LiPo battery, it’s not usable.

It turns out that this chip uses some sort of charge/discharge cycle. This is what happens without LiPo attached:

SCR34

IOW, it’s delivering 4.2V for a while, and then dropping the voltage to see whether the LiPo itself will fill in the gaps. A pretty clever way to figure out the state of the attached battery, if you ask me.

One way to use the chip without attached LiPo would be to bypass the Vin and Vout pins of the chip, i.e. just disable it altogether via a (solder-) jumper. Drawbacks: 1) you have to remember this, and act accordingly, 2) this means PWR would be 4.2V with LiPo attached, and 5V without, and 3) when bypassed, there would be no over-current protection for the USB port.

Especially that 3rd issue is bad – JeeNodes are about tinkering with stuff, and JN USB’s are about tinkering while attached to a computer USB port. Without over-current protection, tinkering can damage your computer – scary!

There is one more way to solve this, but it’s not very practical: add a big electrolytic cap which sort of takes the place of a battery. I used a 6800 µF (which pulls too much current on power-up, BTW). The result:

SCR36

A voltage on the PWR pin which carries 3.8 .. 4.2V, with a 10 Hz ripple. Not great, but good enough to make the JeeNode’s internal regulator work. Except that a 6800 µF capacitor is huge and highly impractical, of course!

Sooo… back to the MAX1555 it is. That chip works differently: it senses the charge current and the output voltage.

Note to self: don’t replace chips without testing all essential modes they’ll be used in.

And good bye Mr. Murphy, how considerate of you to drop by once in a while…

Assembling the LED Node v2

In AVR, Hardware on Dec 28, 2012 at 00:01

After yesterday’s little mistake, here’s a walk-through of assembling the LED Node v2:

DSC_4332

Note that the LED Node comes with pre-soldered SMD MOSFETs so you don’t have to fiddle with ’em.

The LED Node is really just a JeeNode with a different layout and 3 high-power MOSFET drivers, to control up to 72W of RGB LED strips through the ATmega’s hardware PWM. Since there’s an RFM12B wireless module on board, as well as two free JeePorts, you can do all sorts of funky things with it.

As usual, the build progresses from the flattest to the highest components, so that you can easily flip the PCB over and press it down while soldering each wire and pin.

Let’s get started! So we begin with 7 resistors and 1 diode (careful, the diode is polarised):

DSC_4333

Be sure to get the values right: 3x 1 kΩ, 3x 1 MΩ, and 1x 10 kΩ (next to the ATmega).

(note: I used three 100 kΩ resistors i.s.o. of 1 MΩ, as that’s what I had lying around)

Next, add the 4x 0.1 µF capacitors and the IC socket – lots of soldering to do on that one:

DSC_4334

Then the MCP1702 regulator and the electrolytic capacitor (both are polarised, so here too, make sure you put them in the right way around), as well as the male 6-pin FTDI header:

DSC_4335

Soldering the RFM12B wireless radio module takes a bit of care. It’s easiest if you start off by adding a small solder dot and hold the radio while making the solder melt again:

DSC_4336

Then solder the remaining pins (I tend to get lazy and skip those which aren’t used, hence not all of them have solder). I also added the 3-pin orange 16 MHz ceramic resonator, the antenna wire, the two port headers, and the big screw terminal for connecting power:

DSC_4337

Celebration time – we’ve completed the assembly of the LED Node v2!

Here’s a side view, with the ATmega328 added – as you can see it’s much flatter than v1:

DSC_4338

And here’s a top view of the completed LED Node v2, in all its glory:

DSC_4339

You can now connect the FTDI header via a USB BUB, and you should see the greeting of the RF12demo sketch, which has been pre-loaded onto the ATmega328.

To get some really fancy effects, check out the Color-shifting LED Node post from a while back on this weblog. You can adjust it as needed and then upload it through FTDI.

Next step is to attach your RGB strip (it should match the 4-pin connector on the far left). Be sure to use fairly sturdy wires as there are up to 2 amps going through each color pin and a maximum of 6 amps total through the “+” connector pin!

Lastly, connect a 12V DC power supply (making absolutely sure to get the polarity right!) and you will have a remote-controllable LED strip. Enjoy!

Meet the JeeNode Micro v2

In Hardware on Dec 2, 2012 at 00:01

Just in yesterday, haven’t even had the time yet to assemble it!

DSC 4294

Dig that JeeLabs logo on there! :)

As you can see, the shape and layout have not changed much in this revision:

JMv2 traces

Here’s the main part of the new JeeNode Micro v2 schematic:

Screen Shot 2012 12 01 at 16 23 13

Several major changes:

  • the power to the RFM12B module is now controlled via a MOSFET
  • the PWR pin is connected to the +3V pin with 2 diodes
  • there’s room for an optional boost regulator (same as on the AA Power Board)
  • and there’s even room for a RESET button

When you look at the PCB’s, you’ll see that the extra headers have all been removed, there is just one 9-pin header left – the “IOX” signal from v1 now controls power to the RFM12B.

Through a sneaky placement of the ISP header, there is still a way to connect a single-cell AA or AAA battery to opposite ends of the board.

This extra power control is intended to reduce the current consumption during startup, but I haven’t tried it yet. The idea is that the RFM12B will not be connected to the power source before the ATtiny starts and verifies that the voltage level is high enough to do so. After that, it can be turned on and immediately put to sleep – in practice, its power probably never needs to be turned off again.

The other main change has to do with the different power options:

  • 2.2 .. 3.8V through the +3V pin, intended for 2-cell batteries of various kinds
  • 3.5 .. 5.1V through the PWR pin, for 5V and LiPo use
  • 0.9 .. 5.1V through the PWR pin when the boost regulator is present

The latter might seem the most flexible one, but keep in mind that the boost regulator has a 15 .. 30 µA idle current draw, even when the rest of the circuit is powered down, so this is not always the best option (and the extra switching supply components add to the cost).

As you can imagine, I’ll be running some final tests on all this in the next few days – but the new unit is now available for pre-order in the shop (“direct power” version only for now, the boost version will be available later this month). Design files are in the Café.

The JeeNode, as seen from 15.24 km

In AVR, Hardware on Dec 19, 2011 at 00:01

(that’s 50,000 feet, or 9.47 miles – if those units mean more to you)

This post was prompted by a message on the forum, about what this whole “JeeNode” thing is, really.

Here are a JeeNode v6 and an Arduino Duemilanove, side by side:

DSC 2826

Let me start by saying, tongue-in-cheek: it’s all Arduino’s fault!

Because – let’s face it – the core of each Arduino and each JeeNode is really 95% the same: an Atmel AVR ATmega328P chip, surrounded by a teeny little bit of support circuitry and placed on a printed circuit board. So part of the confusion comes from the fact that the Arduino introduced its own conventions, moving it further away from the underlying common ATmega technology.

The differences between an Arduino Duemilanove and a JeeNode v6 – which resemble each other most – are:

  • the JeeNode has a “skinnier” shape, incompatible with Arduino “shields”
  • the Arduino runs at 5V, whereas the JeeNode runs at 3.3V (this carries through to all I/O pins)
  • the JeeNode includes a wireless radio module, called the RFM12B by HopeRF
  • the Arduino includes an FTDI <-> USB interface, while the JeeNode relies on an external one

There are many other differences, of course – so let’s continue this list a bit:

  • the Arduino’s “eco-system” is far, far bigger than the JeeNode’s (translation: everyone who finds out about JeeNodes probably already knows about the Arduino platform, and usually already has one or more of ’em)
  • this carries through to articles, websites, books, and discussion forums – Arduino is everywhere
  • you can do lots of stuff with an Arduino without ever touching a soldering iron, whereas the JeeNode is really not usable without some soldering (even if just to solder on a few pin headers)
  • different pinouts… it’s one big conspiracy to confuse everyone, of course! (just kidding: see below)

My reasons for coming up with the JeeNode have been documented in the past on this weblog, and can be summarized as: 1) running at 3.3V for lower power consumption and to better match modern sensors and chips, and 2) supporting a simpler form of expandability through the use of “plugs” – little boards which can be mixed and matched in many different combinations.

On the software side, JeeNodes remain fully compatible with the Arduino IDE, a convenient software environment for Windows, Mac, and Linux to develop “sketches” and upload them to the board(s).

The biggest stumbling block seems to be the way pins are identified. There are 4 conventions, all different:

  • Atmel’s hardware documentation talks about pins on its internal hardware ports, in a logical manner: so for example, there is a port “D” with 8 I/O pins numbered 0..7 – the sixth one would be called PD5.
  • Then there is the pin on the chip, this depends on which chip and which package is being referred to. On the 28-pin DIP package used for an ATmega328P, that same PD5 pin would be identified as pin 11. That’s the 11th pin, counting from the left side of the chip with pin 1 at the top.
  • The Arduino run-time library has software to control these pins. For a digital output pin, you can set it to “1” for example, by writing digitalWrite(5,1). This resembles PD5, but it fails for other pins (PB0 is “8” in Arduino-land, and PC1 is “1” if used as an analog input, or “15” if used otherwise – go figure…).
  • The JeeNode organizes several pins as part of 6-pin “Ports” (no relation to Atmels terminology!), each of them having 1 digital and 1 analog-or-digital pin.

The thing about JeeNode Ports is that there are 4 of them, and they can all be used for plugs in the same way. To support this, there’s a Ports library which lets you define port objects. This is an abstraction layer on top of the Arduino runtime. The reason is that it lets you associate a port object with a header on the JeeNode:

    Port myport (2);

Then you can connect your hardware / sensor / plug / whatever to the header marked “P2” on the JeeNode, and access it as follows:

    myport.digiWrite(1);

This happens to be the same pin as in the examples above, i.e. PD5 of an ATmega, pin 11 of the 28-pin DIP chip, and digitalWrite(5,1) on an Arduino. This also means that there are numerous ways to perform the same action of setting pin 11 of the chip to a logical “1” (i.e. 3.3V or 5V):

  • the “raw” C-level access, using Atmel’s register conventions and definitions (fastest, by far):

        PORTD |= 1 << 5;  // or ...
        PORTD |= _BV(5);  // same thing
        bitSet(PORTD, 5); // same thing, using an Arduino macro
    
  • the Arduino way of doing things:

        digitalWrite(5, 1);
    
  • the JeeNode Ports library way of doing things, as shown above:

        Port myport (2);
        myport.digiWrite(1);
    
  • … let’s throw in an extra bullet item, since every other list in this post appears to come in fours ;)

The one (minor) benefit you get from using the Ports approach on a JeeNode, is that if you attach your hardware to a different port, say port 3, then you only need to change a single line of code (to “Port myport (3);” in this case). The rest of the code, i.e. everywhere where its pins are being read or written, can then remain the same.

For an overview of all pinout differences, see also this weblog post. For full details, see the JeeNode PDF docs.

The beat goes on

In Hardware on Sep 4, 2011 at 00:01

Today, a milestone was reached:

    $ jeemon examples/driver-demo/
    15:45:01.975 RF12demo config usb-A700fdxv RF12-868.5
    reading:RF12-868.5.3:radioBlip:ping = 493295
    reading:RF12-868.5.3:radioBlip:age = 365
    ^C

That’s nearly half a million packets, one every 64 seconds, all on a single LiPo battery charge:

Screen Shot 2011 09 03 at 15 51 53

The setup is very simple. A 1300 mAh LiPo battery (I just picked one up in a camera shop with a convenient size), attached to a JeeNode USB:

At 3.94 V the battery is still far from dead, so it’ll probably stay alive for quite a bit longer…

The sketch running on this node is:

Screen Shot 2011 09 03 at 16 14 28

(looks like I had lost the low-power stuff in the “radioBlip” code, now fixed on GitHub)

Lots of low-power nodes are holding out nicely here at JeeLabs, by the way. There are about half a dozen permanent room nodes, and with the latest roomNode sketch they just keep going. Some are running on 3x AA rechargeable EneLoop batteries, others use 3x AAA with even less juice, and all of them have been running with just a single charge since the beginning of this year.

JeeNode with a 32 KHz crystal

In AVR, Hardware on Jun 28, 2011 at 00:01

Another experiment: running a JeeNode on its internal 8 MHz RC clock while using the crystal input to run timer 2 as an RTC. This would allow going into a very low-power mode while still maintaining a much more accurate sense of time.

To this end, I modified a JeeNode SMD, by replacing the 16 MHz resonator with a 32 KHz crystal:

Dsc 2599

I didn’t even bother adding capacitors, these are probably not needed with this crystal (same as on the RTC Plug) since there is probably enough parasitic capacitance already.

The tricky part is the code, since the ATmega is now running in a not-so-Arduino-like mode. Could almost have used OptiBoot with this setup, but the only internal RC clock build for it is the LilyPad, which has an ATmega168.

I ended up using the ISP programmer. IOW, I now compile for “LilyPad w/ 328” and then bypass the bootstrap and serial-upload. Less convenient, but it works.

Here’s a quick test sketch which writes a dot on the serial line exactly once a second:

Screen Shot 2011 06 24 at 15.51.49

So this setup is working. It draws 4.10 ma, consistent with the recent current measurements: slightly less than with the 16 MHz resonator pre-scaled by two.

In idle mode, current use drops to 1.71 mA, not bad!

Now let’s power down with just the timer running as real time clock. There’s a special “power save” mode which does just that. The difference is that timer 0 will now be off, so there won’t be interrupts waking up the ATmega every 1024 µs (as side-effect, the millis() function will start to lose track of time):

Screen Shot 2011 06 24 at 16.15.04

A small adjustment is needed to make sure the serial port is finished before we go into low-power mode, hence the call to delay(3).

Hm, power consumption is still 0.67 mA – quite a bit, given that we’re really powering down most of the time.

Ah, wait. I forgot to turn off the radio. Doing that brings the reading down to 0.15 mA – and I forgot to turn off the ADC and other sub-systems. Now we’re down to … 0.05 mA, while still printing dots:

Screen Shot 2011 06 24 at 16.39.15

Note that these 1 second interrupts are very accurately timed, more so even than with the standard 16 MHz resonator. This could be used to perform time-domain tricks on the wireless side, i.e. waking up just in time whenever a “scheduled” packet is expected to come in – as described in yesterday’s post.

There’s probably more left to try. The delay is running on full power, waiting for the serial output to clear the USART. It could be done while in idle mode, for example. Anyway… that entire delay becomes superfluous when we stop sending out debugging output over the serial port.

So there you have it – a JeeNode running at ≈ 8 MHz, with a precise 32,768 Hz pulse feeding timer 2, in a way which supports low-power sketches while maintaining an accurate sense of time.

Wanna make a clock?

Time-controlled transmissions

In Hardware, Software on Jun 27, 2011 at 00:01

Receiving data on remote battery-powered JeeNodes is a bit of a dilemma: you can’t just leave the receiver on, because it’ll quickly drain the battery. Compare this to sending, where nodes can easily run for months on end.

The difference is that with a remote node initiating all transmissions, it really only has to enable the RFM12B wireless module very briefly. With a 12..23 mA current drain, brevity matters!

So how do you get data from a central node, to remote and power-starved nodes?

One way is to poll: let the remote node ask for data, and return that data in an ACK packet as soon as asked. This will indeed work, and is probably the easiest way to implement that return data path towards remote nodes. One drawback is that if all nodes start polling a lot, the band may become overloaded and there will be more collisions.

Another approach is to agree on when to communicate. So now, the receiver again “polls” the airwaves, but now it tracks real time and knows when transmissions for it might occur. This is more complex, because it requires the transmitter(s) and receiver(s) to be in sync, and to stay in sync over time.

Note that both approaches imply a difficult trade-off between power consumption and responsiveness. Maximum responsiveness requires leaving the receiver on at all times – which just isn’t an option. But suppose we were able to stay in sync within 1 ms on both sides. The receiver would then only have to start 1 ms early, and wait up to 2 ms for a packet to come in. If it does this once a second, then it would still be on just 0.2% of the time, i.e. a 500-fold power saving.

Let’s try this out. Here’s the timedRecv.pde sketch (now in the RF12 library):

Screen Shot 2011 06 24 at 20.54.37

It listens for incoming packets, then goes into low-power mode for 2 seconds, then it starts listening again. The essential trick is to report two values as ACK to the sender: the time the receiver started listening (relative to that receiver’s notion of time), and the number of milliseconds it had to wait for the packet to arrive.

There’s no actual data processing – I’m just interested in the syncing bit here.

The sender side is in the timedSend.pde sketch:

Screen Shot 2011 06 24 at 20.58.17

This one tries to send a new packet each time the receiver is listening. If done right, the receiver will wake up at just the right time, and then go to sleep again. The ACK we get back in the sender contains valuable information, because it lets us see how accurate our timing was.

Here’s what I get when sending a new packet exactly 2,096 milliseconds after an ACK comes in:

Screen Shot 2011 06 24 at 20.39.33

Not bad, one ack for each packet sent out, and the receiver only has to wait about 6 milliseconds with its wireless receiver powered up. I’ve let it run for 15 minutes, and it didn’t miss a beat.

For some reason, send times need to be ≈ 2.1 s instead of the expected 2.0 s.

Now let’s try with 2,095 milliseconds:

Screen Shot 2011 06 24 at 20.37.17

Something strange is happening: there’s consistently 1 missed packet for each 5 successful ones!

My hunch is that there’s an interaction with the watchdog timer on the receiver end, which is used to power down for 2000 milliseconds. I suspect that when you ask it to run for 16 ms (the miminum), then it won’t actually synchronize its timer, but will fit the request into what is essentially a free-running counter.

There may also be some unforeseen interaction due to the ACKs which get sent back, i.e. there’s a complete round-trip involved in the above mechanism

Hmm… this will need further analysis.

I’m using a standard JeeNode on the receiving end, i.e. running at 16 MHz with a ceramic resonator (specs say it’s 0.5% accurate). On the sender side, where timing is much more important, I’m using a JeeLink which conveniently has an accurate 16 MHz crystal (specs say it’s 10 ppm, i.e. 0.001% accurate).

But still – even this simple example illustrates how a remote can receive data while keeping its wireless module off more than 99% of the time.

Current measurements

In AVR, Hardware on Jun 26, 2011 at 00:01

Wanted to check a few things w.r.t. current consumption of a JeeNode. The old way of doing this was a bit inconvenient, so I made a new test setup:

Dsc 2597

(old one on the left, new one on the right)

Sturdier, no need to disconnect the multimeter to short it out, and most importantly: high-side current sensing! That’s quite important, because multimeters can add a small voltage drop when used in current measurement mode, and that voltage drop will affect the serial I/O on the FTDI pins when placed in the GND line. Silly me, should have been on the PWR line all along!

The back side of the new connector is trivial:

Dsc 2598

The multimeter attaches to the top pins, bent apart for easy connection. The jumper shorts it out so this contraption can still be used when the multimeter is turned off.

Ok, time for some simple measurements:

  • ATmega full speed, doing nothing: 6.84 mA
  • ATmega full speed, with the RFM12B receiver on: 18.42 mA
  • ATmega powered down, only the RFM12B receiver on: 11.53 mA
  • ATmega full speed, with the RFM12B tranmitter on: 29.92 mA

Idle mode is a simple way to reduce power consumption without changing the logic of the code. It turns the MPU off until an interrupt occurs. Basically, you’re telling it “I’ve got nothing to do until something new happens”. It’s a pretty safe change, and well worth doing in any idle loop which isn’t directly polling I/O pins. The ATmega’s current consumption is slashed by more than half:

  • ATmega in idle mode, doing nothing: 2.80 mA

Another way to reduce power consumption, is to slow down the clock at which everything takes place, by setting the “clock pre-scaler”:

  • ATmega @ 16 MHz, doing nothing: 6.84 mA (as before)
  • ATmega @ 8 MHz, doing nothing: 4.35 mA
  • ATmega @ 4 MHz, doing nothing: 2.96 mA
  • ATmega @ 2 MHz, doing nothing: 2.02 mA
  • ATmega @ 1 MHz, doing nothing: 1.55 mA
  • ATmega @ 500 KHz, doing nothing: 1.28 mA
  • ATmega @ 250 KHz, doing nothing: 1.16 mA
  • ATmega @ 125 KHz, doing nothing: 1.09 mA
  • ATmega @ 62.5 KHz, doing nothing: 1.06 mA

Diminishing returns, clearly. Note that lowering the system clock in this way is not necessarily the best choice – getting something done N times faster and then powering down completely might be more efficient (see below).

One thing to watch out for: don’t go below 4 Mhz if you want to be able to use the RFM12B, or the processor will be too slow to process each byte.

When combining this, we get:

  • ATmega @ 4 MHz in idle mode, doing nothing: 1.48 mA
  • ATmega @ 62.5 KHz in idle mode, doing nothing: 1.03 mA

The advantage of this approach is that the clock is still running on the 16 MHz resonator (which probably draws most of that remaining current), so you’re still able to keep track of time – just more slowly.

A different approach is to go into real low power mode, and use the watchdog to get back out of this comatose state. The watch dog timer is less accurate, but depending on your application that may not be an issue.

Here’s the current consumption with the ATmega alternately in full speed and in power down mode:

  • ATmega 16 ms @ 16 MHz / 16 ms powered down, doing nothing: 3.49 mA
  • ATmega 8 ms @ 16 MHz / 16 ms powered down, doing nothing: 2.31 mA
  • ATmega 4 ms @ 16 MHz / 16 ms powered down, doing nothing: 1.39 mA
  • ATmega 2 ms @ 16 MHz / 16 ms powered down, doing nothing: 0.80 mA
  • ATmega 1 ms @ 16 MHz / 16 ms powered down, doing nothing: 0.46 mA

That last one does about the same amount of work as when running constantly @ 1 MHz, but with a third of the power consumption. Here is the corresponding sketch:

Screen Shot 2011 06 24 at 13.45.56

And it will continues to scale downward:

  • ATmega 100 µs @ 16 MHz / 16 ms powered down, doing nothing: 90.4 µA

Which still represents 100,000 active processor cycles per second…

And lastly, let’s take it into power down and run for just 1 ms per second, i.e. 0.1% of the time. I can’t measure this with the multimeter, because the power use jumps up every second, but the comatose period draws a mere 6.8 µA, which is consistent with what has been reported several times before (the watchdog is still active, and so is the brown-out detector).

MCP1702 current draw

In Hardware on Jun 21, 2011 at 00:01

The MCP1702 used in JeeNodes and other circuits here at JeeLabs is a nifty little voltage regulator. It’s not particularly good for high voltages (limited to about 13V), but it has a very low idle current. That’s very useful for low-power circuits, especially when trying to get months or even years of service out of one set of batteries.

Let’s find out how it’s performing. I’ve set up this little test circuit:

Screen Shot 2011 06 20 at 00.39.11

Well, it’s not really a test circuit at all – it’s in fact exactly what you need to use one of these things.

Putting 5V on the input (Vin), and leaving it a few minutes to settle, gives me a reading of 2.2 µA. Great, just what the specs say. It doesn’t really go up much with input voltage: 2.8 µA @ 12V. This is at no load.

With a 10 kΩ load, current draw rises to 338.1 µA, i.e. 330 µA for the resistor and about 8.1 µA for the regulator (assuming perfect calibration). That’s only 6 µA more, i.e. about 2% of the load.

Now let’s take the input voltage down, and see how this “low-drop” regulator behaves:

  • 5.0 V -> 2.2 µA
  • 4.0 V -> 2.2 µA
  • 3.5 V -> 2.1 µA
  • 3.3 V -> 2.1 µA
  • 3.2 V -> 90.4 µA
  • 3.1 V -> 84.1 µA
  • 3.0 V -> 78.2 µA

Whoa… it sure doesn’t like being fed less voltage than it needs to supply a regulated output of 3.3V! The change is quite pronounced between 3.30 and 3.28V (I couldn’t get my power supply knob to adjust any more accurately).

For yesterday’s AA power board discussion that’s actually bad news, because it means that when the supply drops a mere 20 mV, it could cause the regulator to start wasting a fair amount of current (relatively speaking).

Let’s try something different: no power on Vin, but power on Vout instead.

This simulates connecting a battery to the +3V pin, and bypassing the MCP1702 voltage regulator altogether. Evidently, it’s not a good idea putting much more than 3.3V on there, since now we’re reverse feeding the regulator, something not all regulators are happy with:

  • 3.40 V -> 1000 µA
  • 3.35 V -> 500 µA
  • 3.30 V -> 90 µA
  • 3.25 V -> 90 µA
  • 3.20 V -> 90 µA
  • 3.10 V -> 84 µA

The conclusion seems to be: when using the AA Power Board in combination with a JeeNode, it might be better in certain cases to omit the regulator altogether if you’re aiming for minimal power consumption!

It’s not enough to short the regulator’s Vin and Vout, it really has to be taken out of the circuit. Fortunately, you don’t have to disconnect all three pins – just disconnect the ground pin (on the JeeNode v4..v6, that’s the one closest to the FTDI connector).

But if all you want to do is power the whole thing from some power source over 3.3V, such as a 3x AA battery pack or a LiPo battery, then all is fine… you’ll see that ultra-low 2.2 µA figure – as intended in this design.

Just beware of low voltages: weird things do happen!

AA boost ripple

In Musings on Jun 20, 2011 at 00:01

The AA Power Board contains a switching boost converter to step the voltage from a single AA battery up to the 3.3V required by a JeeNode.

Nifty stuff. Magic almost… if you take the water analogy, then it’s similar to pushing water up a mountain! Wikipedia has a schematic with the basic idea:

Boost Circuit

Think of the coil as a rubber band (I’ll use a gravitational force analogy here), then closing the switch is like stretching it from the current voltage to ground. Opening the switch is equivalent to letting it go again – causing the rubber band to contract, pulling the end back up and then exceding the original height (voltage) as it overshoots. The diode then sneakily gets hold of the rubber band at its highest point. The analogy works even better if you imagine a cup of water attached to the end. Well, you get the picture…

The trick is to repeat this over and over again, with a very efficient switch and a good rubber band, eh… I mean inductor. The way these boost regulators work, you’ll see that they constantly seek the proper voltage (feeding a storage pool at the end, in the form of a capacitor).

Enough talk. Let’s look at it with a scope:

Open

What you’re seeing is not the output voltage, which is of course 3.3V, but the variation in output voltage, which is measured in millivolts. IOW, 45 times a second, the regulator is overshooting the desired output by about 20 mV, and then it falls back almost 20 mV under 3.3V, at which point the booster kicks in again.

Let’s load the circuit lightly with a 10 kΩ resistance, i.e. 330 µA current draw:

10k

No fundamental change, but the horizontal axis is now greatly enlarged, because the discharge is more substantial, causing the boost frequency to go to 2.2 KHz.

With a 1 kΩ load, i.e. 3.3 mA current draw, you can see the boost working a bit harder to charge up, i.e. the slope towards ≈ 20 mV above 3.3V is more gradual:

1k

Keep in mind that the difference is also due to yet more magnification on the horizontal time axis. The boost converter is cycling at 21.1 KHz now.

With a 330 Ω load, i.e. 10 mA current draw, the wavevorm starts getting a few high-frequency spikes:

330

The total regulation is still good, though, with about 25 mV peak-to-peak ripple.

Now let’s simulate what happens with the RFM12B transmitter on, using a 100 Ω load, i.e. 33 mA current:

100

Looks like the regulator needs more time to charge than to discharge, at this power level. Still the characteristic “hunting” towards the proper voltage level.

With a 68 Ω / 50 mA load, the regulator decides to use more force, losing a bit of its fine touch:

68

The scope’s frequency measurement was off here, it probably got confused by the high frequency components in the signal. Repetion rate appears to be ≈ 65 KHz. But now the total ripple has increased to about 70 mV.

That’s probably about as high as we’re going to need for a JeeNode with some low-power sensors attached. But hey, why stop here, right?

Here’s the output with a 47 Ω load, i.e. about 70 mA:

47

Whoa… that’s a ± 0.05 V swing, regulation is starting to suffer. I also just found out that the scope software has peak-to-peak measurement logic built in (and more). No need to estimate values from the divisions anymore.

Note that a 70 mA current at the end will translate to some 200 mA current draw on the battery – that’s the flip side of boost regulators: you only get higher voltage by drawing a hefty current from the input source as well.

Until this point, I used a standard 1.5V alkaline battery, but it’s not fresh and showing signs of exhaustion at these power levels (the output was a bit erratic).

To push even further, I switched to a fully charged Eneloop battery, which supplies 1.2 .. 1.3V and has a much lower internal resistance. This translates to being able to supply much larger currents (over 1 A) without the output voltage dropping too much. In this case, the change didn’t have much effect on the measurements, but I was worried that continued testing would soon deplete the alkaline battery and skew the results.

To put it all in perspective, here is the output with the same 47 Ω load, but showing actual DC voltage levels:

47dc

So you see, its still a fairly well regulated power supply at 70 mA, though not quite up to 3.3V, as it should be.

One last test, using a 33 Ω resistor, which at 3.3V means we’ll be pulling a serious 100 mA from this circuit:

33dc

Measuring these values with a multimeter gives me 3.16 V @ 89 mA, while the resitance reads as 32.7 Ω – there’s some inconsistency here, which might be caused by the high-frequency fluctations in the output, I’m not sure.

But all in all, the AA Power Board seems to be doing what it’s supposed to do, with sufficient oomph to drive the ATmega, the RFM12B in transmit mode, and a bit of extra circuitry. A bit jittery, but no sweat!

Update – With a 10 µF capacitor plus 10 kΩ load the limits don’t change much, just the discharge shape:

Slow

The same, at higher horizontal magnification:

Cap

Note that AC coupling distorts the vertical position, it’s still ± 18 mV ripple, even if the up peak appears higher.

EtherCard library API

In Software on Jun 19, 2011 at 00:01

As you may have noticed in the last few weblog posts, the API of the EtherCard library has changed quite a bit lately. I’m not doing this to be different, but as part of my never-ending quest to try and simplify the calling interface and to reduce the code size of the library (these changes shaved several Kb off the compiled code).

The main change was to switch to a single global buffer for storing an outgoing Ethernet packet and for receiving the next packet from the controller. This removes the need to pass a buffer pointer to almost each of the many functions in the library.

Buffer space is scarce on an ATmega, so you have to be careful not to run out of memory, while still having a sufficiently large buffer to do meaningful things. The way it works now is that you have to allocate the global buffer in your main sketch:

Screen Shot 2011 06 15 at 09.32.45

This particular style was chosen because it allows the library to access the buffer easily, and more importantly: without requiring an intermediate pointer.

To make this work, you have to initialize the EtherCard library in the proper way. This is now done by calling the begin() function as part of your setup() code:

Screen Shot 2011 06 15 at 09.34.46

The ether variable is defined globally in the EtherCard.h header file. The begin() call also needs the MAC address to use for this unit. The simplest way to provide that is to define a static array at the top of the sketch with a suitable value (it has to be unique on your LAN):

Screen Shot 2011 06 15 at 09.37.18

Next, you can use DHCP to obtain an IP address and locate the gateway and DNS server:

Screen Shot 2011 06 15 at 09.39.27

The printIp() utility function can optionally be used to print some info on the Serial port.

If you are going to set up a server, then a fixed IP address might be preferable. There’s a new staticSetup() function you can use when not doing DHCP:

Screen Shot 2011 06 15 at 09.42.55

The gateway IP address is only needed if you’re going to access an IP address outside of your LAN, and the DNS IP addres is also optional (it’ll default to Google’s “8.8.8.8” DNS server if you do a DNS lookup). To omit values, pass a null pointer or leave the arguments off altogether:

Screen Shot 2011 06 15 at 09.45.55

Just remember to call either dhcpSetup() or staticSetup() after the begin() call.

DNS lookups are also very simple:

Screen Shot 2011 06 15 at 09.47.32

The one thing to keep in mind here, is that the website argument needs to be a flash-based string, which must be defined as follows:

Screen Shot 2011 06 15 at 09.51.10

Note the “PROGMEM” modifier. See the Saving RAM space weblog post for more info about this technique.

This concludes the intialization part of the EtherCard library. Next, we need to keep things going by frequently polling for new incoming packets and responding to low-level ARP and ICMP requests. The easiest way to do so is to use the following template for loop():

Screen Shot 2011 06 15 at 09.59.01

The packetReceive() function polls for new incoming data and copies it into the global buffer. The return value is the size of this packet (or zero if there is none).

The packetLoop() function looks at the incoming data and takes care of low-level responses. The return value is the offset in the global packet buffer where incoming TCP data can be found (or zero if there is none).

As to what to do next: it really all depends on what you’re after. Check out the examples in the Ethercard library for how to build web servers and web clients on top of this functionality.

To get an idea of the code overhead of the EtherCard library: a simple web client using DHCP and DNS is around 10 Kb, while an even simpler one using static IP addresses (no DHCP and no DNS) is under 7 Kb. The fairly elaborate EtherNode sample sketch, which includes DHCP and the RF12 library is now ≈ 13 Kb.

IOW, lots of room for adding your own app logic!

Complete web client demo

In AVR, Software on Jun 17, 2011 at 00:01

After yesterday’s addition of DHCP to the EtherCard library, it’s only a small step to create a sketch which does everything needed for convenient stand-alone use on a local LAN.

Here’s a webClient.pde demo sketch which sets itself up via DHCP, then does a DNS lookup to find a server by name, then does a web request every 5 seconds and displays the first part of the result:

Screen Shot 2011 06 15 at 09.04.57

Sample output:

Screen Shot 2011 06 15 at 09.05.51

The total sketch is under 10 Kb, so there’s still lots of room to add the RF12 wireless driver, as well as a fair amount of application logic.

Who says a little 8-bit processor can’t be part of today’s internet revolution, eh?

DC high-side control

In Hardware on Jun 12, 2011 at 00:01

Good news: the “high-side” DC power switch works!

Dsc 2561

On the bottom, a DC jack getting 12V power, on the right a cable with a DC plug powering an external USB disk.

The little board in the middle is sort of a breakout board for two SMD chips: a dual P-MOSFET and a low-drop -3.3V linear voltage regulator to power the JeeNode. The rest is boilerplate stuff, i.e. the JeeNode Experimenter’s Pack, a couple of resistors, and some electrolytic caps.

I’ve only tested it with a load of about 1A, but it should work up to 3A without any problem. What’s also nice is that as a high-side switch, it doesn’t really care what voltage is being used as power supply – anything between 3.5V and 16V should work just fine. That means this can also be used for 5V devices and even with devices powered off 1..4 LiPo-batteries. This simply fits between a DC power plug and its device – convenient!

The current consumption is 21 mA with the ATmega and receiver permanently on. Could easily be lowered a few mA by putting the ATmega in “idle” mode.

The current sensing capabilities are definitely working, but the resistance of the P-MOSFET is not quite 0.1 Ω: with a 390 mA current, I see about 90 mV across the MOSFET, indicating that its internal resistance when driven from a 3.3V JeeNode is more like 0.23 Ω. That’s on the high side (pardon the pun), because this would mean a 1A load will get about 0.23V less out of the power supply than it would with a direct connection – and 0.7V less when drawing 3A. Oh well, it’ll be ok for most devices, cheap power bricks don’t always supply exactly 12V anyway.

The question of course is how consistent this MOSFET resistance is. I suspect that there will be quite a bit of variation across different units. But that’s not necessarily a problem: we don’t really care about absolute currents, we just need to see how the device’s current consumption is relative to full power and idle modes, basically. And we can always calibrate the value with a multimeter or power resistor.

The other weak spot in all this is that the voltage levels measured with this setup are very low, and only cover a few percent of the ADC range. It would be nice to have a bit more resolution there.

Ok, let’s throw an op-amp into the mix…

How the JeeNode evolved

In AVR, Hardware on Jun 8, 2011 at 00:01

Thought it might be interesting to put the six JeeNode versions / designs next to each other. It nicely illustrates my progress in learning PCB design, and making some trade-offs and pinout choices over the past 2.5 years:

JeeNode v1:

Jlpcb 002

JeeNode v2:

Jlpcb 003

JeeNode v3:

Jlpcb 018

JeeNode v4:

Jlpcb 044

JeeNode v5:

Jlpcb 105

JeeNode v6:

Jlpcb 128

We’ve come a long way. And I think it’s now time to call this final v6 design… it!

Hard disk power – bonus

In Hardware on Jun 2, 2011 at 00:01

Ok, there’s now a design for a high-side power switch which can power disk drives up and down at will.

Wait a minute…

You’re not supposed to power down disk drives just like that! It might be in the middle of a disk write. Even journaled disks are at risk, because journaling usually covers meta data (directories, files sizes, allocation maps, etc) … but not the data itself. So an unfortunate power down could leave the disk in an awful state: sure, the diks will be scanned and fixed on startup, but even then, some of the data blocks might contain inconsistent data. Whoops – bad idea!

One solution would be to add a JeeLink to the computer, and have it send out the power down command only after it finishes flushing and unmounting the disk. It’ll take some scripting, depending on the OS, but it’s all doable. Also, this isn’t really for disks which need to be online most of the time – for that, the normal hard disk spin down and idling modes will be fine.

But I’d like it to be a bit more automatic than that. I don’t want to have to remember to turn off the disks. Nor tie it to a specific time of day, or day-of-the-week. The whole point of these disks, is that I rarely need them. Some disks may stay off for weeks, even months.

Here’s an idea: by adding a current sensor to each disk power supply line, we could monitor disk activity and make sure that power is never shut off while a disk is “doing something”. By adding a bit of extra logic in the sketch, we could implement a timer so that the disk will only be powered down if the disk has been idle for say 15 minutes. Most operating systems have a periodic flush in place, so that changes always get flushed out to disk fairly soon after they have been buffered by the OS. If nothing has happened for a while, then we know there’s no important change pending.

OK, how do you measure the amount of current a circuit draws? Easy: insert a small resistance in series with the load, and measure the voltage drop. For the same reasons as before, we can’t do this “low side”, i.e. in the ground connection. But high-side would be fine:

Screen Shot 2011 05 30 at 02.00.54

With 1A of current, we get (using Ohm’s E=IxR law): E = 1 x 0.1 = 0.1V voltage drop across the resistor. And since the high side of the resistor is tied to “+”, all we need to do is connect the other side to an analog input.

The nice thing about the power control circuit presented yesterday, is that it has a MOSFET between + and the disk drive power pin. And MOSFETs are really very much like a small resistor when turned on. So we can simply use the MOSFET itself as a sense resistor:

Screen Shot 2011 05 30 at 01.54.25

Here are the characteristics of the P-MOSFET I’m going to try this with:

Screen Shot 2011 05 30 at 02.06.51

As you can see, at 3.3V, the MOSFET acts almost exactly like a 0.1Ω resistor: 0.1V drop at 1A – perfect!

There is still one problem though: when the MOSFET is turned off, the voltage on the low side will be at ground level, which is 8.7V below the JeeNode’s “ground”. So we can’t just tie it to an analog input pin, it would fry the ATmega. That’s is why I added a 10 kΩ resistor: it will still be a very “bad” input signal when the MOSFET is off, but the resistor will limit the current to less than 1 mA, and it will flow through the internal ESD protection diode. That amount of current should be harmless.

So now we have a way to sense the current. When the disk draws 1A, the analog input will be at 0.1V below 3.3V, i.e. 3.2V, which can easily be measured. Since the ADC resolution is 3.3 mV, this means that a change in power consumption as small as 33 mA could in principle be detected by this setup. Should be accurate enough to detect a disk spinning up or down and the seek actuator moving.

I’ve ordered a bunch of parts and will report when something useful comes out of these experiments.

Hard disk power #3

In Hardware on Jun 1, 2011 at 00:01

As promised in the previous post, here’s an improved design for controlling hard disk power.

The first conclusion is that we need to switch the positive +12V line, not the ground. Ground is inter-connected between all disks, the server, and this circuit – so we shouldn’t mess with it.

Here’s one way to do a “high-side” switch:

Screen Shot 2011 05 29 at 20.02.56

First problem: we don’t have a voltage higher than 12V available, so the N-MOSFET can’t simply be moved to the upper power line (it needs a few volts above its source to drive it, and when conducting, that source is at 12V). A P-MOSFET solves that, because it needs a few volts below 12V to drive it into conduction.

Second problem: we can’t drive the P-MOSFET high enough (12V) to make it disconnect, when driven from an ATmega output pin (which can’t go higher than 3.3..5V). So we need a resistor to pull the gate up, and a transistor to pull the gate down. And lastly, we need a resistor to limit the current into the transistor.

Quite a few parts, expecially since this circuit needs to be repeated for each hard disk.

For reasons which will become clear tomorrow, I’d like to simplify this circuit a bit further, and get away from handling 12V power levels. This “simplification” needs a bit of explanation, unfortunately:

Screen Shot 2011 05 29 at 21.05.13

To see what’s going on, this trick may help: look at the VOUT pin as being a regulated 8.7V voltage. In other words: the JeeNode “ground” is at +8.7V above ground, in relation to the power supply, hard disks, and server.

This means that the JeeNode is running with a 12 – 8.7 = 3.3V voltage difference between its 3.3V and GND pins, just as it always does. It’s merely floating a bit above ground, but that’s all relative anyway. As far as the JeeNode goes, it’s getting exactly the right power levels.

The result is that the output pins of that JeeNode will be at about 8.7V when “0” and at 12V when “1”. Which is just right to drive the gate of a suitable P-MOSFET (a “1” will turn it off, and a “0” will make it conduct).

So instead of making all the disk ground levels float, this setup places the JeeNode at an unusual 8.7V above ground level, which lets it turn on and off P-MOSFETs by controlling the positive supply line.

Now we need a regulated 8.7V supply. Eh, actually, no… we need a supply which is exactly 3.3V below the +12V line. That way, even if it fluctuates a bit from hard disk load changes, the JeeNode still gets a nice clean 3.3V.

The way to do that is to use a minus 3.3V regulator, such as an LM337. And from the perspective of that regulator, +12V is “ground” and ground is… -12V!

Perfect. You just have to look at voltages upside-down :)

Hard disk power #2

In Hardware on May 31, 2011 at 00:01

Yesterday, I described a design to control the power of hard disks. Now let’s see what happens when two hard disks are hooked up this way:

Screen Shot 2011 05 29 at 19.24.25

I’m including the USB cables to the server now, because that’s what causes a major problem: ground loops!

USB is a 4-wire (+ shield) connection between computer and devices. It is not isolated, i.e. all devices get hooked up galvanically. This in turns means that the ground potential of all inter-connected devices will be the same.

With a disk powered from a 12V power supply, ground is the negative wire. It’s also the ground of the USB connection to the server, so the “–” side of the power supply is connected directly to ground on the USB cable.

When two or more disks are plugged into one computer via USB, all ground pins will be connected together.

So far, no problem. Most devices have their own power supply, and these are all “floating”, i.e. they will adopt any ground voltage potential imposed on them (if any). You can connect any number of power supplies together through their “–” pins, and they’ll happily each feed their own devices and share a common ground.

Yesterday’s design is different – it uses a MOSFET to connect or disconnect the GND level from the disk drive:

Screen Shot 2011 05 29 at 19.36.05

The MOSFETs act as switches, connecting or disconnecting the wires on top to the JeeNode (and power supply) ground. So what one disk sees as “ground” is not the same as what the other sees (unless both are powered up). But… with the USB cables inserted, we’ve in effect created a direct connection between “GND1” and “GND2” through the USB’s common ground wires.

The result will be that no matter which MOSFET turns power on, it will end up powering BOTH disk drives!

And what’s (much) worse: the power supply current for the other drive will go through both USB cables and the server, which isn’t designed to handle the 1..2A peak currents flowing on startup.

Phew! I’m glad I didn’t start building this circuit :)

Tomorrow, I’ll describe a better design.

Hard disk power control

In Hardware on May 30, 2011 at 00:01

There’s a server running 24 hours a day, 7 days a week here at JeeLabs. It has two internal hard drives, one of them used as hourly backup for the system partition on the other disk. It’s running a couple of VM’s with all sorts of services, and it’s been running flawlessly for several months. Draws 10..15W.

Now, I’d like to attach a couple of extra hard disks to this server. A pair of disks for off-site backups (yes, there is a daily cloud backup, but I want a second fall-back system for some files), and a disk with stuff I rarely need, but don’t want to throw away. Disks are cheap – in fact I’ve got enough disks, so disk storage is actually free here. And while I’m at it: maybe add a little NAS for private stuff, since it’s been lying around and collecting dust anyway.

But I don’t want to have everything on-line all the time, for safety reasons and to keep power consumption low.

Why not use a JeeNode to control the power to these devices, which all run off a 12V supply? And why not just use one beefy switching supply, instead of that endless collection of power bricks?

Here’s a first idea:

Screen Shot 2011 05 29 at 18.49.52

Only one of the two channels on the MOSFET Plug is used here. And instead of switching a power LED or LED strip with it, it’s being used to control the power to the external disk drive.

There’s a flaw in this design, though: it’ll only work with ONE hard disk…

Tomorrow I’ll go into this and explain what’s going on, and why it can’t work with multiple disk drives. Hint: this setup only works if the JeeNode is controlled by wireless.

Summary of ISP options

In AVR, Hardware, Software on May 29, 2011 at 00:01

First of all, see this weblog post for an overview of what ISP is, why you’d want to know, and when you need it.

There have been quite a few posts about ISP on this weblog over time – all tagged, so they can be reached via this link: https://jeelabs.org/tag/isp/.

I’ll summarize here, since particularly the different sketches floating around by now might be a bit confusing.

The ZIF socket is a way to connect to chips before they have been soldered into a circuit. There’s one for through-hole DIP chips, and one for 32-TQFP SMD chips:

Once soldered into a circuit, you can use an I(C)SP programmer, which not everyone has. So I created a couple of different options based on a JeeNode (can also be an RBBB or Arduino) to perform the same function.

My first trial was a hack with the isp_flash.pde sketch, which then led to the Flash Board (info). The nice thing about this board is that it has 128 Kbyte of EEPROM on board – enough to hold the complete programming instructions for an ATmega168 or ATmega328.

One way to use the Flash Board is as capturing ISP programmer: you send a sketch to it as if it were an ISP programmer, and then you can disconnect it and use it repeatedly to upload that sketch to other boards via ISP:

I used this to build a 4-fold Multi-ISP programmer to program all those gazillion ATmega’s needed for JeeNodes:

Took a few attempts to get all the bugs worked out, but now it works perfectly.

But there’s a much simpler way to do this, if all you want is to fix a JeeNode, occasionally:

… or use an Arduino:

These two ISP setups use an isp_repair.pde sketch, which has as novelty that it includes the sketch and bootstrap its needs for programming – as data array in flash memory. So all that’s needed is: connect the two boards and power up the master. No need to use the Arduino IDE’s “Burn Bootloader” command or anything.

Then came OptiBoot, which is compatible with the Arduino Uno, and smaller/faster. This is a relatively new boot loader so you might want to update your current JeeNodes – even though an ISP programmer isn’t normally needed for development.

I updated the isp_repair.pde sketch, and then fixed a few remaining problems with it:

And finally, I added a LiPo battery, and 4 config switches, to end up with this tool:

On the software side, the most recent design is called isp_repair2.pde. It supports two different sketches, up to four different bootstrap loaders, and setting the fuses either as 16 MHz crystal or optimized specifically for ceramic resonators.

The include files with the bootstraps included with these sketches are generated from HEX files created by the Arduino IDE. This is done with a small Tcl script called hex2c.tcl, which is located in a slightly older isp_prepare example sketch folder. It’s not needed for normal use, only when one of the boot loaders changes.

Phew. Still there?

In a nutshell: if you need to re-flash your ATmega, pick one of the above options to hook things up, and use the isp_repair2 sketch in the Ports library. By default, it’ll upload a blink demo sketch and the OptiBoot loader.

More bootstraps

In AVR, Hardware, Software on May 28, 2011 at 00:01

Some projects just don’t want to lie down…

The isp_repair example sketch in the Ports library was written for a single purpose: to upgrade a JeeNode to the OptiBoot loader, which leaves more room for sketches and is compatible with the Arduino Uno.

It took two attempts to get it right, but in the end I think it all worked out as intended.

Until featuritis sets in…

First, I added a #define OPTIBOOT in the sketch, to allow re-using that same sketch to revert to the original boot – in case you ever want to go back. So now it’s a setup which can “repair” an ATmega in various ways.

But why stop there?

There are a couple variations for flashing which all make sense in the context of JeeNodes:

  • load a short Blink sketch, or load the entire standard RF12demo sketch
  • OptiBoot vs the original Arduino 2009 bootstrap code
  • faster wakeup after power down, works only with a 16 MHz resonator

The fast wakeup makes it possible to completely power down an ATmega between the reception and transmission of individual bytes via the RF12 driver. It won’t make a huge difference, but it will reduce power consumption just a notch more than staying in idle mode.

So here’s a new setup, and hopefully the last:

Dsc 2536

It includes yesterday’s DIP-switch Plug, which gives me 4 bits of configurability. There’s a new sketch which adds support for these switches and includes all the different pieces if code – it’s called isp_repair2:

Screen Shot 2011 05 26 at 01.34.25

The sketch includes up to four different boot loaders, currently:

Dip Switch Plug

There are two “sketch” code sections, followed by 4 bootstrap code sections:

Screen Shot 2011 05 26 at 03.09.23

With all switches set to “1” (same as not connecting any switches at all, BTW), we get:

Screen Shot 2011 05 26 at 03.06.53

And since (in my case) there’s an on-board LiPo recharger and battery tacked onto the back: this setup is fully self-contained and ready for use at any time.

Hmmm, I wonder what sort of bootstrap loader I could put in that spare slot, one day…

RF bootstrap design

In Software on May 24, 2011 at 00:01

After some discussion on the forum, I’d like to present a draft design for an over-the-air bootstrap mechanism, IOW: being able to upload a sketch to a remote JeeNode over wireless.

Warning: there is no release date. It’ll be announced when I get it working (unless someone else gets there first). This is just to get some thoughts down, and have a first mental design to think about and shoot at.

The basic idea is that each remote node contacts a boot server after power up, or when requested to do so by the currently running sketch.

Each node has a built-in unique 2-byte remote ID, and is configured to contact a specific boot server (i.e. RF12 band, group, and node ID).

STEP 1

First we must find out what sketch should be running on this node. This is done by sending out a wireless packet to the boot server and waiting for a reply packet:

  • remote -> server: intial request w/ my remote ID
  • server -> remote: reply with 12 bytes of data

These 12 bytes are encrypted using a pre-shared secret key (PSK), which is unique for each node and known only to that node and the boot server. No one but the boot server can send a valid reply, and no one but the remote node can decode that reply properly.

The reply contains 6 values:

  1. remote ID
  2. sketch ID
  3. sketch length in bytes
  4. sketch checksum
  5. extra sketch check
  6. checksum over the above values 1..5

After decoding this info, the remote knows:

  • that the reply is valid and came from a trusted boot server
  • what sketch should be present in flash memory
  • how to verify that the stored sketch is complete and correct
  • how to verify the next upload, if we decide to start one

The remote has a sketch ID, length and checksum stored in EEPROM. If they match with the reply and the sketch in memory has the correct checksum, then we move forward to step 3.

If no reply comes in within a reasonable amount of time, we also jump to step 3.

STEP 2

Now we need to update the sketch in flash memory. We know the sketch ID to get, we know how to contact the boot server, and we know how to verify the sketch once it has been completely transferred to us.

So this is where most of the work happens: send out a request for some bytes, and wait for a reply containing those bytes – then rinse and repeat for all bytes:

  • remote -> server: request data for block X, sketch Y
  • server -> remote: reply with a check value (X ^ Y) and 64 bytes of data

The remote node gets data 64 bytes at a time, and burns them to flash memory. The process repeats until all data has been transferred. Timeouts and bad packets lead to repeated requests.

The last reply contains 0..63 bytes of data, indicating that it is the final packet. The remote node saves this to flash memory, and goes to step 3.

STEP 3

Now we have the proper sketch, unless something went wrong earlier.

The final step is to verify that the sketch in flash memory is correct, by calculating its checksum and comparing it with the value in EEPROM.

If the checksum is bad, we set a watchdog timer to reset us in a few seconds, and … power down. All our efforts were in vain, so we will retry later.

Else we have the proper sketch and it’s available in flash memory, so we leave bootstrap mode and launch it.

That’s all!

ROBUSTNESS

This scheme requires a working boot server. If none is found or in range, then the bootstrap will not find out about a new sketch to load, and will either launch the current sketch (if valid), or hit a reset and try booting again a few seconds later.

Not only do we need a working boot server, that server must also have an entry for our remote ID (and our PSK) to be able to generate a properly encrypted reply. The remote ID of a node can be recovered if lost, by resetting the node and listening for the first request it sends out.

If the sketch hangs, then the node will hang. But even then a hard reset or power cycle of the node will again start the boot sequence, and allows us to get a better sketch loaded into the node. The only drawback is that it needs a hard reset, which can’t be triggered remotely (unless the crashing sketch happens to trigger the reset, through the watchdog or otherwise).

Errors during reception lead to a failed checksum at the end, which then leads to a reset and a new boot loading attempt. There is no resume mechanism, so such a case does mean we have to fetch all the data blocks again.

SECURITY

This is the hard part. Nodes which end up running some arbitrary sketch have the potential to cause a lot of damage if they also control real devices (lights are fairly harmless, but thermostats and door locks aren’t!).

The first line of defense comes from the fact that it is the remote node which decides when to fetch an update. You can’t simply send packets and make remote nodes reflash themselves if they don’t want to.

You could interrupt AC mains and force a reset in mains-powered nodes, but I’m not going to address that. Nor am I going to address the case of physically grabbing hold of a node or the boot server and messing with it.

The entire protection is based on that initial reply packet, which tells each remote node what sketch it should be running. Only a boot server which knows the remote node’s PSK is able to send out a reply which the remote node will accept.

It seems to me that the actual sketch data need not be protected, since these packets are only sent out in response to requests from a remote node (which asks for a specific sketch ID). Bad packets of any kind will cause the final checksums to fail, and prevent such a sketch from ever being started.

As for packets flying around in a fully operational home network: that level of security is a completely separate issue. Sketches can implement whatever encryption they like, to secure day-to-day operation. In fact, the RF12 library includes an encryption mechanism based on XTEA for just that purpose – see this weblog post.

But for a bootstrap mechanism, which has to fit in 4 Kb including the entire RF12 wireless packet driver, we don’t have that luxury. Which is why I hope that the above will be enough to make it practical – and safe!

Still running on LiPo

In Hardware on May 21, 2011 at 00:01

A while back, a post on this weblog described a simple setup I had running to see how long the radioBlip.pde sketch would keep running on a single LiPo battery.

Here’s the setup again:

That’s a 1300 mAh battery, and the test sketch on it sends out an incrementing counter approximately once a minute (I extended the counter to 4 bytes, instead of the 2 bytes used in the original sketch).

It’s still going strong, i.e. this sketch has been running for 9 months on a single battery charge so far.

The counter is now at about 350,000 and I’ve determined that packets actually go out every 64 seconds, so that puts the counter at about 260 days. There’s a gap there, because the node was once reset some two weeks after being started for the first time.

So with some 275 days of running time, we can deduce that the average power consumption of this node has to be under (1300 * 1000) µAh / (275 * 24) h = 197 µA. This assumes that the battery would be empty, which it isn’t yet – so we know the average current must be lower (a lot lower, probably). Unfortunately, I didn’t include logic to measure and send out the LiPo voltage, which would be a good indicator of how far the LiPo battery actually is. The good news: a check with my multimeter shows the battery to still supply a whopping 3.985 V!

Anyway – I wouldn’t be surprised to get at least 4 times as much runtime, i.e. 3 years, out of this setup (which would translate to 50 µA average current draw).

Sooo… just hang around for another few years, and I’ll let you know!

Self-powered Opti-rebooter

In AVR, Hardware on May 18, 2011 at 00:01

After yesterday’s post about switching to OptiBoot, I decided to go one step further and go for a self-powered solution, a bit like this unit which has been serving me well for many months now.

So here’s the “Opti-rebooter” with a 400 mAh LiPo backpack:

Dsc 2521

Hookup is trivial, given that the JeeNode USB has an on-board LiPo charger. I picked a battery which matches the width of the board and fits quite well:

Dsc 2522

The two connectiosn of the LiPo battery are wrapped up in heat-shrink tubing to prevent accidental short circuits – the currents involved could easily cause trouble. Note that this is a “raw” LiPo cell, without any protection circuitry. That’s fine in this case, because the on-board circuitry takes care of charging.

To make this complete, the isp_repair.pde was extended to completely power down when done. So there’s no need for an on-off switch, the idle consumption is probably lower than the battery’s own self-discharge rate. And it blinks the on-board led twice: once on power up and once when properly programmed. Very convenient!

The way to use this thing, is: connect to a target JeeNode / JeeLink / Arduino, press the RESET button, wait three seconds, disconnect, done.

I also made changes to the very similar but slightly more elaborate isp_prepare.pde sketch, which was presented in this weblog post.

The updated isp_prepare.pde sketch supports a number of variations. These can be configured by adjusting a few values at the start of the sketch:

Screen Shot 2011 05 16 at 15.00.32

You can choose which type of boot loader to install, which sketch to load initially (just to start off, this can be overwritten later), and there’s a third option to adjust some “fuse bits” in the ATmega to select how fast the ATmega can start up after resuming from a power down.

That third option is particularly useful with battery-powered JeeNodes using the RF12 driver. With USE_FAST_WAKEUP set to 1, the power-up sequence is fast enough for an ATmega to wake up when the first data byte is received. This means you can completely power down the ATmega (while leaving the receiver running), and it’ll still be able to pick up incoming packets and respond to them. There is one gotcha: USE_FAST_WAKEUP can only be set to 1 on units running with a resonator – JeeLinks and Arduino’s running with a crystal must be not use the fast wakeup mechanism, as the clock may not start up properly in this case.

Haven’t tried it though – for now, that LiPo powered unit shown above is really the most convenient way for me to upgrade all the JeeNodes, JeeLinks, and Arduino’s floating around the house at JeeLabs.

Switching to OptiBoot

In AVR, Hardware on May 17, 2011 at 00:01

Now that some of the JeeNode/JeeLink boards from JeeLabs come pre-loaded with the OptiBoot boot loader, it’s time to start thinking about switching everything over. Having to constantly switch the Arduino IDE between “Arduino Uno” (OptiBoot) and “Arduino Duemilanove w/ 328” (original 2009 boot) is quickly going to become very tiresome …

See this weblog post for a quick summary of what all this uploading and boot loader stuff is about, and why you should care. In a nutshell: you need a boot loader on the ATmega to save sketches onto it via FTDI and USB.

There’s a nasty detail, though: to upload sketches you need a boot loader, but how does that boot loader end up on the ATmega in the first place? The good news is that this is usually done in the factory, well, ehm… at JeeLabs, in my case. The good thing is, it’s all taken care of, and the boot loader doesn’t normally get damaged or need to be replaced. It just works.

Except when the boot loader itself needs to be changed, as in the case of OptiBoot. Note that it’s quite worthwhile to switch to OptiBoot: the uploads are twice as fast, and you get 1.5 Kb of extra memory for your own sketches.

So how do you go about updating the boot loader on a JeeNode when you don’t have a special hardware tool called an “ISP Programmer”?

Fortunately, there is a simple trick to do this using a second JeeNode (or Arduino). I’ve written about this in a previous post. There’s an isp_repair.pde sketch in the Ports library which does everything (it emulates an ISP programmer, basically).

I’ve just updated the isp_repair.pde sketch to use OptiBoot.

Here’s the setup to upgrade a target JeeNode to OptiBoot using another JeeNode:

Six wires need to be connected as follows:

And then it’s a matter of attaching the target to the programming JeeNode, and then powering up the whole assembly.

If you happen to have the serial port connected to the programming JeeNode, you’ll see this info:

Screen Shot 2011 05 16 at 17.08.48

I made a permanent setup using a JeeNode USB, because I’ve got a pile of JeeNodes to reprogram here at JeeLabs:

Dsc 2518

The connector was constructed from a 2×4 header, with the pins bent in such a way that the whole thing stays in place when pressed into the 2×4 holes of the SPI/ISP header. And then the whole thing was sealed off with a few pieces of heat-shrink tubing:

Dsc 2519

To program a board (in this case another JeeNode USB), just power it all up and wait 3 seconds:

Dsc 2520

That’s it – you could call this an “opti-rebooter” :)

RFM12B range testing

In Hardware on May 15, 2011 at 00:01

There have been many questions and discussions about the range achievable with the RFM12B wireless modules. Usually, my answers have been: 1) should be about 100m outside, and 2) gets through about two walls inside the house. But the most accurate answer really is a resounding “it depends” …

Because it really does. RF range will depend on a huge number of factors. What works for me may not work for you, and what works today may not work tomorrow.

Triggered by some recent discussions on the forum, and with the help of Steve Evans (@TankSlappa) who wrote a good set of sketches and did some tests, I’ve come up with two sketches and a setup to report reception quality.

This setup requires two RFM12B modules evidently, plus an LCD connected via the LCD Plug. I re-used one of my Mystery Boxes – one of so many projects here at JeeLabs waiting to get finished.

My sending unit is a JeeNode with an AA Power Board on the back. The rfRangeTX.pde transmitter sketch is very simple, and sends out 1-byte packets 10 times per second:

Screen Shot 2011 05 14 at 15.00.18

The receiver is based on a JeeNode USB with LCD and LiPo battery, so both units are portable / self-powered:

Dsc 2513

The code for the rfRangeRX.pde receiver sketch is too long to be shown in its entirety, but here’s an overview:

Screen Shot 2011 05 14 at 15.03.34

The display shows 4 fields:

  • top left = percentage of packets received in the last 5 seconds
  • top right = percentage of packets received in the last second
  • bottom left = sequence number of the last valid incoming packet
  • bottom right = history of last reception counts (10x 0.5s intervals)

Here, one packet was missed in the last second (98% is 1 out of 50, 90% is 1 out of 10):

Dsc 2509

And here, two packets were missed a few seconds ago:

Dsc 2511

Feel free to take these sketches as starting point for your own tests. You could do all sorts of funky range testing with this, from just seeing how much gets lost in a particular setup, to investigating the effect of different RFM12B baud rates, working in other bands, antenna optimization, identifying in house “cold spots”, and checking the effect of adding an extra pull-up resistor, as recently suggested here and here on the forum.

There are still quirks (i.e. bogus reports every 5s when no packets are coming in, due to byte wraparound).

Both sketches have been added to the RF12 library. There is probably a ton of neat stuff to add – please share your improvements and I’ll try to fold them in so others can use them too. By adding logic for two buttons (or a joystick as on the above RX unit), we could even configure the receiver in the field.

Many thanks to Steve E for coming up with the original idea and getting a first implementation going.

Crunch time

In Hardware on May 14, 2011 at 00:01

Ouch…

The new JeeNode v6 boards have run out. The initial batch has been flying out the door quite a bit faster than I anticipated. And it’s going to take another 10 days until new ones arrive, unfortunately.

My apologies for the delays this will cause.

Assessing the damage

In AVR, Hardware on May 12, 2011 at 00:01

Yesterday’s post was about wearing out the EEPROM memory on an ATmega168. It took over 6.7 million writes to address zero to make it fail. As mentioned, this is a limited test, because reading out the value was done right after writing it. But hey, at least I didn’t have to write 100,000 times to each EEPROM address and wait 20 years @ 85°C to find out whether each byte was still correct…

So we got a failure, now what?

Well, re-running the test caused it to fail after a mere 6,200 write cycles, so that EEPROM definitely isn’t up to spec anymore.

Today, I wanted to see what effect this single massive rewrite of address zero did to the rest of the EEPROM. So I wrote another test which would go through the entire EEPROM and see how well writes + read-backs would work on this same ATmega168 with its massively-abused EEPROM:

Screen Shot 2011 05 11 at 17.23.32

All failures are counted, per EEPROM address. Whenever the maximum number of failures at any single address increases, a map is printed with the counts for each of the 512 bytes. Here’s the startup situation – no errors yet:

Screen Shot 2011 05 11 at 17.23.10

The map counts are encoded as single characters:

 0         =  "."
 1 to 9    =  "1" .. "9"
10 to 35   =  "a" .. "z"
36 to 61   =  "A" .. "Z"
62 and up  =  "?"

Every 100 cycles, the cycle count is printed, just to let me know that the sketch is still running. Unfortunately, re-writing all 512 bytes in EEPROM is way slower than yesterday’s test, over 1 second per cycle. So I also added an LED to toggle on each cycle:

Dsc 2503

Now the waiting begins… it’s going to take hours (maybe even days!) to force the next failure again.

And one thing is clear: it’s not easy to get these chips to fail quickly!

Update – 100,000 cycles later, no new failure yet…

Destruction!

In AVR, Hardware on May 11, 2011 at 00:01

No, not distractions

Had a ATmega168 chip lying around which isn’t going to be used anymore anyway, so why not do some destructive testing on it, eh?

There have been a couple of such tests floating around on the web, so I thought I’d try to replicate them – to try and find out how many read-write cycles the internal ATmega’s EEPROM can sustain. I started from the info on John Boxall’s weblog, and set up a similar configuration, but based on a JeeNode:

Dsc 2497

Note that this isn’t using the LCD Plug, but has direct connections to 6 digital output pins (I used the same pins as in the original sketch: digital 4..9).

Made a simpler sketch to just toggle bits in the EEPROM and display the counter (the display is fast when there’s no I2C expander chip involved):

Screen Shot 2011 05 10 at 18.46.38

It turns out that flipping all the bits in the EEPROM takes a few seconds, and with an expected lifetime well over 100,000 that test would have lasted several days. So instead, I rigged the test to only flip byte 0 in the EEPROM. Let’s see how much beating that single byte can take!

Several hours later…

Dsc 2499

Over 3,260,000 write cycles and still going.

Note that this is only testing EEPROM address 0x000, and that the check is right after the write, so this is not necessarily a very useful test: bad bytes might hold charge, but not for over 20 years as listed in the specs, and some other address might give an error much sooner.

But still… 32x above spec so far. Not bad!

Update – The ATmega168 finally broke down:

Dsc 2502

Then it failed 6200 cycles after the next power-on.

Meet the JeeNode SMD

In Hardware on May 4, 2011 at 00:01

After yesterday’s change of name, I’m pleased to announce a brand new member of the ever-expanding JeeNode family, the JeeNode SMD (aka NS1).

It’s a pre-assembled unit with SMD parts, and just some 6-pin headers you have to solder on yourself. Here’s a hand-soldered test unit with the port headers mounted sideways:

Dsc 2493

Here’s that same unit, seen from the bottom:

Dsc 2494

Sideways mounting adds a new option for using plugs, because this unit is flat enough to use upside down:

Dsc 2495

(Note: oops, that BUB needs to be flipped around!)

You don’t have to do it this way, and can of course just choose to mount the headers in the normal vertical orientation.

The main differences with the standard JeeNode Kit are:

  • on-board activity LED (same as JeeLink and JeeNode USB)
  • on-board reset button
  • pads for A6/A7 analog in, and the AREF pin
  • much flatter, fits in more places than the trough-hole kit
  • less soldering, just a few headers (so you get to choose their orientation)

Still the same as a JeeNode in most other respects, i.e. same size, same battery options, same FTDI connection to the outside world, and same RFM12B radio.

The Café page is here. Along with a page in the shop.

What’s in a name

In Hardware on May 3, 2011 at 00:01

The JeeSMD is getting a new name:

Jsx

JeeSMD is OUT, SMD Kit is IN!

Sknew

The new product link is https://jeelabs.org/sk1 (was “js2”). The SKU label and link on the PCB will be updated later, in the next batch of boards.

The new shop link is https://jeelabs.com/products/smd-kit (was “jeesmd”).

All in the name of progress…

Meet the JeeNode v6

In Hardware on May 1, 2011 at 00:01

The JeeNode v5 addeth a diode, and the JeeNode v6 taketh it away again:

Dsc 2490

Here is the new board, which I’ve started including in the latest packages:

Dsc 2492

The differences with v5 are:

  • The diode jumper is now shorted out by default (cut a trace on bottom side to use a diode).
  • There is a new ground connection near the antenna connection.
  • The PD2 (INT0) and PB2 (SS) pins are now connected to pads (same layout as on JS2).
  • Minor tweaks, such as labeling fixes.

Nothing big or serious, as you can see – I’ll gradually update various bits and pieces on the web to match this revision. For now, please just continue using the links and build instructions of the v5.

(Apologies for the long hiatus, but I needed the break!)

EtherNode on a breadboard

In AVR, Hardware, Software on Jan 30, 2011 at 00:01

After some recent comments on the forum about the etherNode.pde sketch, I wanted to make sure that the code is still working properly on this hassle-free setup (as well as with the Carrier Board):

Dsc 2432

And sure enough, it works as intended:

Screen Shot 2011 01 29 at 21.12.06

The output shows some packets from node 19 – which is the modded RFM12B running the RFM12B_OOK sketch, and it’s working nicely as you can see.

This sketch takes about 12 Kb of code (web server + EtherCard + RF12 driver), so there is ample room to add more features in there. You could use a modded RFM12B module, for example, and have everything you need to create a gateway between 868 MHz OOK devices and the LAN. In both directions in fact, since the RFM12B can also be tricked into sending out OOK packets.

Note that the Ether Card uses a few extra I/O pins from the JeeNode, so be sure to connect the 2×4 headers on the SPI/PSI pins between JeeNode and Bridge Board.

And the best part is that even with this Ether Card attached, all 4 ports on the JeeNode are still available for other uses. They are all brought out on the 8 leftmost pins, clearly labeled with both port numbers and Arduino pin numbers. Also available from the bridge board, as bonus: 2 LED’s and a push button.

As you can see, there’s a lot of empty real-estate on that breadboard – yearning to be put to good use…

PS. In case you’ve been waiting for one of those wooden bases, as included with the JeeNode Experimenter’s Pack: not to worry, I haven’t forgotten about you. The recent batch of packs were sent out without the base – they will be shipped separately once back in stock.

New OOK and DCF relay

In Hardware on Jan 29, 2011 at 00:01

With all the pieces finally in place, and now that I’m getting a little bit more time to hack around again, this seemed like a good time to reconsider the OOKrelay.

So I combined a JeeNode USB, the new OOK 433 Plug, a Carrier Board with box, and half a Carrier Card:

Dsc 2429

In the top left I also added a DCF77 receiver from Conrad, attached to the Carrier Card prototyping board. It’s a bit hard to see, because the little receiver board is actually mounted upright. Here’s a better view:

Dsc 2430

A JeeNode USB was selected, because this thing will be powered permanently, and I chose to hide the connector inside the box to make it more robust. So all this needs is a little USB charger. The LiPo charge option might be useful if I decide to make this thing more autonomous one day (i.e. to record accurate power outage times).

Note that this is a modded JeeNode, as described here, to be able to receive 868 MHz OOK signals.

So what this thing can do – as far as the hardware goes – is listen for both 433 MHz and 868 MHz OOK signals at the same time, as well as pick up the DCF77 atomic clock signals from Frankfurt. Sending out 433/868 MHz OOK is possible too, but since the unit isn’t constantly listening for OOK packets, it’ll have to poll for such commands, which will introduce a small delay.

That’s the hardware, i.e. the easy part…

The software will be a lot more work. I’m going to adapt / re-implement the functionality from the OOKrelay sketch, i.e. this unit will decode and re-transmit all incoming data as RF12 packets, so that they can be picked up by a JeeLink hooked up to my PC/Mac. The clock signal will be useful to accurately time-stamp all receptions, and is really of more general use.

So far, the following I/O pins have been used:

  • one port for the OOK 433 Plug, i.e. one DIO and one AIO pin
  • one input pin for the modded JeeNode, to receive 868 MHz OOK signals
  • one input pin for the DCF77 signal

There is still lots of room left for expansion. A Pressure Plug perhaps, to track barometric pressure. Or a Memory Plug to save up the last data while the central receiver is unavailable. Or both, since these can combined on a single I2C port.

Absent from all this, is a display. First of all, squeezing a 2×16 LCD in there would have been very tight, but more importantly, now that there is a JeePU, there really is no need. I’m already sending the info out by wireless, so a remote graphical display is definitely an option – without PC – or I could use a central server to get this info to the right place(s). This box is intended to be hidden out of sight, somewhere centrally in the house.

Only thing I might consider is a small LED near the USB cable, to indicate that all is well. Maybe… I’m not too fond of blinking LEDs everywhere in the house :)

Carrier Board fix (v2)

In Hardware on Jan 25, 2011 at 00:01

This was looong overdue…

The Carrier Board has been updated to fix a problem with an incorrectly placed DC jack, as described here.

The new board simply omits the (faulty) connection to the DC jack:

Dsc 2421

If you want to use the DC jack you’ll need to connect some wires to it (both “+” and GND). It may not be the most elegant “fix”, but it’s effective and this change was risk-free…

To re-iterate: the DC jack can be soldered to all four pads now, there is no longer a risk of shorting anything out due to mixed-up wires on the schematic. It’ll be much sturdier than before.

All boards sent out in 2011 include the new design – you can recognize it by the fact that it includes the white DC Jack silk-screen printing on the back side – which v1 did not. And that it’s labeled “cb2” instead of “cb1”.

Onwards!

Nodes, Addresses, and Interference

In Software on Jan 14, 2011 at 00:01

The RF12 driver used for the RFM12B module on JeeNodes makes a bunch of assumptions and has a number of fixed design decisions built-in.

Here are a couple of obvious ones:

  • nodes can only talk to each other if they use the same “net group” (1..250)
  • nodes normally each have a unique ID in that netgroup (1..31)
  • packets must be 0..66 bytes long
  • packets need an extra 9 bytes of overhead, including the preamble
  • data is sent at approximately 50,000 baud
  • each byte takes ≈ 160 µs, i.e. a max-size packet can be sent in 12 milliseconds

So in the limiting case you could have up to 7,500 different nodes, as long as you keep in mind that they have to share the same frequency and therefore should never transmit at the same time.

For simple signaling purposes that’s plenty, but it’s obvious that you can’t keep a serious high-speed datastream going this way, let alone multiple data streams, audio, or video.

On the 433 or 868 MHz bands, the situation is often worse than that – sometimes much worse, because simple OOK (which is a simple version of ASK) transmitters tend to completely monopolize those same frequency bands, and more often than not, they don’t even wait for their turn so they also disturb transmissions which are already in progress! Add to that the fact that OOK transmitters often operate at 1000 baud or less, and tend to repeat their packets a number of times, and you can see how that “cheap” sensor you just installed could mess up everything!

So if you’ve got a bunch of wireless weather sensors, alarm sensors, or remotely controlled switches, chances are that your RF12-based transmissions will frequently fail to reach their intended destination.

Which is why “ACKs” are so important. These make it possible to detect when packets get damaged or fail to arrive altogehter. An ACK is just what the name says: an acknowledgement that the receiver got a proper packet. No more no less. And the implementation is equally simple, at least in concept: an ACK is nothing but a little packet, sent the other way, i.e. back from the receiver to the original transmitter.

With ACKs, transmitters have a way to find out whether their packet arrived properly. What they do is send out the packet, and then wait for a valid reply packet. Such an “ACK packet” need not contain any payload data – it just needs to be verifiably correct (using a checksum), and the transmitter must somehow be able to tell that the ACK indeed refers to its original packet.

And this is where the RF12 driver starts to make a number of not-so-obvious (and in some cases even unconventional) design decisions.

I have to point out that wireless communication is a bit different from its wired counterpart. For one, everyone can listen in. Radio waves don’t aim, they reach all nodes (unless the nodes are at the limit of the RF range). So in fact, each transmission is a broadcast. Whether a receiver picks up a transmitted packet is only a matter of whether it decides to let it through.

This is reflected in the design of the RF12 driver. At the time, I was trying to address both cases: broadcasts, aimed at anyone who cares to listen, and directed transmissions which target a specific node. The former is accomplished by sending to pseudo node ID zero, the latter requires passing the “destination” node ID as first argument to rf12_sendStart().

For the ACK, we need to send a packet the other way. The usual way to do this, is to include both source and destination node ID’s in the packet. The receiver then swaps those fields and voilá… a packet ready to go the other way!

But that’s in fact overkill. All we really need is a single bit, saying the packet is an ACK packet. And in the simplest case, we could avoid even that one bit by using the convention that data packets must have one or more bytes of data, whereas ACKs may not contain any data.

This is a bit restrictive though, so instead I chose to re-use a single field for either source or destination ID, plus a bit indicating which of those it is, plus a bit indicating that the packet is an ACK.

With node ID’s in the range 1..31, we can encode the address as 5 bits. Plus the src-vs-dest bit, plus the ACK bit. Makes seven bits.

Why this extreme frugality and trying to save bits? Well, keep in mind that the main use of these nodes is for battery-powered Wireless Sensor Networks (WSN), so reducing power usage is normally one of the most important design goals. It may not seem like much, but one byte less to send in an (empty) ACK packet reduces the packet length by 10%. Since the transmitter is a power hog, that translates to 10% less power needed to send an ACK. Yes, every little bit helps – literally!

That leaves one unused bit in the header, BTW. Whee! :)

I’m not using that spare bit right now, but it will become important in the future to help filter out duplicate packets (a 1-bit sequence “number”).

So here is the format of the “header byte” included in each RF12 packet:

Screen Shot 2011 01 13 at 23.35.02

And for completeness, here is the complete set of bytes sent out:

Screen Shot 2011 01 13 at 23.34.14

So what are the implications of not having both source and destination address in each packet?

One advantage of using a broadcast model, is that you don’t have to know where to send your packet to. This can be pretty convenient for sensor nodes which don’t really care who picks up their readings. In some cases, you don’t even care whether the data arrived, because new readings are periodically being sent anyway. This is the case for the Room Nodes, when they send out temperature / humidity / light-level readings. Lost one? Who cares, another one will come in soon enough.

With the PIR motion detector on Room Nodes, we do want to get immediate reporting, especially if it’s the first time that motion is being detected. So in this case, the Room Node code is set up to send out a packet and request an ACK. If one doesn’t come in very soon, the packet is sent again, and so on. This repeats a few times, so that motion detection packets reach their destination as quickly as possible. Of course, this being wireless, there are no guarantees: someone could be jamming the RF frequency band, for example. But at least we now have a node which tries very hard to quickly overcome an occasional lost packet.

All we need for broadcasts to work with ACKs, is that exactly one node in the same netgroup acts as receiver and sends out an ACK when it gets a packet which asks to get an ACK back. We do not want more than one node doing so, because then ACKs would come from different nodes at the same time and interfere with each other.

So normally, a WSN based on RFM12B’s looks like this:

Screen Shot 2011 01 13 at 23.35.09

The central node is the one sending back ACKs when requested. The other nodes should just ignore everything not intended for them, including broadcasts.

Note that it is possible to use more than one receiving node. The trick is to still use only a single one to produce the ACKs. If you’re using the RF12demo sketch as central receiver, then there is a convenient (but badly-named) “collect” option to disable ACK replies. Just give “1c” as command to the second node, and it’ll stop automatically sending out ACKs (“0c” re-enables normal ACK behavior). In such a “lurking” mode, you can have as many extra nodes listening in on the same netgroup as you like.

To get back to netgroups: these really act as a way to partition the network into different groups of nodes. Nodes only communicate with other nodes in the same netgroup. Nodes in other netgroups are unreachable, and data from those other nodes cannot be received (unless you set up a relay, as described a few days ago). If you want to have say hundreds of nodes all reporting to one central server, then one way to do it with RF12 is to set up a number of separate netgroups, each with one central receiving node (taking care of ACKs for that netgroup), and then collect the data coming from all the “central nodes”, either via USB, Ethernet, or whatever other mechanism you choose. This ought to provide plenty of leeway for home-based WSN’s and home-automation, which is what the RF12 was designed for.

So there you have it. There is a lot more to say about ACKs, payloads, and addressing… some other time.

Another topic worth a separate post, is using (slightly) different frequencies to allow multiple transmissions to take place at the same time. Lots of things still left to explore, yummie!

Touch screen

In Hardware on Dec 21, 2010 at 00:01

Steve Evans (tankslappa on the forum) emailed me recently to present some really exciting developments he’s been working on: a touch screen interface for the Graphics Board:

Whatiwrote

You’re looking at a little touch screen, placed over the Graphics Board, and as you can see, the size matches up surprisingly well.

Pretty fantastic result! And considerably more precise than I had expected.

He used the touch screen overlay of the Nintendo DS, which can be obtained from eBay. As it turns out, this can be hooked up using 2 digital + 2 analog I/O pins, which is exactly what’s still available on the unused two ports.

All that was needed, were 4 pull-down resistors:

Connection

The devil is in the details, though. very small details in fact:

Tinyconnector

Steve mentioned that it took a considerable amount of patience to get 4 wires soldered to that tiny flexible ribbon, with 0.5 mm between each connection. Clearly, a proper connector would have been a bit more convenient (though just as tiny).

Being resistive and analog, this whole thing needs to be calibrated:

Calibrate 1

The code for this has been added as a sample sketch called touchscreen.pde in the JeeLabs repository.

BTW, this is part of a new GLCDlib library, which I’ll describe in more detail tomorrow. Stay tuned!

Rethinking the Arduino hardware interface

In AVR, Hardware, Software on Dec 18, 2010 at 00:01

It’s been almost two years since the first design was created from which the JeeNode was born. It went from this very first prototype:

… to this leaner-and-meaner design, which is the current JeeNode v5:

Jlpcb 105

As you can see, it’s still essentially based on the same layout.

The JeeNode has been the flagship product here at JeeLabs for quite some time. It has been expanded to include a JeeNode USB variant which includes a USB interface and a LiPo charger, as well as a USB “stick-like” JeeLink that ties nicely into the WSN use of JeeNodes. And then there’s the bare-bones JeeSMD, which doesn’t have a wireless module built-in, but which is pin-compatible with the other two members of the JeeNode family.

With all the end-of-year stories coming up, and new year’s resolutions to follow soon, it seems like a good time to present my reasons for doing things this way.

Rethinking the Arduino hardware interface
That’s – in a nutshell – the essence behind the JeeNode.

I stumbled upon the fascinating world of Physical Computing and “Arduino’s” over two years ago, around the time when I also discovered an interesting low-cost wireless module. Lots of things “clicked” right away, but a few didn’t. Given that the Arduino is simply an ATmega (hardware), plus an IDE (software), plus a set of conventions (shields), I quickly realized that there might be more ways to skin this cat, and something new was born (inspired by the RBBB) – as summarized here a year ago.

I don’t want to rehash those points, but let me simply state what the JeeNode is about, assuming you know what an Arduino is.

  • the JeeNode lowers the operating voltage to 3.3V (implications)
  • it includes a wireless radio module (with software)
  • it drops the concept of shields (hard to combine)
  • instead, it adds 4 interchangeable 6-pin Ports (layout)
  • each port includes two dedicated I/O pins as well as power
  • there are numerous Plugs using this port pinout (list)
  • about half the plugs use (software) I2C and can be daisy-chained
  • there are many interface classes and code examples (here and here)
  • the remaining I/O pins are on two extra headers (details, PDF)
  • JeeNodes can be mounted upside-down (CB, GB, POF)
  • … or used alongside a solderless breadboard (BB)
  • with extension cables to move plugs further away (EC)
  • … or a prototype board to re-use all the I/O pins differently (PB)
  • reduced cost by using a detachable / reusable USB-FTDI interface

All this, while remaining fully compatible with “the” Arduino’s software + firmware.

But perhaps the most interesting bit coming out of all this, is that the JeeNode has become a practical ultra-low-power platform, with battery lifetimes measured in months, almost a year even, so far. There have already been tons of posts about this topic. It even spawned a nice little add-on to run JeeNodes from a single AA or AAA cell.

You may or may not agree with all the choices, but this is what the JeeNode is about.

Update – the Redmine repository is no longer available, everything is now on GitHub.

Voltage: 3.3 vs 5

In AVR, Hardware on Dec 16, 2010 at 00:01

One of the decisions made early on for the JeeNode, was to make it run at 3.3V, instead of the 5V used by the standard Arduino.

The main reason for this was the RFM12B wireless module, which can only be used with supply voltages up to 3.8V, according to the specs. Running them at 5V seems to give varying results: I’ve never damaged one, but there have been reports of such failures. Given that the older RFM12 (no B) worked up to 5V, my hunch is that something in the design was found to give problems at the higher voltage. It’s just a guess on my part, though.

So what’s the deal with 3.3V vs 5V?

Well, the first thing to note, is that the ATmega328 used in a 3.3V JeeNode runs at the same 16 MHz frequency as a 5V Arduino does. This overclocking is “out of spec”:

You’re not supposed to do this, but in my experience the good folks at Atmel (the designers and manufacturers of ATmega’s and other goodies) have drawn up specifications which are clearly on the conservative side. So much so, that not a single case has been reported where this has caused problems in any of the several thousand JeeNodes produced so far. As I pointed out in a previous post, that doesn’t necessarily mean everything is 100% perfect over the entire temperature range. But again: no known problems to date. None.

This is good news for low-power uses, BTW. It means you can get the same amount of work done using less power, since power = voltage x current. Even more so because both voltage and current are lower at 3.3V than when running at 5V.

A second reason for running at 3.3V, is that you can use 3 AA batteries instead of 4 (either alkaline or rechargeable). And that you can also power 3.3V circuits with LiPo packs, which have this hugely convenient 3.5..4.2V range.

The third important reason to run JeeNodes at 3.3V, is that more and more neat sensor chips are only available for use in the 2.7 .. 3.6V range or so. By having the entire setup operate at 3.3V, all these sensors can be used without any tedious level converters.

Occasionally I’ve been bitten by the fact that I used a chip which doesn’t work as low as 3.3V, as in the first RTC Plug trial. But more often than not, it’s simply a matter of looking for alternative chip brands. One recent example was the 555 oscillator used on the Infrared Plug: the original NE555 needs at least 4.5V, but there’s an ICM7555 using CMOS technology which works down to 3V, making it a non-issue.

Mixing 3.3V and 5V devices

The trouble with these voltage differences, is not just that the power supply needs to be different. That’s the easy bit, since you can always generate 3.3V from a 5V supply with a simple voltage regulator and 2 little capacitors.

The real problem comes from the I/O interface. Placing a 5V signal on a chip running at 3.3V will cause problems, in the worst case even permanently damaging the chip. So each I/O pin connected is also affected by this.

Fortunately, there’s often a very simple workaround, using just an extra resistor of 1 kΩ or so in series. To see how this works, here’s the way many chips have their input signals hooked up, internally:

Screen Shot 2010 12 14 at 23.35.16

There’s a pair of diodes inside the chip, for each pin (not just the inputs), used for ESD protection, i.e. to protect the chip against static electricity when you pick it up.

These diodes “deflect” voltage levels which are above the VCC of the device or below GND level. They do nothing else in normal use, but if you were to place 5V on in a pin of such a device powered by 3.3V, then that would lead to a (potentially large) current through the upper diode.

With electronics (as with humans, btw), it’s usually not the voltage itself which causes damage, but the current flow it leads to, and – in the case of sensitve electronics components – the heat produced from it.

By placing a 1 kΩ resistor in series, we limit the flow through the diode to under 2 mA, which most devices will handle without any problems:

Screen Shot 2010 12 14 at 23.42.27

Ok, so now we can hook up signals to a JeeNode, even if they swing in the 0..5V range. This works best with “slow” signals, BTW. The extra resistor has a bad effect on rise and fall times of the signal, so don’t expect this to work with signals which are in the 1 MHz range or higher. Then again, it’s unlikely you’ll need to tie such fast signals directly to an ATmega anyway…

How about the other direction?

What if you have a chip running at 5V which needs to receive signals from a chip running at 3.3V, i.e. signals going in the other direction?

Well, it turns out that this may or may not work by simply tying the two lines together. The 3.3V output signal will definitely not damage a chip running at 5V. The worst that can happen, is that the 5V side doesn’t consider the signal valid.

We need to look into logic levels to figure this one out, as specified in the datasheet of the chip. The easy part is logic “0”, i.e. a low level. Most chips consider anything between 0 and 0.8V a logic “low”. There will hardly ever be an issue when tying a 3.3V chip to a 5V chip.

The tricky part is logic “1”, i.e. a signal which is intended to represent a high level. Now it all depends on what the 3.3V chip sends out, and what the 5V chip requires.

Most CMOS chips, including the ATmega, send out nearly the full power line voltage to represent a logic “1” (when the load current is low), so you can expect output signals to be just about 3.3V on a JeeNode.

On the input side, there are two common cases. Some chips consider everything above 1.6V or so to be a logic one. These chips will be perfectly happy with the JeeNode signal.

The only case when things may or may not work reliably, is with chips which specify the minimum logic “1” voltage to be “0.7 x VCC” or something like that. On a 5V chip, that translates to a minimum value of 3.5V …

Note that datasheets usually contain conservative specs, meant to indicate limit values under all temperatures, load conditions, supply voltages, etc.

In practice, I find that even with “0.7 x VCC”, I can usually drive a 5V chip just fine from a JeeNode. The only exception being higher power chips, such as stepper motor drivers and such, which operate mostly at much higher voltage levels anyway. For these, you may have to use special “level translator” chips, or perhaps something like the I2C-based Output Plug, which can be powered with voltages up to 50V or so.

This post only addresses digital I/O signals. With analog I/O, i.e. varying voltage levels, you will need to carefully review what voltage ranges are generated and expected, and perhaps insert either a voltage divider or an op-amp to amplify voltages. That’s a bit more involved.

But all in all, living mostly in a 3.3V world is often more flexible than living mostly in a 5V world, nowadays.

Which is the fourth reason why I decided to run JeeNodes at 3.3V, BTW.

RF12 acknowledgements

In Software on Dec 11, 2010 at 00:01

The RFM12B wireless module is a transceiver, i.e. able to send and receive packets over wireless. This is an important advantage over simple sensor units which just send out what they measure, and things like RF-controlled power switches which only listen to incoming data but are not able to report their current state.

The only thing is… it’s a bit more work.

This is reflected in how the RF12 library works:

  • simple reception is a matter of regularly polling with rf12_recvDone()
  • simple transmission means you also have to call rf12_canSend() and rf12_sendStart()
  • the above are both essentially uni-directional, so packets can get lost

The second mechanism added to RF12 was a set of “easy transmission” functions, i.e. rf12_easyPoll() and rf12_easySend(). These look similar, but they send out data packets asking for an ACK (acknowledge) packet from the receiver to confirm that the packet was correctly received. If nothing comes in, they will re-send the packet (and repeat a few times, if needed). This mechanism greatly improves the chance of a message arriving properly at the destination. Losing an occasional packet is one thing, losing all retries is a lot less likely!

Note that packets can be damaged or get lost at any time. It may well be that the original packet arrived just fine, but the ACK got lost instead. The sender will resend, and then (probably) get the ACK which stops this retry cycle.

So with the easy transmission functions, note that very occasionally a packet might be received twice. If it is crucial to weed these out, you can include a counter in your data packets to help detect and ignore duplicates.

With RF12demo as receiver, ACK handling is automatic. It knows when the originating node wants to get an ACK, and will send it out as soon as possible. This is reported in the output as the text “-> ack”.

The code for this in RF12demo is horrendous:

Screen Shot 2010 12 10 at 18.27.08

This is silly, and overkill for simple cases. So let’s improve on it.

I’ve added two utility definitions to the RF12.h header, which can simplify the above code to:

Screen Shot 2010 12 10 at 19.58.02

That’s better, eh?

The rest is just there to deal with a special configuration setting in RF12demo.

So if all you want is to add logic in your own sketch to send back an empty ACK packet when requested, the above can be simplified even further to:

Screen Shot 2010 12 10 at 19.59.09

For completeness, here’s a complete processing loop for a receiving sketch which supports nodes using the easy transmission mechanism:

Screen Shot 2010 12 10 at 19.59.45

You have to send out the ACK after processing the packet, because the rf12_sendStart() call will re-use the same packet buffer and overwrite the incoming packet.

Also, RF12_WANTS_ACK and RF12_ACK_REPLY are defined as macros which access the global rf12_hdr variable, as set by rf12_recvDone(). IOW, the convenience comes for free, but it does depend on some fixed assumptions. I can’t think of a situation where this would lead to problems, given that RF12-based sketches are probably all structured in the same way, and that globals are part of the RF12 driver.

For another example, see the blink_recv.pde sketch, which has also been simplified with these two macros.

No more diode!

In Hardware on Dec 6, 2010 at 00:01

The JeeNode v5 introduced a change, which I now regret – due to the amount of confusion it has generated, and the limited utility: an extra protection diode in the PWR line on the FTDI connector (and only there!).

Here’s the PCB layout, as seen in EAGLE:

Screen Shot 2010 12 05 at 17.44.49

The diode is marked “D1”, with a solder bridge on the back side of the board (red lines are on top, blue lines on the bottom, and plated-through holes are in green).

Here’s a close-up:

Dsc 2074

What it does, is block the power when it’s connected the wrong way around. But that only protects the FTDI connector, which is actually quite well protected agains reversal already (if you flip the connector, GND will go to the reset cap, which blocks all DC current anyway).

The drawback of this design is that it lowers the voltage by about 0.7V, so instead of 5V, you get about 4.3V on the remaining PWR pins, such as on all the port headers.

Worse still, is that it causes the JeeNode to stop working from a 3.3V power source, such as the AA Power Board, because it will drop the voltage to about 2.5V – which is too low to run at 16 MHz!

I did design a workaround into the JeeNode v5: there’s a solder jumper on the other side of the board, to bypass that diode. Where “bypass” means: short out the diode, as if it wasn’t part of the circuit in the first place.

The irony is that I’ve been closing this solder jumper on every new JeeNode I’ve built so far.

Add to that the fact that the holes for that diode are almost too small to push the thick diode wires through, and it becomes clear that this new “feature” causes more problems than it solves.

Starting now, once the stock of kits is exhausted, new kits will be shipped WITHOUT the diode!

You will now have to always add a drop of solder to close the jumper on the back:

Screen Shot 2010 12 05 at 18.04.03

If you don’t, there will no power connection from the FTDI header to the JeeNode.

It’s an important change, but it removes the nasty suprise that sometimes things work and sometimes they don’t!

Oh, and if you’re into this tradition – I hope you had a nice Sinterklaas!

Bridge Board – caveats

In Hardware on Dec 2, 2010 at 00:01

There is some complexity lurking in the design of the Bridge Board, which in turn may lead to some head scratching, I’m afraid…

That complexity comes from the fact that not all I/O pins are always available.

Let’s start with an overview of the different pin groups:

Annotated bb

The basic idea is that when you connect all four port headers, then you’ll get access on the breadboard to all the pins marked above in RED. This is the most common usage, and main intended use of the Bridge Board. Note that DIO2, DIO3, AIO2, and AIO3 are available on multiple pins.

So if you follow yesterday’s post, you can use all the pins shown in red as is. The main benefit being that you can easily access the main 8 I/O pins, and that port 2 is in fact replicated in the same layout on the breadboard if you want to hook it up to JeePlugs.

If all you need are the leftmost 16 pins – you can skip the rest of this post.

The remaining pins takes a bit more explanation and preparation, and requires adding some more header on the Bridge Board as well as on the JeeNode! – here’s the summary:

  • to use the 6 SPI/ISP pins marked in BLUE, add the 2×4 pin header on the right
  • to use 4 more I/O pins marked in GREEN, add a 8-pin header on the left (the middle 6 are actually enough)
  • to use FTDI, add the 8-pin header on the left (only JeeNode v4: also the 2×4-pins on the right)

That last option also requires soldering in a 0.1µF capacitor if you want to include the reset-on-open capability for easy uploading. It’s mostly intended for use with a JeeSMD, which does not have an upload capability of its own.

There is a reasoning behind all this madness:

  • The leftmost 16 pins on the breadboard were the main design goal for this board.
  • The middle 13 pins (IRQ to B0) match the layout need for the Ether Card.
  • The rightmost 20 pins are compatible with both Ether Card and Carrier Board.
  • The Bridge Board is compatible with JeeNode v5 and v4, JeeNode USB, and JeeSMD.

The two LEDs are brought out on separate pins and always available – on the LED1 and LED2 pins, respectively. They are very efficient and require only a few mA to shine brightly. You can hook them up to any I/O pin or other 3.3/5V signal on your breadboard. They make a great debugging tool when the going gets tough.

The push-button at the top of the board is also always available on the BTN pin. It is connected to ground, so pressing the button shorts the BTN pin to ground – you can use the internal ATmega pull-up and some software debouncing to read out this button.

The button can be used as reset button if you have the RST pin, which is right next to it, hooked up to the JeeNode. This requires either the 8-pin PSIX header or the 2×4-pin SPI/ISP header to be hooked up, as described earlier.

Assembling the Bridge Board

In Hardware on Dec 1, 2010 at 00:01

This is going to be one of those long posts again, with lots of pictures…

I’ve switched to a new Bridge Board v2 revision, which differs only in some minor ways from the BB v1, so this also applies to that board. The changes are:

  • the FTDI connector orientation has changed to match the underlying JeeNode
  • one extra breadboard pin on the right, to better match the large breadboard
  • minor tweaks to layout and labeling

Since this is an assembly guide, let’s start with the parts included in the kit:

Dsc 2368

And here’s what we want to end up with – a module which plugs into a breadboard:

Dsc 2381

Ok, let’s get started… there are two current limiting resistors for the on-board LEDs. I prefer to mount them on the bottom of the board, because that leaves the “1” and “2” labels clearly visible on top:

Dsc 2369

Everything else is soldered on the top side of the board. Let’s start with the LEDs. These are polarized, so make sure to insert them properly:

Dsc 2370

The only other component left is the push-button:

Dsc 2371

Congratulations! All that remains is to solder on the various pin headers.

More…

Read the rest of this entry »

More box options

In Hardware on Nov 24, 2010 at 00:01

Here are a few more options for putting JeeNodes in a box which turn out to work really well:

Dsc 2316

Of course anything larger will fit as well, but I wanted to find out which boxes would be just enough for a JeeNode. As it turns out: several!

These boxes are all available from Conrad, which has an online shop in several European countries. I’m not going to stock them for two reasons: 1) there are just too many choices, and everyone has different needs and preferences, and 2) they won’t fit in an envelope. So to get them, you’ll have to order from Conrad yourself.

The good news is that all these boxes are very inexpensive.

Below is a summary of each one shown above, along with the Conrad order numbers and external dimensions.


#534347 – 85x56x25 mm

The smallest box of ’em all. The JeeNode PCB fits in any of the slots, but you need to make a small notch on the inside of the top cover:

Dsc 2311


#534346 – 85x56x39 mm

A taller version, same color and same perfect fit for a JeeNode (as with the previous box, the FTDI pins need to point up, not out). No need to adjust the cover on this one:

Dsc 2312


#530113 – 88x58x30 mm

This one is slightly larger on the outside, but the sides are slanted and the board only fits by slightly enlarging the plastic notches inside. There’s a small hole in one of the shells:

Dsc 2313

However, there’s also an optional PCB for it with copper islands on one side (#530126). Then the JeeNode can just sit on top as is:

Dsc 2317


#520861 – 90x60x51 mm

On the large side, and fairly high. The JeeNode won’t fit in tightly, so you’ll need to fasten it somehow. This box could almost include a 3x AA battery holder with switch, but to do so you’ll need to remove some plastic inside on all 4 stand-offs:

Dsc 2314


#528373 – 124x72x30 mm

This box is almost identical to the Jee Labs box, but it’s transparent, it has slightly smaller inner dimensions, and there are no slots to slide the Carrier Board into. You can either shorten the pcb a fraction of a millimeter or make some very shallow grooves on the inside of the box to hold the pcb in place:

Dsc 2315

This box also comes in BLUE (#528834), RED (#528347), and GREEN (#528360).

Don’t know about you, but I’m pretty sure I’ll find a good use for each of these little boxes around here…

Indoor temperature, etc.

In Hardware, Software on Nov 20, 2010 at 00:01

Here’s a fun little project…

A Graphics Board with a JeeSMD and two plugs: a Pressure Plug and a partially-populated Room Board.

The result is a geeky little indoor environmental monitoring station:

Dsc 2293

Couple of notes here:

  • I took the lazy way out and merely display the info as text, graphics would be so much nicer!
  • Both sensors can read the temperature, but as you can see, they don’t fully agree…
  • I added the FTDI hookup and used it to power this thing via an AA Power Board.
  • The AA board does double duty, as a little stand to hold this thing slanted upwards.

Adding FTDI was very useful in this case, since it also makes it possible to re-program the JeeSMD, which has no FTDI connector on board. All it needs is a 0.1 µF cap and the 6-pin header:

Dsc 2298

But there’s more to it than that, alas: to be able to upload to the JeeSMD, you need to hook up all the headers on the JeeSMD, i.e. also the PSI and the SPI/ISP headers. Adding those after the fact is very tricky, since you can’t reach the back of the Graphics Board pcb anymore if you soldered the LCD on permanently – as I did.

I had to solder the female headers slightly higher, to just barely reach the pins from the top with a very fine soldering iron tip (I use 0.4 mm). It worked, but as a result, the JeeSMD sits a bit higher on its pins than usual:

Dsc 2297

Here’s the indoor.pde sketch, also added to the Ports library:

Screen Shot 2010 11 17 at 22.47.37

Onwards!

Meet the Graphics Board

In Hardware on Nov 15, 2010 at 00:01

Sometimes, 2×16 characters (or perhaps a few more) just don’t cut it, when I’d like to present things graphically, or use larger fonts for some of the info. That’s when a “GLCD” would be handy, one which lets you set individual pixels, that is. I was pointed to a nice low-power 128×64 display recently, and decided to create a pcb for it – so here’s the new Graphics Board:

Dsc 2258

Due to the size of the board, it’s not a plug or an add-on to a JeeNode, but the other way around: you can take a JeeNode, JeeNode USB, or JeeSMD, and push it onto this board to power and drive the display.

Ports 1 and 4 are used for the diplay, but ports 2 and 3 are available, and brought out in such a way that plugs can easily be added on. To make a clock, add an RTC Plug. To add a few touch buttons, add a Proximity Plug. To create a fancy Reflow Controller, add a Thermo Plug. Or just use it as is and add a sketch to display messages received over wireless. Endless possibilities…

Here’s the display in action, it’s pretty bright when driven from 5V:

Dsc 2278

It can display up to 8 lines of 21 characters, but it’s also fully graphical of course. BTW, in real life the display looks much more white-on-black.

I particularly like this setup, using the AA Power Board to make this thing completely self-powered:

Dsc 2245

The backlight resistor is chosen such that on 3.3V, this display draws ≈ 6 mA, and on 5V it draws ≈ 19 mA. It will last a few days with an AA Power Board, but when the 100 Ω resistor is replaced by 270 Ω or even 470 Ω, you can get well over a week of battery life on a single AA (assuming the JN itself is sleeping most of the time) – at the cost of dimming the backlight to a fairly low level.

There is a solder jumper on the board which normally connects the backlight to the PWR line. By connecting it to the IRQ line instead, that pin can turn off the backlight under software control (or dim it, using PWM).

The display is based on the ST7565 chip and can be driven by Limor Fried’s great ST7565 LCD library. Note that this library uses a 1 Kb RAM buffer.

Here’s the glcd_demo.pde sketch which generates the above display:

Screen Shot 2010 11 14 at 17.20.36

I included logic to put the ATmega and radio into power down mode to let me measure the display’s current consumption. While active, they draw another 5..30 mA.

The Graphics Board is now in the café and the shop.

UpdateHere is a copy of the ST7565 code I use.

JeeNode Experimenter’s Pack

In AVR, Hardware on Nov 8, 2010 at 00:01

Neat – it looks like JeeNodes are starting to become popular for workshops!

I’m not really surprised: it’s more fun than an Arduino, IMO, because you get to learn the basics of electronics and soldering, and of course every JeeNode comes with wireless connectivity built-in. As I’ve said before, making things happen by wireless is a bit like magic…

FWIW, there are a couple of workshops scheduled for this month (“in-house”, i.e. for a specific audience, and I’m only indirectly involved), all are based on either a JeeNode or an RBBB. Both are well suited for solderless breadboards, which – if you ask me – is one of the greatest inventions ever for tinkering and learning electronics. Sure, soldering works best when the circuit is known and proven, but nothing beats a breadboard, some jumper wires, and a bunch of components and chips to try out things!

This gives me great satisfaction. No, not for the money side of it (it’s all discounted anyway), but because I find nothing more exciting than to see people try out new fun stuff and nurture their tech geek sides :)

Learning is great: if you’re young, it’ll make you wiser – if you’re old, it’ll make you younger … (and it’s fun!)

The big question is always: “what do I need to get started?” – and my answer is usually: “it depends on what kind of adventure you’re after”.

I’ve come up with a new “JeeNode Experimenter’s Pack” to create a baseline for the future. That way, it will be easier for me to set up and document my experiments, knowing that there is a common baseline on which to build. It’s also the logical step after this rubber-band concoction. It consists of the following key components:

Dsc 2221

In prose:

In addition, and only in combination with the rest of the Experimenter’s Pack, I’m throwing in a little 10×17 cm laser-cut wooden base and an LDR to get started with some sensor experiments:

Dsc 2220

The base turns the whole thing into a self-contained “project platform” for all sorts of experimentation. And the AA Power Board will supply 3.3V to make this setup portable and usable anywhere. The rest of the empty space is all yours. That’s where the fun happens :)

The AA Power Board is not just a gimmick, BTW: an AA battery will actually provide more power @ 3.3V than a 9V “block”! As someone pointed out recently, it’s also a great way to drain any half-used AA batteries you might still have lying around (who hasn’t?).

Here’s a recent example of use (which required a bit more power, so I hooked it up to a 12V supply):

Dsc 2215

It’s a little stepper motor tester (using an EasyDriver board). Nothing fancy, but it was a convenient way for me to try something like this out. That project board has now been cleared to make room for new experiments…

That’s the whole point, really – this self-contained setup is intended to provide a quick path for trying out new ideas. USB-connected or battery-powered, serial or wireless, local or remote, whatever.

Once it all works, you could:

  1. take the design and redo it as a more permanently soldered circuit
  2. design a pcb for it (which is what I did for the graphics board)
  3. put it all into a custom enclosure and keep using the setup
  4. stash it all away as is, for some other time
  5. put hot glue on it? (yikes!)

I’ve added this to the shop, as 1- and as 10-pack.

Meet the Bridge Board

In AVR, Hardware on Oct 27, 2010 at 00:01

As mentioned not so long ago on this weblog, I’ve been doodling with some ideas to simplify using a JeeNode alongside a solderless breadboard. So – tada! – here’s the new Bridge Board:

Dsc 2167

As the name says, it acts as a bridge between a JeeNode (also USB or SMD variants) and a breadboard. All the I/O and power pins in one row, labeled for easy reference (including Arduino pin numbers), with two pins sticking into the power rail for ground and +3.3V. The JeeNode goes underneath, component-side up, with the radio on the right-hand side.

Two LEDs and a push button are also brought out, available for general-purpose use.

In the most basic form, the Bridge Board has just 4 6-pin male haders to push into the JeeNode ports, and 29 (+ 2 power-rail) pins to push into a medium or large size breadboard.

The generality of this setup increases if you hook up more headers between the JeeNode and the Bridge Board. With the SPI/ISP connector included, you get the ability to hook it up to an Ether Card, for example:

Dsc 2165

The reason this works, is that the 20 pins on the right are compatible with a Carrier Board – with the “BTN” and “LED2” pins extra. Note that with an Ether Card hooked up, all four ports (i.e. 8 DIO/AIO pins) are still fully available for your own use.

If you connect the 8-pin PSIX header on a JeeNode v5 (or both PSI and SPI/ISP on the other variants), plus a 0.1 µF capacitor, then the FTDI header on the left side can be used. This is paricularly useful for the JeeSMD, which doesn’t have an FTDI connector of its own.

Some I/O signals are brought out on more than 1 pin on the breadboard: DIO2/AIO2 and DIO3/AIO3. This maintains compatibility with the Carrier Board and also means that Port 2 is available on the breadboard in the standard port header layout: PWR, DIO, GND, +3V, AIO, IRQ if you want to insert any of the Jee Plugs.

Another way to combine plugs with the breadboard is to use stacking headers, so that the 4 ports can be re-used on the top of the Bridge Board. See the setup I plugged into the lower left:

Dsc 2166

Evidently, I had to make sure that all the I/O pins work properly, so I pre-loaded the SMDdemo.pde sketch onto a JeeNode and hooked up lots of LEDs:

Dsc 2161

Yeay – it works!

(note how the push-button has been turned into a reset button – this requires either the SPI/ISP or the PSIX headers to be hooked up)

I expect this new setup to be very convenient for all the endless experimentation going on here at Jee Labs. I’ll be updating the documentation site and shop shortly to reflect this addition to the Jee product line-up. I’ll also be adding 6- and 8-pin stacking header 10-packs.

Long live the breadboard!

Wireless mousetrap

In Hardware on Oct 22, 2010 at 00:01

Mathias Johansson recently sent me a description of his project which is just too neat to pass up. So here goes – photos by him and most of the text is also adapted from what he told me in a few emails.

I’ll let Mathias introduce his project:

It is late autumn here in Sweden and the mice starts to search for a winter home. They do normally stay outside modern constructions but I have a croft that is over 100 years old and they tend to like my attic. Mice are pretty cute, and I wish them no harm, but they damage my ceilings! Therefore I have to catch them in traps and transport them deep into the forest and release them near the brink of a stream.

Some properties of each of the three traps built so far:

  • Does not harm the mouse
  • Immediately reports which trap is closed on a webpage
  • Disables itself if the alarm system is turned on for longer periods of absence

Here’s the mousetrap, ready to go:

Mouse Trap

With a guest…

Mouse in Trap

And here the status page indicating which traps have been sprung:

Homepage

The schematic was implemented on what looks like a mini breadboard, here’s the Fritzing version of it:

Musetrap v0 1 bb

The infrared receiver was salvaged from a BoeBot and is used to detect the presence of a guest to spring the trap. Note that by the time it detects something, the tail of the mouse will be mostly inside the trap, so this is a gentle as it gets – well, if you’re a mouse…

Mathias concludes with:

Feel free to publish the pictures (and text) in your “success story” forum or elsewhere on your web-page if you think they are of interest to others or inspire new uses for the JeeNode.

Thanks, Mathias, for sharing your ideas and your delightful rodent-friendly project!

Room Node redesign

In Software on Oct 15, 2010 at 00:00

Room nodes were one of the first reasons I came up with the JeeNode in the first place. It has all evolved a bit since then (and it will evolve further until there is a good enclosure):

Dsc 2134

It’s now time to start redesigning the software for Room Nodes. The main reason being that the code needs to take more advantage of all the low-power savings achievable with JeeNodes. Current battery lifetimes are 1..2 months, using 3x AA alkaline batteries. That’s not nearly good enough – I really do not want to go through the house replacing tons of batteries every month or so (even rechargable ones).

I can think of two reasons why the current rooms.pde sketch isn’t doing that well:

  1. The “easy transmission” mechanism does retries when no ACK is received – this is a good idea in general, but there is no exponential backoff mechanism in place in case the central node is off, mal-functioning, out of range, or if there is simply too much interference at times. What’s even worse is that the node sits there waiting for an ACK for many seconds, guzzling electricity like crazy with the RFM12B and the ATmega full on!

  2. The code sends out a fresh packet on each transition from the PIR motion detector. If the sensor is in a room where motion is very common, then new packets may get sent out far more often than necessary – and quickly drain the battery.

So the question is how to improve on this. One thing I’m going to do is side-step the rf12_easyPoll() etc. interface for the next Room Node implementation, and go back to rf12_recvDone() etc. Coding at this slightly lower level is more work, but also gives me substantially more control in return.

Next, some decisions need to be made about how often and when to send out packets, and when to work with acknowledgements. Here are some of my considerations for that – evidently not everyone will agree with this set of choices, but I think they are sufficiently general to work in many cases:

  • Temperature, humidity, and light levels need only be sent out once per five minutes. Perhaps averaging the values once a minute to smooth out measurement variations.

  • No need to use ACKs for this. Not knowing the exact temperature for the past hour is not the end of the world. The new logic can just send out readings once every five minutes, with the expectation that most of them will usually come in just fine.

  • The PIR motion sensor is a completely different matter: I’d like to be told when new motion is detected as quickly as possible, i.e. within less than a second.

  • Then again, once motion has been detected, I don’t really care too much about frequent vs. infrequent motion. Telling me once a minute whether any motion was detected in that past minute should be enough.

  • Once motion ceases to be detected for a minute, the system goes back into its highly responsive mode, i.e. the moment new motion is detected, I want to hear about it again, right away.

  • The system could send different packets for different triggers, but I don’t want to complicate things unnecessarily. My expectation is that in a room with no motion, there will be one packet going out every 5 minutes, with one “wasted” bit for the motion detector state. In a busy room, there will be a packet going out up to once a minute due to the motion detector firing all the time. The number of bytes saved is probably not worth the extra trouble of having to deal with different types of packets at the receiving end.

  • The last reason to send out packets, is when the battery voltage of the sensor node is getting low. This can be checked once a minute, along with the temp/humid/light cycle.

  • Changes in motion or battery level are important events. These should use the acknowledge mechanism to make sure the event gets to its destination even with occasional packet loss.

  • The mechanism for acks needs to be more sophisticated than it is now. The first big optimization is to only wait a few milliseconds for the ACK. If it doesn’t come in, go back to sleep, and try again a second later. That should by itself reduce the current worst-case current draw by two orders of magnitude.

  • Refinements such as exponential back-off would be nice, but I don’t expect them to make that much of a difference, in a home monitoring setup where all serious failures are likely to be noticed and resolved within a day.

  • Another refinement I don’t care too much about, is to adjust the 5-minute reporting interval depending on the measured light levels. Note that this does not apply to motion (which must always remain alert) – it’s just a way to reduce packet transmissions even further at times when very little happens anyway. I’m not sure it will increase battery life that much, though: brief packet transmissions are not the main power drain, the always-on PIR is the main determinant for battery life, as far as I can tell.

The highest packet frequency for this new approach is almost two packets per minute: motion is detected, then one minute later a packet comes in reporting that it is no longer being detected, and then immediately after that new motion is detected again.

So if you sit still in front of a Room Node, and move exactly once every 61 seconds, you’ll get extra brownie points and trigger twice as many packets as when you move around all the time. I’m willing to dismiss that scenario as being almost hypothetical :) – I can’t prove it, but my hunch is that this worst-case scenario will always exist, no matter what the algorithm is.

Decoding IR pulses

In Hardware, Software on Oct 13, 2010 at 00:01

After the last few posts, it must come as no surprise that I’ve been working on a new Infrared Plug – so now it’s time to start exploring the software side of things. Note that IR reception doesn’t really need a plug at all, I simply inserted a TSOP32238 IR decoder chip into port 2 while debugging the code:

Dsc 2129

Note: I’ll be using the TSOP34838 for the planned Infrared Plug. It only differs in pinout (!) – and both can be used at 3.3V, which is essential.

In preparation of that new plug (atoms need time!), I’ve added a new “InfraredPlug” class to the Ports library, with the following interface:

Screen Shot 2010 10 12 at 17.30.37

This allows receiving IR codes on the AIO pin of any port, as well as sending out IR bit patterns on the DIO pin.

There’s a new ir_recv.pde sketch to demonstrate reception of arbitrary IR signals:

Screen Shot 2010 10 12 at 17.33.59

Here is some sample output, using two different Apple remotes which send using the NEC protocol, as described on this excellent site by San Bergmans:

Screen Shot 2010 10 12 at 16.49.22

You’re looking at a decoded bit stream – some minor processing will be needed to extract the actual data bits from each packet. This was done to make the decoder as flexible as possible – allowing it to handle all sorts of remotes.

The basic idea is that you set up the InfraredPlug instance with “slot” and “gap” parameters. The slot value (1..255) specifies the granularity of the time slots used by the decoder (in units of 4 µs). The default slot value is 140, this corresponds to time slots which are 560 µs wide. De gap value tells the driver when to consider a data packet as being complete (in units of 256 µs). The default gap value is 80, i.e. treat a series of pulses as one packet once 20 ms have elapsed after the last pulse.

The values can be changed with the “configure()” method. In fact, ir_demo will change the slot value when it receives an integer followed by lowercase “s” on the serial port (not echoed). The default setting on startup is “140s”. For RC5 codes, use “222s”, for RC6 “111s”, and for Nokia remotes “125s”, to name a few.

Each time a packet has been received, ir_demo will send the decoded data to the serial port. The data consists of a series of hex digits, each representing one 4-bit nibble of data, as returned by the InfraredPlug class:

  • 0..9 = 1..10 slots
  • A = 10 = 11 or 12 slots
  • B = 11 = 13 or 14 slots
  • C = 12 = 15 or 16 slots
  • D = 13 = 17 or 18 slots
  • E = 14 = 19 or 20 slots
  • F = 15 = 21 or more slots

The nibbles at even positions correspond to pulse ON widths, the nibbles at odd positions are pulse OFF widths – both as a multiple of the configured slot time, with the above adjustment of longer pulses applied.

The “send()” method uses a different format. You give it a bit pattern and the number of bits to send. Each bit represents an ON or OFF signal value. The duration of each bit is the same slot value as used in the receiver.

That’s it. A simple design which should be able to support lots of different appliances and remotes.

Bridge Board it is

In Hardware on Oct 9, 2010 at 00:01

Yesterday’s post triggered some great comments and email exchanges. I came up with this 29-pin design:

Jlpcb 116

There’s a lot more to say about the board and the choices that ended up being made for this particular setup, but I’ll refrain from doing so until the pcb is ready and comes back for testing.

Let me just point out the two uncommitted LEDs with current-limiting resistors, as well as the sideways push-button at the top – again uncommitted, but it can easily be tied to the RESET pin.

Note again that this board is for male pins pointing down, so this effectively holds a JeeNode, JeeNode USB, or JeeSMD together with a half- or full-sized breadboard.

Attentive readers will have noticed the list of Arduino pin numbers along almost the entire length of the board. No more guessing or doc searching if you live in the Arduino ecosystem most of the time – Uno, Due, whatever. A few signals come out on more than one pin, but there’s a reason for that…

Onwards!

Experimenter’s setup

In Hardware on Oct 8, 2010 at 00:01

I keep looking for ways to make it easier to try out stuff – since that’s what I tend to do a lot, here at Jee Labs.

Here’s a trial with a graphics LCD I was mucking about with recently:

Dsc 2111

I don’t like it. Even if the JeeNode’s pins were facing down into the solderless breadboard, it eats up a lot of real-estate, while only a few pins are actually used. Part of the reason is that the ports have a lot of duplicated power pins (that’s the whole point when you use them independently).

I’d much rather use the JeeNode as follows:

Dsc 2109

Then you develop, upload, and test things while tethered. And when it’s ready to use elsewhere, just replace the BUB with an AA Power Board:

Dsc 2110

Now I’m wondering if it wouldn’t be useful to create a little “breadboard interface panel”, like this:

Screen Shot 2010 10 07 at 14.43.48

It’s a bit like the Breadboard Connector that is included with each Expander Plug, as described in this post.

The panel would re-route all pins to the pins along the top row of the breadboard, as well as hook up to the two power rails along the top.

The top of the panel could have extensive labeling for reference. Even some port headers to hook up plugs, if I can figure out which orientation might work best. No components, it’d just be a little back, eh, I mean, front-plane.

Room Node battery life

In AVR, Hardware on Oct 6, 2010 at 00:01

The current Room Node sketch only gets 1..2 months of life out of a 3x alkaline AA battery pack. Not enough – by far – for practical use around the house.

The good news is that it’s almost entirely a software issue. There have been JeeNodes running for many months now, some up to 10 months, so there is no hardware limitation to achieve such lifetimes.

In fact, I’d like to push it a bit further and see how long one could run a Room Node off a single rechargable AA battery using the AA Power board. If it’s not that long, I could still opt for the 3x AA pack.

Let’s estimate the idle current draw of a JeeNode first.

The big consumer is the PIR sensor. I recently switched to a new one, because it only needs 3.3V and because of its low current draw. Note that the PIR motion sensor is the only component in the Room Node which should not be disabled during sleep: the whole point is to be able to detect motion at all times, after all. Also, a PIR sensor needs time to stabilize, in the order of a minute, so turning it on briefly is no option.

Here’s the good news:

Dsc 2077

That’s 41 µA idle current.

The JeeNode draws ≈ 3.3 µa, let’s round it up to 4 µA.

The SHT11 draws 2..5 µW, let’s round it up to 2 µA.

So total idle draw is 47 µA.

As it turns out, transmissions consume a neglegible amount of current – if the frequency of transmission is 5 minutes, for example (i.e. 288x per day). The motion detection is different, this needs to go out as soon as there is motion, but this probably won’t happen more than a dozen times a day, on average).

For a transmission, the RFM12B needs to be on for about 2 ms, at which point it draws around 25 mA. With 2 ms once every 300 seconds, that’s a duty cycle of 1:150000, i.e. under 2 µA when averaged out.

So let’s round up and assume that the average current draw of a Room Node is 50 µA @ 3.3V.

A 3x AA battery pack of 2500 mAh would last 50,000 hours, i.e. over 5 years if we ignore the self-discharge rate … assuming that the low-power code is perfect, that is!

Now for the AA Power Board lifetime estimate. At very low current levels, the efficiency of the LTC3525 regulator is 75..80%, according to the datasheet. But first, we need to estimate the current draw. Keep in mind that the power source will be 1.2 .. 1.3V, so we basically need a 3-fold step up. Let’s calculate the input current draw, assuming 1.2V in, 3.3 V out @ 50 µA, and 75% efficiency:

input current = 50 x 3.3 / 1.2 / 0.75 = 183 µA

With an Eneloop battery, I’ll assume it has 1900 mAh capacity, and loses 15% of its charge in two years. Let’s assume that it’ll be used no more than 2 years, and that it lost that 15% charge right at the beginning. Then this is effectively nothing more than a 1600 mAh battery.

Ok, how long can it power a JeeNode plus Room Board?

lifetime = 1600 / 0.183 = 8743 hours = 364 days

So all in all this setup should be able to run just about one year off a single rechargable AA battery. Note that there was some rounding in several places in these calculations, so these estimates are probably a bit conservative.

One year battery life… that’s in fact exactly what I was hoping for!

Now the “only” remaining challenge is to optimize the “rooms.pde” sketch enough to make this happen.

Low-end light box

In Hardware on Oct 5, 2010 at 00:01

Yesterday’s post was about trying to make better pictures for this weblog. The jury is still out on whether the results are dramatically better, but here’s the setup I used – first an add-on for the Nikon D40 built-in flash:

Img 20101003 11

What it does is place a small piece of mirror (extracted from a flatbed scanner) in front of the pop-up flash to reflect all the light up. It’s made of a few little scrap pieces of foam board, glued together to keep the light from directly reaching the object, reflecting the light upwards instead. It’s held in place by friction:

Screen Shot 2010 10 03 at 21.10.03

That solves one half of the problem. The other issue is to get light all around the object to avoid excessively sharp shadows. I made a little “light box” for that, from a little wooden storage box with the interior covered entirely in white foam board:

Img 20101003 12

I can now place the object on the bottom in the back, and sort of peek inside with the camera. The trick is to make sure that the flash sends its light inside the box, bouncing up against the top foam board.

That’s basically it!

The reason I chose this setup, is that I need the height to get the flash inside, and I wanted something that could be easily dismounted and stored away. Like this:

Img 20101003 13

All the foam pieces were cut from five A4-sized panels, because I’ve got lots of ’em lying around. Everything is held together purely by friction, so it’s trivial to assemble and disassemble, but also very easy to replace one of the form boards if it ever got dirty or damaged.

I can also rearrange things, and put the wooden box flat on the table, with the camera looking down into it for shots straight from above.

One detail I’d still like to improve is the amount of diffuse light striking the object at the front. There is currently still a bit of a shadow. One idea is to cover the top with aluminum foil, and perhaps also a surface inside which is slanted forward. Here is a cross section:

Screen Shot 2010 10 03 at 16.27.41

Here is the current setup (no foil yet), with the slanted top panel showing on the left:

Img 20101003 14

Note that foam board is very easy to use for “broken” panels – simply don’t cut them all the way through:

Img 20101003 15

Simple. Now I just need to understand all the adjustments and photo stuff a bit more…

Update – here’s the last trial – different angle, slightly more interesting surfaces, but the FTDI pins are too washed out:

Img 20101004 31

Better pictures?

In Hardware on Oct 4, 2010 at 00:01

Almost all the pictures on this daily weblog are taken with a Nikon D40 + 18..55 mm “kit” lens. I bumped into a fantastic deal two years ago for that setup and have never looked back since then.

Pictures matter on this weblog. In fact I try to get a picture, drawing, or code snapshot image into every single post. It’s simply more fun – to make, to read, and to look back to later.

And until now, almost all pictures were taken in plain daylight (indoor, on a table next to one of the windows). This has been a mixed blessing really – gorgeous light at times, but a widely varying white balance due to the different times of day at which I decide to take some snapshots. And with winter nearing, good daylight conditions are going to get scarce again.

Seeing some of the pictures uploaded to the new “JeeLabs” Flickr group (check it out!), I felt that I really need to beef up the images on future weblog posts a bit. Better close-ups, and more importantly: more consistent lighting conditions and while balance. I’m hoping to do this without killing the low-key basic approach to everything done at Jee Labs.

After some lengthy conversations with Steve Evans and with many thanks for his tips, I’m going to try doing a bit more with flash. At first I wanted to try something with RGB strips, but it simply makes no sense to light up a little scene like a theater (requiring substantial amounts of light!) while the shot only takes a fraction of a second.

There are three problems with using the built-in flash, though:

  • it causes horrible reflections
  • it causes horrible shadows
  • it’s still fairly weak

For decades, I’ve routinely turned off flash for any picture I took. It seemed so ill-suited to capture anything meaningful in a pleasant way, especially with people.

The good news: project / product shots are different…

First of all, everything I shoot for the weblog tends to be fairly small. So a “lightbox” is definitely an option: a micro-studio set up to photograph a very small area with all the lighting in place.

Ok, time for some examples (sorry if it looks a bit like a JeeNode commercial). This is the JeeNode v3, Jul 2009:

Dsc 0424

This is the JeeNode v4, Nov 2009:

Dsc 0767

And here’s the JeeNode v5, Sep 2010:

Dsc 1968

All of them shot out of hand, in daylight, most of them tweaked a bit for exposure, white balance, and shadows, and cropped / rotated for proper framing. No big setups, no comparisons, just some tweaks until it “looks right”, each time.

Here’s a shot of the JeeNode v5, as it came out today, while spending a lot more time on lighting, setup, histograms – but still essentially just some quick ad-hoc tweaking:

Img 20101003 7

Basically, I adjusted the exposure until the background is fully white, and I’ve boosted both color and the sharpness a fair bit (using Nikon’s View NX2 instead of my usual iPhoto).

That last image is definitely closer to the real thing. Much more detail in the shadows and in the highlights. I’m also pretty certain that this new setup can deliver results which are far more repeatable (and at any time of day).

But it is “better”? I’m not convinced. The crystal on the RFM12B is a good example of how you gain detail, but also lose some “vibrance”. Somehow, that JeeNode isn’t jumping off the page anymore … it just sits there.

Oh, here’s another fun shot:

Img 20101003 10

Maybe I’ve simply been staring at too many JeeNodes today. Comments welcome.

Tomorrow, I’ll show the setup I made for this.

Assembling the JeeNode v5

In AVR, Hardware on Sep 26, 2010 at 00:01

New JeeNode means: new build instructions.

Here goes. A long description of how to go from this:

Dsc 1973

… to this:

Dsc 1970

Make sure you’ve got a nice soldering iron (not too hot, not too large) and some solder wick to remove solder in case you need to back up a bit to fix things. The JeeNode printed circuit is very sturdy and can handle a lot of abuse, but some traces are thin, so be careful and don’t apply too much force.

Components are soldered on from lowest to highest profile, because then you can turn over the board and push on it to get each component snugly against the board as you solder it. So let’s start with the resistor:

Dsc 1974 Dsc 1975

Once you’re satisfied with the soldering, turn it over and snip off the leads:

Dsc 1976 Dsc 1977

More…

Read the rest of this entry »

Meet the JeeNode v5

In AVR, Hardware, News on Sep 25, 2010 at 00:01

I’m very pleased to introduce the – Fresh!Updated!New!JeeNode version 5 board:

Dsc 1929

Hold on. Don’t get too excited. It’s not that big a deal. It’s basically still the same JeeNode v4, with just some incremental changes.

Allow me go through each of the differences in some detail:

  • on the left, there is now a diode between the FTDI power input and the rest of the PWR lines – so you can power the board from a 4.5..13V battery, etc. and it won’t fry the FTDI board or cable when plugged in
  • this also means that “PWR” will be about 0.7V lower on the PWR pins in several places across the board, than on the power supplied to the FTDI power pin (i.e. 4.3V when fed from a USB-BUB)
  • for 100% compatibility with the JeeNode v4 and older, the diode can be disabled (i.e. shorted out) with a solder jumper on the back side
  • two extra header pins have been added (+3V and RST), on either side of what was the “PWR/SER/I2C” header on the JeeNode v4 – it is now called the “PSIX” header (X = eXtended)
  • on the right, the RFM12B module was moved a bit to make room for a hole for the antenna wire
  • not as easy to see, but the board is also fractionally longer, so that the RFM12B no longer sticks out
  • slight re-arrangement of components (caps and reset pull-up)
  • most holes are slightly larger, making it easier to unsolder components, if you ever need to
  • the long sides of the board are now routed i.s.o. V-scored, i.e. much smoother and more precise:

Dsc 1966

That’s more or less it. Oh, and D O T Sfour big white dots on each side of the board to be precise, next to the PWR pin of each of the Port 1 .. 4 headers. You’ll be surprised by how convenient that can be when hooking up all sorts of plugs – which have the same dots to mark the proper orientation.

All in all, no big changes. Nothing incompatible with the JeeNode v4, the JeeNode USB, or the JeeNode SMD. This isn’t about planned obsolescence, these are just some tweaks to squeeze the maximum usability out of what is essentially the flagship and workhorse of Jee Labs, if you pardon this odd mix of metaphors.

I did forget to fix two little teeny tiny label name spelling errors which were also on the JeeNode v4 (left as exercise for the diligent reader). Oh well. I hereby claim victory anyway, and now declare this v5 PCB to be TUJ!

… TUJ ?

Yes: TUJ. Shorthand for The Ultimate JeeNode of course! What else?

PS. The JeeNode v5 is shipping now. I don’t play “There’s Something New Coming Soon” games.

Update – I’ve updated the documentation:

  • JeeNode v5 manual (PDF)
  • JeeNode v5 pinout (PDF)

It’s all a bit in transition, with the Café moving to Redmine soon – which is where these docs will go, eventually.

It’s time to Do The Right Thing

In AVR, Hardware on Sep 24, 2010 at 00:01

This is long overdue…

If you have one or more JeeSMD v1 boards, which look tike this:

Dsc 1772 2

… then you are entitled to a free upgrade to the new JeeSMD v2 board, with the fixed VR (and tented vias):

Dsc 1963

Actually, I won’t send you a replacement board for each one you have, but an entire JeeSMD kit.

Likewise, if you ordered one or more Carrier Boards with Boxes, and never got these:

Dsc 1964

… then I owe you that DC Power Jack and matching connector. Ignore the 0.1 µF ceramic capacitor if you already have one – it’s for adding the reset circuitry on the Carrier Board’s FTDI connector.

Email me (please include the order number if possible) and I’ll get it out to you. No questions asked.

Mistakes happen – and I can’t undo the past. But I won’t walk away from my responsibilities either.

HomeSeer and JeeNode WSN’s

In Software on Sep 22, 2010 at 00:01

HomeSeer is a commercial Windows-based home automation software package. I’ve seen it demo’d a few times, but I’m not using it myself – nor do I have a license for it (I don’t have a permanent setup running Windows).

The following describes a great new development by Tijl van der Velden, who wrote a very interesting extension for HomeSeer to link into aWSN based on JeeNodes, Room Boards, plus a JeeLink on the PC side.

Tijl just finished his project, which was done as student assignment for Computer Science at the University of Utrecht. He was so kind to send pictures of his setup and screen shots of the resulting application in HomeSeer.

I’m just the messenger in this case, but I’m very happy to be able to report about this on the weblog. For details about Tijl’s project, which has been released as open source on SourceForge, visit the JeeSeer page. The code running on Windows is VBScript, as used by HomeSeer – the software on the JeeLink and JeeNodes are C/C++ Arduino-type sketches.

Here’s his test stup:

Sam 0381

You can see the JeeNode with Room Board on top (and the temperature, humidity, light, and motion sensors), as well as an extra LED and small DC motor, driven by a transistor (with the inductive kickback protection diode).

The sketch running on the JeeNode includes some very interesting customizable “decision rules”, which can be configured from HomeSeer. Here’s the customization screen:

Decision Rules 2

The sketch running on the JeeNode looks fairly generic, allowing for different devices, so that you can use the port I/O pins for various purposes – both as inputs and as outputs. From a brief look, it reminds me a bit of Firmata.

The Jeelink is also running a custom sketch, to be able to pass these special requests and replies to a JeeNode and back. As with RF12demo, you can configure the JeeLink to listen on a specific frequency band and filter out a specific net group. This is also nicely configurable from the HomeSeer web interface:

Config 2

And here is what it’s all about – sensor results and device (i.e. LED + motor demo) control:

Status Page 2

Thank you Tijl, for completing this project and for sharing your results and your code on SourceForge. You are making it possible for others to learn from what you did, to plug what you made directly into HomeSeer, and to let people extend things further as the need arises.

It’s great to see the JeeNode – domotics integration becoming a reality!

Room Node mount?

In Hardware on Sep 21, 2010 at 00:01

I’m still searching for ideas to mount a JeeNode with a Room Board, a.k.a. as a “Room Node”. Now that the AA Power Pack lets me get rid of two of the 3 AA’s, I’m sort of hoping to bump into some new and practical options.

How about this position, against the ceiling?

Dsc 1957

The PIR motion sensor is placed above an empty spot between the JeeNode and the AA Power board. It’ll need to be wired up in that position, of course.

The shapes are still agonizingly unsuited for placement into a corner, but then again… it’s a lot better than with the 3x AA battery pack! Here’s the whole setup again, in close-up:

Dsc 1958

The trick will be to cover it up properly, here’s a first trial using my favorite foam-board as prototyping tool:

Dsc 1960

That’s 6.5 cm wide, btw. Any less, and the battery holder will poke into it and make it wobble.

Does it look good? I don’t know. I think I could live with a slanted 6.5 x 20 cm white strip along the ceiling, with a little PIR peeking out in the middle (and a small hole for the LDR + temperature/humidity sensor).

Next challenge is to come up with a mounting bracket for this darn thing. Perhaps 3D-printed? Two triangles on the end or something? If they slant slightly inwards, they would cast a shadow and not draw much attention…

It all needs to be properly detachable, since this thing runs on battery power. I could stick two little solar panels on the surface to get a warm fuzzy environmental feeling… but I doubt they’ll capture enough energy in that position.

Anyway – I’m happy to have a fresh option to think about. We’ll see…

AA power options

In Hardware on Sep 19, 2010 at 00:01

The new AA Power board is a pretty darn flexible little board, if I may say so myself. Its switch regulator draws very little current itself, 7..30 µA depending on the input voltage. The input voltage range is approx 1.0 .. 5.5V, to be able to start up, but it will drain the power source all the way down to 0.4V if it can, pulling every last bit of juice out of regular AA batteries.

But the AA Power board is also capable of providing a pretty decent amount of current when needed. This is essential for the on-board wireless radio of the JeeNode, but it even works with heavier loads than that:

Dsc 1942

That’s an Arduino-compatible JeeNode with an LCD Plug and a 2×16 character LCD with backlight – all running off a single 1.2V AA NiMH battery!

The maximum current depends on the input voltage. It is guaranteed to be at least 60 mA from a 1V supply, going up to 140 mA from a 1.8V supply. Note that the input current can be much more than that – drawing 60 mA at 3.3V means the battery may have to deliver about 200 mA at 1V to make it happen. A clever little power regulator it is – a producer of energy it is not!

There a several ways to connect the AA Power board with a JeeNode:

  • inline, feeding the PWR pin with 3.3V (this will be dropped some 30..50 mV by the on-board regulator of the JeeNode itself, with no ill effects)
  • in piggy-back mode, with an AA cell inserted in the battery clips (alkaline or NiMh)
  • as a shield on top of the JeeNode, again with an AA cell inserted

There’s also a fourth way to use this board: leave off the battery clips, and connect a battery between any PWR and GND pins on the JeeNode itself (or use the battery holes) – this requires a solder jumper on the AA Power board.

The flexibility of the regulator means that you can connect any power source between 1.0 and 5.5V to PWR and GND, just as you would with a stand-alone JeeNode. Whatever it is, the +3V pin will carry the essential 3.3V level.

There is one issue to beware of: when PWR is connected to BAT+ via the solder jumper, then do not hook up a second power source at the same time. The most common case is probably: when a battery is connected to PWR, do not connect an FTDI adapter such as the BUB, because it’ll put 5V on the PWR pin … and the battery (or the BUB!) probably won’t like it.

The PWR pin can in fact be used in four different modes:

  • normal – it’s higher than 3.3V and the on-board regulator brings it down to 3.3V for the +3V pin – this would be the case with 3 to 8 AA’s, for example (no need for an AA Power board)
  • boosted – it’s lower than 3.3V and it’s used to feed the AA Power board – in this case the on-board regulator does nothing (and could be omitted)
  • parallel – the PWR pin is connected directly to the +3V pin – this can be used with the AA Power board to make sure the PWR pin also carries power (always 3.3V), in case some plugs expect a supply voltage on the PWR pin
  • floating – the PWR carries no power – this is the case when the AA Power board is used without solder jumper (default case)

The important point here is that the PWR pins do not necessarily carry a higher voltage than the +3V pins. It might be more (normal), less (boosted), the same (parallel), or none (floating). Not every JeePlug can be used with each mode of operation, so be careful to check.

Tomorrow, I’m going to fool around with a bunch of batteries :)

AA mounting options

In Hardware on Sep 18, 2010 at 00:01

As promised yesterday, here is some more info on how to use the new AA Power board.

You’ve already seen the “inline” mode, using an Alkaline cell this time:

Dsc 1932

The second main mounting option is in piggy-back mode, flipped over and mounted on the back of a JeeNode:

Dsc 1939

This can be done either with regular male header pins (1×6 and 2×4, or 3×4), or with extra long pins which will stick out the front of the JeeNode as normal header pins:

Dsc 1938

Doing so requires some care, because once these two boards are soldered back-to-back, you can’t reach everything anymore. Disassembling such a sandwich later is tricky.

Note that you can stand the whole assembly on empty AA battery clips, but once a battery is inserted, this becomes unstable because the round battery sticks out:

Dsc 1940

With AAA clips and the much thinner (and weaker) AAA battery, it turns out that the whole construction does stand upright, but the size and position of the clips gives it limited stability when adding plugs on top.

There is a third option – use the AA Power board on top of a JeeNode with stacking headers, i.e. like a “shield”:

Dsc 1953

There is not that much room, but the 4 port headers can still be used. Note that the AA Power board needs to be mounted upside down in this case, i.e. with the SMD components and the silk screen facing down towards the JeeNode. Here’s another view of this shield-style option:

Dsc 1951

Coming up… a description of the full range of power connections supported by this little magician.

Long live the AA battery!

In Hardware on Sep 17, 2010 at 00:01

The AA Power board announced yesterday just arrived:

Dsc 1931

And it looks like it does indeed perform exactly as expected. Here’s the ripple:

Screen Shot 2010 09 16 at 13.41.07

That’s with the 1.6 mA LED load, i.e. a 75 µs cycle / roughly 13 KHz – this was as predicted: at light loads, the recharge frequency can reach down into the audible range. But it’s highly unlikely to be noticable due to the tiny size of the inductor, which after all is not built to act as a loudspeaker :)

Here’s the “AAv1” fully mounted for powering a JeeNode via the FTDI connector:

Dsc 1934

(there’s no charge circuit here, I’m just using an externaly-recharged battery as power source)

And here’s the whole setup in actual use:

Dsc 1935

Works like a charm. Runs just fine with the “rooms” and “radioBlip” sketches, and wireless just works – as before.

Quiescent current draw is about 20 µA when powered this way. That goes down to 10 µA when used with two cells @ 2.4V, and down to an amazing 7 µA when powered from a 3V source (a CR2032 ought to work nicely!). Above 3.3V, the circuit becomes just a tad less efficient when it switches into step-down mode, drawing about 30 µA all the way up to 5.5V.

Great, now we’re starting to get into some serious low-power options.

Tomorrow, I’ll describe other ways to use this new AA Power board…

Meet the AA Power board

In Hardware on Sep 16, 2010 at 00:01

Remember the recent post about running a JeeNode off a single battery?

Dsc 1897

That was 9 days ago, and that LED shown above is still lit. It’s not a huge accomplishment, because the LED draws only about 1.6 mA and is very dimly lit, but still. Over two hundred hours of operation time, and the rechargeable battery I used (this one) is still going. It started off at 1.35V and is now at a decent 1.22V level.

Assuming a 70% efficiency (at such low voltages, it probably won’t be much higher than that), and an average of 1.3V getting boosted to 3.3V, the power consumption over this period is … scribble, scribble … 1.6 * 3.3 / 1.3 / 0.7 * 216 = 1253 mAh, i.e. about two thirds of the total capacity of this one-cell AA battery.

Not too shabby. Even without power-down tricks, just by entering idle mode in all the busy loops, an ATmega328P will draw less than 1.6 mA when running at 16 MHz on 3.3V (which is slightly overclocked, but it works just fine). Idle mode is very nice, because you don’t have to play any serious low-power tricks, you just have to tell the ATmega: I have nothing to do right now, take it easy until the next interrupt occurs.

In other words: using only the simplest of all the low power tricks, a JeeNode can run about two weeks off a single AA battery (less, if you have power-hungry peripheral chips connected, of course).

Try running an Arduino Duemilanove off a 9V battery, or even a 4x AA battery pack. Fine board, but it sure ain’t low power…

Anyway, I’ve decided to design an AA Power board for this little power magician:

Screen Shot 2010 09 15 at 21.20.21

It’s not specific to the JeeNode, but it was of course designed to be a particularly good match for it:

  • the width of the board is exactly the same as JeeNodes and all the JeePlugs
  • it can be attached in-line, i.e. like an FTDI board/cable
  • it can be used in piggy-back mode, i.e. attached to the back of a JeeNode
  • or use it in shield mode, i.e. on top of a JeeNode with stacking headers
  • it has mounting holes (since there is plenty of room on this thing)
  • the board can be fitted with either AA battery clips, or AAA battery clips
  • or attach external batteries to it: one, two, three (even four, if NiMh) … you decide!

Whatever the power source is, this board will either boost or step-down the voltage as needed. The efficiency will be up to 95%, depending on load and supply voltage. But in any case, it’ll be way more efficient than any linear voltage regulator, including the one on the JeeNode.

One AA is smaller than 3 or 4, obviously, so a JeeNode with this AA Power board will also fit into smaller places.

In case you insist on using 3x or 4x AA’s, then you’lll still benefit from a much higher conversion efficiency, and the ability to run the batteries down until they are completely empty. In other words: they will last longer!

Now it’s just a matter of waiting to find out whether I did all my homework properly, and got the connections, traces, and physical dimensions right.

Modular nodes

In Software on Sep 13, 2010 at 00:01

Ok, so we have JeeNodes and JeePlugs, and it’s now possible to sense and hook up all sorts of fun stuff. In theory, it’s all trivial to use and easy to integrate with what you already have, right? Well… in practice there’s a lot of duplication involved – literally, in fact: for my experiments, I often take an existing sketch, make a fresh copy and start tweaking it. Shudder…

  • New plug. New bit of code to include in the sketch for that plug. New sketch.

  • New device connected. New bit of code to talk to that device. New sketch.

  • New idea. New logic to implement that idea. New sketch.

Yawn. Some of this WSN stuff sure is starting to become real tedious…

There are a couple of ways to deal with this. The traditional way is to modularize the source code as much as possible: create a separate header and implementation source file for each new plug, device, sensor, and function which might need to be re-used at some point. Then all you have to do is create a new sketch (again!) and include the bits and pieces you want to use in this sketch.

I have a big problem with that. You end up with dozens – if not hundreds – of tiny little files, all with virtually no code in them, since most interfaces definitions and interface implementations are trivial. My problem is not strictly the number of little files, but the loss of overview, and the inability to re-factor such code collections across the board. It just becomes harder and harder to simplify common patterns, which only show after you’ve got a certain amount of code. The noise of the C/C++ programming itself starts to drown out the essence of all these (small & similar) bits of interface code.

The other serious problem with too fine-grained modularization of the source code, is that you end up with a dependency nightmare. Some of my sketches need the RF12 driver, other need the PortsI2C class, yet others use the MilliTimer.

At the opposite end of the spectrum is the copy-and-paste until you drop approach, whereby you take the code (i.e. sketches) you have, and make copies of it all, picking the pieces you want to re-use, and dropping everything else. I’ve been doing that a bit lately, because most of this code is so trivial, but it’s a recipe for disaster – not only do I end up with more and more slightly different versions of everything over time, it also becomes virtually impossible to manage bug fixes and fold them into all the affected sources.

A version control system such as subversion can help (I couldn’t live without it), but it just masks the underlying issues, really. Being that some parts of the code deal with the essence of the interface, and other parts exists just to make the code into a compilable unit.

There is another alternative: go all out with C++ and OO, i.e. create some class hierarchies and make lots of members virtual. So that slight variations of existing code can be implemented as derived classes in C++, with only a bit of code for the pieces which differ from the previous implementation. This is not very practical on embedded microcontrollers such as the ATmega, however. V-tables (the technique used internally in C++ to implement such abstractions) tend to eat up memory when used for elaborate class hierarchies, and worse still, much of that memory will have to be in RAM.

There is a solution for this too, BTW: C++ templates. But I fear that the introduction of template programming (and meta-programming) is going to make the code virtually impenetrable for everyone except hard-core and professional C++ programmers. Already, my use of C++ in sketches is scaring some people off, from what I hear…

Is there a way to deal with a growing variety of little interface code snippets, in such a way that we don’t have to bring in a huge amount of machinery? Is there some way to plug in the required code in the same way as JeePlugs can be plugged in and used? Can we somehow re-use bits and pieces without having to copy and paste sketches together all the time?

I think there is…

The approach I’d like to introduce here is “code generation”. This technique has been around for ages, and it has been used (and abused) in a wide range of tasks.

The idea is to define a notation (a related buzzword is “DSL“) which is better suited for the specific requirements of Physical Computing, Wireless Sensor Nodes, and Home Automation. And then to generate real C/C++/sketch code from a specification which uses this notation to describe the bits and pieces involved:

Screen Shot 2010 09 12 at 17.16.38

To create a sketch for a JeeNode with the Room Board on it and using say an EtherCard as interface to the outside world, one could write something like the following specification:

Screen Shot 2010 09 12 at 18.29.39

The key point to make here is that this is not really a new language. The code you add is the same code you’d write if you had to create the sketch from scratch. But the repetitive stuff is gone. In a way, this is copy-and-paste taken to extremes: it is automated to the point that you no longer have to think of it as copying: all the pieces are simply there for immediate re-use.

Problems will not be gone simply by switching to a code generator approach. There will still be dependencies involved, for example. The “RoomBoard” device might well need the MilliTimer class to function properly. But it is no longer part of the code you write. It doesn’t show up in the source file, there’s no #include line as there would be in C/C++ or in a sketch. Which means it also no longer matters at this level whether the RoomBoard driver uses a MilliTimer class or not.

Code generation in itself also doesn’t solve the issue of having lots of little snippets of code. But what you can do, is combine lots of them together one source file, and then have the generator pick what it needs each time it is used:

Define RoomBoard {
    ...
}
Define EtherCard {
    ...
}

The technique of code generation has many implications. For one, you have to go through one more step before the real code can be compiled and then uploaded – you have to first produce an acceptable sketch. And with mistakes, the system has to be able to point you to the error in the original specification file, not some very obscure C/C++ statement in the generated source code.

And of course it’s a whole new mechanism on top of what already exists. One more piece of the puzzle which has to be implemented and maintained (by someone – not necessarily you). And documented – because even if the specification files can reduce a large amount of boilerplate code to a single line, that one line still needs to be clearly documented.

So far, these notes are just a thought-experiment. I’ll no doubt keep on muddling along with new sketches and plugs and nodes for some time to come.

But wouldn’t it be nice if one day, something like this were a reality?

RGB multi-meter?

In Hardware on Sep 12, 2010 at 00:01

How’s that for a weird title, eh? ;)

Just got around to hooking up a test set of 2x 5 meter RGB LED strips to the MOSFET Plugs – using the setup created and described here a few days ago.

These are water-proof strips, with only 30 LEDs/m and a somewhat unfortunate brown strip background color:

Dsc 1925

That’s with all LEDs full on.

Now some more color and power experiments, in the evening – full on:

Dsc 1920

You can see the current reading, the JeeNode setup, and the power supply.

And with 100% / 45% / 15% settings for red, green, and blue, respectively:

Dsc 1923

The color came out much more yellow on this picture than it actually was, btw.

Some power measurements on the 12V line:

  • full on: 2.4 amps @ 12 V = 28.8 watt
  • color-adjusted: 1.9 amps @ 12V = 22.8 watt

The power supply is a beefy 12A @ 12V cage which draws 4.4 watt even without anything connected. That’s very unfortunate, because I’d like to turn the LEDs off on the 12V side and leave the power supply on at all times. Will need to find a better supply – 4A would be plenty.

These results are slightly disappointing. First of all, 60 LEDs per meter will be a minimum to provide a decent level of (indirect) house lighting at full power. But also, it’s frustrating to see how the power gets eaten up in the supply and by the resistors (especially with red LEDs dimmed less than the others).

No doubt this is way better than incandescent lighting, but still…

Another surprising outcome, is that the RGB settings for this strip are completely different from the 5050 RGB test setup I used a few days ago. It looks like I’m going to have to adjust each strip individually to get a nice consistent white balance.

And then there’s the issue of fringing. Looking directly at these LED strips clearly shows the distinct RGB components, with the color balance very much dependent on the viewing angle. I sure hope that the 60 LED/m strip with white background and used as indirect lighting will even this out.

On the plus side, the ≈ 300 Hz PWM of the new rgbAdjust.pde sketch I’m using on the JeeNode seems to make these LED strips completely flicker-free.

Onwards!

PC Bees

In Hardware on Sep 10, 2010 at 00:01

New batch of JeeSMD‘s and Carrier Boards just came in:

Dsc 1918

At last! – this batch took a lot longer than anticipated…

The JeeSMD fixes a nasty error reported in the Talk forums, which had two pins exchanged on the 3.3V voltage regulator.

The reason I missed this, is that I used the JeeSMD on a LiPo battery pack, which runs at around 3.7V – and as it so happens, an MCP1703 will generate a voltage drop of roughly 0.4V when connected the wrong way around. So it all basically worked exactly as expected in my setup.

I bet Mr. Murphy had a major role in this “accidental” design detail…

The Carrier Boards haven’t changed. I simply ran out of the first 100 way faster than I had expected. The good news with the Carrier Board + Box kits, is that I’ve now also got a decent stock of DC jacks, so these will be included with all orders. In fact, I’m also throwing in a DC plug, so you can make your own power cables, or adapt some 5..12V DC power supply to fit these standard 2.1/5.5 mm jacks:

Dsc 1919

There are several dozen packages waiting for this back-ordered stuff. I’ll get them out in the coming days!

RGB strips – the software

In Software on Sep 9, 2010 at 00:01

Now that the hardware is ready, let’s move on to the software. First task is to figure out all the pin assignments with a little “rgbTest.pde” sketch:

Screen Shot 2010 09 08 at 12.43.29

Yep, it works. Here’s AIO4 in action:

Dsc 1913

On to the real thing. I’m going to re-use the code from this post, but with a couple of modifications:

  • since that code apparently still flimmers a bit, I’m going to make it run faster by reducing the number of steps from 256 to 101, i.e. intensity values 0..100 – that should increase the refresh rate to about 300 Hz
  • the fourth value will be re-used as a general intensity control, so “RGBW” now means: take each individual RGB intensity times the W intensity
  • the main logic will remain the same, even for the “White” dimmer – this is harmless, since there is nothing connected to port 3
  • need to re-define the pin assignments to match the above, twice

Ok, the new sketch is here – it’s a bit long to include in this post. Now I can send messages via a JeeLink to control this thing:

  • full on: 100,100,100,100,100,100,100,100,30s
  • full off: 100,100,100,0,100,100,100,0,30s

And here’s a very first / rough attempt to create a decent white tint:

  • 100,40,5,0,100,40,5,100,30s

Here’s my (messy!) workbench with four different light sources:

Dsc 1916

  • top right – a warm white incandescent lamp, seems to use a 12V headlight
  • middle back, under the shelf: commercial sort-of-warm-white LED lamp
  • middle center, magnifying glass: fluorescent cool white tube
  • left front, paper sheet: my RGB test setup, indirect lighting

When looking straight at the LEDs (always a bit painful), you can clearly see the different colors. The color offsets produce a slight fringe in the shadows cast from this light:

Dsc 1917

This won’t be good enough for photographers, but my impression is that it might work out fine when used as indirect lighting.

The results did surprise me quite a bit: for this tint, you have to turn on as much red as possible, add some some green, and drop almost all the blue.

The unfortunate part is that the red LEDs are responsible for most of the energy loss via their series resistors. Sigh. I wish they’d make RGB strips with all resistors the same small value – I could easily adjust the actual intensity with PWM and stay below the maximum specs.

Some estimates gleaned from the lab power supply w.r.t. current draw for the 50 cm 60-LED strip + JeeNode:

  • all off: 10 mA
  • full on: 620 mA
  • warm white: 270 mA

That last one translates to 6.72 Watt/meter (with some 2W eaten up by the red-side resistors, yikes). I don’t think I’d want to go any lower than that as full-on lighting setting, so if Jee Labs is to get more of these RGB strips around the house, I’ll definitely want to use the 60 LED/meter strips.

RGB strips, revisited

In Hardware on Sep 8, 2010 at 00:01

A while back, I reported about hooking up an RGB strip. That was then.

Now there is the MOSFET Plug to make such hookups a lot simpler. So it’s time to revisit that experiment, because I want to find out how well RGB strips would work for < w a r m > white lighting in the house. Theoretically, RGB can generate any color, so that would include any “temperature” of white, right? Trouble is, I’m not convinced that LED strips are color matched well enough across their entire length to accomplish such lighting conditions over a few meters. The other concern is that RGB LEDs have the Red, Green, and Blue LEDs sitting next to each other, so there may be some fringe colorization – maybe diffusers will be needed.

Then again, I do have one LED lamp of 1 meter long which generates an abolutely great tint of white (“white tint” – interesting concept, eh?).

Time to find out:

Dsc 1912

I obtained some samples of “5050” RGB self-adhesive LED strip, one with 30 LEDs per meter, the other with 60 LEDs. They are mounted on nice white flexible strips, and the whole thing was tacked onto my all-time favorite material: foam board!

Since 2 x 3 is 3 x 2, I used 3 MOSFET plugs to connect this together, these are in turn plugged into a Carrier Board with a JeeNode on its back, and the whole kaboodle is placed in half a box. Since the plan is to later attach this unit to much longer LED strips, I don’t really want to close that box – the MOSFETs will no doubt generate too much heat once they drive several amps each.

Here is how everything is wired together:

Screen Shot 2010 09 07 at 22.31.09

Oh, there’s one more wire: on the photo you can see a red jumper wire running from +12V to a PWR pin on the Carrier Board (I used the FTDI connector) – so the same 12V supply is used to power the JeeNode itself.

That’s it. Six output lines to control the on-off state of two independent strips of RGB LEDs.

Tomorrow – the software…

Running off a single AA battery

In Hardware on Sep 6, 2010 at 00:01

The other day, I found the LTC3525 – an interesting little (yes, tiny!) boost regulator chip, which might be a pretty good power source for low-power JeeNodes.

Couldn’t resist – had to try it…

Here’s a test setup using my favorite foam-board as base, with one AA battery driving a test LED:

Dsc 1897

(hard to see, but that LED is indeed on)

Did I mention that the whole thing uses tiny parts? It did take some patience…

Dsc 1898

Tests show that it will regulate any input voltage from 0.8V .. 5.5V to 3.3V @ 60..200 mA depending on the input voltage. And with 70..90% efficiency, even in the 10’s of µA current consumption range. I’ve verified that it will indeed down-regulate when fed > 3.3V, which makes it very flexible.

The quiescent current draw of this circuit appears to be around 20 µA on a 1.3V input.

So it looks like this could work out nicely:

Dsc 1899

My hunch is that this thing could last 6 months for a room node. Maybe more, but with a 6-pack of AA batteries plus charger, who cares?

Hmm, might be worth designing a little board for…

JeeNode goes solar

In Hardware on Sep 3, 2010 at 00:01

Now that ultra low-power options are coming into reach for JeeNodes, lots of new scenarios can be explored.

The most obvious one is probably a solar-powered JeeNode … so meet the latest new node #5 at Jee Labs:

Dsc 1875

It also uses a 0.47 F supercap, same as yesterday, but now hooked up to a small 4.5 V solar cell (which can only deliver a few mA in bright sunlight), and a Schottky diode between the solar cell and the capacitor.

Here’s the “power supply” in more detail:

Dsc 1876

As you can see, the solar cell is tiny. A few square cm’s only. In fact, it takes quite some time for it to charge the supercap to acceptable levels. I had to place the cell in moderately bright sunlight for about half an hour to get to a 4 Volt charge. It was inching along, taking several seconds per 0.01 V increase.

To avoid losing all that charge right away in the power-up cycle, I modified the ATmega’s fuses to start in 258 clock cycles after power down, and to start up within 4.1 msec after reset. That way it will start up as quickly as possible at all times. The 258 CK setting is particularly nice, because it means the ATmega can get out of total power down within about 16 µs, fast enough to respond to a byte RX/TX interrupt from the RFM12B!

Does it work? Check it out: after connecting the JeeNode with the “radioBlip.pde” sketch pre-loaded… away it went – sending one packet every 60 seconds as node 5:

    OK 5 1 0
    OK 5 2 0
    OK 5 3 0
    OK 5 4 0

While exposed to the current partly-sunny / partly-cloudy light levels, the voltage on the supercap is still increasing. This is good – it means there’s a surplus of solar energy, even with these transmissions going on. That extra energy will be crucial if this thing is to last through the night…

If everything works out, this little Arduino-compatible bugger could well be the first JeeNode to become completely autonomous and transmit wirelessly… forever!

Time will tell :)

Sending packets without battery

In AVR, Hardware, Software on Sep 2, 2010 at 00:01

Here’s a fun experiment…

After yesterday’s improved power-down current results, I wanted to find out how much power it really takes to send out a bunch of small packets. No acks, just periodically sending out a packet and sleeping.

Trouble is, I didn’t want to wait for a battery to run down, since that would take months or even years. Bit long to get results for this weblog, eh?

So instead, I used this little chap:

Dsc 1873

It’s a super-capacitor which can handle up to 5.5V and has a capacity of 0.47 Farad! That’s like putting a thousand 470 µF caps in parallel. Amazing stuff, in an even more amazingly small package.

Here’s a JeeNode, fitted with this new power source, to give you an idea of just how small this thing is:

Dsc 1874

The next step was to design a small sketch to test this. Here’s what I came up with:

Screen Shot 2010 08 29 at 11.57.38

Some of the code left out for brevity. Full source code can be found here.

What this demo does is send out a packet with a 2-byte payload, then sleep for approximately 1 second, then send again, etc. Until power runs out.

Sure enough, packets started coming in every second:

    OK 4 0 0
    OK 4 1 0
    OK 4 2 0
    OK 4 3 0
    [...]

I expected it to send out say 100 packets or so, before the charge in the 0.47 F supercap would run out.

Guess how far it went…

    [...]
    OK 4 178 28
    OK 4 179 28
    OK 4 180 28
    OK 4 181 28

That’s packet number … clickety, clickety … 28 * 256 + 181 = 7349 !!!

In other words, the JeeNode was able to send out well over 7000 packets, i.e. two hours of packets sent once a second.

This is fantastic. I think the secret – apart from the 3 µA powerdown mode – is that the RFM12B + RF12 driver require very little time to start up, send off a packet, and go back to sleep again. There is no ACK involved, the RFM12B is hardly ever in reception mode.

With real-world use, I expect power requirements to be considerably higher. First of all, a Room Board will draw around 50 µA, due to the on-board PIR sensor. And second, I’m going to want to use ACKs for at least the motion detector reports, so that the system has a robust mechanism for reporting motion whenever it is detected. This means putting the RFM12B in receive mode for a few milliseconds, waiting for the ACK. And repeating this process a few times if that ACK isn’t immediately received.

But still … over 7000 packets without a battery!

Update – with one packet per 5 seconds, the charge lasted 4523 packets, i.e. just over 6:15.

Update #2 – with one packet per 60 seconds, 771 packets got sent out, that’s 12:51 hours … looks like the self-discharge of the supercap is eating up the remaining energy.

Sleep!

In AVR, Software on Sep 1, 2010 at 00:01

The “powerdown_demo.pde” sketch in this recent post draws 20 µA, which surprised me a bit…

A while back, I got it down to a fraction of that, by turning off the brown-out detector (BOD) through a fuse bit on the ATmega. That’s a little circuit which prevents the ATmega from coming out of reset and doing anything if the voltage is too low.

As it turns out, you can turn off the BOD in software, but only for sleep mode. The reasoning being that there’s no point in protecting the processor from going berserk while it’s not doing anything in the first place…

Well, my code to turn off the BOD was wrong. You have to do this right before going to sleep. Here’s the updated powerdown_demo.pde sketch:

Screen Shot 2010 08 28 at 12.50.18

(correction – I mixed up my bits: change “PINB |= …” to “PINB = …” or “PORTD ^= …”)

The result?

Dsc 1872

Now we’re cookin’ again!

Sideways?

In Hardware on Aug 25, 2010 at 00:01

I’m always looking for new ways to fit stuff together. JeeStuff ain’t no Lego, but that sure won’t stop me from trying to make it as modular as possible…

Here’s an idea:

Dsc 1842

I just used a pair of Proto Boards and inserted a bunch of plugs into them. Just to see what it would lead to, not as “the” actual design.

Would probably have to invent another type of “backplane” for this approach, but what surprised me was how sturdy the resulting object was.

Would probably need to have 15 to 25 possible slots to place headers in (perhaps even allow soldering the plugs in for good?). And some way to select which AIO and DIO pins go to which port. With I2C, they could be connected in parallel, with dedicated plugs you’d have to reserve a port for them of course.

The reason this could work is that everything in the JeeFamily has the same 21.1 mm width. That was quite deliberate, although I didn’t have this particular path in mind at the time.

Hmm… mounting? Power options? Ethernet? Breadboard area?

Just doodling… ideas are cheap – and plentiful, here at Jee Labs!

Another LiPo option

In Hardware on Aug 21, 2010 at 00:01

The other day, I found a Lithium battery in a local shop, which has just about the right size and properties for use with a JeeNode USB:

Dsc 1818

Found it here, for €9 … so it won’t break the bank.

The nice bit, apart from its size, is that it is fully enclosed and isolated, with two contacts which are easy to solder:

Dsc 1819

Do read that warning, and then proceed anyway :)

What you see above, is the battery with a bit of solder applied to each terminal. Next, I attached some wires:

Dsc 1820

I used two-sided tape to permanently fasten the battery to the JeeNode USB’s back side. Note that the headers were already soldered on, with all the extruding pins clipped to get a slightly flatter surface:

Dsc 1821

The ground wire didn’t need insulation after all, since it connects right next to where the battery is. The positive wire was connected to PWR on port 3, to leave the PSI header free if it ever needs to be hooked up later.

And that’s all there is to it:

Dsc 1822

There is no switch to disconnect the LiPo, so the JeeNode USB can run down the battery if it’s not running a good power-saving sketch. But who needs a switch anyway, when you can do it in software, right? Just upload this:

Screen Shot 2010 08 16 at 01.23.09

When run, the JeeNode will power off completely. This code has been added as “powerdown_demo.pde” sketch in the Ports library.

For proper use, sketches running on a LiPo-powered JeeNode USB should periodically measure the current LiPo voltage via the ADC6 pin, which is tied to a voltage divider. For this to work, the voltage should not have dropped below about 3.4V, so that the ATmega still gets a properly regulated 3.3V as AREF to compare with. The voltage on ADC6 is always half the voltage on the PWR pin. So what every sketch needs to do, is to occasionally measure the voltage, and once it reaches 3.4V, shut down completely using something like the above code.

So there it is – another JeeNode, ready to go … to recharge it, I just plug it into USB!

Improved EtherNode

In Software on Jul 14, 2010 at 00:01

The EtherNode.pde sketch described in this post not so long ago has been extended a bit with some of the functionality of the RF12demo.pde sketch.

That way, an EtherNode can now also be used as sort of a replacement for RF12demo – through Ethernet i.s.o. USB: i.e. to collect data (by polling the server and scraping all new data from the home page) and to send out packets (via a GET request with a properly-formatted HTTP query string).

First of all, the configuration settings are now saved to EEPROM, so that the webserver will come back with the same settings after a restart:

Screen Shot 2010 07 13 at 23.13.11

As you can see, the “collect” mode has also been added. When enabled, the EtherNode will not reply with an ACK when receiving a packet. The issue here is that at most one node should respond with an ACK to broadcast packets. IOW, for each net group you use, you should normally have a single node running RF12demo or EtherNode with collect mode turned off. The others will be “lurking” (with collect mode enabled), i.e. they will be able to see all packets but they won’t reply.

Note: there is one other way to deal with collect mode and ACKs: if you have software such as JeeMon (or your own code) set up to explicitly generate an ACK, then again you should set collect mode on, so that the ATmega itself doesn’t generate the ACK as well. This is why this feature was called “collect mode” btw: the ATmega collects packets and passes it hrough, but it does not act as a full receiver which sends out ACKs.

Also new is that for debugging, you can now connect a serial console to see the full incoming requests:

Screen Shot 2010 07 13 at 23.12.22

The main screen hasn’t changed very much:

Screen Shot 2010 07 13 at 23.19.29

The only changes are a new link to a “send packet” page, and the fact that packets are now properly numbered from 0000 to 9999 (and then wrapping back to 0000).

The send packet page is new: it lets you send out a packet with up to 66 bytes of arbitrary data, to either a specific node, or as broadcast:

Screen Shot 2010 07 13 at 23.43.52

There is currently no way to request an ACK or send out ACKs via this mechanism. It’s just for sending out a data packet via a web request.

This is just the beginning of what’s possible with a JeeNode hooked up to Ethernet, of course. The sky is the limit, since everything else is a matter of uploading new software. Long live open source :)

Serial communication vs packets

In Hardware, Software on Jul 12, 2010 at 00:01

When you hook two devices up via wires, you’ve got essentially two options: parallel, i.e. one wire for each bit you want to transmit & receive (example: memory cards inside a PC). Or serial, where information gets sent across bit by bit over only a few wires (examples: ethernet, USB, I2C). Parallel can achieve very high speeds with little circuitry, but serial is more convenient and cheaper for large distances.

Serial communication is very common. The model even carries through to the way we think about the “command line” – a stream of characters typed in, followed by a stream of output characters. Not surprising, since terminals used to be connected via RS232 serial links.

Wireless connections are also essentially serial: you rapidly turn a transmitter on and off (OOK), or you change its frequency of operation (FSK), to get the individual bits across.

But there’s a lot more to it than that.

With two devices connected together, you get a peer-to-peer setup with a link which is dedicated for them. This means they can send whenever they please and things will work. The same can be done with wireless: as long as only two devices are involved, one device can send whenever it likes and the other will receive the signal just fine (within a certain range, evidently).

With such a peer-to-peer setup, the serial nature of the communication channel is obvious: A sends some characters, and B will receive them, in the same order and (almost) at the same time.

But what if you’ve got more than two devices? Ah, now it gets interesting…

With wires, you could do this:

Screen Shot 2010 07 11 at 11.20.41

It’s easy to set up, but it’s pretty expensive: lots of wires all over the place (N x (N-1) / 2 for N devices) plus lots of interfaces on each device (N-1). With 10 devices, that would be 45 wires and 90 interfaces!

Worse still, this is very hard to use with wireless, where each “wire” would need to be a dedicated frequency band.

The solution is to share a single wire – called multi-drop:

Screen Shot 2010 07 11 at 11.24.58

Now there’s one wire, a couple of “taps”, and one interface per device. Much cheaper!

Trouble is, you’ve now created a “channel” which is no longer dedicated to each device (or “node” as it is usually called in such a context). They can’t just talk whenever they like anymore!

Whole new slew of issue now. How do you find out when the channel is available? What do you do when you can’t send something right away – save it up? How long? How much can you save up? What if someone else hijacked the channel and never stops transmitting? What if all nodes want to send more than the channel can handle? How do you get your information out to a specific node? Can all nodes listen to everything?

Welcome to the world of networking.

All of a sudden, simple one-on-one exchanges become quite complex. You’ll need more software to play nice on the channel. All nodes need the same software revision. And you’ve got to deal with being told “not now”.

Note that these issues apply to wired solution sharing the same channel (RS485, Canbus, USB, Ethernet) as well as all wireless networks.

Simple OOK transmitters used in weather station sensors just ignore the issue. They send whenever they want to, in an après moi le déluge fashion… (“what the heck, I don’t care whether my message arrives”). This usually works fairly well when transmissions are short, and when lost transmissions are no big deal – they’ll send out a new reading a few minutes later anyway.

Another aspect of this shotgun approach is that it’s a broadcast mechanism. The sending node transmits its messages into the air without interest as to who receives them, or whether there’s anyone listening even. All it needs to do is include a unique code, so that the receiver(s) will be able to tell who sent the message.

For weather sensors, the above is ok. For security / alarm purposes, it’s a bit unfortunate – missing an intrusion alert is not so great. So what the simplest systems do is to yell a bit louder: repeat the alert message many times, in the hope that at least one will arrive intact. No guarantees, yet some very common security systems seem to be happy with that level of reliability.

For more robust setups, you really need bi-directional communication, even if the payload only flows in one direction. Then each receiver can let the transmitter know when it got a packet intact.

There’s a lot more (software) complexity involved to use a channel effectively, to get data across reliably with “ACK” packets, to detect new and lost nodes, to deal with “congestion” and external causes of bad reception, etc.

With JeeNodes and wireless comms via the RFM12B module, the basic RF12 driver is somewhere in the middle between unchecked uni-directional transmission and fully checked self-adapting configurations.

So what does this all mean for the “end user” ?

Well, first of all: wireless communication can fail. A node can be out of range, or a badly-behaved machine can be sending out RF interference to such an extent that nothing gets across no matter what nodes do. Wireless communication can fail, it’s as simple as that! But with bi-directional communication, at least all nodes can find out whether things work or not.

The second key property of communication via a shared channel, is that you can’t just send whenever you like. You have to be able to either save things up until later, or discard messages to let future ones through.

This means that treating a wireless channel as a serial link is really a very bad idea. Keep in mind that the baudrate can drop to zero – this means that you must be prepared to save up infinitely much data for re-transmission. And the more you intend to re-transmit later, the longer you’re going to have to need that channel when it becomes available. That will frustrate all the other nodes trying to do the same thing.

One way around this, is to use a RF link with very high data rates. That way there will be a lot of slack when nodes want to catch up. But then you still need to be able to buffer all that data in the first place. Not a great idea for limited devices such as an ATmega…

The better way is to design the system to work well with occasional loss of packets. Take an energy meter, for example: don’t sent the pulse or rotation trigger, but keep a count and send the current count value. That way, lost packets will not affect the accuracy of the results, they will merely be updated less frequently when the RF link is down.

The RF12 driver used in JeeNodes was designed for the context of a little data, sent on a periodic basis. The difference with a serial link, is that you don’t get garbled text on the other side, but packets (i.e. chunks of data). All you need to keep in mind is that occasionally an entire packet won’t make it.

This design also deals with multiple nodes. Each incoming packet can have a “node ID” so receivers can tell everything apart. Packets never get mixed up or combined or split in any way. Each packet is a verified and consistent amount of data.

Couldn’t we implement a virtual serial link?

Well, yes – there are well-known techniques to implement a virtual circuit on top of a packet-based communication channel.

But doing so would be a bad idea, for reasons which have hopefully become clear from the above. A virtual circuit would either have to act as perfect channel (not feasible with finite data storage) or drop characters in unpredictable places. It is far more practical to impose a packet / chunk structure on the sender, and then be allowed to drop chunks with clearly-defined boundaries when the RF link is out of service or overloaded.

The moral of the story: think in packets when using JeeNode wireless comms – you’ll get a lot more done!

Update – see some good comments by John M below, about IP, UDP, TCP, and the OSI model which describes all the levels of abstraction involved with networking, and all the standard terminology.

RF12 communication

In Hardware on Jul 11, 2010 at 00:01

(This weblog post seems to accidentally have escaped into the wild a few days early…)

The RFM12(B) wireless radio modules from HopeRF, as used on the JeeNode, uses “Frequency Shift Keying” (FSK) as the way to get information across a wireless channel on the 433, 868, or 915 MHz band.

With wireless, there’s always a trade-off between speed and range. More speed, i.e. a higher data rate, lets you either get more data across in the same time or the same amount of data in less time, which might reduce battery consumption. But higher data rates require a larger frequency shift in the transmitter for the receiver to still be able to detect all the bit transitions reliably. A larger frequency shift wastes more power though (I think…). And a larger frequency shift means that the receiver has to accept more bandwidth to catch all the signal details.

Btw, another way to extend the range is to improve the antennas – see this discussion.

I’ll leave the narrow-band vs. wide-band details to the EE’s and amateur radio experts in this world, along with all the RF / HF calculations, because frankly I’m at the limit of my knowledge on these topics.

But what the above comes down to is that we’ve got essentially three parameters to fool around with when using RFM12B’s for wireless networking:

  • the data rate, which needs to be identical on both sides
  • the frequency shift on the transmitter side
  • the bandwidth on the receiver to filter out unwanted signals

Here are the relevant sections from the HopeRF RF12B datsheet:

Data rate

Screen Shot 2010 07 08 at 00.58.29

Frequency shift

Screen Shot 2010 07 08 at 01.00.43

Bandwidth

Screen Shot 2010 07 08 at 01.01.15

Screen Shot 2010 07 08 at 01.01.37

The challenge is to find “good” settings, which really depends on what you’re after. The settings used in the RF12 v3 driver are as follows:

  • Data rate = 49.142 KHz (see this discussion)
  • Frequency shift is set to 90 Khz
  • Bandwidth is set to 134 KHz

This was chosen partly on what I found around the web, and partly by pushing the data rate up while verifying that the range in the home would be sufficient for my own purposes (i.e. to reach the office from the electricty meter: a few concrete walls and floors).

It can probably be improved, but since such changes affect all the node in a net group, I never bothered after the initial tests were “good enough”.

The RF12 library now includes a new rf12_control() function, which allows making changes to these parameters. It’s a low-level option, but you could easily add some wrappers and an API to adjust parameters in a more intuitive way.

As mentioned in the forum, there’s a (Windows-only) tool to do the conversion to hex parameter settings. That ought to make it fairly easy to tweak these things, if you want to push the envelope.

Some people will no doubt be quite interested in such optimizations, so if you’ve found an interesting new combination of parameters, please consider sharing your findings in this forum discussion.

Having said all this, please keep in mind that these settings will still lead to fairly low data rates. The default data rate corresponds to ≈ 6 Kbytes/second of one-way data, assuming perfect conditions and 100% utilization (“hogging”) of the frequency band. With the official ISM rules imposed on the 868 MHz frequency band in Europe, each node is allowed to use only 1% of that rate – i.e. about 60 bytes per second of throughput! (there are no such restrictions @ 433 and 915 MHz – but 915 is not allowed in Europe).

There are alternate bands in the 860’ish MHz range, but I’ve never quite figured out what works where, so for now I’m sticking to this simple 1% rule. For day-to-day sensing and signaling purposes around the house, it’s actually plenty.

To put things into perspective: the IEEE 802.15.4 standard used by XBee’s has up to 16 channels of 250 Kbaud each at its disposal, when operated at 2.4 GHz. It’s a whole different ball game. And a different range: 2.4 GHz gets absorbed far more by walls than the sub-GHz bands (which is why mesh networking becomes a lot more important, which requires more resources, making it harder to keep overall battery consumption low, etc).

So you see: speed, range, complexity, cost – lots of tradeoffs, as with everything in this world!

Update – just got an email with a lot more info about the 868 MHz regulations (for the Netherlands, but I assume it’ll be the same across Europe). Looks like cordless headphones get 40 channels to pick from with 100% utilization (in the 864..868 MHz range), so you could pick one of those channels to avoid the 1% rule.

Uploading? ISP? FTDI? Huh?

In AVR, Hardware, Software on Jul 4, 2010 at 00:01

There seems to be a fair bit of confusion in- and outside the Arduino world, and it’s spilling over to JeeNodes …

I’d like to go through some terms and buzzwords to try and clarify how to get your Arduino or JeeNode to do the thing you want it to do. I’m going to assume that you are familiar with the process of writing software (“code”), compiling it, and running it – at least on a Windows, Mac, or Linux computer (let’s call them all PC’s for now). With software for the ATmega, there are two approaches, depending on whether you use the Arduino IDE or not:

Screen Shot 2010 06 28 at 23.50.22

Both lead to the same result: a “hex” file with code that needs to be transferred from the PC to the ATmega.

The step which can be puzzling when starting out with physical computing and embedded hardware is how to get things across from your PC to that little Arduino or Arduino-like system you’re holding in your hand. And vice versa, since we often want to get results back or see some confirmation that things are working properly.

The confusion comes from the different conceptual levels involved, and things like:

  • do you mean how to connnect? – plug in a USB cable
  • do you mean how does the ATmega change its own code? – through a boot loader
  • do you mean via ISP (In System Programming)? – no, that’s normally not needed
  • do you mean via FTDI? – yes, that’s the name of the chip which is hooked up to USB
  • isn’t FTDI a connector? – yeah, that too, sort of… i.e. a 6-pin convention
  • isn’t a power + serial cable enough? – no, resets also play a key role
  • do I have to use the Arduino IDE? – no, you can also use a program called “avrdude”
  • what’s avrdude? – a program which can upload to a boot loader or an ISP programmer
  • do I need an ISP progranmmer? – nope, the boot loader does essentially the same thing
  • so why not just get rid of ISP? – because you need ISP to install the boot loader

Confused? Welcome to the club…

In case you’re wondering… the process is called “uploading” because the PC initiates this as outbound transfer:

Screen Shot 2010 06 29 at 01.51.50

To get your code (“sketch” in Arduino-speak) into an ATmega, you need three things, working together to make uploading happen under all possible conditions:

  1. An electrical connection – to power the ATmega, to communicate with it, and to restart the ATmega when it is stuck or busy doing something else.

  2. A common language / protocol – the communication must be understood by both sides, i.e. PC and ATmega.

  3. Software on both sides of the connection – Sending something when the other side isn’t listening, or listening while no-one is sending will not have the desired outcome.

Let’s go through each of these separately.

1. An electrical connection

There are several ways to make the connection. With an Arduino, or any similar board which has a USB connector, you can simply plug in the USB cable:

Screen Shot 2010 06 28 at 23.52.41

Some boards use a separate USB interface (“FTDI adapter”), allowing reuse of that interface for multiple boards:

Screen Shot 2010 06 28 at 23.54.08

The end effect is the same: a connection which powers the ATmega and allows communicating with it using a simple serial protocol. There’s also a trick in this hookup to let the PC reset the ATmega whenever it wants.

2. A common language / protocol

Ah, now it gets interesting. First thing to note is that there is no single common language / protocol!

That’s right. It all depends on what you want to do. Here we want to upload code from the PC to the ATmega. That requires exchanging “ISP commands” over the connection. But once uploading is done, we really want to reuse the connection as a regular two-way serial link.

The way it works is that the PC will reset the ATmega just before uploading new code. This activates a “boot loader” on the ATmega. Now both sides will be in sync (briefly) so they can exchange the necessary information to make an upload happen. IOW, right after reset the protocol is “ISP commands”. Once the upload is done, the connection can be reused for any protocol you like – as determined by the code that was uploaded.

3. Software on both sides of the connection

Back to the software now. We need to send ISP commands over the connection.

As you may have guessed, that’s exactly what the Arduino boot loader on the ATmega understands. When reset, the boot loader in the ATmega gets control. It waits and listens for incoming STK500 ISP commands. If none come in within a second or so, it relinquishes control to whatever was previously uploaded to the ATmega.

On the PC side, we need software which resets the ATmega and then immediately sends all the ISP commands needed to transfer and program the contents of a hex file.

This is what “avrdude” does. You can either use it implicitly from the Arduino IDE by starting an “Upload” from the menu, or you can launch it manually from the command line – avrdude needs a few options to tell it where the USB port is, what baudrate to use, the type of ATmega, the protocol to use (i.e. STK500), etc.

There’s more…

The above describes the different pieces and concepts involved in getting code into an ATmega. The beauty of it is that once it works, it really works well. Supplying power, uploading, communication, control, debugging … all with one simple USB cable. You only need to go back a few years to appreciate just how much this approach simplifies embedded development.

But there’s one important detail: the ATmega has to have a functioning boot loader. Placing a boot loader into an ATmega is a bit more complicated (and involves other things such as “fuses”). It’s a chicken-and-egg problem.

This is where the ISP programmer comes in. An ISP programmer is a fairly simple piece of hardware. In fact, you can make your own, as I’ve described in several posts on this weblog. See this and this post for some quick solutions which require nothing more than a working Arduino or JeeNode.

The good news, is that you usually don’t have to worry about installing the boot loader – it’s all done for you. Once. For the mechanism described above, you’ll never need an ISP programmer.

Some people actually prefer to use the ISP technique for uploading their sketches. In fact, sometimes you have no choice, i.e. when you need the serial port at all times, or when you can’t spare the 1..4 Kb required by the boot loader code, or when working with ATtiny chips which don’t support bootloaders.

In thoses cases, you’ll need a setup with an ISP programmer. But for most people doodling around with ATmega’s and the Arduino IDE, the above boot loader mechanism is usually very convenient and the easiest to get going.

Either way, it helps to understand the process. I hope the above was helpful in that direction.

Six lousy pins!

In Hardware on Jul 3, 2010 at 00:01

This has been a somewhat frustrating week. Just when June ended up being the biggest month ever for the shop (no doubt propelled by the special June discount), Mr. Murphy strikes again.

I’ve been waiting for several weeks now for a batch of pin headers. Had lots of them when I ordered, but since the 6-pin headers are included in just about everything, I still ended up running out sooner than expected.

This is the cuplrit – the 6-pin female port header connector:

Dsc 1764

It’s not easy to find alternatives, because I insist on having a clean 6-pin header, not some cut-off-from-a-long-strip header with very rough plastic edges on both sides.

All would have been well, if the shipment had gone its normal route. But it’s been in this country, at Schiphol Airport, for over a week now! And some lazy bum in customs seems to be sitting on it. The irony is that they do this to charge me 19% VAT – which I then get back (being a company) a few months later. More paperwork.

I’ve started shipping some packages without this item, but often even that is not an option. I can’t really send out new JeeNode kits without these headers, for example – it really wouldn’t solve anyone’s problem.

So there you go. If you’re among the several dozen people waiting for the goodies from Jee Labs to get sent to you: I’m just as eager as you to get it all resolved! – probably more, because here, all those frustrations tend to accumulate by proxy :(

Affected are: Plug Headers, JeePlug Packs, JeeNode kits, Wireless Starter Packs, and probably a few more.

(A separate issue is that the JeeNode USB won’t be back in stock for at least another week)

What can I do? Order lots and lots of them, evidently. Which is what I did (many thousands) – in the hope that this silly state of affairs won’t happen again. And offer my sincere apologies to everyone waitng.

Six lousy pins! And in two days I’ll probably be drowning in them…

Update – Just got a letter from the postal service: no invoice included. Need to supply info. By mail. So there is light at the end of the tunnel, but it’s going to take several more days. My apologies. All for some VAT, which gets refunded later. What a silly world.

Fixing a faulty ATmega (Arduino)

In AVR, Hardware, Software on Jul 2, 2010 at 00:01

After a recent post on how to repair an ATmega with a faulty (or even missing) bootloader and helping someone out with it, it occurred to me that this mechanism will work for any Arduino – not just JeeNodes.

Any 3.3V or 5V Arduino’ish system which lets you upload the isp_repair.pde sketch can be used to program any board with an ISP connector on it. The code is for ATmega328’s, because that’s all I use around here these days.

The trick is to hook up a few power and I/O lines in a specific way:

Screen Shot 2010 06 28 at 16.59.11

I’m using an Arduino Pro as example, but that’s just one of many you could use. Now connect these six wires:

  • ISP pin 1 = BLUE = Digital pin 4
  • ISP pin 2 = RED = VCC (+5V)
  • ISP pin 3 = GREEN = Analog pin 0
  • ISP pin 4 = PURPLE = Analog pin 3
  • ISP pin 5 = ORANGE = Digital pin 7
  • ISP pin 6 = BLACK = GND

Note: if your working board operates at 3.3V, then you should connect the RED wire to +3.3V, not +5V (that way signal levels and power supply will match). Also: the target board should not be connected to anything, since it will be powered through the ISP connector.

The only thing left to do is to upload the isp_repair.pde sketch to your working board, and open up a console window. You should see something like this:

That’s it – disconnect all the wires. The ATmega on the target board now has a boot loader and the standard pin 13 blink sketch. Ready again to accept whatever sketch you upload to it!

Going for gold with the BMP085

In Software on Jun 30, 2010 at 00:01

The recent post about adding some battery savings logic got a lot of mileage out of a very simple change – more than 10x lower average power consumption.

Warning: getting power consumption down can be an addictive puzzle!

Jörg Binkele was very helpful, and sent me a scope image, measuring the voltage drop over a 10 Ω resistor in the power line (before the regulator). Here are the first 5 seconds after powering up:

Jeenode Start tb0

As expected, the node settles into a very low power mode most of the time, with an occasional blip once a second. FYI: one vertical division is 10 mA. The little horizontal bar at both ends is probably the trigger level.

One small surprise was the startup behavior. Well, that first 18 mA bump is really a very simple bug: in the first second when the timer is running and being polled, the node is not in low-power mode. Aha, of course – my power-down logic is at the end of loop(). Ok, trivial to change – just move the end of loop() to the beginning:

Screen Shot 2010 06 24 at 11.11.51

Yup, that seems to get rid of the 1 second hump @ 18 mA. Great. I don’t have an explanation yet for the initial 1.5 seconds, but I suspect that the RF12 driver is waiting in rf12_initialize() – there is still some oddness with RFM12B initialization after power-up. Oh well – that’ll be for another day.

But now it gets interesting – I told you it’s addictive! – the image above shows that each blip is ≈ 75 msec @ 18 mA. That’s when both the ATmega and the RFM12B are turned on.

Wait a minute. Why so long? Sure, the BMP085 needs to measure temperature and pressure, and that takes several tens of milliseconds. But why keep everything else running full throttle? There’s no need.

So I rearranged the core loop a bit, in a way where all major delays would be done with as much of the node’s hardware turned off as possible (bmp085demo.pde):

Screen Shot 2010 06 24 at 19.06.55

Here is the result, again courtesy of Jörg – and then annotated:

Detail Power use

There’s lots of info here. Please note that the time scale is 25 times more detailed than the first scope image. The fun part is that you can essentially tie each power level to a line of code.

For example, the first hump is when the timer hasn’t yet reached 1000 milliseconds (since the watchdog can only take steps of at least 16 ms), so the node waits. But since it uses idle mode i.s.o. normal mode, power levels are about half of what an ATmega usually consumes. With almost no effect on the code. All we’re doing is switch off to wait for the next timer interrupt – that’s 50% of easily obtained savings.

Then there are two medium peaks when the ATmega starts the BMP085 measurements, and in between it drops back to power-down levels. Then we waste some power sending results out on the serial port (this could be removed). Lastly, when it’s time to transmit the readings, we switch on the radio, make sure it gets its job done, and then loop, again in power-down mode with the watchdog to keep us going.

If you look very closely, you can even see how long the BMP085 is busy with measuring temperature (about 4ms) and pressure (roughly 20 ms). Exactly according to specs.

The blip on the first screen is about 4 divisions on the second screen, and as you can see, the node is now asleep most of that time. That’s probably another 10-fold improvement. I wouldn’t be surprised if this node will now run a year or so on one set of AA batteries. And it’s still reporting once a second.

The moral is: match your reasoning to measured facts, and you can get a lot of power savings. Each case will be different, but it’s not rocket science.

Thanks Jörg, but please don’t send any more scope shots … I need to kick this addiction again! ;)

(Reminder: last day of the June special in the shop!)

TwitLEDs finale

In AVR, Hardware, Software on Jun 29, 2010 at 00:01

The TwitLEDs project by Myra and Jean-Claude Wippler (daughter and father) has come to a conclusion. It was great. I’ll just summarize by pointing to the six posts on the Jee Labs weblog describing the technical details, and some pictures and videos, showing the results.

Here you can see the finished TwitLEDs robot:

Dsc 1741

This is the, ehm… print head?

Dsc 1749

And last but not least, some videos. First a trial run for the print mechanism:

Next, a trial run for the vehicle, trying to stay out of trouble:

And here the result!

And one more:

Ok, that’s it. Myra and I both had oodles of fun building this and trying things out – hope you did too :)

Onwards!

(If you can’t view the videos on vimeo, see 1, 2, 3, and 4)

RFM12B as spectrum analyzer

In Software on Jun 27, 2010 at 00:01

Intrigued by a very interesting post by “loomi” on the discussion forum, I wanted to find out more…

What he did was use the RFM12B as a crude spectrum analyzer: sweep the frequency across its entire range, and use the RSSI threshold and status bit to find out whether there is any signal on that frequency.

First of all, I added an rf12_control() function to the RF12 library, to allow access to the low-level registers of the RFM12B. This allows changing the frequency and RSSI settings, and reading out the RSSI status bit.

On the software side, a sketch is needed for the JeeNode which does the sweeping and measuring:

Screen Shot 2010 06 21 at 00.26.21

This reports one line of 476 digits 0..6 for each sweep. Each digit in this line of text represents the measured signal strength at that particular frequency.

The RSSI readout is very crude. All you can do is set a threshold and read out a single bit in the status register, telling you whether the signal is above or below the threshold. Tedious, but doable.

The fun part starts once you get to plotting this as a graph. I used JeeMon and wrote a Tcl/Tk script for it:

Screen Shot 2010 06 21 at 00.30.15

And here’s some sample output:

Screen Shot 2010 06 21 at 00.21.30

The green line is the default frequency setting of the RF12 driver.

Each sweep will add a set of black dots to the graph, but since the values are being accumulated in a “counts” array, the dots will creep higher and higher, drawing a bar as more sweeps come in. Using the current delays, one sweep takes a few seconds, so to get the above graph I had to keep JeeMon running for a few minutes.

When left running for some 15 minutes, the large bars will move out of range, but the smaller accumulated counts will now become clearer:

Screen Shot 2010 06 21 at 00.30.53

I haven’t figured out whether these values are valid, nor what could be causing all this RF activity. The peaks are fairly sharp though, so it would seem like a reasonable set of measurements.

A small improvement to rf12_sendStart()

In Software on Jun 21, 2010 at 00:01

The RF12 driver has a function called rf12_sendStart() which – you guessed it – is used to start sending out a new wireless packet.

Yesterday’s post was about battery savings, which I implemented by going into a power-down state right after sending out a new data packet.

That code included this little detail:

Screen Shot 2010 06 20 at 03.50.41

The reason for this is that the RF12 driver works mostly on an interrupt basis – i.e. in the background. Without the delay, the node would power down before the packet had actually been sent out. Then, when waking up, the transmission would fail due to the transmitter underrun caused by this logic.

By simply waiting a bit, the interrupts can continue to take place, and all the bytes will get sent to the RFM12B and from there into the airwaves.

Totally by chance, an EtherCard software problem was reported on the Jee Labs discussion forum, which turns out to be related to this very same issue. Sure enough, adding the “delay(5);” fixed that problem as well.

This felt a bit unsatisfactory as solution, so I’ve extended the rf12_sendStart() function to support a “synchronous mode”. The change is backwards compatible, i.e. the default behavior of rf12_sendStart() hasn’t changed.

Now, if you pass 1 as fourth argument, rf12_sendStart() will wait for the packet transmission to actually complete before returning to its caller. In general, calling rf12_sendStart() in sync mode is probably a good idea. Sync mode can be used for sending data packets as well as acknowledgement packets.

So the above code can be replaced by this single line:

Screen Shot 2010 06 20 at 04.02.11

This simplifies the bmp085demo.pde sketch slightly, and it also solves the problem that the EtherCard library may occasionally lock out interrupts on the SPI bus a bit too long to keep the RF12 driver running.

The code and documentation have been updated.

Onwards!

Battery savings for the Pressure Plug

In AVR, Hardware, Software on Jun 20, 2010 at 00:01

Reducing power consumption is fairly tricky, as you can see in the many previous posts about this topic. And to be honest, I haven’t quite gotten to the point where I want to be with the Room Board. My first “major” (ahem) setup with about a dozen nodes around the house didn’t quite go as I had hoped. Most batteries were empty within a month. A few nodes are still going, but those are hooked up to power adapters…

I’d like to revisit this issue and try to improve things a bit. To make the rooms sketch perform better, and also to make the code structure a bit clearer. The current rooms code is quite complex and hard to follow.

But before messing with the rooms.pde sketch, let’s tackle something simpler: the wireless sensor node based on the Pressure Plug, as described here, and then simplified here. I’ll use that last version as starting point.

The first point to note is that to get a substantial first power reduction, you have to focus on the portion of the code where it’s spending most of the time. Which, in the case of “bmp085demo”, is here:

Screen Shot 2010 06 17 at 01.55.06

That’s right: it’s waiting for the next second to “happen”. And even with a slow’ish sensor such as the BMP085 at maximum resolution, it’s spending more than 90% of its time there… waiting!

I’ll use an approach which might be a bit surprising: let’s not change any of the current logic. The idea is that once we’ve done our thing for the current second, we can go into low power mode, as long as we make sure to get back to normal operating conditions in time for the next second.

So what we’re going to do is add some code to the end of the loop() function. It’s functionally equivalent to adding it at the start, since loop(), eh, loops – but I think it makes a better point.

The end of loop() used to look as follows:

Screen Shot 2010 06 17 at 02.01.01

I’m changing it to this:

Screen Shot 2010 06 17 at 01.43.00

IOW, at this stage all the hard work has been done. We wait a bit for all interrupt-driven I/O to complete (serial and RF12). And then we need to figure out how much time remains until the next second. The power saving happens by spending that time in power off mode.

But this requires some preparation. When inducing a comatose state like this, you have to make absolutely sure that something is still able to get you out of coma and back up and running again. This is what the ATmega’s “watchdog” is for: we set it up to wake us up in 16 milliseconds, just before entering sleep mode. And then we keep doing that until it’s almost time to take another reading. The actual watchdog interrupt handler does nothing, btw – all we want is to get back out of power down.

Note that the radio also needs to be turned off and back on again. It’s the biggest power consumer when enabled. Turning it off and going into power down mode is what lets us go from a tens-of-milliamps current drain to a tens-of-microamps current drain.

All the logic for this is located in the loseSomeTime() function, which was adapted from a slightly different version in the rooms.pde sketch:

Screen Shot 2010 06 17 at 01.42.33

And that’s about it. The average power consumption of this sensor node will go down by an order of magnitude. It’ll still be 1..2 mA, but it’s a major improvement: this node should now run 2..3 months on AA batteries. The source code for bmp085demo.pde has been updated.

I’d like to stress that such gains require very little effort for many types of sketches. All you have to do is figure out where the sketch is spending most of its time, and deal with just that part of the code. Getting into yet lower power consumption levels would require more work.

RGB via the Dimmer Plug

In Hardware on Jun 17, 2010 at 00:01

As someone pointed out in the comments a few days ago (see? that’s what weblog comments are for!), there’s Jee Labs’ own Dimmer Plug to unload the ATmega of all PWM duties:

Dsc 1729

Hm, I really forgot all about that one… doh.

It’s a great suggestion, of course. And fortunately, it can easily be swapped into the RGB strip controller series. All I need is a slightly different JeePlug to tie things together:

Dsc 1730

The result has a 2×3 pin header which matches the one on my previous interface, so now it’s just a matter of swapping cables.

And new software, of course. Here’s a test sketch which cycles brightness and colors similar to the first test sketch:

Screen Shot 2010 06 15 at 18.42.36

Except that this no longer requires any processor attention once set. And there are a few extras: it’ll work with up to four independent sets of RGBW LED strips, and it has a “global” brightness control (currently set to max), making it easy to set up the color once, and then dim the whole shebang while keeping that setting.

Also – because it’s hardware now – the PWM happens much faster. I can’t tell the difference, but I have this hunch that our cat probably can. There’s got to be a difference between blinking at 120 Hz and 100 KHz!

I’m not sure yet which approach I’ll keep. Both software and hardware PWM work fine. Decisions, decisions…

Remote RGB strip control

In Software on Jun 15, 2010 at 00:01

To continue this series on driving RGB strips with a JeeNode, here is a sketch which allows setting the brightness levels using PWM. It’s a bit long for a weblog post, but I thought it’d be useful, since there is quite a bit of trickery in here. Notes follow below:

Screen Shot 2010 06 11 at 23.17.29

This code does some hefty bit manipulation. The idea is to keep an array of 256 time “slots”, with bits to indicate when an I/O pin should be toggled on or off. The loop then continuously scans these slots at the rate of ≈ 32 microseconds per slot (this corresponds to roughly 120 Hz). The 8 bits in each slot map to the JeeNode’s I/O pins: bits 0..3 = AIO1 .. AIO4 and 4..7 = DIO1 .. DIO4.

A refinement is that only the first 255 of the 256 slots are scanned. This way, 0 is 100% off and 255 is 100% on.

The static “masks” array defines which setting gets mapped to which I/O pin. It depends on the way the output driver is connected to the JeeNode.

The main PWM timing loop is done fully in software. It will run slightly irregularly due to timer interrupts and RF12 driver interrupts, but the effects aren’t noticeable.

The RGBW values are stored in EEPROM, so that the LEDs come back on with the same settings after power cycling. The settings can be adjusted by sending a packet with the new values to node 30, group 5 @ 868 MHz.

This sketch could be extended to support “animations”, i.e. ramping up/down to specific levels, mood lights, etc – I’m not interested in that, I just want to be able to trim the color of my room lighting to a pleasant level of white:

Dsc 1723

All I did to adjust the strip on the right was send the following “RGBW” command out via a JeeLink:

255,140,40,120,30s

The above sketch does PWM, but this whole thing is still being turned on and off with an old-fashioned mechanical switch … if you still remember those :)

FWIW, I’m considering making a dual-channel “MOSFET Plug” – two of those could then be used to replicate this same setup for the LED strip on the left.

Tomorrow: a little GUI front end for all this.

RGB driver board

In Hardware, Software on Jun 14, 2010 at 00:01

To follow up on yesterday’s post, I made a more permanent 4-channel board for driving an RGB LED strip plus the original white LED strip already in use.

A JeeNode is used to drive these strips, using a small custom JeePlug to hook up ports 1 and 4, as well as to use the LED voltage as power source for the JeeNode:

Dsc 1717

Here is the plug in more detail:

Dsc 1718

It includes an LP2950 linear regulator to put 5V on the PWR pin, that way this thing can be used with any input voltage from 12 to 24V. Here is the bottom side:

Dsc 1719

The driver itself uses four IRLZ34N MOSFETs, three of which will be used for the RGB strip, and the other for the white strip so that it too can be controlled and even dimmed remotely:

Dsc 1715

The back side is hand-wired using sturdy copper wire, although in this case only 300 .. 600 mA is being switched per color. The 10 kΩ pull-down resistors prevent the lights from turning on in the absence of control signals.

Dsc 1716

And here’s the completed setup:

Dsc 1714

The two wires sticking out are for attaching my 12V lab power supply during testing. The other green 2-pin screw terminal is for attaching the white LED strip.

The RGB ledstrips can now be installed next to the LED strips already in use here at Jee Labs:

Dsc 1722

Here’s a trivial test sketch to turn each of the 4 colors on and off:

Screen Shot 2010 06 11 at 13.17.35

The results can be seen in this brief video.

What remains, is to write the software so this thing can be controlled via wireless. I might add an LDR to sense ambient light levels, or even a Room Board. Perhaps some basic ramp-up / ramp-down PWM logic. Or maybe I’ll just duplicate this setup and drive the two sets of LED strips I have, independently and from a single JeeNode.

Hardware is easy, it’s always the software… the code will be presented tomorrow!

Reminders: 1) June discount and 2) Jee Labs will be closed from July 14th to August 14th.

Driving an RGB strip with MOSFETs

In Hardware, Software on Jun 13, 2010 at 00:01

Another day, another project started. I have a nice 5-meter LED strip in the office, which provides indirect lighting at Jee Labs. Works fine, but despite being called “warm white”, it’s slightly greenish. Not so great…

Someone suggested adding an RGB strip next to it, to compensate for the color.

So to start off this multi-part series, I wanted to simply control RGB. This is very easy to do with three MOSFETs. I used IRLZ34N’s N-channel, since the LED strips are common anode. The circuit is trivial: source to ground, drain to LED cathode, and gate to an I/O pin. Rinse and repeat three times. I didn’t even add a pull-down resistor to the gate, though I probably should.

Here’s the circuit, fully connected to a test strip with 9 RGB LEDs using a separate 12V power supply:

Dsc 1664

I wrote a little test sketch which ramps the light levels up and down using PWM, and which goes through all the RGB combinations – using some bit fiddling:

Screen Shot 2010 06 07 at 13.17.10

The LEDs are pulsed in software, with a cycle time of 8160 µsec (32 * 255), i.e. roughly 120 Hz. No discernible flickering. A more advanced version ought to use interrupts to keep the PWM going in the background.

Here’s a video of the result – with apologies for the very low quality.

Since the JeeNode has RF on board, it will only be a small step to add wireless control. Stay tuned…

Update – Source and drain were listed the wrong way around, I’ve updated the text above.

IR trigger for Nikon camera

In AVR, Hardware, Software on Jun 12, 2010 at 00:01

Here’s a fun project: sending out infrared remote codes to takes snapshots :)

This is the code:

Screen Shot 2010 06 10 at 17.19.44

This sketch is doing everything in software, and it’s sort of pushing the limits by pulsing a TSKS5400S IR emitter LED at 38.4 KHz using software delay loops.

The timing diagram on this website was a great help to get this working in no time. Here’s another site.

With the 33 Ω resistor in series, total current through the IR LED should be somewhere between 20 and 50 mA. Since the latter is beyond the ATmega’s current sourcing capapbility, I suspect that the pin voltage will actually drop quite a bit below VCC. A transistor or MOSFET could be added for more power. As it is, this seems to trigger reliably up to about a meter away.

Here’s the setup, triggering my trusty D40 Nikon:

Dsc 1692

a self-portrait!

Lot’s of people have already done this ages ago, btw. Here’s a sketch which uses assembler to get the timing more accurate. But the above does work – the main point is to avoid digitalWrite(), which is relatively slow.

A Happy Ending!

In AVR, Hardware, Software on Jun 10, 2010 at 00:01

The multi-ISP programmer I built and started using some two weeks ago, turned out to be quite a nightmare. Not only were incorrectly programmed ATmegas sent out to about two dozen people, I also had to go through about 70 kits, prepared as new stock just days after I started using this programmer. Twice!

Yes, twice. Because the first “fix” turned out to be insufficient. Doh.

This was a clear case of one bug hiding another, and another, and another. Yep, four bugs: a bug in the MemoryStream class in the Ports library, a timing problem exposed by fixing that bug, and two incorrect assumptions about how the “avrdude” utility works. I’ve now got an explanation for everything that went wrong.

There’s no doubt some interesting psychology at work here … I was so proud of my idea op programming multiple ATmega’s! The main idea was to create an AVRISP-compatible unit which stores everything sent through it and then just replays the saved stream as often as needed. Trouble is, I jumped to conclusions the minute a first “run” worked. Roll the presses! Print it! Tell it to the world!

Anyway. There is a happy ending to all this!

The latest version of the isp_capture.pde sketch in the Ports library has been working properly for over a week now, programming well over a hundred ATmega’s (and it now does auto shut-down a few minutes after use):

Isp Capture Output

The last bug was a very puzzling one: everything worked, but sometimes the fuses wouldn’t get programmed. It turns out that avrdude first reads the fuses, and only sends out commands to program them if the fuses don’t match the new value. Since the programmer needs to work with brand-new as well as previously-programmed chips, the replay mechanism would have depended on the prior state of the chips: not good.

The solution is very simple: I now always program each fuse twice, with two different (valid) values. The second one will remain in force, evidently. Since the replay code was already ignoring fuse mismatch checks, this now means that even if the first setting is skipped by avrdude, the second will always be emitted.

Here is the shell script to prepare the Flash Boards:

Screen Shot 2010 05 30 at 01.35.40

So this has now become a very useful tool at Jee Labs:

Dsc 1432

I love the on-board LiPo battery: I can grab it, use it where I need it, and put it back – no wires = freedom!

For pre-loading the fuses, boot loader, and RF12demo, it already saved me a huge amount of time. Its “burn rate” is up to 500 chips/hour. And Mr. Murphy taught me some valuable lessons along the way…

And now it’s time to move on!

Repairing a faulty ATmega

In AVR, Hardware, Software on Jun 9, 2010 at 00:01

This post is being written after a pretty nasty foul-up on my part w.r.t. sending out badly-flashed ATmega chips. It’s probably too late to be of use to anyone involved in that little débâcle, but I thought I’d describe a DIY fix here in full detail anyway. I’ve simplified the code to make it even easier to use than what was described here.

So what is this about, eh?

The ATmega328 chip used in JeeNodes (and Arduino’s, and various other similar board) comes with a serial boot loader pre-loaded into the high end of its flash memory. This is arguably one the most important features that made the Arduino popular: it lets you upload a new “sketch” into the ATmega over the serial or USB port.

Lots of little details, but the point here is that the boot loader itself can’t easily be damaged, even if you load a non-functional sketch into the ATmega. Just resetting it will let the boot loader overwrite the flash memory with a new version – hopefully a better one. Basically, no matter what goes wrong, there’s always the boot loader in the ATmega to upload a new sketch to it.

There’s a chicken-and-egg problem, though: how do you get that boot loader into the ATmega in the first place? Well … you don’t. It’s normally placed there by the supplier of your ATmegas.

Since Jee Labs is one of the suppliers of JeeNodes (for Europe, and Modern Device for the US), I do need to do a little more. I use an “ISP” programmer to place that boot loader there, along with the RF12demo sketch.

But there’s really not much to all this, and this whole boot loader / ISP stuff can easily be performed by anyone. Keep in mind that’s it’s just about getting that first step right: proper fuses and the boot loader stored in flash memory. Nothing more.

All you need is a working unit and a second target unit with the ATmega that needs to be repaired (or initialized for the first time – same thing). For Arduino’s, it’s all explained at http://arduino.cc/en/Tutorial/ArduinoISP.

As it so happens, there’s now even simpler software to do this, so I’m going to describe the process in terms of using one (working) JeeNode to repair another JeeNode (note that this still should work for Arduino’s as well).

The basic idea is still the same: we need to connect 6 wires. There are 2 wires for +3V and GND and 4 wires connected to ports 1 and 4. On the target JeeNode, the wires will be connected to the ISP connector:

Screen Shot 2010 05 29 at 01.37.23

The target JeeNode will receive its power from the working JeeNode, so don’t plug it into anything. Note that this can also be done with JeeNode USBs. All we need, is to make a few connections for power and I/O.

The working JeeNode should be plugged into a USB-BUB, or something similar. Do that now, because the following wiring step can be a bit sensitive to movement.

The following six connections need to be made:

Screen Shot 2010 05 29 at 02.57.58

On the working unit, the wires or wire jumpers can be inserted into the 6-pin port headers.

On the target side, you’ll probably just have gold-plated holes for the ISP connector. The nice thing about gold plating is that it easily makes contact. So one way to hook up the wires is to insert all six as shown above, and position the whole thing in such a way that there is a slight tension on the wires – just enough to make contact.

Ok, you should now have the working unit powered up, and the target unit receiving power and signals through these 6 wires. Good, leave them alone now.

To do the actual reflashing, I’ve added an isp_repair.pde sketch to the Ports library, which does everything. Upload that sketch to the working JeeNode, and open up the console. Here’s what you should see:

Screen Shot 2010 05 29 at 02.24.05

That’s it. The target ATmega has been set up with the proper fuse settings and a boot loader. You can remove all the wires, and hook up the JeeNode to a USB-BUB. It’ll now accept sketches like any other JeeNode. Fixed!

Why use acknowledgements

In Software on Jun 6, 2010 at 00:01

Yesterday’s post showed how to receive packets sent out by the “bmp085demo.pde” sketch, and report them back to the serial port. By reporting in the same format as the sender, this makes it possible to easily switch between a local direct-connect setup and a two-node wireless setup.

But there’s a bit of unnecessary complexity in there.

Note that I’m using the Easy Transmission mechanism, which is indeed easy to use – only four lines of C code is all it takes to turn a local node into a wireless node.

If you try out this setup, you’ll see that the receiver doesn’t always report packets, i.e. not every second. That’s not because it’s missing packets, but because the Easy Transmission mechanism includes logic to avoid sending anything if the data hasn’t changed.

There is a way to force sending packets with rf12_easySend.

But there’s another issue with this setup. The Easy Transmission mechanism uses acknowledgements and timers to make sure that all data arrives at its destination. If no ACK is received within one second, the data will be resent.

Trouble is, this is a bit silly: we’re sending out fresh readings every second anyway, in this setup! Why use timeouts and a retransmission mechanism, just to resend potentially outdated information in the first place?

This setup doesn’t need a retransmission mechanism, it adds no value.

In fact, we don’t even need ACKs: what’s the point of an ACK if the proper arrival at the receiver end doesn’t really matter to the sender? In this setup, the sender is going to send updated readings once a second anyway.

This is a clear case of overkill, so let’s simplify. Here is the improved sender:

Screen Shot 2010 05 26 at 22.11.57

It’s not shorter than before, because the rf12_easy* functions really are indeed quite easy and compact. But the code size is reduced a fair bit:

Screen Shot 2010 05 26 at 21.33.00

vs.

Screen Shot 2010 05 26 at 22.13.12

(Much of the remaining code size is due to the code needed for the BMP085 pressure calculations)

And here’s the receiver, which no longer sends ACKs:

Screen Shot 2010 05 26 at 22.08.15

The difference in size is due to no longer loading any transmit code:

Screen Shot 2010 05 26 at 21.38.27

vs.

Screen Shot 2010 05 26 at 22.07.28

More importantly perhaps, the receiver now reports readings once a second, including unchanged ones:

Screen Shot 2010 05 26 at 22.22.32

… and of course, that – without the ACKs – there will be about half as many packets flying through the air.

The moral of this story is: don’t include functionality if it doesn’t serve a need!

Switching from direct serial to wireless

In Software on Jun 5, 2010 at 00:01

The recent weblog post about the BMP085 sensor used on the Pressure Plug sends its readings out to the serial port once a second. It also included a few extra lines of code to send the results wirelessly via the RF12 driver. I added that code to illustrate how easy it is to go from a wired hookup to a wireless hookup with JeeNodes:

Screen Shot 2010 05 26 at 21.36.01

Sending it is only half the story – now I need pluck it out of the air again. I could have used the RF12demo sketch with – say – a JeeLink to pick up these transmissions, but then I’d get something like this back:

Screen Shot 2010 05 26 at 21.33.22

I.e. 6 bytes of raw data. One way to deal with this is to write some code on the other end of the serial port, i.e. on the receiving workstation, to decode the reported temperature and pressure values. That’s what I’ve been doing with JeeMon on several occasions. Then again, not everyone wants to use JeeMon, probably.

Another way is to simply create a special-purpose sketch to report the proper values. Such as this one:

Screen Shot 2010 06 24 at 18.42.53

Sample output:

Screen Shot 2010 05 26 at 21.27.22

I used the same format for the output as the “bmp085demo.pde” sketch, but since the two raw data values are not included in the packets, I just report 0’s for them. As you can see, the results is more or less the same as having the Pressure Plug attached directly.

The ACK logic in this sketch looks a bit complicated due to the bit masking that’s going on. Basically, the goal is to only send an ACK back if the sending node requests one. And since we assume that the sending node used a broadcast, we can then extract the sending node ID from the received packet, and send an ACK just to that node.

Tomorrow, I’ll describe how all this can be streamlined and simplified.

IC socket ≠ IC socket

In Hardware on Jun 3, 2010 at 00:01

Ok, so the JeeNode v4 kit is fine, judging from how many people have ordered them and built them. Cool, that was the whole point – a small Arduino-compatible kit with RF on board that’s easy to build and use.

As was to be expected, I ran out of IC sockets the other day. So I ordered new ones. Except, I picked a different supplier (DigiKey i.s.o. Farnell), because I thought it would simplify my life to obtain everything from as few sources as possible. Silly me…

Here’s what I got, 500 times:

Dsc 1500

Guess where it doesn’t fit?

Dsc 1503

The bent pins won’t fit through the JeeNode v4 PCB, where I used smaller holes to simplify soldering. Grrr…

There’s a solution, but it requires a bit of extra work. Take a set of flat beak pliers and flatten the pins, sort of:

Dsc 1501

Now it will fit, with a bit of juggling, while being careful not to bend any pins:

Dsc 1502

Problem solved. But I’ve learned another lesson: when things work, don’t change … A N Y T H I N G !

FWIW, I only found out about this problem after a handful of JeeNode kits had been sent out with these bent-pin IC sockets. I immediately ordered more suitable ones, which arrived the next day, and switched over to resolve the problem.

(Luckily, these IC sockets fit just fine on the Ether Card, so all it not lost…)

Mystery boxes

In Hardware on Jun 2, 2010 at 00:01

Ok, here’s a puzzle for you. A project with two boxes, but what are they for?

The first box is truly a “black box” – no connections at all, no display, no button, nothing:

Dsc 1495

Not much to see on the inside either:

Dsc 1494

The second box has a 5-way button and an LCD display:

Dsc 1497

There’s a USB connector on the bottom right, but it’s only used for charging and debugging.

There’s a bit more electronics inside this one:

Dsc 1496

Still a few wires missing, because I haven’t hooked everything up yet.

So there you have it. Both boxes are self-contained, but the project I’ll be using them for needs both. I’ll reveal the project once I’ve got the basic software going – it’s always the code that takes the most time to develop!

JeeNode as web server

In AVR, Software on May 31, 2010 at 00:01

The new Ether Card add-on makes a lot of new fun stuff possible. Even with a measly 8-bit ATmega chip, it’s possible to create some pretty neat things. Like a little webserver for displaying the last received RF12 packets.

I’ve added an EtherCard library to the subversion repository, next to the Ports and RF12 libraries, etc. It’s now listed on the software page in the Café.

This is mostly the Ethernet code by Guido Socher and Pascal Stang, but I’ve moved some stuff around a bit, and kept the changes added by Andras Tucsni to make this work together with the RF12 driver.

A new “BufferFiller” class has been added, to help create web pages and such:

Screen Shot 2010 05 22 at 00.04.55

What it does is expand a PSTR given to it, by replacing $S, $F, and $E with strings copied from RAM, flash, or EEPROM, respectively. A bit like “printf” in standard C. It’s easiest to just show an example of use:

Screen Shot 2010 05 22 at 01.42.00

The $D code is expanded as integer, for convenience. And since BufferFiller derives from the Arduino’s “Print” class, all the usual “print()” and “println()” members are also available.

The above code will generate the following web page (and yes, it’s been up and running more than 3 days):

Screen Shot 2010 05 25 at 09.55.06

It’s part of the etherNode.pde sample sketch in the EtherCard library – a little web server which shows the last few incoming RF12 packets and continuously self-refreshes to present the latest info.

There’s also a configuration page:

Screen Shot 2010 05 21 at 18.46.32

The whole etherNode demo sketch is under 10 Kbyte, including both EtherCard and RF12 drivers, leaving plenty of room to implement more features.

Assembling the Ether Card

In Hardware on May 30, 2010 at 00:01

(This is going to be a long post, so I’ve split it up a bit)

Here are the steps needed to assemble the Ether Card kit, starting from this PCB:

Dsc 1433

This board is very easy to build, since it uses only through-hole parts and has relatively few components. The basic idea is to build from the flattest to the highest components. That way, when you turn the card over for soldering, you can push on it to press the component against the board.

So let’s start with the 7 resistors. Don’t mix them up, they have three different color-coded values:

Dsc 1435

Turn over the board, don’t use too much solder, make clean solder joints, and snip the wires off when done:

Dsc 1436

The important thing is to get the solder flowing into the plated-through holes.

Next, the ferrite bead (a small inductor which blocks high frequencies):

Dsc 1439

More…

Read the rest of this entry »

Using LiPo batteries

In Hardware on May 29, 2010 at 00:01

The latest revision of the JeeNode USB includes a LiPo battery charge circuit:

Screen Shot 2010 05 22 at 13.45.15

The “+5V” pin is the incoming pwoer from the USB bus, it goes directly to the MAX1555 LiPo charger. From there, the PWR line is fed, so this will normally be at 4.2V when no battery is attached. That PWR voltage in turn is fed to the on-board 3.3V regulator for the ATmega and RFM12B.

This design was chosen because it lets you very easily add a LiPo battery: simply attach it between PWR and GND. There are no switches or switch-over issues: plug-in to charge, then use unplugged as needed.

I’m going to use the Carrier Board as example, and I’m going to use a LiPo battery from SparkFun, which comes with a polarized JST plug already attached. Here is the matching socket:

Dsc 1486

What we need is a spot where this socket can be soldered on. Ah, here it is, on the PWR/SER/I2C connector:

Dsc 1487

The trouble is that the pins are not 0.1″ apart as needed here, and that the socket won’t be usable if mounted sideways. So I cut off the plastic tabs and bent the wires a bit differently (taking care not to bend too much, because they break very easily):

Dsc 1484

The result fits perfectly on the Carrier Board, with the whole setup in turn fitting very nicely in the ABS box:

Dsc 1485

I’m using an 850 mAh LiPo cell.

One point to note is that the charge current from the MAX1555 is fixed at 280 mA. The rule for LiPo battery is to charge them at no more than 1C, i.e. a 850 mAh cell shouldn’t be charged with more than 850 mA. So in this case, we’re fine, with an estimated charge time of 3..4 hours for a fully discharged battery.

IOW, don’t use this setup with LiPo batteries smaller than 300 mAh or so.

Another thing to avoid with LiPo batteries is to discharge them below about 3V. You can check rf12_lowBat() from the RF12 library once in a while. It reports when the voltage at the RFM12B drops below 3.1V, i.e. around 3.2 .. 3.3V on the LiPo. Once this happens, power down the ATmega + radio to avoid draining the battery any further.

Why all the fuss? Because LiPo batteries can burn and explode, when improperly handled. There’s a lot of energy in there, and at some point things can exceed the design limits. Search for “lipo explode” on YouTube…

There are really only two issues: 1) the short-circuit discharge current can be extremely high (20C, i.e. 17 Amps with the above unit!), so short circuits and polarity reversals must be avoided at all times. And 2), charging should be done with the proper circuitry, such as the one in the JeeNode USB.

Why use LiPo’s? Well, they are very compact for the amount of energy they store, they can be recharged over and over again, and they have a very low self-discharge rate (i.e. long shelf life when not used).

When used properly, LiPo batteries are a great way to power JeeNodes, etc.

Dear Mr. Murphy

In AVR, Hardware on May 28, 2010 at 00:01

Dear Mr. Murphy, you must have had a ball these past few days…

I goofed. Again. Big time. Well, not Toyota- or BP-scale big time, but still. It’s all your fault, Mr. Murphy!

About two dozen faulty ATmega’s were shipped as part of the JeeNode Kits. And another five dozen or so were packed into kits-in-stock:

Dsc 1505

What happened? Well, that “flashy” new multi-ISP programmer I was so proud of has a bug when the “isp_cpature.pde” sketch is used in replay mode: it doesn’t program the fuse bits properly. Whoopsy daisy. I thought I had all the scenarios covered and tested, but clearly I didn’t. Those ATmega’s are shipped running at 1 MHz, and the pre-loaded RF12demo is initializing the serial port to a totally useless 57600 / 16 = 3600 baud.

This morning (i.e. yesterday by the time this post comes out), I went through the stock of ATmegas, including those in already-packaged-and-labeled JeeNode kits, and redid the fuses and uploads. Not quite my idea of fun.

Anyway. The good news is that everyone has been contacted, and that I’ve sent out replacement ATmega’s to those people who I’m quite certain have the botched version. A few people will have run into the problem (that’s how I found out!), but most kits are probably still in transit, and will now be followed by the fixed ATmega(s) shortly.

In case I missed anyone, here are the symptoms: the LED on the USB-BUB stays on relatively long when a JeeNode kit is plugged in, there is no greeting from the pre-loaded RF12demo or there are only garbled characters, and you can’t upload to the JeeNode. The problem is only with ATmegas sent out in the past few days, no more than perhaps a week ago. JeeNode USBs and JeeLinks are not affected. If you run into exactly this problem, please email me and I’ll send you a replacement ATmega.

To make matters worse, I also mixed up some of the early Carrier Board and Ether Card orders, fogetting to include this or that. All issues reported to me have now been resolved.

Oh well, live and learn.

Now go home, Mr. Murphy, and don’t come back. Please? :)

Meet the Ether Card

In AVR, Hardware, Software on May 24, 2010 at 00:01

Yesterday’s post was a sneaky way to show you a glimpse of an exciting new addition to the always-evolving Jee Labs product range – meet the Ether Card !

Dsc 1454

It’s a low-end Ethernet extension card, with a form-factor specifically made for the Carrier Board + Box:

Dsc 1467

It is based on the good ol’ trusty ENC28J60 chip, with all the components needed to hook it up to a JeeNode (or any other unit running the SPI bus at 3.3V).

I’ve started working a bit on the software side. The Ether Card is pretty standard in every respect, with the GPL2 code by Pascal Stang and Guido Socher working just fine with it. All it needs is a different chip select pin (PB0, Arduino pin 8) and proper interrupt guards to prevent the RF12 driver from interfering.

The card has been running smoothly for days on end here. It gets slightly warm, I’d estimate some 20°C above ambient. The regulator stays cool when powered from 5V. Total current draw is ≈ 150 mA, incl. JeeNode.

The Ether Card only uses through-hole parts, no SMDs. It has been added to the shop as kit and as PCB-only version. Here’s the PCB – in glorious blue-and-gold:

Dsc 1433

Here’s a sample web server requiring under 10 Kb of flash and showing a page with the last 25 RF12 packets:

Screen Shot 2010 05 19 at 11.33.18

So there you have it. JeeNodes can now handle wireless and wired networking.

It’s going to be oodles of fun to develop software for / on / with this Ether Card!

Credits: I would like to thank Andras Tucsni, who started the ball rolling by prototyping a complete working system and implementing the chip-select and interrupt changes needed for inter-operation with the RF12 driver on SPI. Andras also wrote the demo sketch which generated the above output. Knowing that it can be done and having working sample code makes a huge difference!

In and out of the box

In Hardware on May 23, 2010 at 00:01

The last two posts about the Carrier Board and Carrier Card showed how the whole kaboodle was designed for a specific light-gray plastic ABS box:

Dsc 1463

If you just use batteries and wireless, then that’s the end of the story.

But most of the time, this needs some cutouts. Let me describe how I created a custom version with a standard low-voltage power jack and an RJ-45 connector, using just these tools:

Dsc 1480

First step is to very carefully mark the position and saw some thin slots in this thing. ABS plastic is very soft and easy to cut with a little saw like the one above:

Dsc 1468

I tend to make the cutouts too narrow, because there is no way back!

To get a clean break, I use the knife to scratch along the line where the plastic needs to break, and then bend it (oops, you’ll also need some small pliers for that):

Dsc 1469

This coutout was in the top half, for the DC jack. After some trimming with the knife, the cutout looks pretty accurate. Next one was the RJ-45 connector:

Dsc 1470

Same idea: mark, saw, scratch, and break off:

Dsc 1471

Almost there. Still a bit too narrow, and not quite deep enough – some more trimming produced this:

Dsc 1473

Ah, that’s just about perfect (the left side could still be made a tad deeper):

Dsc 1478

Finished!

Meet the Carrier Card

In Hardware on May 22, 2010 at 00:01

The companion to yesterday’s Carrier Board is the Carrier Card:

Dsc 1458

It fits exactly in the plastic case, of course:

Dsc 1459

(If you look closely, you can see a hole to screw the left half of the board to the center of the shell.)

The Carrier Card is made of two halves which can be broken apart and used separately, if needed:

Dsc 1462

Here’s another configuration:

Dsc 1461

This allows inserting all sorts of JeePlugs, and using some or all of the connectors on the lower edge of the carrier Board for more elaborate projects. Everything is on a 0.1″ grid, so this also works with perf-board, etc.

By including the PWR/SER/I2C + SPI/ISP headers and connecting everything together, up to 19 I/O pins from the JeeNode are available when a full-width Carrier Card is inserted in the lower row of five 6-pin headers.

I’m looking forward to finally setting up some of the Jee Labs projects in a more permanent manner.

Tomorrow, I’ll show how to make some nice cutouts in the side of this box. ABS plastic is fairly easy to trim manually. Really good looking rectangular cutouts in the top or bottom are no doubt a bit harder – I intend to experiment with some CNC stuff for that.

Stay tuned!

Meet the Carrier Board

In Hardware on May 21, 2010 at 00:01

Finally, all the pieces have arrived to be able to announce the Carrier Board !

Dsc 1434

It fits into a plastic box of about 70 x 125 x 30 mm, made of two identical ABS shells which click together:

Dsc 1310

The JeeNode, JeeNode USB, and JeeSMD can all be used, they are “carried” by this board, so to speak:

Dsc 1311

Tons of ways to hook up plugs to this thing. There’s a diagram with all the pinouts (PDF).

Here’s a version which has all headers soldered in – not very useful, but I had to test everything anyway:

Dsc 1315

Note that only the port headers use male pins on the Carrier Board (towards the JeeNode, that is). The PWR/SER/I2C and the SPI/ISP headers both use pins with the opposite orientation. This was done because the ISP header is more useful as pins on the JeeNode, and to avoid confusing the PWR/SER/I2C header with ports, since both types use 6 pins.

More related news tomorrow…

A subtle RF12 detail

In Software on May 20, 2010 at 00:01

Someone recently emailed about a baffling problem when trying to get two JeeNodes to alternately transmit and receive. It turns out that there is a subtle aspect to calling the rf12_canSend() routine in the RF12 driver, which really needs to be clarified.

The basic idea is to have two nodes running the same sketch. Each of them broadcasts a small packet every 3 seconds, and displays incoming data the rest of the time.

I used my favorite LED debugging technique to create a simple setup with two JeeNodes:

Dsc 1456

The idea is to blink the red LEDs on each send, and the green ones on each receive. Here’s a first attempt which doesn’t do what you’d expect:

Screen Shot 2010 05 17 at 17.40.42

There’s one minor and one major problem with the above code.

The minor problem is that since sending takes place in the background, you’ll probably not see the send LED blink at all: it’s only lit for a few microseconds. The same holds for the receiving end, although there it’ll probably be visible because serial I/O takes some time. The solution for this little problem is to insert delays so the LEDs stay on longer.

But the big problem with the above code is that it doesn’t work. Whoops!

The reason for this is that rf12_canSend gets called constantly, i.e. each time through the loop. Even when the timer hasn’t gone off, and we won’t be sending anything out.

The thing about calling rf12_canSend is that it is also being used to signal your intention to send out a packet. So when sending is possible, and rf12_canSend returns 1, the RF12 driver will stop reception and get ready to send your packet out. Which is what the subsequent rf12_sendStart will do.

The gotcha is that if rf12_canSend returns 1, then you have to also call rf12_sendStart.

How do we solve this? We can’t just exchange the calls to rf12_canSend and the timer poll, because we’d lose timer events (i.e. when the timer fires and just at that very moment rf12_canSend happens to return 0 – which it does, occasionally).

The problem can be solved by using a slight variation of the code:

Screen Shot 2010 05 17 at 17.51.10

I’ve added the complete code of this “pingPong.pde” sketch as example to the RF12 library.

Note: both nodes are set to ID 1. This isn’t a problem in this case, because the packets are sent as broadcasts. A node will never receive its own packet, since it is busy sending. With RF12, packets always go out to “everyone else but me”. When you’re only using broadcasts (and no ack’s), node IDs are irrelevant.

Multi-ISP programmer

In AVR, Hardware on May 18, 2010 at 00:01

This is a project I’ve been meaning to do for a long time:

Dsc 1432

It’s a portable ISP programmer which can program four 28-pin ATmega’s independently. It takes about 12 seconds to program fuses, bootloader, and RF12demo sketch into each chip, so with this unit I can essentially keep going and program some 20 chips per minute. Just what I need for yesterday’s batch of fresh ATmega’s. For reference: a USBtinyISP needs a few minutes per chip! (update: but it can be speeded up, see comments below)

Not that I need to program 1200 chips/hour! The point is that at this speed, I can now flash ATmega’s just-in-time, i.e. with the very latest version of RF12demo, etc.

This multi-ISP programmer is built from 4 Flash Boards, 1 JeeNode USB, 3 JeeSMD’s, a 450 mAh rechargeable LiPo battery, and a couple of ZIF sockets, resonators, and resistors. I’ve got roughly a dozen more ZIF sockets for the shop of there is interest. Also some 6-pin IDC headers and flat-cable.

The unit uses the capturing ISP programmer sketch and is very simple to use: plug the JeeNode USB in and use it as a normal AVRISP programmer @ 19200 baud. Use as many programming steps as you want. When idle for 3 seconds, the process stops – blinking the LED twice. Then exchange its Flash Board with one of the others and repeat the process until all flash boards have been set up.

From then on it can also work in battery-powered mode: insert chip, press button, wait for LED to start blinking, then rinse and repeat. Total current draw will be well under 90 mA, so this programmer should get over 5 hours of autonomy on one charge – up to 6000 chips… :)

The programmers are independent, so I can upload different contents in each of them. I’ve labeled each flash board to be able to do this without mixing things up.

The JeeNode USB v3 powers all the boards and includes the LiPo charge circuit, so the battery can be recharged by simply plugging it in. There’s a slide switch to disconnect the LiPo battery.

Some more build pictures. As you may have noticed, there is no connection from the 2×3-pin ISP header to the ZIF socket. That’s because I wired those up from below by using stacking headers for 2 of the 4 ports:

Dsc 1422

Here is the other side, wired up manually with wire-wrap wire. I’ve since covered it up a bit to avoid accidental shorts. The risky one is a direct short between the LiPo power pins, the rest is probably harmless.

Dsc 1430

And here’s the side view:

Dsc 1431

I’m looking forward to using this thing: swap chip, push button, swap chip, push button, … how convenient!

New ATmega batch

In AVR, Hardware on May 17, 2010 at 00:01

At last, 250 new ATmega328’s came in from DigiKey:

Dsc 1419

You may not have noticed, but in these past months there has been a major shortage of ATmega328 chips – everywhere. Once that happens, people start stockpiling, driving the shortages and delays up yet further, etc.

That’s 250 chips to intitialize with a boot loader + RF12demo sketch! Kinda illustrates my need for a good ISP programmer setup, eh?

There’s a substantial amount of capital investment involved in this stuff, so I’ve been cautiously moving about while trying to keep all the essential items in stock for the shop. So far, so good, mostly. But this batch sure is welcome… one less thing to worry about.

Onwards!

Reflow revisited

In Hardware on May 9, 2010 at 00:01

As mentioned yesterday, I’m restarting the reflow oven/grill project because my old setup with an NTC resistor is causing some mechanical problems with the connection of the NTC and because I want to end up with a setup which will be easier for others to replicate.

My intention is to start this project from scratch, using a JeeNode and a Thermo Plug as sensors, and then adding a JeeLink, an FS20 remote-controlled power switch, and of course a grill to create a fully automated and self-contained reflow station for soldering SMDs on printed circuit boards.

I’ll be replicating some of the first experiments, but there will be no need to calibrate NTC readings.

I’m also going to use JeeMon to illustrate how to design and implement the software for this from scratch. I expect to extend and improve JeeMon itself along the way, since it’s still very much in its infancy.

In case this is all new to you: reflow soldering is a technique whereby you apply solder paste to a PCB, carefully add all the components on top, and then bake that whole enchillada according to a preset temperature / time profile. The end result is a finished circuit. Here are some pictures from a few months ago.

Here is the intial setup:

Dsc 1413

From left to right: a 4.5V 3x AAA battery pack, the JeeNode, the Thermo Plug, and a 1-meter thermocouple sensor. This consists of two metal wires of different types, joined at the end. The end is where sensing takes place, because every junction of two different metals generates a tiny electric potential related to temperature.

Yesterday’s post contained the very simple sketch I’m using for this first step.

Tomorrow, I’ll describe the software setup and the first steps needed to read out the data sent by this sketch.

Update – switched to a slightly simpler setup, as shown in the updated picture.

Assembling the Flash Board

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

Here is a step-by-step instruction for assembling the Flash Board, starting from these components:

Dsc 1386

The 24M01 1 Mbit EEPROM is already on the board. The build proceeds essentially in flattest-to-higher order, so that when you turn the pcb around for soldering, you can push down the part properly.

We start with the 470 Ω current limiting resistor for the LED:

Dsc 1388

Try to make nice and shiny joints:

Dsc 1387

Cut off the excess wires:

Dsc 1389

Next is the little start button:

Dsc 1390

There are four pins to solder:

Dsc 1391

They are a bit long, so it’s best to cut them off:

Dsc 1393

Next, the LED. This one is polarized, be sure to put it in the right way:

Dsc 1394

The last component on the top is the 2×3-pin ISP header:

Dsc 1396

Again, make sure all pins have good solder joints:

Dsc 1397

Now, all we need to do is solder in the 4 6-pin headers. The easiest way to do so is to push these headers into a JeeNode for proper positioning:

Dsc 1398

The push the Flash Board on top and you’ve got a convenient way to solder them:

Dsc 1399

That’s it, done!

Dsc 1400

Now you can upload the isp_capture.pde sketch on this page and use this brand new ISP programmer.

Happy programming!

Low-level development

In AVR, Hardware on May 6, 2010 at 00:01

I’m working on some ideas which require some low-level code, and fairly accurate timing. Serial or wireless I/O are not an option, and hooking up the logic analyzer is not convenient (I may have to, if the going gets tough).

For now, here’s a very simple setup which ought to be sufficient:

Dsc 1385

Two boards, hooked up via two USB ports. They are on the same computer, so there should be no issues with voltage levels when leaving them both connected at the same time (I’m not too worried about the ground loop).

The board at the top is the Flash Board as ISP programmer (I’m not using the new capturing features here). The board below is the “target”, a plain JeeNode hooked up to a USB-BUB. Nothing fancy.

I’ve added 8 bits of “I/O” by hooking up 8 LEDs with current-limiting resistors – red on the DIO pins, green on the AIO pins as debugger, as described here.

The target board also has the option to communicate over serial (i.e. through its USB connection), but that adds code and affects timing – something which I probably can’t tolerate in my specific tests.

Nothing very unusual here, but it’s worth pointing out that a couple of years ago, a setup like this could easily have cost over 1000 <pick-your-favorite-currency>, whereas this one is well under 100.

Let’s see how it goes…

A capturing ISP programmer

In AVR, Hardware, Software on May 5, 2010 at 00:01

Meet the new, improved, autonomous, self-guiding, hassle-free, portable ISP programmer!

Dsc 1381

It works as follows:

  • hook up a JeeNode or JeeNode USB to your computer
  • upload the isp_capture.pde sketch to it
  • insert the Flash Board and hook it up to the target
  • program the target, using this as a standard STK500/AVRISP programmer @ 19200 baud
  • wait for the LED to blink twice
  • done

And this is where the fun starts:

  • connect the JeeNode to a battery or any other power source
  • insert the above Flash Board again and hook it up to the target
  • press the button on the Flash Board
  • wait for the LED to first turn off and then start flashing
  • done

You’ve just programmed another target MPU … look ma, no hands!

The first hookup went through a normal programming cycle, but it also stored everything in the EEPROM on the Flash Board: code, data, fuses, verification bytes, everything. That’s why I’m calling this a capturing programmer.

When pressing the button, it essentially repeats all the same steps.

This works for anything you can program with an AVRISP programmer: ATmega, ATtiny, whatever. And it will even capture multiple programming cycles, as long as they are started before the LED blinks twice, i.e. within a few seconds. So you could set up a script to call avrdude with a few different things to do – e.g. set fuses, program the flash, program the AVR EEPROM, set the lock bits.

There are some tricks under the hood to make this work. First of all, the baudrate as ISP programmer is set to 19200, so that the bootloader in the JeeNode doesn’t accidentally take over after reset (it listens at 57600 baud).

Another trick, and the main reason this all works transparently, is that the entire serial communication session is stored in EEPROM as is. When pressing the button, it simply replays the input to the programmer code as if it was coming from the serial port (and matches the results, also against EEPROM). There is some logic involved to be able to store both input and output streams, and keep them properly apart.

The EEPROM is connected via I2C to port 3. I used the MemoryPlug and MemoryStream classes from the Ports library to access it.

Lastly, there is some debugging built in. While used as AVRISP programmer, the serial port is in use for programming @ 19200 baud. But when in replay mode, the serial port is set to 57600 baud and used to report what the programmer is doing. Here is a transcript:

[isp_capture]
ISP bytes: 39680
Code size: -32768
Page size: 128
Data size: 1024
Signature: 86 00 00 01 01 01 01 03 FF 95 0F
Programming...
Done in 13.9 seconds.

That’s it. There is visual feedback when programming succeeds in the form of a flashing LED, so that this setup can be used without serial link. I’d like to add auto power-down one day, for serious battery use.

I’m going to use a bunch of Flash Boards here, pre-loaded with the different contents of ATmega’s and ATtiny’s I’m constantly preparing here at Jee Labs. Will probably also dedicate a bunch of JeeNodes to this, but that’s optional – any available JeeNode can be temporarily turned into an ISP programmer by simply uploading the “isp_capture.pde” sketch to it and inserting a Flash Board.

Now I can easily reprogram all those Room nodes in the house!!

PS. There’s nothing JeeNode-specific about this setup. The on-board wireless isn’t used (yet?).

PPS. For your convenience, I’ve tagged all related posts on this weblog with ISP.

ATtiny 8-pin ISP programmer

In AVR, Hardware on May 1, 2010 at 00:01

Yesterday’s ISP programmer used a 28-pin socket wired up for ATmega328 chips (and the older 48/88/168 versions).

As it turns out there are enough unused pins available in that socket to also support the ATtiny 8-pin series (such as 25/45/85). The trick is to add a few extra wires so that the ISP programming signals have the proper setup for these smaller chips as well:

Dsc 1376

This allows placing an ATtiny in the socket at the top end, i.e. using just pins 1..4 and 25..28:

Dsc 1377

This trick works, because the I/O pins used by the ATtiny happen to be normal I/O pins for the ATmega, so it doesn’t mind having some logic signals there (pins 9..12 and 17..20 can probably also be used, but then inserting the chip becomes more error-prone).

And sure enough, avrdude can now program the ATtiny as well:

Screen Shot 2010 04 25 at 02.44.46

For other chips, you’ll need to wire up a chip-specific socket, but at least for these ATtiny chips an ATmega setup will work just fine!

ATmega 28-pin ISP programmer

In AVR, Hardware on Apr 30, 2010 at 00:01

The Flash Board presented a few days ago was only half the story. Here is the other half, i.e. the chip socket.

What you need is a board with a 10 kΩ reset pull-up resistor, an 8..16 MHz resonator for the clock, and – just to be safe – a 0.1 µF decoupling capacitor. I used an empty JeeNode v4 PCB to hook it all up:

Dsc 1372

I added the ISP connector in a slightly unusual way: with long pins bent sideways. The reason being that the ZIF socket won’t fit on the board otherwise. In fact, it won’t fit directly anyway because the holes are too small and the socket is too long. So I pushed it (hard!) into a 28-pin IC socket first:

Dsc 1371

Then I soldered the socket in, and there it is:

Dsc 1373

An ISP programmer for 28-pin ATmega’s!

Tomorrow, I’ll describe how I’ve modded this setup to also allow programming 8-pin ATtiny DIP chips …

Meet the Flash Board

In Hardware on Apr 26, 2010 at 00:01

The Flash Board is a brand new piggy-back board to turn a JeeNode into an ISP programmer:

Dsc 1352

It’s compatible with the ISP plug described a few days ago, but it includes a few extra features:

  • on-board button and LED
  • on-board 128 Kbyte EEPROM memory
  • holes for a “direct-connect” ISP connector

It works with the isp_flash.pde and isp_prepare.pde sketches. See those two posts for details about these.

This board is now in the shop as kit, with the EEPROM soldered on since most people probably don’t want to solder such tiny surface-mounted chips. Note that the above two sketches don’t use the on-board EEPROM.

Here’s the Flash Board in more detail:

Dsc 1357

Nothing fancy, but I find it convenient, especially in combination with a JeeNode USB and a LiPo battery pack as a Portable ISP Programmer!

The “direct connect” ISP connector is a funky way to dispense with the ISP cable altogether, and plug this thing directly into a board with 6-pin ISP holes:

Dsc 1358

The master JeeNode + Flash Board are pushed upside down into the 6 holes of the ISP header, i.e. without header. Due to the way these extra long pins are placed, they will go in under an angle and push sideways to make a good connection. The trick is that these pins use two separate ISP headers, to end up with pins 1-2/3-4/5-6 swapped, so that they’ll work properly upside down. See the after-burner weblog post for another example of this.

Sure, it’s a bit funky. And you don’t have to use this. But it works :)

Preparing ATmega’s with ISP

In AVR, Software on Apr 25, 2010 at 00:01

Here’s a second use of yesterday’s ISP plug: pre-loading ATmega’s with a fixed sketch and bootloader.

This uses a very nice trick from the Arduino Boot-Cloner: store the code to be sent to the target MPU as PROGMEM data inside the ISP sketch itself!

I’ve adapted that Boot Cloner so that it takes its data from a separate C include file, added a couple of other features, and speeded the whole thing up a bit.

The result is called “isp_prepare” (code here).

Here’s what you’ll see on the USB serial port when starting it up:

Screen Shot 2010 04 18 at 23.14.22

The list reports the files which have been integrated into this sketch at build time, using this C code at the top of isp_prepare.pde:

Screen Shot 2010 04 18 at 23.23.36

Here is the contents of that include file, with most of the data bytes omitted:

Screen Shot 2010 04 18 at 23.24.51

The data consists of “sections” of code, to be programmed into the target ATmega using ISP. In this case there are two sections, a RF12demo sketch starting at address zero, and a bootloader in high memory.

Here’s is isp_prepare in action:

Screen Shot 2010 04 18 at 23.14.47

So the steps to load RF12demo onto a JeeNode with a fresh ATmega are as follows:

  • upload this isp_prepare.pde sketch to a “master” JeeNode
  • insert the ISP plug described yesterday,
  • connect the target JeeNode to this master JeeNode via ISP
  • enter G to start programming and wait for it to complete
  • done: disconnect, now the target JeeNode is ready to run with RF12demo on it

I’ve also included a “data_blink.h” header file, if you want to preload the ATmega with the standard Arduino blinking LED demo. Just change the include in isp_prepare and upload the sketch again.

I can now use this setup for initializing all the ATmega’s here at Jee Labs, since it means I no longer have to start up the Arduino IDE or use avrdude.

Convenience!

ISP plug

In AVR, Hardware, Software on Apr 24, 2010 at 00:01

For one of my projects, I needed a quick way to reflash an AVR via ISP. Didn’t want to have to use any of the several ISP programmers around here, so I made my own “ISP plug” for use on a JeeNode:

Dsc 1353

The pins are connected as follows:

  • ISP pin 1 = MISO = DIO1
  • ISP pin 2 = VCC (+3.3V)
  • ISP pin 3 = SCK = AIO1
  • ISP pin 4 = MOSI = AIO4
  • ISP pin 5 = RESET = DIO4
  • ISP pin 6 = GND

Here the top view, made from a little JeePlug board:

Dsc 1354

Bottom side:

Dsc 1355

Note that this ISP setup draws 3.3V from the JeeNode and uses it to power the target, so the target board should not have its own power and it should not draw more than say 100 mA of current @ 3.3V.

The code for this is called “isp_flash.pde” and is derived from the “ArduinoISP” sketch. I added software-based (bit-banged) SPI communication for use with the above I/O pins, and did a fair bit of cleanup of the source code.

The nice thing about this ISP programmer is that it works out of the box with Arduino IDE 0018:

  • upload the ISP_flash.pde sketch to the JeeNode
  • insert the ISP plug and hook it up to the test circuit (or one of these …)
  • burn the boot loader using the Arduino IDE:

Screen Shot 2010 04 18 at 18.04.06

The result will be a properly initialized ATmega, with protected bootloader and the default blink demo pre-loaded.

It’s not terribly fast because it uses a 19200 baud connection, but it’s simple and can be a life-saver if you ever damage the bootloader on an ATmega, or want to prepare blank ATmega’s for use with a JeeNode.

This plug can in fact be used as ISP programmer for any type of ATmega or ATtiny with “avrdude”:

Screen Shot 2010 04 18 at 18.14.42

You’ll need to adjust the serial / USB port, fuse settings, and sketch as needed, of course.

A mini scope

In Hardware, Software on Apr 22, 2010 at 00:01

Triggered by a discussion on the forums, here’s a little demo of how to build your own “Poor Man’s Scope”:

Screen Shot 2010 04 21 at 20.36.10

I connected an LDR between AIO1 and ground, and played around with light levels during this screen shot. The last samples were all over the map because I inadvertently touched the LDR leads.

All you need to reproduce this experiment is: an LDR, a JeeNode, and the JeeMon runtime. Oh, and the Arduino IDE to compile and upload a sketch to the JeeNode.

The sketch is adapted from the arduino-arduinoscope.pde demo. This is not nearly as fancy (or even flashy) as that Processing-based version, but it’s very easy to set up and get started with, IMO.

Anyway, here is the sketch running on the JeeNode:

Screen Shot 2010 04 21 at 20.44.32

It does a lot more than I’ll be using here, since I’m only picking up and displaying the first analog value, i.e. AIO1 on the JeeNode.

To get started with JeeMon, you could go read this page to get some background, but all you need really is the executable, so you can just download the appropriate one: for Windows, Mac, or Linux.

Then:

  • unpack the ZIP file, so you end up with a “JeeMon” executable
  • create a directory called “JeeMon-rigs”
  • in that directory, create a file called “application.tcl” (contents shown below)
  • adjust the serial port of the JeeNode to your setup (look at the top of application.tcl)
  • launch JeeMon, and you should get the real-time scope display shown above

Here is the application.tcl file, written in Tcl and using the built-in Tk GUI subsystem for visual display:

Screen Shot 2010 04 21 at 20.53.36

I’ve sprinkled some comments in the code. There are a fair number of pesky little details (as in all programming languages), but even without knowledge of Tcl/Tk you should be able to more or less see what’s going on.

There’s a lot one could improve or add to this thing. There always is. This is just a starting point.

But there you go: a Poor Man’s Scope in less than 100 lines of JeeNode sketch + JeeMon rig code. Fun!

More OOK decoders

In Software on Apr 19, 2010 at 00:01

O(o)k … so there are now several decoders for OOK transmissions: 3 for 433 MHz and 4 for 868 MHz:

Screen Shot 2010 04 15 at 10.36.43

Sample output:

Screen Shot 2010 04 14 at 23.20.21

The code is here now here. It has been set up as an Arduino sketch, but the decoder logic is not Arduino-specific, nor even ATmega-specific in fact. The sketch compiles to under 5 Kb, leaving plenty of room for future extensions.

All that is needed is to call the decoders with pulse widths in microseconds. They all run in parallel, but normally at most one will succeed for any given pattern of pulses. The actual decoding completion happens during the final long pulse (2000 µs or more, in most decoders).

Here is the rest of the sketch, which drives the decoder from pulses measured in an interrupt routine:

Screen Shot 2010 04 15 at 10.36.58

Note that there is something odd in this code: all the decoders are fed the same pulses! In real use, separate receivers will need to be connected for 433 Mhz and 868 Mhz, and then pulses fed to the appropriate decoders only. The reason I did it this way was for testing: I can simply replace the OOK receiver with whatever I’m currently trying out to see if it works – no reset needed.

So that’s it for now: 7 decoders, capable of decoding packets from several dozen different types of sensors and transmitters.

The data is reported as a set of hex nibbles, which need to be separated into the specific bit patterns for each type of packet. Also, checksums still need to be verified, to weed out any remaining false positives.

But that’s another topic, for another day.

Note – the RFM12B receiver cannot receive OOK signals. I hooked up extra hardware to make the above work.

Picking up RF noise

In Hardware on Apr 14, 2010 at 00:01

In yesterday’s OOK scope, there were many pulses at around 880 µs and 1100 µs which I couldn’t explain:

Screen Shot 2010 04 11 at 152609

Here’s another graph from new readings, same sketch, same ELV 868 MHz receiver:

Screen Shot 2010 04 11 at 16.39.16

That’s clearly much better. The difference? It’s all about how you hook up the RF receiver!

This was used during the first set of readings:

Dsc 1337

And this was used for that second graph:

Dsc 1336

So the receiver is picking up a lot more noise from the Carrier Board!

It’s not that surprising, in hindsight – the Carrier Board has a lot of traces running all over it it to hook up the numerous different signals on the board.

Note also that it took 20% less time to pick up the roughly 1,000,000 pulses for that second graph. My hunch is that the receiver’s AGC is ending up being set more sensitive without the spurious noise picked up from the circuit next to the OOK receiver.

Anyway, that’s one mystery solved.

Is the Carrier Board a bad idea? Not so fast. Here’s the ELV 433 MHz receiver, plugged directly into a JeeNode:

Screen Shot 2010 04 11 at 17.19.58

And here it is again, with a Carrier Board between receiver and JeeNode:

Screen Shot 2010 04 11 at 17.28.43

So at 433 MHz, it’s now attenuating the noise from the JeeNode.

Unfortunately, it gets even more confusing: look how few pulses the 433 MHz Conrad receiver picks up when plugged directly into a JeeNode during the same amount of time:

Screen Shot 2010 04 11 at 17.38.21

I’m inclined to go with the Conrad receiver for testing BTW, since it seems to pick up all the important pulses. Much simpler to debug with less noise!

Looks like I’ll have to be real careful while comparing results and drawing conclusions. And use some sort of ground plane or shield in the final setup.

An OOK Scope

In Software on Apr 13, 2010 at 00:01

Using yesterday’s OOK plugs, I wanted to get a feel for what sort of RF pulses are flying around here at Jee Labs. It’s a first step to picking up that data and trying to decode some of it.

Meet the OOK Scope, a sketch which reports every pulse it receives over the serial port, and a matching Tcl/Tk script for JeeMon to display the results graphically, and in real time.

Here’s the “ookScope.pde” sketch:

Screen Shot 2010 04 11 at 14.17.41

The analog comparator is used to generate interrupts on each transition of the input signal across the 1.1V bandgap reference voltage (the digital pin-change interrupt would also have worked – I’ve use both in the past).

One byte of data is sent over the serial port for each transition, containing the elapsed time since the previous one.

Note that the serial port can easily become a bottleneck for all these pulses: at 57600 baud, it can “only” report some 5700 pulses per second, so rapid pulse trains under 170 µs or so will hit the serial port bandwidth limit.

Reporting pulse lengths with 2 bytes of data would halve this bandwidth, so a trick is used to be able to report pulse lengths from 20 µs to over 3 ms using a single byte of data. It works by encoding large values more coarsely, sort of like a poor man’s logarithm:

  • pulses are measured at 4 µs resolution, using the Arduino micros() function
  • pulses of 20 µs or less are ignored, they are simply too short to deal with
  • 24..508 µs pulses are reported as byte values 6 .. 127 (4 µs granularity)
  • 512..1020 µs pulses are reported as values 128 .. 191 (8 µs granularity)
  • 1024..1532 µs pulses are reported as values 191 .. 223 (16 µs granularity)
  • 1536..2044 µs pulses are reported as values 224 .. 239 (32 µs granularity)
  • 2048..2556 µs pulses are reported as values 240 .. 247 (64 µs granularity)
  • 2560..3068 µs pulses are reported as values 248 .. 251 (128 µs granularity)
  • 3072..4604 µs pulses are reported as values 252 .. 255 (256 µs granularity)
  • all longer pulses are also reported as value 255

In other words: short pulses get reported fairly precisily, longer ones less so.

Due to the way AGC (Automatic Gain Control) works, most receivers will end up constantly generating pulses, because the gain is adjusted continuously until something is detected, whether actual RF signals or noise.

So this sketch tends to generate a huge amount of data over the serial port. In my case, I’m usually seeing over 2000 bytes of data per second coming in.

That’s a lot of bytes. Trying to make sense of it is not trivial – needles and haystacks come to mind …

So let’s just start by plotting the frequency with which pulses of different durations come in. This is an excellent task for JeeMon, with its built in Tk graphical user interface.

Here’s a first plot, based on some 1,000,000 samples:

Screen Shot 2010 04 11 at 15.34.35

The shortest pulses are represented by the lines at the top (i.e. starting at 24 µs), the longest ones are lines furher down. The width of the lines is the number of times such pulse lengths were received. The whole graph is scaled to fit horizontally, with some statistics showing in the window title.

Every 10th pulse width is marked in blue. Every 100th is marked in red.

Note that these are condensed values, as listed above. The “widths” are shown as values 5..255 on the vertical axis.

What the graph shows, is essentially noise. There’s a gradual decrease in pulse widths, i.e. short noise pulses are more frequent than longer noise pulses.

There is a very surprising peak of pulse lengths around 880 µs – I haven’t figured out where they are coming from, but that’s clearly not noise.

Let’s change the graph by switching to a logarithmic scale on the horizontal axis from now on (note that the vertical scale is sort of logarithmic as well, due to the above encoding). Here’s the logarithmic version, from roughly 1,000,000 samples:

Screen Shot 2010 04 11 at 15.26.09

Interesting: there’s another source of pulses around 1100 µs – again, no idea where those come from.

Here’s a graph where I held down a button on an FS20 remote control:

Screen Shot 2010 04 11 at 15.44.50

Sure enough – peaks around 380 µs, 412 µs, and 584 µs. The FS20 protocol works with 400 and 600 µs pulses – the variations are probably due to skew in the receiver, with different skews depending on the length of the preceding pulse.

Here’s the Visonic “fingerprint”, also on 868 MHz:

Screen Shot 2010 04 11 at 16.05.53

Let’s try the 433 MHz band now – a nice clean histogram using the ELV 433 MHz OOK receiver:

Screen Shot 2010 04 11 at 15.14.58

And here’s one using the Conrad 433 MHz OOK receiver:

Screen Shot 2010 04 11 at 15.12.35

Odd, there’s a blind spot in there. Also, the Conrad receiver reports only 1/10th the number of pulses reported by the ELV receiver. Either it’s filtering out noise much better, or it’s simply a lot less sensitive!

The ookScope code (sketch and Tcl/Tk script) can be found here.

Closing in …

In Hardware on Apr 11, 2010 at 00:01

The first Carrier Boards and Carrier Cards have come in, as described a few weeks ago on this weblog:

Dsc 1309

The Carrier Board is sort of a chameleon, given all the options it has for connecting stuff together:

Dsc 1329

You’re not supposed to use all those options at the same time, although you could if you really want to:

Dsc 1313

On the back you can plug in either a JeeNode, a JeeNode USB, or a JeeSMD as “processing engine”. Here’s a JeeNode USB:

Dsc 1315

As you can see, the USB connector will fall inside the case when plugged in this way, e.g. when you don’t use it, or to hook up a cable permanently.

Or… you can turn the board around, and make a cutout in the case to access the USB jack from the outside:

Dsc 1316

Wanna see how much you can cram into a box? Here’s a first attempt, with still some room to spare:

Dsc 1323

One more feature worth mentioning, is that there are pads and holes for an SMD-type DC jack. Here’s the jack soldered on, with a JeeSMD plugged in (the “+” end needs to be wired up manually):

Dsc 1325

Lots of options with all this. Great, now I can start working out some projects which need an enclosure.

There is one issue with the Carrier Board, alas … It turns out that the RX/TX pins on the FTDI connector (top right, first picture) were accidentally reversed. So this board doesn’t work with a USB-BUB out of the box.

That’s ok, though. I only had five of these prototypes made – just enough to try them out. Will fix it before ordering more boards for the shop.

It’ll take some time, but it’ll all work out nicely in the end, I expect.

Debugging with LEDs

In AVR on Apr 10, 2010 at 00:01

There was a problem in the RF12 driver with startup, with hard-to-reproduce behavior, unfortunately. I couldn’t make heads or tails of it, until more details started coming in via the Jee Labs forumlong live open source!

The problem, as originally identified: sketches don’t start reliably, when power is applied through batteries.

The diagnosis: it’s not related to battery power, it’s due to the RFM12B staying in some sort of “powering-up” limbo mode for several seconds.

Trouble with this sort of problems is that they can be very hard to reproduce, and even harder to debug. It all happens at startup, before any comms with the outside world is possible, and what’s worse: sending out some debug bytes over the serial port may affect the problem, due to the time it takes to do so, or the interrupts taking place, or even RAM memory being changed by the debugging.

They’re called Heisenbugs, and they’re the worst…

In this case, the breakthrough came when I had a “reliably failing” setup: running the lcd_demo.pde sketch and inserting a call to rf12_config() was enough to get a hang after each power-up. Good – now I can chase this bug!

In this case, there was an LCD hooked up, but it gets initialized after the rf12_config() call. All I wanted to know at first, is where the code hangs.

Time for the LED debugger:

Dsc 1331

Two LEDs, inserted in an unused port. Both with 1 kΩ current limiting resistors in series (470 Ω would be brighter). One between DIO and GND, the other between +3V and AIO.

The code to init this is quite simple:

pinMode(5, OUTPUT);
digitalWrite(5, 0);
pinMode(15, OUTPUT);
digitalWrite(15, 1);

I used port 2, i.e. DIO = Arduino pin 5 and AIO = Arduino pin 15. Due to the way these LEDs are connected, the one on the left will light when DIO is set high and the one on the right will light when AIO is set low. The above code starts with both LEDs off.

Now, all I have to do is turn DIO on at the start, and move the code to turn it off further and further into the initalization code:

digitalWrite(5, 1);
rf12_config();
digitalWrite(5, 0);

As expected, the LED never turns off again – rf12_config is going haywire.

Then I tried simplifying, replacing rf12_confg() by a call to rf12_intialize(). Same outcome: hangs. So it’s not the EEPROM code.

Tried out several things: delays, sending stuff to the RFM12B driver to try and initialize it better, or even twice – no difference: stil hangs.

Hm. The RF12 driver uses interrupts. Maybe it’s in there (yuck, even harder to debug). I called rf12_inititalize() with 0 as first arg, so attachInterrupt() would not be called – and bingo … no more hang.

So the RFM12B is generating interrupts, at a point when I don’t expect it: i.e. right after initialization. Interrupts should only happen when sending out data bytes (TX FIFO empty) or when receiving them (RX FIFO full).

To make a long story short: the RFM12B is pulling the IRQ line low for some eight seconds after power up. Since the IRQ line is set up as a level interrupt, that means it’s generating interrupts all the time!

No matter what I tried, I couldn’t make the RFM12B stop generating interrupts. But then, after about 8 seconds, it ended up going high and all was fine. Go figure.

So now I’ve added a loop which waits and polls the RFM12B in the init code, until it stops pulling IRQ low. On power up, that takes around 8 seconds. On reset, there is no wait. This should fix the remaining issue reported with hanging of JeeNodes, battery-powered or otherwise, i.e. any scenario which doesn’t use resets to restart the ATmega when the RFM12B is ready. If this affected you, get the latest code and re-compile / upload your sketch.

In hindsight, I’m surprised it worked before this fix!

Case closed. One more victory over bits and silicon. Onwards!

The JeeNode USB v3 has arrived

In Hardware on Apr 9, 2010 at 00:01

Well, I finally got around to finishing the details (ehm… at least some) of the new JeeNode USB v3.

I’ve added it to the Shop, replacing the older JeeNode USB v2. Starting now, all JU’s sent out will be v3’s.

As you may recall, the main reason for bringing out a new version was because the v2 model had the 3.3V on-board regulator mounting messed up, requiring manual fixes to be made for each unit.

The new v3 board has the regulator mounted correctly. Here is a list of all the differences, since a new run gave me the opportunity to do a bit more:

  • The 3.3V regulator is now also used to supply power to the ATmega and RFM12B. This improves ADC accuracy, since running the ATmega off the FTDI regulator and bringing out 3.3V from another regulator isn’t really a good idea.

  • The RFM12B has been moved to the side a bit, to make room for a pad with hole to solder the antenna wire to. Less risk of it breaking off during use.

  • The board length has been increased (80.7 mm vs 79.8 mm) so the RFM12B no longer sticks out.

  • The USB jack has been moved out a bit, so now it sticks out. This will be more convenient when mounting the board flush against the outer wall of some enclosure.

  • There is now an on-board MAX1555 Lithium Polymer battery charge chip on board, as well as an orange LED, which lights up while the circuit is charging.

  • As a result, the PWR pins brought out on the port headers, etc, will now be at 4.2V instead of 5V, while plugged into USB. When on battery power, it will be whatever the battery supplies. You can still connect other types of batteries to the PWR pin to power the unit, as long as their voltage does not exceed 5V!

  • The on-board FTDI chip used for USB comms will be unpowered while running off batteries, to lower power consumption (it draws a few mA).

  • There is an on-board voltage divider connected to PWR, so that the ATmega can monitor the current battery voltage level. This is a high-impedance divider.

Oh, and since I got bored with just fixing things, I decided to throw a fresh bug into the mix ;)

The current boards have some incorrect silkscreen labels:

Juv 3 Silkscreen Errors

Just ignore ’em. The P1 / P2 / P3 / P4 labels are the proper ones. FWIW: this was caused by panelizing this board in EAGLE without moving the labels out of the NAME layer. Probably a common (beginner’s?) mistake.

Anyway, I’ll get new boards made once my small initial batch runs out. Speaking of batches… I’ve now got lots of obsolete “JeeNode USB v2” pcb’s :(

Comes with the territory, I guess: bugs in the atom world lead to REAL junk!

Demo remote LCD

In Hardware, Software on Apr 6, 2010 at 00:01

It’s hard for me to realize just how confusing all this Jee stuff can be, and it’s certainly good to be reminded of that once in a while. Not everything makes sense for people who aren’t immersed into all this every day.

I want to improve that. In fact, it’s the main reason I’ve been chasing around in search of a good forum + wiki setup. As it stands, I’m hesitant to start writing down lots of things and, eh… yes, documenting all this Jee stuff. But this will change. Promise.

For starters, some good news on the forum + wiki front: I’ve decided to standardize on Markdown as formatting language. It’s ancient (i.e. proven), it’s clean, and with just one or two extras it will be good enough for most of the things I need. The reason I’m bringing it up here, is that I’ve just finished converting all the wiki pages to Markdown, as well as 90% of the current Jee Labs documentation pages. The forum remains bbForum, but it has now been adjusted to use Markdown formatting as well. So has WordPress. In fact, this is the first weblog post written in Markdown (in Textmate, my favorite text editor).

Yeay for one set of conventions, and yeay again for simplicity!

Ok, back to the main topic of this post.

Here’s a demonstration on how to send a text string to a remote LCD via wireless JeeNodes. This is the hardware I’m going to use for that remote LCD node:

  • a JeeNode USB
  • an LCD Plug with 2×16 LCD display
  • one extension cable
  • plus a hookup to USB to power this whole thing

Dsc 1300

Ok let’s set up a simple demo sketch for the remote receiver end (code here):

Screen Shot 2010 04 05 at 20.09.58

Very simple, really: wait for an incoming packet and display the bytes as characters on the LCD. Plus some initialization code.

On the sender end, I’m using a JeeLink running the pre-loaded “RF12demo” sketch:

Dsc 1302

First step is to put the JeeLink in the right mode:

8b 4g 1i

That’s the 868 MHz band, group 4, node ID 1.

Now we can send a message to node 9, which is running the remoteLCD sketch, by sending a packet with the individual character codes to the JeeLink (the “9” at the end is the destination node ID):

84,101,115,116,32,49,50,51,9s

The result:

Dsc 1305

Yippie. No wires. Magic! :)

Stencil Jigs

In Hardware on Apr 4, 2010 at 00:01

Ok, I’ve prepared a couple more Stencil Jigs for applying solder paste:

DSC_1297.jpg

Here’s one in more detail:

DSC_1298.jpg

Basic idea is that a couple of scrap PCB pieces are hot-glued to an A5-sized piece of foam board to keep the panel in a fixed spot. Then add the stencil and fix it to the jig in exactly the right spot.

The placement of components is still a manual task, and quite a precision job for some of the latest boards, but by now my daughter and I are starting to get quite good at it – yep, it’s become a family thing :)

The new jigs will speed up production of the ever-growing Jee Labs collection of JeePlugs and other boards!

After-burner

In AVR, Hardware on Apr 3, 2010 at 00:01

To reply to a comment posted yesterday, this is the contraption I use to re-flash a JeeNode or JeeLink after the fact via its ISP connector:

DSC_1295.jpg

It has two diodes, dropping the incoming 5V power from the programmer to around 3.8V – this turns out to be needed in the case of JeeLinks, which has the VCC pin on the ISP header connected to 5V instead of the 3.3V driving the ATmega. The high voltage was causing problems with logic signal levels.

The other component on the board is a 100 µF capacitor, to reduce voltage fluctuations (it.s probably superfluous, I added it while debugging the setup).

Here’s this “after burner” in action:

DSC_1296.jpg

The long pins are at an angle, because that way they can be gently pressed into the holes and they will stay there during programming.

Like most hacks, it looks awful, but it works pretty well!

AVRISP mkII w/ 5V power

In AVR on Apr 2, 2010 at 00:01

I’ve been using the USBtinyISP AVR programmer for some time now, to set the fuses, burn the boot loader, and burn the RF12demo.pde compiled sketch into each ATmega.

Trouble is, it’s slow as molasses …

So I got the AVRISP mkII programmer a while back, but the problem is that it’s unpowered. Not good for my setup, which expects power from the USB programmer:

2937E56E-F019-4E55-99F4-60B1B15111DB.jpg

So I went looking around for tips on how to bring 5V to pin 2 of the 6-pin ISP connector. Found this mod which uses a 5-to-3.3V regulator, and this one which draws 5V directly from the board.

I decided to tap the 5V USB power, but after the polyfuse, so that a short won’t damage the computer or USB hub as easily:

DSC_1294.jpg

The connection is jumpered, so this can still be used in its original form when needed.

And then I spent ages chasing ghosts…

It turns out that avrdude needs a “-B 3” time adjustment to reliably program the chips. Now how am I supposed to know that!

Anyway, here’s the shell script I’m currently using on my old PowerBook, which automates it all:

Screen shot 2010-04-01 at 23.08.28.png

That last character being echoed is a CTRL+G, i.e. an audible bell to signal when the process is done. It used to be essential, since the USBtinyISP took so much time for each burn. Now, it’s clocking in at 17 seconds, and that could probably be reduced even further by combining the three separate avrdude runs.

A roughly 10-fold improvement!

New stencil is in

In Hardware on Apr 1, 2010 at 00:01

Just received the new solder paste stencil from Pololu, it’s laser-cut from 3 mil mylar sheet:

DSC_1293.jpg

Great, once all the parts are in I can try out the new JeeNode USB v3 boards and start “baking” a couple!

Improved carrier board

In Hardware on Mar 28, 2010 at 00:01

Two weeks ago, I posted a note about a new enclosure and carrier board design to mount a JeeNode inside.

This led to several (virtual) experiments, to figure out how it would work out in different usage scenarios. One of the main problems remaining was that the design was not suited for a JeeNode USB, because the USB connector would have been inside the case – not perfect…

Here’s an improved design, which has been sent off to create a first prototype:

Screen shot 2010-03-27 at 21.23.13.png

The main change is that this allows using either a JeeNode with FTDI connector or a JeeNode USB. This was accomplished by moving the connectors around a bit, which urned out to be fairly tricky due to the huge number of interconnections.

The new trick is that this carrier board can now be used with two different JeeNode orientations. By attaching it one way, the FTDI or USB connector will end up inside the box, while turning it around 180° will put those connectors on the left side, almost sticking out. Just right to access it through a cutout.

Two other improvements over the previous design are that the carrier board includes connectors positioned in such a way that they will accept a Room Board, and the presence of an extra FTDI connector.

As before the bottom row of five 6-pin headers gives access to all signals of the JeeNode. Plugs can be attached in many different ways, supporting lots of combinations, with room for a variety of other components.

Battery level on JeeNode USB

In Hardware on Mar 26, 2010 at 00:01

The new JeeNode USB v3 includes a resistor divider to track the voltage level before the voltage regulator. This signal is connected to the otherwise-unused A6 input of the ATmega328 SMD chip.

Here’s a little sketch to see what it does:

Screen shot 2010-03-24 at 01.02.16.png

In prose: read out analog pin 6 once a second, and broadcast the measured value as wireless data packet on netgroup 2. The readings are also sent to the serial port.

Since a 1:2 voltage divider is used, the full-scale of the ADC (i.e. 3.3V in) is 6.6V, a value which can never be reached on the JeeNode USB. The map() function is used to scale this back to an integer in the range 0..660, i.e. hundredths of a volt.

Here is the serial output while connected:

Screen shot 2010-03-24 at 01.04.19.png

This is exactly as expected: the LiPo charger outputs 4.2 Volt when no battery is connected, which then goes into the on-board voltage regulator.

Here’s the serial output when a fully charged LiPo battery is connected (still plugged into USB):

Screen shot 2010-03-24 at 01.04.36.png

Again as expected: the battery pulls down the voltage slightly to 4.17 Volt.

But the interesting bit of course is when unplugging the USB cable. That’s why the RF part was included in this example: we can’t use the serial port anymore, and have to pick up the packets with a second JeeNode or JeeLink.

Sample output:

Screen shot 2010-03-24 at 00.52.51.png

That’s two bytes in each packet, forming a little-endian 16-bit int. The corresponding value is 161 + 256 * 1 = 417. The battery is still charged, so we’re still getting the same 4.17 Volt readout.

By leaving this sketch running on the LiPo battery for a while, it will slowly discharge. Output after one hour:

Screen shot 2010-03-24 at 01.27.15.png

Not much difference: 4.16 Volt.

Here’s a different LiPo battery which has been lying around unused for several months:

Screen shot 2010-03-24 at 01.24.23.png

Still a very respectable 126 + 256 * 1, i.e. 3.82 Volt!

So there you go. The node can run off a LiPo battery, and track its charge state. This could be used to power down the node when the voltage becomes critically low – perhaps 3V or so. LiPo’s don’t like being run down completely, and this is how a node can avoid doing so.

You may be wondering why the voltage readings were not immediately stable on startup, as seen in the first two output screens. Even if restarted, this same behavior will be observed, i.e. even if there was no power dip.

I think this is due to the fact that two very high impedance 1 MΩ resistors are being used for the voltage divider. These cannot supply a lot of current, which means the input charge for the ADC’s sample-and-hold isn’t being built up quickly enough. This will probably happen each time the ADC is switched over from another channel.

But there is a good reason for this: with 1 MΩ resistors, the leakage from this voltage divider is only 2 µA. For a battery-powered application, where every constant current drain affects its total lifetime, this matters.

Heading Board

In Hardware, Software on Mar 24, 2010 at 00:01

Another new plug: the Heading Board.

This one is a pretty odd combination: a 2-axis compass, a barometric pressure sensor, and a thermometer:

DSC_1266.jpg

It’s based on the HDPM01 module by HopeRF, and the board underneath is just to re-route the pins to the proper headers. As you can see, it barely fits.

Note that this board requires two port headers and sits on top of a JeeNode in the same way as a Room Board. This is necessary, even though the sensor uses I2C, because it also needs two more signal lines: a XCLR control signal, and a 32 KHz clock, i.e. 4 I/I pins in all.

The clock signal is tied to the IRQ line, because this is also the OC2B timer 2 output. So this board ties up timer 2 to generate a 32800 Hz clock, and it interferes with using the IRQ pin (which is shared by all port headers). Furthermore, one of the AIO pins is unused. So it’s a slightly odd fit for the JeeNode, really. Oh, well… soit.

Now let’s try it out.

There’s a new HeadingClass in the Ports library, which handles all the basic logic to access this board.

Here’s the heading_demo.pde sketch to read out the temperature and pressure sensor:

Screen shot 2010-03-22 at 23.58.36.png

Very simple stuff, given that most of the code is in the HeadingPort class.

Sample output:

Screen shot 2010-03-22 at 23.58.24.png

I’m not convinced of the accuracy of these sensors. Both the temperature and the pressure values vary a bit, and differ about 0.5% from the readings I see on the Pressure Plug.

Tomorrow, you’ll see why this is called a Heading Board!

Meet the JeeNode USB v3

In AVR, Hardware on Mar 19, 2010 at 00:01

Just got a couple of new boards back (this was an experiment, expediting some of the boards to get them several days ahead of the rest of this prototype batch).

Meet the new JeeNode USB v3 (this unit was soldered by hand – phew!):

DSC_1248.jpg

As you may know, the main reason for this revision was to resolve a problem with the voltage regulator, but since I had to rework the design anyway I also added a LiPo charge circuit.

The good news is that everything seems to work fine so far. There are some cosmetic problems with this board, but no show stoppers.

And of course the big deal is being able to hook up a Lithium Polymer (LiPo) battery:

DSC_1249.jpg

There is an extra LED in the corner, left of the USB jack, which will be orange (once I get them in). It lights up while charging. The charge current is max 280 mA, so this board won’t draw more than that from USB.

Without LiPo connected, the current still goes through the charge circuit, so another major change is that the PWR pin on all the headers of this board never carries more than 4.2V – don’t use the JeeNode USB if you need 5V in your circuit (use a JeeNode + USB-BUB if you really need the 5V).

Two BIG honking warnings, since LiPo batteries can be quite dangerous: one is that they need to be charged with the proper circuitry, such as on this new board, so don’t hook ’em up any other way. The other issue to keep in mind at all times, is that LiPo’s can discharge at a very high rate! That “20C” label above means that this particular little battery is rated to sustain a discharge @ 20 x 450 mA = 9 amps!

You can probably cause a fire with those wires shown above, by simply shorting out a fully charged battery!

And you will probably fry the circuit and vaporize PCB traces by connecting the battery in reverse!

I’m exploring some options to reduce these risks. Hard-wiring the LiPo would be one way to reduce the chance of loose wires shorting out something. Perhaps a small custom PCB glued to the battery, with a fuse or polyfuse and a switch, wrapped in heat-shrink tubing? The trouble is that battery sizes and capacities vary greatly.

Some first tests w.r.t. power consumption: it looks like the JeeNode USB v3 will draw about 120 µA when in sleep mode. With the above 450 mAh battery, it would last up to 5 months without recharging (and without doing anything useful, such as turning on the radio module once in a while). There’s probably still some room for improvement here, but for now it’ll have to do.

FWIW, I’m going to hand-assemble a few of these boards in the coming weeks, but unfortunately that means there won’t be many v3 units available in the shop, initially. I’m also having solder paste stencils made up right now. Once these are in, the new boards will be much easier to assemble – using the reflow grill that gets a lot of work done here at Jee Labs.

Meet the JeeSMD kit

In AVR, Hardware on Mar 18, 2010 at 00:01

Meet the new kid kit in the Jee family – the JeeSMD !

DSC_1246.jpg

At a glance:

  • Same pinout as a JeeNode – same 4 port headers, same PWR/SER/I2C, same SPI/ISP
  • No wireless, no FTDI, just an ATmega328 – all SMD (32-TQFP, SOT-23, and 0603)
  • Two extra pins on the right side (allocated to the RFM12B module on JeeNodes)
  • Has a 3.3V regulator, a 16 MHz resonator, and four passive components

What’s the point? Well, it’s going to be made available as an SMD kit, and it’s going to be low-cost. If you don’t care about wireless or FTDI, then this is a convenient and compact way to hook up some Jee Labs plugs.

Of course, all the other stuff fits as before, including the Proto Board, for example:

DSC_1247.jpg

Here’s the board in more detail:

DSC_1243.jpg

(don’t look too closely at this prototype PCB – there are some silly cosmetic mistakes…)

There are some trade-offs w.r.t. JeeNodes:

  • No FTDI on board – you have to either add the equivalent connections yourself via the left and right headers plus a 0.1µF cap, or use ISP for flashing the ATmega328 chip
  • No wireless, so this isn’t a “node” in the usual sense – just a tiny Arduino’ish board
  • It’s all SMD, so if you want to practice soldering SMD by hand – this is one way to get started!

I’ve got a few boards for people who want to get their hands on them. The kits will be ready in about a week.

Now the JeeSMD kit needs a detailed set of instructions and close-up shots on how to assemble and start using it – more work to do!

Software- and hardware-I2C

In Software on Mar 15, 2010 at 00:01

Until now, the Ports library supported software I2C on the 4 “ports”, whereas hardware I2C required the Arduino’s Wire library. The unfortunate bit is that the API for these two libraries is slightly different (the Ports library uses a slightly more OO design).

See the difference in resulting code with and without Plug shield, for example.

Triggered by an idea on the forum, I decided to extend the Ports library, so that “port 0” gets redirected to Analog 4 (PC4) and Analog 5 (PC5), i.e. the hardware SDA/SCL pins on an ATmega.

So now you can use the Plug Shield with the same code based on the PortI2C class as with JeeNodes. Simply specify port zero when using this with an Arduino and a Plug Shield!

Here’s the Arduino example again, which no longer requires the Wire library:

Screen shot 2010-03-13 at 19.27.28.png

Note the use of port 0 to connect to hardware I2C pins.

The benefit is that all plugs for which code exists based on the Ports library (Pressure, UART, LCD, etc) can now be used on an Arduino with a Plug Shield.

A nice extra is that this will also work on an Arduino Mega, without requiring two extra patch cables to hook up to the hardware I2C pins.

Long live simplicity!

Carrier Board

In Hardware on Mar 14, 2010 at 00:01

Yesterday’s enclosure has started a new ball rolling…

I’ve decided to support a mix of plugs with room for prototyping. A first mockup:

DSC_1231.jpg

This will be made possible by a new Carrier Board with tons of different ways to connect to:

jlpcb-088.png

Ports 1 and 4 each have four positions for adding plugs. All connected in parallel, so you can hook up more than one if you’re using a bus such as I2C on that port. Note the big dots, identifying the PWR pins for orientation.

Ports 2 and 3 can be plugged in, but their pins are also brought out to a series of 6-pin headers in the bottom right. These 18 pins bring out everything else, including full SPI, hardware I2C, and the serial I/O lines.

Lastly, the SPI/ISP and the PWR/SER/I2C connectors from the JeeNode have been duplicated.

Note that you can also ignore all that plug stuff and just insert your own board into the entire bottom row, using five 6-pin headers. That gives you access to all the pins on a JeeNode. Here’s a board I’m going to try out:

jlpcb-089.png

There’s a split down that board, to allowing breaking off and using either side independently. The left side is essentially a dual JeePlug and will fit in all the 2-port positions on the Carrier Board.

These boards will be included in the next round of PCBs. We’re back to the “Patience, grasshopper!” part…

JeeNode enclosure

In Hardware on Mar 13, 2010 at 00:01

At last! – Here’s a fantastic enclosure for the JeeNode:

DSC_1229.jpg

The plugs are just one possible orientation, they will also fit sideways, i.e. stacked on their side like the JeeNode in there. No screws, no glue – this just needs a PCB of the right size – or as in this case: perf-board with some male headers to connect to the JeeNode ports.

The whole box clicks together with the other side, which has exactly the same shape:

DSC_1230.jpg

Available in light gray and in black from Dick Best in the Netherlands.

I’ll look into adding this enclosure option to the shop.

Xanura CTX15

In Hardware, Software on Mar 9, 2010 at 00:01

Another popular home automation module is the Xanura CTX15:

DSC_1228.jpg

That’s a live 220V power-line connection in the top right corner!

I’ve connected the CTX15 module through a UART Plug, with a 4.7 kΩ resistor in series with the RX signal (yellow from CTX15). This is because the signal swings up to 5V, whereas the UART plug only accepts 3.3V voltage levels. The module is powered from the PWR pin, which on a JeeNode USB carries 5V.

The CTX15 is a bi-directional interface, it can send as well as receive A10-type power-line commands (a superset of X10). The trouble is that it needs to be polled to read out what has been received and buffered so far.

Here’s a sketch which takes care of that:

Screen shot 2010-03-08 at 12.08.53.png

And here’s some sample output:

Screen shot 2010-03-08 at 12.08.40.png

As a test, I powered up yesterday’s XM10E test setup as well, to send out on and off commands to unit A.1 every 3 seconds. As you can see with the CTX being read out every 5 seconds, multiple received packets will sometimes be combined and returned as one reply.

X10 control

In Uncategorized on Mar 8, 2010 at 00:01

Let’s go some more into home automation – the X10 power-line system in this case.

Here’s is a sketch which turns a remote appliance on and off every 3 seconds:

Screen shot 2010-03-07 at 23.06.56.png

I used the Arduino X10 library (had to mess around with the use of headers to get rid of compile errors, and enable the pull-up on the zero-crossing input).

This sketch runs @ 3.3V on a JeeNode with some stuff attached to port 1:

DSC_1224.jpg

It’s just a simple re-wiring to an RJ11 connector. This in turn, plugs into the XM10E opto-isolated interface:

DSC_1225.jpg

There’s also a X10 receiver built into the XM10E, which I’m going to ignore for now.

X10, in its simplest and oldest form, is a power-line transmission system, i.e. the signals to control a switch are sent over the same wires as the AC power itself (using a 120 KHz signal injected at the zero crossings). Proper mains isolation is essential, of course – as built into the XM10E unit.

The result is that you can plug this device into any outlet in the house and it’ll switch on and off as defined in the above sketch:

DSC_1226.jpg

It’s hard to miss – the relay built into that thing switches on and off with a very loud “clunk”!

The power consumption of this switch is 0.6 W off and 0.9 W when on, according to the Cost Control. Not bad, until you start installing many dozens of these switches around the house … then it will add up!

Fabrications

In Hardware on Feb 24, 2010 at 00:01

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

DSC_1203.jpg

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

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

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

Secure transmissions

In Software on Feb 23, 2010 at 00:01

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

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

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

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

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

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

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

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

Screen shot 2010-02-21 at 18.37.36.png

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

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

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

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

Screen shot 2010-02-21 at 22.42.27.png

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

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

Wireless works, sort of…

In Software on Feb 10, 2010 at 00:01

Ah, now we’re getting somewhere!

This is my current test setup:

Screen shot 2010-02-07 at 21.23.55.png

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

Screen shot 2010-02-08 at 01.02.16.png

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

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

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

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

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

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

Screen shot 2010-02-07 at 21.26.39.png

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

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

Connecting to a CupCake

In Software on Feb 9, 2010 at 00:01

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

Screen shot 2010-02-07 at 16.19.43.png

And sure enough, it works:

Screen shot 2010-02-07 at 16.08.55.png

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

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

Wireless CupCake

In Hardware on Feb 8, 2010 at 00:01

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

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

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

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

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

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

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

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

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

Here’s the idea:

DSC_1177.jpg

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

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

DSC_1178.jpg

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

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

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

Screen shot 2010-02-07 at 15.05.08.png

And here’s the corresponding output:

Screen shot 2010-02-07 at 15.04.35.png

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

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

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

Fascinating concurrency

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

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

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

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

Screen shot 2010-02-03 at 01.13.19.png

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

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

DSC_1167.jpg

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

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

B R I L L I A N T .

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

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

JeeNode USB v2 error!

In Hardware on Feb 3, 2010 at 00:01

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

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

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

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

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

Screen shot 2010-02-02 at 13.51.39.png

Here are the printed circuit board traces:

Screen shot 2010-02-02 at 14.39.16.png

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

DSC_0737.jpg

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

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

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

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

JU2 no VR.png

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

MCP flip.png

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

DSC_1164.jpg

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

DSC_1162.jpg

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

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

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

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

Room Board assembly

In Hardware on Feb 2, 2010 at 00:01

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

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

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

DSC_0980.jpg

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

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

DSC_0981.jpg

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

DSC_0982.jpg

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

DSC_0983.jpg

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

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

DSC_0984.jpg

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

DSC_0985.jpg

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

DSC_0986.jpg

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

DSC_0987.jpg

Next, we need to connect the boards together:

DSC_0988.jpg

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

DSC_0990.jpg

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

DSC_0991.jpg

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

DSC_0992.jpg

That’s it – you’re done!

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

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

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.

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.

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.

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.

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 :)

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.

JeeNodes and complexity

In Hardware, Software on Dec 29, 2009 at 00:01

In yesterday’s post, I commented on a couple of aspects of the Arduino world which are giving me some trouble.

Now it’s time to do the same for all this “JeeNode” and “JeePlug” stuff I’ve been working on in 2009. Because there too, there are some ugly edges, uncomfortable trade-offs, and unsolved issues.

Let me start by pointing out the obvious: the Arduino world and Jee Labs are totally and utterly incomparable in scale. In terms of number of people involved, money involved, business interests, variety, maturity, promotion, reach, ambition, … they really differ in every aspect you can think of.

Except technology: Arduino’s and JeeNodes both live in the space of Physical Computing. And JeeNodes are compatible to Arduino’s in terms of software and PC interfacing. That’s not so surprising, since I designed JN’s to get going as fast as possible with as few key changes as possible.

These key changes were:

  • Voltage levels – run at 3.3V to support more sensors and wireless
  • Hardware ports – multiple identical interface connectors
  • Hardware extension – I2C buses which allow daisy-chaining
  • Software – connector-independence through the “Ports” library
  • Physical shape – a much smaller RBBB-like form factor

Two key additions driving some of this were:

  • Wireless – built-in bi-directional wireless link
  • Low power – selecting all hardware so it can run off batteries

Because one major use for all this is remote battery-powered operation, a minimal PC interface was chosen (3.3V signals for use with an FTDI adapter).

So is all this Jee stuff merely about creating wireless nodes? Not really. That just happens to be my area of interest. Staying focused is good, and I definitely intend to stick to this for quite some time.

So far so good. I thought I had it all figured out.

Then reality – and complexity – set in. Here are a number of issues:

  • Connector choices – ports use 6-pin 0.1″ headers as connectors: cheap and widely available. Not polarized, so you can plug things in the wrong way (and you will) – it took a while, but it has been standardized, and the POF approach solves polarization where it matters most: during experimentation.
  • Library dependencies – the “Ports” and “RF12” (wireless) libraries have become inter-dependent, so you now have to include both of them all the time. As far as I can tell, this is not a software modularity issue but an Arduino IDE problem. This is starting to become a major inconvenience for small projects.
  • Class dependencies – classes such as “MilliTimer” are very small and self-contained but the more they get used, the more they lead to the above library dependency troubles. If adding modular and useful code leads to headaches, then something is definitely wrong.
  • Wireless functionality – a small driver takes care of packet reception and transmission in the background. It’s very low level but an easy transmission layer on top now adds robust communication for sensor networks. More convenience functions like these need to be added.
  • Multi-node development – it’s tedious to deal with multiple interfaces when more than one JN is plugged in, because USB interface names are meaningless. There is currently no way to auto-detect when a JN is plugged in or removed, let alone do something specific depending on what sketch that JN is running.
  • I2C ≠ I2C – ports support a software (bit-banged) I2C bus, but the ATmega also has pins which support hardware I2C. The underlying driver code is completely different. There is no generalized layer yet to hide these differences, so right now code written to use I2C plugs via the Ports library needs to be changed to work with hardware I2C and the Arduino’s “Wire” library. This must be fixed.
  • Ports vs. Plug Shield – due to the I2C differences described in the previous item, code written for ports on a JN needs to be adapted to work with the Plug Shield on an Arduino, and vice-versa. Tedious.
  • External power – the various power pins on a JN are all tied together, because the voltage drop of diodes would hamper ultra-low power use. That means you can’t hook up a JN to FTDI while a battery is tied to one of the other power pins (unless the battery has an on/off switch and you’re careful).

Some of the above issues have already been sorted out. Others can be addressed in future hardware designs. Some, such as “external power” are likely to remain as is for now. And some just need more or better software.

Adding or modifying software is easy. The hard part is avoiding restrictive decisions which have long-term consequences. Here’s the most challenging one: should I maintain 100% software compatibility with the Arduino world and benefit from all the shared knowledge already built up, or should I start off on a new journey and redo whatever is needed from scratch to reach a workable level again? I haven’t decided.

Screen shot 2009-12-28 at 00.33.52.png

When you hit a wall, do you look for a way around it or do you tear it down? Depends on the wall, I s’pose.

Carrier detection

In AVR, Software on Dec 26, 2009 at 00:01

Wireless communication is a complex process. The ISM bands used by the RFM12B module get used in various ways – some quite simplistic. For “serious” use, what you want is to avoid transmissions interfering with each other – which means at most one transmitter should be active at any given time for a specific frequency band.

Easier said than done. This is what CSMA/CA is all about. It’s quite similar to ethernet: you listen to the “ether” and wait until there is no carrier before starting to send yourself. If everyone does so, then there will be fewer “collisions” – i.e. messed up packets.

CSMA/CA isn’t perfect. It doesn’t scale all that well if there are lots of nodes, all trying to find a free slot to send their packets out. There is always a non-zero probability of collision, when two nodes decide at nearly the same time that there is no-one else transmitting. And then, BOOM! … as they say.

One solution for that is another acronym: TDMA. Basic idea: have all the nodes agree to only send in specific time slots allocated to them. This requires a central coordinator, as well as pretty accurately keeping track of time (which is non-trivial with RC-based watchdog timers for sleep modes used with low-power nodes!).

In the ISM band, at least the 868 MHz one used in Europe, a simpler solution is used: keep the air-waves more or less free. The rule is that each transmitting node should send no more than 1% of the time, on average. With one or two dozen nodes and a bit of randomness in timing, the idea is that collisions will be relatively rare.

I recently added the 1% rule to the easy transmission mechanism in the RF12 driver (for the 868 MHz band only). So with the rf12_easy…() calls, adhering to the 1% rule is now automatic.

The 1% rule is a very simple system, yet it works surprisingly well. I’ve got over a dozen nodes around the house, sending out packets whenever they feel like it. The off-the-shelf commercial weather station nodes I use are very simplistic – they just send, ignore collisions, and send new data again a minute or two later. Those nodes probably don’t even have receive capability.

The RFM12B transceiver module in the JeeNode is slightly more sophisticated, in that communication can take place in both directions. So the receiver can send back an “ack” packet, and the originating node will have some idea of whether its last data packet ever made it to the destination (note that ack’s can get lost as well – but that’s another story).

Still – the RF12 driver used in JeeNodes is just as careless as the other nodes: it starts sending the moment it feels like it – except if a packet for its own net group is currently being received. Sending packets with the RF12 driver can still easily mess up whatever is currently going on in the air.

Well, as of today, things will improve a bit further. I’ve extended the RF12 driver code to look at the RSSI status bit before starting to transmit. If a carrier is detected, even one that isn’t being recognized by the RFM12B, then transmission will be delayed a bit. Here is the latest code in the RF12.cpp driver:

Screen shot 2009-12-21 at 02.16.28.png

This isn’t perfect – nothing ever is – because most nodes will be polling very frequently and then start to send right after the carrier drops. So the chance increases that nodes two and three will both try sending when node one finishes. But let’s assume that the RSSI signal doesn’t drop to 0 for all nodes at exactly the same time. If that turns out to be insufficient, a timer-based exponential back-off mechanism can be added later.

And there is a substantial benefit: nodes will no longer mess up packets which are currently “on the air”. As more nodes are being added around here, I expect this change to cause less degradation due to collisions.

In summary: the RF12 driver is a very simple system. No CSMA/CA, no TDMA. There are definitely limits as to what it can be used for. There are some severe limits on how much data it can send, given that (on 868 MHz) each node can only send up to 1% of the time, but this is also why such a simple approach is actually quite effective. And why the RF12 driver is still just a few Kb on an 8-bit ATmega, leaving lots of room for application specific code. I happen to think that the RF12 approach strikes a pretty decent balance between simplicity and effectiveness – and I’m always open for suggestions on how to take this further.

OOK reception with RFM12B ?

In AVR, Software on Dec 25, 2009 at 00:01

Yesterday’s post described a setup to see the RSSI and DQD status bit reported by the RF12 driver in real time.

One of the interesting results is that I can see the RSSI light come on when pressing a button on the FS20 remote transmitter – even though that’s an OOK signal, not FSK!

When adjusted to run at 433 MHz, the RSSI indicator also lights up with the KAKU remote.

In both cases, the DQD signal appears useless – it just shimmers all the time.

The RSSI signal is encouraging, though. It turns out that getting it to blink reliably did depend on setting the threshold right. At -103 and -97 dBm, it was on all the time – only the -91 dBm value produced a usable signal. I hope that’s the case with all units.

Could this be used to receive FS20 or KAKU?

Well, I just had to try. My idea was to continuously poll the RSSI status bit and then “mirror” its value to a DIO output pin. Then use a second JeeNode to treat this as a normal OOK pulse train.

Here’s the “rssiMirror” sketch I used:

Screen shot 2009-12-20 at 17.07.34.png

Does it work? Unfortunately … no :(

Time to hook up the Logic Analyzer to see what’s going on. I connected the above digital output to the first channel, and a real OOK receiver on the second channel:

uuu.png

Guess what… the RSSI signal is indeed detecting the presence of a transmitted signal, but it’s way too slow!

Here’s the same sample, zoomed in on the real OOK pulse train:

ooo.png

As you can see, there’s a pretty good sequence of transitions, 400 µs and 600 µs apart. Oh well, so much for the RSSI status bit – it’s nice to detect the presence of a carrier, but not more than that.

Next thing I tried was the DQD signal. After tweaking the DQD threshold to 3, this is what came out:

eee.png

Yeah, sure, it seems to track the signal, but not reliably, and with a huge number of extra transitions. Note how the top timings are all multiples of 25 µs apart – that’s because it takes 25 µs to read out the DQD status bit. Coarse, but fine enough in principle to track 400 / 600 µs pulses from an FS20 remote.

So, again: nice, but no dice. Neither the RSSI nor the DQD status bits are fast and accurate enough to decode a slow OOK pulse train with.

Next attempt was to try and pick up the ARSSI signal, direct off the RFM12B module – as mentioned in this forum discussion. There’s a German forum which describes where to pick up that signal:

rfm01.JPG.jpeg

And sure enough, here’s a scope capture of an FS20 transmission:

www.png

Yeah, it’s there alright. But the signal is a bit weak. I’d rather not dedicate the analog comparator or ADC to it, and besides – that still leaves the need to compare against the average level – there’s a nasty 0.4V bias in that signal.

Here’s the same signal, AC coupled:

qqq.png

And here’s a zoomed-in area, showing what looks like pretty decent 400 µs and 600 µs pulses:

hhh.png

So yes, a small self-adjusting comparator can proabably turn this into a nice digital pulse train – but it’ll require some extra components, and I’m a bit out of my league on designing such a circuit.

Oh well – perhaps this information will help someone else further along. It’s been a good learning experience for me, even if the result is not quite what I had hoped…

Tomorrow, I’ll describe another – successful! – outcome from this RSSI / DQD exploration.

RF12 status lights

In Hardware, Software on Dec 24, 2009 at 00:01

Here is a little setup to see what’s going on in the ether, wirelessly speaking, that is:

FlySketchExport.png

Four LEDs, blinking according to the following status signals:

  • RECV – blinks briefly for each received packet
  • RSSI – shows the value of the RSSI bit in the RF12 status
  • DQD – shows the value of the DQD bit in the RF12 status
  • ALIVE – blinks at 1 Hz, just to show that this node is alive

I changed some thresholds to get better results: RSSI threshold -91 dBm and DQD set to 7 (normally -103 and 4, in the current RF12 driver).

Here is the sketch which drives the LEDs accordingly:

Screen shot 2009-12-20 at 16.05.18.png

In this example, I’ve set up the RF12 parameters to receive group 5 in the 868 MHz band.

The result is quite interesting: DQD is flashing constantly, in an irregular pattern. RSSI blinks only once in a while, and some of these cause RECV to light up – as expected: only packets with the proper FSK format are filtered out, and only some of those are for this specific net group.

The reason for doing this will become clear tomorrow…

Power tracker – software

In AVR, Software on Dec 22, 2009 at 00:01

Yesterday’s post described a small circuit to track power consumption of JeeNodes to help optimize sketches for minimal power consumption.

Let’s put that circuit to use, with a bit of software to measure actual power consumption. The basic idea is to continuously measure current and then integrate these measurements to determine the sum of all power consumption intervals, regardless of levels.

The reason for this is that we’re not really interested in current draw but in the amount of charge consumed by the JeeNode. As far as the battery is concerned, drawing 1 mA for 1 hour is the same as drawing 100 µA for 10 hours (in the ideal case, anyway). The fancy way to say this is that we need to measure Coulombs, not Amps. Or rather micro-Coulombs, i.e. µC. That’s really easy once you realize that 1 µA is the same as 1 µC per second. Or to put it differently again: 1 mAh = 3600 mC. So a 1000 mAh battery is really nothing but a 3600 C charge.

Ok, back to the problem at hand: measuring average current draw per second.

Here is a simple sketch which does all the auto-ranging and integration:

Screen shot 2009-12-19 at 19.34.25.png

It reports averaged power drain in µA/sec (the second value is the number of samples per second). The 10% correction which I had to apply in my setup could be due to a number of factors – most likely it’s due to resistor tolerances (they are all 5%).

Here’s an interesting case with the latest rooms node:

Screen shot 2009-12-19 at 20.01.21.png

As you can see, the baseline power drain is a fantastically low 56 µA/sec in this case, but once or twice a minute it goes up to 14 mA/sec for several seconds. Not sure what’s going in here – need to investigate (now that I can!).

It would be nice to automatically detect the baseline, i.e. the average low-level sleep consumption, and things like the peak current and the percentage of the total consumption caused by such peaks. Extending the software to handle this is more work.

With slightly more elaborate software, it will be possible to place the power measurement plug between the measuring JeeNode and the JeeNode under test, and then leave it alone. A 1-day or 1-week average should give an excellent estimate of battery lifetimes.

Power consumption tracker

In Hardware on Dec 21, 2009 at 00:01

After the recent battery life estimation and refinement posts, I wanted to create a more permanent and more automated setup for monitoring the total power consumption of JeeNodes. I expect to be repeating these power usage optimizations regularly, with new sketches.

Here’s the idea. A little interface to let one JeeNode (or Arduino, whatever) monitor the power consumption of another. This ought to provide a fairly accurate measurement within a day or so.

First the schematic:

Screen shot 2009-12-19 at 16.27.09.png

This is a “low-side” current meter. In fact there are two of them in series, one with a 60 mA range, the other with a maximum range of about 1 mA. So this setup can measure up to 60 mA with approximately 1 µA resolution at the lower end. These ranges could easily be changed by adjusting the 5 Ω (2x 10 Ω) and 270 Ω resistors.

The low range resistor has a forward-biased diode, which limits the total voltage drop over it to under about 0.6V. This means that the total voltage drop over the measurement circuit will stay under 1V for currents up to 60 mA. With a 5V supply, that leaves about 4V to be supplied to the JeeNode being tested – more than enough headroom for the 3.3v regulator to do its thing.

Note that there is a drawback to low-side current sensing: the “ground” level supplied to the test circuit isn’t really ground. It’s floating “somewhere” above zero, and what’s worse is that the actual level will depend on the amount of current drawn. But in this case it doesn’t really matter, since the test circuit isn’t connected to anything else anyway (we’re doing all this to measure a battery-power wireless system, after all).

Two op-amps are used to amplify the 0 .. 0.3V signals 10 times. A neat trick: the low range op-amp (on the right) nicely compensates for the floating reference level from the high-range resistor by using that as reference for its negative input. So basically, these two op-amps generate two analog voltages in the total range of 0 .. 3.3V. I picked the OPA2340 CMOS op-amps because they can operate at 3.3V and can output rail-to-rail voltages. They also happen to draw very little current.

Here’s a custom-made JeePlug with all the above components:

DSC_0867.jpg DSC_0872.jpg

Note: I don’t know what got into me while building this plug, but the pins on the port connector are all reversed. So I’m forced to plug this thing in the other way around. Doh!

This is only half the story. Tomorrow: the software side of power tracking.

Update – for a very nice current metering setup, see also David Jones’ µCurrent adapter.

Battery life – refinement

In AVR, Hardware, Software on Dec 19, 2009 at 00:01

Yesterday’s post described how to estimate the battery life of a JeeNode running the “rooms” sketch with the SHT11, ELV PIR, and LDR sensors. To summarize:

  • the code started out using 370 µA average current, i.e. roughly 7 months on 3 AA cells
  • of these, 200 µA were caused by the 1-second periodic wakeup “blip”
  • another 120 µA were due to the actual measurements and packets sent every 30 seconds
  • and finally, the remaining 50 µA come from the PIR + JeeNode current draw in sleep mode

Yesterday’s post was also about reducing that 200 µA blip consumption to somewhere around 20 µA.

Today, let’s tackle the other power “hog”: the 300 ms @ 12 mA spike. Here is that pattern again:

b1.png

The high peak at the end is the RF transmission of a packet, followed by a “knee” during which the node is waiting for the ack packet in RF receive mode.

Note that the main power drain is NOT caused by wireless communication!

This period of over 300 milliseconds is when the ATmega is polling the SHT11, waiting for a fresh reading. Twice in fact: once for the temperature and once for the humidity measurement.

So the explanation is very simple: we’re polling and waiting in full-power mode. Quelle horreur!

The fix requires a small modification to the SHT11 driver in the Ports library. Instead of a fixed delay, it needs to be extended to allow using an arbitrary function to waste some time. Here’s the modified code:

Screen shot 2009-12-18 at 01.00.53.png

A new second arg has been added, specifying an optional function to call instead of delay(). The code remains backward compatible, because this argument defaults to zero in Ports.h:

Screen shot 2009-12-18 at 01.02.45.png

So now all we need to do is define a delay function which goes into real power down mode for a little while:

Screen shot 2009-12-18 at 01.52.23.png

… and then adjust the two measurement calls to use this function:

Screen shot 2009-12-18 at 01.05.08.png

Does all this make a difference? You betcha:

b2.png

That’s a substantial fraction of a second in which the ATmega will draw considerably less than 12 mA. How much less? Let’s expand the vertical scale:

b3.png

Most of the time, the voltage is around 50 mV, i.e. 1 mA over 47 Ω. That’s the SHT11 current draw while active. There are two measurements – so everything behaves exactly as expected!

A couple of quick wake-ups remain, to check whether the SH11 measurement is ready. And so does the wireless TX/RX peak, of course. Here is an isolated snapshot of that RF activity (200 mV/div and 4 ms/div):

b4.png

Approximate current draw: TX = 35 mA, RX = 20 mA. Total time is about 10 ms.

Looks like we’ve reduced the power consumption of this once-per-30-second spike by perhaps 90%. As a result, the node now consumes about 20 (blip) + 20 (spike) + 50 (sleep) = 90 µA on average. Even with much smaller 800 mAh AAA cells, the battery life of these low-power nodes should now be over a year.

There are several conclusions to take home from this story, IMO:

  1. The biggest drain determines battery lifetimes.
  2. Measuring actual current profiles always beats guessing.
  3. A simple USB storage scope is plenty to perform such measurements.

If I had followed my hunches, I’d no doubt have spent all my time on getting the current draw of packet transmissions down – but as these experiments show, their effect on power drain is minimal.

There are more optimizations one could explore. There always are. But the gains will be limited, given that the ELV PIR sensor consumes 30..40 µA, and that it needs to be on at all times anyway, to be able to detect motion.

Sooo… end of story – for now :)

All source changes checked in. The entire rooms sketch still compiles to under 8 Kb of code.

Battery life estimation

In AVR, Hardware, Software on Dec 18, 2009 at 00:01

To get an indication of battery power drain, I measured the voltage drop over a 47 Ω resistor in series with the 5V supply, using a JeeNode with Rooms Board and the latest version of the “rooms” sketch.

Here’s the blip I see, once a second (100 mV/div and 20 msec/div):

on-time-1.png

That’s a 40 msec pulse of about 5 mA, in other words: 5 mA during 4 % of the time, which averages out to around 200 µA current draw continuously. Not bad, but not stellar either: it’s 4 times the sleep mode current.

Every once in a while, a much longer and bigger spike shows up:

occasional-peak.png

Which looks like roughly 350 msec @ 12 mA.

Let’s assume the big one is a real transmission. It sort of fits: the spike at the end is a brief transmission at ≈ 35 mA total, followed by a 20-ish mA period of reception (waiting for the ack to come in).

Very roughly speaking, the area of that extra spike at the end is about the same as the 5-to-10 mA step at the start of this period. So as an estimate, we’re consuming about 12 mA during 350 msec – let’s round down to 300 msec.

Let’s also assume these bigger current patterns happen every 30 seconds, when the node is reporting changed values (everything other than motion gets reported at that rate in the latest “rooms” sketch).

So 1% of the time (300 ms every 30s), power consumption is 12 mA. This averages out to 120 µA continuous current consumption.

In other words: a JeeNode running this latest rooms sketch with the SHT11 and ELV-PIR sensors, is consuming roughly 200 (blip) + 120 (spike) + 50 (sleep) = 370 µA.

Using a 2000 mAH 3-cell AA battery, this should lead to a 225-day lifetime – over 7 months.

Can we do better? Sure.

It’s basically a matter of figuring out what’s going on during those 40 and 350 msecs, respectively. Interestingly, more can be gained by improving non-transmitting “blips” than twice-a-minute high-power RF packet exchanges.

Do those 40 ms @ 5 mA every second look a bit suspicious? Yep – that’s the “idling” power level. What happens is that I was a bit too pessimistic in the time spent in sleep mode. This was the code:

Screen shot 2009-12-17 at 00.51.26.png

Looks like this is about 40 ms off, and so the code ends up waiting for the 1 sec timer to expire… in idle mode!

Let’s change this to end up closer to the desired time:

Screen shot 2009-12-17 at 02.59.16.png

Here’s the new blip (different scales):

better-blips.png

We’re down from 40 to 10 msec blips – tada!

That translates to an average 50 µA current draw from the blips, bringing the total down to 220 µA. Which translates to a 375-day battery life: over a year!

Now we’re cookin’ … but could we do even better? Sure.

Note that only the 2 ms spike at the end of the 5 mA blip is the actual active period. The time up to then we’re just waiting in idle mode – and wasting power.

We could shorten the sleep timer to 994 ms, since we don’t care whether readings are taken exactly 1 second apart. Now the RFM12B-based watchdog timer will wake us up just 2 ms short of the target time. And sure enough, the 5 mA blip is down to around 3 ms – shown here with an even further expanded time scale:

final-blip.png

But that’s silly. We’re tweaking a millisecond timer, and we’re not even interested in an “exact” 1000 ms cycle in the first place! It makes much more sense to just use the RFM12B wakeup timer to get us close to that 1 second cycle, and then immediately take a measurement. Here’s the corresponding code change in periodicSleep():

Screen shot 2009-12-17 at 02.35.36.png

Does this make a difference? Definitely:

best-blip.png

One final remark: the above battery lifetime estimates do not take into account the increased power consumption when motion is detected and more packets are sent (up to once every 5 seconds). On the plus side, when no light / temperature / humidity changes happen, the packet frequency will drop further, to once-a-minute.

The above changes have been checked into the source code repository.

Update – I just found out that the DSO-2090 scope has a high-pass low-pass filter option:

smooth.png

Sure wish I’d found out about that feature sooner… it’s so much more informative: the initial ramp is probably the clock starting up, and the little peak could well be the LDR pull-up during ADC conversion!

Prototyping

In Hardware on Dec 17, 2009 at 00:01

Some things I just can’t seem to do without are these:

DSC_0861.jpg

… and these:

DSC_0862.jpg

Great for all those Projects On Foam in various stages of incubation here at Jee Labs:

DSC_0787.jpg

Since I’m too lazy to always dismantle and re-use everything – especially POFs – I decided to get some more and also add these mini breadboards and wire jumpers to the web shop.

Pretty low tech stuff, but these just work so well that they’ve become timeless.

Rooms sketch, reloaded

In AVR, Hardware, Software on Dec 16, 2009 at 00:01

With the new easy transmission mechanism and the low power logic implemented, it’s time to revisit the “rooms” sketch, which I use for all my house monitoring nodes based on the Room Board.

I’ve wrapped the code used in POF 71 a bit further, with these two extra functions:

Screen shot 2009-12-15 at 22.25.44.png

With this, the main loop becomes very simple – even though it will now power down the RFM12B and the ATmega328 whenever there’s nothing to do for a while:

Screen shot 2009-12-15 at 22.25.57.png

The lowPower() and loseSomeTime() code is still the same as in POF 71 – this is where all the hardware low-power trickery really takes place:

Screen shot 2009-12-15 at 22.24.57.png

Note that these need an “#include <avr/sleep.h>” at the top of the sketch to compile properly.

I’ve also disabled the pull-up resistor on the LDR while not measuring its value. This drops power consumption by over 100 µA, depending on actual light levels.

A quick measurement indicates that power consumption went down from 20 mA to some 50 µA (much of that is probably the PIR sensor). These are only approximate figures, because my simplistic multi-meter setup isn’t really measuring the charge (i.e. integrated current draw), just the current draw while in sleep mode.

These changes have been checked into the repository as “rooms.pde”.

This code isn’t perfect, but since “perfection is the enemy of done” I’ll go with it anyway, for now. One difference with the original rooms sketch is that the motion sensor is not read out as often so brief motion events might be missed. Another issue with this code is that if the central node is off, a lot of re-transmissions will take place – without the node going into sleep mode in between! IOW, a missing or broken central node will cause all remote nodes to drain their batteries much faster than when things are properly ack’ed all the time. Oh well, let’s assume this is a perfect world for now.

With these levels of power consumption, it’s finally possible to run room nodes on battery power. I’ll use some 3x AAA packs, to see what sort of lifetime this leads to – hopefully at least a couple of months.

Will report on this weblog when the batteries run out … don’t hold your breath for it ;)

Update – I just fixed a power-down race condition, so this code really goes back to sleep at all times.

Better FS20 transmissions

In Software on Dec 14, 2009 at 00:01

The RFM12B can be tricked into sending OOK (on-off-keying) signals – which is also called ASK (amplitude shift keying), by doing exactly what the term stands for: turning the transmitter on and off.

This has been used in several examples to control FS20 and KAKU remote power switches – just search for these terms on this weblog in the box at the bottom right of this page and you’ll get all the related posts.

The code I’ve been using for FS20 so far is:

Screen shot 2009-12-13 at 16.29.17.png

As it turns out, the timing is not quite up to scratch. JGJ Veken drew my attention to this in the forum and by sending in a couple of pictures, including this one:

03 jee-node transmitter 0 en 1 not ok.JPG

(Wow – great instrument, a 100 MHz Tektronix 2232 storage scope!)

A 0 bit comes out as 250/468 µS, and a 1 bit as 428/722 µS – pretty far off the 400/400 + 600/600 µS specs.

Here’s what we came up with after a few trials:

Screen shot 2009-12-13 at 17.20.28.png

The end result is within a few percent of the target, well within spec – yippie!

Jeenode Transmitter FS20 bitstream.JPG

I’ve updated the code in the RF12 examples (including RF12demo) in the code repository and the ZIP file.

A similar tweak could probably be used for the KAKU signals, but these use a lower rate of bit signaling, so the jitter is probably somewhat less important.

Update – the KAKU tweak has also been checked in, and the code has been simplified a bit further.

Re-flashing and ISP

In AVR, Hardware on Dec 11, 2009 at 00:01

This is the second of two posts about everything related to uploading, re-flashing, bootstraps, FTDI, and ISP.

Yesterday’s post described the process of uploading new sketches via USB or RS232 using a boot loader.

But how did that boot loader get into the ATmega328?

That’s a bit of a chicken-and-egg problem. Ya’ can’t use a boot loader to get the boot loader into flash memory!

This is where a lower-level hardware-based mechanism called In System Programming (ISP) comes in. ISP is a clever trick in the ATmega chip which in effect activates a special boot loader built into the hardware. This is done by holding the RESET line of the ATmega low, at which point the chip becomes essentially useless, since the reset prevents the chip from starting to run its firmware. The trick is that in this mode, some of the pins on the ATmega become an interface to that special hardware-based built-in boot loader.

So what we need to do, is to manipulate those pins to send commands which will store data into the flash memory. What we’re going to send in most cases, is the data for the boot loader in upper memory. With that boot loader in place we can then switch to “normal” uploading via the serial interface and USB.

ISP programming is also used to change “fuse bits” on an ATmega. There are a few configuration settings for the ATmega – what type of clock it uses, how it boots up, enabling a watchdog timer, etc. These are stored in “fuses” which can only be adjusted via ISP programming.

There are 3 I/O pins involved in ISP programming, plus the reset line and power. On the Arduino as well as on the JeeNode and JeeLink boards, these lines are available via a 2×3-pin ISP connector with the following layout:

ISP pins.png

The interesting thing is that you don’t even need an Arduino or JeeNode to set up flash memory and fuses. ISP is so low-level that it works directly on the pins of an ATmega chip. This is very useful to pre-load the boot loader (or test program – anything you like, really) onto a chip before soldering it permanently onto a board.

(continued…)

Read the rest of this entry »

Uploading and FTDI

In AVR, Hardware on Dec 10, 2009 at 00:01

This is the first of two posts about everything related to uploading, re-flashing, bootstraps, FTDI, and ISP.

First, our goal: what we want to do is get our software (“sketch”) from the PC/Mac into the AVR ATmega328 microcontroller on our Arduino or JeeNode. This is a fairly simple process once all the pieces are in place…

The effect is that the flash memory built into the ATmega is re-flashed. Being flash memory, your software will remain in the microcontroller even without power – ready to start again once power is applied.

There are two ways to get your software into the ATmega: In System Programming (ISP) and uploading. ISP will be described tomorrow, here we’re going to focus on uploading.

Uploading works with a “boot loader”. This is a small piece of software started after power-up (or a reset), which usually listens on the RX and TX pins of the serial interface for commands. These commands then tell it what data to store in which part of the flash memory:

Screen shot 2009-12-09 at 12.25.31.png

The surprising thing is that the boot loader itself is also stored in flash memory. It’s stored in a small (1..4Kbyte) area in upper memory, and the data it writes always goes to the lower part of memory. That’s why it’s called a bootstrap or boot loader – imagine lifting yourself by pulling on the straps of your own boots. In this case the ATmega is lifting its own functionality up by reprogramming its flash memory via its own boot loader.

(continued…)

Read the rest of this entry »

Low power mode again

In AVR, Software on Dec 9, 2009 at 00:01

After yesterday’s Wireless Light Sensor was announced, I wanted to push a bit more on the low-power front.

The POF described two simple tricks to get the power consumption from 19 to 3 mA, roughly. It turns out that a single extra step will get the idle consumption down to some 20 µA. That doesn’t mean we’re getting a 15-fold battery lifetime increase, because I’m measuring the current at idle time but not accounting for the brief periods of high-current activity which also occur. But it’s a major reduction in power consumption.

Here’s how … but this requires going a bit deeper into some low-level AVR/ATmega chip features.

First, here are some utility functions we’re going to need:

Screen shot 2009-12-08 at 10.04.31.png

The lowPower() routine disables the ADC subsystem and then enters the specified low-power mode in the ATmega. Once it resumes, the ADC subsystem setup will be restored to its previous state.

The loseSomeTime() does just what is says on the box: go into comatose mode for a more-or-less controlled amount of time. The trick is to activate the RFM12B watchdog just before passing out. This leads to larger power savings than we would have with the ATmega’s watchdog, btw – and it’s easier to implement.

The complication is that we risk losing all track of time. It’s a bit hard for an ATmega to count heartbeats when its heart has stopped beating – not only are there no beats, it’s also stripped of its counting abilities while in coma…

So instead, we estimate just how long we’ve been away from the watchdog time chosen for the RFM12B, and correct the milliseconds timer built into the Arduino. That’s what the “timer0_millis” stuff above is about. It will not be quite as accurate as before, but that’s probably acceptable for a sensor node like this one.

The last issue is that we need an indication about how long we can go comatose. I’ve added a “remaining()” member to the MilliTimer class to obtain this information.

Now, all the pieces are in place to change the code in the Wireless Light Sensor from this:

Screen shot 2009-12-08 at 10.14.23.png

.. to this:

Screen shot 2009-12-08 at 10.15.53.png

So there you have it. Most of the time between each measurement once a second, the node will now go into a very low-power mode of around 20 µA. My current measurement tools are inadequate to measure exactly what amount of charge is being consumed, which is what this is really about. So accurate battery lifetime calculations are not yet possible – but I expect it to be in the order of months now.

I’ve updated the Wireless Light sensor POF to point to this post and include this trick.

Wireless Light Sensor – POF 71

In AVR, Hardware, Software on Dec 8, 2009 at 00:01

After last week’s Hello World POF to get started, here is a new Project On Foam:

DSC_0824.jpg

A battery-powered wireless light sensor node. This is POF 71, and it’s fully documented on the wiki.

This project goes through setting up the Ports and RF12 libraries, setting up a central JeeNode or JeeLink, and constructing the light sensor node.

It also describes how to keep the node configuration in EEPROM, how to make a sensor node more responsive, and how to get power consumption down for battery use.

The POF includes code examples and uses the easy transmission mechanism, with the final responsive / low-power sketch requiring just a few dozen lines of code, including comments. The sketch compiles to under 5 Kbyte, leaving lots and lots of room to extend it for your own use.

All suggestions welcome. Anyone who wants to participate in these POFs, or in the wiki in general, just send me an email with the user name you’d like to use. I’m only restricting edit access to the wiki to prevent spamming.

JeeNode power pins

In Hardware on Dec 7, 2009 at 00:01

The JeeNode has a number of connections for external power. This is the place before the 3.3V LDO regulator. Keep in mind that all these pins are tied together, electrically:

JeeNode power pins.png

This has two important consequences:

You can power a JeeNode through any of these pins. It does not matter how you connect power to a JeeNode, all of them will have the same effect. You don’t have to connect a battery to the battery connector or the FTDI connector, you can also tie it to a PWR pin on any of the port headers (as I tend to do with Projects On Foam).

You should avoid connecting multiple power sources. If you connect a 9V battery, for example, the JN will work fine. But if you leave it connected when plugging in an FTDI interface such as a USB-BUB, then the 9V will find its way to the FTDI chip, and through the internal ESR diodes probably also to some I/O pins. Chances are high that you’ll damage at least the FTDI and the ATmega chips at this point (thanks to Paul Badger for pointing this out). A 3- or 4-cell Alkaline / NiMh battery pack can probably take some abuse without damaging anything.

There are no diodes in these various connections because the JeeNode is designed to be usable under very low power conditions. Throwing away 0.6V (or even just half that with a Schottky diode) is not always an option. The MCP1702 voltage regulator on the JeeNode was specifically selected to have an extremely low drop-out voltage (under 0.1V at low power levels) and a minute quiescent current draw (under 2 µA). This means that you could power a JeeNode from just 3.4V, perfect for 1 LiPo or 3 NiMh batteries, for example. The price is reduced protection against incorrect use.

The JeeNode USB is slightly different. It is intended to always be powered from USB, i.e. with PWR fixed at 5V. There are no FTDI and battery connectors, and all the other pins are connected to the 5V line via a 350 mA polyfuse (PTC) as protection against over-current on the USB power line. You can probably power a JeeNode USB through any of the port or PSI connectors, as long as the voltage is around 5V. The current draw will be several mA higher than with a plain JeeNode due to the on-board FTDI chip.

Building the JeeNode v4

In Hardware on Dec 6, 2009 at 00:01

Here are the updated build instructions, using the latest v4 board.

This is the contents of the kit:

DSC_0593.jpg

You’ll need some basic skill at soldering but don’t worry, as there are only a few parts to solder on. The best way is to start with the lowest-profile part, that way you can place things flat on the table and press down to keep the parts in place. So let’s start with the 10 KΩ resistor:

DSC_0595.jpg

Turn the board around and solder the leads:

DSC_0596.jpg

(continued…) Read the rest of this entry »

FTDI Reset Supressor

In AVR, Hardware on Dec 5, 2009 at 00:01

Sometimes the simplest things are so obvious that it’s easy to miss them…

I occasionally do not want to reset a JeeNode when accessing it via USB. The reset is great for uploading, because the ATmega’s bootloader runs right after reset and intercepts such upload requests in a very convenient way. But sometimes, you just want to leave the ATmega running when re-connecting to it.

Meet the “FTDI Reset Suppressor”:

DSC_0827_2.jpg

All it does is break the reset connection between an FTDI interface such as the USB-BUB and the JeeNode.

Just to make this post a little longer, here are the steps to make one:

DSC_0827.jpg

And here is an action shot:

DSC_0828.jpg

Tada! And it’s totally voltage, baud-rate, and platform independent… :)

Update – it just occurred to me that this already exists, it’s a 5-pin stacking header! Or a 6-pin one, as follows:

DSC_0836

JeeNode clock

In Hardware, Software on Dec 4, 2009 at 00:01

To follow up on a recent post, here is the same real time clock demo using a JeeNode + USB BUB instead of an Arduino + Plug Shield:

DSC_0816.jpg

(instead of JeeNode + USB BUB, the new JeeNode NoRF or a JeeNode USB could also have been used)

I chose to use two different ports for RTC and LCD, but these could just as easily have been daisy-chained on a single port.

The changes to the code are minimal, here is the complete sketch:

Screen shot 2009-11-29 at 15.44.07.png

The changes affect a few declarations at the top, and the fact that the use of the Wire library was hard-wired into the getDate() function.

Easy transmissions

In Software on Dec 2, 2009 at 00:01

I’ve extended the RF12 driver with three “rf12_easy…()” functions, which should make it easier to implement nodes which need to periodically report some data to a central JeeNode or JeeLink.

Here’s a complete sketch which sends the current value of the millisecond counter over wireless:

Screen shot 2009-12-01 at 21.50.44.png

The above sketch compiles to roughly 3 Kb of code. Some extra notes:

  • The “rf12_initialize(…)” call sets this node up as node “W” (23), using 868 MHz, and using group 5.
  • The “rf12_easyInit(5)” call sets up the easy transmission system, with data to be sent every 5 seconds.
  • The “rf12_easyPoll()” call needs to be called often – at least once per millisecond or so would be best.
  • The “rf12_easySend(…)” call passes the data to be sent, i.e. pointer to that data and the number of bytes.

There’s quite a bit of additional logic hidden behind these three calls:

  • Even if called often, new data will only be sent at most every 5 seconds, as requested.
  • Lost and damaged packets will automatically be resent, with up to 8 retries.
  • Packets are only sent if the data has changed.
  • To force data to be re-sent even if unchanged, call “rf12_easySend(0,0)”.

Here is some output from a capture utility I use:

Screen shot 2009-12-01 at 23.18.15

As you can see, the 4-byte millisecond value is only sent once, every 5 seconds.

The argument to rf12_easyInit() is in seconds, and can be anything from 1 to 255 seconds. In addition, using zero as argument means: send as often as possible. For the 815 MHz band this depends on the number of data bytes, to enforce the “1% max bandwidth rule”. The actual rate will range from about 7 packets per second for 1 byte of data, to about 1 packet per second for 66 bytes of data. For the 433 and 915 MHz frequency bands, the maximum rate is fixed at 10 packets per second, regardless of the data size.

I’m currently using a simple algorithm which tries to resend at 1-second interfals when packets are lost or damaged. This can be extended to “exponential back-off with randomization” later on. My first concern is a simple-but-robust first implementation.

There is still an issue with the current RF12 driver, which can cause duplicate packets to arrive at the destination (an extra sequence bit needs to be added to each packet to detect loss of acknowledgement packets – this change affects the protocol and requires re-flashing all the current nodes, which I don’t want to do just yet). Such duplicate packets can easily be filtered out at the destination. There is also an issue with picking up the wrong ack, this probably only affects nodes at the limit of their range (i.e. when not all the nodes receive the same things).

No changes were made to the RF12 driver core, these calls are purely a layer on top. They use broadcasting to get data from different nodes to a single central node, and currently there is no way to combine this with reception of data coming towards a node. But as the above example shows, for the specific scenario of sending out data these calls should simplify the development of remote nodes a fair bit.

The new code is now in the subversion repository, as well as in the RF12.zip archive.

Update – documentation for these new calls has been added to the Café docs.

JeeNode comparison matrix

In AVR, Hardware on Nov 26, 2009 at 00:01

All the final boards are in now. It’s time to step back a bit. Let’s start with a picture:

DSC_0785.jpg

From left to right: JeeLink (v2), JeeNode USB (v2), and JeeNode (v4).

Here is a summary of the similarities and differences between these units:

jee-comparison.png

(this comparison matrix is also available as PDF)

So there you have it – one happy JeeFamily :)

Update – Nov 30: lower prices for the JeeNode USB and the JeeLink!

Update – Dec 1: added the new low-cost “JeeNode NoRF” kit.

Node, node, node

In AVR, Hardware on Nov 24, 2009 at 00:01

Ok, finally got around to building a bunch of JeeNodes for all those room boards I had waiting:

DSC_0775.jpg

Just for the heck of it, I decided to leave the boards joined together, as they come from the pcb manufacturer. This picture was taken just before separating these final units.

Small detail: on the left the original 10 µF capacitors, lying down, and on the right the new ones I will be using from now on, which are much smaller and leave the battery connection pads exposed.

The good news is that these units all worked out of the box. Great, eight of ’em will go straight to their room :)

I’m not having quite as much luck so far with the assembly of JeeLink and JeeNode USB boards, both using SMT parts. There, I often have to debug 2 or 3 out of 10 boards before they work. Occasionally, even that doesn’t solve it so once in while a board gets set aside, awaiting further debugging some other time.

It’s called “production yield”, I think, and I’m not quite there yet… oh, well.

OOK unit

In AVR, Hardware, Software on Nov 21, 2009 at 00:01

Here’s an ELV 868 MHz OOK receiver, connected to the new JeeNode USB:

DSC_0771.jpg

Note that this plug can be used for any of the four ports, simply by plugging this thing in one of the four possible orientations. In this case, it’s hooked up to port 1.

The receiver is mounted on a JeePlug for stability:

DSC_0768.jpg

There really are only three wires: GND, +3V, and the received bit stream, which is tied to the AIO pin:

DSC_0769.jpg

You can clearly see the built-in pcb antenna on these last two pictures.

The code for this is similar to the one used in an earlier post and basically runs a couple of bit decoders in parallel to recognize FS20, (K)S300, and EM10 commands. It’s available here. Sample output:

Screen shot 2009-11-19 at 15.02.31.png

Or have a look at the OOK relay, with which this plug will also work.

I really need to clean up and merge the different OOK decoding sketches – they all have slightly different capabilities…

One thing which would be very nice to do with this unit, is a general sketch which reports incoming OOK packets but which also uses the OOK sending capabilities of the RF12 driver to send out such packets, to control FS20 devices for example. That mould make this a general-purpose bi-directional 868 MHz OOK unit, connected via USB and controllable via simple serial-port commands.

I’ll punt for now. Don’ have time to go into this. Or perhaps I should say… exercise left for the reader :)

And maybe one day we’ll get OOK input going without extra hardware ?

PS. Good news: everything is now in for the JeeNode USB, so I’ve started shipping them.

Build and pinout errors on older posts

In AVR, Software on Nov 8, 2009 at 00:01

There has been an unfortunate dependency between the Ports library and the RF12 library for some time now, causing the Arduino IDE to generate errors such as these:

ide-errors.png

(etc…)

The workaround right now is to include both in your sketch, even if you only need one:

Screen shot 2009-11-04 at 10.50.42.png

I’ve been planning to do a major overhaul of the library and software in general, but until then this is the way to avoid those pesky errors. It probably affects quite a few sample sketches on this weblog.

Another thing to watch out for (thanks, Ian!) is that some older examples on this weblog use the JeeNode v2 or even v1, which have a different pinout. To uses those examples with the latest JeeNodes, you have to swap pins 4 and 5, i.e. +3V and AIO.

Please let me know when examples from earlier weblog posts don’t work as described. A small fix and note added to these posts might be all that is needed!

Meet the JeeNode USB

In Hardware on Nov 7, 2009 at 00:01

Here is a brand new JeeNode USB v2, this is the successor of the JeeLink v1:

DSC_0737.jpg

This is the first (hand-soldered) unit, I had to stack a resonator on its side to fit it in – properly-sized resonators should be coming in soon. The final version will have the usual bright yellow antenna wire – I merely used black to remind me that this is a prototype. You don’t want to know how many different versions of various units are scattered all over the Jee Labs…

The JeeNode USB is a JeeNode with built-in FTDI interface and mini-USB jack. It uses surface mounted parts and has exactly the same size as the basic JeeNode. All the headers and connectors are in the same place, so this thing is plug-compatible – apart from the 6-pin FTDI connector vs. the mini-USB jack, of course.

The JeeNode vs. JeeLink naming confusion is a bit unfortunate, but I’m hoping to resolve it now – before the confusion gets even worse. There is no “v1” of the JeeNode USB, btw.

The JeeNode is the unit with ports and headers. There is the basic JeeNode v4 with through-hole parts, and now there is also a JeeNode USB v2, with SMT parts.

The JeeLink v2 is the unit in the shape of a USB stick, using SMT parts. It has no headers, but it has extra flash memory on board. And it comes in a Cool Clear Case.

Both JeeNodes as well as the JeeLink have an RFM12B wireless radio module.

Ok, everything is starting to come together now.

Activity LED

In Hardware on Nov 6, 2009 at 00:01

The new JeeLink v2 has an “activity LED” added, which is not present on the JeeNode.

This is simply a LED from PB1 (Arduino pin 9) to “+” via a current limiting resistor. It’s very easy to add the same activity light to the JeeNode, using a 4-pin connector:

DSC_0623.jpg

Now place this contraption on the SPI/ISP connector as follows:

DSC_0621.jpg

Voilà – it even has PWM!

The latest RF12demo code now has a “l” command to test the led – “1l” turns it on, “0l” turns it off again.

Woohoo – this is post #300 !

JeeNode v4 on a breadboard

In Hardware on Nov 2, 2009 at 00:01

Now that the JeeNode has labels on the back, there’s a convenient way to use it with mini-breadboards:

DSC_0671.jpg

This uses male-male headers with extra-long pins, so that the JeeNode can still use female headers:

DSC_0670.jpg

To get more space to work with, use two mini-breadboards:

DSC_0672.jpg

Plenty of room for lots of experiments, even for a few plugs.

More room sensors

In Hardware on Oct 30, 2009 at 00:01

I’m getting ready to install a new round of room sensors around the house. Am using the remaining prototype boards, now that the final version is ready:

DSC_0674.jpg

Some rooms here don’t really need relatively expensive SHT11 sensors and some places don’t need a motion sensor, hence the variation across these 6 new units.

These boards require some patches, as described earlier, for use with the EPIR sensor, i.e. the three leftmost boards shown above.

The patches are easy to apply on the back of these little boards:

DSC_0675.jpg

That’s a 4.7 kΩ pull-up for the DS18B20 1-wire sensor, and a 100 kΩ pull-up for the EPIR.

Installing these will bring the total to 10 active nodes, but that’s still not the end of the story. Once everything is done, I’ll have 16 JeeNodes with room boards and sensors watching over this house. It’ll be interesting to see how the temperature changes across the different rooms, and what humidity levels are reached in the basement and beneath the house once winter sets in…

Updated RF12demo

In AVR, Software on Oct 29, 2009 at 00:01

The RF12demo software which comes pre-loaded on all JeeNodes and JeeLinks has been extended a bit:

Picture 1.png

The new commands are:

  • l – to turn the activity LED on or off, if present
  • f – send a FS20 command on the 868 MHz band
  • k – send a KAKU command on the 434 MHz band

The new FS20 and KAKU commands were added so that a JeeLink can be used out-of-the-box to control the commercially available remote switches of these types. The updated demo is included with all new JeeNodes and JeeLinks from now on.

For example, to turn on channel 1 of a FS20 unit with housecode 0x1234, you can type in “18,52,1,17f” – i.e. the house code in bytes, the channel, and 17, which is the “on” command. Likewise, to turn on channel 1 of group B on KAKU, type “2,1,1k”.

The KAKU transmission range is not very high because the RFM12B radio used is tuned for the 868 MHz band, but even more so because the attached wire antenna is completely wrong for use at 434 MHz. If you want to use this for controlling KAKU devices and don’t get enough range, try extending the antenna wire to around 17 cm, i.e. double its current length. You can just attach an extra piece of wire to the end.

Which – unfortunately – is going to substantially reduce the range at 868 Mhz… so if you really want to use both frequency bands, you’ll have to use two JeeNodes or JeeLinks, each with their own properly sized wire antennas.

For more info about FS20, see these posts on the weblog. For KAKU, see these.

Shop news

In News on Oct 27, 2009 at 00:01

Big news today for people from the US, Canada, Australia, and other parts of the world where the 915 MHz band is available for use with JeeNodes.

Paul Badger of Modern Device has added JeeNodes and a few other items to his shop – check it out:

ModevcoLogoLong.png

Please be patient as Paul gets all the necessary bits and pieces ready, but this means you’ll be able to get Jee stuff with US prices and (much) lower shipping costs if you live on the other side of the big pond.

Behind the scenes, Paul Badger has been actively involved in the Jee Labs since early this year. I’m very happy that at last he’ll also be able to get involved with actual shipments.

Things are still evolving quite rapidly here w.r.t. plugs, so we’re still figuring how and when to make all the different plugs available, boards, pre-assembled, etc. The intention is to eventually provide all the same options as in the European Jee Labs Shop, but it may take some time to get there. It’s going to be a bit tricky to get it right with such a moving target…

This change also means that I’m no longer offering 915 MHz units from Europe – just 868 MHz.

On the plugs front there is some good news as well, as final versions of the Blink / Expander / Memory / RTC / UART plugs and the Proto Board are set to arrive here tomorrow. I’ll be updating the various bits and pieces and pictures once they come in, of course.

The astute reader will notice that there are still a few items missing. I’m expecting a few more boards by the end of the week, but there are also some delays due to a production issue which requires some boards to be re-made. That means some boards won’t be in for another two weeks and there’s little I can do about it :(

Not to mention the fact that stupid little mistakes with boards seem to have become a habit of mine… each mistake leads to a new round trip to the pcb shop, i.e. 3 weeks on average. Which is why I’m juggling as many overlapping release cycles as I can – while trying not to make yet more mistakes!

Next month all this frantic shop stuff should be over, and I hope to get back to some “real” lab work, with more s/w coding and finishing up some of the numerous projects cluttering up my desk… eh, I mean my entire office!

Four generations

In AVR, Hardware on Oct 26, 2009 at 00:01

After one year, I thought it’d be nice to compare all the JeeNode versions which have come out – up to and including the latest v4:

DSC_0581.jpg

Here is the back side of each of them:

DSC_0582.jpg

The back side in particular illustrates the evolution which has taken place this year.

In version 1, there were no labels – mainly because I hadn’t figured out how to do those and I was eager to just see the darn thing work

Version 2 added some minimal labeling (in copper, to save on production charges!) and a ground plane. Port pairs 1+4 and 2+3 were moved 0.1″ further apart. The mounting holes were dropped.

Version 3 was really the first production-ready one. It added lots of text on the component side, plus a bit of eye candy by going for blue solder masks. I switched to yellow wire for the antenna, to help remind me that this is the version with the final port and pin layout – the one which matches all the new JeePlugs. Version 3 did get the silkscreen for the regulator wrong, but it also made it to the Make Magazine weblog – cool! :)

Version 4 now takes this evolution to its logical conclusion: a clear visual “identity” in the form of blue-and-gold color choices and lots of labels on both sides of the board. No more guessing! The PWR/I2C connector moves a bit and is augmented with two more pins. This JeeNode is the narrowest of all, it now has precisely the same width as all the plugs (21.1mm / 0.83″). This is the grown-up version at last, focusing on actual usage convenience along with a proud & pleasing appearance.

It’s time to move on. The JeeNode is done.

Happy birthday, Jee!

In News on Oct 25, 2009 at 00:01

Today, exactly one year ago, I discovered the Arduino platform and decided to explore it and write about my adventures. That’s when this weblog started. Within a month, it became a daily weblog – as it still is today.

Early 2009, the JeeNode was born. Like every youngster, it has kept me very busy ever since, deep into the night at times. Fortunately youngsters grow up, eventually …

So today, I’d like to announce the availability of the JeeNode v4 – the fourth iteration of the JeeNode:

DSC_0617.jpg

The one thing you’ll notice (other than the by now “standard” blue-and-gold design) is the changed PWR/I2C header, left of the ATmega chip. It now includes the RX and TX pins, and has moved to a new location, closer to the port headers. The 4 inner pins are still the same. And it’s now called the PWR/SER/I2C (PSI) header.

The back of the JeeNode v4 has changed a lot more:

DSC_0619.jpg

Text! Lots of clearly readable labels to indicate what all the ports and pins are. And on the far right three “check-boxes” to mark which type of radio is on the board. The white area in the middle is for writing down your own info, such as the node ID assigned to this unit – or which sketch it is running. See the updated documentation.

The JeeNode v4 replaces the JeeNode v3 as of today. Le roi est mort, vive le roi!

As you may have seen, the new JeeLink v2 USB stick was announced a few days ago.

Along with these two, I’d also like to announce that a new JeeNode USB v2 prototype is currently on its way. It has exactly the same size and layout as the JeeNode v4, but with the FTDI pins replaced by a mini-USB socket (same as what’s used in most digital cameras). The JeeNode USB v2 replaces the JeeLink v1, using a different USB connector. Like the JeeLink, it is built with SMT components:

Picture 2.png

The JeeNode USB and the JeeLink are USB devices, and have three LEDs: green/red for RX/TX activity on the USB port, respectively, and a blue LED which could be used as wireless activity indicator. The base JeeNode has no LEDs, but it’s very easy to add an activity LED between SPI/ISP header pins 2 and 8.

The two JeeNodes will of course continue to work just fine with all the plugs, but they are also a particularly nice match for the new Proto Board:

DSC_0591.jpg

(shown here half-inserted on a JeeNode v4 for clarity)

I’d like to point out that the Proto Plug gives access to 18 of the ATmega328’s 20 I/O pins. Only two pins are dedicated to the on-board wireless radio module (INT0 and SS). To put it differently: these JeeNodes add ports as a modular way to extend and use the ATmega I/O capabilities, but their use is entirely optional: you can simply ignore all the extra supply and ground pins if you don’t need them. And you can run totally unmodified Arduino sketches on the JeeNodes and JeeLink.

So there you have it. One year old, yet already grown up: a nice little range of modules which combine low-cost wireless with an Arduino-compatible design, using a modular architecture for tying stuff to the physical world…

I’m very proud to see how far Jee Labs has come in one year, and can’t wait to put these building blocks to new uses and to see what others figure out to do with all this.

Assembly service

In AVR, Hardware on Oct 24, 2009 at 00:01

It’s time to try something new!

Sometimes, this DIY electronics stuff can be a bit daunting. Maybe you’ve never soldered microprocessor circuits before. Or maybe you’re worried about that RFM12B “SMD” module on the JeeNode. Or maybe you just want to get going fast, and not spend your time on the hardware side of things.

Meet the new Assembly service option:

DSC_0676.jpg

For a small fee, I’m going to offer to assemble JeeNode kits for you, as well as soldering headers onto any of the plugs available from the shop.

This can help more people get started on this wireless and sensor hookup stuff. And it lowers your risk – you could get two kits, have one of them assembled, and build the other one yourself. Or if you don’t care about soldering at all, just get all the pieces you want to hook up in assembled form.

In fact, I’m going to extend this new service even further: if you get a kit to build yourself and it turns out that you can’t get it to work, then you can send it back and I’ll assemble / finish it for you. I can only do this if all the components are still undamaged, otherwise you’ll need to get a replacement kit. Since I don’t know whether this will work out, nor whether I can handle such a “return/repair” flow of items, I will only commit to do this until the end of November. If it works well enough, I’ll prolong this service.

The reason for doing this is not to add a massive amount of assembly to my workload, but to help people take the plunge with less risk. Especially if you’re new to all this physical computing stuff and electronics, I think you’ll find out that assembling kits can be a lot of fun and very rewarding. But hey, if you’re in doubt, just get a kit and some assembled parts so you don’t have to worry about everything at the same time.

OOK packet decoding

In Software on Oct 22, 2009 at 00:01

The OOK packets are now collected and stored in the JeeMon database.

Here are the first few readings from the barometric pressure sensor inside the OOK relay, as received by the central node and graphed by JeeMon:

Picture 3.png

Here is the outside temperature from a WS300 weather station on the roof:

Picture 1.png

JeeMon is written in Tcl – the following new code was added to process packets from the OOK relay and get the different parameters stored:

Picture 2.png

The RELAY decoder processes incoming data, separating the bytes into one or more messages and calling the corresponding type-specifc decoders. The RF868 decoder merely reformats incoming data to the format used by another decoder called “ALT” and which was already present in JeeMon. The RF434 decoder is just a stub for now. Note also that the DCF decoder logs the current time – it may seem odd, but storing the received time along with the current system time can be used later to detect local clock drift and compensate for it.

It’s perhaps all mumbo-jumbo for now, I just wanted to illustrate how messages get routed inside JeeMon, and that it takes relatively little logic to deal with new data sources.

This would really benefit from a flexible plug-in system, so that this sort of logic does not have to be added in JeeMon itself but can be picked up on-the-fly. Then it would be easy to add new nodes such as the OOK relay and have JeeMon automatically incorporate the corresponding logic to decode, process, and store their data packets.

OOK relay, revisited

In AVR, Software on Oct 21, 2009 at 00:01

The OOK relay to pass on 433 and 868 MHz signals from other devices has been extended:

DSC_0665.jpg

Spaghetti!

The following functions are now included:

  • 433 MHz signals from KAKU transmitters
  • 868 MHz signals from FS20 and WS300 devices
  • the time signal from the DCF77 atomic clock
  • pressure + temperature from a BMP085 sensor

Each of these functions is optional – if the hardware is not attached, it simply won’t be reported.

The BMP085 sensor in the top of the breadboard could have been plugged directly into port 3, but it’s mounted on a tiny board with the old JeeNode v2 pinout so I had to re-wire those pins.

Sample output:

Picture 1.png

There are still a few unused I/O lines, and additional I2C devices can be connected to port 3. Room to expand.

The source code for this setup is available here. It compiles to 10706 bytes, so there is plenty of room for adding more functionality.

This code includes logic for sending out the collected data to another JeeNode or JeeLink with acknowledgements, but I’m working on a refinement so it gracefully stops retransmitting if no receiver is sending back any acks.

As it is, this code will forever resend its data every 3 seconds until an ack is received, but this doesn’t scale well: all the “rooms” nodes do the same, so when the central receiver is unreachable every node will keep pumping out packets while trying to get an ack. It would be better for nodes to only re-send up to 8 times – and if no ack ever comes in, to disable retransmission so that only the initial sends remain.

I’m also still looking for a way to properly mount all this into an enclosure. There is some interference between the different radio’s, maybe all in one very long thin strip to maximize the distances between them?

Solar power

In Hardware on Oct 20, 2009 at 00:01

The Lighty project described earlier on this weblog was an attempt to create a node for outdoor use, which periodically reports some light measurement details and powers itself indefinitely via solar energy.

At the time, I couldn’t figure out how to get the power consumption down far enough, nor how to prevent the LiPo battery from overcharging.

I think I found a solution for both, triggered by a recent article in Elektor:

Picture 2.png

The main idea here, is to simply short out the solar panel when the LiPo voltage reaches 4.15 V, using a MOSFET. The battery voltage has to be measured using a voltage-divider which doesn’t constantly drain the battery – this can be solved with a low-power op-amp in voltage follower mode, using a 2:1 voltage divider. The LT1494 op-amp will work with varying supply voltages and consumes only about 1 µA.

I think I’ve got the resistors attached wrong though – need to brush up on my op-amp knowledge…

When using the ATMega’s A4 (PC4) and A5 (PC5) pins, everything can be hooked up using just the PWR/I2C connector. If this works as intended, it’ll make a nice and simple solar power setup for any JeeNode.

Anyway, I’ve ordered a MOSFET and an op-amp to see whether this idea can be made to work.

Update – looks like the op-amp can be avoided, the ATmega328p datasheet says the ADC input impedance is 100 MΩ, so two 1 MΩ resistors should work fine as voltage divider, with less than 2 µA power consumption.

Documentation conventions

In Hardware on Oct 19, 2009 at 00:01

With so many plugs and boards (f)lying around here these days, I’m trying to stick to a couple of tagging and documentation conventions.

First and most important one, is that each package has a unique ID which refers to a web page:

FlySketchExport.png

Even each board has such an ID:

FlySketchExport2.png

(this plug is now called an “RTC Plug”, btw)

When you type in the URL, you’ll be redirected to its main documentation page – for example:

Picture 3.png

Did I mention that everything on this site is open source, software and hardware? Well, as you can see above, all the design files are freely available. Enjoy… just don’t do anything with ’em your mother wouldn’t approve of.

The other way to get to these documentation pages is via the “DOCS” link at the top of all the weblog pages. It points to an index of all available documentation pages.

As you can see, all product IDs are two letters plus a version number from 1 to 9. URLs of the form http://JeeLabs.org/ + lowercase-letter + lowercase-letter + digit always redirect to the latest documentation page, regardless of the structure of this site.

I’ll let you know when I run out of all the 6084 codes :)

Of JeeNodes and JeeLinks

In Hardware on Oct 18, 2009 at 00:01

There’s a new JeeLink coming…

DSC_0543.jpg

No external connections, just a little antenna wire sticking out. Uses a 10 ppm crystal to accurately keep track of time and has 1 Mbyte of flash memory on-board so it can collect data in unattended mode. This new JeeLink’s only purpose is to attach to a computer for communicating with JeeNodes and several commercially available RF controlled devices (KAKU, FS20, etc). It has three LEDs: RX, TX, and ACTIVITY.

The above will be called the JeeLink (v2) – I’ve just sent off my second prototype to the pcb shop. Quite a few tweaks and tricks were needed to fit everything into such a tight enclosure:

Picture 1.png

The current JeeLink (v1) is also going to change. First of all, it’s going to be called the JeeNode USB (v2) in the next revision since it really is a JeeNode, but with the FTDI-USB adapter added-on. Other changes will be mostly to make the standard JeeNode and this new JeeNode USB even more compatible with each other.

A JeeSupply?

In Hardware on Oct 15, 2009 at 00:01

For some time now, I’ve been thinking about creating better tools for my own use here at Jee Labs. One of them would be a simple power supply with adjustable voltage and current limits. Nothing fancy, even 1 Amp is really overkill. But with a finely adjustable current limit and a continuous readout of the actual voltage and the current draw would be really nice.

Yes, there are lots of laboratory supplies. Cheap ones even, with such capabilities. I’ve got one. But they don’t measure or limit well in the milliamps range I’m interested in. And they are all so… b u l k y !

So the idea of a “JeeSupply” was born: a little unit which runs off any simple power brick, and which uses a JeeNode to perform all the control tasks. Why a JeeNode? Well, because then I could display the readout on the PC/Mac screen, and do it wirelessly without cluttering up my desk. And set it wirelessly as well, of course. It wouldn’t take much to turn it into a stress testing rig, gradually raising the voltage and plotting the current draw over time, or lowering to see when the circuit fails. Auto power-off. Watt-metering. Motor/servo test rig. Lots of extensions come to mind once it’s under computer control.

As I said, I don’t really need much power. Even just going up to 12 V @ 500 mA would be quite useful. Especially if the whole unit is so small that you can place it on the table next to the circuit it’s feeding.

Here’s a first design for it:

Picture 1.png

Click here for a larger PDF.

It has two switching power supplies. One produces 5V and powers the JeeNode and some of the other chips, the other is based on a L6902D and generates the requested voltage. This particular switching regulator has built-in current limiting. Normally, this would be done via a fixed current sense resistor, but in this case there’s a “high-side current sensor” chip involved which converts the current to a 0-based voltage level – this level is read out by the JeeNode, and also attenuated by a digital potentiometer to adjust the actual current limit. A second digital potentiometer is used to adjust the output voltage. This is all done via an I2C bus.

The digital pots have 257 steps, which is a bit limited at the end of the V and I ranges. For this reason, I added a second pair of pots in parallel to be able to tweak the values a bit more. My hunch is that the non-linearity of this setup may work out nicely, but I haven’t thought it through yet – these extra digital pots are entirely optional anyway.

The JP1 .. JP4 connectors on the left are connected to the port headers on a JeeNode. All pins have been assigned to some function, just to see how far one could take this.

There are two more connectors: one brings out the I2C bus to drive an LCD display, the other allows connecting some LEDs, buttons, and a rotary encoder to adjust settings directly. Both are optional – with remote control, this JeeSupply would need no other connections than a power jack and the two output power lines. It could all be built very compactly – not much larger than the JeeNode itself:

Picture 5.png

The above circuit can deliver up to 25 V or so, and can probably handle 1 amp. But I really don’t care – any 8 .. 30 V power brick will drive it. I just want it to work well in the 2 .. 5 V range with a few hundred milliamps of current at most. And because both supplies are efficient switching types, there will be little heat involved.

I haven’t built this circuit, I haven’t even tried it on a breadboard. But I sure could use a pair of these in my daily lab work. Something like this would definitely help detect and debug short circuits and other common electrical wiring mistakes in all those little projects sprawling around here. It might even save a chip from frying, occasionally.

What do you think?

An OOK relay

In AVR, Hardware on Oct 12, 2009 at 00:01

After having hooked up OOK radios in a few ways, I’ve decided to create an “OOK relay” – a little unit which listens for OOK-encoded data on the 433 and 868 MHz bands, and then re-transmits the decoded data as “normal” packets via the RF12 driver. OOK stands for “On-Off Keying” as opposed to the more advanced FSK – “Frequency Shift Keying” used by the RFM12B’s – i.e. AM vs. FM.

The benefit of an OOK relay is that OOK reception then automatically gets integrated into all the data collection from other JeeNodes that’s already going on anyway. Since an RFM12B can send both 433 and 868 MHz OOK signals, the end result is a pretty complete solution for all sorts of things going on over the air.

Here’s the hardware test setup:

DSC_0650.jpg

The 433 MHz receiver is seen from the side, standing almost straight up with the white antenna wire. It’s connected to DIO of port 1. The 868 MHz receiver is lying flat, with the red antenna wire, and is connected to AIO of port 1. Both receivers are powered from the 3.3V supply.

The reason for this particular setup is that I can use two different pin change interrupts for both: PCINT1_vec for 868 MHz and PCINT2_vec for 433 MHz. No need to decide inside the interrupt routine which is which – this saves some interrupt routine overhead.

The code was created from the two existing decoders for these receivers, and will be made available once everything is finished. Right now, the decoders work happily alongside each other:

Picture 3.png

Sample output:

Picture 2.png

I cheated a bit though by selectively powering the receivers, because there is a hardware problem… it looks like these receivers are interfering with each other. They only work when the other one is off. It’s not that surprising, given that one frequency is almost an exact harmonic of the other. Maybe placing the two receivers physically further apart, or adding better RF power supply decoupling will fix it. They should be able to work together, even receive signals on the two frequency bands at the same time.

More work left to do…

Experimentation setup

In AVR, Hardware on Oct 11, 2009 at 00:01

After coming up with the JeeBoard, which needs a PCB with at least an I/O expander and two LEDs/switches, I decided to go one step simpler and just wire up a version with no active components at all:

DSC_0565.jpg

It connects the same 3.6 .. 4.5 V battery pack through a slide switch, and ties a breadboard to the AIO + DIO pins of ports 1 .. 3, along with +3V and GND. With a few headers placed flat on the board for various plugs.

Wiring this up is simple – note the added rubber feet:

DSC_0566.jpg

Now it’s ready to go, with 3 rechargable NiMH’s:

DSC_0568.jpg

And here’s the final setup:

DSC_0571.jpg

Just to show how you can go nuts with plugs:

DSC_0570.jpg

The battery pack connection is removable to give me a nice spot to insert a current-measuring multimeter.

First demo of this board coming up tomorrow…

Mounting options

In Hardware on Sep 27, 2009 at 00:01

I’ve been getting some questions about mounting options for the JeeNode lately. And once some plugs are out, that same issue is going to come up for these too, no doubt.

There are no mounting holes in the JeeNode. The reason for this is that it would increase the size by quite a bit (one hole isn’t enough, even two is debatable), which in turn could actually reduce the options for using a JeeNode since it would be larger than the current design.

The basic solution for this for me, is to treat the JeeNode as a module that plugs onto something else – be it a generic board such as the Jeeboard idea I described a while back, or a custom board created for a specific application.

Here is an example of a JeeNode with an LCD display:

Picture 2.png

Note that the JeeNode is mounted upside down, with the components facing downwards.

But where do you go from there? One approach would be to place a transparent acrylic plastic panel over this entire thing, with some stand-off’s to create a sandwich consisting of base panel, JeeNode and other components, and the acrylic panel on top. That’s the geeky way to do it: make the electronics visible!

I’m not sure I’d always want that. I also like things which are “closed”, with only control/display functions visible, and the whole thing having a nice and calm front plate.

This would be an intermediate solution – a clean front panel hiding all the techy stuff underneath it:

Picture 3.png

Still open on the side, where the connectors, power jacks, and even simple controls switches could be located.

The reason why all this awkward compromising is needed of course, is that with only single units (or say a few dozen kits), there is simply no way to get custom enclosures made that are affordable and also really look sweet – a JeeNode is not an iPhone!

Here are a few other options I’ve been pondering about:

  • Cardboard – design a fold-up box and print it out as template for a DIY cardboard enclosure. Would be very low-cost, but not very sturdy. And it looks a bit cheap…
  • Wood – this is the classical enclosure: a lot of work, but you can make it look any way you like, if you’re willing to go through all that. Takes a lot of craftsmanship.
  • Sandwiched foam – of the kind used as poster board for photographs. Again, a DIY design which you’d have to cut out and assemble yourself. Probably not easy to get real clean edges, cutouts, and holes. Not truly sturdy.
  • Acrylic front – as described above: a base pcb with everything mounted on it and the acrylic as cover on top. The you-can-see-what’s-inside option. Not easy to do yourself without a laser cutter or CNC router.
  • Aluminum front – this is a variation of the acrylic front. End result is no longer transparent, but creating a clean panel with labels is not trivial.
  • Prefab box – this is what many hobbyists do: get a plastic box, and drill holes and cut-outs in it, possibly also with an aluminum faceplate. Again, hard to get a nice clean result without a CNC router. But to be honest, I don’t think these (mostly black) boxes look that spiffy…

I really would love to find a nice generic solution for this. Right now, since pcbs are already being made completely to specification, and because they end up looking quite nice, I’m inclined to look for solutions with either the front, the back, or perhaps even both made of pcb material. With SMT components, most if not all through-holes can be avoided, leaving the back side available for all sorts of visible cutouts and labeling.

So what’s the solution? Just let everyone figure this out for themselves? Start saving for a laser cutter or a CNC router to be able to provide simple but accurately machined parts? To be honest, I wouldn’t mind doing the CNC thing – but until it becomes clear what a desirable result should look like, there’s little point picking any tool!

And then there’s plugs and daisy-chained plugs…

If you’ve got further suggestions or ideas on how to come up with kits that not only work well but also make the end result look really nice, please let me know!

Parts!

In Hardware on Sep 25, 2009 at 00:01

The flip side of experimenting with electronic stuff, is that you end up with a lot of little things!

DSC_0530.jpg

To avoid losing my sanity, I’m now trying to get organized. The above has about 50 bags with one or a few tiny parts in them, mostly stuff from DigiKey and Farnell. SMD, through-hole parts, sensors, little batteries, buzzers, you name it…

And that’s just a fraction of the mess I’m creating around here :)

Anyway, I’ve been spending my time to try and get to grips with this. Bags of similar sizes in one box. A sheet printed out with unique label numbers, and then the work starts: put label on bag, place in box, and add a line to a little database with Location, Label, Description, and Notes. Then it won’t matter where the stuff is, since it’ll be tagged with a note in the database. I use DEVONthink for this, its storage and search capabilities are just right for me.

The trick of course, is to use tags. I’m going to start using the different vendor options to add my own tags during the on-line ordering process. Doesn’t matter one bit what the tag is, as long as it’s unique. I’m using tags like F0001/F0002/… for Farnell items, D0001/D0002/… for DigiKey, etc. By printing a batch of them on a sheet, it’s trivial to keep all tags unique. I don’t have small labels, so I print on larger ones and then slice up the sheet to create lil’ ones:

DSC_0532.jpg

The texts are created in Tcl/Tk by placing a bunch of them on a canvas the size of an A4 sheet along with thin cutting lines, and then saving the result as postscript. So now I can run “numprint X2500” to get a printable sheet of labels X2500 .. X2639 in exactly the right spot. Very configurable, very automated.

So trivial. So overdue…

Bi-color LED

In Hardware on Sep 23, 2009 at 00:01

In trying to save precious I/O lines, I wanted to use one line for three states:

Picture 2.png

Red (logic 1), green (logic 0), and off (tri-state).

The way this SMD bi-color LED is connected is:

Picture 3.png

The idea being that together, the forward voltages of these LEDs is more than 3.3V, so they can’t both light up. Both are rated at 2.0 V typical (2.4 V max) forward voltage.

And in fact it almost works as expected. The only problem is that when the I/O pin is left floating, the red LED still lights up dimly – it’s hard to see in the photo, but it really does.

These LEDs are rated at 80 mA peak and 30 mA continuous, btw – so I figured I wouldn’t need a resistor, at least for the test. For a more permanent setup, a 100 Ω resistor between this circuit and the I/O pin would probably be better.

I wonder if there is a simple way to turn the red LED completely off – a 1N4148 diode between 3.3V and the red LED perhaps? That might also dim it a bit, since it’s brighter than the green one.

Geek news: this is post # 2^8 :)

Update – the extra diode helps. Here’s a better test, showing red, orange, green and off:

Picture 2.png

The “orange” isn’t truly convincing with the clear LED I’m using, but its reflection on a piece of white paper looks ok.

Four states on a single I/O pin!

Connecting a battery

In Hardware on Sep 17, 2009 at 00:01

There are a number of ways to run a JeeNode off batteries. The lower bound is around 3.5 .. 3.6 V, depending on current draw. With 3.5V, the voltage regulator only has about 0.2V to work with, which is probably ok as long as the total current consumption stays under 50 mA or so. The maximum allowed voltage is around 13V, but drawing too much current at that level will lead to excessive heating and cause the voltage regulator to shut down.

So with alkaline and NiMH, you need only 3 cells.

For temporary connections, use the FTDI connector:

DSC_0496.jpg

For more permanent connections to the JeeNode v3, you can hook up a 3-or-more-cell battery pack as follows:

DSC_0497.jpg

The 10 µF capacitor next to the battery connectors can then be folded flat over these wires again, if needed.

Another option would be a 9V battery:

DSC_0498.jpg

Keep in mind that 60% of those 9V will be turned into useless heat in the voltage regulator…

And then, there is the option of using a rechargeable Lithium cell (LiPo). They supply 3.7 .. 4.1 V – a perfect match, if you take the proper safety precautions with charging them.

Update – note that the FTDI connector and battery connectors are both attached to the same “PWR” line, so please remove the battery (or add a disconnect switch) when connecting the unit to FTDI.

JeeNode pinout

In Hardware on Sep 16, 2009 at 00:01

I don’t think I published this pinout overview before:

jeenode pinout.png

Also available as PDF – use your printer’s print-4–pages-per-sheet setting to print a smaller version as reference.

Port extension

In Hardware on Sep 15, 2009 at 00:01

Found these 6-pin female-to-female cables at Seeed Studio:

DSC_0495.jpg

Available in 100, 200, and 300 mm lengths.

By adding an extended-length 6-pin male header as shown on the right, this can be turned into a convenient extension cable for ports and plugs.

The color coding helps create a convention for ports, since their connectors are not polarized, but be careful – it looks like my batch used a different set of colors than what is currently showing on their website. And the colors also differ from an FTDI cable, alas.

Ah, conventions… so many to choose from! ;)

Daughterboard

In Hardware on Sep 13, 2009 at 00:01

Here’s a simple design for a little “Proto Board” which covers all the port headers and the ISP/SPI connector:

Picture 1.png

The PWR/I2C header on the JeeNode is not covered by this board. I’m still exploring some options, hence the unmarked rectangle at the right end. The board is deliberately slightly asymmetric, to make it easier to remember which way it goes on.

Holes will be plated through as always, with text labels on the other side as well.

I’m considering not adding any connections to allow all solder pads to be used in various ways. This does mean wires need to be attached directly to the header pins to use them.

Just exploring for now – I’ll probably add this to the next panel prototype run, just to see how it works out.

Boot loader problems

In AVR, Software on Sep 11, 2009 at 00:01

Whoops – I messed up with several packages I’ve sent out to people. Ouch.

The gory details are in the discussion forum, but here’s the short version:

  • I’m shipping ATmega’s pre-programmed with the Arduino bootstrap and the RF12demo sketch. Mighty convenient, since it can get you going a lot quicker.
  • And to simplify my work I, ehm… sort of tried to automate it a bit.
  • So I burn the bootloader with the Arduino IDE and the burn the RF12demo sketch using “avrdude” from the command line.
  • Cool. Except that the second step undid the work of the first step… doh!
  • So I ended with ATmega328’s which have the RF12demo but no bootstrap loader.

It turns out that avrdude erases a chip by default when re-programming it. So the bootloader, which is loaded in high-mem, got cleared when storing the demo in low-mem. And of course that doesn’t show in a quick test: the demo on the chip, which I always check, works just fine. Which is why I sent out a few bad JeeNode kits and JeeLinks.

All it took to fix this was one lousy little “-D” command option for avrdude!

So now I’ve decided to automate all the way, and burn the fuses, the bootloader, and the demo sketch all in one go – from the command line.

Here’s what it takes – I have these files in one directory:

Picture 1.png

The hex files were copied from the Arduino “bootstrap” area and the RF12demo “applet” build area, respectively.

The makefile contains these commands:

Picture 2.png

So all I need to do now is to plug in the ISP programmer and put a fresh ATmega chip in its socket, then type “make”. This works for both the JeeNode and the JeeLink chips.

Easy… once done right!

Meet the JeeBoard

In AVR, Hardware on Sep 2, 2009 at 00:01

I hate wires. Wires to power up stuff. Wires to transfer data. What a mess.

I just want to try out physical computing ideas on my desk, next to my (wireless) keyboard and my (wireless) mouse – while exploring the possibilities of hardware + firmware + software running on my “big” computer.

So here’s to scratching my own itch: meet the JeeBoard – a little 8×10 cm unit with no strings attached – heh ;)

pastedGraphic.png

A first mock-up with real parts, here still using a green JeeNode v2:

DSC_0469.jpg

On the left, a couple of demo plugs have been inserted. Those that use I2C can be daisy-chained.

One port is permanently hooked up to an I/O expander chip with 6 digital I/O lines for the mini-breadboard, 2 LEDs, and 2 pushbuttons. The on-board battery pack provides 3.6V with NiMH or 4.5V with alkaline cells.

The little overhanging board on top of the mini-breadboard “feeds” 8 wires into the center of the breadboard: +3.3V, ground, and the 6 general-purpose I/O lines.

I’m going to mess around with the layout a bit and explore some actual hookups before designing a real PCB for this. But even just looking at the mockup makes me want to start trying out stuff with it. Wireless, of course!

JeeNodes now with 328

In AVR, Hardware on Aug 31, 2009 at 00:01

Starting now, I will be replacing the ATmega168 by the ATmega328p in all future JeeNode kits:

DSC_0467.jpg

Twice the memory: 32 Kb flash, 1 Kb EEPROM, and 2 Kb RAM – and twice the creative fun!

Memory Plug design

In Hardware on Aug 30, 2009 at 00:01

Got some ideas about storing a bit more data than the JeeNode can handle by itself, so here’s a little plug for EEPROM memory chips:

Picture 4.png

There’s room for up to four chips, i.e. 64 .. 512 Kbyte total. Plenty for a bit of data-logging and for storing compiled sketches / code for remote nodes. Or you could push for new limits with a flash-based O/S :)

This uses an I2C bus: the 6-pin male header on the right plugs into a port and is wired-through to the 6-pin female header on the left, just as with the Expander Plug described a few days ago. The width of this board has been increased so that it can’t be mistaken for a dual-port daughterboard.

Ok, so much for plugs… I need to re-check and finish each one and get a few prototype boards made!

Sensor data coming in

In Software on Aug 25, 2009 at 00:01

There are now a few sensors installed around the house. The only inconvenience is having to run a low-voltage power line to these units. I’ve reduced the number of wall plugs (and the number of wall outlets “consumed” by them) by putting two sensors on a single power supply and placing them close to each other where possible, i.e. on two sides of a wall, overlooking adjacent rooms.

Also added a new graph page to the JeeMon web server to view all readings added to the database:

Picture 4.png

To give you an idea of what’s involved in producing this graph, here’s the “try-rooms.html” definition file for it:

Picture 3.png

It’s written in the Tcl language, using my own “rig” template mechanism to generate HTML pages. The actual graph is drawn in JavaScript by the “Flot” package.

RJ11 daughterboard

In Hardware on Aug 24, 2009 at 00:01

For connecting the JeeNode to a bunch of opto-sensors to track energy, gas, and water consumption, I’m thinking of using RJ11 telephone cables. Not only is the 4-wire version of these cables easy to get and cheap, you can in fact get two cables by cutting them in half and connecting the loose wires to whatever you like.

Here’s a daughterboard idea which would make it very easy to use JeeNodes for such a setup:

DSC_0445.jpg

This is a mockup – the pin distances do not fit the 0.1″ proto-board grid, but you get the idea. Should probably add a power-on LED as well.

The power jack makes it easy to attach any standard 4..12 V power adapter. The 6-pin FTDI connector on the side is only for re-programming the unit – it can be omitted if you flash the ATmega with the proper code before inserting it into its socket.

I’m not sure what to do about mounting such a unit, though…

Update – The term “RJ11” is not quite accurate. It’s a 6-pin socket (RJ12), which could be used either with 2 (RJ11), 4 (RJ14), or 6 (RJ25) wires connected, as described on this page, for example. So it’s more like an RJ12 daughterboard, for use with RJ14 or RG25 cables.

Lots of nodes

In AVR, Hardware on Aug 22, 2009 at 00:01

I’m gearing up to install over half a dozen nodes around the house to monitor temperature, humidity, light levels, and to detect motion:

DSC_0444.jpg

The plug at the bottom is a one-off to check out the connections for the EPIR version.

These are my last JeeNode v2 boards, salvaged from various experiments, with all their port headers replaced by the new 6-pin-female-up standard.

Given that these are v2 boards, I’m hand assembling the plugs to match the “old” port pinout. Beyond these, I’ll use the new v3 boards with a little pcb “room plug” to be created later.

Back to soldering a few more of these little sensor critters!

New home sensor setup

In Hardware on Aug 19, 2009 at 00:01

Here’s my new prototype for sensor nodes in the house:

DSC_0435.jpg

It has an SHT11 temperature/hunidity sensor, an LDR, and a PIR motion sensor. Prototyped using a JeePlug, of course. Ports 2 and 3 are still unused. Note that this little board can also be plugged into ports 2/3 or even turned around – all configurations will work (by adjusting the port numbers accordingly).

Here’s a silly mounting option, which will have to do for now:

DSC_0434.jpg

This setup is attached inside a bookshelf under the top panel, roughly pointed so the motion sensor covers the room. Not shown is the power connection from a 5..12V wall-wart (I’ll look into battery mode at a later date).

Totally crude, but it works and lets me easily detach the unit between tests.

Here’s another prototype based on old “plugs” I had lying around and a JeeNode v2:

DSC_0436.jpg

The source code for this is called “rooms” and replaces the older “pulse” sketch. It’s available here. It handles both configurations, i.e. the ELV PIR and the ZDOT SBC.

This setup will be used instead of the earlier “pulse” design described in these posts. If there is interest, I can design a little board for it handling either PIR module.

Building the JeeNode v3

In AVR, Hardware on Jul 15, 2009 at 00:01

The v3 boards are finally ready! Here’s a step by step overview on how to assemble a JeeNode v3 kit:

DSC_0427.jpg

You’ll need some basic skill at soldering but don’t worry, as there are only a few parts to solder on. The best way is to start with the lowest-profile part, that way you can place things flat on the table and press down to keep the parts in place. So let’s start with the 10 KΩ resistor:

DSC_0408.jpg

Turn the board around and solder the leads:

DSC_0409.jpg

Then carefully cut them off:

DSC_0410.jpg

Continue in a similar vein with the four 0.1µF ceramic capacitors:

DSC_0413.jpg

Next the IC socket, which is a bit more work. The best thing is to solder two diagonally opposite pins, then check that the socket is pushed in all the way:

DSC_0414.jpg

If not, reheat and fix it. Then solder the remaining 26 pins:

DSC_0415.jpg

The 10 µF electrolytic capacitor is polarized – there is a “+” marking to indicate which way it should be soldered in. I normally bend the leads first and then make it lie flat on the board:

DSC_0416.jpg

Next the voltage regulator IC. This one needs special attention because it has to be mounted differently from what the marking on the board says. The reason is that the board was designed for an LP2950, but the kit includes an MCP1702 which has a different pinout. Here is how it should be mounted:

DSC_0417.jpg

The 16 MHz resonator is next, it’s the tallest part on the board:

DSC_0418.jpg

You’re almost there now. The radio module is a surface mounted module, which needs a slightly different approach. Put a bit of solder on one pad, then place the module over it and reheat to stick it in place:

DSC_0419.jpg

Once correctly positioned, add solder to each of the remaining pads to make shiny round joints:

DSC_0420.jpg

The 6-pin male FTDI connector can now be soldered on, I usually mount it sideways, but the choice is yours:

DSC_0421.jpg

A simple wire acts as antenna for the radio – attach it to pin 1 of the radio module. You can bend it as needed afterwards. I used a red wire, even though the kit probably has a yellow one.

One more step and you’re done: add the four 6-pin port headers.

Good, the soldering is over. Now bend the pins of the ATmega microcontroller slightly inwards so it fits into the socket. Make sure you only press it firmly down after all the pins are in the proper position.

Voilá! Your finished JeeNode:

DSC_0424.jpg

If you have a USB-BUB adapter, you can now plug it in and try out the board (note the 3.3V jumper – the JeeNode uses 3.3V logic signals). The ATmega that comes with the kit is pre-loaded with the RFM12demo sketch to get you up and running in no time:

DSC_0428.JPG

That’s it. Congratulations with your new JeeNode v3!

Reflow controller

In AVR, Software on Jul 14, 2009 at 00:01

Yesterday, I presented my new reflow system. Here’s the temperature graph from a sample run:

graph.png

The purple steps are the different phases:

  • Preheat (50) is whatever time it takes to reach 140°C.
  • Soak (100) is a 30-second temperature ramp up to 170°C.
  • Dwell (150) is defined as whatever time it takes to reach 220°C.
  • Reflow (200) is defined as 20 seconds at 220°C.
  • Cool down (250) is where the buzzer goes off and I open the lid.

The green bands indicate when the heater is on. The blue line is the target temperature which the system is trying to reach. The red line is the actual temperature. As you can see, the heater stops well before target temperatures are reached, and does a pretty good job of ending up in the desired range.

All in all, this appears to be ok. The 700-watt heater isn’t quite hot enough to ramp up 3°C/sec, more like 2°C/sec at best. Since the grill isn’t heating up quickly enough, the soak phase ends up taking 60 seconds instead of the planned 30, so the target stays pinned at 170°C a bit longer. This could probably be shortened by aiming directly for 170°C, but I don’t think this phase is critical. My only concerns are that it took about 80 sec to “dwell” from 170°C to 220°C and that the system is above 200°C for some 60 sec. This was shorter in other trials, but as you can see the heater is turning on a few times to nudge the system towards 220°C as things slow down a bit.

This plot was produced by a really nice free package for the Mac, called Plot (how original). The readings were obtained by logging the sketch output from the USB port and reformatting it to tab-separated numeric values.

Mounting a JeeNode with plugs

In Hardware on Jul 9, 2009 at 00:01

As promised: here’s an idea how to combine things. First let me show that plug pinout again – because I can…

Picture 3.png

An idea I’d like to present is to mount the JeeNode facing down. The board would look something like this:

DSC_0396.jpg

Each of the four port groups has the corresponding pins tied together. With a JeeNode plugged in you get this:

DSC_0395.jpg

And with some example plugs added:

DSC_0394.jpg

Note how plugs mount the proper way up, i.e. lying flat on the perf-board, because the upside-down mounting of the JeeNode takes care of mirroring the connector. The only thing to keep in mind is that port numbering now runs clockwise, with port 1 in the top right.

The extra female headers can be used for testing, or as simple breadboard pins for hooking up some LEDs. Some space could be saved by leaving them out, though.

I think there could be several advantages to this setup:

  • plugging stuff in the “right” way becomes quite obvious
  • if you wire up plugs appropriately, you can chain them sideways (i.e. for I2C use)
  • mix and match: put some components directly on the board if you prefer
  • it’s all easily constructed with off-the-shelf “perf board” (with or without copper)
  • it could even be made from a piece of cardboard with a few holes in it
  • my favorite fastening system works: a couple of zip-locks to tie things down
  • for better protection, simply add a cover and leave cables coming out the side
  • the whole sandwich can be solidified with spacers and remains low-profile
  • it’s all laid out in the plane – place a paper design on the board to guide you
  • it’s easily documented: just take a picture of it…

But perhaps best of all, you can still create a completely different setup for permanent use. Just unplug everything and re-assemble it in some other orientation. So while this approach takes up relatively much space for the connectors, it does give you total flexibility to re-arrange things any time later.

I’ll try this out in a couple of projects. But even just with this mockup I noticed that having the plugs flat on a supporting surface makes it all surprisingly stable, and easy to carry around.

IO Expander

In AVR, Hardware, Software on Jul 7, 2009 at 00:01

Here’s a way to expand the number of digital I/O lines on a port:

3686066291_f856efcb63_o This is a JeePlug filled to the rim with tiny components and connectors. It’s based on a PCA8574A I2C 8-bit I/O expander. Each of 8 pins can be used either as inputs or as “mostly” open collector outputs. See the datasheet for details.

Here’s the bottom side of the plug:

3686871488_b2366a7459_o

Crowded indeed!

And here’s a demo sketch called “expander” which blinks the eight LEDs connected between PWR and the respective I/O pins:

Picture 3.png

As with yesterday’s example, this is running the I2C at maximum bit-banging speed, and seems to work fine. It’s used to make 8 leds blink:

3686871410_0e325c3a2b_o

The connector block on this plug has 8 sets of three connections: GND, PWR, I/O. Note that PWR is connected, not +3.3V. The reason for this is that I’d like to try driving a bunch of servos from this plug one day – it’ll load the JeeNode down a bit but it should be feasible.

The “expander” sketch has been added to the Ports library and is available as ZIP file and in subversion.

External memory

In AVR, Hardware, Software on Jul 6, 2009 at 00:01

For one of the projects in the Jee Labs, I needed a bit more “permanent” memory than the ATmega’s EEPROM or even flash could provide. Here’s what I came up with:

3683813851_d524fedae2_o

That’s a 64 Kbyte AT24C512B serial EEPROM memory which talks via I2C.

It takes only 4 wires to hook this thing up:

3684626986_c2c8f1119c_o

And this is the mess you get in when you don’t have the right connectors and need to deal with older boards:

3683813971_e00e924cb0_o

That’s the “regret plug” mentioned a few days back, to turn the downward pointing male header into an upward pointing female header, plus a “cross-over plug” to let me wire this thing up for the new JeeNode v3 pinout, yet use it on a (minimally populated) v2 board. Yuck!

Lesson: think about headers before deciding how to solder them on …

All future JeeNodes will be supplied with 6-pin female headers for the ports. Soldering them on pointing up is probably most convenient: it lets you stick little LEDs and wires in there, and JeePlugs can be placed pointing upright – such as this memory.

Back to the memory expansion. Here’s a test sketch:

Picture 5.png

Sample output:

Picture 4.png

As you can see, the count did not start with 255, as it would have if the EEPROM had still been empty. The JeeNode was powered off in between to demonstrate data retention.

This example code runs at full bit-banging speed – seems to work just fine.

The “eemem” demo sketch has been added to the Ports library and is available in this ZIP file as well as here.

There you go … a whopping half million extra bits of permanent storage :)

Ligthy power save

In AVR, Software on Jul 5, 2009 at 00:01

Getting the power consumption down of yesterday’s “Lighty” example turns out to be quite a challenge.

One thing to do is to separate out the logic for enabling the different sensors, and extending it to also support disabling all of them:

Picture 3.png

Powering down completely works best when all internal peripherals are also turned off, as implemented in the following code:

Picture 4.png

Now the trick is to enable some interrupt source to take us out of this deep sleep phase again. This could be the ATmega watchdog, but the radio watchdog uses even less power, so here’s how to stay off for about 4 seconds:

Picture 5.png

So far so good. This disables all power consuming sensors and internal circuits, preps the radio to wake us up in 4 seconds, powers off, and then reverses the whole process.

Bug there is a bug in all this – somewhere… From some earlier experiments, I would have expected to see a power draw of a few microAmps with this code. But for some reason, it never drops below 2.7 mA, i.e. still “burning” 1/10th of full power!

I haven’t been able to figure out yet where these milliamps are going :(

For the sake of argument, let’s assume this works properly. Then the next problem will come up, which is that measuring and sending packets every 4 seconds drains more power than I’d like to. It takes several milliseconds to measure all readings and send out a packet. But who needs readings every 4 seconds?

So the solution to this is to just sleep a bit longer, using the 4-sec wakeups to quickly read-out some sensors, and calculate their averages. Here’s is the final loop of the power-saving “LightySave” sketch:

Picture 8.png

This will integrate readings for 75x 4 seconds, i.e. 5 minutes, and then send out a single packet. Note how the power-hungry radio module is only enabled at the very last moment. All we have to do is make sure it’s ready to send, then send one packet, then wait again until the send is complete.

Then the loop restarts, sleeping in low-power mode, etc.

Only issue is to find out where the 2.6 mA are going! I’ll try to figure this out, and will post here once fixed …

Lighty

In AVR, Software on Jul 4, 2009 at 00:01

Let’s call yesterday’s mystery JeeNode “Lighty” from now on. As promised, here is the first sketch:

Picture 3.png

LightySerial reads out several sensor values each second and dumps the results to the serial port. Plain and simple – using the Ports library for most pins and Arduino’s analogRead() for reading out voltage levels on A4 and A5.

Sample output:

Picture 4.png

FYI, all the Lighty sketches are available for download as a ZIP file.

Now let’s turn that into a wireless version using two JeeNodes. The first step is to separate the measurement and reporting sides of things.

Here is the main code of LightyTransmit, causing it to send out its readings once a second:

Picture 8.png

It puts all values into a structure defined as follows:

Picture 6.png

… and then sends that off to the broadcast address, i.e. whoever is listening. No acknowledgements are used. If the packet arrives, great, if not then the next one will.

The receiver then takes it from there, here is the entire LightyReceive sketch:

Picture 7.png

Note that the Ports library is not needed here since the receiving JeeNode does not use ports, it merely picks up packets and reports them on the serial line.

That’s basically it. Each of these sketches compiles to some 3 .. 4 Kb code.

We’ve got ourselves a Wireless Sensor Network!

LightyTransmit uses about 24 mA. Tomorrow, I’ll go into reducing the power drain, because Lighty’s tiny 20 mAh LiPo battery won’t even last an hour this way.

Mystery JeeNode

In AVR, Hardware on Jul 3, 2009 at 00:01

Some more pictures from yesterday’s puzzle…

3681641100_900fdf0f6e_o

Added a second LDR on the left and a DS18B20 1-wire temp sensor. A 4.5V @ 35mA solar cell has also been soldered in.

The sensor is a TSL230R light sensor, as Milarepa correctly commented:

3679117790_f89f0caa7d_o

It has one frequency pulse output, with two other port pins used to control sensitivity (1x/100x) and frequency divider (2x/50x). The fourth I/O pin is used as power supply for the chip, so that it can be turned off completely in sleep mode.

Here’s the whole assembly from the side:

3681641152_3a6d49194e_o

And here the complete JeeNode (using a different solar panel which turned out to be too weak):

3679151344_f871517b7c_o

So what does it do? And what is it for?

Well, two things really – but I’ll be the first to admit that this isn’t truly general purpose and unlikely to be very meaningful for anyone else.

The first use is to help me take better pictures. The photos on this weblog are all taken using nothing but a white sheet of paper and plain old-fashioned daylight. Benefits are that it’s free and abundant, it needs no space for a light-box setup, and it tends to produce beautiful images.

The problem which you may have seen on this weblog, is that daylight ≠ daylight. Sometimes it’s too dark outside, and sometimes the light is too harsh. Worse still, many of the photos end up with a blueish tint. I’m having a hard time predicting this, so it seemed like a nice idea to just throw a bunch of light sensors together and try to correlate this to picture quality over a few weeks time.

The other purpose of this unit is to act as test-bed for long-term solar-powered use. That means getting the power drain down to very low levels of course. But I also added the ability to read out the voltage of the solar cell and of the battery, as well as temperature (solar cells are sensitive to that). And LDRs facing opposite directions, to try and detect sun vs. cloud cover weather info.

This seemed like an excellent project for JeeNodes and JeePlugs. Once it’s working well enough – auto-ranging the light sensitivity and such – I intend to put this up on the roof and just let it send out packets every 5 minutes or so, day and night. This will make an excellent yet non-critical test setup as well as allow me to track solar intensity over the entire year. Think solar panels…

Tomorrow I’ll post several sketches: one showing how to read out everything and report it over the serial FTDI connection, then two more to show how to turn this into a send/receive solution with two JeeNodes, and the last one showing how to get power consumption down.

Stay tuned!

JeePlugs have arrived

In Hardware on Jun 30, 2009 at 00:01

Got some JeePlugs in today – yippie!

Here’s how I’ll probably use them most often – with one or two sideways headers:

JeePlugs

(These boards were sent off before the big URL rename – such is life…)

Note that both ends and the middle rows are connected in a pairwise fashion. The middle row traces are thin and can easily be cut if necessary.

I used flat headers, soldered in the underside of the plug. That way you can chain them and they’ll hold the plug slightly above the plane for pins sticking out, etc.

Here’s one way to use them on a JeeNode:

JeePlugs

The blue is the new green – all boards from JeeLabs will be blue with white markings.

Note the orientation here: in this setup, components are mounted on the outside.

And here’s another way to use the plugs, as mini shields:

JeePlugs

The headers are soldered onto the inner rows, leaving the connections to each header pin available from both sides on the outer rows.

There’s nothing JeeNode-specific about these boards, by the way. They have plated through holes, which makes them more convenient for soldering components and wires on either side. And the pairwise pad connections can save a bit on wires.

Breadboard limits

In AVR, Hardware on Jun 29, 2009 at 00:01

Here’s something which isn’t a good idea with breadboards:

Breadboard limits

I used a socket with wire-wrap pins to be able to connect a few wires yet still be able to use the whole thing in a breadboard. If you look closely, you can see that the 5-pin metallic connectors inside the breadboard are pushed out – making the adhesive separate from the rest. Whoops.

Wire-wrap pins are clearly too thick to be pushing into breadboards…

New Jee Labs shop

In News on Jun 26, 2009 at 00:01

I’ve set up a web shop to simplify getting JeeNode kits – and whatever else comes out of Jee Labs – to those of you who are interested. The shop has its own web site:

shop.jeelabs.com

It’s a basic design, because this is not about trying to become the next Amazon. Or acting like it. Or trying to “project a corporate image”. I’ll leave that to others.

Nah, the JLS is just a an easy-to-use shopping cart setup for dealing with PayPal and bank transfers:

Picture 3.png

No muss, no fuss. I hope you like it.

Note that there’s a Product News page in the shop, which is a blog I’ll use to announce the “availability of new products”. I won’t clutter this daily weblog with that sort of sales/marketing drivel. To track both types of news, simply subscribe to both blogs.

JeePlugs are on their way

In Hardware on Jun 25, 2009 at 00:01

Ok, I’ve decided to get a bunch of JeePlugs made.

A JeePlug is a little prototype board designed to fit exactly on one or two port headers of a JeeNode (or JeeLink). Here’s the layout:

Picture 6.png

See an earlier post for a description of how these plugs can be fitted to the JeeNode / JeeLink.

Some of the holes are connected in a pairwise fashion. With traces which can be cut when such a connection is not desired. The outermost two rows are for header pins and wires to connect to each pin, respectively.

The main intended use for these plugs is as a mini-breadboard hanging off the side of the JeeNode, so that up to four of these can be attached at the same time. But sometimes a single AIO + DIO pin just isn’t enough, in which case these plugs can be used as mini-shields bridging across two opposite ports.

It’s pretty low-tech obviously, but I expect these plugs to be a huge time-saver. Not just because they make it easy to hook up all sorts of sensors, indicators, and actuators, but because the result really is a plug. They can be mixed and matched at will, since all ports are equivalent. All that’s needed is to adjust the port number in the sketch / code to match the chosen header, a trivial 1-line change.

And because ports are so versatile, each plug can be an analog + digital I/O line, or an I2C bus, or a serial line. There are definitely limits to this approach, given that a JeeNode is after all based on a micro-controller, not a full-blown PC – but still.

Being flexible, modular, and inexpensive – that’s what JeeNode ports are really about. Oh yes… and wireless :)

I hope to get various plug examples going in the Jee Labs in the months ahead.

Meet the JeeLink

In AVR, Hardware on Jun 24, 2009 at 00:01

I’m proud to announce a new board next to the JeeNode, called the JeeLink. Yes, there’s a pattern in the naming choices made for products on this site.

The JeeLink is very much like a JeeNode, but in the format of a USB stick and with a few small differences listed below. Here’s the layout:

Picture 2.png

As you can see, the JeeLink has basically the same headers as the JeeNode, but with a USB plug in the place of the JeeNode’s FTDI connector.

The JeeLink is useful in two different ways, I think: first of all, if you have a couple of remote JeeNodes, you’ll probably need a central node as well to tie the whole network to a personal computer. The second use case is that it can be used as a JeeNode with built-in FTDI-to-USB conversion – which is exactly what it is, technically speaking.

A major difference with the JeeNode also, is that the JeeLink is built with SMD parts. The intention is to make it available in pre-assembled form and as bare board. No kits with parts – that’s reserved for the JeeNode since I don’t want to stretch myself too thin.

There will be a more detailed description of the JeeLink once it is ready and working, but here’s a first overview:

  • the dimensions of a JeeLink are slightly different, obviously
  • the I2C and SPI/ISP headers are not in exactly the same position as on the JeeNode
  • there’s no battery connector (who needs one with USB?)
  • the FTDI-type USB connection includes two on-board activity leds

So there you have it – a new descendant in the Jee family. With on-board RFM12B wireless radio of course, and 4 ports to connect absolutely anything you like to. Just like the JeeNode.

The JeeLink is the initiative of – and was designed in collaboration with – Paul Badger of Modern Device. We’ve been having a heck of a time together, hammering out all the details and making sure the result will be as good as we can possible make such a new concept. I’m proud of the result, and hope you’ll like it as well. Should have properly working JeeLinks in my hands in July, assuming Mr. Murphy doesn’t barge in to spoil the party.

More JeeNode v3 changes

In Hardware, News on Jun 22, 2009 at 00:01

Here are a few more details about the upcoming JeeNode v3 board.

First off, I said no more changes w.r.t. the pinout. Not true – the I2C/PWR pinout has also changed:

i2c.png

For a couple of reasons which I don’t want to go into just yet. The GND pin is now on the outside, just as on the FTDI header. Note that PWR is the incoming voltage, not the regulated 3.3V at which the ATmega operates (including those SDA / SCL pins).

The other change worth mentioning here, is that components have been rearranged slightly to make room for 2 pads to connect a battery or battery pack – along with holes for strain relief. Both leads are clearly marked “+” and “-” to avoid polarity mistakes.

The JeeNode is well suited for battery use due to it’s 3.3V design and because it has no on-board LEDs. The regulator lets you choose from a huge range of battery options (hence the soldering pads i.s.o. a fixed battery choice): 3x or 4x AAA or AA, NiMH or Alkaline, or one of the increasingly popular 3.6 .. 4.1 V Lithium batteries, which are great as long as you take care not to short-circuit them and not to discharge them beyond their advised limits.

So there you have it. The new JeeNode v3 board is just about ready to send off to manufacturing. I hope to get my hands on them early July.

More SMD stuff

In AVR, Hardware on Jun 21, 2009 at 00:01

My adventures in SMD miniaturization-land continue:

SOIC chips

Those are two Atmel chips – an ATtiny85 (SOIC-8) and an ATtiny84 (SOIC-14).

Compared to 0603 parts, these are actually quite large. The distance between the pins is 1.27mm (0.05″), half of regular through-hole parts.

But you do need fine tweezers, and a ZIF socket to flash them or try them out without soldering is also nice:

SOIC chips

The lid snaps down, making a firm connection with each of the 14 pins.

Hm, I see now that the SOIC-8 dimensions are a bit wider than the SOIC-14 package. So the smaller package doesn’t fit in this (pricey) ZIF socket.

So not only is this stuff small – it’s also easy to overlook such differences!

Fortunately there are datasheets.

JeeNode v3 pinout

In Hardware, News on Jun 20, 2009 at 00:01

There are two important pinout changes in the upcoming JeeNode v3:

  • On all four ports, pins 4 and 5 will be swapped (AIO and +3V)
  • Pins 1 and 2 of the SPI/ISP header will become pins 7 and 8

So the final pinout for ports is:

Preview of “jeenode-v3.graffle”.png

The change isn’t being made on a whim – I’ve got several things plugging into ports here which will need to be changed to work with the new pinout. And it will affect everything plugged in for years to come. One of the reasons for the change is that it lets you plug in a 3-wire servo (pins 3..5). Another reason is that it is compatible with the BBB board already out there (also pins 3..5).

As before, a 4-pin connector on pins 2..5 is often all you need. The outer two pins are for more advanced uses.

As before also, pin 1 carries the input voltage to power the board, and can be anything from 3.5V to 13V. With an FTDI connector it will usually +5V. Batteries work great, anything from a 9V block, or 3x AAA/AA (both NiMH and alkaline), or even a LiPo battery.

Note also a small change in pin names: the 3.3V regulated power supply is now called “+3V” instead of the somewhat ambiguous “VCC”, and the interrupt line is called “IRQ” instead (was INT).

Every future JeeNode design will use this pinout on every port.

The new SPI/ISP header is (pin 1 at top left):

spisp.png

This is an “extended” ISP header. The main reason for this change is that pins 1..6 are now compatible with a standard 6-pin in-system programming connector, through which the ATmega’s fuses, flash, and EEPROM can be programmed. Note that the JeeNode is a 3.3V device, it should not be driven by an ISP programmer set to 5V voltage level.

The two extra pins are tied to digital I/O lines B0 and B1, and allow connecting more SPI devices to the JeeNode. Note that SPI is used internally by the RFM12B radio module, so these pins should not be re-configured for other purposes, although you could use SEL0 and SEL1 as general-purpose I/O lines if you want – a LED and a push-button switch perhaps.

I’ve made a few experimental add-ons using the SPI/ISP connector, such as this one. They will need to be adjusted for v3, but as with ports the same new pinout will be used for all future JeeNodes and derivatives from now on. Although some of them might not have such a connector at all.

That’s it – no more changes. Now I can “standardize” everything I want to connect to the JeeNode ports!

What a waste

In Uncategorized on Jun 19, 2009 at 00:01

What a waste… this box arrived today:

Waste

Stuffed with lots of brown paper.

And the contents was that single item laid out in front: a 15 ml resin flux pen!

Flammable, sure. But does it really have to be delivered that way? As a separate shipment and delivery? And by UPS, those huge brown trucks – always the largest delivery vehicles coming here.

Does that make me a major carbon emitter, energy waster, and polluter? I guess in a way it does :(

Don't sneeze

In Hardware on Jun 18, 2009 at 00:01

Ok, so this is what 0603 SMT parts look like:

Don't sneeze

That’s a 0.1 µF capacitor and a 10 kΩ resistor.

Trouble is, they are small

Don't sneeze

The “0603” part designation for SMD’s stands for 0.06″ x 0.03″ (roughly), which is 1.6 x 0.8 mm. Here’s a good overview, from that same SMT page on Wikipedia:

SMT_sizes_by_Zureks.png

Well, it sure is something new for me to try out such miniature components!

Fortunately, that’s as small as it gets (I’ll leave 0402 components to the industrial parts-placement machines). Other capacitors (3216), voltage regulators (SOT23), and microcontrollers (SOIC) are all a bit larger.

JeeNode headers

In AVR on Jun 17, 2009 at 00:01

More details about how to connect stuff to any of the four “ports” of a JeeNode. Each port has this pinout:

A few notes:

  • the DIO pin is for digital I/O only, the AIO pin can be for analog in or for digital I/O
  • a port has six pins, with both 3.3V (VCC) regulated and +V (PWR) unregulated power
  • with just a 4-pin header on pins 2..5, you still get the most important pins
  • if all you need is a single I/O line, you could even use a 2-pin header on pins 3..4
  • the IRQ signal is shared between all ports

Another thing to note is that the ports all have an identical pin-out, when looking from the outside of the board:

(the above two diagrams are from the JeeNode v2 PDF documentation)

And then there is the aspect of distances between the port headers:

headers.png

This is where the story gets a bit fuzzier:

  • JeeNode v1 uses A and B as distance between the port headers
  • JeeNode v2 and v3 use A and D as distance between the port headers

If you want your plugs to remain usable on all future JeeNode designs, then you will need to make sure that they can deal with separations between the headers as small as C and E.

I’m not saying there will be such JeeNodes any day soon, I just want to keep the option open to go there.

Prototyping with JeeNodes

In AVR, Hardware on Jun 16, 2009 at 00:01

Here’s a little board I used for a while with a JeeNode:

Pulse prototype

It has 6 female header underneath, which get plugged into a JeeNode with its header pins sticking upwards. It has an LDR, a diode I tried to use as voltage reference, a plugged-in SHT11 temperature / humidity sensor, a 3-pin connector to plug in a Parallax PIR sensor, and a 2-pin header (top right, behind the SHT11) which was used to connect a couple of 1-wire temperature sensors).

There are a couple of issues with this, though some are probably unavoidable for such one-off / ad-hoc solutions. For one: it’s a bit of a mess. One reason is that with this setup the 1-sided perf-board I used has to be mounted upside down to allow soldering in the female headers. That’s awkward, because it means you have to “surface mount” most components.

One option is to use perf-boards with plated-through holes. These are several times more expensive than single-sided boards, though. But more importantly, cheap one-sided boards are often based on “Pertinax” (SRBP) which is a lot easier to handle than FR-4 epoxy: you can simply break them on a sharp edge, with the row of holes acting as perforation.

The other problem with putting everything on a single board is reduced flexibility. In this case I had to add a second 4-pin female header on top to accommodate the SHT11 plug I had already made – which would have fitted just as well directly on the JeeNode.

One nice benefit of per-port prototyping is that it is easy to re-use this stuff in different configurations. In fact, as with the SHT11 plug showing in the picture, that’s precisely what happened.

So I’ve been thinking a bit about ways to use JeeNodes for experimentation. Which happens a lot around here. One simplifying convention is to always use male headers on the JeeNode. That leaves essentially two choices (ignoring sideways mounting for now):

Picture 1.png

I’m thinking of having a bunch of, ehm, “JeePlugs” made: tiny boards with a 6×8 “prototype” area containing plated-through holes, plus a 6-pin female header and connecting pads. Three ways to use these:

Picture 2.png

You’ll need male headers for use with a breadboard, but I’m assuming you’ve used the breadboard to figure out the connections with the bare parts, so this post focuses on using female headers for the JeePlugs.

In all cases, the orientation of the pins is the same, so once you have a plug set up with stuff on it, you could still use it in multiple ways. And plug them onto any of the 4 ports at will, of course.

One last refinement is to make these plugs around 20 x 25 mm – i.e. long enough to optionally plug onto two ports in that inverted 3rd example shown above. Here’s a first design:

Picture 3.png

It’s really not much more than a tiny perf-board of the proper size for JeeNodes with a couple of doubled-up connections. Using plated-through holes so components and wires can easily be soldered from either side.

The plugs are not labeled with pin numbers or signal names, because those depend on the orientation in which you use them. For that, use the markings on the JeeNode itself (starting with v3, that is).

These JeePlugs only makes sense in larger quantities, so I haven’t yet decided whether I really want to order them. I sure could use some, but it wouldn’t be practical to have less than a hundred or so of them produced.

New JeeNode v3 design

In AVR, Hardware on Jun 14, 2009 at 00:01

Here’s an – improved! – board design for the JeeNode:

Picture 1.png

The main two changes are: labeling of all the components and pins, and a change in the ISP/SPI pin header (pin 1 is now also pin 1 for ISP). All connectors are in exactly the same place, but the board is a tiny fraction wider.

For details, see the EAGLE files (jee-pcb-011.sch and jee-pcb-011.brd). The PDF of the schematic shows that the functionality is unchanged – other than the ISP/SPI header pinout change, this board should be 100% compatible with the JeeNode v2.

The v3 board was designed in collaboration with Paul Badger of Modern Device, to whom I’m most grateful.

I’ve just ordered a batch of these boards. Should be able to report here in ten days or so as to whether they are working properly. Let’s hope so!

Ancient technology

In Hardware on Jun 12, 2009 at 00:01

This is fun. For one of my numerous projects, I wanted to resurrect a 15 year old LaserPrinter which has been gathering dust for a while:

Ancient technology

A “state of the art” 600 DPI PostScript laser printer for the Mac. With a whopping 6 MB RAM and LocalTalk / RS-232 / Parallel interfaces. Those were the days.

Plugging it in and running a self-test from the menu was all it took:

Ancient technology

As you can perhaps guess from the Dutch report in the bottom left, it has printed a mere 8050 pages in its lifetime so far.

Yeah. Back then, they knew how to make things. You just turn it on and it works. That toner cartridge must be at least 10-years old, btw!

Got some ideas about hooking up a JeeNode to this thing, probably via the serial port. The printer draws a lot of power and does not really have a standby mode, so the RFM12B could be used to control a remote KAKU power switch, for example. We’ll see…

JeeNode v2 kit notes

In AVR, Hardware on Jun 11, 2009 at 00:01

Just to make sure I didn’t forget anything – here’s the contents of a JeeNode v2 kit with parts:

JeeNode kit contents

For those of you who are about to receive the kits: they should match what’s shown above. If I forgot anything please let me know and I’ll take care of it right away.

The ATmega168 is pre-flashed with the standard Arduino boot loader and the RF12demo sketch.

As for assembling these kits, the main thing to keep in mind is the orientation of a few components and the ways things should be hooked up – see the recent post and the reference doc and close-ups on this site such as this one:

JeeNode v2

These are first-generation boards without silkscreen (I’m still learning about all this PCB design stuff!), although there are tiny markings on the top copper layer if you look really closely.

One important detail I forgot about is the antenna: for these 868 MHz units, I use a piece of 85 mm insulated wire. It needs to be connected to the ANT pin, which is the one in the corner as you can see in the above picture. You need an antenna, I’ve not been able to bridge even the shortest distance without one.

Building the JeeNode

In AVR, Hardware on Jun 9, 2009 at 00:01

Now that a few people have started building JeeNodes for themselves, here’s a close-up:

MCP1702 detail

Make sure you put that MCP1702 voltage regulator in exactly as shown. That’s the TO-92 package in the middle.

The board was intially designed for an LP2950, which has a different pinout. The MCP1702 does not have ground in the middle, hence the twisted positioning.

Note also how I use flat 6-pin headers, even for the FTDI connector. All the header pads are large enough to solder them on in any orientation you like.

FWIW, I’ve still got 9 JeeNode boards left (and probably all the parts needed as well). So if you want ’em let me know. I can send bare PCBs for €5 each. Or the PCB with all parts including 868 MHz radio and pre-flashed ATmega168 for €17.50. Shipping included if you order more than one.

JeeBot Duo schematic

In AVR, Hardware on Jun 8, 2009 at 00:01

Heh – my most “sophisticated” robot so far. Here’s the plan for the electrical hookup of the JeeBot Duo:

Picture 1.png

There’s quite a bit of functionality in there, all the way to an on-board LiPo battery charger. Other things to note: the Baby Orangutan controller (BOC) can shutdown all power (to avoid running down the battery too far) and the JeeNode can reset the BOC if need be.

The two processors communicate with each other via an I2C bus. The on-board FTDI header connects to the BOC serial port and supplies power to the LiPo charger. The FTDI header on the JeeNode can be used for monitoring, control, and uploading, as usual.

JeeBot Duo – in progress

In AVR, Hardware on Jun 7, 2009 at 00:01

To continue this bot-craze, here’s another design, the JeeBot Duo

More JeeBots in progress

This design is considerably more advanced. From left to right:

  • two 50:1 micro motors with wheels and encoders (Pololu)
  • a 6-pin FTDI header
  • the Baby Orangutan 328 motor controller (Pololu)
  • underneath: a low-voltage boost regulator (Pololu)
  • at a 45° angle: IMU board with 2-axis accelerometer and gyro (SparkFun)
  • a JeeNode v2 with on-board RFM12B 868 MHz radio module
  • underneath: a 860 mAh LiPo battery

It’s called a JeeBot Duo because there are two processors on board. The plan is to put the self-balancing smarts in the Baby Orangutan – which has all the hardware needed to connect to all sensors and motors. The JeeNode is available for telemetry, remote control, and perhaps to connect to further gimmicks later on.

Initial tests show that the motors have plenty of speed and torque, and draw 40 .. 300 mA each, depending on load. The boost regulator can produce a constant 5.4 V for the motors, while the battery level gradually decreases. There’s a tiny bit of slack in the gears, which translates to about 1 mm of slack/travel on the wheels.

The remaining space is for a compass module and an on-off switch. That makes this a relatively complete autonomous unit, able to sense its vertical position and change, as well as the distance traveled and the compass heading. With the proper software, it should one day be able to respond to commands such as “go 2 meter north”, or “drive around in a 1-meter circle”.

But that’s a long way off. Lots of tuning and software development will be needed to get there…

Reliable RF12 communication

In Software on Jun 5, 2009 at 00:01

I’m currently adding a reliable communications option to the RF12 driver. This will deal with two important communication errors: lost packets (the receiver did not get the packet) and lost acknowledgements (the sender doesn’t know the packet has arrived). Both involve timers and re-transmissions, something which the current driver doesn’t provide for.

The current driver API is not affected, these changes only add functions. Here is how they should be called:

Picture 3.png

There are two parts, reception and transmission. Reception occurs at unpredictable times, which is why rf12_recvDone() has to be called fairly often. It’s very quick when there is nothing to do, so calling it inside loops is ok and cheap. The receiver code also handles all acknowledgements and other events, so it must be called even if you only intend to send data out. Also, you must always end with a call to rf12_sendReply() when accepting the data, even if the reply is empty.

Transmission can be started by you whenever you want, but you can’t flood the driver with sends, you have to wait until it has finished the previous one. This is why there is a check on “rf12_todo”. If it is ≥ 0, you have to either wait and re-check until it becomes negative, or give up this send and try sending new data later on. Note that sends can slow down indefinitely, for example when the receiver is out of range or even turned off completely.

There is a lot to say about how to design your communications structure, all way beyond the scope of this post. It becomes considerably simpler if you can set up things such that dropping packets is no big deal. By sending all values each time, for example. Or by adding a sequence number such that lost packets are easily spotted. The fancy term for this is to make requests “idem-potent” – the HTTP protocol and web browsers normally work that way too, BTW.

To send data reliably, set the “ack” argument of rf12_sendData() to 1 and be prepared to accept occasional slow-downs. To send data on a best-effort basis, set it to 0.

The last important comment to make here is about buffer management. The RF12 driver only does a limited amount of buffering – this has two important implications:

With received data, you may only access the incoming packet in rf12_buf between the rf12_recvDone() and rf12_sendReply() calls. At all other times, rf12_buf, rf12_crc, and rf12_len are indeterminate.

The other implication is that you have to provide a pointer to your own buffer with data to rf12_sendData(), and this buffer must remain available and unchanged after rf12_sendData() returns. The buffer is given back, i.e. available for your re-use, when rf12_todo becomes negative again. You can use multiple buffers and send a different one each time, as long as the current buffer being sent adheres to these rules.

Limited-bandwidth wireless communication such as with the RFM12B on the 433/868/915 MHz bands is more effective at best-effort packet delivery than at getting each and every packet across with 100% reliability. The RF12 driver is small and uses few resources, but it does come with some trade-offs. With the additions described above, you’ll be able to set up a reliable data stream when needed. I’ll report here when these additions are ready for use.

Telemetry

In AVR, Software on Jun 4, 2009 at 00:01

The JeeBot now has telemetry functionality, continuously sending real-time process data by wireless for analysis and display on a desktop PC.

It was quite simple to add this: send a buffer with the latest data every 200 msec, using the RF12 driver. No acks, no checking – the receiver grabs as much as it can off the air, and simply ignores invalid and lost packets.

Here is the essence of the code added to the JeeBot loop, which runs every 20 ms – in lock-step with the pulses it generates to control the servos:

Picture 2.png

A second JeeNode acts as receiver to pick up these data packets and transfer them to the serial port – here’s the complete sketch:

Picture 3.png

Sample output:

Picture 1.png

These values show what the JeeBot is doing while running on its own internal batteries … i.e. wireless telemetry in practice!

The next step will be to analyze and visualize this data to help me properly tune the PID control parameters. That’s more work.

Minimal motion

In AVR, Hardware on Jun 3, 2009 at 00:01

Now that I’ve been bitten by the robot bug, it’s hard to stop. Wanted to experiment with a minimal setup for self-balancing:

Minimal motion

These are 1.5 .. 3V motors with 1:96 gears from Conrad. What’s special about these is that they only need some 20..30 mA current, which is sort of within the direct-drive capability of an ATmega168. That means 2 I/O pins per motor can be used to create an H-bridge without any further electronics.

Here’s a small sketch to drive these from a JeeNode:

Picture 1.png

A couple of details show that this really is pushing the limit: without the capacitors, timing becomes erratic. Also, the delays between reversals seems to be needed to bring the motors to a stop. I suspect that there’s still some very bad stuff happening due to inductive kickback, so diodes to ground and VCC are probably required to avoid damaging the MPU chip.

But it does run. It’s all driven off a tiny 100 mAh LiPo battery in that picture above, and it kept going longer on a charge than I was willing to wait for. Probably over an hour – total power draw is in the 50 .. 60 mA range.

Anyway, this is even more spielerei than the JeeBot. Just wanted to find out whether these components might be used for a little baby balancer one day. This would also require wheels and at least an accelerometer.

Yet more AVR size comparisons

In AVR, Hardware on May 30, 2009 at 00:01

Ok, let’s finish off what I started yesterday – here are yet more tiny AVR boards:

Another AVR board line-up

From left to right:

  • JeeNode v2 – ATmega168/328, FTDI, wireless
  • Strobit – ATmega168V, FTDI, wireless
  • RBBB – ATmega168/328, FTDI, 5V power
  • iDuino – ATmega168/328, USB
  • Dorkboard – ATmega168/328, 5-pin FTDI’ish
  • Arduino Nano – ATmega168 , USB
  • Arduino Pro Mini – AtMega168, FTDI
  • Arduino Mini – Atmega168, 5-pin FTDI’ish

Here is the previous line-up again for comparison:

More AVR size comparisons

See yesterday’s page for a description of what is what.

If you look closely, you’ll see that yesterday I used a JeeNode v1 board.

Update – same photos, higher resolution: first, second.

More AVR size comparisons

In AVR, Hardware on May 29, 2009 at 00:01

Here’s another comparison of little AVR-based boards:

More AVR size comparisons

From left to right:

  • JeeNode – ATmega168/328, FTDI, wireless
  • Boarduino – ATmega168/328, USB
  • Stickduino – ATmega168, USB stick
  • Teensy++ – AT90USB646, on-chip USB
  • Teensy – AT90USB162, on-chip USB
  • Baby Orangutan – ATmega328, motor drivers

Unfortunately, I forgot to show the RBBB (Real Bare Bones Board), and the new Strobit unit (also shown here) – they both deserve a place in this line-up.

These little boards are not entirely equivalent, but all of them are great for AVR-based fun DIY projects.

Meet the JeeBot

In AVR, Hardware on May 27, 2009 at 00:01

Here’s a fun new project, the JeeBot:

Meet the JeeBot

A little platform with two continuous-rotation servos, a JeeNode, and a (4x AA) battery pack. It’s all mounted and fixed together with what I had lying around: strong epoxy-based perf-board and lots of fasteners.

The electronics isn’t “quite finished” as you can see:

Meet the JeeBot

The JeeNode can be removed. There’s a small slide switch on the side to turn on power.

First task would be to get this thing rolling and steering – adding a small coaster of some sort on the right side under the batteries, to keep this thing off the floor.

The more ambitious plan is to make this thing stand upright and self-balance… who knows, one day, maybe it’ll be able to walk roll on two feet wheels?

RF size comparison

In AVR, Hardware on May 26, 2009 at 00:01

Here are four very similar wireless AVR-powered solutions side-by-side:

RF size comparison

From left to right:

  • Arduino Duemilanove with XBee shield (ATmega168/328) – 2.4GHz
  • JeeNode with RFM12B (ATmega168/328) – 433/868/915 MHz
  • Strobit board with RFM12B (ATmega168V) – 433/868/915 MHz
  • Busware CPM with CC1101 (ATtiny84) – 868 MHz

The XBee has more software on board, giving it more functionality. The CPM module, which is only marginally bigger than a DIL-14 chip – including antenna! – does not come with software loaded AFAIK, but there is open source software available for it. The middle two boards are compatible with Arduino IDE “sketches” and support the RF12 driver library by yours truly.

Servo fun

In AVR, Hardware on May 24, 2009 at 00:01

Here’s some fun with a servo:

Servo fun

A slider drives the two servos in opposite directions, so you can make this thing turn on the spot.

Here’s the sketch:

Picture 1.png

Had to use SoftwareServo instead of the Servo library which comes with Arduino IDE 0015 – which didn’t work for me.

Turns out that only pulses from 1.4 to 1.6 msec actually have any effect on the speed of the servos, the rest of the 1.0 .. 2.0 msec range just makes them run at full speed. These ara Parallax (Futaba) Continuous Rotation Servos.

Note that the servos are driven from the PWR line, i.e. the full 5V – but the servo pulses are 3.3V, like the rest of the JeeNode.

It’d be nice to use a Wii Nunchuk controller as input. Even more fun would be an accelerometer / gyro combo to turn this thing into a self-balancing bot …

New RF12 sleep support

In AVR, Software on May 23, 2009 at 00:01

The RF12 driver has been extended to support power down as well as wake-up.

This example uses the RFM12B wake-up timer to generate an interrupt in about 1 second, then powers down, then leaves the radio off once power is back up:

Picture 3.png

That last call is important, because otherwise if the system happens to power up due to some other trigger, then the wake-up interrupt may happen later and cause problems. This way, regardless of why the system came back up, we make sure that the RFM12B wake-up interrupt stays off. The radio is still off at this point.

The argument to rf12_sleep() is a time value, in units of 32 ms. The maximum value is 127, i.e. 4 about seconds between wake-ups. If you need longer sleep times, change the logic to go back to sleep right away until the proper amount of time has elapsed.

To turn the radio back on, use “rf12_sleep(-1)” to start listening to packets again after the next rf12_recvDone() poll. Since the RFM12B consumes a fair amount of power, it’s best to wait with this right until you’re ready to send out a packet.

Here is the new code, which is now included in the updated RF12 driver:

Picture 1.png

The RF12 driver software is available over here or as ZIP, this is an Arduino-compatible library.

JeeNode Pulse revisited

In AVR, Hardware on May 21, 2009 at 00:01

The JeeNode Pulse hasn’t fully materialized yet – it’s the configuration I’d like to use around the house. Here’s a new configuration:

Pulse revisited

PIR and LDR on port 1, BMP085 on port 2, and SHT11 on port 3. There’s obviously no point in having a BMP085 sensor in more than one node, but for now it’s easy to leave it in for testing.

Different PIR sensor (from ELV). That sensor draws 30..40 µA – this matters for battery-operated use because it’ll be permanently on.

Here’s the main part of a first sketch, using the new power-down logic:

Picture 3.png

The code compiles to around 9 Kb. This includes floating point calculations in the SHT11 driver and the serial port reporting, both of which could be jettisoned later.

Sample output:

Picture 4.png

The values are:

  • temperature x10, from BMP085
  • barometric pressure x100, from BMP085
  • relative humidity, from SHT11
  • temperature, from SHT11
  • motion detect, from PIR (1 = no motion)
  • light level, from LDR (high means dark)
  • the number of milliseconds spent measuring

That last value is way too high for battery use – this code is spending 0.316 seconds collecting sensor data… in high power mode!

Breaking down the time spent, it looks like the BMP085 takes 2x 7 ms, and the SHT11 takes 2x 70 ms. The odd thing is that the SHT11 seems to take 300 ms when taking both temperature and humidity readings.

The good news is that the power-down current consumption of this setup is around 40 µA.

What needs to be done, is to spend the waiting time in these sensor read-out periods in power-down mode as well. The BMP085 driver already supports low-power readout by splitting the start and end parts of the driver, so that the waiting time can be handled in the calling loop. The SHT11 driver will needs to be adjusted to allow a similar approach.

With a bit of luck, only a millisecond or two will have to be spent in high-power (10 mA, haha!) mode. Then perhaps 2..3 milliseconds with the RFM12B radio active, and that should be it.

With a 15..60 second reporting period, the node would stay almost entirely in power-down mode. An average power consumption of under 100 µA total should be feasible – giving well over a year of service on 3 standard AAA batteries.

But that’s not all. To effectively use the PIR module, the code must be set up to handle motion-detect triggers at any time, also in power down mode. One approach would be to wake up (i.e. use a pin change interrupt), note the change and power back down. A refinement would be to “preempt” and start transmitting right away when motion is first detected – and then re-schedule future transmissions so the average reporting period remains the same. This makes the central JeeHub aware instantly of motion detected by the various nodes.

Parallel WSN choices

In Hardware on May 20, 2009 at 00:01

Just came across the eKo range of commercial products by Crossbow. Interesting how the eKo and Jee-Node/-Hub/-Mon designs almost exactly overlap – well, seen from a large distance anyway.

Their “JeeNode”:

Picture 2.png

Their “JeeHub”:

Picture 3.png

Their Linux server hardware and software:

Picture 4.png

Of course the eKo products are a million times more mature and advanced than the Jee-stuff which isn’t even a product, but still…

Future JeeNodes – thoughts

In AVR, Hardware on May 19, 2009 at 00:01

After several months tinkering with the JeeNode v2 boards, I’m starting to make a list of things I’d like to change for a future design.

What I’d like to keep:

  • having 4 identical “ports”, both physical and in software
  • running at 3.3 V, with on-board regulator
  • the wireless radio module :)

What I’d like to change:

  • switch to SMD to create a smaller unit
  • add a PCB antenna, even though it’s frequency band specific
  • add mounting holes

This could perhaps become the layout:

Picture 1.png

Not 100% sure about the SPI/ISP and I2C/PWR pin headers – though I’m inclined to keep them, somehow.

No idea when or even whether this ever materializes, just some thoughts.

Trying to receive OOK data

In AVR, Software on May 18, 2009 at 00:01

Here is an experiment to try and (ab)use the RFM12B module for OOK reception, such as sent out by a FS20 remote control. First the complete sketch:

Picture 2.png

The interesting bit is that this appears to work – the LED flashes when I press a button on the FS20 remote:

OOK receive trial

Since the signal is made to come out on the AIO port 1 pin (A0), this whole unit can be plugged into a second JeeNode running the OOK decoding code from an earlier post. Like this:

OOK receive trial

The reason for using two JeeNodes is that the one receiving the OOK signal is 100% tied up in a loop polling the status register. No problem – we simply upgrade to a dual-core setup :)

Unfortunately, the combination isn’t working yet. I’ll need to use the scope or logic analyzer to figure out what’s going on. Perhaps the RFM12B’s RSSI circuit is not fast enough to faithfully reproduce OOK transitions.

Oh, well.

Better PCB auto-routing

In Hardware on May 17, 2009 at 00:01

While surfing around on the web, I came across the FreeRouting website. It lets you grab a Java app which does auto-routing. It takes time, but it is quite advanced.

One feature really caught my attention: the ability to take an EAGLE .brd file, auto-route (or just optimize) it, and then bring the results back into EAGLE. It’s all documented here.

Here’s what it did to the JeeNode v2 design (jee-pcb-003.brd), which was routed 100% by EAGLE (after quite a bit of tweaking to make it succeed).

Before:

Picture 1.png

After:

Picture 2.png

(there are some discrepancies between the two, due to some hidden ground planes)

I haven’t checked it much, nor applied any DRC’s, but if it’s all correct then that’s 9 via’s instead of 26 – not to mention the considerably simpler traces. Impressive!

Power consumption – more savings

In AVR, Hardware, Software on May 16, 2009 at 00:01

Let’s get that JeeNode power consumption down

The no-savings baseline from two days back was 10 mA, with a few simple measures getting it down to 1.31 mA, i.e. waiting in idle mode with the pre-scaler set to 64 and turning the RFM12B clock off.

It turns out that the ATmega328 is quite a bit more power efficient in that mode, the same sketch consumes 0.67 mA, i.e. half that of an ATmega168. Great – that’s an easy gain. Unfortunately it doesn’t carry over as much to power down mode: 125 µA versus 137 µA. There is still some unexplained power use there – maybe some of the circuits need to be turned off explicitly, or some more output pins floated.

Anyway, the next idea to go beyond 1.31 mA is to use the watchdog timer for idling away in power down mode. The basic code structure will be as follows:

Picture 1.png

Ooh, wait – turns out that there is a simpler way, which doesn’t require changing the main application logic after all. We can let the watchdog generate an interrupt without resetting the system. Here’s the code I ended up with after some experimentation:

Picture 2.png

Note the added dummy watchdog interrupt routine. Without it, the code apparently enters a nasty infinite loop when the watchdog fires, which is hard to get out of – even after a hardware reset.

Usage: 139 µA while waiting – 99% of the time. Great.

The code can actually be streamlined a bit – simply leave the watchdog running to pull the processor out of power down mode once a second:

Picture 4.png

But there’s more. The ADC can be disabled to reduce the power drain even further:

Picture 5.png

Now usage drops to 24 µA while waiting. Cool.

One last change is to disable the brown-out detection, which in turn disables the internal voltage reference. Changing the high fuse from 0xDD to 0xDF drops total power usage to a diminutive 6.8 µA. Perfect.

So there you have it – 1500 times less power usage!

Update – see the discussion in this post for a change which gets this down to 3.7 µA …

Update 2 – changed the low fuse from 0xFF to 0xEE, i.e. 64 µs start-up i.s.o. 1+64 ms (ok for resonator, not ok for a crystal). This will help get the power up duration down once I start looking into it.

Power consumption – subtle bugs

In AVR, Software on May 15, 2009 at 00:01

Yesterday’s code has several bugs:

Picture 2.png

As already mentioned, a delay is needed to let the serial data leave the USART before the pre-scaler change messes up the clock and baudrate. But there are also two other serious problems:

  • the “limit = millis() + …” expression will overflow and fail (after about 49 days)
  • the “millis() == limit” condition can “miss a beat”, leading to an almost-infinite loop

Both bugs can be fixed by carefully rewriting the code:

Picture 1.png

The differences are subtle, but essential. Without it, the loop will get stuck within just a few seconds of starting the sketch. With the above fixes it’ll run properly forever… I think.

Power consumption – baseline

In AVR, Software on May 14, 2009 at 00:01

Ok, first step in lowering JeeNode power consumption is to establish a baseline.

Here is the original code, the first few lines of the loop that is – the rest is the actual sensor readout and calculations, which take about 10 milliseconds:

Picture 1.png

Usage: 9.80 mA (slightly different from yesterday’s post, hooked up to USB from now on).

First change is to make the delay loop explicit:

Picture 2.png

Usage: 10.05 mA – no idea why it’s slightly higher. Anyway 10 mA will be used as baseline – this is the current drawn before any power-saving measures are introduced.

First step: lower power use by putting the processor in idle mode while it’s waiting for the next readout time. Included “avr/sleep.h” and changed the loop to be as follows:

Picture 4.png

Usage: 5.58 mA – it works, cool!

Next idea is to lower the system frequency, but only while waiting – so that readout, processing, and serial I/O remain unaffected:

Picture 5.png

Usage: 1.99 mA – whee! But there is a small gotcha – the system now goes into slow mode before the serial port has finished transmitting. A “delay(3)” at the end (or start!) of the loop is needed to fix this.

For comparison: with just the pre-scaler and no idle mode, usage is 2.15 mA – so the bulk of the savings comes from slowing down the system clock. Idle mode saves roughly 10% at lower frequencies.

One more important saving is possible due to the onboard RFM12B radio module, which powers up with its 10 MHz crystal clock running. Adding a bit more code to access the radio and disable its clock lowers power usage from 1.99 mA to 1.31 mA.

So these three simple measures combined already lead to a 7.5-fold power reduction: “waiting” a bit more carefully and turning off the RFM12B. All without affecting the main application code in any way.

As for the bottom line: putting the processor in power down (from which this code won’t ever wake up) uses 137 µA – and removing the MPU chip brings it to 17 µA. Note that with 140 µA average usage, a JeeNode can run for two years on 3 standard AA batteries.

It ‘s possible to reduce the power consumption from 1.31 mA to the µA range by powering down the processor and using the watchdog timer to wake it up – but that requires another set of changes to code and fuses – stay tuned…

Update – see this more recent post for additional details.

Power consumption

In AVR, Hardware on May 13, 2009 at 00:01

This contraption:

Measuring power draw

… when connected as follows:

Measuring power draw

… makes it easy to measure the supply current, with a BMP085 pressure sensor hooked up in this case:

Measuring power draw

Just under 10 milliamps, as you can see. That’s just the JeeNode running the BMP085 demo at 16 MHz, sending a new reading over the serial port every second. The RF12 module has not been turned on.

If the JeeNode is to be used for a WSN, then it will have to get its power consumption down. Way down, in fact…

Something happened …

In AVR, Hardware on May 11, 2009 at 00:01

The electricity / gas metering monitor – which has been running for months – stopped working:

Picture 1.png

It just flat-lined, dead, nada. Power cycling everything and re-flashing the meter node did not fix it. I don’t see any packets from the meter node on the air when listening via an independent JeeNode.

The only packets right now are from a JeeNode pulse upstairs, which keeps resending – indicating that the central JeeHub isn’t replying with an ack. Weird.

I’ve adjusted all nodes to explicitly use netgroup 0x50, since there have been changes to the RF12 default netgroup and CRC calculation. Just to rule out a potential issue.

Still no go. I’m flabbergasted.

Update – uh, oh… the JeeHub 3.3V regulator is way too hot. It’s shutting down from time to time. Not good!

Time to switch to plan B – a JeeNode used as packet receiver connected to my “Bubba II” NAS. It’s been running all the time to collect weather data from the KS300 anyway. Still no electricity / gas metering data coming in, but at least all the remaining JeeNode and KS300/FS20 data gets logged again.

Update 2 – first there was one problem (JeeHub failing), then I created another one by re-flashing the metering JeeNode with the wrong node ID – doh! Anyway, metering data is coming in again now. Still don’t know why / how the JeeHub broke, but it was up for a hardware revision anyway…

New RF12 data packet I/O

In AVR, Software on May 10, 2009 at 00:01

Following up on yesterday’s new serial I/O layer, implemented on top of the RF12 driver, here’s another demo using the “<<” and “>>” operators to send data across. First the sample code:

Picture 5.png

Then the sample output:

Picture 3.png

Picture 4.png

(these are slightly older screenshots, not yet using “rf12_config()”)

The output is a bit mixed up because the nodes were not reset at the same time, but you can see the data coming in on both nodes. These are independent bi-directional transmissions, even though in this case similar data is being sent since the same demo is running on both nodes.

As with the “rf12serial” demo, there are still some serious limitations with this – I still need to debug and add more flow-/congestion-control logic in this new implementation (the code is in “RF12sio.cpp” inside the RF12 library).

Much of this sort of logic relies on timers: the “RF12sio.h” header defines a simple millisecond timer which is also available for general use.

New RF12 serial I/O layer

In AVR, Software on May 9, 2009 at 00:01

The new RF12 code is starting to work. I’ve added it to the RF12 library, along with a demo which sends characters across the wireless link in both directions. Here’s the code:

Picture 6.png

And here’s some sample output on two terminal screens:

Picture 1.png

Other side (the “transmittee” text is my typo):

Picture 2.png

There are still major flaws in the code:

  • it doesn’t properly pack/unpack small packets sent back-to-back
  • in fact, it chokes when too much data comes in
  • it seems to have trouble with the very first character sent

But it’s a start!

Teensies

In AVR, Hardware on May 8, 2009 at 00:01

The “Teensy” by PJRC is a tiny AVR processor with embedded USB device port:

Teensy

It’s similar but not quite identical to an ATmega168 Arduino (no analog inputs, no I2C, and some other diffs). But the basics are the same, and you can even adapt the Arduino IDE to feed it sketches.

Now there’s a “Teensy++” with 64 Kb flash, 4 Kb RAM / EEPROM, and analog inputs and I2C:

Teensy++

Plenty of oomph for much larger applications!

It’s still not quite what I’m after though, since these operate at 5V (although the Teensy++ can be made to run at 3.3V that only works when not tied to a USB port). I’ve all but abandoned 5V logic, because the RFM12B wireless modules require < 3.8V to operate and because battery power is simpler when in the 3 .. 4.5 V range.

Still, these look like nice little boards, and at a good price.

RF12 configuration in EEPROM

In AVR, Software on May 7, 2009 at 00:01

It’s becoming a bit tedious to set up and manage JeeNodes, each with their own RF12 configuration. Prompted by a recent request, I’ve created what I think is a much more practical configuration system using some of the ATmega’s built-in EEPROM.

The basic idea is to split the configuration and the setup code. The “RF12demo” sketch which is part of the RF12 library has been extended into a general EEPROM configuration utility. Here’s its new startup screen:

Picture 2.png

So now you can type commands on the serial port to adjust settings. These are stored in EEPROM along with a description string and a 16-bit CRC checksum. When launched later on, the last settings get re-used so this becomes a set-and-forget thing.

What’s more important though, is that the RF12 library has been extended with a new “rf12_config()” call which you can use instead of “rf12_initialize(…)”. It does a couple of things:

  • retrieve the settings from EEPROM and check that they are valid
  • if so, configure the RF12 hardware accordingly
  • display the current settings on the serial port

As a result, it’s now a lot simpler to set up a sketch with RF12 communication. All you need to do is upload and run the RF12demo once to configure things, then upload your own sketch and use “rf12_config()” to re-use the same configuration.

Here’s an example / skeleton:

Picture 4.png

The output from this sketch is:

Picture 3.png

It’s a bit cryptic to keep the code overhead small, but you can see that I configured this unit to act as node “Z” (i.e. 26), using network group 212, and operating in the 433 MHz band.

The RF12 configuration data is stored in EEPROM addresses 0x20..0x3F (this can be changed in “RF12.h” if it interferes with your own EEPROM use).

RFM12 vs RFM12B – revisited

In AVR, Hardware on May 6, 2009 at 00:01

Now that the RFM12 is working, here’s the list of differences between RFM12 and RFM12B I’ve come across:

  • The RFM12 works up to 5V, the RFM12B only up to 3.8V (but it won’t be damaged by 5V).
  • The RFM12 needs a pull-up resistor of 10..100 KΩ on the FSK/DATA/nFFS pin, the RFM12B doesn’t.
  • The RFM12 can only sync on the hex “2DD4” 2-byte pattern, the RFM12B can sync on any value for the second byte, not just D4.

More differences, found by Reinhard Max:

  • The B version can be set to a single sync byte.
  • The “PLL setting command” (CCxx), which only exists on the RFM12B.
  • Different values for RX sensitivity and TX output power.
  • A slightly different formula to calculate the time of the Wake-Up Timer.

Here is the back of the module, RFM12 on the left, RFM12B on the right:

RFM12 vs RFM12B

(these also happen to be for different frequency bands, as you can see)

And here is the front view, with RFM12 on the right and RFM12B on the left this time:

RFM12 vs RFM12B

The RFM12 unit on the right has a pull-up resistor added on top – note also the exposed pads at the top.

Note how the alignment of the solder pads on the JeeNode PCB is a bit off – these are v1 PCB’s, the v2 PCB’s have better alignment.

JeeNode in a bottle

In AVR, Hardware on May 3, 2009 at 00:01

When you have a hammer, everything looks like a nail. Or in my case, a potential enclosure for JeeNodes:

JeeNode in a bottle

This adjustable enclosure came with some small relays shipped to me a while back.

Now if only I could figure out a way to make JeeNodes run a while on these batteries:

3.7 V @ 100 mAh Lithium

That’s a 3.7 V @ 100 mAh Lithium cell. Three months endurance would be the minimum needed to make this practical, that’s about 40 µA average power draw (the RFM12B draws 30 µA in sleep mode, though that could be lowered tenfold by connecting it to a switchable regulator such as the LP3985). Hm, might actually be feasible.

Yet another PIR

In AVR, Software on May 1, 2009 at 00:01

Found yet another passive infrared module for around €10, by ELV:

PIR by ELV

Hooked up to port 1 of a JeeNode, and shown here with the USB “BUB” interface by Modern Device. Note that this uses a JeeNode with 6-pin port connectors, since the PIR module requires at least 5V. The output is open-collector, and therefore compatible with the 3.3V levels expected by the JeeNode (using the internal pull-up resistor).

Sample output, from a slightly adjusted version of the “pir_demo” example sketch which is in the Ports library:

Picture 1.png

Range and sensitivity seem to be ok. The signal is more jittery that with the ePIR and Parallax modules, it will have to be de-bounced it a bit in real-world use.

Receiving and decoding FS20

In Hardware on Apr 30, 2009 at 00:01

Here is a little kit by ELV which can receive FS20 signals and switch 4 independent open-collector outputs:

4-channel FS20 decoder

This board has an on-board regulator and requires 5..24V DC. Most of the components are SMD’s on the other side, the wire bridges show that this is a single-sided pcb.

Pretty obvious stuff… my reason to buy this was simply to get another 868 MHz receiver module!

RFM12 vs RFM12B

In AVR, Hardware on Apr 29, 2009 at 00:01

Here’s an RFM12 433 MHz module from Pollin, hooked up to an Arduino Duemilanove:

RFM12 (not RFM12B) @ 5V

One major difference between the RFM12 and the RFM12B is that the RFM12 can run at 5V, whereas the maximum operating voltage for the RFM12B is 3.8V (it can withstand up to 6V, which is good to know).

Alas, there seems to be some other difference which eludes me, because the RFM12 hooked up in the above picture only seems to be able to send. The RF12 demo code, which works fine for send and receive on RFM12B’s seems to do something wrong. Same behavior with another RFM12 module – so it looks like this is not due to a broken module. Send works, but nothing is coming in other than occasional garbage data.

The transmit part works fine when sending to an RFM12B, also in OOK mode: the RFM12 successfully controls both 433 and 868 MHz units (KAKU and FS20, respectively). But as packet receiver for other RFM12 or RFM12B modules … no joy so far.

Weird. Tips, anyone? Please let me know.

Update – Thanks to R. Max’s comment below, the problem has been solved: the RFM12 does not support arbitrary 2-byte sync patterns, it has to be 0x2D + 0xD4 – then it works fine!

Update 2 See also the RFM12 vs RFM12B revisited page for a list of differences.

RF woes – solved!

In Software on Apr 28, 2009 at 00:01

Turns out my troubles with using the 868 MHz OOK radio next to the RFM12B module were caused by a silly software mistake (I mixed up the port assignments). No hardware or RF issues after all.

Latest sample output:

Picture 2.png

(the VOLT and BARO readings are bogus because the hardware is not connected)

As you can see, it’s receiving both packet types now. Still some trickiness with allocating the port signals properly, since some lines do require specific pins: the OOK receiver uses the analog comparator, but the ADC gets used as well, so I’ll need to adjust things a bit to use a pin change interrupt instead (used a crude workaround for now).

So now the basics are there to receive all types of signals with a single JeeHub: packets from other JeeNodes using the RFM12B, an 868 MHz OOK receiver for weather data and the FS20 remotes, and a 433 MHz OOK receiver for picking up KAKU remote commands (and possibly some other cheap weather sensors later).

RF12 protocol improvement

In AVR, Software on Apr 24, 2009 at 00:01

A small change was recently made to the RF12 wireless packet driver. This is the structure of a version 1 packet:

Picture 1.png

And this is the new structure in version 2:

Picture 2.png

Small change, big implications: the 16-bit CRC now includes the SYNC2 byte.

The SYNC2 byte is actually abused a bit by the RF12 driver, because it is set to the network group. Since RFM12B modules can look for a two-byte sync pattern with a configurable second byte, this is actually quite useful. By filtering on the network group, the receiver will completely skip packets which do not start with the proper group. This greatly reduces processor load when packets for different groups are being sent around in the same area.

There may still be some false syncs, since the RFM12B continues to look for the 2-byte pattern during the entire transmission, but it reduces overhead nevertheless.

The problem with version 1 packets is that a bit error in the group byte will generate a valid packet for another group. Extending the CRC tail to include the group fixes the problem, since the CRC will no longer be valid (almost never, that is).

This change is incompatible, i.e. packets sent with one version of the driver cannot be received by the other version. To make this less of an issue, the default group has been changed from 0x50 in v1 to 0x51 in v2.

With the new v2 driver, many network groups can coexist in the same area with no interference, other than having to share the total channel bandwidth.

New RF12 driver progress

In Software on Apr 23, 2009 at 00:01

The current RF12 is a bit simplistic, which means you may have to do a lot of work to get things across reliably. I’ve been working on a more sophisticated layer on top of the current RF12 driver code, which supports a reliable streaming mode.

Here’s a basic example which lets two nodes treat the connection as a serial link:

Picture 1.png

Everything typed on one node ends up on the other, in both directions. This is actually pretty hard to get 100% right, because it has to deal with packet loss as well as congestion (when you try to send data faster than the link can currently handle).

A far more interesting use of the streaming mode is to get all sorts of data across, grouped as a command with extra arguments. For example:

Picture 2.png

The “<<” operator pushes arguments into the stream. The send() call then starts the transmission, including an arbitrary 1-byte command code. Note how different data types can be specified for each argument.

On the receiving end, unwrapping is handled with the “>>” operator and a number of variables. The first value pulled out is actually the command code. Again, all conversions are automatically taken care of.

A basic implementation of the packetizing code is now working. But it needs more work to take care of lost and damaged packets and to make sure this gracefully slows down when the channel capacity is reached. Which could be quite low at times due to range or interference issues.

This example also illustrates how tedious it can be to format data as text using the Serial implementation: a 1-line “RF12 >> …” statement does the equivalent of a dozen “Serial.print(…)” calls.

P.S. The MuxShield and front-end are extremely convenient for debugging this sort of code.

RF woes

In Hardware on Apr 22, 2009 at 00:01

I’ve been trying to set up a JeeNode as forwarding gateway from the various 868 MHz OOK signals into the RFM12B packet format. The lower left block in the following diagram, that is:

RF woes.png

But I can’t seem to get it to work…

The 868 MHz OOk receiver and the RFM12B transceiver both work fine. In isolation. But when I run code which enables both receivers, the OOK module stops receiving proper data.

There was a mention somewhere about having to provide a really clean power level to the OOK radio, so I’ll probably try again with a separate regulator for it. Or maybe move the two radio modules further apart, since they are both to the same 868 MHz frequency band.

Can’t think of much else. Hm, again.

More OOK signal decoding

In AVR, Software on Apr 21, 2009 at 00:01

The ES-1 energy sensor described in yesterday’s post is now also recognized by the OOK reception code (the touch panel too, since it uses the FS20 protocol):

Picture 2.png

The main state machine code is still essentially the same:

Picture 1.png

Note that three completely different and independent pulse patterns are being recognized. These recognizers run in parallel, although evidently only at most one will end up with a successful reception at any point in time.

An updated sketch for the Arduino IDE can be found here.

Production

In AVR, Hardware on Apr 19, 2009 at 00:01

It’s starting to look like a little assembly line over here…

Assembly line...

That’s five fresh JeeNodes … and they all worked right away, yippie!

Mounting the JeeNode Pulse

In AVR, Hardware on Apr 18, 2009 at 00:01

Here’s another experiment in creating a practical Pulse setup, using a fully populated JeeNode:

JeeNode Pulse mounting

The PWR/I2C and ISP/SPI connectors use wire-wrap pins mounted the other way:

JeeNode Pulse mounting

Here are four “peripheral boards”, ready to add all sorts of sensors:

JeeNode Pulse mounting

They look a bit like feet, ha ha:

JeeNode Pulse mounting

The nice bit is that since each of the boards uses one port and all ports are identical, it is very easy to use various sensor configurations.

Here’s the “carrier board”, mounted on part of the enclosure:

JeeNode Pulse mounting

All the pieces fit together nicely, of course:

JeeNode Pulse mounting

And lastly, the protective shell:

JeeNode Pulse mounting

Case closed… heh :)

Switching AC

In Hardware on Apr 16, 2009 at 00:01

Got myself a couple of these relays from Pollin, for less than the coin next to it:

Bi-stable relay

They can switch 220V @ 16A, and work at 3V. The specialty is that this relay is bi-stable, IOW there are two 15 Ω coils and you send a short pulse through either of them to switch to the corresponding position. So it takes some power to switch, but after that the relay keeps its last position without power. Like a mechanical switch.

It does take some 200 mA – briefly – to switch, so the power supply has to be up to that.

My plan is to connect this to a JeeNode as follows:

Picture 3.png

Probably using a pair of BC547 transistors and 1N4148 diodes (or maybe a ULN2803, to control up to 4 relays). That way, each port would be able to drive one relay. A pretty cheap solution to control any 220 V appliance.

Haven’t decided yet how far to go into actual AC control, since the other option is to use off-the-shelf RF-controlled switches, such as the Conrad/ELV FS20 868 MHz series or the cheap KAKU 433 MHz switches. But relays can be more secure, if some encryption is added to the RF12 driver.

Fun note: I spent a lot of time as a teenager thinking about building a (feeble) computer with relays. After all, this is essentially a 1-bit memory. I’ve moved on since then … slightly :)

JeeHub modularity

In Hardware on Apr 13, 2009 at 00:01

The current JeeHub setup is a bit of a mish-mash:

Picture 1.png

It includes the RFM12B radio of course, to receive data from all JeeNodes. But it also includes a 433 MHz OOK receiver, a BMP085 pressure / temperature sensor, and a DCF77 clock signal receiver.

Trouble is, these things interfere with each other …

The 433 MHz OOK receiver seems to severely degrade RFM12B reception – so I yanked it out. Didn’t have an immediate need to decode KAKU signals anyway.

But worse, the DCF77 receiver also fails to work inside the current JeeHub enclosure. I suspect that either radiated RF power or some messy interference on the power supply levels is preventing it from detecting the 77 kHz signal. I really want DCF77 as reference clock, but I haven’t been able to make any use of it so far.

It looks like there’s too much going on in the current JeeHub prototype, electrically or electro-magnetically.

This is silly – and there’s a very simple way out: move some data sources / sensors to a separate JeeNode. After all, the JeeHub has been doing one thing really well for some time now, i.e. collecting data from remote JeeNodes via the RFM12B:

Picture 2.png

All I need to do is add support for OOK receivers plus BMP085 to the pulse software, and then attach them to one of the remote JeeNodes. Would also make it possible to connect both 433 and 868 MHz OOK receivers.

Haven’t made up my mind about the DCF77 receiver though. Having it tightly integrated with the JeeHub still makes sense – it’s where all the data comes through and gets time-stamped. Maybe the DCF radio will start to work once I disconnect all the other cruft. If not, I’ll either move it physically away from the rest of the JeeHub or reassign it to a remote JeeNode as well.

Surprising, how physical / electrical aspects are starting to impose themselves…

JeeNode Pulse deployment

In Hardware on Apr 11, 2009 at 00:01

This is my plan for sensors in each room in the house:

pulse-deployment1.png

This setup uses a power supply, which is a bit inconvenient. But the ePIR motion sensor draws too much power to run long enough off a battery. And I haven’t yet figured out low-power use of the RFM12B anyway. With everything permanently on, total power consumption should be under 40 mA.

Am still looking for a nice power supply to use, Pollin has several, some as cheap as € 2. Given that the JeeNode has an on-board regulator, any 4..8 V DC supply will do.

The sensors listed above require 2 ports, so there is room for expansion – depending on room requirements:

  • more temp sensors, strung together via 1-wire
  • door and window contact sensors, water level, etc

The JeeNode is placed up against the ceiling to give the motion sensor an optimal view of the room. For really accurate temperature and humidity measurements, it might be preferable to move the SHT11 sensor down a bit – or alternately, to put the JeeNode near the power supply and run a 4-wire cable to the ePIR + light sensors.

Decisions, decisions …

New "jeelab" mailing list

In News on Apr 8, 2009 at 00:01

For those who want to share their interest / questions / ideas w.r.t. any of the Jee Labs projects, I’ve set up a mailing list at Google Groups:

Picture 2.png

See http://groups.google.com/group/jeelab/about – if you don’t want to sign in to Google to join this list, let me know and I’ll add your email address manually.

Update – the mailing list has been replaced by the Jee Labs discussion forums at http://talk.jeelabs.net/.

Rethinking sensor nodes

In Software on Apr 4, 2009 at 00:01

The current “JeeNode Pulses” used around the house are getting a bit large in terms of code size – about 12 Kb of the available 14 Kb have been used up. A lot of this is due to debugging code, with each node generating a detailed report on its serial port. And then there’s the configuration code: displaying the current configuration on startup and interpreting commands entered on the serial port to change those settings.

Here’s serial output from a simple unit with 3 readings:

Picture 2.png

Most of this code becomes irrelevant once the nodes are installed and working properly, since the only thing that matters are the transmitted wireless packets. It seems a bit wasteful to have each node carry this logic around – and it’s inconvenient because settings can only be inspected and changed through a serial connection. Not so great for “remote” nodes…

A lot of this logic could be centralized, if only remote nodes were able to respond to wireless requests. But this requires some care: better not allow anyone anywhere to re-configure the JeeNodes in your house at will! IOW, we need a secure channel.

The simplest way is probably with a simple encryption protocol such as XXTEA, with a per-node “key” securely installed in EEPROM via the serial port. Once that is in place, we can securely send requests to any node to reconfigure and reboot it.

But why stop there? Why not generalize the entire transfer of state in both directions? What I’m thinking of is the following design:

  • Each node has a unique 128-bit key, known only the central server.
  • The central server can send encrypted configuration data, up to 60 bytes (1 packet).
  • The remote nodes can send readings data (perhaps up to 250 bytes).
  • Both sides keep track of the state of this data and only send differences.
  • The ack contains a CRC of the full state – if it is wrong, the full state will be re-sent.
  • Both the unique key and the configuration data are stored in EEPROM, and get copied to RAM on startup.
  • It might take a few packets to send all readings, but since only differences are sent, often a single packet will suffice.
  • The basic content of a packet would be: OFFSET, BITMAP, DIFFS, HASH.
  • The same mechanism could even be used to re-flash a remote node one day, given a suitable wireless bootstrap.

With such an approach, the code for JeeNode Pulses could become a lot simpler. No need to display text results on the serial port, since the central node has access to all relevant state (including all intermediate values which are not used as final readings). And no need to embed a command interpreter, since the server can produce the exact byte values needed for configuration – with a fancy GUI even, if needed.

The challenge now is to tie things together easily. How to define simple C code on the Pulse which is fully configurable on another system. This is sort of a poor-man’s SNMPhmm, I’ve got some ideas to try out.

This is getting out of hand

In AVR, Software on Apr 1, 2009 at 00:01

I’ve installed a preliminary JeeNode pulse upstairs, with a few 1-wire temperature sensors to track hot-water and central heating a bit. Here’s the real-time read-out, coming from the JeeHub:

Picture 4.png

These readings are coming from the following sources, mostly via wireless:

  • Electricity / gas meter, from a prototype JeeNode.
  • Weather data from 1 KS300 + 2 S300 commercial sensors.
  • Barometer and battery check, inside the JeeHub.
  • Room data and central heating temperatures, from a JeeNode Pulse
  • Some test values, from a second JeeNode Pulse on my desk.

But this display clearly won’t scale visually. Besides, it’s just a big pile of numbers. I really need to figure out a way to present this information nicely!

It’s fun to watch, seeing values update in real time…

Meet the JeeNode "Pulse"

In AVR, Hardware on Mar 30, 2009 at 00:01

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

Pulse prototype

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…

The JeeNode v2 works

In AVR, Hardware on Mar 23, 2009 at 00:01

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

JeeNode v2

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)

Let's pick a few more names

In Hardware, Software on Mar 20, 2009 at 00:01

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).

Picture 1.png

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.

The above names are also used in the source tree repository now.

There are no doubt still infinitely many ways to lead you astray, but I hope that these definitions will help me place everything into an increasingly coherent context.

Collecting data with JeeMon

In Software on Mar 17, 2009 at 00:01

This is the information I’m currently tracking real-time:

Picture 1.png

(it’s in Dutch, but you can probably guess most of these)

And this is the setup I’m using for it:

Picture 2.png

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.

Minimal JeeNode

In AVR, Hardware on Mar 16, 2009 at 00:01

Here’s a functioning ATmega168 on a JeeNode v1 PCB:

Minimal JeeNode

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.

Package from China

In Hardware on Mar 15, 2009 at 00:01

The other day (three weeks ago, actually) I ordered a wide range of connectors in 10x sample quantities from 4Uconnector. Then this came in:

Package from China

A little envelope full of low-cost goodies, such as this 4-way RJ11 jack:

Sample RJ11 connectors

Look how neatly it’s packaged. All the other parts were placed in little zip-lock bags and accurately labeled. How convenient, 100% ready to use and store.

The RJ11 jacks are an idea I’d like to try out to easily hook up sensors and other peripherals. Simply cut a standard 2-/4-/6-wire telephone cable in half and you’re all set to hook up two devices!

The only snag here is that the minimum order quantity is often 100’s or even 1000 units. So it’ll be crucial to choose wisely and stick with it…

Using a crystal

In AVR, Hardware on Mar 14, 2009 at 00:01

For the JeeHub, I wanted better clock stability than the 0.5% provided by a ceramic resonator, so I mounted a crystal instead:

Crystal mounting

This needs 2 extra 20 pF capacitors to ground, which I mounted on the other side as SMDs:

SMD 20 pF capacitors

A bit of solder and a short wire to the ground pin did the trick. Wow, even those 1206 components are tiny…

JeeHub prototype

In AVR, Software on Mar 12, 2009 at 00:01

Voilá – the first JeeHub prototype exists!

JeeHub prototype

(click on the image to see the annotated version)

It’s a pretty simple setup so far, as can be seen on the backside:

DSC_0117

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:

Picture 1.png

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.

Decoding 433 MHz KAKU signals

In AVR, Software on Mar 10, 2009 at 00:01

Here is a simple OOK receiver, hooked up to AIO port 3:

Decoding 433 MHz KAKU signals

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

Picture 1.png

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:

Picture 2.png

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.

JeeHub mock-up

In Hardware on Mar 7, 2009 at 00:01

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

JeeHub prototype

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.

So yeah, this post is a bit of a teaser for now…

DCF77 clock reception

In AVR, Software on Mar 6, 2009 at 00:01

The DCF radio in Frankfurt sends out a constant beacon signal at 77 KHz which can be received by a cheap radio module all over Western Europe:

DCF77 clock reception

Updatethe above connections are wrong. The diagram was showing the bottom view, all wires need to be flipped over to the other end of the DCF77 screw terminal block. No harm done, it works now.

The code has been added as “dcf77demo” in the Ports library.

Sample output:

Picture 1.png

JeeNode v2 PCB

In AVR, Hardware on Mar 5, 2009 at 00:01

Ok, here’s a new design for the JeeNode board:

JeeNode v2 PCB

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.

Anyway, I recently ordered a couple of these new ones… we’ll see!

EAGLE schematic (PDF) & board files (jee-pcb-003).

Update – the new PCBs are in, I’ve added some preliminary documentation here (PDF).

Dataflash via SPI

In AVR, Hardware on Mar 4, 2009 at 00:01

The AT45DB081D dataflash memory holds over 8 Mbit, organized as 4096 pages of 256 (or 264) bytes. It’s easy to connect to a JeeNode:

Dataflash via SPI

Looks a bit messy at close-up but it’s actually quite sturdy with 6 wire-wrap wires.

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

Dataflash via SPI

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.

OOK signaling with an RFM12B

In AVR, Software on Mar 3, 2009 at 00:01

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:

OOK signaling with an RFM12B

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:

OOK signaling with an RFM12B

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…

Sensing light levels

In AVR on Mar 2, 2009 at 00:01

Here is the TSL230 sensor (see SparkFun #08940), hooked up to a JeeNode:

TSL230 demo

And here’s the source code, using the Ports library:

TSL230 source

Sample output:

TSL230 output

Adding a µSD card

In AVR on Feb 28, 2009 at 00:01

Secure Digital cards are particularly simple to connect to, because they can be made to run in SPI mode – even the tiny µSD version. The SPI/ISP 2×4-pin header on a JeeNode has all the power lines and signals to do so:

Adding a µSD card

That’s a 2 gigabyte memory card, the size of a fingernail…

Enough storage capacity to “sniff” lots and lots of wireless packets from the airwaves. Just what I need to collect house measurement data of all kinds in a fully unattended manner, in fact.

In this case the hardware is actually the easy part. It takes much more work to read and write 512-byte blocks and to create a simple way to organize and access the stored data. I don’t really need a file system, just a robust way to log data and to play back selected parts of the stored data to another computer later.

Right now, all this does is identify the card and read and write 100 blocks:

Adding a µSD card

Looks like reading a block takes about 3.5 msec, writing one takes 41 msec. This is not a show-stopper, but with the µSD sharing the same SPI bus as the RFM12B, care will have to be taken to avoid dropping too many packets.

Out of spec

In AVR, Hardware on Feb 27, 2009 at 00:01

Running an Atmega168 at 16 MHz on 3.3V power is beyond its specs:

Out of spec

Officially, you’re only allowed to run it at up 13.333 Mhz with 3.3V. Easy math: it’s 10 Mhz change over a range of 1.8V, and 3.3V is one third of the way up from 2.7V.

Yet I’ve been running this chip with a 16 Mhz resonator on at least a dozen JeeNodes now. I don’t know whether that means all is well because the limits are conservative ones, or whether they might fail outdoors in an extended temperature range, or whether a few units will not work.

Memsic 2-axis accelerometer

In AVR, Hardware on Feb 26, 2009 at 00:01

Yet another sensor mounted on a breakout board by Parallax, is the Memsic 2125 accelerometer:

Memsic 2125 2-axis accelerometer

Demo sketch, called “accel2125_demo” in the Ports library:

Memsic 2125 2-axis accelerometer

Sample output:

Memsic 2125 2-axis accelerometer

The pulses are 5 msec at rest, and changed slightly when I moved this thing (rather gently).

Might work nicely for a self-balancing robot…

QTI measures reflection

In AVR, Hardware on Feb 25, 2009 at 00:01

Parallax offers a QTI sensor, which is a led + photo transistor on a breakout board. It’s easy to hook up to a JeeNode because the pin-out matches port pins 3..5: