Computing stuff tied to the physical world

Posts Tagged ‘Sensors’

Small Gravity Plug update

In Hardware on Sep 25, 2013 at 00:01

The Gravity Plug contains a BMA020 3-axis accelerometer from Bosch Sensortec, which is being replaced by a newer BMA150 chip. Luckily, it’s fully compatible in both hardware and software, so the GravityPlug implementation in JeeLib will continue to work just fine with either one.

But the new chip does have more features: you can override its calibration parameters and defaults, by changing values in a new EEPROM area added to the chip. That in itself is probably not too useful for simple setups, but the new chip also offers access to its built-in temperature sensor, so I’ve added some extra code and expanded the gravity_demo sketch to take advantage of that:

#include <JeeLib.h>

PortI2C myBus (1);
GravityPlug sensor (myBus);
MilliTimer measureTimer;

struct {
  int axes[3];
  int temp;
} payload;

void setup () {
    Serial.begin(57600);
    Serial.println("\n[gravity_demo]");

    if (sensor.isPresent()) {
      Serial.print("sensor version ");
      sensor.send();
      sensor.write(0x01);
      sensor.receive();
      Serial.println(sensor.read(1), HEX);
      sensor.stop();
    }

    rf12_initialize(7, RF12_868MHZ, 42);
    sensor.begin();
}

void loop () {
    if (measureTimer.poll(1000)) {
        memcpy(payload.axes, sensor.getAxes(), sizeof payload.axes);
        payload.temp = sensor.temperature();

        rf12_sendNow(0, &payload, sizeof payload);

        Serial.print("GRAV ");
        Serial.print(payload.axes[0]);
        Serial.print(' ');
        Serial.print(payload.axes[1]);
        Serial.print(' ');
        Serial.print(payload.axes[2]);
        Serial.print(' ');
        Serial.println(payload.temp);
    }
}

Here is some sample output:

GRAV 2 -10 130 41
GRAV 0 -9 133 41
GRAV 4 -14 127 41
GRAV 0 -12 134 41
GRAV 4 -15 130 41
GRAV 4 -13 129 42
GRAV 3 -8 128 41

The reported temperature is in units of 0.5°C, so the above is reporting 20.5 .. 21.0 °C.

Unfortunately, the old chip isn’t reporting anything consistent as temperature:

GRAV 51 -31 -225 2
GRAV 50 -29 -225 0
GRAV 51 -30 -224 1
GRAV 52 -30 -227 1
GRAV 51 -30 -229 1
GRAV 52 -31 -223 2
GRAV 51 -31 -225 1

I have not found a way to distinguish these two chips at runtime – both report 0x02 in register 0 and 0x12 in register 1. Makes you wonder what the point is of having a chip “ID” register in the first place…

Anyway – in the near future, the Gravity Plug will be shipped with the new BMA150 chips. It should have no impact on your projects if you use these accelerometers, but at least you’ll be able to “sort of” tell which is which from the temperature readout. Note that the boards will probably still be marked as “BMA020″ on the silkscreen for a while – there’s little point in replacing them, given that the change is so totally compatible either way…

Hard disk power – bonus

In Hardware on Jun 2, 2011 at 00:01

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

Wait a minute…

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

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

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

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

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

Screen Shot 2011 05 30 at 02.00.54

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

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

Screen Shot 2011 05 30 at 01.54.25

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

Screen Shot 2011 05 30 at 02.06.51

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

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

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

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

Gas flow measurement artifacts

In Hardware on Mar 14, 2011 at 00:01

The raw gas consumption graph always looks a bit odd:

Screen Shot 2011 03 13 at 12.59.45

Green is gas flow, red is electricity consumption.

This is the same oddity I described two years ago on this weblog. The values are calculated from the last rotation time of the meter, but with gas flow things are a bit different: gas consumption is not continuous but a discrete on/off process, with some “modulation” once on.

So instead of each of those “tapering off” effects, what really happens is that the flow stops completely for a while and then resumes again later on.

This is an example of where the measurements need to be “fixed” (!), by injecting fake data points. It also illustrates how you can’t really know anything about consumption between disk rotation pulses.

The vertical grid lines in the above graph are spaced 500 l/h (resp. 500 W) apart, btw.

Meet the new Room Board v2

In Hardware on Nov 28, 2010 at 00:01

For some time now, the Room Board kit has been outfitted with a new PIR sensor:

It’s nicely low-power, but unfortunately it has a pin-out which differs from the ELV model, even with 3 pins!

So I’ve decided to make a new Room Board v2, which drops support for the 8-pin ePir to allow the new PIR sensor to be mounted in two different ways.

Here’s the board, with a solder drop already applied for the SHT11 (much easier to solder it in that way):

Dsc 2345

Things have been moved around a bit, but the basic setup hasn’t changed. The 3 pins in the top left are still for the ELV PIR, and the 1-wire DS18B20 option is still there (with fixed pinout, yeay!).

Here is the board with SHT11 and LDR soldered on:

Dsc 2348

And here are the two ways to attach the new PIR sensor:

Dsc 2350 Dsc 2349

That second setup is the most compact, but also the most inconvenient one if you ever need to make changes or reach the headers. Note that the PIR pins were soldered in as far out as possible, and that the LDR was bent sideways a bit:

Dsc 2354

I would advise to use the first setup where possible.

Having said that, here’s a complete Room Node with the (relatively) “compact” layout:

Dsc 2355

Bit of a hodge-podge, but that’s what you get when everything is kept modular.

Spectrum Analyzer

In AVR, Software on Nov 26, 2010 at 00:01

Intrigued by this post, I wanted to try the same thing with the Graphics Board.

So here goes:

Dsc 2330

A real-time Spectrum Analyzer, with due credit to “deif” on the Arduino forum for making Tom Roberts’ simple 8-bit FFT implementation available (three more people are credited in the source code). On the above display you can see a typical “power spectrum”, with one dominant frequency plus harmonics at fixed intervals.

The sketch can be found here:

Screen Shot 2010 11 23 at 00.14.25

This is almost the same code as the 100 KHz DSO sketch, just extended with FFT.

The LCD is refreshed at maximum speed. As you can see, the lag of the LCD itself is actually quite useful in this context. This did bring a bug to the surface: I’ve noticed that the speed-up I implemented for the ST7565 was slightly too fast for this chip. After running for a while, the display would just turn black and stop refreshing.

So I changed these two lines in ST7565::spiwrite() :

Screen Shot 2010 11 22 at 23.48.10

… to this, slightly slower but equivalent code:

Screen Shot 2010 11 22 at 23.48.43

I’ve also updated my version of the ST7565 ZIP file accordingly.

One more note about this code is that it uses most of the available RAM now: the 1 Kb buffer in the ST7565 library, plus two 256-char arrays to store 256 datapoints for running the FFT on.

With code such as this, it would actually be possible to get rid of the ST7565 buffer, since we’re re-constructing the entire display each time.

But for now, I’ll just leave it at this…

2-channel Logic Analyzer

In AVR, Hardware, Software on Nov 25, 2010 at 00:01

Let’s continue the tiny lab-instrument series ;)

Here’s a logic analyzer which takes 512 samples of 2 bits (DIO2 and AIO2):

Dsc 2318

The “trace” starts when either of the inputs changes. I’ve enabled the internal pull-ups, so in this example you can see that DIO2 has no signal. The AIO2 signal is from a JeeNode running the Arduino IDE’s built-in “ASCIItable” demo, which sends out a bunch of characters at 9600 baud (I took the signal from the USB-BUB connector).

Here is the glcdTracer.pde sketch which implements this:

Screen Shot 2010 11 20 at 17.24.06

Lots of trickery with bits. To keep memory use very low, I’m storing the 512 samples in a 128-byte buffer (512 x 2 bits = 128 x 8 bits). Low values are drawn as a pixel, high values are drawn as a little vertical line.

The code includes a minimal triggering mechanism, i.e. it waits for either of the input signals to change before collecting 512 samples.

Samples are collected at about 10 KHz, but this can easily be changed (up to ≈ 200 KHz with the current code).

Note that it would be possible to double the number of samples to 1024 and display them as 8 groups of 2 signals, but then you’ll have to really squeeze the output to fit it onto the 64×128 pixels on the display.

BTW, there’s some shadowing visible on the display – has to do with how the chip drives the GLCD, no doubt.

Soooo… now we also have a portable Logic Analyzer!

100 KHz DSO

In AVR, Hardware, Software on Nov 23, 2010 at 00:01

You might have been wondering why I created the digital-to-analog converter a few days ago.

Well, because I needed a test signal… to build this thing:

Dsc 2307

You’re looking at a <cough> Digital Storage Scope </cough> with 100 KHz bandwidth :)

First of all: please don’t expect too much. There is no signal conditioning and no triggering whatsoever, and there are no external controls. This is simply a JeeNode plus a Graphics Board. It’s using the built-in ADC, with the conversion clock pushed quite a bit higher than what the Arduino’s analogRead() function will do. This speed comes at the cost of conversion accuracy, which isn’t so important since the Graphics Board display only has 6-bit vertical resolution anyway.

The screenshot shows a 1 KHz sine (from that Bleep! thing, obviously). As you can see, one cycle more-or-less covers the entire x-axis. So that’s about 128 samples per millisecond. This is not the maximum value, the ADC can also work twice as fast – i.e. with a division factor of 4 (ADPS2:0 = 2). This translates to 4 µs per sample.

Using the Nyquist–Shannon sampling theorem again, you can detect a frequency if you sample it at least twice per cycle, so that would have to be a cycle of at least 8 µs, i.e. over 100 KHz. Which is why I decided to call this thing a 100 KHz DSO :)

The code tries to get as many samples as possible into a little 128-byte buffer before doing the rest of the work. The graphics display has a fairly limited response time, so I’m refreshing the display at 5 Hz (it’s still visible up to 50 Hz, but only just…).

I find it pretty amazing what an MPU such as the ATmega can do these days, with just a few lines of C code. Here’s the entire glcdScope.pde sketch:

Screen Shot 2010 11 19 at 02.58.10

The rest of the code is in the same modified ST7565 library as used in the past few days.

There’s lots of room for expansion, this code uses less than 4 Kb.

So there you have it – a very crude, but functional, oscilloscope!

Meet the Heading Board

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

Here’s another plug which didn’t work initially, but as always it was a simple mistake in the software (and a not-so-clear datasheet) which prevented me from using this thing:

Dsc 2157

The Heading Board is based on a somewhat unusual HDPM01 combination sensor by HopeRF, containing a 2-axis compass / magnetometer and a … temperature + pressure sensor. My interest in this thing was the compass, which is relatively low-cost compared to most other options out there.

There’s now a HeadingBoard class in the Ports library to make this thing sing. Note that it’s called a “board” and not a “plug” because it requires two ports and sits as a mini-board on top of a JeeNode (same as the Room Board):

Screen Shot 2010 10 24 at 17.39.20

This board is a somewhat awkward match for the ports concept, because it needs a 32 KHz clock to function. I’ve hooked that up to the IRQ pin, which is reprogrammed by HeadingBoard::begin() to generate that clock using Timer 2, so you may have to jump through some hoops to use this if other ports use the IRQ pin for a different purpose. A more general approach would be to generate the required 32 KHz on-board with an NE555, as is done in an upcoming Infrared Plug – but that requires extra board space (or components on both sides of the pcb).

Here is the “heading_demo.pde” sketch, now added to the Ports library as example:

Screen Shot 2010 10 24 at 17.40.20

Sample output:

Screen Shot 2010 10 24 at 17.17.02

I haven’t figured out the conversion from X-/Y-axis values to compass heading yet. There is some sensitivity to how the board is positioned horizontally – this could be compensated by detecting the angular position using a Gravity Plug. But as you can see, there is a clear variation in readings as I turned the JeeNode + Heading Board around the Z axis.

So if you’re into robots: a Heading Board plus a Gravity Plug is all you need to determine your absolute orientation in all the 3 axes in space, i.e. X, Y, and Z.

Onwards!

PS. Here’s a crazy idea: we could use the Heading Board to create a door-open sensor. Simply attach this thing to a door, and track the Z-axis orientation!

Meet the Proximity Plug

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

The Proximity Plug was created a while back, but at the time I couldn’t get the chip to respond properly. Turns out that this was just some silly mistake in the code, so now all is well and ready for use:

DSC_1267.jpg

This plug uses an MPR084 to support up to 8 capacitive touch sensors. These can be created in any shape you like, using some conductive board, film, or tape. There’s a solder jumper to set one of two I2C addresses, so up to 16 sensors can be hooked up to a single port.

Here’s a little test setup:

Dsc 2154

Capacitive sensing can be fairly tricky to get right – the sensors may respond slightly differently, cross-talk between each sensor, electromagnetic noise pick-up, etc. But this chip does a lot of the work for us.

There are many configurations settings, and I’ve only started to scratch the surface so far. The current setup is configured to only report a single touch at a time, and does auto-calibration on startup. I’m still seeing some cases where things lock up and may have to be reset (in software), so the interface class for this thing is very basic for now – simply giving acces to the individual registers from I2C.

Screen Shot 2010 10 24 at 13.01.33

I’ve added a “proximity_demo.pde” sketch to the Ports library to demonstrate the use of this plug:

Screen Shot 2010 10 24 at 13.10.36

It will print a message whenever a “key-press” is detected. The commented-out code prints out the following ID string extracted from the chip:

    #reescale,PN:MPR084,QUAL:EXTERNAL,VER:1_0_0

Note that the MPR084 chip wants a 100 KHz I2C bus.

One thing I’d like to try with this thing, is to create some input buttons with it using the Carrier Board box. It would be nice if the sensors can be made sensitive enough to reliably work with a bit of copper on the inside of the box, then you wouldn’t even have to drill holes or make any cutouts to be able to control what’s inside. Otherwise, perhaps a slit for adhesive / conductive copper tape, covered up with plastic foil?

More detective work needed…

Wireless mousetrap

In Hardware on Oct 22, 2010 at 00:01

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

I’ll let Mathias introduce his project:

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

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

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

Here’s the mousetrap, ready to go:

Mouse Trap

With a guest…

Mouse in Trap

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

Homepage

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

Musetrap v0 1 bb

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

Mathias concludes with:

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

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

Reporting motion

In AVR, Software on Oct 21, 2010 at 00:01

Yesterday’s post presented a new sketch which did everything the old sketch did, except report motion. The reason was that the requirements for reporting motion are quite different from the rest: it has to be reported right away – using ACKs, time-outs, and retries to make sure this message is properly received.

The latest version of roomNode.pde now adds the missing logic. And it does indeed get a lot messier – doubling the total number of lines in the source code.

Here is the new loop() code:

Screen Shot 2010 10 19 at 22.37.41

The key change is that there is now a check for “pir.triggered()” which will be called outside all normal scheduling actions. Note that this code is still using scheduler.pollWaiting(), so the code is still spending most of its time in power-down mode.

Except that now, we’re also setting up a pin-change interrupt for the PIR sensor:

Screen Shot 2010 10 19 at 22.40.16

The new code to handle these PIR triggers is as follows:

Screen Shot 2010 10 19 at 22.42.14

So instead of folding this complicated case into the rest of the code, when a PIR trigger goes off, we now simply send that packet out and wait for the ACK, repeating it a few times if necessary. The normal measurement and reporting tasks are not affected by any of this, other than that the measurement scheduling is postponed a bit to avoid triggering another report right away.

The new PIR motion sensor turns out to be quite convenient, because it has an on-board trimpot to set the re-trigger timeout. As long as motion is detected more often than this threshold, the PIR output will remain 1, so there is no need to play tricks in software to avoid constant triggers. We’ll get one pin change for the start of motion, and another one when no motion has been detected for a preset amount of time.

Having said that, I’ve implemented a similar re-triggerable one-shot mechanism in software anyway, because my older nodes use the ELV PIR sensor, which send out a pulse for each motion trigger. So all ON pulses within 30 seconds of each other get coalesced into one.

To illustrate that the system is still doing almost nothing most of the time, I added a debug mode which prints a “.” on each iteration of loop(). In normal Arduino sketches, this would cause an incessant stream of characters to be printed out, but in this sketch there are just a few:

Screen Shot 2010 10 19 at 22.12.35

Motion detection now works more or less independently of the normal measure / report tasks.

There are still some rough edges, but I expect this new code to perform considerably better in terms of battery lifetime already. The dreaded battery rundown problem when the central node is not reachable should be gone. All that remains are a few attempts (I’ve set it to 5) whenever the PIR sensor turns on or off. In both cases the ACK has to be received within 10 milliseconds – after that the sketch enters power-down mode again.

The new code should also make it much easier to add sensor types (switches, hall-effect, 1-wire, barometer).

FWIW, this code needs 8238 bytes (without serial I/O), so it’ll still easily fit in an ATmega168. Without SHT11 (which uses floating point) that drops to 5682 bytes, including the RF12 driver. How’s that for a WSN node!

New roomNode code

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

It’s time to start putting the pieces together now: sensor readout, scheduling of measurements and packet sends, and low-power mode. Looks like the code in the Ports and RF12 libraries is now making this easier than ever.

There’s a new roomNode.pde sketch which illustrates the whole shebang. At 145 lines, it’s a bit too long to include here in full, but I’ll show some of the interesting pieces.

Note that this version implements everything except motion reporting, which is a bit more complex.

Following the good ol’ top-down tradition, first the setup() and loop() code:

Screen Shot 2010 10 19 at 14.06.12

It starts the measurement loop, which then keeps itself running periodically. The report activity is started every once in a while. Note also the “now” variable, which will make it easier to use 2-byte ints in the logic which will decide later about when to report motion, etc.

The measurement code depends completely on what sensors are supported, and is pretty straightforward:

Screen Shot 2010 10 19 at 14.10.36

No surprises, we just have to be careful to do things in an energy-efficient manner. All the readings end up in the “payload” struct.

And here’s the reporting code:

Screen Shot 2010 10 19 at 14.14.24

Here’s some sample output on the serial port:

Screen Shot 2010 10 19 at 14.18.17

I still need to add the logic for motion detection, but with the new scheduling capabiltities, I expect that extra complexity to stay within a small portion of the code – unlike the current rooms.pde sketch, where everything seems to affect everything else.

The best part? My multimeter stays mostly under 60 µa, i.e. the low-power logic is automatically kicking in!

Modular nodes, revisited

In Software on Oct 16, 2010 at 00:01

As pointed out in the comments yesterday, “nodes” in a WSN should to be more parametrized. With ports, it’s very easy to mix and match different sensors – creating nodes which are not all the same should be equally easy.

I’ve touched on a related topic before in a post titled Modular nodes.

Ideally, you want to write interface code for say a PIR motion sensor once, and then re-use it in different nodes. Same for an SHT11 temperature/humidity sensor, an IR send/receive sensor, a barometer, door switches, an OOK receiver, and so on – the list is bound to grow considerably over time.

Even “more ideally” (heh), you probably would like someone else to already have written that interface code, so you can just fill in the parameters and incorporate it into your own room-or-other node.

In fact, the whole (modular!) Plugs & Ports concept of JeeNodes is yearning for this type of modularity to be carried through to the software.

To achieve such modularity all the way through, several questions need to be answered:

  • are these interface code “snippets” always very small and self-contained, or do they need additional C/C++ source files?
  • can interfaces depend on other interfaces / is a class hierarchy the best way to modularize such dependencies and derivations?
  • can we have multiple instances of the same interface in a single node? (answer: yes, for example multiple door-open sensors, attached to different I/O pins)
  • how do we deal with a mix of interfaces which use different timing periods for readout?
  • how do we compose packets to send, if the information types vary?

One way to implement this modularity, is what I’ve been doing in the Ports library until now: define and implement C++ classes for each interface, and then create (static) instances of each interface needed in a particular node.

This is an extract of the Ports.h library header file:

Screen Shot 2010 10 15 at 21.54.25

It works – and I think it’s a decent start – but it doesn’t go far enough:

  • Many configuration parameters are variables (and data members inside C++ objects), even though they are essentially contant (the port number, an I2C device ID, I/O pin choices, etc). This eats up scarce RAM space, and prevents the compiler from fully optimizing the code. The “heavy” solution to this is C++ templates, as I’ve written about in threeolderposts. Trouble is: C++ templates are “viral”, once you start on that path, everything tends to become a template. Not my idea of simplicity…

  • I want to figure out what a good set of reporting periods is, to minimize the number of packets sent, for example. This task comes back with every type of node, so having some automated tool to help with that effort would be useful.

  • There can be severe resource constraints in low-power nodes. I’d like to see what the RAM and EEPROM (and FLASH) usage is when choosing a specific mix of interfaces. I’d also like to find out whether the interrupts can co-exist and still service everything sufficiently quickly. And I’d like to get estimates for battery life. None of this is impossible, even if unnecessary for a first implementation.

  • Implementing pin-change interrupt handlers is not easy to fit into C++ as run-time mechanism, even though for any given interface mix it is very simple to generate the interrupt handler code for it.

  • The result of a choice of interfaces is not just a sketch – it also implies specific packet structures, as used for getting data across. And indirectly, it also means there has to be something node-specific at the central node (not necessarily in that receiving node, it could be code that runs on an attached PC).

  • If the number of interfaces grows considerably, and if more people were to start implementing such interfaces, then the management and versioning of all these interface definitions (code, data, docs) needs to be addressed.

What this points to IMO, is the need for a “configurator” or “wizard” type tool, which knows about a large number of interfaces, and which produces a sketch when given a bunch of configuration choices. An even more convenient tool would let me manage my entire collection of nodes, so I can make most configuration choices once, and then manage all node definitions together. It’d let me add and update interfaces and nodes as needed, over time:

Screen Shot 2010 10 15 at 22.30.14

What comes out is still a C/C++ coded sketch, since that’s what needs to be uploaded to the node.

What should also come out (not included in the above diagram), are one or more packet structure definitions, as well as the code (or data definitions) needed to decode those packets again.

With this approach, you can pick the hardware needed for a specific node, enter your choices into the configurator, and be done with it. Upload the sketch it generated, turn the node on, and launch the central server with the information it needs to understand the new incoming data packets. For other nodes, or to make changes, simply rinse and repeat…

I haven’t decided yet whether I’ll actually go for this. It’s fairly ambitious, even for a simple first implementation. But it sure would scratch an itch of mine…

Room Node redesign

In Software on Oct 15, 2010 at 00:00

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

Dsc 2134

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Decoding IR pulses

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

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

Dsc 2129

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

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

Screen Shot 2010 10 12 at 17.30.37

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

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

Screen Shot 2010 10 12 at 17.33.59

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

Screen Shot 2010 10 12 at 16.49.22

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

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

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

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

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

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

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

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

New PIR motion sensor

In Hardware on Aug 30, 2010 at 00:01

From now on, the Room Board is going to be shipped with a new PIR (passive infrared) motion sensor:

Dsc 1866

The reason I went looking for a replacement is that the ELV unit was out of stock for a long time, especially in quantity. It seems to be back now, but I had already found a good alternative.

The unit shown above is nice for a couple of reasons:

  • it’s equally low-power, drawing 40..50 µA
  • this unit is specifically for 3 .. 3.3V, whereas the ELV unit was running slightly out of spec
    • (it officially requires 5..24V, but the regulator brings that to 3V)
  • it’s slightly lower on the sensor side (and higher on the component side)
  • the sensor seems to be sensitive over a somewhat wider angle
  • it’s no longer a kit, no need to solder-in that sensitive PIR chip anymore

I’ve yet to do some serious testing w.r.t. range, but it appears to be ok.

Here are the two sensors side-by-side:

Dsc 1867

One unfortunate detail is that the pinout is different. Yes, even 3 pins can lead to incompatible variations!

The old sensor has: VCC GND OUT – the new one uses: VCC OUT GND. Besides, I want to connect it to +3V now, i.s.o. PWR.

I solved this by using the other side of the room board, and reconnecting GND slightly differently – i.e. cutting the pin off and rewiring it as follows:

Dsc 1868

It’s a hack, but it works. The two remaining pins are still enough to keep the sensor board firmly in place.

Onwards!

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!)

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.

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.

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!

BMP085 in high-resolution mode

In Software on May 27, 2010 at 00:01

The BMP085 is a pressure sensor, as used on the Pressure Plug:

Dsc 0735

It’s quite popular. Some people get more than one – I can only assume it’s for some sort of altitude application.

By popular demand, I’ve updated the BMP085 code to support all 4 resolution modes. There is now an optional second argument to set the oversampling:

Screen Shot 2010 05 22 at 11.45.55

Allowed values are 0..3 – the default is the same as before, i.e. 0 (no oversampling).

Sample output from the bmp085demo.pde sketch in the Ports library, adjusted to use maximum oversampling:

Screen Shot 2010 05 22 at 11.42.09

Note that the return values of some intermediate routines have been changed from 16-bit to 32-bit. The calculated results are the same as before: temperature in units of 0.1°C and pressure in Pascal (i.e. x 0.01 hPa).

Thermocouple enigma

In Hardware on May 8, 2010 at 00:01

I’ve been scratching my head while trying to get the Thermo Plug to work with an on-board AD597 + thermocouple.

Sure, it works fine…

But only on a 4.5V battery pack! When I connect this thing through a USB-BUB, the readings are severely distorted 9 out of 10 times.

Here’s a sample of the readings on USB:

251 251 251 238 244 261 238 248 251 254 251 206 241 261 251 254 241 209 244

Here are some readings I get on battery power, i.e. not attached to anything:

206 209 206 206 206 209 206 209 209 209 206 206 206 209 203 206 206 206 209

This is the sketch I’m using (code here):

Screen Shot 2010 05 07 at 14.36.29

I’ve tried to rule out noise and other flakiness on the 5V PWR pin by adding capacitors and even a ferrite bead to filter out HF, but none of it seems to have any effect.

Big puzzle! Does anyone have any suggestions what else to try?

The good news is that everything works fine with batteries, so I can continue working on the code for my reflow grill controller. It needs an update because the NTC has a flaky wiring connection (can’t use solder there!) and because I want an accurate temperature readout without having to calibrate things.

More OOK decoders

In Software on Apr 19, 2010 at 00:01

O(o)k … so there are now several decoders for OOK transmissions: 3 for 433 MHz and 4 for 868 MHz:

Screen Shot 2010 04 15 at 10.36.43

Sample output:

Screen Shot 2010 04 14 at 23.20.21

The code is here now here. It has been set up as an Arduino sketch, but the decoder logic is not Arduino-specific, nor even ATmega-specific in fact. The sketch compiles to under 5 Kb, leaving plenty of room for future extensions.

All that is needed is to call the decoders with pulse widths in microseconds. They all run in parallel, but normally at most one will succeed for any given pattern of pulses. The actual decoding completion happens during the final long pulse (2000 µs or more, in most decoders).

Here is the rest of the sketch, which drives the decoder from pulses measured in an interrupt routine:

Screen Shot 2010 04 15 at 10.36.58

Note that there is something odd in this code: all the decoders are fed the same pulses! In real use, separate receivers will need to be connected for 433 Mhz and 868 Mhz, and then pulses fed to the appropriate decoders only. The reason I did it this way was for testing: I can simply replace the OOK receiver with whatever I’m currently trying out to see if it works – no reset needed.

So that’s it for now: 7 decoders, capable of decoding packets from several dozen different types of sensors and transmitters.

The data is reported as a set of hex nibbles, which need to be separated into the specific bit patterns for each type of packet. Also, checksums still need to be verified, to weed out any remaining false positives.

But that’s another topic, for another day.

Note – the RFM12B receiver cannot receive OOK signals. I hooked up extra hardware to make the above work.

Visonic sensors

In Software on Apr 18, 2010 at 00:01

Another set of sensors is made by Visonic. Here’s the door sensor:

Dsc 1341

It has three sources of triggers: a reed switch, normally kept closed with a magnet on the door or window, an extra set of ordinary contacts, and an internal switch which is released when the case is opened.

There are other sensors using the same protocol, such as a PIR motion detector and a “universal transmitter”.

The sensors send OOK data on the 868 MHz band, but it took me a while to figure it all out. The main reason being that I couldn’t find a preamble for these radio packets – apparently there is none! – instead, the tail of the packet is a good reference point, i.e. the 72 pulses preceding the long pause at the end can be reliably decoded.

Each bit is either a short-long pulse pair, or a long-short pulse pair. This can in fact be used to resync even before the end of the packet is reached, because short-short and long-long combinations indicate that we’re off sync.

The total packet has 72 pulse transitions, i.e. 36 bits of data. I add 4 extra zero bits to create a 5-byte result. Here is the main decoding logic:

Screen Shot 2010 04 14 at 16.28.07

Here is some sample output:

Screen Shot 2010 04 14 at 16.35.43

I’ll postpone decoding of the actual bit pattern to another day but note that you don’t really need to interpret all the bits: just look which patterns your sensor is sending out under various conditions, and you can match the incoming packets accordingly.

Improved OOK Scope

In Software on Apr 17, 2010 at 00:01

In yesterday’s post, I used the OOK Scope to find the distinctive pulse pattern emitted by a specific sensor to be able to write a decoder for it.

Keep in mind that this is a bit like looking for a needle in a haystack: there are often over a million pulses coming in within just minutes. That’s why I had to compare the “sensor-off” baseline with the “sensor-on” pattern. And even then, you never know for sure where pulses come from and especially whether they came together in quick succession, as expected for genuine RF packet data.

So I added some filtering: instead of showing all pulses, I only look for pulse sequences with pulse widths and pulse counts in a certain range, followed by a brief period of silence (i.e. a relatively long pulse).

I also added some configurability, i.e. whether to display using a logarithmic horizontal scale, whether to “decay” old data so new pulses are weighted more heavily in the counts.

One last very convenient feature added was a “peak detector”, i.e. trying to identify the most prominent peaks in the graph and reporting their microsecond values in a status line at the bottom (the first value is a pulse count).

I didn’t implement a GUI to adjust these values – I simply set them as needed in the code and restart JeeMon:

Screen Shot 2010 04 13 at 20.58.19

Here’s the result of running the OOK decoder with these settings and waiting for a packet from the Cresta sensor:

Screen Shot 2010 04 13 at 19.52.25

Bingo: very clean peaks, as well as the actual durations of the main pulses, i.e. 392 µs, 576 µs, 880 µs, and 1056 µs. As I’ve been able to determine from previous experiments, these are just two groups of pulses: 392/576 = 0 and 880/1056 = 1. The reason is probably skew – these receivers appear to have a completely different response to carrier-start and carrier-end transitions.

Here’s a plot when leaving the OOK Scope on and accumulating for one hour:

Screen Shot 2010 04 13 at 21.05.53

There’s a bit more garbage now, with additional noise and a few more peaks being “detected”. I’ve added code so that pressing ESC clears the counts and starts from scratch – this can help isolate a specific transmission.

This version of the OOK Scope was used to establish more accurate pulse widths for the Oregon and Cresta sensors, and that’s was led to the values used in those decoders. The latest source code of the OOK Scope has been checked in, replacing the previous version. It’s still very small: under 200 lines of Tcl/Tk code.

Note how much you can do with just an OOK receiver and software: it’s like a special-purpose scope. For these experiments it’s in fact better than a storage scope or a logic analyzer, because of the custom pulse filtering!

Cresta sensor

In Software on Apr 16, 2010 at 00:01

Another day, another sensor:

Dsc 1339

This is a Cresta unit (no serial number on it), with a simple outside temperature sensor (which has been outside for a some time). Here’s the OOK scope fingerprint:

Screen Shot 2010 04 12 at 13.50.25

Here’s the baseline, i.e. the background signal with the sensor switched off:

Screen Shot 2010 04 12 at 14.06.37

Some clear peaks, at values 100, 135, 175, and 195, roughly. These correspond to pulse intervals centered around 400 µs, 570 µs, 890 µs, 1080 µs, respectively.

My hunch is that the 400/570 and 890/1080 pairs are really just the same pulse, skewed by the size of the preceding pulse.

In this case, it turns out that the sensor sends 3 copies of the packet, with a 1..3 counter value inside. Seeing that counter in the raw bits indicates that this sensor is not using Manchester encoding, simply 1 = 1 and 2x 0 = 0:

Screen Shot 2010 04 13 at 20.11.30

I get better results with the sensor at least 1 meter away from the receiver – a very strong signal probably adds extra spikes or shifts pulses too far apart.

Time to write a decoder for this thing:

Screen Shot 2010 04 13 at 20.15.06

With the base unit turned on to see what the values being reported are, I was again able to determine the basic details of the packet layout. Each 8-bit byte is followed by a 9-th parity bit. So this hex data isn’t as easy to read:

Screen Shot 2010 04 13 at 20.18.56

But the expected temperature values are in there, and the 1..3 channel selection is as well. Again, I’ll save the checksum verification and the post-processing in JeeMon for another day.

Onwards!

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!

Not quite a compass, yet

In Software on Mar 25, 2010 at 00:01

This is an attempt to read out the magnetometer / compass of the Heading Board introduced yesterday.

The demo sketch has been extended, and is still deceptively trivial:

Screen shot 2010-03-23 at 17.30.23.png

The meat of the code is in the HeadingPort class implementation in the Ports.cpp source file.

Trouble is – it doesn’t work :(

Sample run #1:

Screen shot 2010-03-23 at 16.28.33.png

Sample run #2, using another sensor:

Screen shot 2010-03-23 at 16.29.04.png

The barometer readings are more or less consistent, but probably both wrong. The local weather station and my Pressure Plug in the ookRelay both report that the current air pressure is currently around 1017 hPa.

As for the temperature readings, well … the temperature sensor in the Pressure Plug reports 20.9°C, and it’s about one meter away, also on my desk.

What’s worse is that the magnetometer readings are missing, and both come out as zero.

Trying again with a different setup, I get this third sample output:

Screen shot 2010-03-23 at 17.25.11.png

The values don’t change when I rotate the sensor. I can’t make anything of this right now, best guess is that the I2C bus transactions are perhaps flakey. Not impossible – this is a pretty simplistic software-based bit-banging I2C implementation after all, which doesn’t support things like clock stretching. I could try it out on a real hardware I2C bus via the Plug Shield. Another day…

The code has been added to the Ports library, as usual.

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!

Gravity Plug

In Hardware, Software on Mar 22, 2010 at 00:01

The plug story continues…

The Gravity Plug contains a 3-axis accelerometer with 2..8g settable range:

DSC_1262.jpg

As before, a new GravityPlug class has been added to the Ports library, along with a “gravity_demo” sketch to illustrate its use:

Screen shot 2010-03-19 at 13.08.33.png

Sample output:

Screen shot 2010-03-19 at 13.26.31.png

Values are X, Y, and Z, in that order.

I’m not sure about the high bit readout with the current code, maybe this needs some tweaking to get the ranges right, but you can see the effect of moving the plug around a bit.

The Y axis wraparound may be due to the chip not being completely flat on the board. This is a minute chip, which can’t be soldered by hand because the pads are too small and on the bottom side of the chip. I applied solder paste manually and then used the reflow grill – but even that is tricky, it’s very difficult to get an even-yet-small amount of paste on there! A solder paste stencil will no doubt solve this.

Lux Plug

In Hardware, Software on Mar 21, 2010 at 00:01

Here’s a second simple plug which works:

DSC_1263.jpg

(the silkscreen markings are incorrect, this plug responds to I2C addresses 0x29, 0x39, or 0x49)

The Lux Plug measures incident light intensity which can be converted to a 16-bit Lux value in the range 1 .. 65535. A 16x multiplier can be used to increase the dynamic range to 20 bits.

A class named – surprise! – “LuxPlug” has been added to the Ports library, as well as a “lux_demo” sketch:

Screen shot 2010-03-19 at 01.31.30.png

Sample output:

Screen shot 2010-03-19 at 01.29.01.png

The two first values are the raw readings from two internal sensors. The TAOS datasheet explains how to derive the Lux value from them. This calculation is included as the “calcLux” member in the class (to be called after getData() has obtained a reading).

Onwards!

New board summary

In Hardware on Mar 7, 2010 at 00:01

Here is a summary of the boards which are currently being, eh … prepared? etched? sprayed? drilled?

First of all, a new JeeNode USB with improved voltage regulator setup:

Screen shot 2010-03-07 at 00.53.02.png

The Dimmer Plug contains a 16-channel LED dimmer with independent PWM brightness control, using I2C:

Screen shot 2010-03-07 at 00.53.25.png

The Lux Plug contains a sensitive light meter with high dynamic range, using I2C:

Screen shot 2010-03-07 at 00.53.36.png

The Gravity Plug contains a 3-axis accelerometer with 2..8G range, using I2C:

Screen shot 2010-03-07 at 00.53.45.png

The Proximity Plug connects up to 8 contacts as capacitive sensing switches, using I2C:

Screen shot 2010-03-07 at 00.53.58.png

The Input Plug supports 16 inputs, as either analog or digital inputs (not I2C):

Screen shot 2010-03-07 at 00.54.09.png

And three more boards. One of them is a mystery sensor – I’ve masked out its name for now :)

Screen shot 2010-03-07 at 00.56.00.png

The other two boards are experimental boards of a different kind – I’ll describe ‘em when they work.

I’ve started setting up documentation pages for these new PCBs, but so far that’s just the EAGLE files. Will add more info in the coming week – with luck they’ll be back here for testing within the next 10 days.

I guess the best tactic for me now, is to just forget about this and work on some other stuff for a while. Drat.

Patience, patience, patience. I hope it pays off!

Voltmeter with GUI

In Software on Feb 27, 2010 at 00:01

Let’s make a 5-digit voltmeter with a JeeNode, an Analog plug, and JeeMon. But instead of a readout on an LCD screen, I’m going to show the results on the desktop. To start with that last part, here’s my little display on a Mac:

Screen shot 2010-02-23 at 20.23.25.png

You’re looking at my feeble attempt to create a good-looking / souped-up GUI, btw :)

Anyway. Here’s the sketch I’m running on the JeeNode, with an Analog plug inserted into port 3:

Screen shot 2010-02-23 at 11.01.16.png

Trivial stuff. It sends out lines with “VOLT <value>” readings twice per second.

The important part is that this sketch starts up with “[analogPlug]” as greeting. To hook up to this sketch, all we need to do is create a directory called “analogPlug”, with a file called “host.tcl” in it.

This new “analogPlug” directory is a sub-directory of “JeeMon-sketches”. This directory, in turn, has been registered as being used for sketches – with this command in my main application code:

Screen shot 2010-02-23 at 12.21.51.png

Back to the “JeeMon-sketches/analogPlug/host.tcl” file. Here’s its contents:

Screen shot 2010-02-23 at 11.40.34.png

That’s the whole kaboodle.

Now, whenever I plug in a JeeNode running the above “analogPlug.pde” sketch, a window pops up showing readings in real-time. When I unplug the JeeNode, the window is closed again. It’s all automatic, as long as JeeMon is kept running.

This mechanism is not limited to JeeNodes or Analog plugs, of course.

New Proximity Plug

In Hardware on Feb 15, 2010 at 00:01

Yet another plug! This time it’s a proximity capacitive sensor based on the MPR084:

Screen shot 2010-02-14 at 22.01.08.png

This one has 8 inputs which can be connected to various surfaces to create capacitive touch sensors. There’s also a pin for a piezo sound unit to produce key clicks.

Slightly more elaborate schematic this time, with an extra 8-resistor array for pull-up:

Screen shot 2010-02-14 at 12.05.27.png

Yet again: connected via I2C, and supports no more than 3.6V as power source. There’s a solder jumper to choose between two I2C addresses, so you can use two of these for a total of 16 inputs on one port (or Plug Shield).

Haven’t tried this chip out yet, but it will be fun to see what it can do – once I get some prototype boards ready.

New Gravity Plug

In Hardware on Feb 14, 2010 at 00:01

Another plug coming up – based on the BMA020? 3-axis accelerometer:

Screen shot 2010-02-12 at 23.07.28.png

Again an awfully tiny chip, with even smaller pads. This chip has a programmable ±2g/4g/8g range with 10 bit resolution. As with yesterday’s plug, this chip communicates over I2C and supports up to 3.6V.

The schematic is obviously very simple again:

Screen shot 2010-02-12 at 23.07.59.png

The Gravity Plug will also work with an Arduino, through the Plug Shield.

It’ll take at least a few weeks before I can test these new plugs and make them available.

Onwards!

New Lux Plug

In Hardware on Feb 13, 2010 at 00:01

There’s a new plug in the works, with a really neat TSL2561 light sensor:

Screen shot 2010-02-12 at 21.06.49.png

The chip is even smaller than what I’ve been working with until now. The nice thing about the TSL2561 is that it has six orders of magnitude dynamic range and that it’s interfaced via I2C.

The JeePlug port headers are in fact perfect for sensor chips like these, which often only tolerate up to 3.6V:

Screen shot 2010-02-12 at 21.08.28.png

The Lux Plug will also work with an Arduino, through the Plug Shield.

Stay tuned. There’s more coming…

Room Board assembly

In Hardware on Feb 2, 2010 at 00:01

As announced recently, I’ve now added a full kit for the Room Board in the shop, containing:

  • The room board PCB.
  • SHT11 temperature + humidity sensor.
  • An LDR light sensor.
  • The ELV PIR motion sensor.
  • Two 6-pin male headers.

Here is the kit (oops, forgot the two 6-pin headers):

DSC_0980.jpg

From top left to bottom right: PIR lens, PIR sensor, 3-pin header, SHT11, LDR, Room Board PCB, pre-assembled PIR sensor board.

The hardest part to solder is the SHT11 sensor. It has 10 gold pads on the side, of which only 8 are connected. Make sure you place the sensor in the right orientation. With the text on the pcb readable, the round part is pointing down:

DSC_0981.jpg

Next, solder in the LDR light sensor. Be sure to place it in the LDR1 position:

DSC_0982.jpg

The wires of the LDR may be a bit more difficult to solder than ordinary components, so be sure to use enough flux:

DSC_0983.jpg

Next, we need to prepare the ELV PIR sensor board – the board itse;f already has all the SMD’s soldered on, just the PIR sensor itself.

Careful – do NOT touch the surface of the PIR sensor, as any traces of oil will reduce its sensitivity:

DSC_0984.jpg

The sensor has to be pushed through the bottom side of the lens holder, into the board – from the non-component side:

DSC_0985.jpg

Solder the three wires and snip them off. Don’t use too much solder or you’ll risk shorting out the pads with the nearby components:

DSC_0986.jpg

Then turn the board around and click the fresnel lens onto the base (it has three different-sized notches):

DSC_0987.jpg

Next, we need to connect the boards together:

DSC_0988.jpg

The pins go through the room board and should be snipped off once soldered:

DSC_0990.jpg

Almost there – the last step is to solder the two 6-pin male headers onto the room board. To hold them in the right position, I just push them into a JeeNode:

DSC_0991.jpg

… then place the room board on top and solder both headers, all 12 pins. Leave the 8 holes on the side of the PCB free (these are for another type of PIR sensor):

DSC_0992.jpg

That’s it – you’re done!

For more info on uploading the “rooms.pde” sketch firmware to the JeeNode, go back to the docs page.

Update – for the Room Board v2, see this weblog post.

Room node – last

In Hardware on Jan 31, 2010 at 00:01

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

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

DSC_0993.jpg

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

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

DSC_0994.jpg

Here’s how everything sits in the completed unit:

DSC_0995.jpg

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

Enough of all this mechanical tinkering!

Room node mount

In Hardware on Jan 30, 2010 at 00:01

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

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

Screen shot 2010-01-29 at 20.48.04.png

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

DSC_0977.jpg

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

DSC_0978.jpg

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

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

Temperature plots

In Software on Jan 22, 2010 at 00:01

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

Screen shot 2010-01-22 at 12.03.23.png

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

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

Screen shot 2010-01-20 at 01.52.42.png

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

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

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 :)

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.

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.

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.

Updated Thermo Plug

In Hardware on Dec 3, 2009 at 00:01

The Thermo Plug prototype has been updated to the final version:

DSC_0818.jpg

This plug supports either a thermocouple, an NTC, or a 1-wire temp sensor on the AIO line, and either a buzzer or a relay on the DIO line. It does not use I2C.

The connections of the AD597 thermocouple readout chip are now correct, and there’s a new 4.7 kΩ pull-up resistor option when using the 1-wire interface.

I’m still looking for a good way to attach the K-type thermocouple (soldering is not a good option with those metals), and am considering adding this plug as kit with AD597, thermocouple, buzzer, and the rest of the components to the shop. This is the combination I’m using in my reflow oven / grill controller. The bare pcb is already available.

Energy tracking with Cost Control

In Hardware on Nov 14, 2009 at 00:01

The ELV Cost Control is a set with two power measurement units and a display:

87747_F01_GeCostControl.jpg

Every 5 seconds the base units transmit their readings over 868 MHz, each with a unique 4-digit ID. The display shows actual and aggregated results for up to 5 units. You have to press a button to get an update, i.e. the receiver is only activated on request – for about 6 seconds.

Setup is trivial. Tracking current power consumption, peak power consumption, projected monthly & yearly cost, and hours on vs. total is extremely straightforward.

This is a very convenient setup because you can put the sensor in the outlet, way down deep behind everything if needed, and then take individual appliances out to see what effect each one has on the total consumption.

I found out that my 5-port Ethernet hub draws 3W (of which 2W in the adapter), and an old monitor I’m only using occasionally uses 4W (both asleep and “off”).

Our TV + amplifier + speakers + satellite receiver is drawing 6W when idle. Most of this is the Mac Mini (used as TV), due to an energy saver which cuts power to all other appliances when the Mac sleeps.

At €12.95 per outlet, this is the cheapest good-working solution I’ve found so far for tracking power use at individual outlets. I’m thinking of getting several more of these for the refrigerator, washing machine, and other intermittent power consumers.

Does anyone know whether the Cost Control wireless protocol has been documented?

Meet the Pressure Plug

In Hardware on Nov 12, 2009 at 00:01

Here is a little interface board for the BMP085 atmospheric pressure sensor – I2C based and daisy-chainable as usual:

DSC_0735.jpg

This sensor is a bit tricky to solder by hand, as you can see in an older post.

The sensor is extremely sensitive and measures both pressure and temperature. The “bmp085demo” sketch in the Ports library hasn’t changed:

Screen shot 2009-11-05 at 15.16.54.png

Here’s some sample output:

Screen shot 2009-11-05 at 15.16.32.png

The temperature is not 27°C around here ;) – this board is simply still cooling down from the reflow!

This new Pressure Plug will replace the hand-soldered one in my OOK relay, of course.

Room Board update

In Hardware on Oct 31, 2009 at 00:01

Here is the latest version of the Room Board, just in:

DSC_0711.jpg

It works for all combinations of SHT11/DS18B20, PIR/EPIR, and LDR. Here’s SHT11 + PIR + LDR:

DSC_0712.jpg

And here’s a setup with DS18B20 + EPIR + LDR:

DSC_0716.jpg

Both can be used with the latest version of the rooms sketch.

But… if look closely at that second board, you’ll see that I still got it wrong!

The DS18B20 temperature sensor is labeled the wrong way around, and must be mounted as follows:

DSC_0717.jpg

Drat – same mistake as last time!

And now I’ve also figured out how this happened. Here is the pinout shown on the Dallas Semiconductor / Maxim data sheet:

Screen shot 2009-10-30 at 14.43.29.png

B o t t o m  view. Doh!

I’m going to declare victory anyway, and call these boards final. Even though this issue will have to be documented and spelled out everywhere to prevent people from falling into this trap. I have 100 room boards, and I simply don’t want to trash them and wait another 3 weeks. Most people will probably use the SHT11 sensor anyway, where this issue is irrelevant.

Available in the shop now. Foul-ups happen, so be it. End of story.

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…

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?

Thermo Plug update

In Hardware on Oct 17, 2009 at 00:01

The Thermo Plug works, basically. Here’s the configuration with an NTC sensor and a buzzer:

DSC_0661.jpg

Sample output, reading out the ADC periodically:

Picture 8.png

As the temperature goes up, the resistance and the ADC readings both go down. The actual conversion to the corresponding temperature will require a calibration and either a lookup table or a polynomial fit, as described in a previous post.

Here is the board layout:

Picture 8.png

The buzzer can be replaced by a relay plus clamping diode. Since it’s driven via an NPN transistor, there will be enough current to drive several types of relays. The buzzer / relay are hooked up to PWR, not +3V.

Another configuration for this board is with the AD597 thermocouple sensor chip. Unfortunately, I forgot to add a wire between pins 1 and 3, so it has to be added by hand – as you can see here:

DSC_0662.jpg

Another view, with the attached K-type thermocouple:

DSC_0663.jpg

The thermocouple responds to temperature change much faster than an NTC – and it’s already calibrated (second number is °C):

Picture 9.png

When I touched the sensor with my hands, it took less than half a second to detect a 5° increase!

Here is the sketch I used for the above demo:

Picture 10.png

Ok, time to tweak the Thermo Plug and fix that missing wire in the next pcb run.

Room Board update

In Hardware on Oct 14, 2009 at 00:01

I finally figured out what was going on with the new Room Board.

The bad news: there are three errors on the board when using it with a 1-wire temp sensor and the EPIR motion detector board.

The good news: each problem is easy to work around.

Problem #1: the 1-wire DS18B20 outline is reversed:

DSC_0656.jpg

So much for taking an EAGLE library component from the web and not checking it…

Problem #2: the 1-wire sensor really needs a 4.7 kΩ resistor pull-up:

DSC_0657.jpg

The solution for both problems is to solder the sensor on the other way, and to add a resistor between two of the pins, as shown above.

Problem #3: a pull-up resistor is missing (again!) – it turns out to be essential to get the EPIR in the proper serial mode on power-up:

DSC_0660.jpg

This can’t be done by enabling a pull-up in the ATmega as I originally thought, because that’s too late. The EPIR really checks for this on power-up. The solution is (again!) to manually add a 100 kΩ resistor between pins 2 and 4 of the EPIR connector.

Phew. So now all configurations work. Sort of… :)

I’ve added the Room Board to the shop, but as PCB only because there are several configurations possible and because some of these sensors and boards are relatively expensive (also for me to keep in stock).

With the caveat that I only have a handful available right now, and that these are “imperfect” prototype boards. With SHT11/SHT15 sensors and simple 3-pin PIRs, these prototypes will work fine. But for 1-wire and/or EPIR use, you’ll need to patch things as described above.

I’m going to create a new revision with all these issues fixed, of course. But it will take a few weeks to have new boards made.

The “Rooms” sketch for these boards has been updated to work with all configurations. It needs the NewSoftSerial library if the EPIR is used, and the OneWire library if the DS18B20 is used.

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:

DSC_0573.jpg

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

DSC_0574.jpg

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!

Analog Plug

In AVR, Hardware, Software on Sep 30, 2009 at 00:01

The second plug panel has arrived. I’ll document my test results in the coming days.

First, the Analog Plug – an 8-channel 12-bit ADC connected via I2C:

DSC_0545.jpg

It’s based on the ADS7828 chip. Here’s a demo sketch to read it out:

Picture 3.png

I hooked it up using various gimmicks lying around here – this ties a trim pot to channel 4, with range 0 .. 3.3V on the wiper:

DSC_0544.jpg

As you can see, the Breadboard Connector can be used to hook up to 8 of the 12 pins of this plug.

Here’s some sample output:

Picture 1.png

I slowly turned the wiper as you can see. It stops at 4095 counts, which represents the 2.5V of its internal reference. Appears to work fine in this test setup at the maximum I2C rate, somewhere over 1 MHz. The readings didn’t change by more than one count when touching various parts of the circuit, so as first impression it looks like it’s pretty stable.

This plug has two solder jumpers, to configure its I2C address to 0x48 .. 0x4B, which in hindsight is a bit overkill. Only minor nit is that I mis-labeled the A0 jumper – as shown in the picture, the address ends up being 0x49 i.s.o. 0x48. Oh well, a small silkscreen fix will resolve that later.

So there you have it – eight 3.5 digit voltmeters on one tiny blue-and-gold plug :)

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…

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!

Thermo Plug design

In Hardware on Aug 28, 2009 at 00:01

The plug rage continues … this is a plug to measure temperature with either a thermocouple or an NTC resistor:

Picture 1.png

The chip is one of the AD594 .. AD597 series for use with J / K type thermocouples. With an NTC, the chip and 2 caps should be omitted, with a pull-up resistor added instead.

The other I/O pin is used for a piezo buzzer. It is driven via an NPN transistor with the positive lead connected to PWR to increase the volume. An alternate use for this pin + transistor is to control a relay or an opto-isolated triac.

Depending on the parts used, this might make a nice plug for a JeeNode-powered reflow controller. Or a temperature-controlled aquarium / soldering iron / 3D extruder / whatever. Or up to four overheating sensors, when used with multiple ports.

Room Plug design

In Hardware on Aug 26, 2009 at 00:01

I’ve started work on a plug for the room sensor nodes, since it’s too tedious to wire up lots of them by hand.

Meet the 20x21mm “Room Plug”:

Picture 1.png

It has room for an SHT11/SHT15 type temperature / humidity sensor, an LDR as light sensor, and one of two types of PIR motion sensor. There are two positions for the LDR, depending on which type of motion sensor is being used.

In normal use the plug will be fully populated and placed as a bridge over ports 1 + 4 (or 2 + 3) of a JeeNode or JeeLink, but it’s also possible to only mount one or two sensors and – depending on which sensors – to plug the board into a single port, pointing upwards. Or even to use it as breakout board for a standard Arduino, or any other setup you like for that matter.

I’m going to look into a few more plug ideas before having prototypes made, to reduce cost a bit since these plugs are so tiny. Many sensors are not really worth a custom-made board, since the generic JeePlug will let you hook up most of them yourself. But having said that… if you’ve got suggestions for a hookup which would be really cool to have as ready-made plugs, let me know!

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.

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.

Reflow temperature

In Hardware, Software on Jul 12, 2009 at 00:01

For my upcoming reflow experiments, I’d like to use a JeeNode to track the temperature and perhaps also control the grill. As the saying goes… when you have a hammer JeeNode, everything looks like a nail sketch.

So I hooked up a 10 KΩ NTC resistor rated up to 300°C as voltage divider with a 1 KΩ resistor pull-up. Bought a cheap and probably not-so-accurate multi-meter with thermocouple-based temperature readout. And then the fun starts – turned my grill on and watched it heat up and then cool down, while jotting down the “readings” from this “experiment”. I felt like a high-school kid in physics class again :)

The results:

Picture 1.png

Not bad. The readout is a bit coarse at the higher end, but I think it’s accurate enough for reflow soldering in the 170° .. 240° range. The grill goes up to 260°C from what I can tell.

But I didn’t want a lookup table, so I went looking for a polynomial least-squares regression fitter on the web and found this one. Great: copy and paste the 18 heat-up readings, then try out a few polynomes – turns out that a 7th degree polynome fits well, matching the measured data within a few tenths of a degree.

And then I found an even better site called ZunZun – it lets you fit polynomes and graph the results and generate the C++ code. No need to copy lots of coefficients!

Here’s what I ended up with, using a “Lowest sum of orthogonal distance (ODR)” fit:

Picture 1.png

Corresponding C++ code:

Picture 4.png

To be able to configure this thing, it would be nice to be able to enter degrees. That’s easy to do by also fitting the inverse function:

Picture 7.png

Corresponding C++ code for the inverse:

Picture 6.png

Great. Onwards!

Ligthy power save

In AVR, Software on Jul 5, 2009 at 00:01

Getting the power consumption down of yesterday’s “Lighty” example turns out to be quite a challenge.

One thing to do is to separate out the logic for enabling the different sensors, and extending it to also support disabling all of them:

Picture 3.png

Powering down completely works best when all internal peripherals are also turned off, as implemented in the following code:

Picture 4.png

Now the trick is to enable some interrupt source to take us out of this deep sleep phase again. This could be the ATmega watchdog, but the radio watchdog uses even less power, so here’s how to stay off for about 4 seconds:

Picture 5.png

So far so good. This disables all power consuming sensors and internal circuits, preps the radio to wake us up in 4 seconds, powers off, and then reverses the whole process.

Bug there is a bug in all this – somewhere… From some earlier experiments, I would have expected to see a power draw of a few microAmps with this code. But for some reason, it never drops below 2.7 mA, i.e. still “burning” 1/10th of full power!

I haven’t been able to figure out yet where these milliamps are going :(

For the sake of argument, let’s assume this works properly. Then the next problem will come up, which is that measuring and sending packets every 4 seconds drains more power than I’d like to. It takes several milliseconds to measure all readings and send out a packet. But who needs readings every 4 seconds?

So the solution to this is to just sleep a bit longer, using the 4-sec wakeups to quickly read-out some sensors, and calculate their averages. Here’s is the final loop of the power-saving “LightySave” sketch:

Picture 8.png

This will integrate readings for 75x 4 seconds, i.e. 5 minutes, and then send out a single packet. Note how the power-hungry radio module is only enabled at the very last moment. All we have to do is make sure it’s ready to send, then send one packet, then wait again until the send is complete.

Then the loop restarts, sleeping in low-power mode, etc.

Only issue is to find out where the 2.6 mA are going! I’ll try to figure this out, and will post here once fixed …

Lighty

In AVR, Software on Jul 4, 2009 at 00:01

Let’s call yesterday’s mystery JeeNode “Lighty” from now on. As promised, here is the first sketch:

Picture 3.png

LightySerial reads out several sensor values each second and dumps the results to the serial port. Plain and simple – using the Ports library for most pins and Arduino’s analogRead() for reading out voltage levels on A4 and A5.

Sample output:

Picture 4.png

FYI, all the Lighty sketches are available for download as a ZIP file.

Now let’s turn that into a wireless version using two JeeNodes. The first step is to separate the measurement and reporting sides of things.

Here is the main code of LightyTransmit, causing it to send out its readings once a second:

Picture 8.png

It puts all values into a structure defined as follows:

Picture 6.png

… and then sends that off to the broadcast address, i.e. whoever is listening. No acknowledgements are used. If the packet arrives, great, if not then the next one will.

The receiver then takes it from there, here is the entire LightyReceive sketch:

Picture 7.png

Note that the Ports library is not needed here since the receiving JeeNode does not use ports, it merely picks up packets and reports them on the serial line.

That’s basically it. Each of these sketches compiles to some 3 .. 4 Kb code.

We’ve got ourselves a Wireless Sensor Network!

LightyTransmit uses about 24 mA. Tomorrow, I’ll go into reducing the power drain, because Lighty’s tiny 20 mAh LiPo battery won’t even last an hour this way.

Mystery JeeNode

In AVR, Hardware on Jul 3, 2009 at 00:01

Some more pictures from yesterday’s puzzle…

3681641100_900fdf0f6e_o

Added a second LDR on the left and a DS18B20 1-wire temp sensor. A 4.5V @ 35mA solar cell has also been soldered in.

The sensor is a TSL230R light sensor, as Milarepa correctly commented:

3679117790_f89f0caa7d_o

It has one frequency pulse output, with two other port pins used to control sensitivity (1x/100x) and frequency divider (2x/50x). The fourth I/O pin is used as power supply for the chip, so that it can be turned off completely in sleep mode.

Here’s the whole assembly from the side:

3681641152_3a6d49194e_o

And here the complete JeeNode (using a different solar panel which turned out to be too weak):

3679151344_f871517b7c_o

So what does it do? And what is it for?

Well, two things really – but I’ll be the first to admit that this isn’t truly general purpose and unlikely to be very meaningful for anyone else.

The first use is to help me take better pictures. The photos on this weblog are all taken using nothing but a white sheet of paper and plain old-fashioned daylight. Benefits are that it’s free and abundant, it needs no space for a light-box setup, and it tends to produce beautiful images.

The problem which you may have seen on this weblog, is that daylight ≠ daylight. Sometimes it’s too dark outside, and sometimes the light is too harsh. Worse still, many of the photos end up with a blueish tint. I’m having a hard time predicting this, so it seemed like a nice idea to just throw a bunch of light sensors together and try to correlate this to picture quality over a few weeks time.

The other purpose of this unit is to act as test-bed for long-term solar-powered use. That means getting the power drain down to very low levels of course. But I also added the ability to read out the voltage of the solar cell and of the battery, as well as temperature (solar cells are sensitive to that). And LDRs facing opposite directions, to try and detect sun vs. cloud cover weather info.

This seemed like an excellent project for JeeNodes and JeePlugs. Once it’s working well enough – auto-ranging the light sensitivity and such – I intend to put this up on the roof and just let it send out packets every 5 minutes or so, day and night. This will make an excellent yet non-critical test setup as well as allow me to track solar intensity over the entire year. Think solar panels…

Tomorrow I’ll post several sketches: one showing how to read out everything and report it over the serial FTDI connection, then two more to show how to turn this into a send/receive solution with two JeeNodes, and the last one showing how to get power consumption down.

Stay tuned!

Reflow experimentation

In Hardware on Jun 15, 2009 at 00:01

Got this little skillet/grill thing recently:

Heating plate

Quite a convenient size (and it can be stored upright) – the usable area is around 25 cm diagonal. It’s also relatively weak at 700 Watt, but since it’s so small it still easily reaches the solder melting point within a few minutes (with the lid closed).

I’ll be experimenting with this thing for SMD reflow soldering. Will need to measure and control the temperature (an NTC resistor rated for 300° no doubt, but I don’t know which type yet).

If the heat collection in these plates makes the thing too slow to control properly, I could take the plates out and use some sort of grid instead:

Heating plate

Note the heat sensor in the middle, triggering a thermostatic switch.

Ideally – of course – I’d want to control this thing with a JeeNode, but I’m not willing to spend very much time on that right now. We’ll see. First thing will be to measure the temperature ramp-up/-down behavior of this thing, with the lid open and closed.

If this works, it’s a pretty good deal for €19.95 !

Bad things happen

In Hardware on Jun 13, 2009 at 00:01

Looks like one of the sensors broke:

Broken sensor

That’s an IMU (Inertial Measurement Unit) with a dual accelerometer and a gyroscope. The gyro is the “big” one on the right. It senses rotation around the Z axis perpendicular to the board. The accelerometers are working fine, but the gyro appears to be toast. No matter what I try, it produces a noisy but fixed analog voltage. Connecting either of the self-test pins doesn’t doing anything.

Ouch, the gyro is also the most expensive part (in the €25..50 range). And this was a rather nice and sensitive one. Oh, well…

(that’s an Arduino with a battery pack by LiquidWare underneath, btw – so I can move this thing around and hook up the scope without having to attach power)

Measuring the AC line frequency

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

There is an interesting site in the UK called Dynamic Demand. The idea is to let the 50 Hz power-line frequency vary slightly to indicate the current load of the entire grid. Simple line-monitors can then track this locally and respond by voluntarily shutting down some power consumers (i.e. turning off freezers, A/C units, or electric heaters for a little while). With a bit of collaboration, the grid would then presumably recover as the load eases off – and overcome these demand peaks. I love the idea, it’s so beautifully simple.

The Dynamic Demand site also has a page showing the current frequency online, here’s a snapshot:

Picture 2.png

I don’t think this mechanism is being used – or even considered? – in the Netherlands but I couldn’t resist setting up a JeeNode to monitor the frequency myself. The sketch:

Picture 3.png

What it does is measure elapsed microseconds between 100 transitions of its input signal against the 1.1V bandgap reference voltage. That’s 50 ups and 50 downs, which should take 1 second.

The AIO pin of port 1 is connected to a rectified but unregulated AC voltage, coming from a 17 VAC power brick through a diode plus 1:10 voltage divider. The signal looks as follows:

ac.png

And here’s some sample output:

Picture 1.png

Note that for stable and repeatable results, the JeeNode will need to be fitted with a crystal as clock.

The accumulation over 100 transitions is a simple way to average all the pulse durations. Most of the code then tries to present a nice result, with sufficient accuracy to display minor variations.

Nice and tidy.

Gyro sensor

In AVR, Hardware, Software on May 25, 2009 at 00:01

Here’s the LISY300AL gyro sensor, mounted on a Sparkfun breakout board:

Gyro sensor

The sensor is not extremely sensitive, but works at 3.3 V. It has a single analog output, so readout is trivial:

Picture 1.png

Sample output:

Picture 2.png

The readout changes as this setup is rotated around the horizontal plane. Looks like the self-test (pin 5) to ground can be omitted, btw.

One (tiny!) step closer to a self-balancing bot…

Update – the Segwii website is a fantastic resource on how to accomplish self-balancing in a fairly similar setup.

Servo fun

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

Here’s some fun with a servo:

Servo fun

A slider drives the two servos in opposite directions, so you can make this thing turn on the spot.

Here’s the sketch:

Picture 1.png

Had to use SoftwareServo instead of the Servo library which comes with Arduino IDE 0015 – which didn’t work for me.

Turns out that only pulses from 1.4 to 1.6 msec actually have any effect on the speed of the servos, the rest of the 1.0 .. 2.0 msec range just makes them run at full speed. These ara Parallax (Futaba) Continuous Rotation Servos.

Note that the servos are driven from the PWR line, i.e. the full 5V – but the servo pulses are 3.3V, like the rest of the JeeNode.

It’d be nice to use a Wii Nunchuk controller as input. Even more fun would be an accelerometer / gyro combo to turn this thing into a self-balancing bot …

JeeNode Pulse revisited

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

The JeeNode Pulse hasn’t fully materialized yet – it’s the configuration I’d like to use around the house. Here’s a new configuration:

Pulse revisited

PIR and LDR on port 1, BMP085 on port 2, and SHT11 on port 3. There’s obviously no point in having a BMP085 sensor in more than one node, but for now it’s easy to leave it in for testing.

Different PIR sensor (from ELV). That sensor draws 30..40 µA – this matters for battery-operated use because it’ll be permanently on.

Here’s the main part of a first sketch, using the new power-down logic:

Picture 3.png

The code compiles to around 9 Kb. This includes floating point calculations in the SHT11 driver and the serial port reporting, both of which could be jettisoned later.

Sample output:

Picture 4.png

The values are:

  • temperature x10, from BMP085
  • barometric pressure x100, from BMP085
  • relative humidity, from SHT11
  • temperature, from SHT11
  • motion detect, from PIR (1 = no motion)
  • light level, from LDR (high means dark)
  • the number of milliseconds spent measuring

That last value is way too high for battery use – this code is spending 0.316 seconds collecting sensor data… in high power mode!

Breaking down the time spent, it looks like the BMP085 takes 2x 7 ms, and the SHT11 takes 2x 70 ms. The odd thing is that the SHT11 seems to take 300 ms when taking both temperature and humidity readings.

The good news is that the power-down current consumption of this setup is around 40 µA.

What needs to be done, is to spend the waiting time in these sensor read-out periods in power-down mode as well. The BMP085 driver already supports low-power readout by splitting the start and end parts of the driver, so that the waiting time can be handled in the calling loop. The SHT11 driver will needs to be adjusted to allow a similar approach.

With a bit of luck, only a millisecond or two will have to be spent in high-power (10 mA, haha!) mode. Then perhaps 2..3 milliseconds with the RFM12B radio active, and that should be it.

With a 15..60 second reporting period, the node would stay almost entirely in power-down mode. An average power consumption of under 100 µA total should be feasible – giving well over a year of service on 3 standard AAA batteries.

But that’s not all. To effectively use the PIR module, the code must be set up to handle motion-detect triggers at any time, also in power down mode. One approach would be to wake up (i.e. use a pin change interrupt), note the change and power back down. A refinement would be to “preempt” and start transmitting right away when motion is first detected – and then re-schedule future transmissions so the average reporting period remains the same. This makes the central JeeHub aware instantly of motion detected by the various nodes.

Power consumption

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

This contraption:

Measuring power draw

… when connected as follows:

Measuring power draw

… makes it easy to measure the supply current, with a BMP085 pressure sensor hooked up in this case:

Measuring power draw

Just under 10 milliamps, as you can see. That’s just the JeeNode running the BMP085 demo at 16 MHz, sending a new reading over the serial port every second. The RF12 module has not been turned on.

If the JeeNode is to be used for a WSN, then it will have to get its power consumption down. Way down, in fact…

Yet another PIR

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

Found yet another passive infrared module for around €10, by ELV:

PIR by ELV

Hooked up to port 1 of a JeeNode, and shown here with the USB “BUB” interface by Modern Device. Note that this uses a JeeNode with 6-pin port connectors, since the PIR module requires at least 5V. The output is open-collector, and therefore compatible with the 3.3V levels expected by the JeeNode (using the internal pull-up resistor).

Sample output, from a slightly adjusted version of the “pir_demo” example sketch which is in the Ports library:

Picture 1.png

Range and sensitivity seem to be ok. The signal is more jittery that with the ePIR and Parallax modules, it will have to be de-bounced it a bit in real-world use.

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.

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:

E0205010000000000001B
E0205020000000000001A
E0205030000000000001A
E0205040100010001001A

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:

F1000001204
F1000011217
F10000212F9
F1000031203

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.

Mounting the JeeNode Pulse

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

Here’s another experiment in creating a practical Pulse setup, using a fully populated JeeNode:

JeeNode Pulse mounting

The PWR/I2C and ISP/SPI connectors use wire-wrap pins mounted the other way:

JeeNode Pulse mounting

Here are four “peripheral boards”, ready to add all sorts of sensors:

JeeNode Pulse mounting

They look a bit like feet, ha ha:

JeeNode Pulse mounting

The nice bit is that since each of the boards uses one port and all ports are identical, it is very easy to use various sensor configurations.

Here’s the “carrier board”, mounted on part of the enclosure:

JeeNode Pulse mounting

All the pieces fit together nicely, of course:

JeeNode Pulse mounting

And lastly, the protective shell:

JeeNode Pulse mounting

Case closed… heh :)

Switching AC

In Hardware on Apr 16, 2009 at 00:01

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

Bi-stable relay

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

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

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

Picture 3.png

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

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

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

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.

JeeNode Pulse deployment

In Hardware on Apr 11, 2009 at 00:01

This is my plan for sensors in each room in the house:

pulse-deployment1.png

This setup uses a power supply, which is a bit inconvenient. But the ePIR motion sensor draws too much power to run long enough off a battery. And I haven’t yet figured out low-power use of the RFM12B anyway. With everything permanently on, total power consumption should be under 40 mA.

Am still looking for a nice power supply to use, Pollin has several, some as cheap as € 2. Given that the JeeNode has an on-board regulator, any 4..8 V DC supply will do.

The sensors listed above require 2 ports, so there is room for expansion – depending on room requirements:

  • more temp sensors, strung together via 1-wire
  • door and window contact sensors, water level, etc

The JeeNode is placed up against the ceiling to give the motion sensor an optimal view of the room. For really accurate temperature and humidity measurements, it might be preferable to move the SHT11 sensor down a bit – or alternately, to put the JeeNode near the power supply and run a 4-wire cable to the ePIR + light sensors.

Decisions, decisions …

Bye bye readout

In Hardware on Apr 2, 2009 at 00:01

This is what remains when I took the ELV WS300 PC unit apart – the enclosure:

ELV WS300 PC

The electronics, with an ATmega168, a temp/humidity sensor (SHT10?), a barometric pressure sensor, a combined USB interface / battery holder, and a pretty nice custom LCD:

ELV WS300 PC

Oh, and an 868 MHz OOK receiver module:

ELV WS300 PC

This unit includes some dataflash memory to store all received measurements and can be connected to a PC for reading everything out. I took it apart because the Windows-only software really isn’t my cup of tea (a not-so-exciting front end with Postgresql as database backend) and because the 3 AA batteries where running out a bit too quickly (why doesn’t it use USB power when available?). Besides, I really wanted to get a better 868 MHz radio. The module in here seems just right: it can receive all the KS300 and S300 data and it runs at 3V.

Maybe I’ll try my hand at de-soldering one day – the sensors might be worth salvaging as well.

Meet the JeeNode "Pulse"

In AVR, Hardware on Mar 30, 2009 at 00:01

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

Pulse prototype

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

  • Either an ePIR via software serial or a PIR on DIO plus an LDR on AIO.
  • The SHT11 sensor, which requires a dedicated port.
  • Two pins for either 2 contact sensors or more I/O via I2C I/O expanders.
  • Up to ten DS18B20’s via a 1-wire interface.
  • This leaves one spare pin – for a status LED or to monitor the voltage.

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

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

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

Reading out an ePIR motion sensor

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

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

ePIR with LDR

A simple Arduino sketch to read it once per second:

Picture 1.png

Sample output:

Picture 2.png

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

The ePIR has a 9600 baud serial interface, connected via Mikal Hart’s excellent NewSoftSerial library.

Sensing light levels

In AVR on Mar 2, 2009 at 00:01

Here is the TSL230 sensor (see SparkFun #08940), hooked up to a JeeNode:

TSL230 demo

And here’s the source code, using the Ports library:

TSL230 source

Sample output:

TSL230 output

Ports on a standard Arduino

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

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

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

Ports on a standard Arduino

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

Ports are mapped to the Arduino pins as follows:

  • Port 1 DIO = Arduino digital pin 4 (PD4)
  • Port 1 AIO = Arduino analog pin 0 (PC0)
  • Port 2 DIO = Arduino digital pin 5 (PD5)
  • Port 2 AIO = Arduino analog pin 1 (PC1)
  • Port 3 DIO = Arduino digital pin 6 (PD6)
  • Port 3 AIO = Arduino analog pin 2 (PC2)
  • Port 4 DIO = Arduino digital pin 7 (PD7)
  • Port 4 AIO = Arduino analog pin 3 (PC3)

The ATmega register bits are listed in parentheses.

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

Picture 2.png

Sample output:

Ports on a standard Arduino

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

Ports on a standard Arduino

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

Memsic 2-axis accelerometer

In AVR, Hardware on Feb 26, 2009 at 00:01

Yet another sensor mounted on a breakout board by Parallax, is the Memsic 2125 accelerometer:

Memsic 2125 2-axis accelerometer

Demo sketch, called “accel2125_demo” in the Ports library:

Memsic 2125 2-axis accelerometer

Sample output:

Memsic 2125 2-axis accelerometer

The pulses are 5 msec at rest, and changed slightly when I moved this thing (rather gently).

Might work nicely for a self-balancing robot…

QTI measures reflection

In AVR, Hardware on Feb 25, 2009 at 00:01

Parallax offers a QTI sensor, which is a led + photo transistor on a breakout board. It’s easy to hook up to a JeeNode because the pin-out matches port pins 3..5:

A QTI sensor measures reflection

Demo sketch, added as example to the Ports library:

A QTI sensor measures reflection

Sample output:

A QTI sensor measures reflection

Could be used to count power / gas meter revolutions.

All together now

In AVR, Software on Feb 22, 2009 at 00:01

It’s time to combine everything:

Combi demo

This is a setup with all the sensor interfaces documented in recent posts:

  1. a SHT11 to measure relative humidity (and temperature)
  2. a BMP085 sensor to measure barometric pressure (and temperature)
  3. PIR + LDR sensors to demonstrate reading digital and analog signals
  4. a Nunchuk with 2-axis joystick, 3-axis accelerometer, and 2 buttons

A new “combi_demo” has been added to the Ports library. The code is essentially the concatenation of the individual demo source files (you can browse the real thing here):

Combi demo

This example illustrates how the Ports library lets you mix and match drivers and ports at will. Note that two I2C interfaces are running in parallel at different speeds (sure, the BMP085 and the Nunchuk could also have been tied to a single port, running at 100 KHz).

Sample output;

Combi demo

This example compiles to 9114 bytes of code with the Arduino 13 IDE, so there is still plenty of room left to add, say, a wireless driver.

Hooking up a Nunchuk

In AVR on Feb 21, 2009 at 00:01

The Nintendo “Nunchuk” controller is for the Wii game console, but it’s also a great I2C input device. So for fun and as a game… I hooked one up to port 4 of a JeeNode:

Hooking up a Nunchuk

Although the “Wiichuck” adapter lets you connect an unmodified Nunchuk, I just ripped the whole thing apart, and cut off the proprietary connector. There are four wires, tied to pins 2..5 of port 4, respectively: green (SDA), white (GND), yellow (SCL), and red (+3.3V). The following “nunchuk_demo” has been added to the Ports library:

Hooking up a Nunchuk

Sample output:

Hooking up a Nunchuk

PS. I2C on port 4 = (on Arduino) SDA: D7, SCL: A3 (see JeeNode-v2.pdf page 3).

Update – swap the red and yellow wires for the JeeNode v3 and v4 (the above is an older unit).

Two simple sensors

In AVR on Feb 20, 2009 at 00:01

This is an example of hooking up two simple sensors to a single JeeNode port:

Two simple sensors

The Passive-IR (PIR) sensor by Parallax is on the DIO pin of port 3 (with ground and +3.3V also connected), and there is an LDR between the AIO pin and ground. Here’s sample code, as included with the Ports library:

Two simple sensors

Sample output:

Two simple sensors

Hooking up a BMP085 sensor

In AVR, Software on Feb 19, 2009 at 00:01

The BMP085 sensor measures barometric pressure (and temperature). I’ve hooked it up to port 2 via I2C:

Hooking up a BMP085 sensor

As SMD, it’s tiny

Hooking up a BMP085 sensor

The 4 wire-wrap wires are connected to port pins 2..5, respectively: SDA (DIO), ground, SCK (AIO), and 3.3V power.

There’s now a bit-banging I2C master driver in the Ports library which works with any of the 4 ports, plus a new driver for the BMP085. Here’s the new demo code, now included with the library:

Hooking up a BMP085 sensor

It looks like the elaborate algorithm from the BMP085 data sheet to calculate pressure in Pascals (millibar) contains an error. After some guess-work and with information from the older SMD500 sensor, I think I’ve come up with the proper computations. The results are now as expected:

Hooking up a BMP085 sensor

This is a very sensitive MEMS sensor. It’s accurate enough in its lowest resolution mode to calculate altitude to 50 cm accuracy given the exact pressure at sea level – just moving the sensor up and down shows a matching variation! Higher-resolution modes have been not been implemented.

Update – There’s a problem with the calculations: with temperatures 25.0 °C and up, the pressure calculations fail and a result of 2.35 mBar is reported. Will need to look into this.

Update 2 – Thanks to a private email suggestion, I’ve finally been able to resolve the > 25 °C bug. The current source code no longer has the problem and shows consistent values also at higher temperatures.

Hooking up an SHT11 sensor

In AVR, Software on Feb 17, 2009 at 00:01

The SHT11 sensor measures relative humidity and temperature. It connects via 2 I/O lines using an I2C’ish protocol with a funny (optional) CRC check. I’ve hooked it up to port 1 on a JeeNode:

Hooking up an SHT11 sensor

There are just four wires to connect to this minute module. Here’s a close-up, with data and ground crossed over to port pins 2 and 3, respectively:

Hooking up an SHT11 sensor

The sensor is mounted free-floating on this little DIY breakout board so it picks up ambient air properties.

A driver for the SHT11 has been added to the Ports library, along with a small demo:

Hooking up an SHT11 sensor

A “sensor” object is defined at the top, tied to a specific “port” – the SHT11 class is derived from the Port class.

Sample output:

Hooking up an SHT11 sensor

The driver uses PROGMEM for the optional crc table. This causes a warning in Arduino-0013 when switching boards (which recompiles PortsSHT11.cpp), probably due to this issue, i.e. gcc bug #34734.

With thanks to Guido Socher for his excellent page about the SHT11 (his version does all calculations using fixed point integers, if you prefer to avoid floats).

Update – Changes checked-in and ZIP file updated. Thanks to Stephen Eaton for pointing out a mistake in the calculation constants for 3.3V.

Better Mousetrap

In AVR on Dec 12, 2008 at 15:48

Now that RF transmissions work better, it was a small step to create a better house usage monitor. This one supports four sensors:

3E7468D6-0CFD-439D-91D9-8E41BAD8FB67.jpg

Only two sensors are being used so far (all sensor inputs are identical).

Sensor #1 watches the electricity meter rotations using the SY310 sensor:

CBCE0CCB-9B9B-4960-9F00-81FA934B304D.jpg

Sensor #2 is a QRD1114 which tracks a little mirror mounted on the last digit “0” of the gas meter:

87BF22D8-4722-46F6-A76B-2C3775CEEE14.jpg

The sensors were described in a previous post. Proper positioning turned out to be crucial, so there’s a fair bit of scotch tape to hold everything in place!

IR Sensors

In Uncategorized on Dec 8, 2008 at 15:35

Here are two new home-made sensors, improving on this one they will soon replace:

8CF78CD3-58D0-48C5-9A03-97A964CB0317.jpg

The top one uses a QRD1114 sensor, which produces an analog signal, whereas the lower one is based on the SY310 with a built-in comparator to generate a digital output. The intended range is around 5..15 mm, hopefully just right to detect the 0-digit reflector on the gas meter and the the rotations of the energy meter, respectively.

Both of these sensors are connected to a 3-wire audio jack cable: shield = ground, ring = +5V, and pin = signal. Both sensors use a 330..470 Ω resistor to drive the IR-LED and a second one of 10..100 KΩ as pull-up for the output signal.

Contraption

In AVR on Dec 4, 2008 at 15:31

This watchamacallit is a hookup to the electricity meter downstairs:

89248D86-7166-454D-88C8-7C711912A943.jpg

It has a sensor concocted from an ultra-bright LED and a phototransistor, which senses when the black marker on the rotating wheel passes underneath it.

This sensor is tied to an RBBB Arduino which tracks and transmits the rotation count every 3 seconds on 868 MHz, using the previously created setup:

D73BA4B6-ECFD-4CE5-84F9-BDDDA6DD129F.jpg

The green transmitter PCB is in front at the top. The whole thing is powered by a 9V adapter.

To deal with quick rotations, the sensor is read out about 100 times per second, also during each 100 msec transmission. These were rough calculations and the transmissions no doubt have considerable jitter due to inaccurate timing. A timer- / interrupt-driven version will probably improve accuracy and transmit range. But for now this crude setup appears to provide acceptable readings.

This Tcl script saves the results to file on MacOSX:

2C7654DB-52CF-40EF-A4CC-D1B16FD14023.jpg

And this is an extract of that log file (showing roll-over and some missed packets):

41E4D41F-D6B3-4FA7-9FEC-9EA8277E47CA.jpg

The 94..97 values are the rotation count. This also shows that the log remains usable even when packets are missed.

Nunchuk

In AVR on Nov 9, 2008 at 00:45

The Wii Nunchuk controller is really just an I2C device, with a triple-axis accelerometer, an X-Y proportional joystick, and two push buttons. Breaking it out of its case allows us to connect it in ways it was never meant for:

EC19CAFA-DD22-4B24-8A54-DD7B726365D1.jpg

It’s very easy to hook up to an Arduino and there’s a good example on the web to read out all the sensors. I’ve tweaked it a bit to use pins 8 and 9 as the I2C/TWI interface.

Connections above are as follows: red = +3.3..5V, white = ground, green = SDA, yellow = SCL.