walumbe
Junior Member level 2
- Joined
- Oct 15, 2013
- Messages
- 20
- Helped
- 0
- Reputation
- 0
- Reaction score
- 0
- Trophy points
- 1
- Activity points
- 174
Code Basic4GL - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 dim Count as word dim Temp as byte dim DarkValue as word sub procedure Interrupt if GPIF_bit = 1 then Temp = GPIO ' Any access to the GPIO register will reset the IOC Count = 0 ' Each time an edge is detected at GP1, reset the timer end if GPIF_bit = 0 ' Clear the Interrupt flag end sub main: ANSEL = %00000001 ' Set AN0 as analog and the rest digital ADCON0 = %00000001 CMCON0 = 7 IOC1_bit = 1 ' Enable Interrupt-on-change feature at GP1 GPIE_bit = 1 ' Enable peripheral interrupts TRISIO = %00000011 ' Set GP0 and GP1 as inputs , GP2 as output GPIO.B0 = 0 ' Initial GP0 value -> Input Dark Sensor GPIO.B1 = 0 ' Initial GP1 value -> Input Vibration Sensor GPIO.B2 = 0 ' Initial GP2 value -> Output LED Count = 0 ' Initialize count while TRUE DarkValue = ADC_read(0) if (DarkValue > 286) and (Button(GPIO, 1, 5, 1)) then ' Checks for voltage >1.4V at GP0 and a high at GP1 GPIO.B2 = 1 ' Turn on transistor to power the LED board GIE_bit = 1 ' Enable interrupts before entering the counter loop do Delay_ms(12) 'Delay for 12ms Inc(Count) loop until Count = 10000 GIE_bit = 0 ' And disable them after leaving Count = 0 ' Reset counter when the loop ends GPIO.B2 = 0 ' Turns off the LEDs end if wend end
remove your interrupt routine, test the gpio.b1 bit inside your main delay routine it will be easier
dont bother with interrupts if you dont need to.
Code Basic4GL - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 dim Count as word dim Temp as byte dim DarkValue as word //sub procedure Interrupt // if GPIF_bit = 1 then // Temp = GPIO ' Any access to the GPIO register will reset the IOC // Count = 0 ' Each time an edge is detected at GP1, reset the timer // end if // GPIF_bit = 0 ' Clear the Interrupt flag //end sub main: ANSEL = %00000001 ' Set AN0 as analog and the rest digital ADCON0 = %00000001 CMCON0 = 7 IOC1_bit = 1 ' Enable Interrupt-on-change feature at GP1 // GPIE_bit = 1 ' Enable peripheral interrupts TRISIO = %00000011 ' Set GP0 and GP1 as inputs , GP2 as output GPIO.B0 = 0 ' Initial GP0 value -> Input Dark Sensor GPIO.B1 = 0 ' Initial GP1 value -> Input Vibration Sensor GPIO.B2 = 0 ' Initial GP2 value -> Output LED Count = 0 ' Initialize count while TRUE DarkValue = ADC_read(0) if (DarkValue > 286) and (Button(GPIO, 1, 5, 1)) then ' Checks for voltage >1.4V at GP0 and a high at GP1 GPIO.B2 = 1 ' Turn on transistor to power the LED board // GIE_bit = 1 ' Enable interrupts before entering the counter loop do Delay_ms(12) 'Delay for 12ms if GPIO.B1 = 1 then Count = 0 Inc(Count) loop until Count = 10000 // GIE_bit = 0 ' And disable them after leaving Count = 0 ' Reset counter when the loop ends GPIO.B2 = 0 ' Turns off the LEDs end if wend end
There is (may be) a problem with the GPIO Change Interrupts. See the datasheet (12.4.3):
"If a change on the I/O pin should occur when any GPIO operation is being executed, then the GPIF interrupt flag may not get set."
In my opinion use the external interrupt on the GP2/INT (datasheet 12.4.1) for sensing the vibration, and use GPIO.B1 for LED output.
Sorry, I misunderstood you.
But:
you wrote this:
"Then issue is the dark sensor not being read once once it enters the interrupt routine"
Of course, since this is the logic of your program.
When the interrupt is (re)occured (a new sensor event), the internal do loop (the 120.000 ms = 2 min delay) always restarts, and stays here, regardless of the adc value since it is not measured here.
In other words, if the sensor signal switching is repeated within two minutes, the program remains in the internal timer loop and never get to the LED off.
The vibration sensor is likely provides repeating signals I think.
I do not know exactly what you want, but you have to change your program logic, for example, be sure to turn off the LED over a given ADC value, regardless of the value of the timer counter.
Other: what compiler you are using? What does exactly the Button function? Is it a debounced pin-reading? I do not like such high-level things because I don't know exactly what's happening...
zuisti
I was afraid of. In my opinion this Button function is unsuitable for read such a repeating signal, since it gives (can give) a random result due to its operation principle (the debouncing), when the signal is oscillating. Instead use an another method, eg a flag, see below.The Button command is for debouncing as the switch that I'm using has two rolling balls inside it and does not instantaneously change its state when tilted/vibrated.
It is not clear to me (sorry), what's the GP1 pin's resting state (when no vibration). Is it LOW?GP1 - a vibration sensor switch (Shot Circuit when there is no vibration) tied to ground with a resistor tied from this pin to +5V
In my opinion you could do, have to a bit of logic.... I'm not familiar with the "changed" flag and how start using it. Examples or links to them would help.
Code Visual Basic - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 ' PIC12F683 Led control, using darkness and vibration sensor ' Written by zuisti, copyright © Istvan K. 2013 dim DarkValue, DarkCompare, Count as word ' DarkValue will be compared by a "software Schmitt-trigger" ' to avoid any switching uncertainties at dusk or at dawn :-) #define DARK 286 ' switching point (value) #define HYST 5 ' switching hysteresis (now appr +- 2% ?) dim Changed_fl as bit ' set in interrupt (sensor 'event' was occured) dim LedState_fl as bit ' to avoid undesirable IOC resets sub procedure Interrupt if GPIF_bit = 1 then ' an "anti-prell" loop (micro-debouncing) do GPIO.B3 = 1 ' no Temp but an unused input-only pin ' Any access to the GPIO register will reset the IOC GPIF_bit = 0 ' try to clear the Interrupt flag (in a loop) GPIO.B3 = 1 loop until GPIF_bit = 0 Changed_fl = 1 ' indicates a new sensor input changing (vibrating?) end if end sub main: ANSEL = %00000001 ' Set AN0 as analog and the rest digital ADCON0 = %00000001 CMCON0 = 7 TRISIO = %00000011 ' Set GP0 and GP1 as inputs , GP2 as output GPIO.B0 = 1 ' Initial GP0 value -> Input Dark Sensor GPIO.B1 = 1 ' Initial GP1 value -> Input Vibration Sensor GPIO.B2 = 0 ' Initial GP2 value -> Output LED Count = 0 ' Initialize count Changed_fl = 0 LedState_fl = 0 DarkCompare = DARK IOC1_bit = 1 ' Enable Interrupt-on-change feature at GP1 GPIE_bit = 1 ' Enable peripheral interrupts GIE_bit = 1 ' lastly enable global interrupts while TRUE ' main loop ' determine and compare darkness in every cycle DarkValue = ADC_read(0) ' the "software Schmitt-trigger": ' assuming a photoresistor type darkness sensor, which ' gives a higher voltage when the darkness is increasing. if DarkValue < DarkCompare then ' no darkness DarkCompare = DARK + HYST ' positive feedback Count = 0 GPIO.B2 = 0 ' always turns off the LEDs LedState_fl = 0 Delay_ms(12) ' need ? Changed_fl = 0 ' ignore any sensor changing continue ' again ' if no "continue" in this language then use a goto or a big else, instead end if DarkCompare = DARK - HYST ' the other direction positive feedback if Changed_fl = 0 then ' sensor resting state, timed led-off if it's on Inc(Count) if Count = 1200 then ' 2 min delay to off Count = 0 ' Reset counter if LedState_fl = 1 then 'to avoid undesirable GPIO accesses (IOC resets), only once: GPIO.B2 = 0 ' Turns off the LEDs LedState_fl = 0 end if end if else ' (sensor 'event' was occured) Changed_fl = 0 Count = 0 ' every (new) changing resets the counter if LedState_fl = 0 then LedState_fl = 1 'to avoid undesirable GPIO accesses (IOC resets), also only once: GPIO.B2 = 1 ' Turn on transistor to power the LED board end if end if ' enough time to receive a new changing if any (to avoid led flashing?) Delay_ms(100) wend ' end main loop end
Hi. I'm surprised because the program itself can not do such a thing.The LEDs flicker for a fractioin of a second each time the sensor is vibrated in the dark.
Such a point does not exist in the program, as you also can (notCould there be a point where GP2 is being turned off before the counter is reset?
It seems your analogue input signal is unstable. I wrote above:I added a 0.1uF filter capacitor from this pin to ground and is seems to stop/reduce the frequency of the flickering. The LEDs turn on for about a second then turn off when it is not completely dark.
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?