Opto interrupter ;>


Closed Thread
Results 1 to 10 of 10

Hybrid View

  1. #1
    Join Date
    May 2010
    Posts
    11

    Default Opto interrupter ;>

    hello everyone i have some problems with counting pulses, main purpose of this program is to stop motor after some time yea i know i could just use delay and stop it after some time, but i need to know the motor position. Something like this: At start motors calibrates to main position, after some work i need to know what positions they are. Sorry for poor English. i am using encoder with 4 positions 90 180 270 360 degrees. so one rotate = 4 pulses. i am now experimenting with led's and tryed this code, i am green in programing if someone could help me it would be great. here is code:
    Code:
    ANSEL = 0
    OSCCON = $60
    TRISB = %00001000
    TRISA = %00000000
    counts var byte
    opto var PORTB.3
    led VAR PORTB.4
    led2 var PORTB.5
    counts = 0
    loop
    if opto = 1 then
    counts = counts+1
    if counts >=10 THEN 
    high led
    endif
    endif
    goto loop
    end
    i am using pic16f88. also i think i need to use interrupts but i don't have any idea how to, i checked on datasheet but its to complex for me :/

  2. #2
    Join Date
    May 2010
    Posts
    11


    Did you find this post helpful? Yes | No

    Default

    someone ?

  3. #3
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,604


    Did you find this post helpful? Yes | No

    Default

    Hi,
    The problem with your current aproach is that if the input stays high longer than it takes for the program to cycle it will keep on counting. Think of it, the input goes high, the variable is incremented and the program starts over, the input is still high, the variable get incremented and the program starts over and so on.

    We're talking micro seconds here so if one pulse from your opto-interupter is 2ms long you may count from 0-10 in one single pulse. You need to wait for the input to go high, increment your count variable then wait for the input to go low again before you allow another count. Something like:
    Code:
    loop:
      if opto = 1 then
        counts = counts+1
        if counts >=10 THEN 
          high led
        endif
        
    Code:
    While opto = 1      'Loop here until input goes low.
        Wend
       endif
    goto loop



    A better way though would be to use one of the PICs internal timers configured as a counter and simply let it count the pulses. Have a look at the TMR1 section of the datasheet.

    About your code then, you haven't DEFINEd the oscillator speed and there's a colon missing after the loop label...

    /Henrik.

    EDIT: OK, I give up....why the heck does the editor keeps inserting code tags on it's own in the middle of a section already surounded by code tags??
    Last edited by HenrikOlsson; - 4th June 2010 at 10:26. Reason: The bloody editor keeps inserting code tags on it's own - AAARGH.

  4. #4
    Join Date
    May 2010
    Posts
    11


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by HenrikOlsson View Post
    Hi,
    The problem with your current aproach is that if the input stays high longer than it takes for the program to cycle it will keep on counting. Think of it, the input goes high, the variable is incremented and the program starts over, the input is still high, the variable get incremented and the program starts over and so on.

    We're talking micro seconds here so if one pulse from your opto-interupter is 2ms long you may count from 0-10 in one single pulse. You need to wait for the input to go high, increment your count variable then wait for the input to go low again before you allow another count. Something like:
    Code:
    loop:
      if opto = 1 then
        counts = counts+1
        if counts >=10 THEN 
          high led
        endif
        
    Code:
    While opto = 1      'Loop here until input goes low.
        Wend
       endif
    goto loop



    A better way though would be to use one of the PICs internal timers configured as a counter and simply let it count the pulses. Have a look at the TMR1 section of the datasheet.

    About your code then, you haven't DEFINEd the oscillator speed and there's a colon missing after the loop label...

    /Henrik.

    EDIT: OK, I give up....why the heck does the editor keeps inserting code tags on it's own in the middle of a section already surounded by code tags??
    Thank You, i will read about TMR1, i played some time and thinked about counting pulses and wited program which works fine for now

    Code:
    ANSEL = 0
    OSCCON = $60
    TRISB = %00001000
    TRISA = %00000000
    cnt var byte
    opto var PORTB.3
    led VAR PORTB.4
    led2 var PORTB.5
    low led
    cnt = 0
    opto = 0
    Begin:
    if opto = 1 then skc
    goto begin
    
    skc:
    cnt=cnt+1
    if cnt >=20 then ledas
    pause 50
    goto begin
    
    ledas:
    cnt = 0
    high led
    goto begin
    end
    But doing it with wile its much better than my idea but now i have problem with doing another process like controlling motor and counting optocoupler pulses, i need use interrupts without question i think :/ OSC is 4Mhz.
    Last edited by deimantas; - 4th June 2010 at 10:59.

  5. #5
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    I think Henriks' idea of using a timer/counter is the way to go. This leaves you tons of time to handle other things while the counter works for you in the background.

    There is no need to wait with any WHILE/WEND, PAUSE, etc.

    Code:
    CMCON = 0        ' Disable comparators
    TRISA.4 = 1      ' RA4/T0CKI = input to TMR0 counter
    PORTB = 0        ' clear all outputs on PORTB
    TRISB = 0        ' PORTB outputs
    ANSEL = 0        ' All digital 
     
    ' OPTION_REG setup for Timer0
    ' Prescaler to WDT with 1:1 prescaler for TMR0
    ' TMR0 clock is external input on RA4/T0CKI
    ' Increment on low-to-high transitions on RA4/T0CKI
    ' Internal pull-ups disabled
     
       OPTION_REG = %10101000 
       TMR0 = 0     ' Clear TMR0 count
     
    Begin:
        IF TMR0 >= 20 THEN Ledas
     
        ' you have time to do lots of other thing here
        ' while Timr0 counts pulses in the background
     
        GOTO Begin
     
    Ledas:
       TMR0 = 0    ' clear Timer0 count here
       HIGH Led
       GOTO begin
    And if you prefer Timer0 to increment on high-to-low transitions on RA4, just change OPTION_REG = %10101000 to OPTION_REG = %10111000.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  6. #6
    Join Date
    May 2010
    Posts
    11


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Bruce View Post
    I think Henriks' idea of using a timer/counter is the way to go. This leaves you tons of time to handle other things while the counter works for you in the background.

    There is no need to wait with any WHILE/WEND, PAUSE, etc.

    Code:
    CMCON = 0        ' Disable comparators
    TRISA.4 = 1      ' RA4/T0CKI = input to TMR0 counter
    PORTB = 0        ' clear all outputs on PORTB
    TRISB = 0        ' PORTB outputs
    ANSEL = 0        ' All digital 
     
    ' OPTION_REG setup for Timer0
    ' Prescaler to WDT with 1:1 prescaler for TMR0
    ' TMR0 clock is external input on RA4/T0CKI
    ' Increment on low-to-high transitions on RA4/T0CKI
    ' Internal pull-ups disabled
     
       OPTION_REG = %10101000 
       TMR0 = 0     ' Clear TMR0 count
     
    Begin:
        IF TMR0 >= 20 THEN Ledas
     
        ' you have time to do lots of other thing here
        ' while Timr0 counts pulses in the background
     
        GOTO Begin
     
    Ledas:
       TMR0 = 0    ' clear Timer0 count here
       HIGH Led
       GOTO begin
    And if you prefer Timer0 to increment on high-to-low transitions on RA4, just change OPTION_REG = %10101000 to OPTION_REG = %10111000.
    This is nice feature in pic, but if i need to count 3 different optocouplers ? as i see in data sheet there are several pins which can do it. y ? BTW Thank You for Your response. I think i need to explain my project, it would be easier to get me on the path. My project is robot arm with 3 motors and 3 optical interrupters. i'm using opto interrupters to track my motors positions. and i am thinking alot about ti but cant find way to do it. at start i thinked about counting all free sensors in the same time but its quite hard to program for a newbie and if i think it will loose some pulses from other sensors because uC will do another processes in that time. also its quite hard to drive motors and count pulses at the same time is there any possibility to do it without interrupts or still its impossible ?
    Last edited by deimantas; - 4th June 2010 at 16:36.

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts