Rotary Encoder and counter variable - Encoder.h library

Status
Not open for further replies.

JohnnyK

New member
I'm using a DDM-247 Rotary Encoder, which is connected to Pin 2 and 3 of Arduino Uno.
Values are display on a I2C-LCD.
https://www.buerklin.com/de/drehimpulsgeber/p/75e512

It works great with the Encoder.h library from Paul. Thank you for your work.
Every click in both directions is recognised.

Problem:
If i add a counter variable "count" the value of "count" shows a different reading from the variable "newPosition". The value starts the same, after a few clicks, it shows a number always lower than "newPosition". It seems that not every click is counted in "count". But "newPosition" seems to be always right.

What is the problem here?



Code:
/* Encoder Library - Basic Example
   http://www.pjrc.com/teensy/td_libs_Encoder.html
   This example code is in the public domain.

   Basic_RotaryEncoder_LCD_v0.1
   Arduino Uno
*/

#include <Encoder.h>

Encoder myEnc(2, 3);
long newPosition =0;
long oldPosition  = 0;
long count = 0;


// LCD Display
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);

void setup()
{
  //  Serial.begin(250000);
  //  Serial.println("Basic Encoder Test:");

  //LCD
  lcd.init();
  lcd.backlight();
  lcd.print(count);
}


void loop()
{
  readEnc();
  

}

void readEnc()
{
   newPosition = myEnc.read()/2; // divide by 2, because every rotary click doubles the value

  // ignore Values < 0
  if (newPosition < 0)
    myEnc.write(0);

  if (newPosition != oldPosition)
  { 
    count++;
    oldPosition = newPosition;
    lcdUpdate();

  }

}

void lcdUpdate()
{
  lcd.print("         ");
  lcd.setCursor(0, 0);  
  lcd.print(count);   
  lcd.print("ms   ");

  lcd.setCursor(0, 1);
  lcd.print("         ");
  lcd.setCursor(0, 1);  
  lcd.print(newPosition);   
  lcd.print("ms");

  
}
 
Two potential problems I can see.

First is that you only update count by one, though if code has been busy or encoder fast the actual number of steps may be more.

Other is that you only increase count, even if actual encoder position went backwards.

Suggest doing count=newPosition-oldPosition; and if the intent is actually to only count upwards regardless of rotation use the ABS function https://www.arduino.cc/reference/en/language/functions/math/abs/
 
Two potential problems I can see.

First is that you only update count by one, though if code has been busy or encoder fast the actual number of steps may be more.
Yes, that seems to be the problem.
Other is that you only increase count, even if actual encoder position went backwards.
Suggest doing count=newPosition-oldPosition; and if the intent is actually to only count upwards regardless of rotation use the ABS function https://www.arduino.cc/reference/en/language/functions/math/abs/

In my previous code i decreased the count. For problem solving i deleted it.

Now i'm using your suggestion: count= count + newPosition-oldPosition; which works for me.

Thank you for your help!
 
Hello guys,
I am playing with this code with an single encoder PEC11R-4220F-S0024 which is changing two diferent parameters at one and second switch and i was wondering how can i make it to keep the values of the parameters Par1 when i am in first mode (first push of encoder) buttonPushCounter ==0 and Par2 when i am in second mode (second push of encoder) buttonPushCounter==1 without modifing each other when the switch encoder is pushed again
Code:
#include <Encoder.h>

Encoder myEnc(3, 4);
//const int Button = 5;

unsigned int Par1;
unsigned int Par2;
int val2;
int val3;

const int  buttonPin = 5;    // the pin that the pushbutton is attached to
//const int ledPin = 13;       // the pin that the LED is attached to

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
bool buttonState = false;         // current state of the button
int lastButtonState = 0;     // previous state of the button

void setup() {

 pinMode(buttonPin, INPUT_PULLUP);
 
 Serial.begin(9600);
}

void loop() {
 // read the pushbutton input pin:
 buttonState = digitalRead(buttonPin);

 // compare the buttonState to its previous state
 if (buttonState != lastButtonState) {
   // if the state has changed, increment the counter
   if (buttonState == true) {
     // if the current state is HIGH then the button
     // wend from off to on:
     buttonPushCounter++;
     if(buttonPushCounter>1)
     buttonPushCounter=0;
   } 
 }
 
 // save the current state as the last state, 
 //for next time through the loop
 lastButtonState = buttonState;

////////// mode 0 - Par1 parameter and mode 1 - Par2 parameter ////////

 if (buttonPushCounter == 0) {
 
   val2 = myEnc.read(); //freqB of Wavetable **0 -> 2^32
   if(val2 <= 0) { // constrain for below 0
   myEnc.write(0); // constrain the encoder object
   }
   else if(val2 >= 1000){
   myEnc.write(1000); 
   }

   Par1 = constrain(val2,0,1000)*5.000;

 } else if (buttonPushCounter == 1) {

   val3 = myEnc.read(); //freqB of Wavetable **0 -> 2^32
   if(val3 <= 0) { // constrain for below 0
   myEnc.write(0); // constrain the encoder object
   }
   else if(val3 >= 1000){
   myEnc.write(1000); 
   }

   Par2 = constrain(val3,0,1000);
   
 }
 
 Serial.print("Status ");
  Serial.print(buttonPushCounter);
  Serial.print(" Enc ");
  Serial.print(val2);
  Serial.print(" Enc2: ");
  Serial.print(val3);
  Serial.print(" FrqA: ");
  Serial.print(Par1);
  Serial.print(" FrqB: ");
  Serial.println(Par2);
}

Also where can i change the library Encoder.h to have only one value at one detent move?

Thanks in advance!
 
As nearly as I can see, the answer to all your question is that *you* need to craft more code to solve your problems.

To keep 2 different parameters, you would need to add code to create 2 variables and manipulate your variables, rather than writing back to the Encoder object which stores only a single count.

To get 1 count per detent, *you* would need to add code which divides the quadrature count by some number (likely 4) to convert to the detent count. The Encoder library always counts the quadrature pulses. If you need a lesser count, it's simple math, just divide by the correct ratio.

Also, I would suggest you use the Bounce library rather than digitalRead to read the button.
 
Status
Not open for further replies.
Back
Top