Shop OBEX P1 Docs P2 Docs Learn Events
Please help me write a simple counter code!!! — Parallax Forums

Please help me write a simple counter code!!!

Tony_tsiTony_tsi Posts: 98
edited 2012-05-22 20:03 in Propeller 1
I am fairly new to propeller. I don't have experience with the counter modules built into the propeller. I have read a lot about them but I am struggling to understand exactly how they work. I need to write a code that adds 1 to a value each time a pulse is received on ina[1] and subtracts 1 from the value each time a clock is received on ina[0] I need to do this as fast as possible. I need this to be done in cog 1 but I need to read the value in cog 0. I still struggle to remember how values work when used in different cogs. This code is going to be used to keep up with some optical encoder motors. The output of the motors go through a flip flop circuit so that a pulse is input on line one for each clockwise step and line 0 for each counterclockwise step. This is going to be used on a robot I am building for school.

Thanks for your help.

Comments

  • JonnyMacJonnyMac Posts: 9,195
    edited 2012-05-19 23:06
    You don't need to use the counters for this; simply write a PASM cog that scans the two pins and xor them with the last scan to see if there was a state change on either. If you and the state changes with the new inputs you can tell which input(s) transitioned from low to high.

    I've attached a sparsely-commented demo object for you to play with.
  • Mark_TMark_T Posts: 1,981
    edited 2012-05-20 05:29
    Tony_tsi wrote: »
    I am fairly new to propeller. I don't have experience with the counter modules built into the propeller. I have read a lot about them but I am struggling to understand exactly how they work. I need to write a code that adds 1 to a value each time a pulse is received on ina[1] and subtracts 1 from the value each time a clock is received on ina[0] I need to do this as fast as possible. I need this to be done in cog 1 but I need to read the value in cog 0. I still struggle to remember how values work when used in different cogs. This code is going to be used to keep up with some optical encoder motors. The output of the motors go through a flip flop circuit so that a pulse is input on line one for each clockwise step and line 0 for each counterclockwise step. This is going to be used on a robot I am building for school.

    Thanks for your help.

    You can't both add and subtract with the same counter - but you can use both counters, count the pulses from each pin separately and then take the difference of the phase registers.

    Mode 010 does edge detection, set up each counter in that mode with FRQ registers set to 1 and PHS registers set to 0 and the APIN set to 0 for counter A and 1 for counter B. You then read PHSB-PHSA to get the difference.

    There will be some discrepancy since you can't read both PHS registers simultaneously though - using PASM will reduce this to 50ns which is probably good enough?

    To write the value to another cog you need to pass the address of the variable to be written. In Spin the registers are in HUB ram, with PASM you'll use WRLONG.

    So if in PASM something like this:
    CON
      INCREMENT_PIN = 1
      DECREMENT_PIN = 0
    
    ....
    
    
    
    
    DAT
    ......
    
    setup_cntrs     movs    CTRA, #INCREMENT_PIN
                    movi    CTRA, #010000  ' mode 01010, plldiv 000
                    mov     FRQA, #1
    
                    movs    CTRB, #DECREMENT_PIN
                    movi    CTRB, #010000  ' mode 01010, plldiv 000
                    mov     FRQB, #1
            
                    mov     PHSA, #0    ' reset the counts
                    mov     PHSB, #0
    setup_cntrs_ret ret
    
    
    
    capture_count   mov    temp, PHSA
                    sub    temp, PHSB
                    wrlong    temp, result_addr
    capture_count_ret ret
    
    
  • Tony_tsiTony_tsi Posts: 98
    edited 2012-05-20 13:11
    Thanks for the help. This is still a little bit over my head. I am reading my propeller manual to better understand this code. Maybe I should start with a simple counter to count only one input. I should also note that the lines coming from the encoder will never both output a signal at the same time. This is because i have constructed a circuit that pulses one line for clockwise rotation and one line for counter clockwise rotation. Sorry for my lack of programing knowledge. How are DAT blocks accessed? Are they like variable blocks but containing commands instead of variables?

    My programing knowlage includes chapter 1-5 of the propeller education book, as well as some basic stamp experence.

    I am trying to spend my summer becoming more familiar with propeller code so that when school starts back I can be a usefull member of the IEEE robot team.
  • Mike GreenMike Green Posts: 23,101
    edited 2012-05-20 14:34
    Make sure you read through AN001. This discusses the various counter modes and how the counters work. It includes some sample code.
  • Tony_tsiTony_tsi Posts: 98
    edited 2012-05-20 14:56
    Thank you!
  • frank freedmanfrank freedman Posts: 1,983
    edited 2012-05-20 15:24
    Tony_tsi wrote: »
    Thanks for the help. This is still a little bit over my head. I am reading my propeller manual to better understand this code. Maybe I should start with a simple counter to count only one input. I should also note that the lines coming from the encoder will never both output a signal at the same time. This is because i have constructed a circuit that pulses one line for clockwise rotation and one line for counter clockwise rotation. Sorry for my lack of programing knowledge. How are DAT blocks accessed? Are they like variable blocks but containing commands instead of variables?

    My programing knowlage includes chapter 1-5 of the propeller education book, as well as some basic stamp experence.

    I am trying to spend my summer becoming more familiar with propeller code so that when school starts back I can be a usefull member of the IEEE robot team.

    Hey Tony,

    Start simple, get the hang of spin and then experiment to see if it will give you the required speeds for your project and make sure the concept does what you think it will. If spin is not fast enough, then move on to PASM. Or learn enough about the counters to use them via spin as a possible state machine to get the speed and spin for the glue logic to make the counters do what you need and interface to the rest of your world. Multiple approaches to doing these, but just experimenting and the prop ed tutorials (no need to buy at Fry's or similar, just download them) will give you the feel for what will work. Rip apart some objects, good ideas there and you can learn some tricks from the masters. Oh, look up PhiPi's traps and tricks document.

    The counters are a 7734 of a lot more complex than the APnote leads one to believe, simple circuit on paper, but the versatility designed into the counters is always causing someone to come up with yet another way to do something unexpected with them. 'course, this chip continues to deliver nice surprises........


    Frank
  • kuronekokuroneko Posts: 3,623
    edited 2012-05-20 18:06
    @Mark_T: How did you post your [post=1099447]comment[/post]? Anything binary related (%001..) gets corrupted either by your way of posting or by the forum software.
  • TymkrsTymkrs Posts: 539
    edited 2012-05-20 20:40
    This may help you understand how the counter code works a bit more:

    http://www.firstspin.tv/2012/03/06/first-spin-episode-015-%e2%80%93-more-directives-and-counters/

    We approached it from a newbie's perspective and I think a few people found value in the explanation!
  • Tony_tsiTony_tsi Posts: 98
    edited 2012-05-21 13:42
    Thanks for everyone's help. i have decided to break this down into small simple steps as follows.

    step#1) write a code that uses if statements, operators and values (things I can use well) that adds a count for each pulse on pin 2 and subtracts a count for each pulse on pin 3. Use buttons to simulate simulate signal.

    step#2) write a code that tracks the count the same way as step 1 but runs in cog 2 and keeps up with a value that can be displayed on lcd from the cog1.

    step#3) write a code that counts up for each pulse on pin 2 using the counter commands.

    step#4) write a code that counts up using pin 2 and down using pin 3.

    step#5) write a code that runs in cog 2 and tracks the count. use cog 1 to display the count on lcd.

    step#6) Hook it up to the motor and see if it is fast enough.

    I hope hope by breaking the steps down in this order I can learn it better. I will post as I complete each step!
  • Tony_tsiTony_tsi Posts: 98
    edited 2012-05-21 13:53
    Here is step one. It works great. If there are simple improvements I can make let me know.

    step#1).spin
  • Tony_tsiTony_tsi Posts: 98
    edited 2012-05-21 14:39
    This code locks up. step#2) Failed.spin think it has something to do with the new cog any ideas?
  • turbosupraturbosupra Posts: 1,088
    edited 2012-05-21 15:17
    Try making your stack "long stack[100]" and report back
  • Tony_tsiTony_tsi Posts: 98
    edited 2012-05-21 15:31
    turbosupra wrote: »
    try making your stack "long stack[100]" and report back
    success!!!!!!!!!!!!!!"
  • msrobotsmsrobots Posts: 3,709
    edited 2012-05-21 15:31
    Hi Tony.

    I guess your stack is to small...see below

    I rarely use COGINIT because I do not care which COG is used.

    having a VAR section somewhere defining
      long  cogID              { to have ID to stop COG }
      long  stack[100]       { used by SPIN-Interpreter better 100 until you know how much you need 6 longs is to less}
    

    to start a COG in SPIN I usally do something like this
       CogID:=COGNEW(m_tracker,@stack) + 1  
    

    COGNEW returns -1 on failure or the ID of the started COG (0-7)

    adding 1 gives me 0 for no cog or (ID+1) if started. I save that value in cogID

    now I can test

    IF cogID

    giving TRUE for not 0 aka cog started


    to stop it (and test if running)
        if CogID
          COGSTOP(CogID~ -1)
    

    the second line is tricky but you see that everywhere inPropellerCode POST SET TO 0

    COGSTOP wants a ID (0-7) CogID contains (1-8)

    so COGSTOP(CogID -1) would do this. But we want to set cogID to also to zero

    and cogID~ does that AFTER evaluating. and still returning the correct number

    I hope thios helps...


    enjoy!


    Mike
  • turbosupraturbosupra Posts: 1,088
    edited 2012-05-21 15:44
    Here is what I have learned ... I always set my stack to 100 or greater sometimes, just to make sure I'm not chasing crazy issues because of a stack being too small. If I ever run out of space on the propeller, it will be easy enough to go back and start trimming longs out of my stacks, if space is that tight, but I haven't had that problem yet.

    Tony_tsi wrote: »
    success!!!!!!!!!!!!!!"
  • Tony_tsiTony_tsi Posts: 98
    edited 2012-05-21 16:04
    msrobots wrote: »
    Hi Tony.

    I guess your stack is to small...see below

    I rarely use COGINIT because I do not care which COG is used.

    having a VAR section somewhere defining
      long  cogID              { to have ID to stop COG }
      long  stack[100]       { used by SPIN-Interpreter better 100 until you know how much you need 6 longs is to less}
    

    to start a COG in SPIN I usally do something like this
       CogID:=COGNEW(m_tracker,@stack) + 1  
    

    COGNEW returns -1 on failure or the ID of the started COG (0-7)

    adding 1 gives me 0 for no cog or (ID+1) if started. I save that value in cogID

    now I can test

    IF cogID

    giving TRUE for not 0 aka cog started


    to stop it (and test if running)
        if CogID
          COGSTOP(CogID~ -1)
    

    the second line is tricky but you see that everywhere inPropellerCode POST SET TO 0

    COGSTOP wants a ID (0-7) CogID contains (1-8)

    so COGSTOP(CogID -1) would do this. But we want to set cogID to also to zero

    and cogID~ does that AFTER evaluating. and still returning the correct number

    I hope thios helps...


    enjoy!


    Mike

    Thank you for the examples. I will be incorporating the cog test in my code this is very helpful. If the cog does not start the robot is lost. lost robot = bad
  • Tony_tsiTony_tsi Posts: 98
    edited 2012-05-22 20:03
    here is the working code
Sign In or Register to comment.