Encoder RPM Feedback

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

How many counts per revolution is the encoder?

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 the IDE autoformat tool (ctrl-t or Tools, Auto format) before posting code in code tags.

Please go back and fix your original post

Project guidance is perfect for questions like this.

Please read and follow this link: How to get the best out of this forum - Using Arduino / Project Guidance - Arduino Forum

Then post the code accordingly.

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.

Is this better?
Sorry i didnt know there was a format and everything for posting

Why aren't both set to INPUT_PULLUP?

i changed them but to INPUT_PULLUP but still wont read negative

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?

Post a data sheet, some documentation or a link to where you bought the encoder so that we can know exactly what you have, please.

Sorry, got tied up before i could add the data sheet to the post,

http://gesgroup.xist4c.de/upload_gesgroup/IH740_198.pdf

i found this post but im not sure if i have to have RS422 Shields or can it be done with just the Mega 2650

https://www.instructables.com/How-to-Use-Industrial-Encoders-With-Arduino/

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.