Computing stuff tied to the physical world

Posts Tagged ‘JeeNode’

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 RFMN12B. 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 eaasiest 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 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. 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 receiver 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.

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 DOCS area.

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 0×1234, 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.