Arduino Quadrature Encoder
Early quadrature encoder development. Not functional – example only
Much of this is from here
volatile long timeA, oldtimeA;
volatile long timeB, oldtimeB;
volatile int LEDstate = LOW;
int tryingToUnderstand = 0;
void A() //interrupt for channel A
{
timeA = millis(); // consider overflow and disable interrupts
LEDstate = !LEDstate;
}
void B() //interrupt for channel B
{
timeB = millis(); // consider overflow and disable interrupts
LEDstate = !LEDstate;
}
void setup ()
{
pinMode(2, INPUT); // interupt 0 is on pin 2
pinMode(3, INPUT); // interupt 1 is on pin 3
pinMode(13, OUTPUT); // heartbeat or debugging
Serial.begin(9600);
oldtimeA = timeA = 0;
oldtimeB = timeB = 0;
attachInterrupt(0, A, FALLING); //interupt on falling edge; int 0 is on pin 2
attachInterrupt(1, B, FALLING); //interupt on falling edge; int 1 is on pin 3
}
void loop()
{
// don't do anything unless something has changed
if ( (timeA - oldtimeA) || (timeB - oldtimeB) )
{
// For understanding what's going on
if (tryingToUnderstand)
{
digitalWrite(13, LEDstate); // update the heartbeat
Serial.print("timeA old ");
Serial.print(oldtimeA);
Serial.print(" new ");
Serial.print(timeA);
Serial.print(" timeB old ");
Serial.print(oldtimeB);
Serial.print(" new ");
Serial.println(timeB);
}
// Real application
// What range would we expect to see? According to data sheet there are 200
// transitions per revolution. Knowing the range of speeds that a visitor
// might turn the knob we could calculate the range of milliseconds expected
// between interupts
if ( (timeA - timeB) > 100 )
Serial.println("right");
if ( (timeA - timeB) < -100)
Serial.println("left");
// Since something has changed, record this time
oldtimeA = timeA;
oldtimeB = timeB;
}
}
Quadrature decoder that works properly
volatile long timeA, oldtimeA;
volatile long timeB, oldtimeB;
volatile int LEDstate = LOW;
int tryingToUnderstand = 0;
void A() //interrupt for channel A
{
timeA = millis(); // consider overflow and disable interrupts
LEDstate = !LEDstate;
}
void B() //interrupt for channel B
{
timeB = millis(); // consider overflow and disable interrupts
LEDstate = !LEDstate;
}
void setup ()
{
pinMode(2, INPUT); // interupt 0 is on pin 2
pinMode(3, INPUT); // interupt 1 is on pin 3
pinMode(13, OUTPUT); // heartbeat or debugging
Serial.begin(9600);
oldtimeA = timeA = 0;
oldtimeB = timeB = 0;
attachInterrupt(0, A, FALLING); //interupt on falling edge; int 0 is on pin 2
attachInterrupt(1, B, FALLING); //interupt on falling edge; int 1 is on pin 3
}
void loop()
{
// don't do anything unless something has changed
if ( (timeA - oldtimeA) || (timeB - oldtimeB) )
{
// For understanding what's going on
if (tryingToUnderstand)
{
digitalWrite(13, LEDstate); // update the heartbeat
Serial.print("timeA old ");
Serial.print(oldtimeA);
Serial.print(" new ");
Serial.print(timeA);
Serial.print(" timeB old ");
Serial.print(oldtimeB);
Serial.print(" new ");
Serial.println(timeB);
}
// Real application
// What range would we expect to see? According to data sheet there are 200
// transitions per revolution. Knowing the range of speeds that a visitor
// might turn the knob we could calculate the range of milliseconds expected
// between interupts
if ( (timeA - timeB) > 100 )
Serial.println("right");
if ( (timeA - timeB) < -100)
Serial.println("left");
// Since something has changed, record this time
oldtimeA = timeA;
oldtimeB = timeB;
}
}
And here is the minimal example of interrupts:
volatile long LEDstate;
void ding()
{
LEDstate = !LEDstate;
}
void setup ()
{
pinMode(2, INPUT); // interrupt 0 is on pin 2
pinMode(13, OUTPUT); // heartbeat or debugging
attachInterrupt(0, ding, FALLING); //interupt on falling edge; int 0 is on pin 2
}
void loop()
{
delay(10);
digitalWrite(13, LEDstate);
}