M2tklib Rotary Encoder Example (problem)

Dear Community,

I am working on a project which needs a menu style of interface where I can vary 2 values. I found the rotary encoder example of the M2tklib. Initially, the sketch displays 2 digit values on a range from 0 to 99. I need values at a range from 0 to 999. I found a way to plot 3 digits. However the variables which store the values when changed with the rotary encoder do not reach 999. Specifically, it can go from 0 to 255. The data type of the variables are "uint8_t". I believe that is the reason which does not let me to plot values greater than 255. Changing the data type of the variables gives me errors that I do not know how to solve. Any input is welcomed. I am providing below the code which plots 3 digits.

#include "U8glib.h"
#include "M2tk.h"
#include "utility/m2ghu8g.h"

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE);
// Forward declaration of the toplevel element

// Simple dialog: Input two values n1 and n2

uint8_t n1 = 0;
uint8_t n2 = 0;

M2_LABEL(el_l1, NULL, "value 1:");
M2_U8NUM(el_u1, "c3", 0, 255, &n1);
M2_LABEL(el_l2, NULL, "value 2:");
M2_U8NUM(el_u2, "c3", 0, 255, &n2);

M2_LIST(list) = { &el_l1, &el_u1, &el_l2, &el_u2 };
M2_GRIDLIST(el_gridlist, "c2", list);
M2_ALIGN(top_menu, "-1|1W64H64", &el_gridlist);

// m2 object and constructor
// Note: Use the "m2_eh_4bd" handler, which fits better to the "m2_es_arduino_rotary_encoder" 
M2tk m2(&top_menu, m2_es_arduino_rotary_encoder, m2_eh_4bd, m2_gh_u8g_bf);

// Arduino Setup & Loop

void setup(void) {
// Connect u8glib with m2tklib
  m2_SetU8g(u8g.getU8g(), m2_u8g_box_icon);

// Assign u8g font to index 0
  m2.setFont(0, u8g_font_7x13r);

// define button for the select message
  m2.setPin(M2_KEY_SELECT, 7);          // dogm128 shield, 2nd from top
// The incremental rotary encoder is conected to these two pins
  m2.setPin(M2_KEY_ROT_ENC_A, 3);
  m2.setPin(M2_KEY_ROT_ENC_B, 2);

void loop() {
  // check rotary encoder also inside the picture loop
  // process events and redraw menu if required
  if ( m2.handleKey() != 0 ) {
    do {
      // check rotary encoder also inside the picture loop
      // draw menu
    } while( u8g.nextPage() );

What was changed to the initial code to plot 3 digits from 2 digits was the below code

M2_LABEL(el_l1, NULL, "value 1:");
M2_U8NUM(el_u1, "c2", 0, 99, &n1);
M2_LABEL(el_l2, NULL, "value 2:");
M2_U8NUM(el_u2, "c2", 0, 99, &n2);

Trying to change n1, n2 from "uint8_t" to "int" which I though that it would solve my problem gives me the following error;

error: cannot convert 'int*' to 'uint8_t* {aka unsigned char*}' in initialization
#define M2_U8NUM(el,fmt,min,max,variable) m2_el_u8_ptr_t el M2_SECTION_PROGMEM = { { { m2_el_u8num_fn, (fmt) }, (min), (max) }, (variable) }

exit status 1
Error compiling for board Arduino Uno.

Thank you,


It appears that the library only supports having 8 bit variables that can be associated with the menu. This means you will have to come up with a different strategy.

A kludge would be to have a second variable that represents 100s and keep your original variable that represents 0-99 and then you would have to combine them whenever you wanted to use the actual value.

Hi blh64,

Thank you for the heads up. Do you think that modding the entire library and substituting every "uint8_t" entry with "uint16_t" is going to do the trick?

Otherwise, how would you go and do the kludge you are talking about? I am saying this because if the library is designed to spit out 8-bit integers how is it going to plot 16-bit int's for instance?



Turns out the library supports uint32_t variables.

Thus what is needed to change is;

uint8_t n1 = 0;
uint8_t n2 = 0;

M2_U8NUM(el_u1, "c3", 0, 255, &n1);
M2_U8NUM(el_u2, "c3", 0, 255, &n2);


uint32_t n1 = 0;
uint32_t n2 = 0;

M2_U32NUM(el_u1, "c3", &n1);
M2_U32NUM(el_u2, "c3", &n2);


the M2_U32NUM takes 3 arguments instead of 5. Also, the end result changes each digit individually