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…

Choosing the sensor

So I decided to replace it with something more trustful. My first plan was to add a PIR sensor but I started having sensitivity problems again. Then I just thought: well, if all I want is to get a notification when someone’s at the door why not checking when it opens? And I started playing with a magnetic switch, a reed switch.

The switch is very easy to use but it’s veeery delicate. I broke two of them trying to bend the leads to the shape I needed. I’ve used the cristal ones but I’ve also bought some insulated ones for the future, they don’t look as fragile. They are very simple switches: when exposed to a magnetic field they close and when the magnetic field is removed they open. So all you need is one of these reed switches and a magnet and you are good to go.

The set up could have been as simple as that. But I added some requirements: it’s got to be small, I didn’t want to use a micro-controller for such a simple thing and I wanted it to notify the server whenever the door gets opened OR closed, and every 5 minutes if no events.

Since my previous project and the gateway I already had in place was based on an Xbee radio that decision was easy. The radio just has to wake every 5 minutes or based on an event (that cyclic sleep plus pin awake modes, or SM5). Then it just has to report the status of a digital pin and the battery status. The only trick here is to awake the radio when the switch gets closed AND when it gets open…

Clear edge detection

Edge detection is a topic by itself. There are lots of information and options. Off course I could have used an uC with an interrupt pin but that was out by requirement. Maybe the simpler solution is using a XOR gate with two input lines with the same signal, only slightly delayed in one of them (a series of NOT gates would do). And then there are different solutions based on latches, multivibrators, monostables,…

My final choice was a 74HC221, a dual monostable multivibrator with schmitt trigger input. It features a dual edge detector with configurable output pulse length. Each detector has two input lines A and B for positive and negative edge detection. So you only need one of these chips to detect rising and falling edges of the same signal. Nice.

The circuit includes a RC filter for the input signal (that with the schmidt trigger in the input lines of the 74HC221 will remove bouncing problems) and a couple of 2222 transistors to “merge” the output signals from the two monostables. And that’s pretty much it.

Door switch prototype

Door switch prototype

Door switch schematic

Door switch schematic

The resistor (1MOhm) and capacitor (100nF) combination produces a 70ms pulse aprox. which is enough to wake up the radio and send the information. The radio is set to SM=5 mode (cyclic sleep, pin wake) with SP=7E4, SN=6 (aprox 2 minutes sleep cycle) ST=32 (50ms time before sleep) and SO=6 (sleep for the whole 2 minutes). The sleep cycle is slightly above 2 minutes (121.2 seconds) but the internal clock is never accurate and it cannot account for the time it’s awake so I always configure the Xbee timings by trial and error. The sample rate is 1 second (IR=3E8) and it is reporting DIO12 and VCC (P2=3 and V+=FFFF). Pull-ups for DIO12 and DTR (Sleep request pin) have been disabled (PR=1BBF).

Run on batteries for months

The final issue is the power supply. Since I wanted the sensor to be as small as possible I thought about using a CR2032 coin cell. Their capacity is about 230mAh and my tests and calculations resulted in a life time of 415 days. The problem is that I never took into consideration the drain current condition of the battery until I started investigating the continuous drop in the battery voltage the sensor reported during the first hours in production environment.

A good resource about stressed coined cells is “High pulse drain impact on CR2032 coin cell battery capacity” (PDF) study by Kjartan Furset and Peter Hoffman. There are multiple factors that determine what e authors define as the “corrected battery capacity”: the peak current, the length of the pulse, the periodicity or the recovery-time. A battery that was designed to have a drain battery of less than 1mA won’t perform as expected with peaks of up to 50mA. A patch to the sensor could be adding a large capacitor across the battery to help it with the current peaks. But I decided to not doing anything just yet and wait and see.

The graph for the first 20 days showed a drop of about 10mV per day average. The Xbee minimum operational voltage is 2100mV so it looked like the sensor won’t last longer than maybe 2 more months instead of the original 13 I had calculated. But then the voltage drop ceased and now, after 2 months duty time, it is more or less stabilized around 2650mV. I cannot tell how much longer it will survive but this has become a new experiment. My plan is to let the battery die and then add a 1000uF capacitor and a fresh battery and compare the lifetime of both batteries.

Forwarding the messages

The sensor works very well. Every time the door opens or closes the server gets the notification through the Xbee2MQTT gateway. An “alarm” daemon processes the messages, waits a second and sends a NMA notification to my Android phone with a picture from the IP camera. The delay is there to get a reliable image of who is at the door, otherwise I would only get pictures of opening doors when someone gets in. The whole process takes no longer than 5 seconds depending on the lag time to my phone. The only issue I have noticed is that sometimes there is an echo: the door opens and closes and on the next cyclic awake the radio reports again the open-close event… the result is a false positive. I have no explanation for it yet but I can live with it.

Here you have a couple of pictures from the final sensor and how I have placed over the door, using the metal door shield to place the magnet that operates the reed switch.

Door switch sensor final

Door switch sensor final

Door switch sensor placement over the door

Door switch sensor placement over the door

CC BY-SA 4.0 Door sensor by Tinkerman is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

21 thoughts on “Door sensor

  1. the5thbeatle

    I am working on my home automation project and am building a door sensor like yours. I need my xbee to hibernate as I want to have it running from battery. I will be using a reed sensor and I definitely want to use some sort of logic circuit to trigger the sleep pin opposed to using an MCU, but I have been stuck on how to build it. I see you are using 74HC221N (I bought the CD74HC123E which looks to be a comparable chip). Can you explain edge detection to me?

    Alternatively, I understand the usage of a monostable 555 timer circuit and how that would work to wake the xbee up long enough to transmit. I am just not understanding the usage of the multivibrator chip and why I need duel edge detection.

    Reply
    1. xose Post author

      Hi the5thbeatle, thanks for visiting my blog!

      Yes, the 74123 and the 74221 are almost identical. The only difference I see is that the 74123 is a retriggerable monostable which means that you might have longer pulses if the edges come too close, but that is not something to worry about in our practical case.

      Edge detection is an interesting topic and I am not an expert by any means, hardly an amateur. Basically you need a pulse, triggered by some event, to wake your XBee long enough for it to send a I/O packet, say some tens of milliseconds. In my case I wanted that *event* to be both the reed switch closing and opening, so I needed a way to detect rising and falling edges of the switch signal. The 123 and 221 ICs are dual monostables, which means you can trigger a pulse based on the combined status of A and B pins and you can actually control the pulse width with an RC-like circuitry, you don’t need a 555 or any other IC to control the pulse width.

      The input for the ICs is !A&B (not A and B). So if you want to detect a rising edge you set pin A to LOW and pin B attached to your signal, !A will be always HIGH and !A&B will be HIGH only when B goes HIGH (rising edge), that will trigger the pulse. If you want a falling edge you have to tie pin A to you signal and pin B to HIGH. When your signal goes LOW !A&B will go HIGH. Since those ICs are dual, you can have rising and falling edge detection each in one half of the chip. Then you only have to merge (OR) the signals and feed the output to the DTR line of the XBee. I did the OR gate with a couple of 2N2222 transistors and a pull-down resistor.

      I think I have not written anything too wrong. That’s how I understand it and it has worked for me. Hope it helps.

      Reply
  2. Ricardo

    Hi Xose,

    Firstly, thanks for sharing your interesting project, I want to make a similar project but at the moment it will not use any server, it will be simpler. It will have only one AT end device radio to manage a reed sensor, and one API coordinator radio connected to its USB adapter and a Processing Java program that communicates with the API coordinator radio via USB, and I have some questions.

    1. I can understand the report of the status of a DIGITAL pin, but HOW can you obtain the battery status? Can you explain it to me in detail. And will it be each 5 minutes or 2 minutes?

    2. What kind of reed switch contact you used, I think it will be normally closed NC?

    3. Can you explain to me why the DTR pin is !DTR (NOT ADR)?

    Thanks in advance,

    Ricardo

    Reply
    1. xose Post author

      Hi Ricardo

      In the documentation for the Xbee module you can read:

      Voltage Supply Monitoring. The voltage supply threshold is set with the V+ command. If the measured supply voltage falls below or equal to this threshold, the supply voltage will be included in the IO sample set. V+ is set to 0 by default (do not include the supply voltage). Scale mV units by 1024/1200 to convert to internal units. For example, for a 2700mV threshold enter 0x900.

      So you just have to set this to FFFF (V+=FFFF, the highest possible value) to make the xbee report the battery status with every IO sample, always.

      The reed switch I’m using is a NO one, the most basic one. But when the door is closed (normal state) the magnet is close to the switch so it is a NC configuration. Remember though that I’m reporting when it opens and when it closes so I really don’t care.

      I don’t understand your third question about the DTR pin…

      Reply
  3. Ricardo

    Hi Xose,

    Can you explain to me how it obtain the battery status? and what type of reed switch did you use NO or NC?

    Thanks in advance,

    Ricardo

    Reply
  4. Ricardo

    Hi Xose,

    Thank you so much for your answer.

    About the question of DTR pin, I wonder why this pin is negative in the XBEE schematic.

    Do you know what are the differences between your circuit and a simpler circuit like a switch de-bouncing circuit (RC filter) and a non-inverter CMOS Schmith Trigger, i.e., I understand that the sleeping and wake times is configured in the Xbee and it manages these times when it detects a change in the DTR pin (pin 9) ?maybe am I wrong?

    I also want to know if you resolve the issue that sometimes there is an echo in your system?

    Thanks in advance,

    Ricardo

    Reply
  5. Ricardo

    Hi Xose,

    Thank you so much for your answer.

    About the question of DTR pin, I wonder if this pin is inverted by the manufacturer, like I see in the XBEE schematic.

    I would also want to know if you resolve the issue that sometimes there is an echo in your system?

    Thanks in advance,

    Ricardo

    Reply
  6. Ricardo

    Hi Xose,

    About the question of DTR pin, I wonder if this pin is inverted by the manufacturer, like I see in the XBEE schematic.

    I would also want to know if you resolve the issue that sometimes there is an echo in your system?

    Thanks in advance,

    Ricardo

    Reply
    1. xose Post author

      I see what you mean with the DTR pin. I really have to give it a second look because it really looks like it should be the other way round. Let me check it.
      No, I did not solve the echo problem. It still happens. It’s like I’m receiving the message when the door opens (using the wake up pin) AND then again when the radios awakes using the cycle sleeping feature… No perfect but hardly annoying.

      Reply
  7. Ricardo

    Hi Xose,

    I didn’t find in the web more information about disabling the internal pull-up resistors of the input lines, I wonder how you determine the value PR=1BBF for DIO12 and DTR?. I only found this reference:

    Pull-up Resistor. Set/read the bit field that configures the internal pull-up resistor status for the I/O lines. “1” specifies the pull-up resistor is enabled. “0” specifies no pullup.(30k pull-up resistors) . Parameter Range: 0 – 0x3FFF. Default: 0 – 0x1FFF

    What parameter I should set to disabled the pull-up resistor of DIO1 (pin 19), can you tell me a link for reference about disabling the internal pull-up resistors?

    Thanks in advance.

    Reply
  8. Ricardo

    Hi Xose,

    I didn’t find in the web more information about disabling the internal pull-up resistors of the input lines, can you tell me how you determine the value PR=1BBF for DIO12 and DTR?.

    I only found this reference:

    Pull-up Resistor. Set/read the bit field that configures the internal pull-up resistor status for the I/O lines. “1” specifies the pull-up resistor is enabled. “0” specifies no pullup.(30k pull-up resistors) . Parameter Range: 0 – 0x3FFF. Default: 0 – 0x1FFF

    What parameter I should set to disabled the pull-up resistor of DIO1 (pin 19), can you tell me a link for reference about disabling the internal pull-up resistors?

    Thanks in advance.

    Reply
    1. xose Post author

      Hi Ricardo

      Sorry for the delay in answering. I’ve been quite busy lately at work…

      Anyway, you can check how to configure the pull-ups in the Product Manual you can download here: http://www.digi.com/products/wireless-wired-embedded-solutions/zigbee-rf-modules/zigbee-mesh-module/xbee-zb-module#docs. In page 137 you can see that the PR value is a 14 bit mask that defaults to 0x01FFF = 01 1111 1111 1111 (all pull-ups enabled except for CTS line). So if you want to disable pull-ups for DIO12 (bit 10) and DTR (bit 6) your mask is 01 1011 1011 1111 = 0x1BBF. Be careful: the least significant bit is bit 0, not 1. DIO1 is bit 3.

      Reply
  9. Ricardo

    Hi Xose,

    I have another question, you assign: SO=6 (sleep for the whole 2 minutes), is it correct?
    because the XBee manual says:

    Sleep Options. Configure options for sleep. Unused option bits should be set to 0.
    Sleep options include:
    0x02 – Always wake for ST time
    0x04 – Sleep entire SN * SP time

    Can you explain me that?

    Thanks in advance

    Reply
    1. xose Post author

      Hi

      Yes, I’m using SO=6 (2+4) because I want the radio to sleep the full SN*SP time without waking up to check incoming messages since the communication is only in one direction.
      When I first configured the radio I wanted to control the sleep and wake times to the millisecond to ensure I can reliable send messages every (say) 300 seconds.
      The 0x04 bit in the SO option controls the extended sleep period and the 0x02 bit should control the wake up period but it just doesn’t work like that.

      As the manual says: “In cyclic sleep mode (SM=4 or 5), if serial or RF data is received, the module will start a sleep timer (time until sleep). Any data received serially or over the RF link will restart the timer. The sleep timer value is settable with the ST command.” So the actual wake up time depends on when you end finishing sending serial data to the radio and that will depend on when you start, how fast you send it (the baudrate) and how much data you send…

      Reply
  10. Ricardo

    Hi Xose,

    Now my prototype is working OK, it is a network of 5 XBee radios: 1 coordinator, 2 routers (working as actuators in both directions, always with power supply) and 2 end devices with Sleep/Wake (working as sensors with batteries) that monitor reed switches. The 2 end devices are configured exactly as yours.

    But, I detected a “problem”, for example, while all is working OK and I disconnect the batteries of the end devices for a while and again connect the batteries these can’t be “synchronized” or detected by the coordinator, it’s annoying. Finally I can get them synchronize with the coordinator openning and closing the reed switches, but I supposed when these switches are installed on the doors I can’t go to open and close the doors to syncronized the end devices.

    So, the question is, how is the correct way for the coordinator to detect the end devices in the event their batteries run off and again they have to work with new batteries?

    Thanks in advance.

    Reply
    1. xose Post author

      Hi

      That’s a hard problem to solve. I’ve hit myself that problem sometimes but I don’t have a 100% success recipe for it. What I normally do is to allow the end device some time to join the coordinator radio before going to sleep the first time but that requires a MCU controlling the process. I don’t know if there is a configuration option for that. The other advice is: be patient, maybe it is just taking longer for the radio to join the network…

      Reply
  11. Pingback: RFM69 WIFI Gateway | Tinkerman

  12. Pingback: Moteino Door Monitor - Tinkerman

Leave a Reply