Timer reads 0 - issue

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
EyLa_1625036
Level 3
Level 3
10 likes given 10 sign-ins 25 replies posted

Hello all ,

i have a custom PCB with PSOC on it ,

i have 1 input pin controlled by a switch (switchPIN),

i have 2 outputs pins (resetPin , onoff_Pin),

i  implemented the following logic :

if someone turn the switch off switchPIN=0 and 6 sec is passed then turn off onoff_Pin-->0,

but if someone turn the switch off switchPIN=0

and BEFORE 6 sec is passed he turns on the switch switchPIN=1

then send reset pulse (resetPin =1 wait 100ms then resetPin =0).

i have 2 isr functions

when the switch is on :sw2_on_int is starting the timer

when the switch is off: sw2_off_int is stopping the timer.

this design works .

but if i start moving the switch very fast on and off

sometimes i get a weird bug .

the sw2_off_int isr is firing and reads 0 time this makes my whole design goes crazy .

i have no idea how can this happens ??

maybe i need to set isr priority?

2 isr is firing at the same time ??

can someone please review my code and tell me

am i doing wrong ???

the bug is in line 112

thank you.

pastedImage_4.png

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

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".

000-Debouncer.JPG

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.

001-schematic.JPG

2) Interrupts

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.

5) Indentations

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?

moto

View solution in original post

4 Replies
Len_CONSULTRON
Level 9
Level 9
Beta tester 500 solutions authored 1000 replies posted

EyLa,

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.

Len

Len
"Engineering is an Art. The Art of Compromise."

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

0 Likes
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

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".

000-Debouncer.JPG

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.

001-schematic.JPG

2) Interrupts

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.

5) Indentations

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?

moto

moto

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