Shop OBEX P1 Docs P2 Docs Learn Events
Count State Change — Parallax Forums

Count State Change

CastrovinciCastrovinci Posts: 26
edited 2008-07-11 02:42 in General Discussion
Bean,
··· I am tring to make this program, but I need it to be very simple (as it is my level) Here is what I am trying to do:

I need to count everytime a pin changes from 1 to 0, but it will be a pulse so it needs to count it quick and then store it in a variable for display.· So basically My device may pulse pin Ra.0 4 times in one second.· I need Var to return a count of 4.· Then if the device pulse another 4 1 second later I need the var to show 8.

Now I tried doing this two ways, but I can't get accurate way.

I have used Pulsin, but I sometimes get 10 pulses, 9 other times.· This is because its measuring the length or width·rather then counting·1 to·0 transition?

I also tried Count and that does not help either?

what is simple that can accomplish this?

Thanks so much!!!· smhair.gif



▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


Post Edited (Castrovinci) : 7/8/2008 5:17:37 PM GMT

Comments

  • BeanBean Posts: 8,129
    edited 2008-07-08 16:32
    PULSIN is used to measure the length of a pulse, not to count it.

    The COUNT command should do it. What do you get with COUNT ?

    Can you post your code that uses COUNT ?

    If you are missing pulses when not in the COUNT command, you might want to use the RTCC input like I suggested in this thread http://forums.parallax.com/showthread.php?p=735697


    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    "A government big enough to give you everything you want, is big enough to take away everything you·have."·· Thomas Jefferson

    "It is our choices, Harry, that show what we truly are, far more than our abilities."·Dumbledore from Harry Potter

    www.iElectronicDesigns.com

    ·
  • CastrovinciCastrovinci Posts: 26
    edited 2008-07-08 17:09
    ·This is the code (template) I have been using, but it returns a high number and not the actual pulse.· If my device pulses once per second it returns a weird high number.· I even tried doing it with the scmitt, and pull up enabled.· I think it is just measuring·a false·hertz from the device·and not counting the state change?·I need something more sutable·where it counts each 1-0 and adds 1 to the variable, and not nessararly in a specified duration.··Any Idea's?

    Its a dollar bill acceptor and I can set the pulses for each bill entered.



    ·{{{{{{{{{{{{{{{{

    If you use COUNT on slowly changing analog waveforms like sine waves, you may find that the value returned is higher than expected. This is because the waveform may pass through the SX’s 1.4-volt logic threshold slowly enough that noise causes false counts. You can fix this by enabling the SCHMITT trigger configuration on the pin used for COUNT.

    {{{{{{{{{{{{{{{{






    DEVICE SX48, OSC4MHZ, TURBO, STACKX, OPTIONX
    FREQ 4_000_000
    ID "COUNT"

    '
    ' IO Pins
    '

    FreqIn PIN RA.0 ··INPUT ' frequency input

    '
    ' Constants
    '

    Duration CON 1000 ' measure for one second

    '
    ' Variables
    '

    hertz VAR Word ' measured cycles
    WATCH hertz ' for Debug display

    ' =========================================================================
    PROGRAM Start
    ' =========================================================================

    '
    ' Program Code
    '

    Start:
    ··DO
    ····COUNT FreqIn, Duration, hertz ' measure frequency
    ····BREAK ' display in Watch window
    ··LOOP

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


    Post Edited (Castrovinci) : 7/8/2008 5:17:19 PM GMT
  • BeanBean Posts: 8,129
    edited 2008-07-08 17:49
    Port RA doesn't have schmitt trigger inputs.
    Use a pin on port RB or RC and it should work "FreqIn PIN RB.0 INPUT SCHMITT"

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    "A government big enough to give you everything you want, is big enough to take away everything you·have."·· Thomas Jefferson

    "It is our choices, Harry, that show what we truly are, far more than our abilities."·Dumbledore from Harry Potter

    www.iElectronicDesigns.com

    ·
  • JonnyMacJonnyMac Posts: 9,392
    edited 2008-07-08 19:19
    I've attached a program that will count the 0->1 edges detected on a pin (RC.0) and display that count on a 4-digit, 7-segment display. As the code sits, it should be good up to 2000 Hz; you can of course adjust for greater range.

    The program uses an interrupt to detect and count edges (count window is user-definable) and multiplex the display.

    [noparse][[/noparse]Edit] Corrected for 1.51.03 compiler (sorry, I was using the beta 2.0 compiler when I wrote this).

    Post Edited (JonnyMac) : 7/9/2008 5:34:07 AM GMT
  • Sparks-R-FunSparks-R-Fun Posts: 388
    edited 2008-07-08 22:53
    The following is an example of how I would try to accomplish what you have specified if I were trying to do it in an easy-to-follow, simplified way.

    DEVICE SX48, OSC4MHZ, TURBO, STACKX, OPTIONX
    FREQ 4_000_000
    ID "COUNT"
    
    ' -------------------------------------------------------------------------
    ' IO Pins
    ' -------------------------------------------------------------------------
    
    FreqIn PIN RA.0   INPUT ' frequency input
    
    ' -------------------------------------------------------------------------
    ' Constants
    ' -------------------------------------------------------------------------
    
    Duration CON 1000 ' measure for one second
    
    ' -------------------------------------------------------------------------
    ' Variables
    ' -------------------------------------------------------------------------
    
    hertz VAR Word ' measured cycles
    WATCH hertz ' for Debug display
    
    Sampled         VAR BIT         ' One bit variable to hold the Sampled state.
    PreviousState     VAR BIT        ' One bit variable to hold the Previous State
    
    ' =========================================================================
    PROGRAM Start
    ' =========================================================================
    
    PreviousState = 1           ' Set the Previous State to one to detect
                                '   the next transition to zero.
    
    ' -------------------------------------------------------------------------
    ' Program Code
    ' -------------------------------------------------------------------------
    
    Start:
      DO
        Sampled = FreqIn        ' Sample the state of the pin labled 'FreqIn'.
    
        IF Sampled <> PreviousState THEN  ' If the Sampled state is different from the Previous State...
    
            IF Sampled = 0 THEN ' If this is a new zero state...
                INC hertz       ' Increment the variable labled 'hertz'.
            ENDIF
    
            PreviousState = Sampled  ' Remember this new state.
        ENDIF
    
        BREAK ' display in Watch window
      LOOP
    


    One "advanced" technique that I did include is a specific sampling of the input that only occurs ONCE in the entire processing of the state. The importance of this is often much more academic than practical. This is especially true with very clean and slow moving signals. However, sometimes making multiple logic decisions that are each based upon the instantaneous state of an input can occasionally lead to unexpected results especially if you happen to be relying solely on the assumption that the signal will not change as you progress through the subroutine. This can be very difficult to find and track down later!

    So my "advanced" tip is to sample your input at one instant in time and do the rest of your processing on the sampled state rather than the possibly still changing input state.


    I hope this helps.

    - Sparks
  • JonnyMacJonnyMac Posts: 9,392
    edited 2008-07-09 00:21
    Here's another demo that may get you closer to your goal -- this one counts pulses as nickels and displays the accumulated money on a 7-segment display until you press the dispense button. Like my other program, this looks for transitions (0->1 in this program) in the ISR and accumulates them. You manually reset the accumulator (called money) when desired.

    Hope this is helpful.

    [noparse][[/noparse]Edit] Changed ISR rate to catch 20 uS pulses.

    Post Edited (JonnyMac) : 7/9/2008 5:31:08 AM GMT
  • CastrovinciCastrovinci Posts: 26
    edited 2008-07-09 02:11
    Ok,
    ·· I figured out one of the problems.· It appears the pulse is only 20US and the count can only handle 1 MS or above.· Do we have any other idea's?· I need it to be with minimal parts for my idea though!· Thanks guys for helping!yeah.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • JonnyMacJonnyMac Posts: 9,392
    edited 2008-07-09 05:12
    That part's easy now that there's a working program. I updated Change_Counter.SXB (see link, above) to run its ISR every 10 uS, that will guarantee that it catches a 20 uS pulse. Not that I changed the FREQ directive to 50 MHz.
  • BeanBean Posts: 8,129
    edited 2008-07-09 11:07
    Castrovinci said...
    Ok,
    ·· I figured out one of the problems.· It appears the pulse is only 20US and the count can only handle 1 MS or above.· Do we have any other idea's?· I need it to be with minimal parts for my idea though!· Thanks guys for helping!yeah.gif
    Using the RTCC pin should work too. Even at low clock frequencies.

    Bean.


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    "A government big enough to give you everything you want, is big enough to take away everything you·have."·· Thomas Jefferson

    "It is our choices, Harry, that show what we truly are, far more than our abilities."·Dumbledore from Harry Potter

    www.iElectronicDesigns.com

    ·
  • CastrovinciCastrovinci Posts: 26
    edited 2008-07-09 13:54
    Ok, this is good.· Its really letting me learn, as I have been trying to heavily do lately on the sx chip since I think it is my favorite chip.



    Here is a couple of more things I came up with though.·

    First Jonny Mac, I modified your program and am work so I figured I catch you guys now.· This is what I came up with, think it will work?· The only problem I have is I can not debug to view·this because I can't have an external osc, can this be done using the internal, and keeping the standard 4mhz freq.· How can I make this work for a watch as far as the setup?·

    Also Bean you meantioned using the RTCC Pin, Can you take my example and show me what you mean, cause that sounds like I can use debug in that method.

    Also what does BOR42 do?



    DEVICE········· SX28, OSCXT2, TURBO, STACKX, OPTIONX, BOR42
    FREQ··········· 50_000_000
    ID············· "HZ_Meter"

    '
    ' I/O Pins
    '
    Dispense·PIN·RC.1 INPUT
    CoinIn··PIN·RC.0 INPUT· SCHMITT


    '
    ' Constants
    '
    Pressed··CON·0···' for active-low inputs
    NotPressed·CON·1


    '
    ' Variables
    '
    flags··VAR·Byte
    ·isrFlag·VAR·flags.0···' isr marker
    ·lastIn··VAR·flags.1···' last input level
    idx··VAR·Byte
    money··VAR·Word
    watch money
    ' =========================================================================
    · INTERRUPT 100_000
    ' =========================================================================
    Mark_ISR:
    · isrFlag = 1
    Count_Pulses:
    · IF lastIn = 1 THEN
    ··· IF CoinIn = 0 THEN
    ····· money = money + 1
    ····· 'Can I add BREAK in here for the watch or do I do it in the main
    ··· ENDIF
    · ENDIF
    · lastIn = CoinIn

    ISR_Exit:
    · RETURNINT

    ' =========================================================================
    · PROGRAM Start
    ' =========================================================================

    '
    ' Subroutine / Function Declarations
    '

    '
    ' Program Code
    '
    Start:

    · PLP_C = %00000011····' pull-up unused pins
    · money = 0
    Main:
    goto main

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • BeanBean Posts: 8,129
    edited 2008-07-09 14:37
    This should work.

    NOTE that you cannot use a period interrupt when RTCC is counting from the external pin though.

    DEVICE          SX28, OSC4MHZ, TURBO, STACKX, OPTIONX, BOR42
    FREQ            4_000_000
    ID              "HZ_Meter"
     
    ' -------------------------------------------------------------------------
    ' I/O Pins
    ' -------------------------------------------------------------------------
    Dispense      PIN RC.1 INPUT 
    ' CoinIn connect signal to RTCC input pin
     
    ' -------------------------------------------------------------------------
    ' Constants
    ' -------------------------------------------------------------------------
    Pressed       CON 0   ' for active-low inputs
    NotPressed    CON 1
     
    ' -------------------------------------------------------------------------
    ' Variables
    ' -------------------------------------------------------------------------
    money  VAR  WORD
     
    WATCH money
     
    ' =========================================================================
      PROGRAM Start
    ' =========================================================================
     
    ' -------------------------------------------------------------------------
    ' Subroutine / Function Declarations
    ' -------------------------------------------------------------------------
     
    ' -------------------------------------------------------------------------
    ' Program Code
    ' -------------------------------------------------------------------------
    Start:
      PLP_C = %00000011    ' pull-up unused pins
      OPTION = %1111_1000  ' Enable RTCC counting from RTCC pin on high to low transition
      RTCC = 0             ' Zero RTCC count
     
    Main:
      money = RTCC ' Get the current count
     
      ' Do something after 5 coins are put in
      IF money = 5 THEN
        ' Do something
        ' Reset counts to zero
        money = 0
        RTCC = 0
      ENDIF
     
      BREAK ' Update debugging window
     
    GOTO main
    

    Bean


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    "A government big enough to give you everything you want, is big enough to take away everything you·have."·· Thomas Jefferson

    "It is our choices, Harry, that show what we truly are, far more than our abilities."·Dumbledore from Harry Potter

    www.iElectronicDesigns.com

    ·
  • JonnyMacJonnyMac Posts: 9,392
    edited 2008-07-09 18:49
    Since you can't use an external oscillator, what do you intend to do about a display? Bean showed how to catch the pulses with the RTCC input, but how will you display the data you have? (you can't do serial [noparse][[/noparse]e.g., LCD] with the internal oscillator) -- or is that not a problem in your final project?
  • CastrovinciCastrovinci Posts: 26
    edited 2008-07-10 01:27
    Jonny,

    ··· Thanks for the reply, no I do not need a display in the final project, I just need to make sure it works in debug as it is easiest that way for me.· The end project will have no display

    P.S. what is the BOR42 on the end of the device settings?

    ·Also if you still have an option like I submitted below with the internal osc let me know.· Thanks Jonny and Bean!· Bean I am going to try yours now.·



    wink.gifwink.gifwink.gifwink.gifwink.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • JonnyMacJonnyMac Posts: 9,392
    edited 2008-07-10 06:53
    Bean's RTCC trick works at any speed -- I tested it at 4 MHz with the attached program. Just keep in mind that the RTCC is a byte so you'll want to ensure that your input doesn't cause the value to rollover.

    BOR42 sets the brown-out control (reset on brown-out) to 4.2 volts.
  • CastrovinciCastrovinci Posts: 26
    edited 2008-07-10 15:10
    Yes, I got bean's program to count.· The only problem I encountered is it does not always count correctly and it sometimes freezes up not counting at all.· I am going to try the one you included when I get home and see if that helps.·I was thinking too, that is there a min delay in between each pulse spec? Because for the dollar bill acceptor·my settings are 4 pulses per dollar, the pulses·seem rather slow in between and with a logic probe I can see its transitions very clearly.· ·Maybe its like you said its rolling over?· What is suppose to happen when it rolls over?·

    Correct me if I'm wrong but doesn't setting the option value disable roll over? OPTION = %1111_1000

    attachment.php?attachmentid=73659



    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    544 x 312 - 11K
  • BeanBean Posts: 8,129
    edited 2008-07-10 15:18
    RTCC doesn't roll over until 255 counts.
    The RTI setting just disables interrupts when it does roll-over.
    NOTE your signal may be open-collector and needs a pull-up resistor on it.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    "A government big enough to give you everything you want, is big enough to take away everything you·have."·· Thomas Jefferson

    "It is our choices, Harry, that show what we truly are, far more than our abilities."·Dumbledore from Harry Potter

    www.iElectronicDesigns.com

    ·
  • JonnyMacJonnyMac Posts: 9,392
    edited 2008-07-10 22:31
    At lunch I wrote a program for another SX that would blast out four, 20 uS pulses (spaced at 20 uS) to the RTCC counter program -- worked without a problem. As Bean suggests, your count error may be hardware related.
  • CastrovinciCastrovinci Posts: 26
    edited 2008-07-11 02:42
    Gents, I just want to say thanks for all your help and I learned a lot as always. I'm sure I'll be back soon......... Thanks!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Sign In or Register to comment.