If you are losing encoder counts, then use an interrupt service routine.
Four of PORTB’s pins, RB<7:4>, have an interrupt-onchange feature.
Use two of these pins for the A/B encoder signals.
Luciano
If you are losing encoder counts, then use an interrupt service routine.
Four of PORTB’s pins, RB<7:4>, have an interrupt-onchange feature.
Use two of these pins for the A/B encoder signals.
Luciano
ok,heres my program ,using interrupts..
the problems i'm encountering are below the code
..
1>The interrupts are worng fine,however the code is still unable to distinguish between CW and CCW,because of which the counting goes awry..Code:DEFINE LOADER_USED 1 led VAR PORTB.7 old VAR BYTE new VAR BYTE direction_bit VAR BIT counter VAR WORD counter_1 VAR WORD counter_2 VAR WORD direction_store VAR BIT adval VAR WORD ' Create adval to store result potval VAR WORD servo_val VAR WORD difference VAR WORD counter=32500 HPwm 0,150,20000 OPTION_REG = $7f ON INTERRUPT GoTo myint ' Define interrupt handler INTCON = $90 ' Enable INTE interrupt loop: High led ' Turn LED on LCDOut $fe,1,"count:" LCDOut $fe,$c0,DEC counter 'Pause 10 GoTo loop ' Do it forever ' Interrupt handler Disable ' No interrupts past this point myint: Low led ' If we get here, turn LED off enc: new= PORTB & %00000011 start_1: old=new & %00000011 again: new= PORTB & %00000011 'load new value of A/B channels into new by anding with HEX3 'IF new=old Then again direction_bit=old.bit1 ^ new.bit0 'check direction IF direction_bit = 1 Then LCDOut $fe,1,"Last was CW" counter = counter + 1 'increment counter LCDOut $fe,$c0,DEC counter," ",BIN direction_bit Else LCDOut $fe,1,"Last was CCW" counter = counter - 1 'decrement counter LCDOut $fe,$c0,DEC counter," ", BIN direction_bit EndIF Pause 10 INTCON.1 = 0 ' Clear interrupt flag Resume ' Return to main program Enable
2>if i remove the "if then " statement for CW/CCW direction and only put a
counter=counter+1,it works well
The whole problem seems to be the direction decoding part..
..i cant seem to find a solution to it..
Last edited by ice; - 3rd May 2005 at 14:00.
Hi!
1.
You are using the wrong interrupt.
Four of PORTB’s pins, RB<7:4>, have an interrupt-onchange feature.
Use two of these pins for the A/B encoder signals.
2.
Use assembly code for the interrupt.
(See PicBasic Pro manual).
3.
In your code the variables "new" and "old" will have
most of the time the same values.
In your code you are doing that:
new= PORTB & %00000011 'get encoder A/B
old=new & %00000011 'old is now same as new
new= PORTB & %00000011 'get encoder A/B again
When you get A/B again, it is very likely that the encoder is
still in the same position, therefore the variables new and old
will have the same values.
* * * *
Did you try the code I posted the 12th April 2005, 11:00?
Does it work if you turn the encoder slowly?
Luciano
Luciano,
when i try the program u recommended [12th april] as below,
there are alot of instances when the program gets confused with direction,
so it sometime increments and decrements.Im not using interrupts
when i move the motor slowly,the problem still persists.
Thank you for your responsesCode:old_val VAR BYTE new_val VAR BYTE direction_bit VAR BIT enc_counter VAR WORD adval VAR WORD ' Create adval to store result potval VAR WORD servo_val VAR WORD difference VAR WORD TRISB=%11111111 enc_counter=32500 HPwm 0,100,20000 new_val = PORTB & %00000011 start: old_val = new_val again: new_val = PORTB & %00000011 'LCDOut $fe,1,"no move" IF new_val = old_val Then again direction_bit = old_val.bit0 ^ new_val.bit1 IF direction_bit = 1 Then LCDOut $fe,1,"Last was CW" enc_counter = enc_counter + 1 LCDOut $fe,$c0,DEC enc_counter Else LCDOut $fe,1,"Last was CCW" enc_counter = enc_counter - 1 LCDOut $fe,$c0,DEC enc_counter EndIF GoTo start
Last edited by ice; - 4th May 2005 at 11:55.
Hi!
I need more info.
The version of the PIC used. (16F628, 16F628A, ...).
If you are using a commercial board for the PIC, I need
the URL where I can see the board.
The brand and model number of the encoder and the URL where I can
download the data sheet.
I also need to know how you have connected the encoder to
PORTB.0 and PORTB.1. (Pull-up resistors? If yes, values).
Luciano
Luciano,
im using the PIC16F873AThe version of the PIC used. (16F628, 16F628A, ...).
I made my own dev board..has an LCD,A/D..the usual features..If you are using a commercial board for the PIC, I need
the URL where I can see the board.
works on a 4Mhz crystal..
The board works perfectly as i have run accelerometers,D/A converters from the same board
Maxon 22578The brand and model number of the encoder and the URL where I can
download the data sheet.
500 counts per turn
http://www.maxonmotor.com/docsx/Down...f/05_238_e.pdf
Pull up resistorsI also need to know how you have connected the encoder to
PORTB.0 and PORTB.1. (Pull-up resistors? If yes, values).
with value 1.8K
Thanks for all your help
Last edited by ice; - 5th May 2005 at 08:39.
ok,a little progress,
seems like i'm loosing counts ,because of the LCDout commands
if i make my code tighter[remove the LCDcommands],i am able to monitor direction ,but a bit of interference still persists.
I'm on a 4Mhz..i'll switch to a 20Mhz tomorrow and post my progress
Bookmarks