Shop OBEX P1 Docs P2 Docs Learn Events
IR Detectors — Parallax Forums

IR Detectors

ErikgunitErikgunit Posts: 4
edited 2009-12-18 13:24 in Accessories
Hi all. So i am trying to time objects as they pass through a set of IR detectors. Basically i want to keep track of the time it takes from the tripping of the first to the tripping of the last sensor similar to the speed sensors used for bullets and archery. Follow me so far?

So by dividing the distance by time, i will get velocity. cool. I am connecting a the IR emitter from V+ to ground through a 330 resistor and that points to a detector that is connected to V+ through a 20k resistor and is pulled low when the detector detects. it works, at least with one IR pair. And the detector and emitter have to bee within about an inch and i know i should have more distance...

I am using an if then statement to light an led when the beam is broken, and it works pretty well by response time is not that quick and if i move my hand too fast it wont see it. How can i get the precision closer, so that i dont have to worry about speed? If that question makes sense lol. Also I just dont see the IF THen statement to be robust enough to handle three IR pairs. Do i have other options then using IF THEN?

Thanks for your help guys.

Comments

  • LeonLeon Posts: 7,620
    edited 2009-12-17 12:52
    What MCU are you using?

    Leon

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Amateur radio callsign: G1HSM
  • Tony B.Tony B. Posts: 356
    edited 2009-12-17 12:58
    I see this is your first post.· For members to be able to help you, you·will need to provide more information about your project, such as, what Micro are you using and your code as an attachment.
    I think the goal of your project is understandable.
  • ErikgunitErikgunit Posts: 4
    edited 2009-12-17 18:20
    The stamp is the BS2.

    Im not at my workstation currently so i cant get the code there but ill put what i can remember from last night.

    Basically we have a simple If then

    Label

    IF Right_IR = 0 then unbroken

    ····· Else High 15 *lights the led telling me that the beam is broken*

    ····· Debug "Beam is broken."

    ····· pause 50

    ····· low 15

    Goto Label

    :unbroken

    Debug "The Beam is unbroken"

    goto label



    This code works fairly well but when i tried to modify to add more IR pairs i ran into an issue of them not getting a chance to even detect. (If that makes sense.)

    I added Elseif statements when i tried to add the other pairs but i think that it was something like this:

    Label

    IF Right_IR = 0 then unbroken

    ····· High 15 *lights the led telling me that the beam is broken*

    ····· Debug "Beam is broken."

    ····· pause 50

    ····· low 15

    elseif Middle_IR = 0 then unbroken

    ····· Else High·13 *lights the led telling me that the beam is broken*

    ····· Debug "Beam is broken."

    ····· pause 50

    ····· low 13

    ELSEIF·Left_IR = 0 then unbroken

    ····· Else High 11 *lights the led telling me that the beam is broken*

    ····· Debug "Beam is broken."

    ····· pause 50

    ····· low 11

    Goto Label

    :unbroken

    Debug "The Beam is unbroken"

    goto label



    It is VERY rudimentary code i know. Thrown together in a few minutes based on what i had seen on line. any optimization and help you guys can give would be awesome.
  • LeonLeon Posts: 7,620
    edited 2009-12-17 18:30
    The Stamp probably isn't fast enough for what you are trying to do; it's running interpreted code which is very slow.

    Leon

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Amateur radio callsign: G1HSM
  • Mike GreenMike Green Posts: 23,101
    edited 2009-12-17 20:05
    Another piece is that the DEBUG statements take quite a bit of time to execute. They transmit their data whether anything is looking at it or not and, at 9600 Baud, it takes about 1ms per character to do so.
  • ZootZoot Posts: 2,227
    edited 2009-12-17 21:29
    Hmmm... certainly the debugs have to go. A Stamp may be fast enough for this if you take a state machine and counter approach, so that the sensors can always be scanned very rapidly and still get other work done, e.g.

    
    Right_IR PIN 0 '  not sure about wiring but it will be easiest if all IR detectors are aligned on nibs
    Middle_IR PIN 1
    Left_IR PIN 2
    More_IR PIN 3
    AllIr VAR INA ' or INL if 8 detectors, or INB if pins 4-7 etc.
    
    IrState VAR Byte ' for "capturing" IR input
    
    
    LedR PIN 12 ' ditto on nib alignment
    LedM PIN 13
    LedL PIN 14
    LedMore PIN 15
    Leds VAR OUTD
    
    state VAR Byte
    counter VAR Word
    
    time VAR Word ' running total of time to get from first to last detector, in loops
    
    Start:
      LOW Led
      state = 0
      counter = 100 ' set up for "startup" state
      time = 0
    
    
    Main:
    
    Update_Detectors:
        IrState = AllIr  ' capture current detector status
    
    Update_Leds: 'this could be moved into each state as well, if you want to blink leds at different rates, or whatever
        Leds = IrState' if broken, input is HIGH, so just move values to LEDs
    
    
    Do_States:
       IF counter > 0 THEN
          counter = counter - 1 ' counter is always decremented to 0 on each pass; states reset to some timeout value
                ' this can be used for delays, led blinks, etc
       ENDIF
    
       time = time + 1 ' incrementel timer, reset to 0 by state machines
       
       ON state GOTO state0, state1, state2, state3, state4, state5, state6  ' etc
       ' generally ON GOTO and ON GOSUB are much much much faster to execute than IF/THEN/ELSE
    
       state0: ' the startup state
            IF counter = 0 THEN
               state = 1
               FREQOUT, Speaker, 2000, 2000 ' longer start beep now we're moving!
            ELSEIF counter//20 = 0 THEN ' occasionally make a beep
                FREQOUT, Speaker, 1000, 1000
            ENDIF
          GOTO StatesDone       
    
       state1:   ' waiting for first beam to be broken
           IF IrState = %0001 THEN ' the first detector (right) must have broken and gone high
              state = 2 ' next state
          ENDIF
          GOTO StatesDone
    
       state2: ' we don't need to deal with LEDs, so maybe do something useful
                  ' here you wait for the detector to go back low again, this state may not be needed if the times are fast 
            IF IrState.BIT0 = 0 THEN ' it's unbroken again
                state = 3
                time = 0  ' reset the time
            ENDIF
             GOTO StatesDone
    
      state3: ' waiting for middle detector to be broken
            IF IrState.BIT1 = 1 THEN ' it's broken
                state = 4
            ENDIF
             GOTO StatesDone
    
      state4: ' waiting for last detector to be broken
            IF IrState.BIT2 = 1 THEN ' it's broken
                state = 5
            ENDIF
            GOTO StatesDone
    
    
      state5: '  then unbroken
            IF IrState.BIT2 = 0 THEN ' it's unbroken, must be done!
                state = 6
            ENDIF
            GOTO StatesDone
            
      state6: ' done, report the time, a debug here is OK perhaps, if no more objects are coming
           DEBUG CLS
           DEBUG "total time from fully passing through detector 1 ", CR, " to fully passing thru detector 3: ", DEC5 time
           state = 0 ' and do it all again
           counter = 100 
    
    
    StatesDone:
          ' could do more common stuff here, like printing status to LCD or whatever, nothing to lengthy
          ' more code
          GOTO Main
    
    
    
    



    Now, if you want a little more "time" to show LEDs lit upon a detector change, you could remove the code for updating the LEDs right from the detector inputs, and add a bit of custom code to each state to set LEDs exactly how you want and set the counter to keep them that way for a bit. I will emphasize that using nibbles and bytes for reading inputs and setting outputs is a good way to keep things much shorter (e.g. quicker). The "capturing" of the IR detector pins is so that a change in input pin state in the middle of executing the loop won't throw things off -- ideally such a pin state change would still be "caught" at the top of the loop on the next cycle.

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

    1uffakind.com/robots/povBitMapBuilder.php
    1uffakind.com/robots/resistorLadder.php
  • ErikgunitErikgunit Posts: 4
    edited 2009-12-18 04:50
    Thanks buddy! I cant wait to try it out. Did you just come up with that code off the top of your head? Actually after looking through the code, it looks like everything i ask, on a silver platter. Way more then i could have asked for!!
    Another quick question, can the BS2 supply enough current for such a system or would an external supply be better? I am going to assume that it is not but we will see.
    well wish me luck, ill be building and testing tonight. Soon!!
  • ZootZoot Posts: 2,227
    edited 2009-12-18 06:24
    Well, the proof will be in the pudding. See if it's fast enough to detect your moving objects. Mike may be right that the Stamp isn't fast enough (he often is) -- it really depends on just how fast your objects are moving. Let us know how it works out.

    Re: current -- if you are talking about the Stamp's on-board regulator -- it's only good for 50ma or so, if memory serves. Not much. So if you are hooking up a bunch of 5v components you may need an external 5v supply (e.g. a beefier regulator and associated circuitry).

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

    1uffakind.com/robots/povBitMapBuilder.php
    1uffakind.com/robots/resistorLadder.php
  • ErikgunitErikgunit Posts: 4
    edited 2009-12-18 08:12
    well i think i may be trying to power too many LEDs. IR and otherwise. Wheni tryed doing an HIGH outd· nothing happened but a high ledr turned one on.
    Does this make sense though. i cant even power 4 leds with a high out put on each LEDs pin. The battery seems ok but i think it may be getting old. getting a new one.
    Last question(for the night...er morning,.) the piece of code:
    Right_IR PIN 0 '  not sure about wiring but it will be easiest if all IR detectors are aligned on nibs
    Middle_IR PIN 1
    Left_IR PIN 2
    More_IR PIN 3
    AllIr VAR INA ' or INL if 8 detectors, or INB if pins 4-7 etc.
    

    Can Allir VAR reference INA. I understand INA is the first 4 inputs but i though VAR had to be bit,nib,byte,word?
    That and my IR detectors go low when the beam is broken· but i modded the code to fit. i am just not sure what to do with the LEDs not lighting up, at least all at once...
    Thanks for your patience!
  • ZootZoot Posts: 2,227
    edited 2009-12-18 13:24
    You can't do a HIGH OUTD -- it's not a "pin" but a variable that refers to the output states of that pin nibble. You set ALL the pins at once:

    OUTD = %0001 ' pin 12 high, 13-15 low
    OUTD = %1001 ' pin 12, 15 high, 13 & 14 low

    etc. Using "OUTX = " only works if the pins are already outputs.

    See the Pbasic manual for details about the input, output and dir registers. In my code example I'm just using AllIr as an "alias" to INA -- so I don't have to use INA or IND or whatever in the code. The reason? Makes it more readable AND if you change pins (where LEDs or detectors are hooked up) you don't have to change INA or OUTD or anything in all the places in main program -- just in once place at the top where the variable aliases are defined.



    If your detectors go LOW when the beam is broken, that is unusual -- what detectors are you using?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    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.