i have one logitech mouse quad rotary encoder attached to pins 2,3 and two attachInterupts to trigger on CHANGE.
the interrupts update a counter depending on positive or negative direction. the counter is a volatile long which sometimes gives really jumpy values:
// [pin2 state],[pin3 state] [counter]
// ....
1,0 33
0,0 32
0,1 31
1,1 30
1,0 29
0,1 27
1,0 25
0,1 23
1,0 21
0,1 19
1,0 409517
1,1 14
0,0 12
1,1 10
0,0 8
// ....
wiring:
<GND>----<R (330 ohm)>----<LED>----<pin 7, HIGH>
<GND>
|
<LDR1>----<pin 2>
|
<5V>
<GND>
|
<LDR2>----<pin 3>
|
<5V>
code:
int ledPin = 7;
int aPin = 0; // digital pin 2
int bPin = 1; // digital pin 3
volatile int aState = LOW;
volatile int bState = LOW;
volatile int last = 0;
volatile long counter = 0;
volatile int counterChanged = 1;
volatile int changing = 0;
void setup ()
{
Serial.begin(9600);
pinMode( ledPin, OUTPUT );
digitalWrite( ledPin, HIGH );
attachInterrupt( aPin, aChange, CHANGE );
attachInterrupt( bPin, bChange, CHANGE );
}
void loop ()
{
if ( counterChanged && !changing )
{
Serial.print( aState );
Serial.print( "," );
Serial.print( bState );
Serial.print( " " );
Serial.println( counter );
counterChanged = 0;
}
}
void aChange ()
{
changing = 1;
aState = !aState;
updateCounter();
changing = 0;
}
void bChange ()
{
changing = 1;
bState = !bState;
updateCounter();
changing = 0;
}
void updateCounter ()
{
int now = (aState << 1) + bState;
if ( (last == 0 && now == 2) ||
(last == 2 && now == 3) ||
(last == 3 && now == 1) ||
(last == 1 && now == 0) )
{
counter++;
counterChanged = 1;
}
else if (
(last == 0 && now == 1) ||
(last == 1 && now == 3) ||
(last == 3 && now == 2) ||
(last == 2 && now == 0) )
{
counter--;
counterChanged = 1;
}
else
{
// ignore
}
last = now;
}
can anyone see the problem here? why would a counter that's updated with ++ or -- be so jumpy? is this due to the serial communication being to tight in loop()?
many thanks!
F
btw, this is to measure a cd-tray which i'm sliding in / out. i'm trying to get around having to read the mouse via PS/2 (http://vimeo.com/1428015) which will not allow to exactly control the motor to stop at a certain position.