Shop OBEX P1 Docs P2 Docs Learn Events
Help needed with Counters — Parallax Forums

Help needed with Counters

DRMorrisonDRMorrison Posts: 81
edited 2012-01-27 11:26 in Propeller 1
Hello, Hope someone can help.
I've created a small SPIN program to test a signal coming from my car. The alarm system has a LED that flashes once each second. The signal is pos 12V with a 20ms dip to zeroV.
I'm trying to use the Neg Edge detector of the counter to count dips in the signal that happen 4 or more times in a 2 second period. This lets me know that the alarm has been activated.
Otherwise, the signal drops to zero once each second, and the counter should only count a maximum of 2 dips in a 2 second period.

The code listed does not work as expected. The counter should not count but more than two neg edges in a 2 second period. But, the count variable increases by one no matter how
few neg edges are put on pin 0.
I'm new to using counters, so I suspect that I'm missing something. If you can see it, let me know. And thanks in advance.
(This is run on a demo board.)
CON      {{Test LED alarm signal for over-count during ON state of alarm:
            If the uProcesor counts incorrectly the number of LED pulses
            during the alarm ON state, count variable will increase and cause
            LED 23 on the demo board to flash once for each error. }}
                         
 _clkmode  = xtal1 + pll16x
 _xinfreq  = 5_000_000


 LEDpin = 0
 
var
 long count
 
PUB Main 


  dira[LEDpin]~                     'input
  dira[16..23]~~                    'output LEDs
  ctra := constant(0110 << 26 | LEDpin)  '0100 = NEG Edge detector. LED of alarm is active low when flashing.
  frqa := 1 
  count := 0
  
 Repeat
   repeat 1                            'flash LED 16 once/loop to indicate running app.
     !outa[16]                        
     waitcnt(clkfreq/50 + cnt)
     !outa[16]   
   phsa := 0                           'clear counter         
   waitcnt(clkfreq*2 + cnt)            'wait 2sec        
   if phsa => 4                        'check for over-count       
     count += 1                        'add to flasher count if over-count      
   repeat count
     !outa[23]                         'flash LED 23 count times
     waitcnt(clkfreq/20 + cnt)
     !outa[23]
     waitcnt(clkfreq/30 + cnt)

Comments

  • ElectricAyeElectricAye Posts: 4,561
    edited 2012-01-26 15:46
    It's not clear to me what you're trying to do, but one thing jumps out at me:

    You set phsa to 0, then you have an IF statement testing to see if it's => 4. What are you trying to do there?
  • kuronekokuroneko Posts: 3,623
    edited 2012-01-26 15:54
      ctra := constant(0110 << 26 | LEDpin)  '0100 = NEG Edge detector. LED of alarm is active low when flashing.
    
    Can you please verify your code? It seems that certain (external?) editors eat binary indicators when copy/pasting. NEGEGDE detection is %01110. That said 110dec comes out as %01101110 so no harm done really.

    The other thing is that you don't clear count, i.e. once you had an alarm going on count will stay e.g. 1 (which in turn will falsh you LED). That's based on the code you posted.
  • DRMorrisonDRMorrison Posts: 81
    edited 2012-01-26 16:07
    Electric Aye

    I'm trying to count the number of low pulses on the alarm LED flasher of my auto. The signal is goes low for 20ms once per second, but then goes low twice per second when an alarm
    is detected. By counting the low pulses for two seconds, I thought I could detect when the alarm went active: phsa => 4

    PM
    kuroneko

    For some reason some of the code was not pasted when I copied it over from the Parallax Tool, such as ctra := constant(01110 << 26 | LEDpin)
    should have read (110 << 26 | LEDpin)

    I'm currently testing this on the bench, and each time I send a neg pulse the count variable gets incremented, causing the second LED to flash.
    The first LED flashes once for each trip through the loop, jut to indicate that it is running. The second LED should only flash if the count var increases,
    and it should only increase if and when phsa sees more that 4 negative edges on the input, pin 0 in a 2 second period.
    The count var increases if phsa indicates more than 3 low edges have been detected on pin 0 during the 2 second period. If so, the second LED flashes
    more than once to indicate such.

    Maybe this is clearer: I want to count the number of negative pulses on the alarm LED signal during a 2 second period. If it goes to 4 or above, an alarm
    is active.

    I plan on setting this up in the auto over night to see if the timing is correct; a sort of trial run.

    Hope this is clear, Thank you, Daniel
  • kuronekokuroneko Posts: 3,623
    edited 2012-01-26 16:43
    DRMorrison wrote: »
    The second LED should only flash if the count var increases, and it should only increase if and when phsa sees more that 4 negative edges on the input, pin 0 in a 2 second period.
    Sure, but once you detected an alarm (count += 1) the next time you run through the loop count is still e.g. 1 so the loop at the bottom keeps flashing?! IOW after the first alarm it stays ON. Is that the intended behaviour (just checking)?

    Do you have a way of tracing the number of edges detected during the 2 second interval?

    As for your binary numbers, they still miss the leading % character. Copy/paste works for me from the PropTool. I never lost anything so far. Can you confirm that they are in the PropTool?
  • ElectricAyeElectricAye Posts: 4,561
    edited 2012-01-26 16:46
    Okay, I see what you're trying to do with phsa.

    I think kuroneko has some very good points.

    Also, when you do this:

    !outa[16]
    waitcnt(clkfreq/50 + cnt)
    !outa[16]

    I think you're only giving yourself 1/50 of a second to see the LED, true? Can you even see it blink in that short amount of time?
  • DRMorrisonDRMorrison Posts: 81
    edited 2012-01-26 17:37
    kuroneko
    It's okay, 'cause the second LED will blink more than once only if phsa counts 4 or more multiple times; at least that is how it is suppose to happen.
    If phsa counts 4 or more on several occasions, the LED will blink that many times, telling me that 4 or more were detected during the test period.

    The fault is that the counter is suppose to count the edges in phsa, and only advance the count var if phsa goes to 4 or more during the 2 second period.
    It increases even if there is only one neg pulse.

    ElectricAye
    I can see the flash; those LEDs are bright.

    This is suppose to only count during the 2 second pause, and then report if phsa goes to 4 or more, increasing count by one, and then causing the second LED to flash
    count times. This tells me later that the count was indeed 4 or more. This is to be set up in the car to monitor the signal overnight. I'm testing this on the bench, and it's
    behaving badly. I've never used these counters before, so I suspect that this is my problem.
  • kuronekokuroneko Posts: 3,623
    edited 2012-01-26 17:41
    DRMorrison wrote: »
    The fault is that the counter is suppose to count the edges in phsa, and only advance the count var if phsa goes to 4 or more during the 2 second period. It increases even if there is only one neg pulse.
    Can you tell us what the exact value of phsa is after 2 seconds?
  • DRMorrisonDRMorrison Posts: 81
    edited 2012-01-26 17:55
    That is a good idea. I shall use the debug tool to print it and let you know. I'll have to return to this tomorrow, so check back :smile:

    Thank you, Daniel
  • JonnyMacJonnyMac Posts: 9,198
    edited 2012-01-26 19:33
    Since the timing changes under an alarm condition, would it not be easier to watch for a falling edge, grab the clock, watch for the next falling edge, then check the clock again for the period? No counters required. Perhaps something like this -- which runs in its own cog and sets a variable to true or false)
    pri alarm_watch(pin, pntr) | t                                  ' start with cognew
    
      long[pntr] := false                                           ' deactivate to start
    
      repeat
        waitpne(1 << pin, 1 << pin, 0)                              ' wait for input to drop
        t := -cnt                                                   ' mark
        waitcnt(cnt += clkfreq >> 5)                                ' wait about 32ms
        waitpne(1 << pin, 1 << pin, 0)
        t += cnt
        if (cnt < (clkfreq >> 1 + clkfreq >> 2))
          long[pntr] := true
        else
          long[pntr] := false
    
  • DRMorrisonDRMorrison Posts: 81
    edited 2012-01-27 11:26
    Not a bad idea JonnyMac

    I did however figure out why this was not working. phsa was counting more than 4 counts on various button pushes due to button bounce. Duh!

    This should now work once connected to the auto's alarm signal wire--no bounce.

    Thanks for everyones help, Daniel
Sign In or Register to comment.