Computing stuff tied to the physical world

Search for “FS20”

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.

FS20 developments

In Hardware on Aug 18, 2009 at 00:01

Looks like the FS20 remote-controlled system from Conrad and ELV has gained a few new units. Here’s a 60-euro 2-channel power-strip, controlled from 868 MHz, hence also from a JeeNode:


Also a 42-euro repeater to get through multiple layers of reinforced concrete.

Great options to avoid having to deal with line voltages. Not ultra-cheap, but still.

The one drawback worth noting with FS20 is that’s it’s not replay-safe. If someone picks up these signals, they can re-send them at a later time, even from outside the house. This means there is essentially no security at all with this approach. But for things like lighting and office equipment, that’s probably not an issue.

Receiving and decoding FS20

In Hardware on Apr 30, 2009 at 00:01

Here is a little kit by ELV which can receive FS20 signals and switch 4 independent open-collector outputs:

4-channel FS20 decoder

This board has an on-board regulator and requires 5..24V DC. Most of the components are SMD’s on the other side, the wire bridges show that this is a single-sided pcb.

Pretty obvious stuff… my reason to buy this was simply to get another 868 MHz receiver module!

Home control with FS20

In Hardware on Apr 20, 2009 at 00:01

There are many different types of FS20 units (by Conrad / ELV). Two new types of units came in recently. Here’s a power monitor which transmits power consumption via 868 MHz OOK in 5-minute intervals:

FS20 home control

It’s recognized by the CUL receiver, showing readings such as these:


Hmm, looks like a cumulative power consumption counter… I plugged in a lamp before that last reading. Maybe there’s both cumulative and real-time power use in there. I’m sure the protocol has been analyzed… and indeed, here it is.

One drawback is that the addressing scheme is limited to at most four ES-1 sensors.

And here’s a little touch-sensitive control panel which can send up to 6 different commands and is made for mounting into the wall:

FS20 home control

The panel can differentiate between short (on/off) taps and long (dimmer) taps, so one panel can actually emit up to 12 different signals. Again, this shows up in CUL:


At € 36 and € 28, respectively, these units are not really affordable enough to sprinkle lots of them all over the house. Then again, maybe a few strategically placed power meters plus the total electricity meter pulses would be enough to figure out most power consumption patterns in the house…

The advantage of these of course is that they are plug-and-play. It ought to be easy to extend the current FS20 receiver code for the RFM12B so they recognize these extra bit patterns.

RFM69s, OOK, and antennas

In Musings on Jul 15, 2015 at 00:01

Recently, Frank @ SevenWatt has been doing a lot of very interesting work on getting the most out of the RFM69 wireless radio modules.

His main interest is in figuring out how to receive weak OOK signals from a variety of sensors in and around the house. So first, you’ll need to extract the OOK information – it turns out that there are several ways to do this, and when you get it right, the bit patterns that come out snap into very clear-cut 0/1 groups – which can then be decoded:

FS20 histo 32768bps

Another interesting bit of research went into comparing different boards and builds to see how the setups affect reception. The good news is that the RFM69 is fairly consistent (no extreme variations between different modules).

Then, with plenty of data collection skills and tools at hand, Frank has been investigating the effect of different antennas on reception quality – which is a combination of getting the strongest signal and the lowest “noise floor”, i.e. the level of background noise that every receiver has to deal with. Here are the different antenna setups being evaluated:

RFM69 three antennas 750x410

Last but not least, is an article about decoding packets from the ELV Cost Control with an RFM69 and some clever tricks. These units report power consumption every 5 seconds:


Each of these articles is worth a good read, and yes… the choice of antenna geometry, its build accuracy, the quality of cabling, and the distance to the µC … they all do matter!

The key-value straightjacket

In Musings, Software on Jan 5, 2013 at 00:01

It’s probably me, but I’m having a hard time dealing with data as arrays and hashes…

Here’s what you get in just about every programming language nowadays:

  • variables (which is simply keyed access by name)
  • simple scalars, such as ints, floats, and strings
  • indexed aggregation, i.e. arrays: blah[index]
  • tagged aggregation, i.e. structs:
  • arbitrarily nested combinations of the above

JavaScript structs are called objects and tag access can be blah.tag or blah['tag'].

It would seem that these are all one would need, but I find it quite limiting.

Simple example: I have a set of “drivers” (JavaScript modules), implementing all sorts of functionality. Some of these need only be set up once, so the basic module mechanism works just fine: require "blah" can give me access to the driver as an object.

But others really act like classes (prototypal or otherwise), i.e. there’s a driver to open a serial port and manage incoming and outgoing packets from say a JeeLink running the RF12demo sketch. There can be more than one of these at the same time, which is also indicated by the fact that the driver needs a “serial port” argument to be used.

Each of these serial port interfaces has a certain amount of configuration (the RF12 band/group settings, for example), so it really is a good idea to implement this as objects with some state in them. Each serial port ends up as a derived instance of EventEmitter, with raw packets flowing through it, in both directions: incoming and outgoing.

Then there are packet decoders, to make sense of the bytes coming from room nodes, the OOK relay, and so on. Again, these are modules, but it’s not so clear whether a single decoder object should decode all packets on any attached JeeLink or whether there should be one “decoder object” per serial interface object. Separate objects allow more smarts, because decoders can then keep per-sensor state.

The OOK relay in turn, receives (‘multiplexes”) data from different nodes (and different types of nodes), so this again leads to a bunch of decoders, each for a specific type of OOK transmitter (KAKU, FS20, weather, etc).

As you can see, there’s sort of a tree involved – taking incoming packet data and dissecting / passing it on to more specific decoders. In itself, this is no problem at all – it can all be represented as nested driver objects.

As final step, the different decoders can all publish their readings to a common EventEmitter, which will act as a simple bus. Same as an MQTT broker with channels, with the same “nested key” strings to identify each reading.

So far so good. But that’s such a tiny piece of the puzzle, really.

Complexity sets in once you start to think about setup and teardown of this whole setup at run time (i.e. configuration in the browser).

Each driver object may need some configuration settings (the serial port name for the RF12demo driver was one example). To create a user interface and expose it all in the browser, I need some way of treating drivers as a generic collection, independent of their nesting during the decoding process.

Let’s call the driver modules “interfaces” for now, i.e. in essence the classes from which driver instances can be created. Then the “drivers” become instantiations of these classes, i.e. the objects which actually do the work of connecting, reading, writing, decoding, etc.

One essential difference is that the list of interfaces is flat, whereas a configured system with lots of drivers running is often a tree, to cope with the gradual decoding task described a bit above.

How do I find all the active drivers of a specific interface? Walk the driver tree? Yuck.

Given an driver object, how do I find out where it sits in the tree? Store path lists? Yuck.

Again, it may well be me, but I’m used to dealing with data structures in a non-redundant way. The more you link and cross-link stuff (let alone make copies), the more hassles you run into when adding, removing, or altering things. I’m trying to avoid “administrative code” which only keeps some redundant invariants intact – as much as possible, anyway.

Aren’t data structures supposed to be about keeping each fact in exactly one place?

PS. My terminology is still a mess in flux: interfaces, drivers, devices, etc…

Update – I should probably add that my troubles all seem to come from trying to maintain accurate object identities between clients and server.

Reporting serial packets

In Software on Oct 16, 2012 at 00:01

The RF12demo sketch was originally intended to be just that: a demo, pre-flashed on all JeeNodes to provide an easy way to try out wireless communication. That’s how it all started out over 3 years ago.

But that’s not where things ended. I’ve been using RF12demo as main sketch for all “central receive nodes” I’ve been working with here. It has a simple command-line parser to configure the RF12 driver, there’s a way to send out packets, and it reports all incoming packets – so basically it does everything needed:

  [RF12demo.8] A i1* g5 @ 868 MHz 
  DF I 577 10

  Available commands:
    <nn> i     - set node ID (standard node ids are 1..26)
                 (or enter an uppercase 'A'..'Z' to set id)
    <n> b      - set MHz band (4 = 433, 8 = 868, 9 = 915)
    <nnn> g    - set network group (RFM12 only allows 212, 0 = any)
    <n> c      - set collect mode (advanced, normally 0)
    t          - broadcast max-size test packet, with ack
    ...,<nn> a - send data packet to node <nn>, with ack
    ...,<nn> s - send data packet to node <nn>, no ack
    <n> l      - turn activity LED on PB1 on or off
    <n> q      - set quiet mode (1 = don't report bad packets)
  Remote control commands:
    <hchi>,<hclo>,<addr>,<cmd> f     - FS20 command (868 MHz)
    <addr>,<dev>,<on> k              - KAKU command (433 MHz)
  Flash storage (JeeLink only):
    d                                - dump all log markers
    <sh>,<sl>,<t3>,<t2>,<t1>,<t0> r  - replay from specified marker
    123,<bhi>,<blo> e                - erase 4K block
    12,34 w                          - wipe entire flash memory
  Current configuration:
   A i1* g5 @ 868 MHz

This works fine, but now I’d like to explore a real “over-the-wire” protocol, using the new EmBencode library. The idea is to send “messages” over the serial line in both directions, with named “commands” and “events” going to and from the attached JeeNode or JeeLink. It won’t be convenient for manual use, but should simplify things when the host side is a computer running some software “driver” for this setup.

Here’s the first version of a new rf12cmd sketch, which reports all incoming packets:

Screen Shot 2012 10 14 at 15 31 51

Couple of observations about this sketch:

  • we can no longer send a plain text “[rf12cmd]” greeting, that too is now sent as packet
  • the greeting includes the sketch name and version, but also the decoder’s packet buffer size, so that the other side knows the maximum packet size it may use
  • invalid packets are discarded, we’re using a fixed frequency band and group for now
  • command/event names are short – let’s not waste bandwidth or string memory here
  • I’ve bumped the serial line speed to 115200 baud to speed up data transfers a bit
  • there’s no provision (yet) for detecting serial buffer overruns or other serial link errors
  • incoming data is sent as a binary string, no more tedious hex/byte conversions
  • each packet includes the frequency band and netgroup, so the exchange is state-less

The real change is that all communication is now intended for computers instead of us biological life-forms and as a consequence some of the design choices have changed to better match this context.

Tomorrow, I’ll describe a little Lua script to pick up these “serial packets”.

Re-thinking solar options

In AVR, Hardware, Musings on May 28, 2012 at 00:01

So will it ever be possible to run a JeeNode or JeeNode Micro off solar power?

Well, that depends on many things, really. First of all, it’s good to keep in mind that all the low-power techniques being refined right now also apply to battery consumption. If a 3x AA pack ends up running 5 or even 10 years without replacement, then one could ask whether far more elaborate schemes to try and get that supercap or mini-lithium cell to work are really worth the effort.

One fairly practical option would be a single rechargeable EneLoop AA battery, plus a really low-power boost circuit (perhaps I need to revisit this one again). The idea would be to just focus on ultra-low power consumption, and move the task of charging to a more central place. After all, once the solar panels on the roof of JeeLabs get installed (probably this summer), I might as well plug the charger into AC mains here and recharge those EneLoop batteries that way!

Another consideration is durability: if supercaps only last a few months before their capacity starts to drop, then what’s the point? Likewise, the 3.4 mAh Lithium cell I’ve been playing with is rated at “1000 cycles, draining no more than 10% of the capacity”. With luck, that would be about three years before the unit needs to be replaced. But again – if some sort of periodic replacement is involved anyway, then why even bother generating energy at the remote node?

I’m not giving up yet. My KS300 weather station (868 MHz OOK, FS20’ish protocol) has been running for over 3 years now, I’ve never replaced the 3x AA batteries it came with – here’s the last readout, a few hours ago:

     :41   KS300 ookRelay2 humi             77
     :41   KS300 ookRelay2 rain             469
     :41   KS300 ookRelay2 rnow             0
     :41   KS300 ookRelay2 temp             18.2
     :41   KS300 ookRelay2 wind             0

And the original radioBlip node is also running just fine after 631 days:

    1:32   RF12-868.5.3 radioBlip age       631
    1:32   RF12-868.5.3 radioBlip ping      852330

Even the JeeNode Micro running on a CR2023 coin cell is still going strong after 4 months:

    1:42   RF12-868.5.18 radioBlip age      139
    1:42   RF12-868.5.18 radioBlip ping     188449

So ultra-low power is definitely doable, even with an Arduino-compatible design.

No worries – I’ll keep pushing this in various directions, even if just for the heck of it…

CC-RT: Choices and trade-offs

In Hardware on Oct 20, 2011 at 00:01

This is part 2 3 of the Crafted Circuits – Reflow Timer series.

There are many design choices in the Reflow Timer. The goal is to keep it as simple and cheap as possible, while still being usable and practical, and hopefully also convenient in day-to-day use.

Display and controls – there are several low-cost options: separate LEDs, 7-segment displays, a character LCD, or a graphics LCD. The LEDs would not allow displaying the current temperature, which seems like a very useful bit of info. To display a few numbers, a small character-based LCD is cheaper and more flexible than 7-segment displays (which need a lot of I/O lines). The only real choice IMO, is between a character-based and the graphics LCD. I’ve decided to go for a 2×16 display because A) fancy graphics can be done on a PC using the built-in wireless connection, and B) a character LCD is cheaper and sufficient to display a few values, status items, and menu choices. And if I really want a GLCD option, I could also use wireless in combination with the JeePU sketch.

For the controls, there’s really only one button which matters: START / STOP. The power switch might be avoided if a good auto-power implementation can be created in software. For configuration, at least one more button will be needed – with short and long button presses, it should be possible (although perhaps tedious) to go through a simple setup process. A third button might make it simpler, but could also slightly complicate day-to-day operation. So two or three buttons it is.

Temperature sensor – this is the heart of the system. There are essentially two ways to go: using an NTC resistor or using a thermocouple. The NTC option is considerably cheaper and can be read out directly with an analog input pin, but it has as drawback that it’s less accurate. In the worst case, accuracy might be so low that a calibration step will be needed.

Thermocouples don’t suffer from the accuracy issue. A K-type thermocouple has a known voltage differential per degree Celsius. The drawback is that these sensors work with extremely low voltages which require either a special-purpose chip or a very sensitive ADC converter. Since thermocouple voltages are based on temperature differences, you also need some form of tracking against the “cold junction” side of the thermocouple. Thermocouple-based sensing is quite tricky.

But the main reason to use them anyway, is mechanical: although there are glass-bead NTC’s which can withstand 300°C and more, these sensors come with short wires of only a few centimeters. So you need to somehow extend those wires to run from the heater to the Reflow Timer. And that’s where it gets tricky: how do you attach wires to that sensor, in an environment which will heat up well beyond the melting point of solder? And what sort of wire insulation do you use? Well… as it turns out, all the solutions I found are either very clumsy or fairly expensive. There’s basically no easy way to get a glass-bead NTC hooked up to the reflow timer in a robust manner (those wires out of the glass bead are also very thin and brittle). So thermocouple it is.

Thermocouple chip – for thermocouples, we’ll need some sort of chip. There seem to be three types:

  • dedicated analog, i.e. the AD597
  • dedicated digital, i.e. the MAX6675 or MAX31855
  • do-it-yourself, i.e. a sensitive ADC plus cold-junction compensator

The AD597 is used the the Thermo Plug and in my current reflow controller setup. It works well, with a voltage of 10 mV/°C coming out as analog signal. So with 250°C, we get 2.50V – this is a perfect match for an ATmega running at 3.3V. The only small downside, is that it needs an operating voltage which is at least 2V higher than the highest expected reading. If we need to go up to say 275°C (above what most ovens can do), then we’ll need a 4.75 V supply voltage for the AD597.

The MAX6675 doesn’t have this problem because the readout is digital, and works fine with supply voltages between 3.0 and 5.5V. But it’s a very pricey chip (over €14 incl VAT). Keeping these in stock will be expensive!

The MAX31855 is also a digital chip, and about half the price of the MAX6675. The main difference seems to be that it can only operate with a supply from 3.0 to 3.6V, which in our case is no problem at all (we need to run at 3.3V anyway for the RFM12B). I’ve no experience with it, but this looks like a great option for the Reflow Timer.

There is a slight issue with each of these chips, in that they do not exist in through-hole versions but only in a “surface mounted device” (SMD) style. The package is “8-SOIC”, i.e. a smaller-than-DIP 8-pin plastic chip:

8 SOIC sml

For people who don’t feel confident with soldering it might pose a challenge. There are no sockets for SMD, you really have to solder the chip itself. Then again, if you’re going to create a reflow setup for building SMD-based boards anyway, you might as well get used to soldering these size chips. Trust me, SOIC is actually quite easy.

(note: there is an all-DIP solution with the LT1025, but it needs an extra op-amp, so I’ve not checked further)


If we can use the MAX31855, then everything can be powered with 3.3V. This means that either 3x AA or 1x LiPo will work fine, in combination with a 3.3V regulator. I’ll stick with the MCP1702 regulator, even though it’s not the most common type, because of its low standby current – this will help reduce power in auto power-down mode.

But how much current do we need? To put it differently: how long will these batteries last? Let’s find out.

The prototype I have appears to use about 35 mA while in operation. Let’s take a safety margin and make that 50 mA in case we also need to drive an opto-coupler for the SSR option. And let’s say we use 2000 mAh AA cells, then we’ll get 40 hours of operation out of one set of batteries. Let’s assume that one reflow cycle takes 10 minutes, plus another 5 minutes for auto power-off, then we can use one set of batteries for 160 reflow cycles. Plenty!

We could even power the Reflow Timer with an AA Power Board, and still get about 50 cycles – but that would increase the cost and require some very small SMD components.

Let’s just go for the 3x AA setup, with either a DC or USB jack as possible alternative.

AC mains switching

For switching the heater, there are several options. The one I’m using now is a remote-controlled FS20 switch from Conrad (or ELV). It can be controlled directly by the RFM12B wireless module. An alternative would be the KAKU (a.k.a. Klik Aan Klik Uit or Home Easy) remote switch, which operates at 433 MHz and kan also be controlled directly from the RFM12B. The advantage of this setup is that you never need to get involved with AC mains – just place the remote switch between mains socket and heater (grill, oven, etc) and you’re done.

Another option is to use a Solid State Relay (SSR), which needs 5..10 mA of current through its built-in opto-coupler. I built this unit a while back to let me experiment with that. The benefit of such a configuration is that all the high-voltage AC mains stuff is tucked away and out of reach, and that the control signal is opto-isolated and can be attached to the Reflow Timer without any risk. Note that with SSR, the RFM12B module becomes optional.

Yet another option would be to use a mechanical relay, but I’d advise against that. Some heaters draw quite a bit of current (up to 10A) and will require a hefty relay, which in turn will require a hefty driver. Also, very few power relays can operate at 5V, let alone 3.3V – which means that a 3x AA powered approach would not work.

So, RF-controlled switch it is, with an extra header or connector to drive the LED in an SSR as option.

That’s about it for the main Reflow Timer circuit design choices, methinks.

CC-RT: Initial requirements

In AVR, Hardware, Software on Oct 14, 2011 at 00:01

Let’s get going with the CC-RT series and try to define the Reflow Timer in a bit more detail. In fact, let me collect a wish list of things I’d like to see in there:

The Reflow Timer should…

  • support a wide range of ovens, grills, toasters, and skillets
  • be self-contained and safe to build and operate
  • include some buttons and some sort of indicator or display
  • be created with through-hole parts as much as possible
  • (re-) use the same technologies as other JeeLabs products
  • be built on a custom-designed printed circuit board
  • use a convenient and robust mechanical construction
  • be very low-cost and simple to build

To start with that last point: the aim is to stay under € 100 as end-user price, including a simple toaster and whatever else is needed to control it. That’s a fairly limiting goal, BTW.

I’m sticking to “the same technologies” to make my life easy, both in terms of design and to simplify inventory issues later, once the Reflow Timer is in the shop. That translates to: an Arduino-like design with an ATmega328, and (for reasons to be explained next) an RFM12B wireless module.

Safety is a major concern, since controlling a heater tied to 220 V definitely has its risks. My solution to controlling an oven of up to 2000 W is the same as what I’ve been doing so far: use a commercially available and tested power switch, controlled via an RF signal. KAKU or FS20 come to mind, since there is already code to send out the proper signals through an RFM12B module. Range will not be an issue, since presumably everything will be within a meter or so from each other.

With wireless control, we avoid all contact with the mains power line. I’ll take it one step further and make the unit battery-operated as well. There are two reasons for this: if we’re going to uses a thermocouple, then leakage currents and transients can play nasty games with sensors. These issues are gone if there is no galvanic connection to anything else. The second reason is that having the AC mains cable of a power supply running near a very hot object is not a great idea. Besides, I don’t like clutter.

Having said this, I do not want to rule out a couple of alternatives, just in case someone prefers those: controlling the heater via a relay (mechanical or solid-state), and powering the unit from a DC wall wart. So these should be included as options if it’s not too much trouble.

To guard against heat & fire problems, a standard heater will be used with a built-in thermostat. The idea being that you set the built-in thermostat to its maximum value, and then switch the entire unit on and off via the remote switch. Even in the worst scenario where the switch fails to turn off, the thermostat will prevent the heater from exceeding its tested and guaranteed power & heat levels. One consequence of this is that the entire reflow process needs to unfold quickly enough, so that the thermostat doesn’t kick in during normal use. But this is an issue anyway, since reflow profiles need to be quick to avoid damaging sensitive components on the target board.

On the software side, we’ll need some sort of configuration setup, to adjust temperature profiles to leaded / unleaded solder for example, but also to calibrate the unit for a specific heater, since there are big differences.

I don’t think a few LEDs will be enough to handle all these cases, so some sort of display will be required. Since we’ve got the RFM12B on board anyway, one option would be to use a remote setup, but that violates the self-contained requirement (besides, it’d be a lot less convenient). So what remains is a small LCD unit, either character-based or graphics-based. A graphic LCD would be nice because it could display a temperature graph – but I’m not sure it’ll fit in the budget, and to be honest, I think the novelty of it will wear off quickly.

On the input side, 2 or 3 push buttons are probably enough to adjust everything. In day-to-day operation, all you really need is start/stop.

So this is the basic idea for the Reflow Timer so far:

JC s Doodles page 18

Ok, what else. Ah, yes, an enclosure – the eternal Achilles’ heel of every electronics project. I don’t want anything fancy, just something that is robust, making it easy to pick up and operate the unit. I’ve also got a somewhat unusual requirement, which applies to everything in the JeeLabs shop: it has to fit inside a padded envelope.

Enclosures are not something you get to slap on at the end of a project. Well, you could, but then you lose the opportunity of fitting its PCB nicely and getting all the mounting holes in the best position. So let’s try and get that resolved as quickly as possible, right?

Unfortunately, it’s not that easy. We can’t decide on mechanical factors before figuring out exactly what has to be in the box. Every decision is inter-dependent with everything else.

Welcome to the world of agonizing trade-offs, eh, I mean… product design!

OOK reception with RFM12B

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

A while back, JGJ Veken (Joop on the forum) added a page on the wiki on how the RFM12B can receive OOK.

I never got around to trying it … until now. In short: if you’re not afraid of replacing an SMD capacitor on the RFM12B wireless module, then it’s trivial!

Here’s what needs to be done – the capacitor on the left is 4.7 nF:

Screen Shot 2011 01 25 at 14.16.36

Unsolder it and replace it with a cap in the range 150..330 pF (I used 220 pF).

This cap appears to determine the time constant w.r.t. how fast the RSSI signal adapts to varying RF carrier signal strengths. With 4.7 nF, it’s a bit too sluggish to detect an OOK signal – which is nothing other than a carrier being switched on and off (OOK stands for: On / Off Keying).

The next trick is to connect the FSK/DATA/nFSS pin of the RFM12B via a 100 Ω resistor to AIO1 (a.k.a. analog 0, a.k.a. PC0, a.k.a. ATmega pin 23 – phew!):

Dsc 2427

As far as I can tell, this is a digital signal, so connecting it to AIO0 is really not a requirement. It might be more practical to connect it to one of the B0/B1 pins on the SPI/ISP header. Perhaps I should add a jumper in a future revision of the JeeNode PCB?

And lastly, the RFM12B must be placed in a special mode to get the RSSI signal onto that pin – i.e. compared to the RSSI threshold, also configured into the RFM12B (97 dBm).

All the pieces were there, and all I had to do was to follow the steps mentioned on the wiki page.

I made some changes to the code and added it as RF12MB_OOK.pde example sketch. Here is the main logic:

Screen Shot 2011 01 25 at 16.42.14

As you can see, all incoming data is forwarded using the normal RF12 mode packet driver.

Sample output:

Screen Shot 2011 01 25 at 16.56.39

It’s happily picking up FS20, EM10, S300, and KS300 packets, and the overall sensitivity seems to be excellent. And since it forwards all data as packets into the rest of the JeeNode network, I now have all the data coming in over a single JeeLink.

Sooo… with this “mod”, no separate OOK receiver is needed anymore for the 868 MHz frequency band!

PS. Haven’t done too many tests with this yet. Transmission is unaffected, as far as I can tell. Reception of packets with the RF12 driver still seems to work – it may be more susceptible to RF variations, but then again a “normal” packet uses FSK which is a constant carrier, so in principle this modification should not affect the ability of the RFM12B to receive standard FSK packets.

Reflow Timer software

In Software on Nov 4, 2010 at 00:01

Another episode in the reflow controller story…

Here is yesterday’s graph again, but manually annotated this time:

Annotated Reflow

Actually, I went ahead and extended the code to add those axis labels in there. I was concerned that they would overlap and distract from the graph data itself, but after seeing this… it clearly improves readability.

The trick is to get the PID control factors right, and these will be different for each setup. Right now, I just picked a couple of values which seem to be working ok on my particular grill. I’ve extended the JeeNode sketch to allow adjusting these values via a serial USB connection:

    <N> P       P factor (x1000)
    <N> I       I factor (x1000)
    <N> D       D factor (x1000)
    <N> L       I limit (x1000)

The PID calculation is:

    (Pfactor*Pval + Ifactor*Ival - Dfactor*Dval) / 1000

In other words, these factors are specified as a multiple of 0.001.

The result is brought into a range of 0..100. This in turn is used to determine when, how often, and how long to turn on the heater in the grill/oven/skillet.

The reflow profile parameters are also adjustable from the serial link:

    <N> o       ON temperature (°C), default 70
    <N> w       minimum time in WARMUP phase (sec), default 60
    <N> p       temperature at end of PREHEAT phase (°C), default 140
    <N> s       temperature at end of SOAK phase (°C), default 170
    <N> m       maximum REFLOW temperature (°C), default 250
    <N> r       minimum time in REFLOW phase (sec), default 15
    <N> c       temperature at end of COOL phase (°C), default 150
    <N> f       temperature at end of FINAL phase (°C), default 50

Once the FINAL phase ends, the JeeNode will power itself down.

A few more parameters:

    <N> l       lower calibration temperature limit (°C), default 40
    <N> u       upper calibration temperature limit (°C), default 120
    <N> d       stable duration (sec), default 5
    <N> t       stable trigger gap (°C), default 25
    <N> a       number of temperature averages to take, default 250

Some parameters for reporting, which happens once per second:

    <N> i       wireless node ID (sending disabled if 0), default 8
    <N> b       wireless frequency (4=433, 8=868, 9=915), default 8
    <N> g       wireless net group, default 5
    <N> e       enable (1) or disable (0) serial reports, default 0

And finally, the parameters which control the FS20 remote switch:

    <N> H       house code to use for FS20, default 4660
    <N> h       device ID to use for FS20, default 1

All PID factors and other parameters are stored in EEPROM, so they will remain in effect until changed.

To get a summary of all the current settings, type a question mark: “?”.

To reset all parameters to their “factory” defaults, type an exclamation mark: “!”.

The code for the “reflowTimer.pde” sketch is here The current code size is ≈ 14 Kb. I’ll probably be tweaking it a bit further in the coming days.

One thing I’d like to try adding to the current sketch is an easy way to self-calibrate and come up with a workable set of P/I/D factors, so that it can be used with a variety of electrical grills, toasters, skillets, ovens, barbecues, whatever – under the motto: if it can melt solder, we should try it!

The JeeMon script is here and is about 150 lines of code. If you save it as “application.tcl” next to JeeMon, it will automatically be picked up when JeeMon is launched. The code is still work-in-progress at this point: you will have to manually edit the “device” variable to refer to your attached JeeNode/JeeLink running RF12demo – you can also set it to a COM port (Windows) or tty device (Linux/Mac). Likewise, the “nodeID” variable should be set to match the current setting in the Reflow Timer sketch (“i” parameter):

    variable device   usb-A900ad5m    ;# which JeeNode/JeeLink to attach to
    variable nodeID   8               ;# which node ID to listen to

The frequency band + netgroup of the JeeNode/JeeLink are assumed to have been previously set in RF12demo.

Note that the script is an optional GUI front-end – you can launch it anytime, or you can ignore this whole JeeMon thing, since the sketch does not depend on it. It’ll drive the reflow process with or without the GUI.

If you try this out, or have suggestions about how to improve things, please let me know.

Update – I’ve adjusted the info above to match the latest code changes.

Meet the Reflow Timer

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

Now we’re cookin’ – here’s the complete reflow configuration I am setting up for use at Jee Labs:

Dsc 2201

Yes, it’s a Project On Foam again!

As before, I’m using a 700 Watt low-end toaster/grill. It can heat about the area of a 10×16 cm pcb and it’s really small and practical for me. I removed the teflon-coated hot plates, and placed a thin aluminum sheet in there, to respond more quickly to heat changes. A small oven or a skillet could probably also be used.

The power is controlled by an FS20 remote switch (available from Conrad or ELV, both in Europe). This is very convenient, since JeeNodes can control this thing through the RFM12B without any further hardware. The big advantage: no need to mess around with 220V AC mains – it’s RF-isolated!

The LCD display makes this thing independent of a PC/Mac. And the battery pack makes it a fully stand-alone solution. The JeeNode (and LCD / radio) will shut off once the temperature drops below 50 °C. This whole setup draws about 30 mA, so with a run time of 10-minutes, four AA batteries will last hundreds of runs, i.e. plenty!

The Thermo Plug and Blink Plug have both been extended in the shop as pre-assembled unit and kit, respectively, including a thermouple which can be used up to 350 °C. I’ve also added a 4-cell battery holder.

Here’s how to operate this thing:

  • set up everything, place the board inside the grill, and close the lid
  • press the GREEN button, the green LED goes on
  • wait for the BEEP, then carefully open the lid
  • wait until the green LED turns off, i.e. the temperature drops under 150 °C
  • done!

This is an example of what happens during a run:

Screen Shot 2010 11 02 at 13.10.19

Tomorrow, I’ll comment on this graph and the JeeMon app that produced it.

Controlling the oven

In Software on May 15, 2010 at 00:01

This is part 5 of my reflow controller series.

Today, I’d like to be able to remotely turn the grill on and off. To avoid having to deal directly with high voltages (220V is scary!), I’m going to use an RF controlled switch – i.e. this FS20 module:

Dsc 1428

It’s perfect here, because it operates @ 868 MHz and can be controlled directly from a JeeLink or JeeNode, and because it has an on/off button right on the unit itself (unlike these). Which is great as emergency stop – we’re going to play with serious levels of electricity, current, and heat after all.

As it so happens, the RF12demo sketch I’ve been using to receive packets from the thermocouple node also supports sending FS20 commands out of the box.

So all that’s needed is to extend the GUI a bit with a control element, and hooking that up to send the proper FS20 command out.

This requires a few extra lines in the initPlot proc:

variable heat
pack [checkbutton .h -text Heater -variable [namespace which -var heat]]
trace add variable heat write [namespace which HeatChange]

And a proc called HeatChange, for which I’ll use a bit of test code for now:

proc HeatChange {args} {
  variable heat
  puts "heat = $heat"

The result is a window with an extra checkbox at the bottom:

Screen Shot 2010 05 12 at 024300

Clicking that button simply generates some test output:

heat = 1
heat = 0
heat = 1
heat = 0

Great. The GUI side is working. Here’s an updated version of HeatChange which actually sends out the proper FS20 commands:

proc HeatChange {} {
  variables heat conn
  if {$heat} {
    $conn send 54,32,1,17f
  } else {
    $conn send 54,32,1,0f

The first 3 values are the house code and address bytes. They can be anything, because FS20 modules are configured by putting them in a special listening mode (press the button until the LED starts blinking). The next RF command sent to them will then be remembered, so that it will respond to that specific code from then on. Code 17 means ON, code 0 is OFF – that’s part of the standard FS20 protocol (see this German info page). The trailing “f” tells RF12demo to send everything out as an FS20 command.

IOW, to respond to these RF signals, put the FS20 unit in that special mode and then send one of the above commands by clicking on the checkbox in the GUI. You should now be able to manually control the remote switch.

Note: make sure you have the latest RF12demo. A nasty OOK bug was fixed a few days ago. If your JeeLink hangs: unplug, reconnect, then upload the latest code.

One more thing I’d like to do is include the heater status in the plot. That requires a few more changes. Here’s the latest “application.tcl” (I’ve collapsed the start and HeatChange code, since they are the same as before):

Screen Shot 2010 05 12 at 03.57.04

Let’s try this new setup, i.e. measuring and controlling 100% by wireless.

What I wanted to do is hook it up to my Ersa I-Con Nano temperature-controlled soldering station (with the soldering tip removed), because that would have been a great demo of how real temperature control works:

Dsc 1418

Unfortunately, that didn’t work – and drove home that there’s a real risk of fire involved in these experiments. Here’s what happened:

Screen Shot 2010 05 12 at 15.48.26

The temperature shot up to 450°C in seconds! – I think there’s a sensor in the very tip of the iron, and it wasn’t touching anything, so this heater went full blast – charring the thermocouple insulation on its way up. I switched the iron off manually, and then everything coooled off.

Second try, this time replicating yesterday’s setup:

Screen Shot 2010 05 12 at 16.02.57

Perfect. A step pulse and the response curve (grill was opened @ 175°C, like yesterday).

Warning: if you try these experiments, make sure you unplug your oven / grill / whatever when you’re done. Starting a fire while you’re tinkering with something else, or out of the house, or asleep is not a good idea…

Tomorrow, I’m going to create a feedback-control loop.

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.

Oregon sensors

In Software on Apr 15, 2010 at 00:01

Let’s try to decode the OOK data coming from an Oregon Scientific THGR810 sensor:

Dsc 1340

It sends at 433 MHz (the above picture was accidentally set to Fahrenheit). I used the OOK scope to figure out which pulse widths to use in the decoder. Ended up splitting pulses shorter and longer than 700 µs.

Anyway, now I can write a bit-decoder for it, using the same finite state machine approach I’ve used before for KAKU and FS20. But there’s one difference: these bits are Manchester encoded, i.e. 0 has two short pulses, while 1 is one long pulse. The Manchester encoding can be deduced from the fact that when you replace two short pulses my one marker, you get more or less consistent packet lengths. Since successive 1’s must flip the interpretation of the signal, there’s one extra bit of state to carry around in the decoder.

Most of these things can be determined by trial and error. Same for the synchronization pattern, the exact bit offset to start the data, and the bit / nibble / byte order of the data.

It helps tremendously that the sensor has an LCD display, showing what values it is transmitting, of course.

My basic approach is to collect lots and lots of pulses, and save them to file as Tcl scripts. Then I weed out impossible runs of bits, keeping only what looks like potential 0/1 sequences of a decent length. Then just keep collecting, until some “packets” end up being received more than once.

Once I have a dozen or more packets which keep showing up, it’s time to look at the preamble, to try and figure out what the common prefix could be. It’s usually pretty obvious by then. The only uncertainty being at which bit the preamble stops and the actual data starts.

Anyway, for the THGR810, this is some of the data I ended up receiving:

Screen Shot 2010 04 12 at 17.43.19

If you look closely, you can already see the reported values in reverse hex in the data.

That’s it!

Here’s the main part of the decoding logic for this sensor:

Screen Shot 2010 04 13 at 16.11.39

And here’s the received data:

Screen Shot 2010 04 12 at 12.18.44

The last value is the seconds timer, showing that this sensor is reporting values roughly every 70..90 seconds. I did some resets and fiddled with the channel switches, to be able to later determine which bits they correlate to.

Another run, showing the temperature dropping from 21.1° ro 20.1°:

Screen Shot 2010 04 13 at 00.37.49

Will do the checksums and separation into readings in JeeMon … another time!

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.

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!

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:


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:


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:


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:


And sure enough, here’s a scope capture of an FS20 transmission:


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:


And here’s a zoomed-in area, showing what looks like pretty decent 400 µs and 600 µs pulses:


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.

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:


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:


There really are only three wires: GND, +3V, and the received bit stream, which is tied to the AIO pin:


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.

More efficient computing

In Hardware on Nov 4, 2009 at 00:01

A few days ago, I replaced my (3y old) MacBook Pro + (8y old) Cinema Display with a brand new 27″ iMac. Here’s the result:

Screen shot 2009-10-31 at 17.59.38.png

That’s the total energy consumption of my work desk – i.e. computer, lights, and a some USB-powered stuff. The scale is in Watt-per-5-minutes, so if you multiply all figures by 12 you’ll get the normal Watt ratings.

There are many different operating modes here – night-time near off, full sleep, display sleep, display on, a few computing peaks, and in the evening also the lights on.

On Oct 30 both machines were active, while all the data from the old setup was being migrated to the new one.

The interesting parts are the low periods at night which more or less dropped to zero, even though the iMac is simply sleeping (with BlueTooth and USB still on), not turned off.

It’s also nice to see that even with this new dual-core 3.3 GHz monster, energy consumption is noticeably lower most of the time – not just in idle mode!

These readings were obtained with the ES-1 sensor described a while back + a central JeeNode + JeeMon.

Updated RF12demo

In AVR, Software on Oct 29, 2009 at 00:01

The RF12demo software which comes pre-loaded on all JeeNodes and JeeLinks has been extended a bit:

Picture 1.png

The new commands are:

  • l – to turn the activity LED on or off, if present
  • f – send a FS20 command on the 868 MHz band
  • k – send a KAKU command on the 434 MHz band

The new FS20 and KAKU commands were added so that a JeeLink can be used out-of-the-box to control the commercially available remote switches of these types. The updated demo is included with all new JeeNodes and JeeLinks from now on.

For example, to turn on channel 1 of a FS20 unit with housecode 0x1234, you can type in “18,52,1,17f” – i.e. the house code in bytes, the channel, and 17, which is the “on” command. Likewise, to turn on channel 1 of group B on KAKU, type “2,1,1k”.

The KAKU transmission range is not very high because the RFM12B radio used is tuned for the 868 MHz band, but even more so because the attached wire antenna is completely wrong for use at 434 MHz. If you want to use this for controlling KAKU devices and don’t get enough range, try extending the antenna wire to around 17 cm, i.e. double its current length. You can just attach an extra piece of wire to the end.

Which – unfortunately – is going to substantially reduce the range at 868 Mhz… so if you really want to use both frequency bands, you’ll have to use two JeeNodes or JeeLinks, each with their own properly sized wire antennas.

For more info about FS20, see these posts on the weblog. For KAKU, see these.

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:



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?

Of JeeNodes and JeeLinks

In Hardware on Oct 18, 2009 at 00:01

There’s a new JeeLink coming…


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.

Light to RF converter

In Hardware on Oct 8, 2009 at 00:01

While testing out some new code to handle extended FS20 packets in the forum, I remembered that I had an FS20 LS sensor still lying around:


Puzzled? Maybe the back will show a bit better what this thing is about:


Still puzzled? Me too – until I assembled the kit and tried it out. There is a light sensor on the back with a bit of sticky tape, which you’re supposed to place over a LED or some other light signal.

What it does is whenever light on or off is detected, it sends out an RF signal at 868 MHz using the FS20 protocol. So any FS20 receiver can pick it up:

Picture 3.png

The four buttons are a way to adjust all sorts of settings. I haven’t tried those, the factory defaults seem to work just fine for me. As it is this is a nice install-and-forget unit. Hopefully the battery will last a year or more.

Could this report the fridge light? Hmm, not sure – not all packets are coming out. Maybe it’ll be ok if the receiver is close enough.

Cool – another wireless gadget to help automate stuff around the house!

My first reflow

In Hardware on Jul 13, 2009 at 00:01

Here’s my new super duper reflow setup:


I decided to use a JeeNode as reflow controller. This is all about hammers, nails, and dog food, after all :)

The grill is turned on and off via an FS20 remote power switch, which is controlled by the on-board RFM12B. No need to get into relays and high-voltage stuff. Total cost including grill, LCD, and remote switch is under € 100.

The whole setup can be battery powered. I used the new plug breadboarding approach for prototyping it all:


The “P” at the lower left indicates it’s currently in the pre-heat phase, now at 110° with a target of 140°.

The port assignments on the JeeNode are:

  • Port 1: serial 4×20 LCD display, based on the Modern Device LCD117
  • Port 2: NTC on AIO with 1 KΩ pull-up to 3.3V, piezo buzzer on DIO
  • Port 3: two leds: green is running, red is grill power on
  • Port 4: two switches: white is run/stop, black is select profile 0..9

I’m not using PID control. Merely did a manual test to determine the overshoot, and am compensating for that by turning off a bit earlier. It turns out that this grill has a huge overshoot: some 65°C ! … so I removed both Teflon-covered metal plates and am now using a 0.5 mm aluminium panel instead. Overshoot is now around 30°.

The system can be configured through FTDI / USB. Once set up, it can be operated without computer. The LCD display is optional but a great convenience.

Here’s the first test board (using some scrap boards from SparkFun):


This is the cool-down phase, i.e. with the grill open. The temperature sensor is taped to a separate board to track things under similar conditions. The tape needs to be heat resistant, of course… I got it from DealExtreme:


And here’s the final result:


Only used a few resistors for this trial, and spread some paste on the TQFP pads to see how that comes out.

If you look closely, you’ll see that the leftmost resistor under header pin 13 is “tomb-stoned” – it’s standing straight up as the capillary pull of one pad took over. I probably put too much paste on one pad and not enough on the other.

But the rest looks good… f a s c i n a t i n g !

I seem to be getting a decent temperature profile. Things heat up nicely, stay in soaking ramp-up mode for a while, and then go up to a few degrees over 220°C. When the grill has to be opened up for cooling down after reflow, the system beeps to draw my attention.

FWIW, the source code for this setup is available here.

There’s still an intermittent problem with the NTC hookup – I’m getting occasional flakey connections on the enamel wires, which are simply wound tightly around each end of the NTC. Can’t use solder there, and I haven’t found another solution for that. For now, the controller just powers off when the NTC reading is bad, but that’s a pretty horrible approach.

Conclusion so far: reflow is absolutely doable for hobbyists (my second try went perfectly!), with the paste being the most tricky bit. Stencils are probably very useful to apply paste quickly and evenly.

See also Stephen Eaton’s recent post, where he describes his latest results with SMD reflow.

Trying to receive OOK data

In AVR, Software on May 18, 2009 at 00:01

Here is an experiment to try and (ab)use the RFM12B module for OOK reception, such as sent out by a FS20 remote control. First the complete sketch:

Picture 2.png

The interesting bit is that this appears to work – the LED flashes when I press a button on the FS20 remote:

OOK receive trial

Since the signal is made to come out on the AIO port 1 pin (A0), this whole unit can be plugged into a second JeeNode running the OOK decoding code from an earlier post. Like this:

OOK receive trial

The reason for using two JeeNodes is that the one receiving the OOK signal is 100% tied up in a loop polling the status register. No problem – we simply upgrade to a dual-core setup :)

Unfortunately, the combination isn’t working yet. I’ll need to use the scope or logic analyzer to figure out what’s going on. Perhaps the RFM12B’s RSSI circuit is not fast enough to faithfully reproduce OOK transitions.

Oh, well.

Something happened …

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

The electricity / gas metering monitor – which has been running for months – stopped working:

Picture 1.png

It just flat-lined, dead, nada. Power cycling everything and re-flashing the meter node did not fix it. I don’t see any packets from the meter node on the air when listening via an independent JeeNode.

The only packets right now are from a JeeNode pulse upstairs, which keeps resending – indicating that the central JeeHub isn’t replying with an ack. Weird.

I’ve adjusted all nodes to explicitly use netgroup 0x50, since there have been changes to the RF12 default netgroup and CRC calculation. Just to rule out a potential issue.

Still no go. I’m flabbergasted.

Update – uh, oh… the JeeHub 3.3V regulator is way too hot. It’s shutting down from time to time. Not good!

Time to switch to plan B – a JeeNode used as packet receiver connected to my “Bubba II” NAS. It’s been running all the time to collect weather data from the KS300 anyway. Still no electricity / gas metering data coming in, but at least all the remaining JeeNode and KS300/FS20 data gets logged again.

Update 2 – first there was one problem (JeeHub failing), then I created another one by re-flashing the metering JeeNode with the wrong node ID – doh! Anyway, metering data is coming in again now. Still don’t know why / how the JeeHub broke, but it was up for a hardware revision anyway…

JeeHub Lite

In AVR, Hardware on May 4, 2009 at 00:01

The current JeeHub includes a MMnet1001 Linux module, which is great for running JeeMon. But for an even more basic always-on system, it’s possible to forego the Linux part – here’s the idea:

Picture 1.png

The whole thing is powered from USB, which must remain on permanently. There is no need for the attached computer to be on all the time, because incoming data can be saved into the on-board DataFlash memory. Depending on data volume and memory size, it ought to be possible to have a few days of autonomy.

The 433 and 868 MHz OOK receivers make this thing suitable for receiving weather data from off-the-shelf components, as well as responding to KAKU and FS20 remotes (and others like them). And since the RFM12B is so versatile, it can also send out 433 and 868 MHz OOK commands to those systems.

One thing I forgot to add in the above diagram, is a DCF77 receiver – or perhaps using a crystal or RTC. As has been mentioned a few times, the JeeHub needs to have a fairly accurate sense of time to do its main job of collecting real-time readings.

Only a minimal number of signals/ports are needed for the main tasks, there are several pins left to connect a few extra sensors.

The main bottleneck will probably be the amount of code needed to make such a JeeHub Lite perform basic home automation tasks. An Atmega328 might help a bit.

The normal monitoring and reporting work is still done with JeeMon, but now running on the attached PC (which can be Windows, Mac OS X, Linux, whatever). In such a configuration JeeMon must catch-up and extract saved data from the DataFlash in the JeeNode whenever it is launched.

RFM12 vs RFM12B

In AVR, Hardware on Apr 29, 2009 at 00:01

Here’s an RFM12 433 MHz module from Pollin, hooked up to an Arduino Duemilanove:

RFM12 (not RFM12B) @ 5V

One major difference between the RFM12 and the RFM12B is that the RFM12 can run at 5V, whereas the maximum operating voltage for the RFM12B is 3.8V (it can withstand up to 6V, which is good to know).

Alas, there seems to be some other difference which eludes me, because the RFM12 hooked up in the above picture only seems to be able to send. The RF12 demo code, which works fine for send and receive on RFM12B’s seems to do something wrong. Same behavior with another RFM12 module – so it looks like this is not due to a broken module. Send works, but nothing is coming in other than occasional garbage data.

The transmit part works fine when sending to an RFM12B, also in OOK mode: the RFM12 successfully controls both 433 and 868 MHz units (KAKU and FS20, respectively). But as packet receiver for other RFM12 or RFM12B modules … no joy so far.

Weird. Tips, anyone? Please let me know.

Update – Thanks to R. Max’s comment below, the problem has been solved: the RFM12 does not support arbitrary 2-byte sync patterns, it has to be 0x2D + 0xD4 – then it works fine!

Update 2 See also the RFM12 vs RFM12B revisited page for a list of differences.

RF woes – solved!

In Software on Apr 28, 2009 at 00:01

Turns out my troubles with using the 868 MHz OOK radio next to the RFM12B module were caused by a silly software mistake (I mixed up the port assignments). No hardware or RF issues after all.

Latest sample output:

Picture 2.png

(the VOLT and BARO readings are bogus because the hardware is not connected)

As you can see, it’s receiving both packet types now. Still some trickiness with allocating the port signals properly, since some lines do require specific pins: the OOK receiver uses the analog comparator, but the ADC gets used as well, so I’ll need to adjust things a bit to use a pin change interrupt instead (used a crude workaround for now).

So now the basics are there to receive all types of signals with a single JeeHub: packets from other JeeNodes using the RFM12B, an 868 MHz OOK receiver for weather data and the FS20 remotes, and a 433 MHz OOK receiver for picking up KAKU remote commands (and possibly some other cheap weather sensors later).

More OOK signal decoding

In AVR, Software on Apr 21, 2009 at 00:01

The ES-1 energy sensor described in yesterday’s post is now also recognized by the OOK reception code (the touch panel too, since it uses the FS20 protocol):

Picture 2.png

The main state machine code is still essentially the same:

Picture 1.png

Note that three completely different and independent pulse patterns are being recognized. These recognizers run in parallel, although evidently only at most one will end up with a successful reception at any point in time.

An updated sketch for the Arduino IDE can be found here.

Switching AC

In Hardware on Apr 16, 2009 at 00:01

Got myself a couple of these relays from Pollin, for less than the coin next to it:

Bi-stable relay

They can switch 220V @ 16A, and work at 3V. The specialty is that this relay is bi-stable, IOW there are two 15 Ω coils and you send a short pulse through either of them to switch to the corresponding position. So it takes some power to switch, but after that the relay keeps its last position without power. Like a mechanical switch.

It does take some 200 mA – briefly – to switch, so the power supply has to be up to that.

My plan is to connect this to a JeeNode as follows:

Picture 3.png

Probably using a pair of BC547 transistors and 1N4148 diodes (or maybe a ULN2803, to control up to 4 relays). That way, each port would be able to drive one relay. A pretty cheap solution to control any 220 V appliance.

Haven’t decided yet how far to go into actual AC control, since the other option is to use off-the-shelf RF-controlled switches, such as the Conrad/ELV FS20 868 MHz series or the cheap KAKU 433 MHz switches. But relays can be more secure, if some encryption is added to the RF12 driver.

Fun note: I spent a lot of time as a teenager thinking about building a (feeble) computer with relays. After all, this is essentially a 1-bit memory. I’ve moved on since then … slightly :)

Decoding multiple OOK signals

In AVR, Software on Apr 12, 2009 at 00:01

It is possible to decode multiple signals with a single 868 MHz OOK bit-by-bit receiver, like this JeeNode setup:

868 MHz reception

Here’s the output from a sample run, receiving data from an FS20 remote, a KS300 weather station, and two S300 weather sensors:

Picture 1.png

The trick is to maintain independent state for all the signal patterns. The pulses need not have the same lengths, as long as each recognizer only picks up what it wants and stops decoding when anything unexpected comes in.

Here is an interrupt-driven implementation, using the analog comparator to pick up bit transitions and timer 2 to measure pulse widths:

Picture 2.png

If no transition is seen within 1024 µsec, timer 2 overflows and resets all recognizers to their UNKNOWN state.

A sketch for the Arduino IDE can be found here.

OOK signaling with an RFM12B

In AVR, Software on Mar 3, 2009 at 00:01

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

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

OOK signaling with an RFM12B

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

OOK signaling with an RFM12B

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

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


In AVR on Dec 20, 2008 at 15:56

Failures are worth documenting too… here is one:


This was intended to become a general-purpose 868 MHz wireless solution: a low-end receiver + transmitter from Conrad, alongside an 868 MHz RFM12B which is likely to become my workhorse module. The receiver + transmitter are compatible with the FS20 wireless remote protocol, and allow listening as well as controlling these devices.

Well, most of this stuff didn’t work once hooked up. For various reasons actually – from bad sensitivity to using the wrong module (turns out that RFM12 unit was in fact for 433 MHz, doh).

In an attempt to salvage this thingamagic, I decided to replace & rewire the whole thing. It is now a 433 MHz receiver + transmitter, and an RFM12, also working on 433 MHz. The whole has been put aside for now, but maybe one day it can be made to work with some 433 MHz stuff, such as this or some cheap weather sensors.

Due to the switch to a lower frequency band, all three antennas are now 17 cm long wires.

The microcntroller is an Arduino Nano, btw. This is a 16 MHz 5V unit with a mini-USB port.

This is not a mouse

In AVR, Hardware on Dec 17, 2008 at 15:53

The CUL is a small gadget which combines a CC1101 RF module with a USB-enabled ATmega processor in a very small unit:


So, yes, it has a tail and it plugs into a USB port, but it’s not a mouse. This thing can receive and decode messages from 868 MHz devices such as the FS20 home control unit, the KS300 weather sensor, and more. Technically, it could also send out such messages since the CC1101 is a transceiver, but apparently the 1.07 firmware isn’t quite there yet.

Switching stuff

In Hardware on Dec 16, 2008 at 15:51

Today, some simple “KAKU” remote switches came in. These are both by KlikOn-KlikOff – the first one is an older setup I was already using, with up to 12 different codes:


The second is a newer model with up to 256 different codes – it’s heavily discounted (€14 for 2 units plus transmitter), probably because this type is being replaced by a newer model which uses unique unit codes:


The drawback with both of these, as compared to the FS20 models by Conrad, is that you can’t control them at the plug – you have to locate the remote and press buttons on it. But then again, at these low prices per unit … you get what you pay for.

These units use 433 MHz signalling, there’s code for Arduinos which understands the KAKU protocol.

Home Control

In Hardware on Dec 7, 2008 at 15:34

The FS20 system by Conrad is a simple RF-based set of modules to turn various appliances on and off. The transmitter looks like this:


The most basic on/off remote control switches are as follows, shown with central European power plugs:


They have an on/off toggle on the unit, which is a big plus over simpler units. The other useful aspect of these units is that they operate over the 868 MHz band, and that the details of the FS20 protocol are available. Several projects exist which can receive and/or transmit the corresponding signals.

Definitely not the most beautiful design, but hey, they get the job done…