Rotary encoder with u8glib

Hi everyone,
I am using Arduino Mega + ramps 1.4 (shield) + RepRapDiscount controller( ST7920 128X64 );
Im trying to get the rotary encoder to work, ן uploaded the example file “Menu” from the u8glib library and changes the pins of the LCD to be correct, but the code it mean to be for buttons and not for rotary encoder
this is the code:

#include "U8glib.h"
U8GLIB_ST7920_128X64_1X u8g(23, 17, 16);  // SPI Com: SCK = en = 23, MOSI = rw = 17, CS = di = 16


#define KEY_NONE 0
#define KEY_PREV 1
#define KEY_NEXT 2
#define KEY_SELECT 3
#define KEY_BACK 4

uint8_t uiKeyPrev = 7;
uint8_t uiKeyNext = 3;
uint8_t uiKeySelect = 2;
uint8_t uiKeyBack = 8;

uint8_t uiKeyCodeFirst = KEY_NONE;
uint8_t uiKeyCodeSecond = KEY_NONE;
uint8_t uiKeyCode = KEY_NONE;


void uiSetup(void) {
  // configure input keys 
  
  pinMode(uiKeyPrev, INPUT_PULLUP);           // set pin to input with pullup
  pinMode(uiKeyNext, INPUT_PULLUP);           // set pin to input with pullup
  pinMode(uiKeySelect, INPUT_PULLUP);           // set pin to input with pullup
  pinMode(uiKeyBack, INPUT_PULLUP);           // set pin to input with pullup
}

void uiStep(void) {
  uiKeyCodeSecond = uiKeyCodeFirst;
  if ( digitalRead(uiKeyPrev) == LOW )
    uiKeyCodeFirst = KEY_PREV;
  else if ( digitalRead(uiKeyNext) == LOW )
    uiKeyCodeFirst = KEY_NEXT;
  else if ( digitalRead(uiKeySelect) == LOW )
    uiKeyCodeFirst = KEY_SELECT;
  else if ( digitalRead(uiKeyBack) == LOW )
    uiKeyCodeFirst = KEY_BACK;
  else 
    uiKeyCodeFirst = KEY_NONE;
  
  if ( uiKeyCodeSecond == uiKeyCodeFirst )
    uiKeyCode = uiKeyCodeFirst;
  else
    uiKeyCode = KEY_NONE;
}


#define MENU_ITEMS 4
const char *menu_strings[MENU_ITEMS] = { "First Line", "Second Item", "3333333", "abcdefg" };

uint8_t menu_current = 0;
uint8_t menu_redraw_required = 0;
uint8_t last_key_code = KEY_NONE;


void drawMenu(void) {
  uint8_t i, h;
  u8g_uint_t w, d;

  u8g.setFont(u8g_font_6x13);
  u8g.setFontRefHeightText();
  u8g.setFontPosTop();
  
  h = u8g.getFontAscent()-u8g.getFontDescent();
  w = u8g.getWidth();
  for( i = 0; i < MENU_ITEMS; i++ ) {
    d = (w-u8g.getStrWidth(menu_strings[i]))/2;
    u8g.setDefaultForegroundColor();
    if ( i == menu_current ) {
      u8g.drawBox(0, i*h+1, w, h);
      u8g.setDefaultBackgroundColor();
    }
    u8g.drawStr(d, i*h, menu_strings[i]);
  }
}

void updateMenu(void) {
  if ( uiKeyCode != KEY_NONE && last_key_code == uiKeyCode ) {
    return;
  }
  last_key_code = uiKeyCode;
  
  switch ( uiKeyCode ) {
    case KEY_NEXT:
      menu_current++;
      if ( menu_current >= MENU_ITEMS )
        menu_current = 0;
      menu_redraw_required = 1;
      break;
    case KEY_PREV:
      if ( menu_current == 0 )
        menu_current = MENU_ITEMS;
      menu_current--;
      menu_redraw_required = 1;
      break;
  }
}


void setup() {
  // rotate screen, if required
  // u8g.setRot180();
  uiSetup();                                // setup key detection and debounce algorithm
  menu_redraw_required = 1;     // force initial redraw
}

void loop() {  

  uiStep();                                     // check for key press
    
  if (  menu_redraw_required != 0 ) {
    u8g.firstPage();
    do  {
      drawMenu();
    } while( u8g.nextPage() );
    menu_redraw_required = 0;
  }
  updateMenu();                            // update menu bar
}

the script works fine except that the rotary doesnt move obviously.
i think that the pins of the encoder should be those:

#define BTN_EN1            31
#define BTN_EN2            33
#define BTN_ENC            35

Help, pls
thanks!

#define BTN_EN1 31
#define BTN_EN2 33
#define BTN_ENC 35

That is what I have for those pins and they work on my Mega with RepRapDiscount display.

ok,
but i meant that i should probably replace those lines :

#define KEY_NONE 0[color=#222222][/color]
#define KEY_PREV 1[color=#222222][/color]
#define KEY_NEXT 2[color=#222222][/color]
#define KEY_SELECT 3[color=#222222][/color]
#define KEY_BACK 4

with a different code using the pins BTN_EN1 , BTN_EN2 , BTN_EN3
i cant find on the internet how to do that
thanks

Where did you get that code? It looks like it was written for one of those LCD shields with the 4 o5 5 buttons, not a rotary encoder.

yes, that id exactly my point
i got the code from the library examples of the "U8Glib".
im using this one:

i want to modify that code for the rotary,
thanks!

Ok,
Does anybody knows what are the correct pinout for this LCD to use the LiquidCrystal library?
this is what i have got:

#include <LiquidCrystal.h>
//LiquidCrystal lcd(LCD_PINS_RS, LCD_PINS_ENABLE, LCD_PINS_D4, LCD_PINS_D5, LCD_PINS_D6, LCD_PINS_D7);
LiquidCrystal lcd(16, 23, 17, 25, 27, 29);

It doesnt work, the background light is on and thats it.
link:
https://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller

Thanks!

The LiquidCrystal library will not work with that display.

Ok thanks!
I managed to play with some code i wrote / got inspired from libraries and internet. i want to make a menu of 3 case [A,B,C] and use the encoder to scroll between those 3 titles.
so i used 3 pins to read the encoder (right,left,push) the code for encoder from u8glib to count to rotates of the encoder.
but, i works not good. i can rotate the encoder and nothing happens, the scrolling jumps between cases and it works sometimes really slowly
here is the code:

#include <SPI.h>
#include <U8glib.h>
#include <SD.h>

// SPI Com: SCK = en = 23, MOSI = rw = 17, CS = di = 16
U8GLIB_ST7920_128X64_1X u8g(23, 17, 16);

#define BTN_EN1         31              // Left Rotation
#define BTN_EN2         33              // Right Rotation
#define BTN_ENC         35              // Pressing Encoder In.


int LastscrollRight = 0; 
int LastscrollLeft = 0; 
int caseNum = 1; 
boolean LastpushButton = false; 
int scrollRight = 0;
int scrollLeft = 0;
int pushButton = 0;
int encoderPos = 1;                     //Current encoder position
int encoder0PinALast;                   //Used to decode rotory encoder, last value
int encoder0PinNow;                     //Used to decode rotory encoder, current value
char posStr[4];                         //Char array to store encoderPos as a string  
char tmp_string[16];


void setup() {
  pinMode(BTN_EN1, INPUT);              // Set BTN_EN1 as an unput, half of the encoder
  digitalWrite(BTN_EN1, HIGH);          // turn on pullup resistors
  pinMode(BTN_EN2, INPUT);              // Set BTN_EN2 as an unput, second half of the encoder
  digitalWrite(BTN_EN2, HIGH);          // turn on pullup resistors
  pinMode(BTN_ENC, INPUT);              // Set BTN_ENC as an unput, encoder button
  digitalWrite(BTN_ENC, HIGH);          // turn on pullup resistors
  u8g.setFont(u8g_font_helvR08);        //Set the font for the display
  u8g.setColorIndex(1);                 // Instructs the display to draw with a pixel on. 
}

void loop() {
 Serial.begin(9600);
 scrollRight = digitalRead(BTN_EN2);
 scrollLeft = digitalRead(BTN_EN1);
 pushButton = digitalRead(BTN_ENC);


//   Read the encoder and update encoderPos    
  encoder0PinNow = digitalRead(BTN_EN2);  // Current Digital read of scrollRight
  if ((encoder0PinALast == HIGH) && (encoder0PinNow == LOW)) {
    if (digitalRead(BTN_EN2) == LOW) {
      encoderPos++;
    } else {
      encoderPos--;
    }
    if (encoderPos > 3 or encoderPos < 0){
      encoderPos = 1; 
    }
  }
  encoder0PinALast = encoder0PinNow;

  Serial.println("RIGHT");
  Serial.println(scrollRight);
  Serial.println("LEFT");
  Serial.println(scrollLeft);


  u8g.firstPage();
  do{
    MainMenu();
  }while(u8g.nextPage());
}

void MainMenu(){
switch(encoderPos)
{

  case 1:
           u8g.setFont(u8g_font_6x13); 
           u8g.setPrintPos(15,15);
           u8g.print("> A");
           u8g.setPrintPos(15,25);
           u8g.print("  B");
           u8g.setPrintPos(15,35);
           u8g.print("  C");  
           break;
  case 2:     
           u8g.setFont(u8g_font_6x13); 
           u8g.setPrintPos(15,15);
           u8g.print("  A");
           u8g.setPrintPos(15,25);
           u8g.print("> B");
           u8g.setPrintPos(15,35);
           u8g.print("  C");  
           break;
           break;
  case 3:
           u8g.setFont(u8g_font_6x13); 
           u8g.setPrintPos(15,15);
           u8g.print("  A");
           u8g.setPrintPos(15,25);
           u8g.print("  B");
           u8g.setPrintPos(15,35);
           u8g.print("> C");  
           break;   
}
}

what am i doing wrong?
thanks!

The only input you're looking at in the encoder section is BTN_EN2. If BTN_EN2 is your clock signal then BTN_EN1 is the data signal. Substitute

    if (digitalRead(BTN_EN1) == LOW) {
      encoderPos++;
    } else {
      encoderPos--;
    }

thanks you!!

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