Skip to content

devpscl/lcd-gui-library

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

39 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LCD-GUI-Library

A universal C-Library to create lcd menus on every platform. The access to any liquidcrysal display must be defined, e.g. HD44780.

Text-based LCDs with 5×8 pixels per cell are recommended. However, any type can be used, as the driver functions must be defined individually. This library can be used on almost all microcontrollers via C code and is 100% heap-free.

image

Get started

Full example for arduino

Global scope

Declaration of lcdgui instance. Multiple instances are possible

lcdgui_inst lcdgui;

A macro to create a constant string array ("On", "Off")

DEFINE_OPTION_LIST(on_off_options, "On", "Off");

The DEFINE_MENU_BUFFER creates a item buffer with a maximum of 2 items. Its required to initialize a menu screen.

DEFINE_MENU_BUFFER(menu_buffer, 2);
lcdsc_menu menu;

Declaration of a textitem with no action

lcdmenu_textitem item_message = MENU_TEXT_ITEM("Lcd Menu", NULL);

Declaration of a option item with no action

lcdmenu_optionitem item_request = lcdmenu_create_option_item("Fan", NULL, on_off_options, 2);

Caution

Menu items and screens should be declared in the global scope

Initialization

  lcddrv driver;
  //## define driver here ##
  lcdgui_init(&lcdgui, &driver);
  lcdmenu_init_screen(&lcdgui, &menu, menu_buffer);

  //Add items to menu
  lcdmenu_add_item(&menu, &item_message);
  lcdmenu_add_item(&menu, &item_request);

  lcdmenu_open(&lcdgui, &menu);

Send inputs

lcdgui_screen_dispatch_input(&lcdgui, INPUT_??);

INPUT_UP, INPUT_DOWN, INPUT_ENTER, INPUT_LEFT, INPUT_RIGHT

"INPUT_LEFT" and "INPUT_RIGHT" are unused.

Tip

Controlling by rotary encoder is recommend: CCW (UP) CW (DOWN) SW (ENTER)

Result

image

Define lcd driver

Example for arduino i2c lcd

  lcddrv driver;
  driver->context = NULL; //optional. The context pointer can be used to pass additional data to the driver functions
  driver->get_width = [](void*) -> uint8_t {
    return 20;
  };
  driver->get_height = [](void*) -> uint8_t {
    return 4;
  };
  driver->print = [](void* context, const char* arr) {
    //...
  };
  driver->clear = [](void* context) {
    //...
  };
  driver->set_cursor = [](void* context, uint8_t col, uint8_t row) {
    //...
  };
  driver->set_cursor_visible = [](void* context, uint8_t visible) {
    //...
  };
  driver->create_custom_char = [](void* context, uint8_t ph, const uint8_t* data) {
    //...
  };
  lcdgui_init(&lcdgui, &driver); //driver being copied

Menu Items

Name Description Action funtion pointer Default property
lcdmenu_textitem Only text with optional action void() 0
lcdmenu_optionitem Option chooser item: selection one of option list void(uint8_t) focusable
lcdmenu_counteritem count signed integer from min to max void(uint8_t) focusable

Properties

Name Function
MENU_ITEM_PROP_FOCUSABLE The item can be edited by trigger input ENTER. In edit (focus) mode, additional inputs can be received to the element.
MENU_ITEM_PROP_DISABLED Action inputs are disabled for this item.
MENU_ITEM_PROP_UNSELECTABLE This item is skipped when scrolling. Ideal for separator items or simple informational items.

Create custom menu item

typedef struct CustomMenuItem {
  lcdmenu_item base;
  uint8_t toggled;
} custom_menu_item;

//-> ON
//-> OFF
void custom_item_render(void* item, cstrbuilderp builder) {
  custom_menu_item* menu_item = (custom_menu_item*)item;
  if (menu_item->toggled) {
    cstrbuilder_append(builder, "ON");
  } else {
    cstrbuilder_append(builder, "OFF");
  }
}

void custom_item_input(void* item, uint8_t input) {
  if (input != INPUT_ENTER) {
    return;
  }
  custom_menu_item* menu_item = (custom_menu_item*)item;
  menu_item->toggled = !menu_item->toggled;
}

void create_custom_menu_item(custom_menu_item* item, uint8_t toggled) {
  item->base.render = custom_item_render;
  item->base.input = custom_item_input;
  item->toggled = toggled;
}

Create custom screen

typedef struct ErrorScreen {
  lcdsc base;
  uint8_t error_code;
} lcdsc_error;

void error_screen_render(lcdsc* screen, lcddrv* driver) {
  ErrorScreen* error_screen = (ErrorScreen*)screen;
  void* ctx = driver->context;
  driver->clear(ctx);
  driver->set_cursor(ctx, 0, 0);
  driver->print(ctx, "An error occurred");
  driver->set_cursor(ctx, 0, 1);

  char buf[13];
  cstrbuilder builder = cstrbuilder_init(buf, 12);
  cstrbuilder_append(&builder, "Error: ");
  cstrbuilder_append_int16(&builder, error_screen->error_code);

  driver->print(driver->context, buf);
}

void error_screen_input(lcdsc* screen, uint8_t input) {
  if (input == INPUT_ENTER) {
    lcdgui_screen_close(screen->instance);
  }
}

void init_error_screen(lcdgui_inst* instance, lcdsc_error* screen, uint8_t error_code) {
  screen->base.render = error_screen_render;
  screen->base.input = error_screen_input;
  screen->base.instance = instance;
  screen->error_code = error_code;
}

lcdsc_error screen;

void init() {
  init_error_screen(&lcdgui, &screen, 8);
  lcdgui_screen_open(&lcdgui, (lcdsc*)(&screen), NULL);
}

Dialog screen usage

lcdsc_dialog dialog;
DEFINE_OPTION_LIST(yes_no_options, "yes", "no");

void init_dialog() {
  lcddialog_init_screen(&lcdgui, &dialog, "Reset?", yes_no_options,
    2, [](uint8_t option) {
      if (option == 0) {
        //resetting...
      }
      lcdgui_screen_close(&lcdgui);
    });
  lcddialog_open_child(&lcdgui, &dialog);
}
image

About

A universal C-Library to create lcd menus on every platform

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages