Shop OBEX P1 Docs P2 Docs Learn Events
counting (up to 400) milliseconds (while waiting for a pulse) — Parallax Forums

counting (up to 400) milliseconds (while waiting for a pulse)

NickeANickeA Posts: 5
edited 2007-05-08 06:18 in BASIC Stamp
Hi!

I need to measure the time·that passes between input pulses (on a bs2). My first thought was using the RCTIME or PULSIN·commands, but·they·can't measure time spans longer than 131 milliseconds.·Maximum time between pulses from my sensor is 400 milliseconds.

My second tought was to make a loop that counts milliseconds:
1. reset counter
2. check pin for pulse
3. if pulse appeared then return counter and end
4. pause 1 millisecond
5. increment counter
6. return to 2.

However, I now suspect that the code itself takes enough time to make the result wrong. I guess that 300 roundtrips in the loop takes considerably more than the 300 milliseconds that the counter would return.

Is that a correct suspicion?

Another solution would be to use RCTIME/PULSEIN several times and keeping track of how many times it "times out". I would then use the result of the RCTIME/PULSEIN and add 131 milliseconds for every time it "timed out".

Do you think this would work? Do you have a better solution?

Best regards, Nicke

·

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2007-05-06 20:08
    Probably the best thing would be to use a PULSIN followed by multiple RCTIME statements. These would take some time to execute (see Tracy Allen's website for timing information: www.emesystems.com), but the time should be reproducible. Something like this?
    time VAR word
    timeExtended VAR byte
    thePin PIN 0
    PULSIN thePin,0,time
    IF time = 0 and thePin = 1 then
      RCTIME thePin.1,time
      IF time = 0 and thePin = 1 then
        RCTIME thePin,1,time
        IF time = 0 and thePin = 1 then
          RCTIME thePin,1,time
          timeExtended = 3
          GOTO workWithIt
        ENDIF
        timeExtended = 2
        GOTO workWithIt
      ENDIF
      timeExtended = 1
      GOTO workWithIt
    ENDIF
    timeExtended = 0
    workWithIt:
    IF time = 0 THEN timeExtended = timeExtended + 1
    ' Here we have an 18 bit number spread across two words
    ' It needs to be converted to a more useful unit at this point
    ' that will fit in a single word.  You could also compensate for
    ' the extra time for the IF and RCTIME statements by
    ' subtracting some empirically determined value * timeExtended
    ' from the result.
    

    Post Edited (Mike Green) : 5/6/2007 8:15:17 PM GMT
  • NickeANickeA Posts: 5
    edited 2007-05-07 18:53
    ".
    PULSIN thePin,0,time
    IF time = 0 and thePin = 1 then
    ."

    Hmm...Do we assume that time = 0 means that we found a startpuls but PULSIN timed out before we found endpulse? It might as well be that PULSIN didn't find the startpulse, and therefore didn't start counting at all, or?
  • Mike GreenMike Green Posts: 23,101
    edited 2007-05-07 19:17
    Yes, the first "time = 0 is intended to check for the case where we found the leading edge of a pulse and timed out before the trailing edge was seen. The "thePin = 1" is intended to catch the case where the end of the pulse occurs before the IF statement completes. My understanding of the PULSIN statement is that it will wait indefinitely for the leading edge of a pulse which is what is needed in this case. If the pulse finishes before the RCTIME executes, the RCTIME will quit with a count of 1 (a reasonable special case). It (the RCTIME) doesn't wait for a leading edge ... which is what we want.
  • NickeANickeA Posts: 5
    edited 2007-05-07 19:43
    The syntax and reference manual says it will not look for the leading edge for more than 131ms.

    "PULSIN will wait, for the desired pulse, for up to the maximum pulse
    width it can measure [noparse][[/noparse]131ms]... ...If it never sees the start of the pulse, or the pulse is too long PULSIN "times out" and store 0 in Variable."

    It's a pity it returns 0 in both cases. It makes my task a bit harder.
  • Mike GreenMike Green Posts: 23,101
    edited 2007-05-07 19:50
    Oh well! Do you have an upper limit for the wait time to the start of the pulse? Do you in fact want to wait indefinitely? You could use an explicit loop to wait for the leading edge, then use another RCTIME rather than the PULSIN to do the first timing. Again, minimizing the number and complexity of statements involved will reduce the uncertainty involved in the timing.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2007-05-08 04:12
    Nicke,

    One thing the BASIC Stamp can do for a protracted period is count pulses. With a little extra hardware, you can convert your pulse intervals into intervals of the same length containing a 32.768KHz clock. Then you can use the COUNT command to count the number of clocks within the interval. The COUNT command requires a fixed interval over which to count. You will have to estimate this interval so you catch one, and only one, pulse interval. Whether this is realistic depends on the maximum and minimum spans and how fast the interval can change. Here's how I'd code it:

    ····1. Wait for Pulses / 2 to be high.
    ····2. Wait for Pulses / 2 to go low.
    ····3. COUNT for estimated interval * 2.5
    ····4. Compute time from number of clocks counted.

    A schematic of the extra hardware, along with some waveforms, is shown below. The oscillator uses a 32.768KHz watch crystal. You may have to fiddle with the resistor and capacitor values for reliable oscillation.

    -Phil
    653 x 414 - 5K
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2007-05-08 06:18
    It sounds from your first post that 1 millisecond of resolution would be okay, and for that your thought to use a loop that counts milliseconds could work. There are a couple of examples of such loops at www.emesys.com/BS2speed.htm#longpulse

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
Sign In or Register to comment.