View previous topic :: View next topic |
Author |
Message |
Lemosek
Joined: 15 Oct 2011 Posts: 36
|
18f4685 encoder problem |
Posted: Wed Feb 15, 2012 8:32 am |
|
|
Hello,
I found on this forum code from Mr. Ttelmah to read encoder position.
I try using this, but I have some problems.
My code:
Code: |
//*****************************************************
//obsługa enkodera
//
//*****************************************************
#int_ext
void int_rb_isr(void) {
static int8 old;
static int8 new;
static int8 value;
new=PORTB; //You don't need a separate function for this....
//Assuming the encoder is on B1, and B2
//Now I have to decode the quadrature changes. There are four
//possibilities:
//I can have a rising or falling edge, on each of the two inputs. I have to
//look at the state of the other bit, and increment/decrement according to
//this.
value=new^old;
//'value', now has the bit set, which has changed
if (value & 0x2) {
//Here the low bit has changed
if (new & 0x2) {
//Here a rising edge on A
if (new & 0x4) --position;
else ++position;
}
else {
//Here a falling edge on A
if (new & 0x4) ++position;
else --position;
}
}
else {
//Here the high bit (B) must have changed
if (new & 0x4) {
//Here a rising edge on B
if (new & 0x2) ++position;
else --position;
}
else {
//Here a falling edge on B
if (new & 0x2) --position;
else ++position;
}
}
old=new;
}
main
{
clear_interrupt(INT_RB);
clear_interrupt(INT_EXT);
enable_interrupts(INT_EXT);
enable_interrupts(INT_EXT1);
enable_interrupts(GLOBAL);
while(1)
{
printf(lcd_putc, "%u", position);
}
}
|
My problem is when I turn left I have for example 10 9 10 11. Other side is 11 12 11 10.
Why does this happen ??
My compiler version 4.120
Encoder is connected to RB0 and RB1 pins.
Best regards
R.L. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Wed Feb 15, 2012 10:53 am |
|
|
That is not the code I posted, but something 'bodged' from it.
My code uses INT_RB only. As posted the code will only respond to changes on one bit and miss two of the four states.
You also have INT_EXT1 enabled without a handler, which will cause indeterminate behaviour.
What chip are you using (affects what pins can be used).
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
Lemosek
Joined: 15 Oct 2011 Posts: 36
|
|
Posted: Wed Feb 15, 2012 11:02 am |
|
|
Hello,
My chip is 18f4685. Maybe my code is wrong.
So how this code I must use. I use RB0(INT0) and RB1(INT1) pins.
I use INT_EXT because this chip don't have INT_RB1 and INT_RB0.
Best regards
R.L. |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9174 Location: Greensville,Ontario
|
|
Posted: Wed Feb 15, 2012 12:47 pm |
|
|
Get familiar to using the 'search' function on this forum. You'll soon find a zillion answers to encoder. It's up to you to decide which best suits your project.
If your PIC has INT_RB, it's a simple matter to get 2 encoders to work with the B7...4 pins.
you could also look at the examples in the examples folder...... |
|
![](templates/subSilver/images/spacer.gif) |
Lemosek
Joined: 15 Oct 2011 Posts: 36
|
|
Posted: Wed Feb 15, 2012 1:13 pm |
|
|
Hello, In example folder, example don't use the interrupt. I can't change pcb to connect encoder to RB7..4. I need to use INT0(RB0) and INT1(RB1).
Can someone help me ??
Best regards
R.L. |
|
![](templates/subSilver/images/spacer.gif) |
Lemosek
Joined: 15 Oct 2011 Posts: 36
|
|
Posted: Thu Feb 16, 2012 4:20 am |
|
|
Hello, I solve My problem code below
Code: |
#int_ext high
void int_rb_isr(void) {
static int8 old;
static int8 new;
static int8 value;
new=PORTB;
value=new^old;
//'value', now has the bit set, which has changed
if (value & 0x1) {
//Here the low bit has changed
if (new & 0x1) {
//Here a rising edge on A
if (new & 0x2) position--;
else position++;
}
else {
//Here a falling edge on A
if (new & 0x2) position++;
else position--;
}
}
else {
//Here the high bit (B) must have changed
if (new & 0x2) {
//Here a rising edge on B
if (new & 0x1) position++;
else position--;
}
else {
//Here a falling edge on B
if (new & 0x1) position--;
else position++;
}
}
old=new;
clear_interrupt(INT_EXT);
}
main
{
clear_interrupt(INT_EXT);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
while(1)
{
printf(lcd_putc, "%u", position);
}
}
|
I don't known why I must add clear_interrupt at interrupt subroutine ??
Best regards
R.L. |
|
![](templates/subSilver/images/spacer.gif) |
|