preload
Feb 14

On my desk i have a JeeNode, equipped with a Pressure sensor. This JeeNode is also controlling a XBee Series 2 module which is configured as Zigbee End Device. All this is battery powered. Calculations on power usage of the JeeNode+Sensor+XBee are good enough to expect an acceptible battery life. A Sparkfun XBee RS232 holds another XBee module, configured as Zigbee coordinator. This setup has been operating for more than a week now. It all looks stable enough to go ahead and connect the Zigbee network (ok, it’s only 2 nodes right now :-) ) to my Domotica system and  actually do something with it; something different from logging the incoming pressure data to a text file and reviewing this file periodically to see if everything is still up and running; so i added another (the 16th) interface to my Domotica system: Zigbee! :-)

In fact all the hard work had already been done in an earlier stage where i created an API-mode interface for Zigbee; in essence, the only thing left to do was making this interface ‘talk’ to the rest of the Home Automation system, add some records in the database for this new sensor type and write a routine that would convert the incoming packets to the measured values of temperature and pressure.

Zigbee interface

Wow! It’s great to see my first Zigbee based sensor really working! The pressure data is being stored in the database, so in a few hours i can start creating an additional web page to show a pressure chart… and here it is!

BMP085 Pressure sensor data

BMP085 Pressure sensor data

Next on the list: finding a suitable, small housing, making a light sensor, a motion sensor, humidity sensor, … the list is to long! :-)

Tagged with:
Feb 14

Now that i have 2 JeeNodes up and running for more than a week and everything’s working fine, it’s time to do some calculations on power usage of the sensors. First thing i wanted to know was how much power a combination of a sensorless Jeenode and XBee module was using, so i created a sketch that would give me some ‘inside’ information about what was going on inside the Jeenode. The sketch i made informs me about a couple of things, like:

- the timespan the JeeNode is awake to power up the XBee, send a packet to the XBee and wait for it to finish transmission;

- the timespan the XBee is powered to send that packet of 10 bytes.

Battery powered JeeNode

With these numbers i should be able to roughly calculate the power usage of this sensor. The power that is used by the JeeNode while it’s awake is about 35 mA, while the XBee uses around 40 mA while transmitting. When both the JeeNode and XBee are in deep sleep, the combination of both uses only 60 μA.

The time measurements i did to find out the timespans mentioned above gave me the following figures: the total time the JeeNode is awake to read a sample from the Pressure sensor, wake the XBee, transmit the data and go back to sleep is 40 ms. The time that the XBee is awake is around 25 ms. With a sample interval of 30 seconds, and a 2000 mAh battery, i have calculated a battery life of more than a year; increase the interval to 60 seconds (still good enough for this type of information) and batteries should survive more than 2 years… i think.

Just ask me in a year or so ..

But good enough to go ahead with the expedition! :-)

Tagged with:
Jan 31

The fact that in the setup i made yesterday, the XBee module sometimes had trouble setting up the connection was troubling me, so i tried to figure out what was going on. My guess was that the CTS line was not monitored, so i built a counter into the loop that waits for CTS to get high; and made this counter part of the packet payload so that i could monitor what was going on; this counter  was always 1, meaning CTS was high at the time the first CTS check was done!

Hmm, seeing that, the error was found very quickly: CTS was attached to the wrong digital input, so CTS wasn’t monitored at all… fixed the wiring and now everything’s OK.

Second thing i changed was for the sake of convenience: the new sketch does the temperature and pressure calculations “on board”, so now the payload immediately shows value that are easily interpreted. I also took the time to create a small Delphi program that uses my XBee API to log all the packets that are received in a more readable style:

31-1-2010 20:43:30:Packet payload=[2 215 100159]
31-1-2010 20:43:41:Packet payload=[7 215 100150]
31-1-2010 20:43:52:Packet payload=[0 215 100153]
31-1-2010 20:44:03:Packet payload=[0 215 100156]
31-1-2010 20:44:14:Packet payload=[0 215 100166]
31-1-2010 20:44:25:Packet payload=[5 215 100156]
31-1-2010 20:44:36:Packet payload=[10 215 100159]
31-1-2010 20:44:47:Packet payload=[0 215 100150]
31-1-2010 20:44:59:Packet payload=[0 215 100156]
31-1-2010 20:45:10:Packet payload=[0 214 100153]

The first value is the time in milliseconds that it takes for the CTS to become high, the second value is the temperature in 1/10th of a degree and the last value is the pressure in mbar.  Neat :-)

Tagged with:
Jan 30
JeeNode connected to XBee

JeeNode connected to XBee

Here you see my first setup of a JeeNode with pressure sensor connected to a XBee Series 2 module.  And it’s working! With Hyperterminal i captured the raw data coming in on my XStick:

XBee API mode packets with sensor data

XBee API mode packets with sensor data

The ‘experts’ will immediately recognize the first character (tilde, ~) as being the frame header of a XBee packet. The payload on the first line is ‘26311 39767′. All characters before that are XBee API frame related as well as the last character, which is the checksum. When you have a look at the code you can see what the payload is made of.

This is absolutely very cool; it think in total it has cost me an evening to put this all together; something i would have never dared dreaming about a year ago!

But there’s still a lot to do:

There seems to be a timing issue in the code, cause i saw the XBee having a bit of trouble joining the PAN. Maybe give it some more time in the setup routine, or give some more time during powering up the XBee to send a new sample… we’ll see.

I need to write some software on PC-side to test reliability of it all.

How long will the batteries survive? I haven’t got a clue… and how am i going to test this? For example, i can’t switch off my PC now, cause the XStick is powered by it; XStick not powered means no PAN means the XBee will keep on searching for the PAN and will use much much more power…

To make the whole package smaller, i need to stop using the pin headers on the JeeNode and just solder the wires right onto the board.

A big step ahead, but still a lot of questions to be answered…

Here’s the code that is currently running on the JeeNode:

#include <Ports.h>
#include <RF12.h>
#include "PortsBMP085.h"
#include <avr/sleep.h>
#include <NewSoftSerial.h>

NewSoftSerial XBSerial = NewSoftSerial(2, 3);
PortI2C two (2);
BMP085 psensor (two);

int pinXBee=7;                        // to Control XBee on/off
int pinCTS=6;                         // to monitor CTS

static int SampleInterval = 1000;     // 60000;
static int HeartBeatInterval = 10000; // 300000;
static int CTS=0;                     // value of XBee CTS pin

struct {
    int16_t temp;
    int32_t pres;
} payload;

static void lowPower (byte mode) {
    // prepare to go into power down mode
    set_sleep_mode(mode);
    // disable the ADC
    byte prrSave = PRR, adcsraSave = ADCSRA;
    ADCSRA &= ~ bit(ADEN);
    PRR &= ~ bit(PRADC);
    // zzzzz...
    sleep_mode();
    // re-enable the ADC
    PRR = prrSave;
    ADCSRA = adcsraSave;
}

EMPTY_INTERRUPT(WDT_vect); // just wakes us up to resume

static void watchdogInterrupts (uint8_t mode) {
    MCUSR &= ~(1<<WDRF); // only generate interrupts, no reset
    cli();
    WDTCSR |= (1<<WDCE) | (1<<WDE); // start timed sequence
    WDTCSR = bit(WDIE) | mode; // mode is a slightly quirky bit-pattern
    sei();
}

static byte loseSomeTime (word msecs) {
    // only slow down for periods longer than twice the watchdog granularity
    if (msecs >= 32) {
        for (word ticks = msecs / 16; ticks > 0; --ticks) {
            lowPower(SLEEP_MODE_PWR_DOWN); // now completely power down
            // adjust the milli ticks, since we will have missed several
            extern volatile unsigned long timer0_millis;
            timer0_millis += 16L;
        }
        return 1;
    }
    return 0;
}

static MilliTimer SampleTimer;     // Interval for reading a sample from the BMP085
static MilliTimer HeartBeatTimer;  // forced maximum interval (Heartbeat)

static byte periodicSleep (word msecs) {
    // switch to idle mode while waiting for the next event
    lowPower(SLEEP_MODE_IDLE);
    return SampleTimer.poll(msecs);
}

static void Send (const void* ptr, byte len) {

  unsigned long tXB1;    // time XBee was woken up
  unsigned long tXB0;    // time XBee was put to sleep

  Serial.println("Sending payload");
  HeartBeatTimer.set(0);

  CTS = HIGH;
  tXB1=millis();
  // wake up Xbee
  digitalWrite(pinXBee,LOW);

  // wait for CTS to become LOW
  do
  {
    CTS=digitalRead(pinCTS);
  } while (CTS != LOW);

  // wait 2 msec otherwise data will be received all messed up
  delay(2);

  // send dummy data
  XBSerial.print(payload.temp);
  XBSerial.print(" ");
  XBSerial.println(payload.pres);  

  Serial.print(payload.temp);
  Serial.print(" ");
  Serial.println(payload.pres);  

  // wait again for XBee to finish transmission
  delay(2);

  // switch off XBee
  digitalWrite(pinXBee,HIGH);
}

static int16_t prevTemp;           // save previous temp value
static int32_t prevPres;           // save previous temp value

// this code is called once per second, but not all calls will be reported
int ReadSensor() {

    int16_t temp = psensor.measure(BMP085::TEMP);
    int32_t pres = psensor.measure(BMP085::PRES);

    Serial.print("Readings: ");
    Serial.print(temp);
    Serial.print(' ');
    Serial.print(pres);
    Serial.println(' ');

    int changed = (temp != prevTemp) || (pres != prevPres);
    prevTemp = temp;
    prevPres = pres;

    payload.temp = temp;
    payload.pres = pres;

    changed = 1;            // force sending always during testing
    return changed;

}

void setup() {

  // setup XBee
  pinMode(pinXBee,OUTPUT);
  digitalWrite(pinXBee,LOW);
  pinMode(pinCTS,INPUT);
  digitalWrite(pinCTS,LOW);   // really necessary?
  delay(10);

  XBSerial.begin(9600);
  // give XBee some time to join PAN
  delay(5000);

  // let the world know we're here
  XBSerial.println("\n[TempPres]");
  Serial.println("\n[TempPres]");

  watchdogInterrupts(0); // 16ms
}

void loop() {
    if (periodicSleep(SampleInterval)) {
      // sensor values changed or heartbeat interval elapsed?
      if (ReadSensor() || (HeartBeatTimer.poll(HeartBeatInterval)))
      {
         Send(&payload, sizeof payload);
       }

    }
}
Tagged with:
Jan 30

I don’t own a weather station, nor do i intend to buy one, but i always did like the idea of having a pressure sensor. Now i have :-)

This BMP085 based pressure sensor doesn’t only do pressure, but can also measure the temperature. Time to hook it up to a JeeNode!

Due to the fact that our plans for today had to be canceled by the bad weather, i had some extra time to test this Pressure Sensor. First i had to solder the 2nd JeeNode i bought last week, cause it was still unassembled in it’s plastic bag. Soldering a JeeNode is quite easy to do; it’s really hard to do something wrong… This time i left the RF12 radio off because i wanted to use one of my XBee modules to send the raw measured values. And i attached a battery holder, cause eventually this is my goal: a battery powered pressure sensor.

I installed the Ports library, uploaded the BMP085 demo sketch from the Ports Library examples  to the JeeNode and everything ran fine:

BMP 26265 39759 225 99390
BMP 26260 39755 225 99372
BMP 26267 39761 226 99400
BMP 26263 39756 225 99378
BMP 26265 39759 225 99390
BMP 26263 39758 225 99384
BMP 26261 39757 225 99378

Next step will be adding code for the XBee and sleeping. To bad, time’s up for now… hopefully, later this evening i have some time left to finish this sensor.

JeeNodev4 with BMP085 Sensor

JeeNodev4 with BMP085 Sensor

Tagged with:
Jan 28

They arrived last Tuesday. 2 JeeNodes, together with a JeeLink and a pressure sensor. And an additional Arduino for experimental stuff.

JeePlug

JeeLink

Although i had a lot of other things to do, i just couldn’t resist building at least one of the two i ordered. The JeePlug kit is easily soldered together so after half an hour i had my JeePlug and first JeeLink running. Next thing to do is get the Pressure Sensor working, receiving the data and processing it in my Domotica system.With all the information provided on Jean-Claude Wippler’s website that shouldn’t be a problem :-)

So when you find a pressure chart on my website in the near future, you know where the data’s coming from…

Tagged with: