Rotary encoder jumps 'in between'

Dear all

First post here and completely new to Arduino and electronics in general :confused:
I started making a polargraph / V-plotter.
Bought stepper motors, Arduino Mega 2560, Ramps 1.4, etc... and an LCD.
The LCD is from RepRapDiscount: full graphic smart controller.

After a long search and a big puzzle using Makelangelo software, I got it more or less under control.
Except the rotary encoder on the LCD-panel...
I can only change lines in the menu if I really really really am soft on the knob.
It reacts somewhere in between the 'click'.

Did a lot of research on internet, but couldn't find a solution.
Some rotary libraries I found don't work with the Mega.

Do I have to change anything in this part firmware of Makelangelo?
I played a lot (without really knowing what I was doing) with "ENCROT" changing ++ and -- into +20 or -10 and so on. It looked like having some effect, but not good enough and random...

Thx in advance!

int buttons=0;
unsigned long next_lcd_read=0;
const char *update_key;
void *update_val;


void LCD_read() {
  long now = millis(); 
  
  if(ELAPSED(now,next_lcd_read)) {
    // detect potentiometer changes
    buttons = ((digitalRead(BTN_EN1) == HIGH) << BLEN_A) 
            | ((digitalRead(BTN_EN2) == LOW) << BLEN_B); //was HIGH
    next_lcd_read=now+30; 
  }
  
  // potentiometer uses grey code.  Pattern is 0 3 1 2
  if (lcd_rot_old != buttons) {
    switch (buttons) {
      case ENCROT0:  switch( lcd_rot_old ) { case ENCROT3: lcd_turn++; break; case ENCROT1: lcd_turn--; break; } break;
      case ENCROT1:  switch( lcd_rot_old ) { case ENCROT0: lcd_turn++; break; case ENCROT2: lcd_turn--; break; } break;
      case ENCROT2:  switch( lcd_rot_old ) { case ENCROT1: lcd_turn++; break; case ENCROT3: lcd_turn--; break; } break;
      case ENCROT3:  switch( lcd_rot_old ) { case ENCROT2: lcd_turn++; break; case ENCROT0: lcd_turn--; break; } break;
    }
    // for debugging potentiometer
    {
      //if(lcd_turn !=0) Serial.print(lcd_turn>0?'+':'-');
      //else Serial.print(' ');
      //Serial.print(millis());     Serial.print('\t');
      //Serial.print(lcd_rot_old);  Serial.print('\t');
      //Serial.print(buttons);      Serial.print('\t');
      //Serial.print(lcd_turn);     Serial.print('\n');
    }
    
    lcd_rot_old = buttons;
  }

  // find click state
  int btn = digitalRead(BTN_ENC);
  if ( btn != lcd_click_old && btn == HIGH ) { 
    // when button is released
    lcd_click_now = true;
  }
  lcd_click_old = btn;
}

On a 3D printer with Marlin firmware it typically requires four encoder steps before taking one step in the menu. Perhaps you can implement something like that.

You're reading the encoder every 30 ms, that's way too slow.

Why are you using void pointers?

Pieter

johnwasser:
On a 3D printer with Marlin firmware it typically requires four encoder steps before taking one step in the menu. Perhaps you can implement something like that.

I think something like that is needed, but how is a big question for me...

PieterP:
You're reading the encoder every 30 ms, that's way too slow.

Why are you using void pointers?

Pieter

I changed that 30 into 1 or even into 1000. No change in anything usefull for me.

I don't use anything :slight_smile: the code is from Makelangelo firmware. The part I posted is what I think responds in tuning the encoder.
Could be wrong!