4 Replies Latest reply on Nov 26, 2019 9:49 AM by EyLa_1625036

    Timer reads 0 - issue

    EyLa_1625036

      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.

        • 1. Re: Timer reads 0 - issue
          LePo_1062026

          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

          • 2. Re: Timer reads 0 - issue
            MoTa_728816

            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

            • 3. Re: Timer reads 0 - issue
              EyLa_1625036

              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

              • 4. Re: Timer reads 0 - issue
                EyLa_1625036

                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