Shop OBEX P1 Docs P2 Docs Learn Events
SX48 counter — Parallax Forums

SX48 counter

David EamesDavid Eames Posts: 4
edited 2009-12-08 06:06 in General Discussion
I am new to programming and the SX48. I want to input a square wave that will run from around 12 to 140hz and keep a running tally of the number of pulses that can be fetched by an Xbee device. This sounds like it should be pretty simple but I have been struggling. Any help or samples would be greatly appreciated.

Dave E.

Comments

  • BeanBean Posts: 8,129
    edited 2009-12-02 13:41
    Dave,
    If you are thinking of using the hardware counters, it's not going to be that easy. There isn't an easy way to actually read what the count is.

    If you are using SX/B there is a COUNT command that should do the job.

    Can you post what you have tried ?

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    1st rule of finance...Don't lose money.
    Never be ashamed of making an honest·profit.
    Live within your means...Make do, or do without.
    ·
  • David EamesDavid Eames Posts: 4
    edited 2009-12-06 23:19
    Ok, I switched to SX/B and used a simple program in the SX/B help file to get started. When I run thin in the SXSim model it stops abruptly when it gets to the IREAD instruction @ 159. I am also using the SXKey tool and it will not run in debug mode. Should have some more time to work on it in the next couple of days.
  • ZootZoot Posts: 2,227
    edited 2009-12-07 01:13
    Why not use a simple RTCC interrupt that's at least 4x faster than your pulses, and count them there? e.g.

    samplePin PIN RB.0 INPUT
    
    sampleFrame VAR Word
    sampleCount VAR Word
    sampleCaptured VAR Word
    sampleState VAR Byte
    
    INTERRUPT 400_000 ' will count pulses up to 100khz
       sampleState.0 = samplePin ' capture pin right now
       IF sampleState.0 = 1 THEN ' this state was 1
             IF sampleState.1 = 0 THEN ' previous state 0, must be rising edge
                 INC sampleCount
             ENDIF
       ENDIF
       sampleState = sampleState << 1 ' save current state as previous
    
       INC sampleFrame
       IF sampleFrame >= 4000 THEN ' capture every 10ms
           sampleCaptured = sampleCount
           sampleCount = 0
           sampleFrame = 0
       ENDIF
    
       RETURNINT
    
    Start:
    
    
    Main:
    
       'debug sampleCaptured
    
       GOTO Main   
    
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST

    1uffakind.com/robots/povBitMapBuilder.php
    1uffakind.com/robots/resistorLadder.php
  • BeanBean Posts: 8,129
    edited 2009-12-07 01:53
    Zoot, that's a good idea, but why not take it one step further and use the RTCC pin for the input.
    Unlike the SX48 16-bit counter, the 8-bit RTCC counter IS easily read.

    Just set RTCC to zero, pause for 1 second and read RTCC.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    1st rule of finance...Don't lose money.
    Never be ashamed of making an honest·profit.
    Live within your means...Make do, or do without.
    ·
  • ZootZoot Posts: 2,227
    edited 2009-12-07 02:36
    That's fine if that's all that's going to happen -- in my own projects I always use (or like to leave open) the ability to have real-time or other RTC processes (i.e. ms or us counters in the ISR, serial comms w/buffer, PWM, IR generation, IR communication tx/rx, etc.).

    If the commitment is made to pin generated interrupt *hardware* then it can be a one-way street. For example, in my code above, I presume that the sample time is constant -- i.e. it's counting samples received in fairly precise 10ms frames (although there's no flag for the mainline). So if sample windows were an issue, a pure RTCC interrupt would prevent that (of course, you could back-calculate a revised RTCC and check if the pin or overflow caused the interrupt, but at that point, my own taste is to just get the ISR wound up tight enough to capture and parse relevant pin states at regular intervals).

    Another way to put it -- with a few changes to bit frame counts, Jon's ISR based serial TX/RX w/buffers could be dropped right in w/o changes to firmware nor hardware.

    David -- here's a slightly revised version that sets a flag to let the mainline know that the count has been "captured". The scenario below presumes that the mainline will never take more than 10ms before getting around to checking/clearing the flag (to keep this example relatively simple):

    samplePin PIN RB.0 INPUT
    Led PIN RB.1 OUTPUT
    
    flag VAR Byte ' global var
    sampleReady VAR flag.0
    
    sampleFrame VAR Word
    sampleCount VAR Word
    sampleCaptured VAR Word
    sampleState VAR Byte
    
    __IsrRate    CON 400_000 '  will count pulses up to 100khz reliably
    SampleHz   CON 100 ' this many samples per second
    
    SampleTicksPerFrame  CON __IsrRate / SampleHz 
    
    INTERRUPT __IsrRate
    
       sampleState.0 = samplePin ' capture pin right now
       IF sampleState.0 = 1 THEN ' this state was 1
             IF sampleState.1 = 0 THEN ' previous state 0, must be rising edge
                 INC sampleCount
             ENDIF
       ENDIF
       sampleState = sampleState << 1 ' save current state as previous
    
       INC sampleFrame
       IF sampleFrame >= MySampleRate THEN ' capture
           sampleCaptured = sampleCount
           sampleCount = 0
           sampleFrame = 0
           sampleReady = 1 ' set flag for mainline
           Led = ~Led ' toggle led -- this would be 50% duty cycle at the sample rate (in this case 100hz)
       ENDIF
    
       RETURNINT
    
    Start:
    
    
    Main:
    
       IF sampleReady = 1 THEN ' must have captured a value during a 10ms sample frame
            ' debug or display or watch the value: sampleCaptured
            sampleReady = 0 ' clear the flag
       ENDIF
    
       GOTO Main
    
    
    



    But it's a matter of style and need and preference, of course. If the SX is standalone and needs no timing-dependent routines, the RTCC is always elegant. The real question is what are you doing w/the counts once you have them? Sending them to another device? Displaying on an LCD? Writing to EEPROM?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST

    1uffakind.com/robots/povBitMapBuilder.php
    1uffakind.com/robots/resistorLadder.php


    Post Edited (Zoot) : 12/7/2009 2:42:43 AM GMT
  • David EamesDavid Eames Posts: 4
    edited 2009-12-07 18:10
    I also want to be able to have the SX48 go into sleep mode. Again, I am new to this stuff, but I thought I read somewhere that if it goes into sleep mode the RTCC register is cleared, so I am going to stick with RB.0 input. Thanks for the guidance. I will most likely be back with more questions. This is a great forum!!
  • David EamesDavid Eames Posts: 4
    edited 2009-12-08 03:28
    I will be sending the value to a computer via xBee devices.
  • ZootZoot Posts: 2,227
    edited 2009-12-08 06:06
    Xbees are serial, so if you do any kind of ISR work (whether using raw pin state counts or RTCC or PORT B interrupt pin states, you'll need to move the serial comm routines into the ISR. SXB serin and serout depend on consistent timing of cycles un-interrupted (or fold it into TASKs but I think the overhead there may be too stiff).

    Or go back to Bean what suggested -- doing a COUNT in the mainline (if you can afford to take time off from counting pulses to do your serial comms and other work).

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST

    1uffakind.com/robots/povBitMapBuilder.php
    1uffakind.com/robots/resistorLadder.php
Sign In or Register to comment.