MCU-less experiments

Some days ago I was reminded of the fact that the Hall-effect sensor I’m currently testing, could very well do without a JeeNode; a combination of this sensor with a XBee could maybe suffice as a wireless sensor. Right; so I made this breadboard setup:

A3214 sensor with XBee

It looks like it’s working, although I haven’t spent that much time on this yet. Yes, I do see incoming “IO Data Sample” packets, I see differences in the bits for “open” and “closed”, but I also see multiple packets (3, 5) where 1 packet would be perfect.

Another big issue is that in this setup the XBee is working in “No Sleep” mode, and that’s a no-go of course when this is going to be battery-powered. Do I want to use cyclic sleep and have IO samples sent at a regular interval? No!, that’s always too late…

Does the XBee Digital IO Change Detection work while it’s asleep? Probably not, although I haven’t tested that yet. But the manual doesn’t give any clue that this will work, so chances are small that it will.

Maybe I can do something with the “Cyclic Sleep Pin-Wake” Sleep mode? Never used that one before…

Or, use a different approach; use “a” circuit, triggered by the sensor, that will wake up the XBee, make the XBee send a IO Data Sample (this can be done with some specific XBee settings) and put it back to sleep after the XBee has finished sending the sample. That’s where I have used a JeeNode for so far .. 🙂 ; but maybe there’s a simpler solution?

Time to find out!

The Allegro A3214 Hall-Effect Switch

As I mentioned yesterday, I’m currently testing a new sensor: the Allegro A3214 Hall-Effect switch. This very small sensor looks like a very good candidate for my own Door & Window sensors. A sample of this sensor was given to me by Jean-Claude Wippler a few weeks ago, and now that I’m waiting for some Mantis parts I ordered and have no more time to spend on the Arduino Workshop, it was time for something new.

Some characteristics of the A3214:

  • 2.4 to 5.5V battery operation
  • minimal power requirements
  • pole independent switching
  • small size

How small is small??

This is small!

Allegro A3214

The magnet (upper left) measures 3x3x3 mm, the sensor dimensions are 4 x 3 x 1.5 mm. Yep, that’s really small 🙂

First thing I did yesterday, was putting this sensor on a breadboard and connecting it to a JeeNode. I wrote a small sketch that used LED2 of the Bridge Board to visually show the status of the sensor output:

#include <Ports.h>
#include <RF12.h>

Port one (1);
Port four (4);

void setup() {
  one.mode(OUTPUT); // LED2 of Bridge Board is connected to Port 1 Digital.

  four.mode(INPUT); // the sensor is connected to Port 4.
  four.digiWrite(HIGH);  // enable pullup
}

void loop() {

  one.digiWrite(four.digiRead());
}

It worked, wow! Moving the magnet towards the sensor made the LED go off (the output is high when the magnetic field isn’t strong enough), moving the magnet away made the LED go on again. The distance between sensor and magnet when the output value changes is approx. 10 mm.

Today I wanted to do some power usage measurements, so I changed the sketch a bit:

#include <Ports.h>
#include <RF12.h> // needed to avoid a linker error :(
#include <Sleep.h>

#define DEBUG 0

int INTpin = 3;
Port one (1);

volatile boolean wdt_expired=0;

// Interrupt Serive Routine that will be executed when the Watchdog Timer expired.
ISR(WDT_vect) {
  wdt_expired=1;
}

//****************************************************************
// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
void setup_watchdog(int ii) {

  byte bb;
  int ww;
  if (ii > 9 ) ii=9;
  bb=ii & 7;
  if (ii > 7) bb|= (1<<5);
  bb|= (1<<WDCE);
  ww=bb;

  MCUSR &= ~(1<<WDRF);
  // start timed sequence
  WDTCSR |= (1<<WDCE) | (1<<WDE);
  // set new watchdog timeout value
  WDTCSR = bb;
  WDTCSR |= _BV(WDIE);
}

void setup(void)
{
  pinMode(INTpin, INPUT);
  digitalWrite(INTpin, HIGH);

  one.mode(OUTPUT); // LED2 of Bridge Board is connected to Port 1 Digital.

  #if DEBUG
  Serial.begin(9600);
  #endif
}

void loop(void)
{
  #if DEBUG
  Serial.print(millis(), DEC);
  Serial.print(" I'm awake, caused by ");
  #endif

  if (wdt_expired==1){
    wdt_expired=0;
    #if DEBUG
      Serial.println("the WDT");
    #endif

    // Do something, like sending a heatbeat
    // sometimes

  }
  else
  {
    // External interrupt triggered!
    byte val = digitalRead(INTpin);

    // disable LED during power measurements
    //one.digiWrite(val);

    #if DEBUG
    Serial.print(val, DEC);
    Serial.println(" INT0");
    Serial.print("Doing some serious stuff now...");
    #endif

    // measure awake
    delay(5000);

    #if DEBUG
    Serial.println("finished!");
    #endif
  }

  //
  #if DEBUG
  Serial.print(millis(), DEC);
  Serial.println(" Sleeping...");
  delay(100);     // wait for serial to finish
  #endif

  // go to sleep and wake up
  // on watchdog or IRQ pin change
  setup_watchdog(9);
  Sleep.powerDownAndWakeupExternalEvent(1, CHANGE);     // sleep function called here
}
The A3214 output was moved to an external interrupt pin, I disabled LED2 and wrote down the power usages with the JeeNode, Bridge Board and A3214 connected to a 3 x AA battery pack producing 4.1 V:
  • JeeNode awake: 7 mA;
  • JeeNode asleep, magnet in range of sensor: 38 μA;
  • JeeNode asleep, magnet out of range: 14 μA.

That’s very good… I’m sure this power usage will be good enough to live on 1 set of AA batteries for a long time. 🙂

Of course, Door & Window sensors is the most obvious application for these sensors. But the small size makes me wonder if I can come up with more useful ideas…

On to the next step!

Small, smaller, smallest?

Really small...Sensors that are used a lot in the house, can’t be small enough in my opinion. As long as it’s not SMD, I know I can handle it. And where possible, I want my sensors to be as invisible as possible of course. In the lower right part of the image there’s a new sensor, connected to a Bridge Board & JeeNode. This is small enough I’d think! This is the first time I have this sensor on a breadboard for testing; the next couple of days I hope to find some time to do more tests with this sensor and explain what it actually is and what it can be used for. The first results are encouraging! That’s all for now 🙂

Notes about the pull-up

The motion sensor i finished yesterday needed some last tests; namely, what resistor should i use? Internal? External? And in the case of external, what value? Now the internal pull-up resistors of the Arduino are 20 k. But why not try to use a higher value, cause even with this resistor the rule V = I * R applies, right? When the JeeNode is in power down mode, i measure 1.36V over the external (100 k) resistor I used till now. That means there’s a current of 13.6 μA going through the resistor. With the internal 20k resistor this would be 5 times more: 68 μA! Yuck! And all that in power down mode, no way!

OK; i bought a huge case with an assortment of resistors a few years ago, ranging from 12Ω to 1 MΩ. Hey, let’s try that last one, 1 MΩ. This will add an additional factor of 10 to the external resistor value, resulting in the current dropping to 1.36 μA. And guess what; with this resistor the behavior of the PIR didn’t change; this is very nice! I hope I’m not overlooking or breaking any electrical laws or rules by doing this, but this seems the right thing to do..

Programming the XBee and placing it in the breakout board is all there’s left to do; I guess you could say this 3rd sensor is finished! 🙂

A new challenge

First a follow-up on yesterday’s TV LED strips; here’s what it looks like a few hour later, around 22:30, while I was watching “24”. One of the few things left that make me sit down, watch and enjoy live TV.

LED strips in the evening

I know; I’m not much of a photographer, but I tried to make it look as best as I could. In real life it looks even better 🙂 OK, this one is finished; on to the next challenge!

Which means back to the motion sensor, the ELV PIR13 i bought recently.

Testing ELV PIR13

After i cleaned the desks, I connected a PIR13 to a JeeNode and uploaded a sketch i used for the Panasonic PIR before. No luck this time; nothing but garbage coming from the PIR.

A digitalRead() produced nothing useful and i didn’t understand why. I tried adding resistors between GND and the PIR output, but that wasn’t succesful either. But somehow i knew i was close…then I remembered reading about internal pullup concerning the PIR13 somewhere, so I added an additional digitalWrite() in the setup routine to enable them. Bingo, now i get the right results!

Now the digitalRead calls produce a ‘low’ when motion is detected and ‘high’ when not. That’s something I can work with. For now this ELV PIR13 will remain on my desk for a while untill I can find some time to solder a new JeeNode, buy some more XBee modules and enclosures, plugs and stuff, cause I’m running out of stock…

Going down even more

Now that i have no more PIR sensors in stock, I had to find me an alternative. The requirements: low power of course, it should be able to fit in the PIR enclosure i already have in use and not too expensive, cause I’ll need a lot of them. The ELV PIR13 seems to be the right candidate for the job; this would bring down the PIR power usage from 170 µA to 40 µA. I don’t have to tell you what that will do to battery life 🙂

ELV PIR13: PCB 25 x 37 mm, 13 mm PIR

I’ve ordered a couple of these ELV PIR13’s and will build a 3rd motion sensor with one of these. In the meantime I also changed some things in the code to reduce the JeeNode power usage in power down mode even more: it went down from 20 µA to 6.5 µA. Calculations show a theoretical battery life of 200 weeks… well, i think the internal discharge will have screwed up the battery before that…

BTW, the 2 motion sensors that are currently being used, are still running fine on their first set of batteries.

Adding Light and Temperature

Since i removed a bunch of MS13 sensors recently, i am missing some input on what is going on at several places in our home. So while i was making a list of things i need in the near future, i realized i should extend the motion sensors a bit more, or otherwise i would lose the dark/light sensor the MS13 provided. And why not add temperature as well; cause that would mean i could do without the Oregon sensors also. I mean, why use 2 sensor devices (one only for temperature and another one for motion and light) when you can combine it all into one? Let’s have a look at temperature…

I still have 10 DS1820 1-Wire sensors somewhere from the days when i started with Domotica, but i never used them; maybe now i finally found a purpose for them? Let’s connect a few to an Arduino and see if  i can get a temperature reading:

Arduino with 3 x DS1820

Arduino with 3 x DS1820

And of course, there’s a library to use 1-Wire devices with an Arduino.. so before i knew it, i was polling the temperature of 3 DS1820s 🙂

Addr:10 6C 5 CA 0 8 0 C3  Temp=25.50 grC
Addr:10 33 EC 3 1 8 0 E1  Temp=25.50 grC
Addr:10 FB 90 C9 0 8 0 1A  Temp=25.50 grC

Addr:10 6C 5 CA 0 8 0 C3  Temp=25.50 grC
Addr:10 33 EC 3 1 8 0 E1  Temp=25.50 grC
Addr:10 FB 90 C9 0 8 0 1A  Temp=25.50 grC

Addr:10 6C 5 CA 0 8 0 C3  Temp=25.50 grC
Addr:10 33 EC 3 1 8 0 E1  Temp=25.50 grC
Addr:10 FB 90 C9 0 8 0 1A  Temp=25.50 grC

Add an additional LDR and I’m done; ready to replace a large part of all my sensors: all remaining MS13s and most of my Oregon Scientific Temperature & Humidity sensors with my own 🙂

Battery life estimation

Exciting… what will be the outcome of the calculations based on monitoring 2 motion sensors during a period of 24 hours and extrapolating this calculated power usage? OK, let’s start with writing down some ‘facts’, taking the worst case of the 2 sensors for each individual measurement:

  • The JeeNodes active time during a period of 24h is 102.4 seconds, with a current of 6.5 mA;
  • Power down current is 20 µA;
  • The XBee sends an average of 120 packets per hour, requiring the XBee to be on for a duration of 34 ms for each packet, using 40 mA current (from the datasheet);
  • XBee power down current is 1 µA (datasheet);
  • The PIR uses 170 µA (datasheet) while in standby mode and 270 µA (datasheet) during motion detection; motion detection duration is estimated at 400 seconds.

With these numbers it should be possible to calculate the average power consumption of each component:

  • JeeNode: 27,68 µA;
  • XBee: 2,88 µA;
  • PIR: 170,46 µA.

This adds up to a total of 201,02 µA. That’s the average current the motion sensor is using, based on a period of 24 hours.  With 2000 mAh batteries this results in 9950 hours = 414 days = 59 weeks… cool! That will do, for now, lol

However… how about the battery self-discharge?? How much will this influence the time this motion sensor will last on 1 set of batteries? I really don’t know; so, still, time will tell how well this sensor performs in terms of long lasting batteries.

Fortunately, I still have enough options to reduce power usage even more, like

  1. Using the energy saving version of the PIR;
  2. Disabling stuff on the ATmega like brown out detection (how do i change fuses? As i mentioned before, where will this end? 🙂 );
  3. Running the ATmega on a lower frequency.

And now that i have it all in a spreadsheet, i can manually adjust some values and see how it effects battery life. The smartest thing would be to go for the 1st option, cause that would reduce the standby current of the PIR down to 46 µA instead of 170… meaning 3 years !!

I’m going to order some extra PIR’s now…

Motion sensor v2 built and in use

Two motion sensors v2 are in use right now, yippee!

I upgraded an existing v1 sensor to a v2 and built a new one. The v2 sensor specs are very different from the v1 but much more promising, yet all i needed to do to was soldering the digital output of the PIR to another JeeNode port (namely ATmega INT1) and use a different digital port for serial I/O with the XBee. Oh, and upload a new sketch of course. Now i have 2 identical v2 sensors:

v1 upgraded to v2

Looking back at how this motion sensor evolved i am wondering, why didn’t i think of interrupts in the first place… not very smart actually..

Or maybe i did think about interrupts but unconsciously thought it would be to hard for me to handle already, cause that’s what you read all the time: interrupts are a tough subject! Maybe it is, but i didn’t notice that yet! 🙂

So now I’ve got 2 motion sensors with the following features:

  • powered by 3 * 1.2V, 2000 mAh rechargeable batteries;
  • PIR with digital output, 100µA standby power usage and 5m detection range;
  • a JeeNode that’s effectively running only a total of about 180 seconds per day (0.2 %), even with 350-400 motion reports and lots of heartbeats. The rest of the time the JeeNode is in power down mode;
  • it’s ZigBee based which is better than 433 MHz in my opinion, especially when you’ve got a lot of sensors;
  • relatively small sensor housing compared to commercial (mostly big and ugly) products;
  • completely DIY so everything is how i want it to be;
  • interrupt-based, the best you can get I’d say;
  • need i go on?  🙂

I’m gonna monitor this sensor very closely in the coming months and learn from it. Here you see one of the sensors being used in the kitchen:

Motion v2 in the kitchen

Finished? Almost; some loose ends in the sketch. Maybe it can be made even smaller/faster/less energy consuming. But I’ll look into that when the 3rd sensor is built.

Update 2010-09-16:

The sketch that’s currently running on these sensors can be found here; the Sleep library i currently use can be found here .

Motion Sensor v2

Here it is, Motion Sensor v2. Not much different from v1 really, the only thing that has changed is that the PIR output has moved to an interrupt pin. And the sketch looks somewhat different here and there. Later this week i’ll build my 2nd motion sensor and start using it right away; i’m very curious about the results! I’ll also change my 1st motion sensor that’s already in use, to an interrupt driven model. Don’t want to wait for what will happen with those batteries…

The JeeNode is completely powered down most of the time. It only gets woken up by the Watchdog timer every 8 seconds or when motion is detected. But even when motion is detected, it’s powered down most of the time, cause a ‘blip’ sent to my Domotica System every 4 seconds during continuous motion is more than enough.

When the motion interrupt is triggered, the ‘blip’ is sent to my system, followed by a power down for 4 seconds without interrupt trigger set. When those 4 seconds have passed (wake up is done by the watchdog timer) a power down is done with interrupt trigger and the whole loop starts all over again. Capice? It doesn’t get much easier than this 🙂

And of course there’s a heartbeat sent every 64 (8 times 8 ) seconds.