Shop OBEX P1 Docs P2 Docs Learn Events
Building an IR tachometer - logic problem? — Parallax Forums

Building an IR tachometer - logic problem?

r.daneelr.daneel Posts: 96
edited 2013-09-29 22:22 in Propeller 1
Hi,

I am building what amounts to a tachometer using an IR sensor, and I am tearing my hair out trying to find what's wrong with my logic. The hardware setup is simple - I have a TCRT5000 IR sensor module pointing at a rotating 50/50 black and white disc. The IR module works at 3.3V, is powered from the same 3.3V supply as the Prop, and is always on. The IR module has both analog and digital output pins - the digital out is connected directly to one of the Prop's IO pins. To test what's happening I have two LEDs connected to two other IO pins.

My simple test program looks like this:
CON
   
  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000


VAR

  long irPin, led1Pin, led2Pin

  
PUB Main

  irPin   := 9           ' IR sensor
  led1Pin := 10          ' BLUE LED
  led2Pin := 11          ' RED LED

  cognew(@entry, @irPin) ' don't care about return value for this test
    

DAT
                        org

entry                   mov     arg, par
                        rdlong  scr, arg           ' IR sensor pin
                        shl     ir, scr            ' mask

                        add     arg, #4            
                        rdlong  scr, arg           ' BLUE LED pin
                        shl     blue, scr          ' mask

                        add     arg, #4        
                        rdlong  scr, arg           ' RED LED pin
                        shl     red, scr           ' mask

                        mov     scr, #0         wc
                        muxc    outa, blue         ' BLUE LED off
                        muxc    outa, red          ' RED LED off

                        mov     dira, #0           ' all pins input
                        or      dira, blue         ' BLUE LED pin is output
                        or      dira, red          ' RED LED pin is output

                        waitpeq ir, ir             ' start - wait for IR pin to go high (seeing black)

loop                    waitpne ir, ir             ' wait for IR pin to go low (seeing white)

                        or      outa, blue         ' BLUE LED on
                        
                        mov     scr, #0         wc
                        muxc    outa, red          ' RED LED off
                                                   
                        waitpeq ir, ir             ' wait for IR pin high (seeing black)
                        
                        mov     scr, #0         wc
                        muxc    outa, blue         ' BLUE LED off

                        or      outa, red          ' RED LED on

                        jmp     #loop              ' loop


ir                      long    1
blue                    long    1
red                     long    1

arg                     res     1
scr                     res     1



It's pretty simple really - as the disc rotates and the black and white halves come into view of the IR sensor, the LEDs are supposed to blink alternately. This works just as expected - as I rotae the disc the LEDs do indded blink alternately.

What I really want is that a switch is turned on and off alternately on every revolution - so on rev 1 the switch goes on, rev 2 off, rev 3 on etc. SHouldn't be too difficult (I thought...). I changed the loop in the code to:
loop                    waitpne ir, ir             ' wait for IR pin to go low (seeing white)

                        or      outa, blue         ' BLUE LED on
                                                   
                        waitpeq ir, ir             ' wait for IR pin high (seeing black)
                        
                        mov     scr, #0         wc
                        muxc    outa, blue         ' BLUE LED off

                        xor     outa, red          ' RED LED on

                        jmp     #loop              ' loop


What I expected was that as the black and white halves of the disc were seen by the IR sensor the blue LED would blink as before, and as the black half of the disc came into view (and only the black half) the red LED would change state. What actually happens is that most of the time the LEDs behave as before - they blink alternately as the black and white halves of the disc come into view. Sometimes they will both come on, but they are never both off.

I've looked at this too long - I can't see where my problem is. Can anyone help?

Thanks.

Comments

  • Beau SchwabeBeau Schwabe Posts: 6,566
    edited 2013-09-25 09:27
    Hi r.daneel !!

    Welcome to the Parallax forum!



    Your code works, as you expected. If the Blue LED represents Bit0 and the Red LED represents Bit1 in a binary counter, then the repeating sequence is ...

    00
    01
    10
    11
    ... and then back to 00 to repeat the sequence

    What does your circuit look like, perhaps there is bounce on your signal that is causing a problem. You mentioned that "The IR module has both analog and digital output pins", but the datasheet for the TCRT5000 is a typical open collector transistor output without any signal conditioning ...basically analog.


    You can also simplify this...
                            mov     scr, #0         wc
                            muxc    outa, blue         ' BLUE LED off
    
    to this...
                            andn    outa, blue         ' BLUE LED off
    
  • r.daneelr.daneel Posts: 96
    edited 2013-09-25 10:59
    Hi Beau, and thanks!

    The IR module I'm using is built from the TCRT5000 sensor. It's one of these:

    TCRT5000 Module 2.png


    My circuit is pretty simple. Both the Prop and the IR module are powered from the same 3.3V source - so VCC and GND on the IR module are connected to the same VCC and GND as the Prop. No switching - when the Prop is powered so is the IR module.

    The DO pin of the IR module is connected directly to Pin 9 of the Prop.
    The AO pin of the IR module is not connected.
    Pin 10 of the Prop is connected to a 100Ohm resistor which is connected to the positive lead of a blue LED. The other side of the LED goes to GND.
    Pin 11 of the Prop is connected to a 100Ohm resistor which is connected to the positive lead of a red LED. The other side of the LED goes to GND.

    That's it...

    I thought about bounce - but the first test program works just fine. Wouldn't that be subject to bounce as well? If it is bounce, can I smooth it out somehow?
    737 x 1015 - 526K
  • Beau SchwabeBeau Schwabe Posts: 6,566
    edited 2013-09-25 12:09
    "I thought about bounce - but the first test program works just fine. Wouldn't that be subject to bounce as well?" - possibly, but you wouldn't necessarily see it visually unless you had a scope. I don't see any kind of hysteresis with those modules.


    " If it is bounce, can I smooth it out somehow?" - A schmitt trigger on the output of the module might help but only after a small integrator circuit....

    Small Integrator
                         1k
    From IR sensor >----/\/\----o------> to Schmitt Trigger
                                |
                                |
                                o--||--> GND
                                  0.1uF
    

    Without hysteresis you will have 'edge' jitter on each transition of your IR detector.

    Note; it is also possible to smooth out a signal bounce in software by oversampling. This is done by ensemble averaging, which basically increases your signal to noise ratio.

    The Signal to noise ratio is essentially equal to the square root of the number of samples taken and closely relates to Nyquist. The caveat is that for every time you sample you take away from the maximum speed or rate in which you can detect a pulse from your IR detector circuit.


    Here is something I put together a few years ago trying to explain Nyquist in a nut-shell...
    http://wiki.ohmspace.org/What_is_Nyquist_doing_for_you%3F
  • Beau SchwabeBeau Schwabe Posts: 6,566
    edited 2013-09-25 16:11
    You can also implement a settling time delay to act as a debounce if you know that your signal is stable at some known time after the HIGH or LOW transition.

    Try the code below and see if that will help. Note, you might need to adjust the Delay value.
    CON
       
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
    
    VAR
    
      long irPin, led1Pin, led2Pin
    
      
    PUB Main
    
      irPin   := 9           ' IR sensor
      led1Pin := 10          ' BLUE LED
      led2Pin := 11          ' RED LED
    
      cognew(@entry, @irPin) ' don't care about return value for this test
        
    
    DAT
                            org
    
    entry                   mov     arg, par
                            rdlong  scr, arg           ' IR sensor pin
                            shl     ir, scr            ' mask
    
                            add     arg, #4            
                            rdlong  scr, arg           ' BLUE LED pin
                            shl     blue, scr          ' mask
    
                            add     arg, #4        
                            rdlong  scr, arg           ' RED LED pin
                            shl     red, scr           ' mask
    
                            andn    outa, blue         ' BLUE LED off
                            andn    outa, red          ' RED LED off
    
                            mov     dira, #0           ' all pins input
                            or      dira, blue         ' BLUE LED pin is output
                            or      dira, red          ' RED LED pin is output
    
                            waitpeq ir, ir             ' start - wait for IR pin to go high (seeing black)
    
    
    loopA                   waitpne ir, ir             ' wait for IR pin to go low (seeing white)
                            call    #Debounce
                      if_c  jmp     #loopA      
                            or      outa, blue         ' BLUE LED on
    loopB                   waitpeq ir, ir             ' wait for IR pin high (seeing black)
                            call    #Debounce
                      if_c  jmp     #loopB      
                            andn    outa, blue         ' BLUE LED off
                            xor     outa, red          ' RED LED toggle
                            jmp     #loopA             ' loop
    Debounce                mov     temp,cnt
                            add     temp,delay
                            waitcnt temp,#0
                            test    ina,ir          wc
    Debounce_ret            ret                        
                  
    
    
    ir                      long    1
    blue                    long    1
    red                     long    1
    
    temp                    long    0
    Delay                   long    800 ' 1/100,000th of a second 
    
    arg                     res     1
    scr                     res     1
    
  • r.daneelr.daneel Posts: 96
    edited 2013-09-25 16:46
    Beau - that's great, thank you! I was just about to code a debounce routine. I'll play with the delay value and see if I can make it work.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-09-25 17:04
    I'm not sure if there's anything in this recent thread about using an encoder with the Propeller would be helpful or not.

    I used three different techniques to capture the encoder pulse but I didn't use your waitpxx technique. I was getting erratic readings when using counters to monitor the encoders. Tracy Allen had some good advice about ground bounce.

    You might be interested in the techniques I used to read the encoder as a comparison to your method. I wonder how many other ways one can read an encoder with a Prop?
  • r.daneelr.daneel Posts: 96
    edited 2013-09-28 14:52
    Duane, thanks. Some interesting stuff there. Any reason you didn't use waitpxx? (Is there something I should have thought about that I haven't...?)

    I'll mark this thread as solved - thanks Beau and Duane.
  • cavelambcavelamb Posts: 720
    edited 2013-09-28 17:31
    What would be "bouncing" with an IR sensor???
  • r.daneelr.daneel Posts: 96
    edited 2013-09-29 14:37
    I think Beau was referring to signal jitter. See

    http://www.techrepublic.com/blog/data-center/noise-and-jitter-nemesis-of-digital-communications/

    I'm a software person that knows enough about hardware to make me dangerous, especially with a soldering iron in my hand. Anything beyond that explanation will have to come from someone like Beau.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-09-29 19:09
    r.daneel wrote: »
    Any reason you didn't use waitpxx?

    I just hadn't thought of using it. I like the idea.
    cavelamb wrote: »
    What would be "bouncing" with an IR sensor???

    I don't really understand. Anything I said would just be repeating what others stated in the thread. As I mentioned in the thread, the issue only occurred when the sensor and servo motor were sharing the same power supply.
  • SteveWoodroughSteveWoodrough Posts: 190
    edited 2013-09-29 19:26
    Just for giggles research Schmidt trigger and Comparator in Google. You'll learn a LOT. Do you have access to a scope? Get access or buy the Prop Scope. Build the Schmidt trigger, then play with a comparator with hysteresis. Also be careful using IR sensors out doors. In the daylight they get blinded, and do funny things. Best Regards,
    Steve
  • cavelambcavelamb Posts: 720
    edited 2013-09-29 21:12
    Duane Degn wrote: »
    I just hadn't thought of using it. I like the idea.

    I don't really understand. Anything I said would just be repeating what others stated in the thread. As I mentioned in the thread, the issue only occurred when the sensor and servo motor were sharing the same power supply.

    Sorry. Didn't see the reference to the servo on the same power supply.
    Inductive kickback makes a lot of electrical "noise". Spiky, high voltage noise.
    the kind of electrical noise that will drive logic circuits nuts.

    Filtering and / or isolation are the only cures for that.
  • r.daneelr.daneel Posts: 96
    edited 2013-09-29 22:22
    cavelamb wrote: »
    Sorry. Didn't see the reference to the servo on the same power supply.
    Inductive kickback makes a lot of electrical "noise". Spiky, high voltage noise.
    the kind of electrical noise that will drive logic circuits nuts.

    Filtering and / or isolation are the only cures for that.

    I had nothing on the same power supply when I was doing my test - well, nothing other than the Prop and the IR sensor. Waiting for the jitter to settle down (i.e. using the code Beau provided) solved the problem. Again, I'm no hardware engineer, but I get the impression that signal jitter is just part of the deal - introducing hysteresis, averaging the signal over a few samples or just waiting for the jitter to settle are just different ways of solving the problem.
Sign In or Register to comment.