I've looked at your design. I have a few suggestions/observations.
You are using a Debouncer component. Most switches will exhibit switch bouncing. In the automotive industry I work in, the minimum debounce time used is not less than 10ms. Usually we're required to have 30ms minimum. With your input clock to the debouncer at 1KHz, your debounce time us effectively less than 1ms. I recommend at least 10ms. Change just the input clock to the Debouncer to 0.1KHz
I also noticed that your "read" variable is set to float type. This means that "read=Timer6sec_ReadCounter();" does a conversion from an integer to a float. The conversion isn't always what you expect. Then later you perform some math on "read" which could get a bit confusing if not done properly. You also perform a equality decision on "read" on line 140: "if(read==0)". Note: Equality decisions with floating values are not recommended. This is because a '0' in float especially if math (this includes int to float conversions) is performed can sometimes yield a very small positive or negative value in float but not exactly '0'. Recommendation: Make "read" and integer and perform integer math to keep from having conversion anomalies.
Another thing I noticed is in the "void stop_Timer100ms(void)" routine you clear and stop the interrupt but don't actually stop the Timer100ms. Is this design intended?
I think I might have code validated your issue:
- You implement Timer6sec as an up counter and a one-shot. Therefore a reset of the counter goes to '0' when "start_Timer6sec()" is run.
- If "sw2_off_isr()" is run (which executes "start_Timer100ms()") within the first 1ms after "sw2_on_isr() (which executes "start_Timer6sec()"), the Timer6sec is still set to '0' as the counter value.
- If the above observation is correct, setting the Debouncer clock to 0.1KHz to make a longer debounce and should allow the Timer6sec to not see '0' as a count value because the minimum time between the "sw2_off_isr()" and "sw2_on_isr()" is greater than the input clock period to the Timer6sec and Timer100ms timers.
The accumulating age might have made me exceptious,
there are some parts I'd like to point.
(1) About the Debouncer
According to the datasheet of Debouncer, the internal circuit is something like below.
But you are using "q" so although you are placing a Debouncer it is working as a "dff".
So I modified the schematic as below
Note: As LePo-san has already mentioned, from my experience a human's response time is in order of 0.01 sec,
so about 10ms (= 100Hz) sampling would be appropriate.
I assigned 200Hz, as the datasheet of Debouncer suggested it as typ, but may be I'll make it to 100Hz later.
You are using Stop() and StartEx() for start and stop interrupt,
but Stop() un-configures the interrupt, I would recommend to use Disable() and Enable()
after you called StartEx() once, unless you change isr()s on the fly.
So I moved StartEx()s to init_hardware()
and replaced Start() and Stop() with Enable() and Disable() in ISRs.
3) variable name "read"
"read" is one of the basic API of C Standard Library.
So although it may work, I'd suggest you to use other name.
In my sample, I changed it to "timer_count".
For me "timer_count == 0" made more sense than "read == 0".
Since you are using 1000Hz clock, the count is ms order,
so I changed timer_count to uint32_t and printed it as 1/1000 sec value.
4) Start and Stop timer
You were not stopping the timer in "Stop_TimerXX" function.
Although it might have been your intention, I could not help adding "TimerXX_Stop()" in it.
Would you please take care of indentation(s)?
Wrong or capricious indentations makes the code very hard to read.
6) Where are we?
Although I'm reading this top in "PSoC 5LP MCU Community > Discussion",
I'd think this should have been posted in the "PSoC 4 MCU Community > Discussion".
Attached is my touched up version of your project.
Except above mentions, I hope that I have not touched the algorithm.
Would you check if there has been some improvement or is your problem still there?
thank you so much !
i have tested your design in the lab (with a few minor changes)
with different switches and a few hounded fast / slow on off movement
and this bug did not appear !
1 . using the debouncer pos neg is so much better - how did i not think about it .
2. Interrupts - i did not fully understood the difference between Stop() startex() and Disable() Enable() but now i know thanks.
3. yes this variable name is indeed a bit confusing.
4. again you are correct - thanks for this fix
5. Indentations - yes this is not the final release version it is very messy ,
has alot of unnecessary comments , and hard to understand now that i know the design is working
i will clean the code
6. Where are we- this specific project is on psoc 4 , but its kind of an independent device question
because i have tried this design on psoc 5lp and on psoc 6 and this issue happened on all of them
so i know i did something wrong . and its doesn't matter where i will post the question
thanks again for your time .
i learn a lot from your design
thank you Len ,
your comment about switches Debouncing helped me
understand the subject a lot better.
regarding the float variable Equality decisions i did not know there is
any issues with that its good to know from what to avoid in the future .
i have tried changing the clock to - 0.1KHz to make a longer debounce that should allow the
Timer6sec to not see '0' as a count value
but this did not solved the issue