Hi,
I'm trying to interface my Arduino micro to this encoder https://www.usdigital.com/products/e4t. The E4T has 500 counts per rev and is at a ratio of 4.706:1 to the output. Therefore 1x revolution of the output will give 2353 counts of the encoder.
I've connected channels A and B of the encoder to pins 0 and 1 of the Arduino Micro and then configured these pins as interrupts. My code is below:
//Output pin mapping
int motorPWMPin = 9;
int motorDirectionPin = A5;
//Encoder variables
unsigned long motorPulseCounter = 0;
int encoderMeasurementInterval = 100; //100ms delay between displaying rpm value
//Timing variable
unsigned long lastTime = 0;
//RPM variable
int rpm = 0;
void setup() {
Serial.begin(115200);
delay(2000); // Delay to allow for initialisation of serial
pinMode(motorPWMPin, OUTPUT);
pinMode(motorDirectionPin,OUTPUT);
attachInterrupt(digitalPinToInterrupt(0),motorInterrupt,CHANGE); //Motor encoder channel A attached to interrupt
attachInterrupt(digitalPinToInterrupt(1),motorInterrupt,CHANGE); //Motor encoder channel B attached to interrupt
setupTimer3_200mS(); //Setup a timer to trigger every 200ms (5Hz)
}
void loop()
{
digitalWrite(motorDirectionPin, 1);
analogWrite(motorPWMPin, 50);
while(1)
{
if (millis()-lastTime > encoderMeasurementInterval)
{
lastTime += encoderMeasurementInterval;
measure();
}
}
}
void setupTimer3_200mS()
{
// Disable global interrupts
cli();
//Disable timer
TCCR3A = 0;
TCCR3B = 0;
//16000000/1024/5 = 3125
// Set compare match register to desired timer count - 200ms 5Hz
OCR3A = 3125;
// Turn on CTC mode WGM32 set CS10 and CS12 bits for Timer3 prescaler of 1024
TCCR3B = bit (WGM32) | bit (WGM32) | bit (CS30);
// Enable timer compare interrupt
TIMSK3 |= (1 << OCIE3A);
// Enable global interrupts
sei();
}
ISR(TIMER3_COMPA_vect) // Timer3 interrupt
{
rpm = calculateRPM(motorPulseCounter);
motorPulseCounter = 0;
}
float calculateRPM(int pulses)
{
//Encoder 500 counts per rev and is at a ratio of 4.706:1 to the output.
//Therefore 1x revolution of the output will give 2353 counts of the encoder.
//pulses / 2353 = number of revs of output shaft in the time the pulses were recorded
//(pulses / 2353) * scale * 60 = RPM
float scale = 5.0; //Number of times per second the encoder pulses are read
float val = ((float)pulses / 2353.0) * scale * 60.0;
return val;
}
void measure()
{
Serial.println(rpm);
}
void motorInterrupt()
{
motorPulseCounter = motorPulseCounter + 1;
}
When I run this I get an output RPM of 0 so something's going wrong! Is it something with my code or is the Arduino micro unable to fire interrupts quickly enough to detect the pulses being sent by the encoder?