I'm trying to get a code working for reading the feedback of a encoder and displaying it on the serial graph as RPM, I got it to work but it reads positive for both directions. Could someone help me with getting CCW to display as negative number on the graph?
Also just wanted to see if there any way to speed up the feedback plotting on the graph and a overall thought on improvement i could make.
I'm using a Mega 2560 with a Inland KS0013 Keystudio Rotary Encoder Module Inland Encoder
unsigned long start;
const byte encoderPinA = 2; //A pin -> interrupt pin 0
const byte encoderPinB = 24; //B pin -> digital pin 4
volatile long pulse;
volatile bool pinB, pinA, dir;
const byte ppr = 25, upDatesPerSec = 2;
const int fin = 1000 / upDatesPerSec;
const float konstant = 60.0 * upDatesPerSec / (ppr * 25);
int rpm;
void setup() {
Serial.begin(2000000);
attachInterrupt(0, readEncoder, CHANGE);
pinMode(encoderPinA, INPUT);
pinMode(encoderPinB, INPUT_PULLUP);
}
void loop() {
if (millis() - start > fin) {
start = millis();
rpm = pulse * konstant;
Serial.println(rpm);
pulse = 0;
}
}
void readEncoder() {
pinA = bitRead(PIND, encoderPinA);
pinB = bitRead(PIND, encoderPinB);
dir = pinA ^ pinB; // if pinA & pinB are the same
dir ? --pulse : ++pulse; // dir is CW, else CCW
}
Picture to see feedback and graph plotting. This was quick turns of the knob both directions a few times
To measure RPM you must count the number of pulses in some defined time period. Google "Arduino frequency counter".
Then RPM is (count / sample time [seconds]) / encoder counts/rev * 60.
Images of code are not worth much. In this case it may not matter much, but for a longer program you should post code properly. Read the forum guidelines to see how to properly post code and some good information on making a good post.
Use theIDE autoformat tool (ctrl-t or Tools, Auto format) before posting code in code tags.
Pulses from a rotating device need calculations. Either he time between pulses is measured or pulses are counted during a certain time and scaled to RPM.
So, that evaluates to read the 24th bit of port D. Does that make sense?
Why not just use digitalRead() there? Or use the digitalReadFast() function of the digitalWriteFast library. if you need speed.
Since the variable named pulse is multi-byte you should guard against interrupts while you read it. You do not want an interrupt to happen in the middle of reading the variable. It could be corrupted.
Like this:
void loop()
{
if (millis() - start > fin)
{
start = millis();
noInterrupts(); // stop interrupts
long copyOfPulse = pulse; // copy pulse
interrupts(); // restart interrupts
rpm = copyOfPulse * konstant; // work with copy of pulse
Serial.println(rpm);
pulse = 0;
}
}
Unfortunately I haven't been able to try your suggestions but I did get the actual encoder today that I need to use for this project. Main difference is that this is a 8 pin vs a 4 pin encoder. I'm not sure how I'd have to adapt the code for that.
Would I need to just add the extra 4 pins?