Category Archives: Learning

Ciseco XRF modules & LLAP Protocol

In my last post about counting events with Arduino and PCF8583 I talked about this “yet another weather station” project I was working on last summer. The station was deployed in the garden of a cute apartment we rented in an old “masia” near Olot, 100 km north of Barcelona. It is in the mountainside, surrounded by woods and 10 minutes walking from the near town. It has a beautiful garden with plenty of space. We spent there most of the summer but now we are still driving there on the weekends. It’s colder, sometimes freezing, and when it rains, well, it does rain. Off course it was the perfect excuse to build another weather station.

One decision I had to take when designing the new weather station was how to send data from the nice housing I built for it in the garden to my home server in Barcelona. I needed some kind of internet connection in the house but that’s something I will talk about in another post. I could have used a RN-XV WIFI module like the one I’m using for the rentalito but it’s expensive and I really wanted something simpler to use.

I had already a couple of Ciseco’s XRF radios and decided to give them a try (they are now selling version 2 of theses radios, I have v1.5 modules). These modules provide an easy way to create a wireless transparent RF serial connection between two nodes, no need to configure anything. They have a better range than Bluetooth, WIFI or Zigbee, since they use a longer wavelength to operate (868 to 915 MHz). Off course they can do a lot more than that. They are based on Texas Instruments’ CC1110, a low-power System-on-Chip and you can write and load your own firmware on them. Ciseco provides a series of closed-source firmwares (they call them “personalities“) for these radios, focused on different sensor inputs. You can find more information in the openmicros.org wiki, there is enough to spend a couple of hours reading but I have to say the wiki is kind of a mess, although they have improved it a lot in the last year or so.

Ciseco XRF wireless RF radio

Ciseco XRF wireless RF radio v1.5

Anyway, out-of-the-box these modules are a transparent RF link and their footprint is compatible with XBee modules, so you can use them with your XBee Explorers, Arduino FIOs,… (well played Ciseco). Like in my previous weather station I decided to use an Arduino FIO as a controller (DC-IN, LiPo battery backed, XBee socket,…) so I just stacked one of these modules on it. Inside the house I prepared the “gateway”: an Arduino Leonardo, with an Ethernet shield and a Wireless Shield with another XRF module. The Ethernet shield connected the Arduino to a TP-LINK WR703N WIFI router loaded with openWRT with a 3G USB stick. The small router provides internet connection to the Arduino and to any other device inside the house via WIFI. The WR703N is a really awesome, small and hackable piece of hardware. But as I have already said, you will have to wait for the whole picture of the connection between the weather station and my home server, I want to focus on the radios and the protocol now.

Now that we have the hardware it’s time to think about the message. Ciseco promotes the use a a light-weigth protocol named, well, Lightweight Local Automation Protocol, or LLAP. You can read all about it in the LLAP Reference Guide in the openmicros.org wiki. The protocol defines two node types: controller and device; a message format formed by a start byte (‘a’), device identification (2 bytes) and a payload (9 bytes); and a communications protocol (address allocation, request/response pairs,…). The different “personalities” provided by Ciseco use this message protocol to report sensor values and they can even be configured remotely this way. But Ciseco also provides an Arduino LLAPSerial library so anyone can easily create LLAP devices using XRF radios or other products from the company that integrate a MUC.

Ciseco LLAP library for Arduino is OK, and it works, but it looks like a draft, something you can use to build upon it. So I decided to do just that. You can checkout my version of the LLAPSerial library for Arduino from Bitbucket. Initially I did a fork of Ciseco version but finally I decided to break the dependency with it because some features I added made it incompatible with the original one, although the protocol is 100% backwards compatible. The differences are summarized in the README file but here you have a quick-view:

  • Removed power management code (this library focuses on LLAP protocol and messaging)
  • Added support to use different Hardware and Software serial ports
  • Provided a unique overloaded sendMessage method that supports sending char/int/float messages
  • Provided a way to broadcast messages (see below) using special device ID ‘..’
  • Defined the “coordinator” node, which will always process all messages, regardless the destination
  • Disallow CHDEVID to coordinator nodes
  • Major renaming and refactoring (sorry)
  • Added doc comments
  • Address negotiation and persistence NEW!!

This sample code shows the use of the library to report data from a DHT22 temperature and humidity sensor using LLAP.


#include <LLAPSerial.h>
#include <DHT22.h>

#define DEVICE_ID "DI"
#define DHT_PIN 2

// DHT22 connections:
// Connect pin 1 (on the left) of the sensor to 3.3V
// Connect pin 2 of the sensor to whatever your DHT_PIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

DHT22 dht(DHT_PIN);
LLAPSerial LLAP(Serial);

void setup() {

   // This should match your radio baud rate
   Serial.begin(115200);

   // This device has a static ID
   LLAP.begin(DEVICE_ID);

}

void loop() {

   static unsigned long lastTime = millis();
   if (millis() - lastTime >= 10000) {

      lastTime = millis();

      DHT22_ERROR_t errorCode = dht.readData();
      if (errorCode == DHT_ERROR_NONE) {
         float t = dht.getTemperatureC();
         float h = dht.getHumidity();
         LLAP.sendMessage("HUM", h, 1);
         LLAP.sendMessage("TMP", t, 1);
      } else {
         LLAP.sendMessage("ERROR", (int) errorCode);
      }

   }

}

There are some things missing from the library, being the main one the address allocation feature the protocol describes (also missing from Ciseco’s implementation). I will try to add it soon. In the meantime feel free to use any of the two libraries and enjoy the simplicity of LLAP. The last version of the library supports address negotiation between the nodes and the coordinator following the guidelines at LLAP Reference Guide, including address persistence, so a node will keep its address after a reboot.

Counting events with Arduino and PCF8583

Hey!

I’ve been away for some time. It’s not that I had stopped tinkering, but work and laziness have kept me away from the blog. During these months I have been working mostly on a new weather station (yes, yet another weather station or YAWS). The project was a step forward in a lot of aspects, from carpentry to remote reporting hacking cheap chinese routers and 3G dongles, from new libraries for Arduino to a bidirectional HTTP to MQTT bridge in node.js…

The result has been kind of a fail… mostly due to improper casing, humidity has been a major enemy. Anyway there are quite a few aspects to talk about, so I’ll try to write a series of posts about different hardware and software components involved in the project.

Counting the wind and rain

Two of these components share the same interface: when an event happens a pulse is triggered. The anemometer is a cheap plastic model I bought from todoelectronica.com. It’s specifications state than a 10km/h wind correlates with 4 pulses per second, so it is a simple pulse counter.

Anemometer

Anemometer

The rain gauge is a little more tricky… I bought a wireless rain gauge at ebay but I really didn’t need the wireless feature, it was just a convenient model to hack. The sensor has a seesaw with two small compartments where rain drops fall when passing through the top hole. The seesaw has a small magnet in the middle. When the water weight moves the seesaw down the magnet closes a reed switch triggering the pulse. The water evacuates and the other compartment starts receiving the water.

Wireless Rain Gauge

Wireless Rain Gauge

I hacked the rain sensor disabling all the circuitry and soldering a couple of wires to the reed switch with a load resistor in series. By “disabling the circuitry” I mean cutting the lines to the switch to avoid spurious currents to create noise but leaving the circuit, so it fits nicely inside the sensor.

I decided to use a standard interface for the cables, a 3.5 stereo jack (a mono jack would have been enough but I didn’t have any around). They plug into the main board of the weather station and the signals go to the event counter pins of a couple of PCF8583.

The PCF8583 is very similar to the PCF8563 but it adds several nice features: hardware configurable I2C address with 2 different addresses available (you can throw 2 of these IC in your project without mush hassle), 240 bytes of free RAM, more alarm options and an event counter mode.

According to the datasheet, “The event counter mode is used to count pulses externally applied to the oscillator input (OSCO left open-circuit).”. The count is stored as BCD values in 3 registers. BCD stands for Binary-coded decimal, the most common implementation is to split a byte into 2 groups of 4 bits and use each group to represent a decimal number from 0 to 9. So, for instance, 37 would be encoded as “0011 0111”. Thus, 3 registers or 3 bytes allow a maximum of 1 million events. This IC is very convenient for any project where you want to remove the responsibility of counting events from your microprocessor, and it would have been a very good choice for my smartmeter pulse counter.

To easily access the IC features I have written an Arduino library for the PCF8586. The library is not complete, there are some methods to be implemented yet. But the core time and event counter methods are already there.

To library comes with a simple exemple of usage (I have to add more examples) but to use it as an event counter you will only have to write something like:


#include

// declare an instance of the library for IC at address 0xA0
// (A0 pin connected to ground)
PCF8583 counter(0xA0);

void setup {

    // configure serial link to debug
    Serial.begin(9600);

    // configure PCF8586 to event counter mode and reset counts
    counter.setMode(MODE_EVENT_COUNTER);
    counter.setCount(0);

}

void loop {

    // report the events every second
    Serial.println(counter.getCount());
    delay(1000);

}

Issues

There are a couple of issues to take into consideration.

First: the counter counts double. That’s it: for every pulse it looks like it counts the rising AND the falling edges so you end up with double the counts. I have not been able to find a reason for this, nor even in the datasheet. I have tested it with a controlled set up, cleaning the input with an RC filter and a Schmidt Trigger and it counts exactly double it should…

Second: the maximum external clock frequency in event counter mode is rated to 1MHz. In the real world of my projects noise is an issue with frequencies way bellow that mark, so I only accept sensible values depending on what I’m measure. For instance, the above anemometer sends 4 pulses per second for a 10km/h wind. Fortunately, where I live there are no hurricanes and I have not checked but I doubt that there have ever been gusts of more than 150km/h. That sets a maximum of 60Hz. So in my code I have a check to not trust any value over 60 counts per second.

Final note

Finally, there are some other libraries for the PCF8586, like this one by Ryan Mickfor Netduino or this other one by Eric Debill for Arduino, that are worth checking as a reference.

As always, any comment will be more than welcomed.

It’s nice to be back 🙂

Geiger Counter

My last project is a über-cool Geiger-Muller Counter.

My Geiger Counter

Final box, with a LCD showing the last average CPM every 6 secons and sending the info to the server every minute…

Hardware: Radio Hobby Store Geiger Counter Radiation DIY Kit (second edition)

Some weeks ago I suffered a radioactivity fever, so to speak. I backed the APOC Mini Radiation Detector at Kickstarter and also bought a Geiger Counter Radiation Detector DIY Kit from Radio Hobby Store at Ebay. The former has finished the funding with more than 11 times the pledged amount. The later arrived home some 10 days ago, so I just started playing with it.

Geiger Counter Radiation Detector DIY Kit by Radio Hobby Store

Geiger Counter Radiation Detector DIY Kit by Radio Hobby Store

The kit comes unassembled but every part is through hole and really easy to solder. The kit contains everything to get a basic Geiger Counter except for the SBM-20 Geiger-Muller tube, but those are easy to find at Ebay also and mine arrived just one day after the kit. Once assembled you get a Geiger counter that can be powered with 5V through USB or a terminal block and it beeps and flashes a LED every time a beta o gamma particle enters the tube… But, you also get a VCC and GND pins and an interrupt pin (labelled INT) to power and monitor the counts with your favourite controller. And that’s fun!

To build the kit follow the seller’s advice: take your time and enjoy. It has a bunch of parts but none is too hard to solder. It took me about an hour. The only problem I had was with IPA. IPA, or Isopropyl Alcohol (C3H7OH), is used to clean electronic boards and components. The people at Radio Hobby Store emphasize the use of IPA after soldering to wash any flux or any other potentially problematic residue since the board uses high voltage (~400V). Even thou my board was quite clean after the soldering I followed their advice.

It took me a couple of phone call and a one hour trip to get a bottle of IPA 99% in Barcelona… I’ve read you can find the in some drugstores but the one I was after had a a spray which I found very convenient. So I applied the IPA and is was a mess. I ended up with a cover of metal (?) dirt all over the board… It took me a while to clean it up again and check that nothing was desoldered or disconnected. I don’t know what happened but it was completely unexpected. My guess is that it had something to do with the type of solder I use (lead-free), but again I don’t know.

I need to know more about what IPA is useful for and how it actuates before trying it again. Alcohols might not be that dangerous but playing with chemicals requires a deeper understanding of what you are doing.

Anyway, after this trouble the board worked as it should. I calibrated the blue pot to get around 400V across the Geiger tube, switched it off, unplugged, installed the tube and plugged it again. Then, with an imaginary sound of drums, I switched it on and it began beeping! Yes!

Hardware: The Controller

I prototyped the counter with an Arduino Pro Mini and a Sparkfun Serial Enabled 16×2 LCD which uses simple serial commands to write characters on the LCD. Everything is 5V except for the Arduino but the LCD works with 3V3 TTL signals so no problem.

The first prototype was really easy to assemble. I had it working in less than half an hour, including a first version of the code to count and display the data on the LCD.

Geiger Counter Prototype with an Arduino Pro Mini

Geiger Counter Prototype with an Arduino Pro Mini

The first evolution was to substitute the Arduino Pro Mini with a bare ATmega328P, the very same micro but in a cheaper and bulkier package. I prototyped this second version in a breadboard adding the XBee. Now, the ATmega328P is 5V but the XBee is only 3V3. A TSC295033 linear voltage regulator lowers the voltage to 3V3 to power the radio and a diode and a pull-up resistor protect de DIN line. When the input is LOW the diode is transparent and the DIN pin of the radio sees the LOW and the resistor is dissipating ~10mW. When the input is HIGH (5V) the diode blocks the current and the resistor pulls up the line to 3V3.

I used a Zener in the first prototype and took the picture below before realising my mistake and replaced it with a 1N5819 Schottky diode. The Zener was a BZX85C 3V3, so it was permanently in avalanche breakdown. In fact you can use a Zener but in a different configuration, check Rob Faludi’s post about Xbee level shifting.

Level shifting is a great topic to learn basic stuff about electronics. Whenever there is a question on any forum about this there are tens of different answers. Just give a try to some of them!

The final prototype with a bare ATmega328P

The final prototype with a bare ATmega328P (note the fail: the diode in the DIN line of the XBee has to be a Schottky, not a Zener!)

Eagle schema

Eagle schema

This is the first project where I use this level shifting technique. I had used the simple resistor divider in other projects before (like the Rentalito) but the resistors slow down the signal and can be a problem when using higher baud rates. Also, my first idea was to use the XBee internal pull-ups for level shifting instead of an external one but finally I opted for the second option because the 30K pull-up was too high and resulted in a less than 3V HIGH value in the DIN input. A 1K2 external resistor solved this problem and removed the dependency on configuration.

Finally I moved everything to a stripboard. To design the stripboard I used VeeCAD, a stripboard editor, and it really helped me. There was little room inside the box and my first design was too big. It would have been a nightmare to erase and redraw everything several times in paper but in the computer everything was simpler and I could play with different designs until I found the one that was both clean and small. The free version is good enough to design anything on a stripboard but the commercial version (26.26 USD) adds some goodies that can make the difference: color, net tracing and the ability to place elements diagonally.

But, I made a mistake. I crossed the RX and TX lines between the controller and the FTDI header and I didn’t realize it until I tried to reprogram the chip. Anyway it was easy to fix and in the layout below, generated with VeeCAD, this mistake has been fixed.

Stripboard layout (powered by VeeCAD)

Stripboard layout (capture from VeeCAD). The RX and TX lines between the ATmega328P and the FTDI header are right

The real thing, note the fix for the RX/TX mistake:

The real thing

The controler board with the ATmega328P and the XBee. Note the green cable I used to fix the RX/TX error.

Hardware: The LCD

Sparkfun’s Serial LCD is really easy to use, but I wanted to give a chance to some cheap LCDs and I2C serial boards I had recently bought at Ebay. I had already done some tests the night I received them. The seller provides a library and some sample code but I was not able to make it work and I quitted to go to bed.

So this was a second chance to make the think work. The boards I had bought to drive the LCD were I2C serial interface boards (just search for “IIC/I2C/TWI/SP​​I Serial Interface Board Module” at Ebay). These boards use a PCF8574, an 8 bit I/O expander with I2C interface, basically it lets you drive the LCD with just 2 wires for power and ground and 2 more for data (SDA) and clock (SCL).

IIC/I2C/TWI/SP​​I Serial Interface Board Module

IIC/I2C/TWI/SP​​I Serial Interface Board Module bought at Ebay. The solder job could have been better…

None of the libraries for Arduino I tested worked with the board. After googling a bit I found a thread on the Arduino Forum where a user (Riva, thanks!) had found out that the connections were not what the library he was using expected. So I grabbed the tester, put it in continuity mode, and checked what connections led where. The library I wanted to use (NewLiquidCrystal) has a constructor where you can explicitly define the pins so I just instantiated my LCD object with the right pin assignments and voilà.

The initialization code for the LCD is as follows:

// Thanks to Riva for pointing out the wrong pin order
// http://arduino.cc/forum/index.php?topic=164722.0
// 0 -> RS
// 1 -> RW
// 2 -> EN
// 3 -> LED
// 4 -> D4
// 5 -> D5
// 6 -> D6
// 7 -> D7
//
// Constructor with backlight control
// LiquidCrystal_I2C(uint8_t lcd_Addr, uint8_t En, uint8_t Rw, uint8_t Rs,.
//                  uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7,
//                  uint8_t backlighPin, t_backlighPol pol);

LiquidCrystal_I2C lcd(0x20, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

Hardware: The Box

I happened to have the perfect box for this project. It is transparent, elegant and everything fits inside like if it was designed for the project. The only trouble was finding a way to place the cables so they do not cover the tube or the radio antennae.

Everything fits nicely in the box

Everything fits nicely in the box

Software

The code is very simple. There are only a couple of things worth noticing: the LCD connection mentioned before and the ring buffer implemented to store partial readings. The reason for the ring buffer is that I wanted to update the display more often than once every minute with a “moving sum” of counts.

Basically there are 10 cells that store partial counts. Every 6 seconds the code stores the current pulses count value in a cell of the ring, overwriting the previous value. So the sum of the cells values is the count value for the last 60 seconds. To avoid having to sum all the cells on every update, the sum gets updated before pushing the new value to the cell by subtracting the current value for that cell and adding the new one.

// calculate the moving sum of counts
cpm = cpm - ring[pointer] + pulses;

// store the current period value
ring[pointer] = pulses;

// reset the interrupt counter
pulses = 0;

// move the pointer to the next position in the ring
pointer = (pointer + 1) % UPDATES_PER_PERIOD;

That’s it. There isn’t much more to say. As always, the code, schematics and other documentation, are available at github.

One last thing about the software: I have started using Ino Toolkit for this project. If you have it installed you can run “ino build” from the code folder to get the binaries. I don’t like the Arduino IDE: it is very feature limited, the editor is clumsy and the whole thing is too heavy. I’ve always used different command line tools like ed.am Arduino Makefile. My first impressions are good, it has better library discovery capabilities but I missed the “make size” command to know how much free space left you have to code more features…

Testing it!

I was going to add some theory explaining the different types of radiation, how a Geiger-Muller tube works and some reference levels but there are plenty of pages on the internet about the subject and I will not add anything new. Instead I can recommend you to read this tutorial that the people from Cooking Hacks have put together for their Arduino geiger counter shield.

There are a number of natural radioactivity sources. The first of them being the background radiation which you will always get. With my detector this background radiation averages 26 CPM over long periods (more than one day). Then you have some commonly available sources like smoke alarms, some paint used in pottery, luminous displays from old watches or compasses, gas mantles or anything with potassium, like some low-sodium kitchen salt or even bananas.

LoSalt

Low sodium salt (66% of potassium salt)

This low-sodium salt is the easiest to find in Barcelona (apart from bananas) so I just went to the supermarket and bought a tin of LoSalt “The Original” (sic). Then I poured some salt on a self-sealing bag and put it over the Geiger-Muller tube. In any given sample, every 8547 atoms of potassium there is one isotope of 40K, which is radioactive. Potassium 40 is a very interesting isotope, it represents the largest source of radioactivity in human body and has a half-life of 1,250·109 years (if you have a sample of 40K, after one thousand million years only half of its atoms will have gone through a radioactive decay). The counts with the potassium salt bag near the tube raised to almost 139 CPM on average over a 10 minutes record. That is more than 5 times the background noise…

The Geiger counter with a sample of LoSalt

The Geiger counter with a sample of LoSalt. The display reads 139 CPM.

To get a higher count sample I went to Ebay and bought one Thorium Latern Mantle or Gas Mantle. Funny enough, even though these mantles were pretty common here 20 years ago I had to go to an USA supplier to get one. These mantles are impregnated with thorium dioxide to produce a brighter white light. They were retired, mainly because the safety concerns for people involved in the manufacture. Thorium (232Th) is a radioactive element, part of the Thorium decay chain which undergoes several alpha and beta decays until it stabilizes as Lead (208Pb). The test with the Thorium Mantle was impressive. The seller said the set of mantles he had read between 1100 and 2100 CPM. Mine read an average of 1662 CPM over a 5 minutes test but wrapping it around the tube I got up to 1903 CPM.

The Geiger counter with a Thorium Gas Mantle covering it

The Geiger counter with a Thorium Gas Mantle covering it

Thorium gas mantle reading

In the picture the display reads 1823 CPM, it peaked 1903 CPM.

I repeated the tests isolating the gas mantle (it was already inside a plastic bag) from the counter with a paper first and then with a couple of layers of aluminium foil. The experiment set up was not quite right because the readings with the paper were about a 33% lower than without it and that makes no sense since the paper would have blocked only alpha radiation and the tube is sensitive to beta and gamma. Nevertheless I think it is worth it to post here the results. In the graphic below, the first bump is the Potassium salt sample, the second is the thorium gas mantle only with the plastic cover, then with the paper and then with the aluminium foil.


The first bump is due to a sample of KCl, the second, third and forth bumps are a Thorium Gas Mantle with plastic, paper and aluminium foil shielding.

Of course, the sensor is also reporting to my home MQTT network and then the readings are sent to Cosm Xively in almost real-time, here you have the last 24 hours of readings:

Weather Station

Keeping on registering data from different sensors my next project has been the all-time favourite weather station. This time I wanted to build an 100% autonomous outdoor sensor.

To achieve this goal I started playing with a LiPo battery and a solar panel. The Arduino Fio looked like the perfect out-of-the-box platform to be the center of the project. It’s a ATmega328P (the same micro as the UNO), has a connection for a LiPo battery, a charge circuit based on the MAX1555 (with an USB connector) and a socket for an XBee radio module. So I just really had to wire things up and work on the code to reduce the power consumption to its minimum.

Hardware

This first version of the weather station uses two sensors: a DHT22 and a BMP085. The former is a temperature and humidity sensor that uses a custom one wire digital protocol. The later is a barometric pressure sensor with I2C protocol. Both sensors are 3V3 compatible (like the Fio) and very easy to set up. Adafruit has tutorials and libraries for the two of them here and here.

Weather Station Schema

The schema is so simple I thought it could be a good opportunity to give Fritzing a try. The result could be better. You have to imagine that the CHG and ON holes are connected to the input of the two voltage dividers on the right to check the voltage from the solar panel and the LiPo battery. The other connector by the on/off switch is there to provide an external on/off switch in the future.

Here you have a picture of the sensor. I think I haven’t said this before: I prefer stripboards (veroboards) over perfboards because they are very suitable for rapid development and the final layout is cleaner.

Weather Station sensor

Power management

The main issue with this sensor is power management. The goal was to have an autonomous sensor that will not require battery replacements. Given that Sun is a natural resource freely available most days here in Barcelona that shouldn’t be a problem.

To provide power I chose the Medium 6V 2W solar panel from Adafruit. The Fio charging voltage requirement goes from 3.7V to 7V and this panel fits quite well in that range. The only drawback is the 3.5×1.3 jack connector – a mini USB would have been a perfect match. No worries, the Fio provides a place holder to connect a custom charging source.

And to store energy I’m using a Lithium-Polymer battery rated 3.7V 850mAh. That’s enough power to make it last for weeks applying simple sleeping strategies. When in power down mode the circuitry consumes a negligible amount of energy (not measurable by my instruments, something around 10 uA?). The problem arises when it wakes up.

The DHT22 sensor is a little picky. It requires a warm-up lapse before reading anything and you cannot perform two readings in a row without another delay in between. After some testing I found out that a 2 seconds warm-up time after wake-up produced constant reliable results. Besides, the reading itself is also time (and power) consuming. At the end every time the Arduino wakes up it waits 2 seconds for the DHT22 to warm-up and 2 more seconds to get the reading from it. The reading from the BMP085 is fast (in comparison) and then sending the data by radio produces a burst of ~55mA for 10 millisecs.

State mA ms/event events/h ms/h mA (avg)
Arduino (and XBee) sleeping ~0 - - 3474488 ~0
Warm-up 10 2000 60 120000 0.333
DHT22 reading 12.5 2000 60 120000 0.417
BMP085 reading 10 10 60 600 0.002
XBee awake 25 80 60 4800 0.033
XBee transmitting 54 10 12 120 0.002

The average is ~0.8mA which means around 44 days for a 850mAh battery. Note than 93% of the power consumption is due to the DHT22 reading process. So here there is a big source for power management improvement, but… don’t optimize until you need it.

Since I still had to buy the solar panel and while I was waiting for it to arrive, I powered the sensor and it started transmitting data. I carried the experiment for some weeks until the voltage from the battery fell below 3300mV and the Fio stopped working. It lasted for 37 days, quite accurate.

Then I plugged the solar panel and (after some trouble shooting) it has never gone below 4200mV except twice where it fell well below 3700mV for a short time. So apparently the current set up is more than good enough. I’m even slightly concerned about continuously charging the LiPo battery but the MAX1555 in the Fio should take care of that.

Software

The software is pretty straight forward. I’m using Ben Adams’ DHT22 library and Adafruit’s BMP085 library to interface the sensors. Like in the Smartmeter Pulse Counter project, I’m using Rocket Scream’s Low Power library to put the Fio to sleep. It’s a very useful one-liner to turn ADC and BOD off and put the Arduino to sleep for two seconds (SLEEP_INTERVAL constant). The every 28 (MEASURE_EVERY constant) intervals it gets a reading from the sensors. Since the reading takes 4 seconds that’s roughly one reading per minute. Every 5 (SEND_EVERY constant) measures it awakes the Xbee and sends the average for all the magnitudes.

void loop() {
    ++interval;
    if (interval % MEASURE_EVERY == 0) {
        readAll();
        interval = 0;
        ++measures;
        if (measures % SEND_EVERY == 0) {
            sendAll();
            resetAll();
            measures = 0;
        }
    }
    LowPower.powerDown(SLEEP_INTERVAL, ADC_OFF, BOD_OFF);
}

The data for each magnitude is stored in a structure with 4 values: maximum and minimum values, sum of all values and number of readings so far. Then, when the code is ready to send the data it subtracts the maximum and minimum values from the sum and averages over the rest of values. This way it gets rid of inconsistent readings and the final value is smoother.

The voltage readings for the solar panel and the battery al calculated based on the actual value of the resistors in each voltage divider and they are expressed as constants in the code (BATT_VOLTAGE_FACTOR and PANEL_VOLTAGE_FACTOR).

Finally, I’ve added some code from Tinker London to get the values from the interval thermometer and voltmeter of the ATmega328.

All the code, along with the Fritzing schema and the XBee configuration file is available in Github.

Boxing it

The sensor is housed in a box to prevent direct Sun exposure. It’s common to use a Stevenson Screen as a shelter for a weather station. The “professional” screens are waaaay too expensive (in the 400€ and above range). There are kits online (most notably this one) to build your own shelter or you can always build one buying the parts from the carpenter or repurposing other items. A good source to get ideas and instructions is this site aimed to schools.

I built mine from scratch. It has slats on three sides (the other is attached to the building facade) and holes on the bottom to ease the air flow inside the box. It doesn’t have double roof or chimney since I have glued the solar panel to the top with a methacrylate stand to make it perpendicular to the winter sun. The solar panel angle was a hard decision but since there is a maximum of power I can store I decided it made more sense to get the maximum from the Sun in that not-so-bright days of winter. The perpendicular of the solar panel points SSW, almost 30 degrees above the horizon, to the winter afternoon Sun…

You will have to let me not showing you any pictures of the final box… it fulfils the requirements but it’s ugly as slapping a father with a wet sock (local quote). Definitely  carpentry is not for me.

To do

It would be interesting to add some sort of power monitoring to the solar panel. Right now I only get voltage readings but most of the time the panel is in nearly open circuit mode. Being able of actually get readings for the power it is providing to the charging circuit (in mW) will provide a more accurate view of the and maybe increase the performance or under-scale the solution (maybe a smaller battery or solar panel would do the job).

I’m also planning to add an anemometer to measure wind speed and a rain gauge. The readings from these two sensors will not be very significant, since the whole building could block the rain or the wind or even create twisted flows of wind around it that will fool the sensor but it will be fun nonetheless. If the battery, backed by the solar panel, has enough juice to permanently power the Arduino (that is, not in sleep mode) I could even get readings for maximum speed of wind gusts, if not I might use a binary counter IC or two (74HC590 will be perfect) to store the counts from the anemometer and get the readings from the Arduino once a minute, avoiding the use of interrupts in the code.

Finally, the data from the sensor is public and available in Cosm.com.

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