I am trying to get wheel encoder ticks using as5600 on my RC car. I have mounted the magnet on the gear of the gear box. Thing is I am running a ros node to get velocity from rpi so along with that I need to update my wheel ticks constantly along with the ros node receiving velocity commands without the sensor polling affecting my current node that i would be running. I was planning to use a incremental encoder and use ISR that way it would affect my ros node code, but i am confused how do i implement the same with the AS5600(the ISR thing, as this sensor is i2c, I would have to poll it again and again)
You could read the PWM output of the AS5600 with a Pin Change Interrupt. No polling is necessary.
So i wrote a code to trigger a timer interrupt every 160uS to poll the sensor, however I am unable to get an output on the terminal. Here's my code:
#include "AS5600.h"
#include "Wire.h"
AS5600 encoder;
long revolutions = 0; // number of revolutions the encoder has made
double pos = 0; // the calculated value the encoder is at
double output; // raw value from AS5600
long lastOutput; // last output from AS5600
ISR(TIMER1_COMPA_vect){
TCNT1 = 0;
output = encoder.getPosition(); // get the raw value of the encoder
if ((lastOutput - output) > 2047 ) // check if a full rotation has been made
revolutions++;
if ((lastOutput - output) < -2047 )
revolutions--;
pos = revolutions * 4096 + output; // calculate the position the the encoder is at based off of the number of revolutions
lastOutput = output;
}
void setup(){
Serial.begin(9600);
output = encoder.getPosition();
lastOutput = output;
pos = output;
cli(); //disable interrupts
TCCR1A = 0;
TCCR1B = 0;
TCCR1B |= B00000100;
TIMSK1 |= B00000010;
OCR1A = 160;
sei(); //enable interrupts
}
void loop(){
Serial.println(pos);
}
I have double checked baudrate in code and terminal. I ran the same interrupt code with LED blink and it ran, but when I ran it with the sensor code or have even tried adding the led code to this to see if the ISR even triggered, the led did not blink.
any ideas what could be wrong?
You seem to be treating the absolute encoder like an incremental encoder. I think you will need to calculate the motion at each sample and add that to an accumulator from which you can then calculate the number of revolutions.
Remember to account for the roll-over from 4095 to 0 on each turn of the shaft.
Something like this:
ISR(TIMER1_COMPA_vect)
{
static long TotalPosition = 0;
static int lastPosition = 0;
TCNT1 = 0;
int currentPosition = encoder.getPosition(); // get the raw value of the encoder
int delta = currentPosition - lastPosition;
lastPosition = currentPosition;
// Correct for overflow
if (delta > 2047)
delta -= 4096; // Turned back
else if (delta < -2047)
delta += 4096;
TotalPosition += delta;
if (TotalPosition < 0)
revolutions = (-TotalPosition) / 4096;
else
revolutions = TotalPosition / 4096;
pos = TotalPosition;
}
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.