Reading Encoder- Trending Error

Hello all,

I am reading an encoder attached to a machine oscillating as a damped pendulum. The graph for the angle over time should reflect something oscillating perfectly and dying over time, but I believe that the way I am reading the encoder may be generating an error in the graph which looks like the image attached. You can see that it has a strange trend, and I am not sure if it is because of my encoder reading delay? If anyone could provide ideas to mitigate this issue, I would truly appreciate it. Below is my code:

#include <digitalWriteFast.h>

const int PinA = 2;

const int PinB = 3;

// Keep track of last rotary value
int lastCount = 0;

volatile float virtualPosition = 0;

unsigned long time;

void isr () {
static unsigned long lastInterruptTime = 0;
unsigned long interruptTime = millis();

// Get rid of bounce
if (interruptTime - lastInterruptTime > 0.1) {
if (digitalReadFast(PinB) == LOW)
{
virtualPosition=virtualPosition- 0.35 ;
}
else {
virtualPosition=virtualPosition+ 0.35 ;
}

// Restrict values
virtualPosition = min(360, max(-360, virtualPosition));

lastInterruptTime = interruptTime;
}
}

void setup() {

Serial.begin(9600);

pinMode(PinA, INPUT);
pinMode(PinB, INPUT);

// Attach the routine to service the interrupts
attachInterrupt(digitalPinToInterrupt(PinA), isr, LOW);

}

void loop() {

time = millis();
Serial.print("");
Serial.print(time);
Serial.print(",");
Serial.print(virtualPosition);
Serial.println("");

lastCount = virtualPosition ;

}

I am sure you know "trend" can be between -1 and +1, so A strange trend is not possible. Are you looking at the superimposed reduced peaked values of your graph? With no time values on your graph, it's a bit hard to know if it is noise being picked up on your encoder reading or what. A schematic of what you have, including any bypass capacitors would help a lot. What do you have powering the project? What actual frequency is your project operating at?

How much time used in reversing direction?

Paul

Hi Paul,

Thanks for repying! The time on the graph I attached is in milliseconds, so the total time here is about 8 seconds (sorry for not labeling anything, it was just test data). The frequency will be changing depending on a couple of masses we will impose, but this will be the slowest it will oscillate. The other frequencies will only be marginally slower, though.

As for the setup, the only connections I have are the encoder A and B outputs directly pinned to the arduino, along with the ground and 5V power directly to the arduino as well. It is powered by my laptop which is also collecting the data. I tried to avoid capacitors by reducing bounce through the code.

Obviously I am new to using arduinos if that is not obvious haha. Just an ME trying to figure out this world.

looking at your code, I see you are reading "virtualPosition" without disabling interrupts before reading and enabling afterward. The interrupt code may or may not be changing the value while you are printing it or saving it.

And, if you are going to show it on the serial monitor, show the saved value, then you only need to do the disable/enable one time in -loop-.

Paul