How to scroll down/up a menu on a ST7920 128x64 LCD display ?

Hi,

I'm working on developing a menu and I reached the part where I want to scroll down/up the menu but I don't know how.

This is the code I'm working on:

#include <U8g2lib.h>
// constants ////////////////////////////////////////////////
// # lists settings

#define   LIST_COUNT            8
#define   LIST_PER_FRAME        5

#define   LIST_Y_START_POINT    1
#define   LIST_X_START_POINT    2
#define   LIST_Y(_Y)            (LIST_Y_START_POINT+(12*_Y))

// # selection settings
#define   SELECT_WIDTH          65
#define   SELECT_HEIGHT         11
#define   SELECT_X_START_POINT  0
#define   SELECT_Y_START_POINT  0
#define   SELECT_Y(_Y)          (SELECT_Y_START_POINT+(12*_Y))

// variables ////////////////////////////////////////////////
uint8_t select_ptr = 0;
//uint8_t list_y = LIST_Y(0);

struct example_list{
  uint8_t y_position;
  const char* list_name;
};

example_list list1[] = {
  {LIST_Y(0), "SETTING 1"},
  {LIST_Y(1), "SETTING 2"},
  {LIST_Y(2), "SETTING 3"},
  {LIST_Y(3), "SETTING 4"},  
  {LIST_Y(4), "SETTING 5"},
  {LIST_Y(5), "SETTING 6"},
  {LIST_Y(6), "SETTING 7"},
  {LIST_Y(7), "SETTING 8"}, 
};

U8G2_ST7920_128X64_1_HW_SPI u8g2(U8G2_R0, /* CS=*/ 10, /* reset=*/ 8);

void u8g2_prepare(void) {
  u8g2.setFont(u8g2_font_6x10_tf);
  u8g2.setFontRefHeightExtendedText();
  u8g2.setDrawColor(1);
  u8g2.setFontPosTop();
  u8g2.setFontDirection(0);
}

void glcd_initialize(void) {
  u8g2.begin(); 
  u8g2_prepare();
}

void glcd_print_list(void){

  u8g2.firstPage();
  do {

    // draw list
    u8g2.setDrawColor(1);
    for(int i = 0; i < LIST_COUNT; i++){
      u8g2.drawStr(LIST_X_START_POINT, list1[i].y_position, list1[i].list_name);
    }

    // selected list
    u8g2.setDrawColor(1);
    u8g2.drawBox(SELECT_X_START_POINT, SELECT_Y(select_ptr), SELECT_WIDTH, SELECT_HEIGHT);
    u8g2.setDrawColor(0);
    u8g2.drawStr(LIST_X_START_POINT, list1[select_ptr].y_position, list1[select_ptr].list_name);

    if(select_ptr > 5){
      // u8g2.drawRFrame(u8g2,,,,); // <---------- I'm here
    }
    
  } while (u8g2.nextPage());   
}

As select_ptr will be modified by push button read function.

The u8g2 library has a graphics example with scrolling text.

Which example ?

I found this:

Introduction to U8log

U8log is an extension to U8g2 and U8x8. It implements a text window with automatic vertical scrolling. Text is written to the current cursor position within the text window.

at:

https://github.com/olikraus/u8g2/wiki/u8logreference#introduction-to-u8log

But how to find it ? I couldn't find it in the library folder.

OK found it in u8g2-master and not in u8glib-master.

OK, I ran the example but it's horizontal scroll. I want a vertical scroll.

Scroll fluidly, pixel by pixel?

Or swapping boxes? Like there's A, B, C. D in a column; you turn your knob and then they're B. C, D, E.
That would be, I think, a lot easier.
Or, similarly, you could have A, B, C, D and turning a knob changes which box is "active", with a border (highlight / outline).

1 Like

Yep, after a lot of trail/error I did it this way:

#include <U8g2lib.h>

// constants ////////////////////////////////////////////////
// # lists settings
#define   LIST_COUNT            8
#define   LIST_PER_FRAME        5

#define   LIST_Y_START_POINT    1
#define   LIST_X_START_POINT    2
#define   LIST_Y(_Y)            (LIST_Y_START_POINT+(12*_Y))

// # selection box settings
#define   SELECT_WIDTH          65
#define   SELECT_HEIGHT         11
#define   SELECT_X_START_POINT  0
#define   SELECT_Y_START_POINT  0
#define   SELECT_Y(_Y)          (SELECT_Y_START_POINT+(12*_Y))

// variables ////////////////////////////////////////////////
int8_t select_ptr = 0;
int8_t name_ptr = 0;
int8_t list_ptr = 0;
bool list_limi_lock = 0;
bool glcd_update = 0; // on button event, sensor read event ... etc.
//uint8_t list_y = LIST_Y(0);

struct example_list{
  const char* list_name;
};

example_list list1[] = {
"SETTING 1", "SETTING 2", "SETTING 3", "SETTING 4", "SETTING 5", "SETTING 6", "SETTING 7", "SETTING 8"
};

U8G2_ST7920_128X64_1_HW_SPI u8g2(U8G2_R0, /* CS=*/ 10, /* reset=*/ 8);

void u8g2_prepare(void) {
  u8g2.setFont(u8g2_font_6x10_tf);
  u8g2.setFontRefHeightExtendedText();
  u8g2.setDrawColor(1);
  u8g2.setFontPosTop();
  u8g2.setFontDirection(0);
}

void glcd_initialize(void) {
  u8g2.begin(); 
  u8g2_prepare();
}

void glcd_print_list(void){

  if(!button_lock && !glcd_update){
    u8g2.firstPage();
    do {

      u8g2.clearBuffer();
  
      // draw full list
      u8g2.setDrawColor(1);
      for(int i = 0, j = list_ptr; i < LIST_PER_FRAME; j++, i++){
        u8g2.drawStr(LIST_X_START_POINT, LIST_Y(i), list1[j].list_name);
      }
  
      // draw selected list with selection box
      u8g2.setDrawColor(1);
      u8g2.drawBox(SELECT_X_START_POINT, SELECT_Y(select_ptr), SELECT_WIDTH, SELECT_HEIGHT);
      u8g2.setDrawColor(0);
      u8g2.drawStr(LIST_X_START_POINT, LIST_Y(select_ptr), list1[name_ptr].list_name);

      glcd_update = 1;
    } while (u8g2.nextPage());  
  } 
}

void glcd_update_button_control(void){
    if (lcd_button_index && button_execution == true) {

      switch(lcd_button_index){
        case BUTTON_UP:
          select_ptr--;
          name_ptr--;
          if(select_ptr < 0){ select_ptr = 0; list_ptr--; }
          if(name_ptr < 1){ name_ptr = 0;}
          if(list_ptr < 1){ list_ptr = 0;}
        break;

        case BUTTON_DOWN:
          select_ptr++;
          name_ptr++;
          if(select_ptr > 4){ select_ptr = 4; list_ptr++; }
          if(name_ptr > LIST_COUNT - 1){ name_ptr = LIST_COUNT - 1; }
          if(list_ptr > LIST_COUNT - LIST_PER_FRAME){ list_ptr = LIST_COUNT - LIST_PER_FRAME;}
          
        break;
        
        case BUTTON_SET:

        break;

        case BUTTON_BACK:

        break;
        
      }
      lcd_button_index = NOT_SELECTED;
      button_execution = false;
      glcd_update = 0;
    }
}

const char *convert_number(uint16_t number) {
  static char buf[3];
  strcpy(buf, u8g2_u8toa(number, 2));
  return buf;
}

const char *print_logic_state(bool number) {
  static char buf[3];
  strcpy(buf, u8g2_u8toa(number, 1));
  return buf;
}

const char *print_motor_speed(uint16_t number) {
  static char buf[3];
  strcpy(buf, u8g2_u8toa(number, 3));
  return buf;
}

I hope anyone find this helpful.

demo it on vimeo or youtube

1 Like

Yep, I'm really planning to, just need some more time to finish my current projects.

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