PDA

View Full Version : Opto interrupter ;>



deimantas
- 3rd June 2010, 21:47
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:


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 :/

deimantas
- 4th June 2010, 09:34
someone ? :)

HenrikOlsson
- 4th June 2010, 10:18
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:


loop:
if opto = 1 then
counts = counts+1
if counts >=10 THEN
high led
endif

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??

deimantas
- 4th June 2010, 10:44
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:


loop:
if opto = 1 then
counts = counts+1
if counts >=10 THEN
high led
endif

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 :)



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.

Bruce
- 4th June 2010, 15:15
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.



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.

deimantas
- 4th June 2010, 16:28
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.



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 ?

Bruce
- 4th June 2010, 17:35
Even more information would help. What type of motors, how are you driving them, what are the minimum & maximum motor speeds, what else does your firmware need to manage besides driving 3 motors, and counting pulses, etc.

deimantas
- 4th June 2010, 17:57
Even more information would help. What type of motors, how are you driving them, what are the minimum & maximum motor speeds, what else does your firmware need to manage besides driving 3 motors, and counting pulses, etc.

i am driving 3x 2.4 1A motors (from electrical screwdriver) via relays (here is circuit: http://www.rentron.com/PicBasic/relay-motor.gif just i am using much more lower resistors 470Ohms.), what speed i don't know, searched for documentation but couldn't find. i will build 3 buttons to calibration mode, at start robot will go from any position to starting position. i think that's all.

Bruce
- 4th June 2010, 18:12
Without some form of speed control you're going to need to know what the maximum RPMs are for these motors. Without knowing that you have no idea how much time you will have to count pulses.

deimantas
- 4th June 2010, 19:19
Without some form of speed control you're going to need to know what the maximum RPMs are for these motors. Without knowing that you have no idea how much time you will have to count pulses.

hmm i don't have any idea how to measure it, i can only visually show how it's working but i don't think it will be helpful.
http://www.youtube.com/watch?v=Ix8MLietGwY