Monday, December 13, 2010

Affected by electrical noise pollution

Several months ago I described a problem with transients affecting the PIR motion detection circuit. A 0.01uF monolithic capacitor was eventually installed at GP3 of the PIC 10F202 MCU. This markedly reduced false triggering of the circuit.

Recently, a newly repaired 2x40W fluorescent lamp which is within a meter or two of the PIR circuit has been causing the MCU to reset (program counter PC is zeroed) almost every time it is switched on, but not when turned off. I speculated that the transients produced by the fluorescent's starting circuit (starter and ballast) might be tripping the MCLR (GP3) pin, causing the resets.

To check whether the MCLR pin was experiencing any abnormal voltages, that pin was monitored using a Fluke 87V set to measure VDC with Min-Max turned on and set to Peak detect (250µsec response time). The fluoro lamps were switched on and off several times. Results showed that the voltage at GP3 was within normal range of zero to 3.3V.

I then rechecked the 5VDC power supply (which was already checked months back and showed no problem). With the same meter and settings the voltage at the power supply pin of the MCU was monitored. Voltage was within normal range.

Voltage at GP2--which is connected to the mode switch--was then checked. It measured a peak maximum 1.243V and peak minimum of -0.030V. The expected value is zero volts with mode switch at its default auto position. Apparently, transients were affecting this pin. Any appreciable length of conductor (more than 5cm) has the potential of capturing and conducting EMI. And the two-wire #22 SPT fixture cable going from the circuit board to the mode switch is around a meter long. So this could explain the nonzero voltage measured at GP2. To try and address this, a 0.1uF monolithic capacitor was installed from GP2 to ground. The lamps were then switched on and off several times. The recorded peak max and peak min values were: 0.080V and -0.018V. With the 0.1uF capacitor no further MCU resets were observed.

I'm curious as to the actual peak voltages impressed upon GP2. I have my doubts whether the Fluke 87V is fast enough, even with its stated 250µs response time, to capture the glitches. The 10F202's spec sheet says the I/O pins can withstand a voltage down to -0.3VDC and so the no-capacitor voltage readings of -0.03 to 1.2VDC shouldn't cause any problems. However, according to the spec sheet as well, GP2 is TTL when configured as input, and the undefined range is between 0.8 and 2.0VDC. The measured peak max of 1.24V is right smack in this badland. I might just do another round of tests using a digital oscilloscope and capture the transients. I'm really curious as to their frequency and amplitude.

On the firmware end, since the reset isn't being caused by a MCLR, I'm suspecting a WDT timeout. I will have to pore over the code and figure out how that might occur.

Thursday, October 7, 2010

These are going to be among my favorite PICks

Product brochure for the PIC 12F/16F18xx. Problem with these chips is that there's hardly any C compiler for them. As far as I know Microchip's own Hi Tech C doesn't support any of them yet. Can somebody please kick their butts?

Thursday, September 30, 2010

Hi-Tech C vs mikroC Pro

Just out of curiosity I compiled a small sample program on Hi-Tech C for PIC18 v9.63L3 and mikroC Pro v4.10 freeware version. Target MCU was a PIC18F2321. Hi-Tech was used within Microchip's MPLAB IDE v.8.30. Hi-Tech's Omniscient Code Generation (OCG) is on (for the duration of the 45-day eval period). I set the mikroC optimization level to 5 (the maximum).

According to the compilers the Hi-Tech version took up 84 bytes of Flash while the mikroC required 122 bytes. Both compilers used only 2 bytes of RAM. Apparently Hi-Tech wins by a mile, at least in this particular test.

Here's the C program I fed both compilers:

#define  int8    unsigned char

void InitRegisters()
{
  IRCF1 = 1;
  ADCON1 = 0b1111;           // turn all analog inputs into digital

  PORTA = 0;
  PORTB = 0;
  PORTC = 0;
  TRISA = 0;
  TRISB = 0;
  TRISC = 0;
}

void OnLoad(int8 *salad)
{
  *salad = 0xFF;
}

void OffLoad(int8 *greens)
{
  *greens = 0;
}

// ====================================================================
//     main
// ====================================================================

void main()
{
  InitRegisters();

  while(1)
  {
    if (PORTC)
      OffLoad(&PORTC);
    else
      OnLoad(&PORTC);
  }  // while (1)
}  // main


Here's the disaasembly listing by Hi-Tech:
1:                 /*
2:                 
3:                 sandbox
4:                 compiler = Hi Tech 
5:                 
6:                 */
7:                 
8:                 #include  
9:                 
10:                __CONFIG (1, INTIO & FCMDIS & IESODIS);
11:                __CONFIG (2, PWRTDIS & BORDIS & WDTDIS & WDTPS4);
12:                __CONFIG (3, PBDIGITAL & LPT1DIS & MCLRDIS);
13:                __CONFIG (4, XINSTDIS & STVRDIS & LVPDIS & DEBUGDIS);
14:                __CONFIG (5, 0xFFFF);                                      // write protect disabled
15:                __CONFIG (6, 0xFFFF);            // write protect disabled
16:                __CONFIG (7, 0xFFFF);                                      // write protect disabled
17:                
18:                
19:                #define  int8    unsigned char
20:                
21:                // ====================================================================
22:                //     Global variables and enumerations
23:                // ====================================================================
24:                
25:                
26:                
27:                
28:                // ====================================================================
29:                //      Functions
30:                // ====================================================================
31:                
32:                void InitRegisters()
33:                {
34:                  IRCF1 = 1;
  1FC8    8AD3     BSF 0xfd3, 0x5, ACCESS
35:                  ADCON1 = 0b1111;           // turn all analog inputs into digital
  1FCA    0E0F     MOVLW 0xf
  1FCC    6EC1     MOVWF 0xfc1, ACCESS
36:                
37:                  PORTA = 0;
  1FCE    6A80     CLRF 0xf80, ACCESS
38:                  PORTB = 0;
  1FD0    6A81     CLRF 0xf81, ACCESS
39:                  PORTC = 0;
  1FD2    6A82     CLRF 0xf82, ACCESS
40:                  TRISA = 0;
  1FD4    6A92     CLRF 0xf92, ACCESS
41:                  TRISB = 0;
  1FD6    6A93     CLRF 0xf93, ACCESS
42:                  TRISC = 0;
  1FD8    6A94     CLRF 0xf94, ACCESS
43:                }
  1FDA    0012     RETURN 0
44:                
45:                void OnLoad(int8 *salad)
46:                {
47:                  *salad = 0xFF;
  1FBC    C000     MOVFF 0, 0xfe9
  1FBE    FFE9     NOP
  1FC0    C001     MOVFF 0x1, 0xfea
  1FC2    FFEA     NOP
  1FC4    68EF     SETF 0xfef, ACCESS
48:                }
  1FC6    0CFF     RETLW 0xff
49:                
50:                void OffLoad(int8 *greens)
51:                {
52:                  *greens = 0;
  1FB0    C000     MOVFF 0, 0xfe9
  1FB2    FFE9     NOP
  1FB4    C001     MOVFF 0x1, 0xfea
  1FB6    FFEA     NOP
  1FB8    6AEF     CLRF 0xfef, ACCESS
53:                }
  1FBA    0C00     RETLW 0
54:                
55:                // ====================================================================
56:                //     main
57:                // ====================================================================
58:                
59:                void main()
60:                {
61:                  InitRegisters();
  1FDC    ECE4     CALL 0x1fc8, 0
  1FDE    F00F     NOP
62:                
63:                  while(1)
  1FFE    D7F0     BRA 0x1fe0
64:                  {
65:                    if (PORTC)
  1FE0    5082     MOVF 0xf82, W, ACCESS
  1FE2    E007     BZ 0x1ff2
66:                      OffLoad(&PORTC);
  1FE4    0E82     MOVLW 0x82
  1FE6    6E00     MOVWF 0, ACCESS
  1FE8    0E0F     MOVLW 0xf
  1FEA    6E01     MOVWF 0x1, ACCESS
  1FEC    ECD8     CALL 0x1fb0, 0
  1FEE    F00F     NOP
  1FF0    D7F7     BRA 0x1fe0
67:                    else
68:                      OnLoad(&PORTC);
  1FF2    0E82     MOVLW 0x82


Disassembly listing by mikroC:
;  LST file generated by mikroListExporter - v.2.0 
; Date/Time: 9/30/2010 8:21:34 PM
;----------------------------------------------

;Address Opcode         ASM
0x0000        0xF000EF2D          GOTO        90
0x0004        0x0000              NOP
0x0006        0x0000              NOP
0x0008        0xF000EF00          GOTO        0
0x000C        0x0000              NOP
0x000E        0x0000              NOP
0x0010        0x0000              NOP
0x0012        0x0000              NOP
0x0014        0x0000              NOP
0x0016        0x0000              NOP
0x0018        0xD7F3              BRA         0
_OnLoad:
;sandbox18F.c,36 ::                 void OnLoad(int8 *salad)
;sandbox18F.c,38 ::                 *salad = 0xFF;
0x001C        0xFFE1C015          MOVFF       FARG_OnLoad_salad, FSR1L
0x0020        0xFFE2C016          MOVFF       FARG_OnLoad_salad+1, FSR1H
0x0024        0x0EFF              MOVLW       255
0x0026        0x6EE6              MOVWF       POSTINC1 
;sandbox18F.c,39 ::                 }
0x0028        0x0012              RETURN      0
; end of _OnLoad
___CC2DW:
;__Lib_System.c,21 ::                 
;__Lib_System.c,23 ::                 
_CC2DL_Loop1:
;__Lib_System.c,24 ::                 
0x002A        0x0009              TBLRD*+
;__Lib_System.c,25 ::                 
0x002C        0xFFE6CFF5          MOVFF       TABLAT, POSTINC1
;__Lib_System.c,26 ::                 
0x0030        0x0600              DECF        R0, 1, 0
;__Lib_System.c,27 ::                 
0x0032        0xE1FB              BNZ         _CC2DL_Loop1
;__Lib_System.c,28 ::                 
0x0034        0x0601              DECF        R1, 1, 0
;__Lib_System.c,29 ::                 
0x0036        0xE1F9              BNZ         _CC2DL_Loop1
;__Lib_System.c,31 ::                 
0x0038        0x0012              RETURN      0
; end of ___CC2DW
_OffLoad:
;sandbox18F.c,41 ::                 void OffLoad(int8 *greens)
;sandbox18F.c,43 ::                 *greens = 0;
0x003A        0xFFE1C015          MOVFF       FARG_OffLoad_greens, FSR1L
0x003E        0xFFE2C016          MOVFF       FARG_OffLoad_greens+1, FSR1H
0x0042        0x6AE6              CLRF        POSTINC1 
;sandbox18F.c,44 ::                 }
0x0044        0x0012              RETURN      0
; end of _OffLoad
_InitRegisters:
;sandbox18F.c,23 ::                 void InitRegisters()
;sandbox18F.c,25 ::                 OSCCON.IRCF1 = 1;
0x0046        0x8AD3              BSF         OSCCON, 5 
;sandbox18F.c,26 ::                 ADCON1 = 0b1111;           // turn all analog inputs into digital
0x0048        0x0E0F              MOVLW       15
0x004A        0x6EC1              MOVWF       ADCON1 
;sandbox18F.c,28 ::                 PORTA = 0;
0x004C        0x6A80              CLRF        PORTA 
;sandbox18F.c,29 ::                 PORTB = 0;
0x004E        0x6A81              CLRF        PORTB 
;sandbox18F.c,30 ::                 PORTC = 0;
0x0050        0x6A82              CLRF        PORTC 
;sandbox18F.c,31 ::                 TRISA = 0;
0x0052        0x6A92              CLRF        TRISA 
;sandbox18F.c,32 ::                 TRISB = 0;
0x0054        0x6A93              CLRF        TRISB 
;sandbox18F.c,33 ::                 TRISC = 0;
0x0056        0x6A94              CLRF        TRISC 
;sandbox18F.c,34 ::                 }
0x0058        0x0012              RETURN      0
; end of _InitRegisters
_main:
;sandbox18F.c,50 ::                 void main()
;sandbox18F.c,52 ::                 InitRegisters();
0x005A        0xDFF5              RCALL       _InitRegisters
;sandbox18F.c,54 ::                 while(1)
L_main0:
;sandbox18F.c,56 ::                 if (PORTA)
0x005C        0x5280              MOVF        PORTA, 1 
0x005E        0xE006              BZ          L_main2
;sandbox18F.c,57 ::                 OffLoad(&PORTA);
0x0060        0x0E80              MOVLW       PORTA
0x0062        0x6E15              MOVWF       FARG_OffLoad_greens 
0x0064        0x0E0F              MOVLW       hi_addr(PORTA)
0x0066        0x6E16              MOVWF       FARG_OffLoad_greens+1 
0x0068        0xDFE8              RCALL       _OffLoad
0x006A        0xD005              BRA         L_main3
L_main2:
;sandbox18F.c,59 ::                 OnLoad(&PORTA);
0x006C        0x0E80              MOVLW       PORTA
0x006E        0x6E15              MOVWF       FARG_OnLoad_salad 
0x0070        0x0E0F              MOVLW       hi_addr(PORTA)
0x0072        0x6E16              MOVWF       FARG_OnLoad_salad+1 
0x0074        0xDFD3              RCALL       _OnLoad
L_main3:
;sandbox18F.c,60 ::                 }  // while (1)
0x0076        0xD7F2              BRA         L_main0
;sandbox18F.c,61 ::                 }  // main
0x0078        0xD7FF              BRA         $+0
; end of _main

Tuesday, September 28, 2010

The PIC16F1827: an inexpensive, fully loaded MCU

I'm excited about the PIC16F1827 because it's packed with peripherals, has five! timers, has an internal clock with a maximum frequency of 32MHz, and yet is no more expensive than other 18pin PIC16s. I want a tube of these!

Just my luck though. I'll have to wait. I try and obtain all my PICs from Microchip Direct, but the 1827 won't be available till the end of this year (extended temperature PDIP is on stock, however). RS Components has none either. Farnell has stocks but comes out way pricier. 

Hardware aside, I have no plans on programming this chip using assembly. So I need a C compiler. You'd expect Microchip's compiler division would have a compiler ready once the chip is out, but even with the acquisition of Hi Tech it has yet to support the 1827. That's rather strange. The just released MikroC Pro v4.10 does support the MCU and several other enhanced PIC16s. BoostC by SourceBoost also recognizes the 1827. 

Guess I'll be playing with this MCU early next year.

Friday, September 24, 2010

On the blink

James Bryant of Analog Devices and his dirty dozen ways for circuits to fail.

The PIR circuit I recently installed has been challenging me. Just two days after it was installed it began to at times fail to switch the load on even if the PIR sensor was detecting motion (I know because the LED had turned on, ergo, PIR output was high). The fault was infrequent and usually occurred the first time the pantry was accessed in the morning--circuit must be too groggy to start the day. After days of checking and monitoring supply voltages (and finding nothing wrong with them), I decided to reprogram the MCU. The problem disappeared. Could've been an intermittent contact problem--which was licked when I removed the MCU and reinserted it--or it could've been a bad burn of the firmware.

Another problem which was noticed along with the above has yet to be resolved. When the dining room lights are turned off, the pantry light sometimes switches on. This occurs probably once every couple of dozen switchings. Rather obviously transients in the power line from switching off four conventionally ballasted plug-in type 11-watt compact fluorescent lamps are falsely triggering the circuit. I've already monitored MCU VDD using the Min-Max with Peak detect feature of the Fluke 87V for some 24hours and found the voltage to be from 4.930V to 5.048V, so no problem there. On the other hand, given the cable length to the PIR module of some 40cm, the problem may lie there. That's No.5 in Bryant's list. I've been mullling where in the sensor circuit to install additional bypass/decoupling caps. May have to put one at the VDD of the module and another at the MCU input pin (GP3); 0.1 to 1uF for the former and 10 to 100nF for the latter.

Wednesday, September 22, 2010

An important pointer on using mikroC with PIC18s

After half a day of trying to get it to work I nearly gave up. Was trying out C pointers using an old version of mikroC on a Microchip PIC18F2321. Here's the test program (to preclude clutter I've removed the initialization routines for OSCCON, PORTx, TRISx, and ADCON1 registers):

void OnLoad(unsigned char *salad)
{
  *salad = 0xFF;
}

void OffLoad(unsigned char *greens)
{
  *greens = 0;
}

void main()
{
  while(1)
  {
    OnLoad(&PORTC);    
    Delay_100ms();
    OffLoad(&PORTC);
    Delay_100ms();
  }
}  

The firware merely toggles PORTC on and off every tenth of a second. An LED is connected to one of the PORTC pins, so it should blink when the MCU is powered up. Well, it didn't work.

After a couple of hours of racking my brain and trying out variations on the program, I decided to test the code on a PIC 16F device. I inserted a PIC12F615 into the breadboard, plugged in an LED and resistor, and hooked up the PICKit 2. Opened a new project in mikroC and used the same program, changing PORTx to GPIO, and initializing the appropriate SFRs. Guess what? Worked the first time around. No problems. That told me there's nothing wrong with the program. Went back to the PIC18.

After several more hours of checking and hair-pulling, it occured to me that there might be something in the MCU configuration bits which hasn't been set properly. Referring to the datasheet, the only one that seemed relevant was the XINST (Extended Instruction Set enable) bit in configuration word CONFIG4L. Noting that according to the datashet it's off by default, I first enabled it. I compiled the firmware, uploaded to the MCU, and powered it up. Nothing. The program still wouldn't work. Went back to mikroC, unchecked the "XINST_ON_4L" box and checked "XINST_OFF_4L."

Hallelujah! The LED finally started blinking, and at the proper rate at that. Finally found the culprit! Just to make sure it was indeed the XINST bit, I enabled it again. Sure enough the program failed again. Disabling XINST once more and the firmware worked. As a final test, I unchecked both these boxes (it was in that condition before I fiddled around with the XINST) and uploaded the compiled code. It didn't work. Therefore, regardless of what Microchip says about the default condition of the configuration words, it is quite clear that they must be explicitly set in mikroC.

So there. A nasty little trap which MikroElektronika does not state in their manual. Beware.

Monday, September 20, 2010

Fluke face to face with Kryptonite

Australian electronics engineer Dave Jones proves that the Fluke 87V DMM goes haywire in the presence of GSM.



Much as I'd like to see this fault for myself, I simply cannot afford to fry my 87V. Instead I used a Fluke 117 as the lab rat. Apparently, the cheapo doesn't even know what a cell phone is. Barely a reaction and not a hint of malfunction.

This GSM susceptibility is yet another item in the list of disappointments I have with the 87V. First and foremost is its unforgivably flimsy 9V battery connector. It's no different from those found in China made toys!


I cannot imagine how Fluke could have blundered something as basic as this. My old Sanwa DMM had a far more superior battery-compartment-connector system. You unscrew the battery compartment at the back of the meter, remove it, flip it over and insert the battery into it, and then plug the whole thing back into the meter body and screw tight. Once inserted the battery terminals automatically make contact with metal prongs inside the meter. Absolutely great design! Now why couldn't Fluke have made something similar with this model? It's already the Series 5!

They certainly did it right on the Fluke 117:



Next on the list, and one that puts me off whenever I notice it is the LCD. For some reason Fluke seems to have sacrificed the viewing angle exactly perpendicular to the unit. When looking straight down the segments have rather poor contrast--not as black--as when looking at an angle. At first I thought my unit was faulty, but I've checked another brand new 87V and an 83V and their LCDs both have the same characteristic. And the batteries are still fresh so it's not a low voltage problem. I was never annoyed with the display of my old Sanwa so I guess it didn't have this quirk. Testing the 87V, the LCD is a  6:00 type with a bias angle somewhere between 20 and 30°. The readout is still tolerable even at 60°.

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!


; ********************************************
; Passive Infrared Motion Detector for home panty
; September 2010
; 
; see "PIR sensor.dwg" for schematic
; *********************************************

 processor 10F202
 #include p10F202.inc
 #include et.inc

 __config _MCLRE_OFF & _CP_OFF & _WDT_ON
 
 cblock 0x08
CENTISECS    ; number of centiseconds for time delay
ICOUNTER    ; counter for iterations
COUNTER:2    ; counters for delays 
 endc
 
 #define  buz  GPIO,0   ; sonalert buzzer
 #define  load GPIO,1   ; switches MOSFET which switches 12VDC relay which switches 220VAC CFL
 #define  sw  GPIO,2   ; mode switch: high = manual (load is continuously on), low = auto (motion detect)
 #define  pir  GPIO,3   ; PIR output, high = motion detected, low = no motion detected
 
 org  0x0
 
 movwf OSCCAL      ; load clock calibration 
 goto initialize
 
; =======================================================================================
; subroutines
;
; 10F202 can only call subroutines if they are located in first 256 memory locations
; =======================================================================================

; ---------------------------------------------------------------------------------
; Time delay that's user dependent 
; Place number of centiseconds of delay in register CENTISECS before calling this routine
DelayCentisec:
 movlf .164, COUNTER
 movlf .20, COUNTER+1
delay_loop 
 decfsz COUNTER,f
 goto delay_loop
 movlf .164, COUNTER
 decfsz COUNTER+1,f
 goto delay_loop
 clrwdt
 movlf .20, COUNTER+1
 decfsz CENTISECS,f
 goto delay_loop
 retlw 0 
; ---------------------------------------------------------------------------------

; ---------------------------------------------------------------------------------
; one centisec beep
Beep:
 bsf  buz
 movlf .1, CENTISECS
 call DelayCentisec
 bcf  buz
 retlw 0
; ---------------------------------------------------------------------------------


; =======================================================================================
; main program
; =======================================================================================

; ---------------------------------------------------------------------------------
initialize:
 clrf GPIO
 movlw b'11011111'    ; TOCS bit must be 0 else GP2 will be an input pin; prescaler is assigned to WDT; prescale = 1:2 
 option
 movlw b'1100'     ; GPIO 0 and 1 are assigned as output, GP2 is input, GP3 is by default an input only pin
 tris GPIO

; do nothing for about half a second (50 centisec) to give PIR time to initialize and bring its output high
 movlf .50, CENTISECS
 call DelayCentisec

; PIR initializes by outputting high twice over a minute or two
; wait until the second falling edge is detected; thereafter any edges detected will be due to normal operation of motion detection 

; wait for first PIR falling edge
init_pir_loop1
 clrwdt
 dnxtrue pir
 goto init_pir_loop1

; wait for PIR rising edge 
init_pir_loop2 
 clrwdt
 dnxfalse pir
 goto init_pir_loop2
 
; wait for second PIR falling edge--signals the end of PIR initialization 
init_pir_loop3
 clrwdt
 dnxtrue pir
 goto init_pir_loop3
 
; ---------------------------------------------------------------------------------

; ---------------------------------------------------------------------------------
main:
 ; wait for PIR rising edge--which signals that motion has been detected
 ; check mode sw status 
 clrwdt
 dnxtrue sw     
 goto manual
 dnxfalse pir
 goto main

main_motion_true
 bsf  load    ; PIR output is high so turn load on 
 
main_loop1
 ; wait until no motion is detected--until PIR output goes low
 ; check mode sw status
 clrwdt
 dnxtrue sw      
 goto manual
 dnxtrue pir
 goto main_loop1

; PIR output is now low 
; give user 5 seconds to activate motion sensor before turning off load
; begin issuing 10ms beep every second for four seconds to alert user that motion is no longer detected
; check PIR output every second; if it goes high (motion is detected) then exit and go to main_loop1 
; check mode sw status every second; if sw level goes high then go to manual mode routine
main_motion_false
 movlf .4, ICOUNTER
main_beep_loop0
 call Beep
 movlf .99, CENTISECS
 call DelayCentisec
 dnxtrue sw      
 goto manual
 dnxtrue pir     
 goto main_loop1
 decfsz ICOUNTER,f
 goto main_beep_loop0

; for the last second issue a 10ms-beep every 200ms
; check PIR output every second; if it goes high (motion is detected) then exit and go to main_loop1 
; check mode sw status every second; if sw level goes high then go to manual mode routine
 movlf .5, ICOUNTER
main_lastsec_beep_loop0 
 call  Beep
 movlf .19, CENTISECS
 call DelayCentisec
 dnxtrue sw     
 goto manual
 dnxtrue pir
 goto main_loop1
 decfsz ICOUNTER,f
 goto main_lastsec_beep_loop0

; if PIR output remains low then turn load off
; go to main whether PIR output is low or high
 dnxfalse pir
 bcf  load
 goto main  


; manual mode routine
; if sw level is high then turn load on 
; if sw level is low and PIR output is low then turn off load
; if sw level is low and PIR output is high then keep load on
; when sw level is low then go to main
manual:
 bsf  load
manual_loop1
 dnxfalse sw
 goto manual_loop2
 clrwdt
 goto manual_loop1
manual_loop2
 dnxfalse pir
 bcf  load
 goto main


 end

; ----------------------------------------------------------------------------------


The Installation

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.

PIR sensor module


Recently bought a couple of passive infrared (PIR) modules. The seller lists the part number as DC-SS015, although I can't be certain that this indeed is true. Unfortunately the seller could not provide any datasheet. It may in fact be a SS015 since the pin designations for the headers are the same as those on a datasheet for the DC-SS015 (see below).

As far as I can tell there are only two ICs on this module. The SOIC-16 (left of center in the photo) does not have any markings. It could be a BISS001 clone. The (4-pin) SOT-89 (lower right in photo) has ""7533-1" printed on it. I googled and this may be a Holtek 3.3V LDO voltage regulator.

The board measures 33mm x 25mm and is marked "Rev1.1." The fresnel lens is hot glued to the board and for now I have not dared remove it for fear of misaligning it.




The black circular thingie beneath the board is just a 35mm film canister to the prop the board up. Needed to  keep it level with the table while taking the picture given the domed fresnel lens on the other side.

 Here are screenshots of the pertinent pages from a datasheet I found for the DC-SS015 some time ago. I can no longer find the link for the pdf file by Sure Electronics



The position on the board and designation of the header pins of the module match those shown on the datasheet.  The 3-pin header at the bottom center of the board (as per the photo above) are for power and output. Left pin (silkscreened "SW") is ground, center pin (marked "OUT") is output, right pin is Vcc.

The 3-pin header on the upper left corner has a jumper to select between single trigger and re-triggerable modes. The topmost pin is labeled "H" on the module, while the lowermost pin is labeled "L." With the jumper plugged into the two top pins (H and common) the circuit becomes retriggerable, that is, any motion detected will reset the output high holding period to whatever the user has set it to. With the jumper plugged into the lower two pins (common and L) only the initial motion detected is counted and any further trigger will be ignored until the output-high holding period has elapsed. In other words, in single trigger mode assuming PIR module output is initially low, the time between motion is detected (output goes high) and output goes low is constant.

The output-high holding period (for both trigger modes) is user adjustable and is set via a 1Mohm trimmer resistor. That's the orange part on the upper right corner of the board. I've played around with it and the range is from almost zero to 16.75 seconds. The module arrived with the trimmer set at center, which had a measured time of between 9 and 10 seconds.

I measured the current draw using a Fluke 87V with its min-max feature turned on. Input voltage was measured at 5.18VDC (using an ATX power supply) and load was a 2N7000 MOSFET with its gate directly connected to the PIR output (no limiting resistor). Minimum current recorded was 37µA while maximum was 98µA. As you can read from the datasheet, quiescent current is specified at 50µA.

With the module powered from the same supply as above, output voltage was measured with a Fluke 8842A and for this test module, without any load, low was less than 0.03mV and high = 3.31V. 

The module has a long initialization time. After powering up output will go high for several seconds, go low for a shorter period of time, high again for several seconds, and then back low. Thereafter, it will be not triggerable for several more seconds. The period for this set up doesn't seem to be fixed, but the whole thing takes about a minute.

This unit is able to detect human movement to 4 meters, but sensitivity at that distance is fair at best. Seems to perform well enough within two meters. Angular coverage is apparently greater horizontally (as per board orientation in the photos above) than vertically. Difficult to give precise values, but 90 degrees would be a ballpark figure.

I've already used one of the modules in a circuit that automatically switches a compact fluorescent lamp inside a pantry. I'll probably do a blog on that soon. 

Finally, for a tutorial on PIR devices check out ladyada.

Saturday, September 4, 2010

Adjustable power supply with automatic transformer tap select


I'm currently designing and testing a 1-amp power supply based on the good old LM317 voltage regulator. I'd like it to be able to supply a voltage from its minimum of 1.25 V all the way to about 30 V. That's within its specs so no problem with that range. However, one problem is the power dissipation of the 317 which is given by:

\[
P_D = I_{VR} ( V_{IN} - V_{O})
\]

where
$P_D$ = power dissipation, in watts
$I_{VR}$ = current through the voltage regulator, mostly the load current, in amperes
$V_{IN}$ = input voltage, in volts
$V_{O}$ = output voltage, in volts

The higher the difference between input and output voltage the greater the power loss in the 317. If we use a single input voltage it would have to be at least 33VDC, more likely >35V to factor in capacitor ripple voltage. With an input of 35V and an output of, say, 5VDC headroom would be 30V. If the load were drawing 100mA it would dissipate 5V x 0.1A = 0.5W while the 317 would be wasting 30V x 0.1A = 3W! Without a heatsink and given the thermal resistance of a TO-220 package of around 65°C/W, the junction temperature would well exceed its 125°C maximum. Of course the 317 will probably shut down before reaching that temperature, or it might fry if the thermal overload protection circuitry somehow fails.Not that we wouldn't install a heatsink. It's indispensable for a 1000-mA supply since even with a constant headroom of 3V (minimum required), the regulator would still be dissipating 3W at a current draw of 1A. In fact my calculations show that on top a heat sink with a thermal resistance of <= 10°C/W, I'll still need a cooling fan given the headroom that my design has.

Heatsinking cannot be overemphasized in this design since with all else constant $V_{O}$ changes with junction temperature. If you check the graphs of any LM317 datasheet you will find that load regulation, adjustment current, and reference voltage are all temperature dependent. Therefore, keeping the 317 temperature as constant as possible is paramount for a good constant voltage output with a varying load.

So there are several reasons for limiting voltage headroom. And one way to do so is to use a multitap transformer and feed the 317 with a voltage that depends on its output. The greater the output voltage the higher the voltage we input to the regulator. A control circuit monitors $V_O$ and selects the appropriate transformer tap via electromagnetic relays.

Unfortunately, for this design I couldn't find a multiple tap transformer (with four or five outputs) whose maximum voltage output is 30 or so volts RMS. The best I could find is a 14-0-14 volt center-tapped, which is equivalent to a 0-14-28. With only two output voltages only one relay is necessary. The idea is to switch to 28VAC when $V_O$ rises above the middle value of around 12VDC and to switch back to 14VAC when it falls below this. A hysteresis band will be necessary to prevent relay "chatter" when crossing the switchover voltage.

In my first design I powered the $V_O$ monitoring circuit from the same transformer. But it turns out that because the secondary windings are not isolated from one another the voltages go haywire when the two taps are used simultaneously--by the 317 and the monitoring circuit. So I've had to use a second transformer, with 12VAC output, to drive the relay and power the ICs that check $V_{O}$.

The monitoring circuit consists simply of a comparator with hysteresis wired in using two positive feedback resistors. I've decided to switch the relay when $V_{O}$ is around 13VDC. I will definitely use $V_{O}$ = 12VDC so I don't want it switching at that level. And I can't change taps at a much higher voltage since there might not be enough headroom for the regulator when current draw goes above 500mA. So I've pegged the trip comparator trip voltage between 13 and 14VDC.

To determine the resistor values, upper and lower trip voltages, and the hysteresis band, I needed formulas. Textbooks have not been of any help. They do have the equations but they're for op amps using bipolar power supplies. I'm keeping to single-supply op amps and those equations simply don't work. I've tried them and results don't match with measured values. Luckily Microchip has the holy grail in their literature.

From the Microchip MCP6541 datasheet we have the following equations to determine the trip voltages given positive feedback.

\[
V_{TLH} = V_{REF}\left ( 1 + \frac{ R_{F1}}{R_{F2}} \right )  - V_{OL} \left ( \frac{R_{F1}}{R_{F2}} \right)
\]

\[
V_{THL} = V_{REF}\left ( 1 + \frac{ R_{F1}}{R_{F2}} \right )  - V_{OH} \left ( \frac{R_{F1}}{R_{F2}} \right)
\]

where
$V_{TLH}$ = trip voltage when voltage at the noninverting input is going from low to high, in volts
$V_{THL}$ = trip voltage when voltage at the noninverting input is going from high to low, in volts
$V_{REF}$ = reference voltage, i.e., voltage at the comparator's inverting input, in volts
$V_{OL}$ = comparator low level output voltag, in volts
$V_{OH}$ = comparator high level output voltage, in volts
${R_{F1}}$, ${R_{F2}}$ = positive feedback resistances, in ohms

If output of the comparator is only very lightly loaded then $V_{OL}$ is only a few millivolts above ground. Moreover, ${R_{F1}}/{R_{F2}}$ is very small. Thus $V_{OL}  ({R_{F1}}/{R_{F2}})$ is practically zero. $V_{TLH}$ then reduces to:

\[
V_{TLH} = V_{REF}\left ( 1 + \frac{ R_{F1}}{R_{F2}} \right )
\]

It follows then that

\[
V_{THL} = V_{TLH} - V_{OH} \left ( \frac{R_{F1}}{R_{F2}} \right)
\]

With a very lightly loaded comparator output, $V_{OH}$ is for all practical purposes equal to the comparator's supply voltage $V_{DD}$.

Upper and lower trip voltages in terms of $V_O$ are obtained as follows:

\[
V_{TLH}' = V_{TLH} \left ( \frac {R_{VD1}+R_{VD2}} {R_{VD2}} \right)
\]

\[
V_{THL}' = V_{THL} \left ( \frac {R_{VD1}+R_{VD2}} {R_{VD2}} \right)
\]


Referring to the schematic above, the comparator's reference voltage is derived from a voltage divider and computed as follows:

\[
V_{REF} = V_{DD} \left ( \frac {R_{REF2}}{R_{REF1} + R_{REF2}} \right)
\]

where
$R_{REF1}$ and $R_{REF2}$ are the voltage divider resistor values, in ohms

The LM317 output voltage $V_O$ is to be monitored by the comparator. But because this swings from 1.25 to around 30VDC, while the comparator maximum input voltage is $V_{DD}$ = 5VDC, we need to "step down" the voltage sensed by the comparator by using a voltage divider. $ R_{VD1}$ and $R_{VD2}$ are chosen such that when $V_O$ is at its maximum then voltage divider output is equal to the comparator $V_{DD}$. Voltage divider output is given by:

\[
V_O \left ( \frac {R_{VD2}}{R_{VD1}+R_{VD2}} \right)
\]

The presence of the feedback circuit in the comparator necessitates a low impedance source. The voltage divider formed by $R_{VD1}$ and $R_{VD2}$ does not meet this requirement. Hence a unity gain buffer is necessary.

I initially used a MC33171 op amp for the comparator and a LM310 voltage follower as the buffer. Instead of having two ICs I want to use a dual single supply op amp IC with a $V_{CC}$ of > 12VDC but unfortunately I don't have any at hand. But I do have tons of Microchip single, dual, and quad op amps. I picked the MCP6282 for its rail-to-rail input and output and its good slew rate. $R_{VD1}$ and $R_{VD2}$ were chosen such that the voltage divider's maximum output is 5VDC.

Resistors, $V_{DD}$, and $V_{OH}$ of the breadboarded prototype were measured using a Fluke 8842A and their values were plugged into the equations above. $V_{TLH}'$ and $V_{THL}'$ were measured with the multimeter probes connected to $V_O$ and ground, and gradually turning the potentiometer. Theoretical and empirical results are within less than 0.25% of each other! That certainly blew my mind.



While designing this power supply I used an old malfunctioning ATX power supply 12VDC brushless motor cooling fan as a load since I could turn $V_O$ up and down and have some visual feedback on how it's affecting the load. And I could afford to ruin it should it burn up when I turned $V_O$ all the way up. Turns out choosing this fan was fortuitous because I discovered something totally unexpected. Without any load the comparator circuit worked fine and, depending on the values of the various resistors, there was some 1.5 to 2V ($V_O$) hysteresis band. But when the fan was powered hysteresis was lost and relay chatter was prominent when the trip voltage level was being crossed. I found out what was happening when I hooked up an oscilloscope to check $V_O$. It showed the fan was introducing positive and negative pulses (see oscilloscope screenshots below). And the comparator circuit was merely following what it's suppose to do--tripping (and being tripped up) when those pulses were present, as the difference between the peak positive and negative values exceeded the hysteresis band set by $R_{F1}$ and $R_{F2}$.

So I added a low pass filter section whose cutoff frequency can be computed as follows:

\[
f_c = \frac{1}{2\pi R_{LPF}C_{LPF}}
\]

where
$f_c$ = filter cutoff frequency, in hertz
$R_{LPF}$ = filter resistor value, in ohms
$C_{LPF}$ = filter capacitor value, in farads

This circuit filters out any transients occurring in $V_O$. With the LPF circuit in place oscilloscope reading of the unity gain buffer output was devoid of the noise pulses introduced by the fan.

I also used a new brushless DC fan as a load. Apparently even brand new fans also introduce spikes into $V_O$ although it seems their amplitude is not as high as those of the malfunctioning fan (see screenshots below). But the fans tested are made by different manufacturers so the noise they introduce may be manufacturer specific.

Given how the comparator and LPF circuits are working perfectly, I decided to lower the hysteresis band to a 500mV (measured at $V_O$), which translates to around 83mV at the comparator input. With resistor values (I used 5% resistors) provided in the schematic, actual measured upper trip voltage = 13.58V and lower trip voltage = 13.00V.



In the Rigol DS1102E oscilloscope screenshots below, channel 1 is set to AC coupling and bandwidth limit is on. $V_O$ is set to 12.50V as measured by the Fluke multimeter. All measurements are with respect to circuit ground.



Point of measurement: unity gain buffer output
Trigger: auto, @296mV
Vertical: 200mV/div
Horizontal: 5ms/div

The used, malfunctioning fan--a Power Logic brushless motor model PL80S12M rated at 12V 0.13A--is powered by $V_O$. There is no low pass filter at the input of the voltage follower. Cursors are on and show that positive peak voltage = 384mVand peak negative voltage= -280mV. The comparator circuit sees these voltage spikes and when $V_O$ is at the trip setting the comparator output rapidly alternates between high and low (because the noise is greater than the hysteresis band) resulting in relay chatter.



Same screenshot as above but the cursors have been changed to measure time. As can be seen pulses occur every 6.7ms.



Point of measurement: unity gain buffer output
Trigger: single shot, 120mV
Vertical: 200mV/div
Horizontal: 2ms/div

The lower waveform is a zoomed in display of the portion above that's between the purple bands. Time base for lower display = 50.00µs/div.



Same as above but zoomed in portion is that of the spike on the right. Time base is also 50µs/div




Point of measurement: unity gain buffer output
Trigger: auto, 0.00V
Vertical: 200mV/div
Horizontal: 5ms/div

The same fan is being powered by $V_O$, but now a first order low pass filter with a $f_c$ of 16Hz (as per schematic above) is connected to the input of the voltage follower. Voltage spikes have been completely eliminated and the comparator circuit performs flawlessly. 



Point of measurement: $V_O$
Trigger: auto, @2.00V
Vertical: 1.00V/div
Horizontal: 20.00µs/div

This is the first type of pulse from the fan but measured at $V_O$. As can be seen it's the same as that output by the voltage follower without a low pass filter. 



Point of measurement: $V_O$
Trigger: auto, @-1.68V
Vertical: 1.00V/div
Horizontal: 20.00µs/div

This is the second type of pulse but measured at $V_O$. As can be seen it's the same as that output by the voltage follower without a low pass filter. 



Point of measurement: $V_O$
Trigger: auto, @1.08V
Vertical: 1.00V/div
Horizontal: 20.00µs/div

This is the only kind of pulse from a brand new ADDA Brushless DC motor model AD0812MS-A70GL rated at 12V 0.15A. Comparing the pulses, that from the Power Logic has a positive peak that reaches 2.1V while this new fan has a peak of only 1.2V. Negative peak is a bit harder to compare because the ADDA sometimes has negatives spikes that dip to around -2.0V.

The most crucial point in all this is that a low pass filter is essential for the $V_O$ monitoring circuit to work properly and reliably given various types of loads loads.




Backtracking a bit, filter capacitor sizing is important to make sure that ripple voltage at maximum rated current of the power supply is such that there is still enough headroom for the 317 to produce a regulated output. That is, at the comparator trip voltage (switching from lower to higher voltage transformer tap) and at the maximum voltage output of the 317 (~30VDC in this design) the following must hold true:

\[
V_{IN_{no\,load}}- V_{PPripple_{max\,load}} > V_{min\,headroom}
\]

where
$V_{IN_{no\,load}}$ =  LM317 input voltage with no load at the output, in volts
$V_{PPripple_{max\,load}}$ =  peak-to-peak ripple voltage at the input of the 317 with maximum load connected to its output, in volts
$V_{min\,headroom}$ = minimum headroom for the voltage regulator, in volts

Minimum headroom for the LM317 is around 2.5VDC. To allow enough leeway I peg it at 3V. This headroom requirement is the reason I chose a 14-0-14V over the more common 12-0-12V transformer. Tests with the latter yielded a poor headroom, its output being only 15VDC, rectified and filtered, even at no-load condition. That should in fact be 17.0VDC ($V_{RMS}\sqrt2 $). This problem may be manufacturer related, or I just got a bad batch. The 14-0-14V transformer (made by a different manufacturer) measured 19.6VDC (rectified, filtered, no-load) tapped at its 14VAC output, which is within 1% of the ideal value of 19.8V.

Assuming a ripple voltage that's triangular in waveform, the relation between peak-to-peak and RMS values of ripple voltage is given by:

\[
V_{PPripple} = V_{RMSripple}2\sqrt3
\]

For light loads the following approximation applies:

\[
V_{RMSripple} = \frac {I_{load}}{4\sqrt3 \,fC}
\]

where
$I_{load}$ = current draw of the load, in amperes
$f$ = mains/line frequency, in hertz
$C$ = capacitance of the filter capacitor, in farads

Peak-to-peak ripple is therefore,

\[
 V_{PPripple} = \left ( \frac {I_{load}}{4\sqrt3 \,fC} \right ) 2\sqrt3
\]

\[
 V_{PPripple} = \frac {I_{load}}{2fC}
\]

With a mains frequency of 60Hz the above simplifies to

\[
V_{PPripple} = \frac {I_{load}}{120C}
\]

In my design I set a limit of $V_{PPripple}$ = 1V. Plugging that into the formula yields a capacitor value of 8333µF. I will use either two 4700µF or one 10mF. Cap working voltage should be a minimum of 50V given the 40VAC peak of the transformer.

To adjust the 317's output I'm using is a Bourns 3590S 5Kohm 10-turn precision potentiometer. A high quality pot is necessary to achieve good, reliable, stable resistance and, consequently, voltage output. 


----

Note: LaTeX math code was embedded using mathcache

----

References:

1. LM317 constant voltage reference design with protection diodes and bypass capacitors: STMicroelectonics LM317 datasheet.

2. Equations for power dissipation of LM317 and heatsink requirements: National Semiconductors LM317 datasheet.

3. Single-supply comparator hysteresis equations: Microchip MCP6541 datasheet.

4. Equations for filter capacitor ripple voltage: Electronics Devices and Circuit Theory, 4ed, Robert Boylestad & Louis Nashelsky, 1987,  p.675 and Appendix B.; Nuts and Volts, February 2004, p.11.


Tuesday, August 10, 2010

Xtreme infrared remote control

A/V remote controls in my sister's home are always undergoing torture tests. Thus far, none have passed muster. One of the more recent losers has been an el cheapo China-made DVD remote control with the brand "Xtreme." As you can see in the photos below parts of the plastic case have broken off and the rubber  button for "volume down" has literally been ripped (or bitten) off. Courtesy of the toddlers, of course.

As always this gadget landed on my bench to be operated on and resurrected if at all possible. Well it worked after some tinkering with the infrared LED which was showing rather advanced pin corrosion, only to die yet again just a day later. Came back to me for surgery once more. After an inordinately long time--as in hours!--and only after checking the VBE of the S9014 NPN transistor (used to switch the LED) with an oscilloscope did I finally find out that the LED wasn't working right anymore. Sure, it would light up (crudely determined via a cell phone camera) if directly connected to a DC current source, but it can't operate properly at all at 38kHz.

I could easily replace the LED, but the control's plastic casing is so badly battered it's better to just buy a new remote. That is, if you can find one. I swear I tried, scouring shops for a good two hours. Seems like no one sells replacements. Eerily, I didn't see anyone selling China DVD players either. And none of the universal remote controls I've checked list "Xtreme" in their repertoire.

And so it was back to the PCB, this time to determine the infrared protocol it was using. At first I thought it was employing the JVC protocol. But it turns out Xtreme uses NEC's (see reference section below). I don't know if Xtreme actually even obtained permission from NEC since the device address it uses is 0x00. I've also checked a Kolin remote control and its address is 0x9D40, which seems to imply that that's what NEC has assigned to Kolin (or Kolin air conditioners). Obviously Kolin uses the extended NEC protocol since it's address is 16 bits long.

To find out the protocol being used and the button codes I hooked up an oscilloscope to the MCU output leading to the base of the transistor. Here are some of the button codes I've deciphered thus far:

button on Xtreme DVD remote controlcommand code in hex
POWER 0x0C
10x00
20x01
90x08
10+0x0A
100x0B
cursor/arrow up0x10
cursor/arrow down0x11
cursor/arrow left0x12
cursor/arrow right0x13
ENTER0x0E
CLEAR0x1B

In the photos below the red (base) and blue (collector) wires coming off the board is where the S9014 NPN used to be. The pins of the transistor were badly corroded and I replaced it, only to find out it was still working! I've hooked these "breakout" wires to transistors/LEDs/resistors on a breadboard to test the pcb. In the photo of the LED you'l see that I've added a 10-ohm resistor since I couldn't find any current limiting resistor on the board. The foil path from the Vcc to anode and cathode to transistor collector is around 1.5 ohms total (I used a Fluke 8842A with test lead resistance nulled). Don't know whether this <2-ohm resistance is sufficient. Neither do I have any idea of the LED's characteristics--if it has some integrated resistance or something. Or if the NPN is being used to regulate maximum current through the LED since the transistor itself does not have a discrete base resistor. The orange rectangular component marked "GHB 455E" is a 455kHz ceramic resonator. It's flanked by its two ceramic caps. Electrolytic filter capacitor is 47uF 10V.



NEC infrared protocol references:

Thursday, July 22, 2010

HP RPN online

For those like me who don't have an Reverse Polish Notation (RPN) calculator but would like to try one out or use one without actually getting a unit, here's one by Hewlett Packard.

I've always been a Casio devotee. And currently my scientific calculator of choice is the FX115MS. Love it. Has every function I need. If it were programmable it would be perfection itself.

Tuesday, July 20, 2010

Where's the spec?

I've been going over the Fluke 80 Series V user's manual but I can't find the specs for the DCmV impedance when high input impedance mode is set. Input resistance is normally 10MOhm but when the "Hz %" button is held down when the meter is turned on its goes into high impedance mode in the DCmV range.

The Fluke 87 (original series) manual actually states how much it is: "The input impedance of the function (400 mV range) is changed from 10 megohms to greater than 4000 megohms." But that's for the 87 not the 87V.

Googling turned up only one source for this datum. Fortunately, it's pretty reliable since it comes from one of Fluke's own engineers. Chuck Newcombe tells us that,
If you want to measure a high impedance dc source, and the anticipated voltage is less than 600 mV, the Fluke 87V has a power-up feature that can save the day. Just hold the 'Hz %' button while you turn the meter on to remove the 10 megohm divider from the circuit. Now, the dmm's loading effect is greatly reduced, with an input resistance of 1000 Megohms or more. 
So there. For the 87V high input impedance mode value is at least 1000 Megs.

Why this isn't in the specs section of the manual boggles the mind.

Sunday, July 11, 2010

Half a Fluke






Always dreamed of having a bench multimeter. Sure can't afford a brand new Fluke. So I settled for a couple decade old 8842A. Got it off ebay. Was excited to start using it when it arrived. But just minutes into checking the various functions my heart sank when I discovered the AC functions weren't working. "Error 30" kept popping up whenever the "VAC" and "mA ~" buttons were pressed. That could only mean that the AC circuit board isn't installed! That's despite the fact the supplier had told me personally that all the functions--including AC--were working fine. But that wasn't the worst of problems. Turned out the power switch is faulty. After turning the unit off for the first I had trouble getting it switched back on. It's a pushbutton type that mechanically latches. Apparently the mechanism is already dodgy. Had to press it several times for it to stay in the down (on) position. After turning it off for a second or third time the switch just died. That was when my heart stopped. I had bought a lemon. I now had a $300 paperweight adorning my workbench.

Lesson learned. Don't buy expensive antique second hand equipment from half a world away unless you're prepared to be disappointed and unless you can afford to have it sent back in case it's not as described in the ad and/or is defective.

Fortunately that isn't the end of the story. The following day I performed CPR on the Fluke. I kept pressing the switch--gently!--while turning the unit over and on its sides. I was banking on the off and off chance that gravity might help get the switch mechanism to engage. I don't know if the turning helped at all but after a minute or so of pressing the switch actually engaged. Well, that was it--I was not ever, ever going to push that button again. No way I'm going to risk being unable to switch this meter on again.

To power the unit up and down I'm now using an extension cord that has a similar latching pushbutton switch. I've already turned the meter on and off at least a dozen times over the past few days and the unit seems to not mind. I'm just crossing my fingers it stays that way. Will eventually have to look for a service center that can replace this switch. My concern, however, is loss of calibration when they take the unit apart, and what component they might wreck!

As a precaution I've stuck a neon yellow Post-It over the 8842A's green power switch to prevent me from accidentally pressing it! Given how absent-minded I am that's bound to happen without this warning sticker.

This is a calibrated unit (well at least that's what the seller tells me) and initial tests show that it is in fact pretty accurate. I used another Fluke and did a side-by-side test of the DCV, DCmA, and ohms ranges and readings from both meter are within 0.01% of each other. The other Fluke has much less resolution so the two meters are hardly on equal footing.

Friday, June 25, 2010

Shape up, Farnell

Four weeks after I placed an order with Farnell, the ICs haven't arrived yet. Their lead time is 1 to 3 weeks. I emailed them saying it was way past the maximum lead time they had provided me. A representative of theirs called me the next morning and told me that all the parts were already in their local warehouse, except for one. And that one part has a lead time of 32 weeks! 7 months! Well, why the heck didn't they tell me earlier? And why didn't they deliver the components that are already in their office? Why did the client have to follow up before informing him of this extraordinary situation? Uhh!

The person I spoke with told me she'll get on matter immediately and deliver the parts that are already around. She gave me the option of retaining or canceling the IC that won't be available till next year. After I said it would be good if could be cancelled, she said she'll have to check whether it can be cancelled. Argghh! Doesn't this company have a policy in place for these situations? This isn't at all what I expect from a global distribution company. Three thumbs down.

I rarely purchase from Farnell because their prices are way higher than RS Components'. The only reason I ever get from Farnell is if RS doesn't carry the part. And I only buy from RS when local suppliers don't have what I need. With this unforgivable incompetence, Farnell has slipped further than last place in my list.

Tuesday, June 22, 2010

Sayonara to Sanwa DMMs

It may be strange to hear but the only multimeters I've used over the decades are those by the Japanese company Sanwa.I've laid hands on various Made in China meters, some of which were Fluke look-alikes, but hey those meters aren't even worth having had for free.

In my small collection I have a very old N101 (purchased c.1970s) which I inherited from my dad. I'm still using the original test leads, and have the original box and its manual (which includes a complete schematic). I really like this meter, specially its exterior design. I don't think there's a Sanwa analog meter that can beat its clean, smart, modern, look. I've burned this meter in the past--accidentally poking the VAC mains while the range switch was set to ohms. You get the shock of your life from the BZZZZT that goes off inside the meter. And you end up with deep fried resistors for lunch. Great thing about these old analogs is that they use large through-hole components which are so easy to replace. Take out the burnt component and solder in a new one and it's good to go again. No ICs to worry about. No surface mounts. Of course, accuracy isn't one of its strong points. But it's good to have one (inexpensive) analog around, even if only as a backup meter. And hey, this N101 is quickly becoming an antique. Maybe it's already appreciating in value. This unit is a keeper. I want to pass it on to one of my nephews--one who will eventually grow up to have a love for electronics/electrical work.

About two decades ago I bought my first digital multimeter--the CD721. (Sorry no pics available.) As always I wrecked this meter within a couple of years. Shot its brain with 240VAC while it wasn't expecting it--ohms range. And moreover, the plastic casing is now bloated. I can't remember exactly how that happened, but it could've been because I left it baking inside the car while it was parked in the sun--we're talking of something like 50Celsius. The CD721 is with my sister now. I have no use for that piece of junk. Her kids like playing around with it though. Yes, I have taken precautions so that the little ones won't be able to stab themselves with the probes or get themselves roasted poking into outlets.

Got a CD771 back in 2007 for around $65 to $70 (depending on what the dollar conversion rate was at that time). I don't even use my meters on a weekly basis. And yet this dang unit has already been on the blink for a year now. It just sucks. When this meter works, it works quite well. But when it's in a fit, it'll throw garbage at you. During those moments, the meter might give yo a reading of 40V while you're measuring a 5VDC circuit or it might even display "OL" meaning it's out of range. And the resistance might read several megohms when you short the probes and autoranging slows down to a crawl. To get the meter to work again I switch it off then on again. Usually after one or two such resets the meter gets its sanity back.

So in terms of ruggedness and reliability I can't but give Sanwa digital multimeters a two thumbs down. I've really become sick and tired of Sanwa DMMs that I got myself a Fluke. No cheapo. The Fluke 80 series is some 5 times pricier than the Sanwa. It hasn't arrived but I know I won't be disappointed. And that's one DMM I'm certain will proudly be on my bench and in my tool box for decades to come.

Monday, June 21, 2010

Thou shalt not turn an op amp into a comparator

Is that writ in stone? A commandment from Mt. Sinai no less?

Texas Instrument engineers Bruce Carter and Ron Mancini say that using an op amp as a comparator is a no-no because "an op amp has an output stage optimized for linear operation, while the output stage of a
comparator is optimized for saturated operation." Moreover, "the comparator is an open loop device, utilizing no feedback resistors." The op amp, on the other hand, is
optimized for closed loop applications. The results are unpredictable when an op amp is used open loop. No semiconductor manufacturer can or will guarantee the operation of an op amp used in an open loop application.
Yet more bad news:
The transistors used for op amp output stages are not switching transistors.... When saturated, they not only may consume more power than expected, they may also latch up. Recovery time may be very unpredictable. One batch of devices may recover in microseconds, another batch in tens of milliseconds. Recovery time is not specified, because it cannot be tested. Depending on the device, it may not recover at all! Runaway destruction of the output transistors is a distinct possibility in some rail to rail devices.
There can be exceptions to the rule, however. 
In some cases, the designer may get away with using an op amp as a comparator. When an LM324 is operated in this fashion, it hits a rail and stays there, but nothing 'bad' happens. The situation can change dramatically, however, when another device is substituted.
But what if we use the op amp with positive feedback? That's no longer open loop, right? Well that's a question that Carter and Mancini don't tackle. And positive feedback is what we put into the touch sensor op amps to turn them into comparators with hysteresis. So does that make the use of op amps as comparators ok? Doubt it. Even if that solves the open loop problem, it still leaves the issue of op amps being used to saturation and slamming its output to rail. Then again maybe we'll get lucky and will be able to get away with it, depending on the op amps we use.

Engineer James Bryant of Analog Devices has the same advice as the guys from TI.
[T]he best advice on using an op amp as comparator is very simple—don't! Comparators are designed to work as open-loop systems, to drive logic circuits, and to work at high speed, even when overdriven. Op amps are designed for none of these. They are intended to work as closed-loop systems, to drive simple resistive or reactive loads, and should never be overdriven to saturation.
Damn.

Bryant does address the matter of building hysteresis into the op amp.

He concludes on a more positive note:
[A]lthough op amps are not designed to be used as comparators, there are, nevertheless, many applications where the use of an op amp as a comparator is a proper engineering decision. It is important to make an educated decision to ensure that the op amp chosen performs as expected.

To do this, it is necessary to read the data sheet carefully and to consider the effects of nonideal op amp parameters on the application. Because the op amp is being used in a nonstandard manner, spice models may not reflect its actual behavior, and some experiment is advisable. Furthermore, because not all devices are typical in their behavior, some pessimism is warranted when interpreting the experimental results.

----

Reference:

Bruce Carter & Ron Mancini, Op Amps for Everyone, 3rd ed., Newnes, 2009, p. 535-538.

Sunday, June 20, 2010

A purely analog touch sensor

My sister's family and I spent the afternoon together last Sunday. Had a late lunch at a fine dining restaurant. Food was great. Unfortunately the kids still need years to develop a taste for good food. Their dad said he'd just bring them to Krispy Kreme after lunch to fill their bellies.

At least twice during the meal the 5- and 4- year old had to go to the washroom. Being the good and lovable uncle I accompanied them.Well, it proved to be an adventure for the boys. The urinals in the air conditioned and plush restrooms had infrared sensors to detect the presence of, well, humans. As can be expected the brats had a ball playing with them, tripping them off with their hands and watching as the gizmo flushed water down.

That evening it occurred to me that I could easily design a circuit the kids can have fun with to turn on a light or just an LED. I already have a circuit installed in my home that switches on the ceiling lights whenever I cross the hallway. It's a windowless area and is pitch black at night. With the circuit I don't have to go back and switch off the lights. The sensor is a Keyence PZ-51 infrared transmitter-receiver with an NPN output, which I set up as a reflective system with the emitter and detector side by side. When something/someone reflects enough of the infrared beam back to the receiver the circuit gets triggered and the lights are switched on for a little over half a minute. A 3-second beep sounds right before the lights go out to warn the person.

Given my experience with photoelectric sensors and the fact that I still have a number of these Keyence products I got from a sale almost a decade ago, I started designing a circuit based on photosensors. But I hadn't even drawn a single schematic when it hit me that this was just overkill. Using an industrial part like the Keyence didn't seem right. Worse, it isn't kid-proof at all!

I needed something simpler and more rugged, something more or less immune to the bashing, smashing, "crayoning," drooling, and what-have-you the sensor will be up against and subjected to with a brood of 2-, 3-, 4-, and 5-year olds. So it occurred to me--Why not detect the 60Hz hum that everyone in the city conducts? That way the sensor could be any conductor--a length of wire, small thumb-sized metal sheet, maybe even the door handle of a cabinet.

Mulling over the circuit requirements, it seemed to me that what had to be done was to amplify the signal from the human touch and pass it through a comparator with hysteresis to get a good clean digital output. I hit the breadboard and configured one of the op amps of a MCP6232 dual op amp as a noninverting amplifier with a gain of 100 and the other as a comparator. Well, surprisingly, it worked!

Oscilloscope showed, however, that there was a lot of high frequency noise being amplified as well. So I figured I'd add a low pass filter (LPF) at the front end (before the amplifier) with a cutoff frequency (Fc) of around 120Hz .To try it out I used a good round figure of 100Kohm and 10nF which gave an Fc of 160Hz.(equation is 1/(2πRC)). Sure enough it cleaned up the signal pretty well.

The design was practically finished and I could feed the 60Hz pulse train output of the comparator to a microcontroller and have that MCU process the signal and turn on lights and buzzers, etc. for, say, a specified amount of time. It can even reject rapid multiple "button presses" to prevent the light from being turned too many times a minute. Or it can process such multiple contacts as a code to turn the load on for a certain amount of time or certain fashion, etc. Once the analog end was able to provide a reliable signal, the MCU could do the rest. And if the MCU had an onboard comparator then we need only filter and gain the input signal before sending it to the MCU.

But I wasn't satisfied. I wanted to push myself and create an output (from the op amps) that stayed high (Vcc) the moment the comparator was triggered and then drop out (go to ground) once the 60Hz pulse train ceased. In other words, if I hooked up the output to trigger an NPN, the transistor would be completely and continuously on while the user was touching the sensor.

So what I had to do was to convert that pulse train from the comparator to a DC signal that would rise to and remain above a certain minimum voltage while the user was touching the sensor. My solution? An LPF with a Fc of <60Hz.

As a first cut, I used a 1uF tantalum and 100Kohm to give an Fc of 1.6Hz.  I then got another MCP6232 and configured one of the op amps as a noninverting comparator (with no hysteresis). The output of the passive LPF was then fed directly into the noninverting input of the op amp.

Lo and behold! I got what I wanted. Well, almost. Not surprisingly the long RC constant of the 1.6Hz LPF caused a hell of a delay in the response of the second comparator. After the user touches the sensor it took tens of milliseconds for the voltage to ramp up to the trip point of the comparator and then after the sensor ceased detecting contact, it took about a hundred milliseconds for the voltage to decay below the trip point. Very slow and humanly noticeable delay.

To alleviate this, I had to decrease the RC constant which meant increasing the Fc. I chose 6Hz. Oscilloscope showed a very significant increase in ripple voltage. And this of course meant that the comparator (remember, it had no hysteresis) could rapidly go high and then low and then high again as the voltage was passing the comparator trip point. And in fact, tests showed that this does happen every once in a while. This meant that hysteresis had to be designed into the circuit.

Which I did. I added positive feedback using two resistors. When I tried the circuit it was a dud. Why? Because the output of the passive LPF is high impedance. The noninverting input of the comparator is very high impedance but with the positive feedback resistors also connected to the noninverting pins of the op amp that just changes the circuit characteristics. Solution was simple but required the use of another op amp. The LPF had to be buffered by a voltage follower (unity gain amplifier). This low impedance signal could then be fed to the comparator with hysteresis.

The following is the final circuit (for now) after tweaking the values for the LPFs, hysteresis, comparator voltage reference, etc. Load resistor RL is necessary and has to be high value. The lower the value the more attenuated the signal becomes. I used a 3Meg in the test circuit. The front end LPF has a Fc of 72Hz. You might notice the "coax." in the schematic. A coaxial cable is needed only if the sensor--a fingernail-sized touch plate for instance--will be located more than a few centimeters from the circuit board. Any plain old conductor acts as an antenna picking up the 60Hz hum; and the longer the conductor the higher the amplitude of the signal. At the amplifier gain of 100, a wire longer than 20 centimeters will transmit a large enough signal to trigger the first comparator. I've actually tried using a meter-long coaxial wire and it does work--the circuit is not triggered unless the far end of the coax is touched. The copper braid (shield) of the coax must be electrically connected to circuit ground.

Note that amplifier A3 is no longer a voltage follower that buffers the 6Hz LPF, but a noninverting amplifier with a gain of 2. The reason is that the buffered LPF signal was approx 2.3VDC with a ripple voltage of around 850mV peak to peak. The upper threshold trip voltage of the comparator A4 is about 1.8VDC. This is no problem when the sensor is fully touched--that is, output of A1 reaches the positive rail (and you get a quasi rectangular pulse train, not a half sine wave). But when A1output is weak (low amplitude but is above the upper threshold trip voltage of comparator A2) the duty cycle of the output of A2 drops and so there is much less on time for CF2 to charge, resulting in a much lower average DC of the LPF output. This causes comparator A4 to fail to trigger. Thus, it was necessary to gain the LPF output to make sure that when A2 trips, A4 will trip too. Both comparators are referenced to 30% Vcc.

Finding the equations for determining the upper and lower threshold voltages of the comparators has been a headache. Still is. The commonly given equations in textbooks are for op amps/comparators using a bipolar power supply. I'm using a single supply. I did find single supply equations in the datasheet for the MCP6541 comparator. However, measurements using an oscilloscope (see below) do not tally with the results from the equations. Perhaps input signals to comparators A2 and A4 need to be buffered.

What follows are oscilloscope (Rigol 1102E) screenshots of the circuit in action. Refer to the schematic for test points P1 to P4.


Test point: P1

Output of A1 when sensor (a 14-cm AWG 22 wire) has not been touched. As can be seen the measured frequency is 60.2Hz and Vpp = 720mV



Test point: P1

Output of A1 when sensor touched. The amplifier saturates. (The Vpp as measured by the scope can't be right of course given the 1.00V/div)



Ch1 test point: P2
Ch2 test point: P1
Ch1: 2.00V/div
Ch2: 1.00V/div
Trigger: Auto, Ch2, 200mV, rising edge

Sensor touched. The output of comparator A2 is almost a square wave. The output of A1 is coming close to square wave. (The scope's Vpp measurement of A1 output is now correct)



Ch1 test point: P2
Ch2 test point: P1
Ch1: 2.00V/div
Ch2: 1.00V/div
Trigger: Auto, Ch2, 200mV, rising edge 

Sensor not touched.



Ch1 test point: P3
Ch2 test point: P1
Ch1: 2.00V/div
Ch2: 1.00V/div
Trigger: Auto, Ch2, 200mV, rising edge 

Sensor is touched. In the above screenshot output of A3 has already stabilized. With the gain of 2 the LPF output reaches positive rail.



Ch1 test point: P3
Ch2 test point: P2
Ch1: 2.00V/div
Ch2: 1.00V/div
Trigger: Auto, Ch2, 200mV, rising edge

Sensor is touched. 



Ch1 test point: P2
Ch2 test point: P1
Ch1: 2.00V/div
Ch2: 1.00V/div
Time base:10.0ms/div
Trigger: Single sweep, Ch1, 200mV, rising edge,

Here we see the very moment A1 output trips comparator A2



Ch1 test point: P2
Ch2 test point: P1
Ch1: 1.00V/div
Ch2: 1.00V/div
Time base: 500microsec/div
Trigger: Single sweep, Ch1, 200mV, rising edge,

This is a zoomed in portion of the preceding single sweep capture. Cursors have been turned on and manually adjusted to the point of intersection between the output of A1 and A2. The scope measures the hysteresis band at 840mV. Comparator A2 upper threshold voltage = 1.88V, lower threshold voltage = 1.04V



Ch1 test point: P3
Ch2 test point: P1
Ch1: 1.00V/div
Ch2: 1.00V/div
Time base: 20.0ms/div
Trigger: Single sweep, Ch1, 200mV, rising edge,

This clearly shows that because of the RC constant of the 6Hz LPF there will be a delay before A4 output goes high.



Ch1 test point:P4
Ch2 test point: P1
Ch1: 1.00V/div
Ch2: 1.00V/div
Time base: 20.0ms/div
Trigger: Single sweep, Ch1, 200mV, rising edge

The delay between touching the sensor and A4 output going high can be seen here. Also shows the clean digital output of A4. The ripple voltage is due to the power supply.




Ch1 test point: P3
Ch2 test point: P2
Ch1: 1.00V/div
Ch2: 1.00V/div
Time base: 50.0ms/div
Trigger: Single sweep, Ch2, 200mV, rising edge

Rise and decay of A3 output in relation to comparator A2 output




Ch1 test point: P3
Ch2 test point: P2
Ch1: 1.00V/div
Ch2: 1.00V/div
Time base: 20.0ms/div
Trigger: Single sweep, Ch2, 200mV, rising edge




Ch1 test point: P4
Ch2 test point: P2
Ch1: 2.00V/div
Ch2: 1.00V/div
Time base: 20.0ms/div
Trigger: Single sweep, Ch2, 200mV, rising edge

A4 output in relation to A2 output. What is most evident is the large delay in A4 output droput



Ch1 test point: P4
Ch2 test point: P2
Ch1: 2.00V/div
Ch2: 1.00V/div
Time base: 2.0ms/div
Trigger: Single sweep, rising edge, Ch2, 200mV

This is a zoomed in portion of the preceding capture. Cursors are on to measure the delay between comparator A2 output and A4 output. In this particular case it's 3.5ms




Ch1 test point: P4
Ch2 test point: P2
Ch1: 2.00V/div
Ch2: 1.00V/div
Time base: 2.0ms/div
Trigger: Single sweep, Ch2, 200mV, rising edge

This is a zoomed in portion of the second to the last capture. Cursors are on to measure the delay between comparator A2 dropout and A4 dropout. In this case it's 57ms.


 
Ch1 test point: P4
Ch2 test point: P3
Ch1: 1.00V/div
Ch2: 1.00V/div
Time base: 50.0ms/div
Trigger: Single sweep, rising edge, Ch1, 1.0V




Ch1 test point: P4
Ch2 test point: P3
Ch1: 1.00V/div
Ch2: 1.00V/div
Time base: 2.0ms/div
Trigger: Single sweep, Ch1, 1.0V, rising edge

This is a zoomed in portion of the preceding capture. Cursors are on to measure the upper threshold trip voltage of comparator A4. In this case it's 1.80V.




Ch1 test point: P4
Ch2 test point: P3
Ch1: 1.00V/div
Ch2: 1.00V/div
Time base: 2.0ms/div
Trigger: Single sweep, Ch1, 1.0V, rising edge

This is a zoomed in portion of the second to the last capture. Cursors are on to measure the lower threshold trip voltage of comparator A4. In this case it's 880mV. The hysteresis band = 920mV.




Ch1 test point: P4
Ch2 test point: P1
Ch1: 1.00V/div
Ch2: 1.00V/div
Time base: 50.0ms/div
Trigger: Single sweep, rising edge, Ch1, 1.0V

A4 output in relation to A1 output.




Ch1 test point: P4
Ch2 test point: Vcc
Ch1: 1.00V/div
Ch2: 1.00V/div
Time base: 20.0ms/div
Trigger: Single sweep, Ch1, 1.0V, rising edge

This one shows the ripple voltage present in Vcc. Also shows how close to the rail A4 output is.

---------------------

Addendum
June 20 11:00pm

I reduced the cutoff frequency of the front end LPF to 1.6Hz by changing CF1 to 100nF. Touching the sensor didn't even trigger A2. I then increased the gain of A1 to 400. Didn't work either. I couldn't get A1 and A2 to have the outputs of A3 and A4 respectively. Seems there are no shortcuts.