I've been working on a replacement wall switch using a qprox touch switch. The basic circuit works fine, but I found that all normal flip-flops I used to toggle the output were sensitive to noise, and I needed to remember the state between power outages. So I bought a pickit2 and some 12c629 chips (they were the cheapest 8-pin dip with eeprom). After a couple of weeks working through several tutorials, I thought I was ready to tackle something as simple as emulating a flip-flop.
The qprox chip outputs a 95 millisecond pulse when triggered. I will have the output of several of these connected together by diodes to a common wire, pulled down with a 50k resistor. So I wrote a program to ignore any pulse less than about 90 ms, wait until the pulse was done, check for a lack of pulse for an additional ms, and then toggle an output pin. The problem is that when I introduce noise into the system, it still toggles my new software flipflop, even though the noise spikes are less than 90 ms. I introduce noise by plugging a transformer into the same ac circuit. It makes enough of a spike to make the speaker click on my pc.
I'm using gp2 as the input as it looks like it is a schmitt trigger when used as a general input pin. I'm using gp0 as an output. (I was using gp5 as an output, but for some reason the circuit quits working after using it a few times on this output?). So to trace the problem, I turn on gp1 to drive an led whenever I get a pulse bigger than 90ms, wait for the pulse to disappear for at least 1ms, and then toggle the output gp0, in the process turning off the test gp1 led.
The circuit works very well under normal circumstances.
The very strange thing is that when I introduce noise spikes into the system as above, I can see the gp1 led turn on and stay on, but it never gets to the code to switch the output gp0 pin high. I can't see how this can possibly happen looking at the code. I disable interupts every time through the loop.
So I need another set of eyes to find the problem. Any additional suggestions for this newbie would also be appreciated.
-Jim
Here's the code:
The qprox chip outputs a 95 millisecond pulse when triggered. I will have the output of several of these connected together by diodes to a common wire, pulled down with a 50k resistor. So I wrote a program to ignore any pulse less than about 90 ms, wait until the pulse was done, check for a lack of pulse for an additional ms, and then toggle an output pin. The problem is that when I introduce noise into the system, it still toggles my new software flipflop, even though the noise spikes are less than 90 ms. I introduce noise by plugging a transformer into the same ac circuit. It makes enough of a spike to make the speaker click on my pc.
I'm using gp2 as the input as it looks like it is a schmitt trigger when used as a general input pin. I'm using gp0 as an output. (I was using gp5 as an output, but for some reason the circuit quits working after using it a few times on this output?). So to trace the problem, I turn on gp1 to drive an led whenever I get a pulse bigger than 90ms, wait for the pulse to disappear for at least 1ms, and then toggle the output gp0, in the process turning off the test gp1 led.
The circuit works very well under normal circumstances.
The very strange thing is that when I introduce noise spikes into the system as above, I can see the gp1 led turn on and stay on, but it never gets to the code to switch the output gp0 pin high. I can't see how this can possibly happen looking at the code. I disable interupts every time through the loop.
So I need another set of eyes to find the problem. Any additional suggestions for this newbie would also be appreciated.
-Jim
Here's the code:
Code:
include p12F629.inc
__config _BODEN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT
;** note, case sensitivity turned off ( /c option)
; ra2 = gp2 = input (schmitt trigger)
; ra0 = gp0 = output
cblock 20
State ; state output should be at. 1h = gp0 on
wait1 ; wait amount (for 1 millisec)
wait2 ; number of millisecs to wait
endc
org 0
Start
bcf status,rp0 ; bank 0
clrf gpio ; initialize gpio (PORTA)
movlw 7h
movwf cmcon ; comparator off (gp2=schmitt input)
bsf status,rp0 ; bank 1
movlw 4h
movwf trisio ; Make gp2=input, all else output
bcf status,rp0 ; back to bank 0
clrf State
ww1
clrf intcon ; disable all interupts, just in case
btfss gpio,2 ; wait for leading edge of pulse
goto ww1
movlw .90 ; want at least a 90ms pulse
movwf wait2
ww2
movlw .200 ; set up for 1 ms delay
movwf wait1
ww3
btfss gpio,2 ;1
goto ww1 ; short noise pulse, ignore and start over
;1
decfsz wait1,f ;1
goto ww3 ;2
;total=200*(5)=1000us=1ms
decfsz wait2,f ; count off millisecs
goto ww2
bsf gpio,1 ;*** for debug, found >90ms pulse, turn on led
nop
nop
ww4
btfsc gpio,2 ; ok, long enough, wait for pulse to end
goto ww4
movlw .200 ; minimum width between pulses, 1ms
movwf wait1
ww5
btfsc gpio,2
goto ww4 ; must have been ringing, start over
decfsz wait1,f
goto ww5 ; wait a bit
movlw 1 ; gp0 (ra0) output
xorwf State,f ; toggle the output bit
movf State,w ; state of light, 1 = on
movwf gpio ; (porta)
goto ww1
end
Last edited: