Tag Archives: xbee

Door sensor

UPDATE: check my post about my new Moteino based door monitor.

In the past I’ve been monitoring my home door with an IP camera and the motion software in my server. Whenever something was moving in the camera range the server saves a little footage, takes a snapshot and calls a couple of scripts I use to send notifications via NMA and email.

The problem with this set up was that it had lots of false positives. Mainly due to shadows or changes in the luminosity when someone opened or closed a door in the corridor that leads to the front door. Playing with the software configuration (sensitivity, zone patterns, trying to remove luminosity bursts,…) made no significant difference. Some days 80% of the alerts were due to this type of events, and then the whole system becomes useless because you stop checking the notifications…

Continue reading

Smartmeter pulse counter (4)

This is going to be the last post for the smart meter pulse counter setup series. I want to wrap up several things like the final hardware, the code and the data visualization.

Final hardware

This is what the pulse counter sensor looks like, almost. The final version that’s already “in production” has a switch to hard-reset the radio from outside the enclosure. Nothing special otherwise. Everything goes in a socket so I could reuse the components, the photocell probe connects to the 3.5mm jack that’s on the top of the box and I’m using 3 alkaline AA batteries (not the rechargeable ones in the picture).

Code

The code is freely available under GPLv3 license on github. The code itself is pretty simple: it uses the Arduino LowPower library by RocketScream to keep the arduino sleeping for most of the time. It only wakes on an event on any of the two possible interrupt pins:

void setup() {

pinMode(LDR_INTERRUPT_PIN, INPUT);
pinMode(XBEE_INTERRUPT_PIN, INPUT);
pinMode(XBEE_SLEEP_PIN, OUTPUT);

Serial.begin(9600);

// Using the ADC against internal 1V1 reference for battery monitoring
analogReference(INTERNAL);

// Send welcome message
sendStatus();

// Allow pulse to trigger interrupt on rising
attachInterrupt(LDR_INTERRUPT, pulse, RISING);

// Enable interrupt on xbee awaking
attachInterrupt(XBEE_INTERRUPT, xbee_awake, FALLING);

}

The LDR_INTERRUPT pin is there the photocell based voltage divider is plugged to. When the photocell resistance drops due to a light pulse the pin sees a RISING transition and the Arduino counts the pulse. The XBEE_INTERRUPT pin is connected to the ON_SLEEP pin of the XBee (pin 13). When the XBee is sleeping this pin is pulled high and when it awakes the pin goes low and the Arduino sends the message.

void pulse() {
  ++pulses;
}
void xbee_awake() {
  ready_to_send = true;
}

On the main loop the arduino sleeps until an event awakes it. If the event has been triggered by the XBee then it calls the message sending methods.

void loop() {

// Enter power down state with ADC and BOD module disabled
LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);

// Check if I have to send a report
if (ready_to_send) {
ready_to_send = false;
sendAll();
}

}

Results

The messages are being received by an XBee coordinator radio that’s connected to an USB port in my home server. On the server my xbee2mqtt daemon is running listening to incoming messages from the radio port. The messages are mapped to MQTT topics (namely /benavent/general/power and /benavent/powermeter/sensor/battery).

The the mqtt2cosm mqtt2cloud daemon (I will write a post about this one soon) pushes the data to Cosm.com or Tempo-db.com. And the final result looks like this:

First issues

The pulse counter has been running for some days now and the first issue has arised. You may notice in the previous graph that from time to time the sensor stops reporting data for several minutes. I still have to find out what’s going wrong but my guess is that there is some issue with the interrupts and the transmissions. I am not disabling interrupts while transmitting because I thought it was not necessary when using the hardware UART, but maybe I was wrong.

The problem doesn’t seem to be related to the time of day, the power measure and in the tests I did while testing the XBee sleep cycle it did not happen (the probe was not plugged in so there were no additional interrupts…). The distance to the coordinator radio was one of the problem generation candidates in my first tests but now I am testing another sensor that’s just one meter apart from the pulse counter and it reports flawlessly…

Any suggestions?

XBee to MQTT gateway

So far I’ve posted about hardware and theoretical stuff like network architecture or naming conventions. I think it’s time to move to the software side.

The core of the sensor network I’m deploying at home is the Mosquitto broker that implements MQTT protocol. It manages the messaging queue, listening to messages posted by publishers and notifying the subscribers.

I’ve been working in parallel to have at least some pieces in place to get and store information from the pulse counter sensor. These are an XBee to MQTT gateway and a couple of consumers: one storing info into a MySQL database and another one pushing it to cosm.com.

I want to introduce you the first piece: the xbee2mqtt daemon. It’s already available on github under GPL v3 license. It publishes the messages received by an XBee radio to the Mosquitto instance. The radio must have a Coordinator API firmware loaded. Right now the gateway understands frame IDs 0x90 and 0x92 which account for “Zigbee received packet” (i.e. data sent through the serial link of the transmitting radio) and “Zigbee IO data sample” (that’s an automatic sample of selected analog and/or digitals pins on the transmitting radio).

I’ve tailored the daemon to my needs, but trying to be as generic as possible. The design is based on small components:

  • The “xbee” component takes care of the connection to the radio and the packet parsing.
  • The “router” maps xbee addresses/ports to MQTT topics.
  • The “processor” pre-processes values before publishing them.
  • The “mqtt” component takes care of the message publishing.
  • And the XBee2MQTT class (which extends Sander Merechal’s fabulous daemon class) glues everything together.

You can read the code to get a full insight of what it does but I’d like to explain here some decisions I’ve taken.

I’ve abstracted the message source to an address and a port. The address is the 8 bytes physical serial number of the radio (SH and SL) and the port is the pin (adc0, adc1,… dio1, dio2,…). 0x90 packets are mapped to virtual ports. The sender can define the name of the virtual port (like “battery:4460\n”) or otherwise a generic name will be used (“serial” by default).

The routing is a basic functionality. As I already explained in my previous post about topic naming conventions I think the mapping should be done in the gateway because no other component should have to know about the physical structure of the wireless (XBee) network. So the xbee2mqtt daemon maps all the messages to MQTT topics with semantic meaning. You can also allow default topic mapping which will publish any message received by an undefined address/port combination to a topic like /raw/xbee/<address>/<port>.

The processor uses a strategy pattern to pre-process any incoming value. I will be using this to do some calculations on the adc7 value the XBees report (that’s the voltage monitor pin) to convert it to the real voltage the batteries are providing.

All the components have been designed so they can be injected to any code that depends on them. This is a common pattern (dependency injection) that favours decoupling and provides a clean way to define strategies at runtime, for instance when mocking components in the unit tests.

As always, comments are more than welcome!

Smartmeter pulse counter (2)

This week I have had some spare time – well, I should say I’ve borrowed some time from my sleep – to work on the smart-meter pulse counter setup.

In my last post about this I analized the signal from my photocell sensor. My conclusion was that the signal was clean and neat, even before throwing in a schmitt trigger to make it more “digital”. I have found out that it is also very dependent on the environmental light so I good isolation is a must for the sensor.

I had already prepared a sensor probe with a 3.5mm audio jack on one end and the photocell on the other. But the photocell is aligned with the cable, which is quite rigid and I am concerned about how to attach it to the smart meter case. For now I will leave it like that and do some real scenario tests. Since it is an external sensor I can change it whenever I want.

Finally I have also added an RC filter to the sensor input. The previous data suggests it is not necessary but I needed to do some tests with a faked signal source (a mini button) and it won’t harm.

Aside from these things I’ve done some very important steps forward. I have a final schema for the board.

There are some points worth noticing:

  • I’ve added a ceramic capacitor across VDD and GND as the Xbee documentation recommends. I didn’t have the 1uF and 8.2pF ones but I have seen some boards with the *standard* 100nF.
  • There is a voltage divider for the battery monitoring on the top right corner.
  • On the bottom you can see the voltage divider with the photocell in series with the RC filter
  • I’m wiring DIO9 *and* DTR to the Arduino, this way I can switch from Xbee-driven to Arduino-driven from code (more on this later).
  • Finally I decided to wire DOUT to the Arduino (I’m using SoftwareSerial, so RX and TX pins are digital 5 and 6 respectively) Not any more. I am using hardware serial on the final version…

This setup allows me to choose between two very different approaches: I can make Arduino drive the sleep cycle by changing DTR pin (Xbee in mode SM1 or “pin sleep”) or I can make the Xbee control the sleep cycle (Xbee in mode SM4/5 or “cycle sleep”) triggering an Arduino interrupt  when it awakes.

The first option lets me send a report every N pulses. In my case 4 pulses equal 1Wh. Lets say I want to report chunks of 5Wh, that’s 20 pulses. That means a report every 4.5 to 90 seconds depending on the current load (200W to 4kW range), being 60 seconds (300W) the average.

With the second option I can report average power consumption every minute. The Arduino counts the pulses and when the Xbee awakes it asks the Arduino (i.e. triggers an interrupt) to calculate and report the average power consumption over the last minute. For instance, if the pulse count is 28, that’s 7Wh over the last minute or an average of 420W.

I prefer the later because the reports are evenly spaced which means they are somewhat easier to graph and the graph is more meaningful: if you graph the power in the Y axis and time in the X axis the area below the power line is the energy (watts * hour). With the former the data should be post-processed to get some useful information like average Wh per day.

I’ve already done some tests but, so far, I have not been able to program the Xbee to follow an accurate sleep cycle. To configure the sleep period you can use SP and SN, the first one represents the time in tens of milliseconds, the second is a multiplier. So with SP=0x03E8 (1000 in hex) and SN=0x06 that’s 60 seconds. The problem is that the awake period has it’s own counter, ST, which is reset “each time serial or RF data is received”. That introduces a random time in the calculation which translates into a slight shift in the reports.

Option B would be to use some RTC to awake the Xbee with an alarm trigger. But I would rather avoid adding more hardware to the sensor.

Well, still a lot of things to figure out… more to follow 🙂