Sunday, September 12, 2010

Pantry light switch using a PIR module

Practically all the dry goods in our kitchen are stored in the pantry and we access this room several times a day. My bugbear has been that everyone who uses it, including myself, forgets to turn off the light rather frequently. Something about this tiny room that makes people run in and out less than a minute later and forget to flip the switch. Must the duration of stay inside. Or maybe not, since I also do fail to turn the garage storeroom lights off even if I've been in there for ten minutes. Yeah, must be the genes.

Been meaning to install a motion detector to address this problem but couldn't find a readily available PIR in the market. Went to a home depot months ago to buy a consumer security gadget that employed PIR and was going to just hack it. Problem is that when I asked them to test if it's working the dang model didn't. Not a single unit of those tried! What the bleep indeed.

Well, fortunately I found an online supplier who had reasonable prices. The module is China-made obviously, but right now I'll take anything over nothing. For details and specs of the passive infrared (PIR) module refer to my previous blog entry.

I could've used the module without employing a microcontroller. A transistor and a relay would've been sufficient to switch on the pantry's compact fluorescent lamp (CFL). But that's crude and not at all very user friendly. What happens when the person is still inside and isn't detected by the PIR? Darkness descends without warning. Therefore, there is a need to provide an alert of some sort that it'll be lights out in a while.

I would've wanted a visual warning, specifically a PWM controlled lamp that gradually dims. The decreasing light level would be a gentle way of informing the user. But such a circuit is more complicated and I certainly can't dim a CFL. LED high-lumen lighting would be nice, but cost is prohibitive and the drive circuitry complex.

So I settled for an audible alert, giving a graduated level of warning as the moment of lamp switch-off approaches. I arbitrarily set the start of warning five seconds before switch-off, with a 10ms beep every second for four seconds. On the last second, a 10ms beep is issued every 200ms for a total of five beeps. The beeps are generated by a small sonalert buzzer but at 10ms they're so short that they sound more like clicks than beeps. My design criterion on this is that the sound level and type should be informative but unobstrusive to those outside the room, so the clicks are on the money.

The MCU's job is simply to monitor the PIR module output and switch the CFL accordingly. When PIR output goes high the MCU immediately switches on the CFL, and when it goes low the MCU starts issuing the alert sequence, after which it turns off the lamp.

However, since this particular module has an initialization ritual it goes through upon power up, the MCU must also be programmed to disregard the output during this period. Well, the MCU doesn't really have to, but for now I've decided that it should ignore the two PIR output high during initialization since energy is wasted when the CFL on. On the other hand, there is some utility to providing feedback that the PIR is in initialization mode. This can be implemented using the buzzer. A distinct pattern of beeps can be continuously emitted during this period.

In anticipation of future PIR module malfunction and of those times when the user would want to keep the light on continuously--i.e., override the sensor--I designed the circuit with a switch to allow the user to turn off auto mode. When in manual mode the CFL will be on regardless of PIR output. The manual override is a surface mount rocker switch rated at 10A @250VAC. Only a feeble current (about half a milliamp DC) will be running through so it'll be dry switching. I'm not worried.

Since the MCU won't be doing much at all and will only need a small amount of code, I decided to use a baseline PIC, i.e., a model from the 10F series. The smallest (in Flash memory) chip I have in stock is the PIC10F202. It has four I/O pins which is exactly the number of pins I need.

Powering the CFL is via a miniature socketed relay with a 12VDC coil. The Telemecanique RXM2AB2JD is a DPDT switch with contacts rated at 12A @250VAC. As a bonus it has a green LED indicator which is on when the coil is energized. It even has a button which the user can push to momentarily close/open the NO/NC contacts and a mechanical lever to latch them. Love its smart look as well. Thumbs up to this model.

To serve as a troubleshooting aid I've added an LED which is switched on by a transistor whenever PIR output is high. The MOSFET is controlled directly by the PIR.

Powering the control circuitry is a generic wall cube which has no markings on it. Thankfully this unit isn't one of those whose casing is glued together. It has two screws which allows it to be opened up. As the schematic below shows it has a transformer, bridge rectifier made up of four diodes (can't make out the last digit of any of the 1N400x) and a filter capacitor. Output of the adapter is 19VDC, no load.

A LM7812 provides a regulated 12VDC. Although not strictly necessary given the current draw of the circuit, a clip-on anodized aluminum heat sink has been installed on this TO-220 as a precaution. To preclude having too high a voltage headroom, the 78L05 regulator's input is drawn from the output of the LM7812. This reduces the dissipation of the 5VDC regulator.

Here are the schematic diagrams and legend to the reference designations.

The 10F series of PICs has no interrupt capability and only a 2 level stack for subroutine calls. Pretty spartan indeed, but quite adequate for simple undemanding circuit requirements like this one. I've used the 10F202 for a number of circuits but something I've not learned or already forgotten manage to trip me up. Pretty vexing really. While prototyping I used GP2 as the I/O for the sonalert buzzer. Well, it didn't work! I went over the firmware and it looked good. Took me a long time poring over the datasheet for me to finally discover that GP2 is by default an input pin even if the TRISGPIO2 bit has been correctly set as output. The fact is the TRISIO register has the lowest priority in determining the status of this pin. OSCCAL register FOSC4 bit has the highest priority followed by OPTION register TOCS bit. No problem with FOSC4 since it is upon power up set to zero which means it hands off this pin to other functions. The problem lies with TOCS. It's set to 1 upon any type of reset including power on. And that means the pin is in high impedance mode waiting for a signal. With TOCS set, Timer0 is in counter mode and increments upon a level change (edge trigger) on the GP2 pin. So in order to use this pin as a general I/O TOCS has to be cleared. The 10F202 is practically the most basic MCU in Microchip's line but I have yet to master it.

In the end I moved the buzzer to GP1 and used GP2 as an input to sense the status of the auto/manual switch. GP3 is input-only and is used to monitor PIR output. Note that the PIR module works at 3.3VDC and its output high can only reach a maximum of this value. With a VDD of 5V a Schmitt trigger input on the MCU won't be able to detect the PIR high since the minimum requirement for a level high is 80% of VDD, or 4V. Fortunately, when the 10F202 pins are configured as general purpose inputs they are all TTL which has a minimum requirement of only 2.0V to be considered as high. Not so in other cases. For instance when TOCS bit = 1, GP2 becomes a Schmitt trigger input for Timer0 counter. Thus, if we feed the PIR output to this pin, Timer0 would never increment. What the PIR outputs as high would be considered a valid high only if MCU VDD drops to 4.1VDC or less.

Firmware consists mainly of a series of polling loops. PIR output is continually monitored while the manual switch is monitored continually only after PIR initialization is complete. When switch SW1 is sensed to be in manual and as long as it is in manual position, PIR is no longer monitored. When SW1 is flipped back to auto position then PIR monitoring resumes.

In auto mode and after PIR initialization has been detected to be over, when PIR output goes high, Q2 is immediately turned on which then switches REL on and hence LOAD. When PIR output goes low, the pattern of beeps (as described above) is issued. Five seconds later LOAD is switched off. If PIR output goes high during this five-second waiting time, the alerts stop and firmware exits the alert routine.

When user switches from manual to auto mode, firmware checks PIR output to determine whether LOAD will be turned off or not. PIR will almost certainly be high since SW1 is located inside the pantry and in an area right under the PIR, thus making sure the user will be detected while operating the switch. Be that as it may, if PIR output is low then LOAD is turned off, otherwise it is kept on.

Currently, there is no routine to issue an audible alert informing the user that the PIR is initializing. There should be. That will probably come in a firmware upgrade.

The actual firmware installed is provided below. It's written in MPLAB assembly. Uses only 87 words of flash and 4 bytes of RAM. Watch out! I use homebrew macros and defines throughout. Blogspot truncates any text that extends beyond the margins so if you want to read the code and comments I suggest copying and pasting into a word processor. Or paste it in MPLAB, copy and paste the macros and defines from the above link as well, build it, and read the disassembly listing or "program memory" listing if you're not a huge fan of my macros. Shame on you if you aren't!

I need to have control over the area covered/monitored by the PIR sensor but don't have the resources nor the perseverance to build a metal articulated aiming gizmo. Scrounged around and found a round tea can made of cardboard whose slip-on lid could be rotated while it was on. That provides one axis of rotation to aim the the sensor. I could easily bore a hole on the side of the canister and fasten the module with the Fresnel lens sticking out. The lid would then be screwed onto a block of wood which in turn would be bolted to the side panel of the top shelf. If I use just one bolt I can swivel the block. That's the second axis of rotation which would be at right angles to the first. Two planes of swivel is sufficient to aim the sensor practically anywhere.

Here are photos of the installation. The first shows the can with the module already in place. I wish I didn't have to glue it to the can but my brain was out of options. The can is actually red. I covered with white paper since the shelves are all white. I don't want it out more than it already will be and calling attention to it. The three wires lead to the circuit board where all the other components are.

The lid of the canister is shown fastened to a scrap piece of wood which is epoxied (the black goo) to another piece perpendicular to the former. The latter is bolted to the shelf side panel. The outlet on the pantry wall is newly installed just for this circuit. The thicker SPT cable is 220VAC power line and the smaller gauge SPT leads from the relay to the CFL. The translucent plastic box contains the circuit board and relay

In the bottom picture, the circuit is powered and operational. There's the wall wart plugged in with its (newly installed) red and black speaker cable leading to the circuit board inside the plastic box. The wire from the black plug leads to the relay. The white SPT wire along the bottom of the photo leads to the auto-manual switch located several shelves below. You can see I just taped it along the edge of the shelf.

In this last photo I am at ground level pointing the camera up. CFL is mounted on the ceiling less than a meter from the module.