#include <U8g2lib.h>
// Initialize your display here
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0);
// 'main_menu_1', 128x64px
const unsigned char main_menu_1_bits [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x10, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00,
0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x88,
0x04, 0x0f, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x82, 0x1f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x42, 0x20, 0xe4, 0xe1, 0xf8, 0x7c, 0x3e, 0x8f, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x42, 0x2f, 0x24, 0x12, 0x21, 0x10, 0x02, 0x91, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x42, 0x20, 0x24, 0x12, 0x21, 0x10, 0x02, 0x91, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x42, 0x2f, 0x24, 0x12, 0x21, 0x10, 0x02, 0x11, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x42, 0x20, 0xe4, 0x11, 0x21, 0x10, 0x0e, 0x0f, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x42, 0x2f, 0x24, 0xf2, 0x21, 0x10, 0x02, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x42, 0x20, 0x24, 0x12, 0x21, 0x10, 0x02, 0x09, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x42, 0x2f, 0x24, 0x12, 0x21, 0x10, 0x02, 0x11, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x42, 0x20, 0xe4, 0x11, 0x21, 0x10, 0x3e, 0x11, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x84, 0x1f, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x88,
0x10, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x88,
0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x10, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x88,
0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x88,
0x04, 0x0f, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x82, 0x10, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x42, 0x20, 0x24, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x42, 0x20, 0x24, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x42, 0x20, 0x24, 0x22, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x82, 0x10, 0x24, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x02, 0x0f, 0x24, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x02, 0x00, 0x24, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x02, 0x0f, 0x24, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0xc2, 0x3f, 0x24, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0xe2, 0x7f, 0x24, 0x1e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0xe4, 0x7f, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x88,
0x10, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x88,
0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x10, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x88,
0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x88,
0x04, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x02, 0xef, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x82, 0x50, 0xc4, 0xf1, 0x78, 0xc0, 0xe7, 0x21, 0x3e, 0x91, 0x87, 0x03, 0x00, 0x00, 0x00, 0x89,
0x42, 0x20, 0x24, 0x12, 0x89, 0x40, 0x20, 0x22, 0x02, 0x91, 0x48, 0x04, 0x00, 0x00, 0x00, 0x89,
0x42, 0x20, 0x24, 0x12, 0x89, 0x40, 0x20, 0x22, 0x02, 0x91, 0x48, 0x00, 0x00, 0x00, 0x00, 0x89,
0x42, 0x20, 0x24, 0x12, 0x89, 0x40, 0x20, 0x22, 0x02, 0x93, 0x48, 0x00, 0x00, 0x00, 0x00, 0x89,
0x82, 0x10, 0x24, 0x12, 0x89, 0xc0, 0xe1, 0x21, 0x0e, 0x95, 0x88, 0x03, 0x00, 0x00, 0x00, 0x89,
0x02, 0x0f, 0xe4, 0x13, 0x89, 0x40, 0xa0, 0x20, 0x02, 0x99, 0x08, 0x04, 0x00, 0x00, 0x00, 0x89,
0x02, 0x00, 0x24, 0x12, 0x89, 0x40, 0x20, 0x21, 0x02, 0x91, 0x08, 0x04, 0x00, 0x00, 0x00, 0x89,
0x02, 0x0f, 0x24, 0x12, 0x89, 0x40, 0x20, 0x22, 0x02, 0x91, 0x48, 0x04, 0x00, 0x00, 0x00, 0x89,
0xc2, 0x3f, 0x24, 0xf2, 0x78, 0x40, 0x20, 0x22, 0x3e, 0x91, 0x87, 0x03, 0x00, 0x00, 0x00, 0x89,
0xe4, 0x7f, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x88,
0x10, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00,
0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20
};
const unsigned char main_menu_2_bits [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x10, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00,
0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x88,
0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x02, 0xef, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x82, 0x10, 0xe4, 0xf1, 0x09, 0xe2, 0x88, 0x7c, 0xe0, 0xf3, 0x10, 0x9f, 0xc8, 0xc3, 0x01, 0x89,
0x42, 0x20, 0x24, 0x12, 0x08, 0x12, 0x89, 0x04, 0x20, 0x10, 0x11, 0x81, 0x48, 0x24, 0x02, 0x89,
0x42, 0x20, 0x24, 0x12, 0x18, 0x13, 0x89, 0x04, 0x20, 0x10, 0x11, 0x81, 0x48, 0x24, 0x00, 0x89,
0x42, 0x20, 0x24, 0x12, 0xa8, 0x12, 0x89, 0x04, 0x20, 0x10, 0x11, 0x81, 0x49, 0x24, 0x00, 0x89,
0x82, 0x10, 0xe4, 0x71, 0x48, 0x12, 0x89, 0x1c, 0xe0, 0xf0, 0x10, 0x87, 0x4a, 0xc4, 0x01, 0x89,
0x02, 0x0f, 0xa4, 0x10, 0x08, 0x12, 0x89, 0x04, 0x20, 0x50, 0x10, 0x81, 0x4c, 0x04, 0x02, 0x89,
0x02, 0x00, 0x24, 0x11, 0x08, 0x12, 0x89, 0x04, 0x20, 0x90, 0x10, 0x81, 0x48, 0x04, 0x02, 0x89,
0x02, 0x0f, 0x24, 0x12, 0x08, 0x12, 0x51, 0x04, 0x20, 0x10, 0x11, 0x81, 0x48, 0x24, 0x02, 0x89,
0xc2, 0x3f, 0x24, 0xf2, 0x09, 0xe2, 0x20, 0x7c, 0x20, 0x10, 0x11, 0x9f, 0xc8, 0xc3, 0x01, 0x89,
0xe4, 0x7f, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x88,
0x10, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x88,
0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x10, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x88,
0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x88,
0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0xc2, 0x39, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x22, 0x46, 0xe4, 0xf3, 0x10, 0x9f, 0xc8, 0x03, 0x1e, 0x1f, 0x47, 0xe4, 0xe3, 0xf8, 0x38, 0x89,
0x12, 0x80, 0x24, 0x10, 0x11, 0x81, 0x48, 0x04, 0x22, 0x81, 0x48, 0x24, 0x10, 0x21, 0x44, 0x89,
0x12, 0x80, 0x24, 0x10, 0x11, 0x81, 0x48, 0x04, 0x22, 0x81, 0x48, 0x24, 0x10, 0x20, 0x04, 0x89,
0x12, 0x80, 0x24, 0x10, 0x11, 0x81, 0x49, 0x04, 0x22, 0x81, 0x48, 0x24, 0x10, 0x20, 0x04, 0x89,
0x12, 0x80, 0xe4, 0xf0, 0x10, 0x87, 0x4a, 0x04, 0x1e, 0x87, 0x48, 0xe4, 0xe0, 0x20, 0x38, 0x89,
0x22, 0x40, 0x24, 0x50, 0x10, 0x81, 0x4c, 0x04, 0x0a, 0x81, 0x48, 0x24, 0x00, 0x21, 0x40, 0x89,
0x42, 0x20, 0x24, 0x90, 0x10, 0x81, 0x48, 0x04, 0x12, 0x81, 0x4a, 0x24, 0x00, 0x21, 0x40, 0x89,
0x82, 0x10, 0x24, 0x10, 0x11, 0x81, 0x48, 0x04, 0x22, 0x81, 0x44, 0x24, 0x10, 0x21, 0x44, 0x89,
0x02, 0x09, 0x24, 0x10, 0x11, 0x9f, 0xc8, 0x03, 0x22, 0x1f, 0x8b, 0xe3, 0xe3, 0x20, 0x38, 0x89,
0x04, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x88,
0x10, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x88,
0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x10, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x88,
0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x88,
0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0xe2, 0x7f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x12, 0x80, 0xe4, 0xf3, 0x10, 0x9f, 0xc8, 0xc3, 0x01, 0x8e, 0x88, 0xe3, 0x03, 0x00, 0x00, 0x89,
0x12, 0x80, 0x24, 0x10, 0x11, 0x81, 0x48, 0x24, 0x02, 0x91, 0x48, 0x84, 0x00, 0x00, 0x00, 0x89,
0x12, 0x80, 0x24, 0x10, 0x11, 0x81, 0x48, 0x24, 0x00, 0x81, 0x48, 0x84, 0x00, 0x00, 0x00, 0x89,
0x12, 0x80, 0x24, 0x10, 0x11, 0x81, 0x49, 0x24, 0x00, 0x81, 0x48, 0x84, 0x00, 0x00, 0x00, 0x89,
0x12, 0x80, 0xe4, 0xf0, 0x10, 0x87, 0x4a, 0xc4, 0x01, 0x81, 0x4f, 0x84, 0x00, 0x00, 0x00, 0x89,
0x12, 0x80, 0x24, 0x50, 0x10, 0x81, 0x4c, 0x04, 0x02, 0x81, 0xc8, 0x87, 0x00, 0x00, 0x00, 0x89,
0xe2, 0x71, 0x24, 0x90, 0x10, 0x81, 0x48, 0x04, 0x02, 0x81, 0x48, 0x84, 0x00, 0x00, 0x00, 0x89,
0x02, 0x12, 0x24, 0x10, 0x11, 0x81, 0x48, 0x24, 0x02, 0x91, 0x48, 0x84, 0x00, 0x00, 0x00, 0x89,
0x02, 0x14, 0x24, 0x10, 0x11, 0x9f, 0xc8, 0xc3, 0x01, 0x8e, 0x48, 0x84, 0x00, 0x00, 0x00, 0x89,
0x04, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x88,
0x10, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00,
0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20
};
const unsigned char main_menu_3_bits [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x10, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00,
0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x88,
0x04, 0x0f, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0xc2, 0x30, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x22, 0x7c, 0xe4, 0x11, 0x79, 0x04, 0x84, 0x03, 0x1c, 0x11, 0xc7, 0x07, 0x00, 0x00, 0x00, 0x89,
0x22, 0x7f, 0x24, 0x12, 0x89, 0x04, 0x44, 0x04, 0x22, 0x91, 0x08, 0x01, 0x00, 0x00, 0x00, 0x89,
0x12, 0xf8, 0x24, 0x12, 0x89, 0x04, 0x44, 0x00, 0x02, 0x91, 0x08, 0x01, 0x00, 0x00, 0x00, 0x89,
0x12, 0xe2, 0x24, 0x12, 0x89, 0x04, 0x44, 0x00, 0x02, 0x91, 0x08, 0x01, 0x00, 0x00, 0x00, 0x89,
0x12, 0x87, 0xe4, 0x11, 0x79, 0x04, 0x44, 0x00, 0x02, 0x9f, 0x08, 0x01, 0x00, 0x00, 0x00, 0x89,
0x92, 0x87, 0x24, 0x10, 0x89, 0x04, 0x44, 0x00, 0x02, 0x91, 0x0f, 0x01, 0x00, 0x00, 0x00, 0x89,
0x22, 0x56, 0x24, 0x10, 0x89, 0x04, 0x44, 0x00, 0x02, 0x91, 0x08, 0x01, 0x00, 0x00, 0x00, 0x89,
0x22, 0x46, 0x24, 0x10, 0x89, 0x04, 0x44, 0x04, 0x22, 0x91, 0x08, 0x01, 0x00, 0x00, 0x00, 0x89,
0xc2, 0x30, 0x24, 0xe0, 0x78, 0x7c, 0x84, 0x03, 0x1c, 0x91, 0x08, 0x01, 0x00, 0x00, 0x00, 0x89,
0x04, 0x0f, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x88,
0x10, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x88,
0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x10, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x88,
0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x88,
0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0xe2, 0x7f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x12, 0x80, 0xc4, 0x11, 0x71, 0x7c, 0xe0, 0xe1, 0x70, 0x04, 0x71, 0x00, 0x00, 0x00, 0x00, 0x89,
0x12, 0x80, 0x24, 0x12, 0x89, 0x10, 0x20, 0x12, 0x89, 0x04, 0x89, 0x00, 0x00, 0x00, 0x00, 0x89,
0x12, 0x80, 0x24, 0x10, 0x89, 0x10, 0x20, 0x12, 0x89, 0x8c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x89,
0x12, 0x80, 0x24, 0x10, 0x89, 0x10, 0x20, 0x12, 0x89, 0x54, 0x09, 0x00, 0x00, 0x00, 0x00, 0x89,
0x12, 0x80, 0x24, 0xf0, 0x89, 0x10, 0xe0, 0x11, 0x89, 0x24, 0x71, 0x00, 0x00, 0x00, 0x00, 0x89,
0x12, 0x80, 0x24, 0x10, 0xf9, 0x10, 0xa0, 0x10, 0x89, 0x04, 0x81, 0x00, 0x00, 0x00, 0x00, 0x89,
0xe2, 0x71, 0x24, 0x10, 0x89, 0x10, 0x20, 0x11, 0x89, 0x04, 0x81, 0x00, 0x00, 0x00, 0x00, 0x89,
0x02, 0x12, 0x24, 0x12, 0x89, 0x10, 0x20, 0x12, 0x89, 0x04, 0x89, 0x00, 0x00, 0x00, 0x00, 0x89,
0x02, 0x14, 0xc4, 0x11, 0x89, 0x10, 0x20, 0xe2, 0x70, 0x04, 0x71, 0x00, 0x00, 0x00, 0x00, 0x89,
0x04, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x88,
0x10, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x88,
0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x10, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x88,
0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x88,
0x04, 0x0f, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x82, 0x10, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x42, 0x20, 0x24, 0x12, 0x11, 0x8e, 0xc8, 0x07, 0xc4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x42, 0x20, 0x24, 0x12, 0x11, 0x91, 0x48, 0x00, 0x44, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0xe2, 0x7f, 0x24, 0x12, 0x11, 0x91, 0x48, 0x00, 0x44, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x32, 0xc0, 0x24, 0x32, 0x11, 0x91, 0x48, 0x00, 0x44, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x12, 0x80, 0x24, 0x52, 0x11, 0x91, 0xc8, 0x01, 0x44, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x12, 0x84, 0x24, 0x92, 0x11, 0x91, 0x48, 0x00, 0x44, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x12, 0x86, 0x24, 0x12, 0x11, 0x95, 0x48, 0x00, 0x44, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x12, 0x86, 0x24, 0x12, 0x11, 0x89, 0x48, 0x00, 0x44, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x22, 0x40, 0xc4, 0x11, 0x11, 0x16, 0xc7, 0x07, 0xc4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0xc4, 0x3f, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x88,
0x10, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00,
0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20
};
const unsigned char main_menu_4_bits [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x10, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00,
0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x88,
0x84, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0xc2, 0x3f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x22, 0x40, 0xf4, 0x71, 0x44, 0x3e, 0xf0, 0x10, 0x8e, 0x4f, 0xe4, 0xf1, 0x71, 0x00, 0x00, 0x89,
0x92, 0x80, 0x44, 0x88, 0x44, 0x02, 0x10, 0x11, 0x11, 0x42, 0x24, 0x12, 0x88, 0x00, 0x00, 0x89,
0x12, 0x8f, 0x44, 0x88, 0x24, 0x02, 0x10, 0x11, 0x01, 0x42, 0x24, 0x12, 0x08, 0x00, 0x00, 0x89,
0x92, 0x90, 0x44, 0x88, 0x14, 0x02, 0x10, 0x11, 0x01, 0x42, 0x24, 0x12, 0x08, 0x00, 0x00, 0x89,
0x92, 0x92, 0x44, 0x88, 0x0c, 0x0e, 0xf0, 0x10, 0x01, 0x42, 0xe4, 0x71, 0x70, 0x00, 0x00, 0x89,
0x92, 0x90, 0x44, 0xf8, 0x14, 0x02, 0x10, 0x10, 0x01, 0x42, 0xa4, 0x10, 0x80, 0x00, 0x00, 0x89,
0x12, 0x8f, 0x44, 0x88, 0x24, 0x02, 0x10, 0x10, 0x01, 0x42, 0x24, 0x11, 0x80, 0x00, 0x00, 0x89,
0x22, 0x40, 0x44, 0x88, 0x44, 0x02, 0x10, 0x10, 0x11, 0x42, 0x24, 0x12, 0x88, 0x00, 0x00, 0x89,
0xc2, 0x3f, 0x44, 0x88, 0x44, 0x3e, 0x10, 0x10, 0x0e, 0x82, 0x23, 0xf2, 0x71, 0x00, 0x00, 0x89,
0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x88,
0x10, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x88,
0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x10, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x88,
0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x88,
0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0xc2, 0x3f, 0x24, 0xe2, 0xf8, 0x80, 0xc3, 0x01, 0x8f, 0xcf, 0xe3, 0xe3, 0xf8, 0x7c, 0x1e, 0x89,
0x22, 0x40, 0x24, 0x12, 0x09, 0x40, 0x24, 0x02, 0x91, 0x40, 0x24, 0x10, 0x21, 0x04, 0x22, 0x89,
0x92, 0x9f, 0x24, 0x12, 0x08, 0x40, 0x24, 0x00, 0x91, 0x40, 0x24, 0x10, 0x21, 0x04, 0x22, 0x89,
0x42, 0x20, 0x24, 0x12, 0x08, 0x40, 0x24, 0x00, 0x91, 0x40, 0x24, 0x10, 0x21, 0x04, 0x22, 0x89,
0x22, 0x4f, 0x24, 0xe2, 0x38, 0x40, 0xc4, 0x01, 0x8f, 0xc3, 0xe3, 0x10, 0x21, 0x1c, 0x1e, 0x89,
0x82, 0x10, 0x24, 0x02, 0x09, 0xc0, 0x07, 0x02, 0x85, 0x40, 0x20, 0xf0, 0x21, 0x04, 0x0a, 0x89,
0x02, 0x06, 0x24, 0x02, 0x09, 0x40, 0x04, 0x02, 0x89, 0x40, 0x20, 0x10, 0x21, 0x04, 0x12, 0x89,
0x02, 0x0f, 0x24, 0x12, 0x09, 0x40, 0x24, 0x02, 0x91, 0x40, 0x20, 0x10, 0x21, 0x04, 0x22, 0x89,
0x02, 0x06, 0xc4, 0xe1, 0xf8, 0x40, 0xc4, 0x01, 0x91, 0x4f, 0xe0, 0x13, 0x21, 0x7c, 0x22, 0x89,
0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x88,
0x10, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x88,
0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x10, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x88,
0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x88,
0xe4, 0x7f, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x12, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x92, 0x80, 0x24, 0x48, 0x24, 0xf0, 0x11, 0x41, 0x3e, 0x0f, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x89,
0x52, 0x81, 0x24, 0x48, 0x24, 0x40, 0x10, 0x41, 0x02, 0x11, 0x11, 0x01, 0x00, 0x00, 0x00, 0x89,
0x92, 0x80, 0x64, 0x4c, 0x24, 0x40, 0x10, 0x63, 0x02, 0x11, 0x11, 0x01, 0x00, 0x00, 0x00, 0x89,
0x12, 0xa0, 0xa4, 0x4a, 0x24, 0x40, 0x10, 0x55, 0x02, 0x11, 0x11, 0x01, 0x00, 0x00, 0x00, 0x89,
0x12, 0xd1, 0x24, 0x49, 0x24, 0x40, 0x10, 0x49, 0x0e, 0x11, 0x11, 0x01, 0x00, 0x00, 0x00, 0x89,
0x92, 0x8a, 0x24, 0x48, 0x24, 0x40, 0x10, 0x41, 0x02, 0x11, 0xf1, 0x01, 0x00, 0x00, 0x00, 0x89,
0x52, 0x84, 0x24, 0x48, 0x24, 0x40, 0x10, 0x41, 0x02, 0x11, 0x11, 0x01, 0x00, 0x00, 0x00, 0x89,
0x32, 0x80, 0x24, 0x48, 0x24, 0x40, 0x10, 0x41, 0x02, 0x11, 0x11, 0x01, 0x00, 0x00, 0x00, 0x89,
0x12, 0x80, 0x24, 0x88, 0xe3, 0x43, 0x10, 0x41, 0x3e, 0x0f, 0x11, 0x01, 0x00, 0x00, 0x00, 0x89,
0xe4, 0x7f, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x88,
0x10, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00,
0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20
};
// 'chat_friends_window', 128x64px
const unsigned char friends_chat_window [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
0x30, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0x00, 0x00, 0x10, 0x11, 0x50,
0x48, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x11, 0x88,
0x10, 0xc7, 0x95, 0x03, 0x0e, 0xcc, 0x9c, 0x32, 0xc5, 0xdc, 0x19, 0x73, 0x20, 0x9a, 0x73, 0x00,
0x20, 0x22, 0x2d, 0x01, 0x09, 0x22, 0xa5, 0x6a, 0x6b, 0x92, 0x90, 0x94, 0xa0, 0x12, 0x91, 0x88,
0x48, 0x2a, 0x05, 0x05, 0x09, 0x22, 0xa5, 0x1a, 0x81, 0x92, 0x92, 0x94, 0xa0, 0x12, 0x95, 0x88,
0x30, 0xc4, 0x05, 0x02, 0x0e, 0xcc, 0x24, 0x31, 0x61, 0x1c, 0x39, 0x93, 0x40, 0x39, 0x92, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x88,
0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x88,
0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x88,
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x89,
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x89,
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x89,
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x89,
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x89,
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x89,
0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x88,
0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x88,
0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x88,
0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x88,
0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x88,
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x89,
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x89,
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x89,
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x89,
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x89,
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x89,
0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x88,
0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x88,
0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x88,
0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x88,
0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x88,
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x89,
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x89,
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x89,
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x89,
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x89,
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x89,
0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x88,
0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x88,
0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x88,
0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x88,
0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x88,
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x89,
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x89,
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x89,
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x89,
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x89,
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x89,
0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00,
0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x88,
0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x50,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20
};
// The width and height of your bitmap
#define main_menu_1_width 128
#define main_menu_1_height 64
#define upButtonPin 6
#define downButtonPin 7
#define rightButtonPin 10
#define leftButtonPin 19
#define selectButtonPin 5
#define homeButtonPin 4
#define returnButtonPin 3
#define receiveButtonPin 18
#define MAX_PAGES 12 // Maximum depth of navigation
#define newButtonPin 1 //pin to display the letter a
#define MAX_MESSAGES 100 // maximum number of messages to display
#define MAX_FRIENDS 100 //maximum number of friends one can have
// Scrollbar properties
const int scrollbarX = 127; // X position of the scrollbar
const int scrollbarY = 0; // Y position of the scrollbar
const int scrollbarHeight = 64; // Height of the scrollbar area
const int scrollbarWidth = 1; // Width of the scrollbar
const int numberOfMenuItems = 12; // Total number of items that can be scrolled
const char* friendNames[] = {"John", "Emma", "Alex", "Olivia", "Liam", "Ava", "Noah", "Sophia", "William", "Isabella"}; // Declare numFriends as a global variable
int pageStack[MAX_PAGES];
int stackTop = -1; // Stack is initially empty
int numFriends = sizeof(friendNames) / sizeof(friendNames[0]); //total number of friends
volatile int currentItem = 0; // Index of the current menu item selected
volatile bool enterIDPage = false; // Flag to enter the ID page
volatile bool showMainMenu = true; // Flag to control main menu display
volatile bool isSelected = false; //Flag to indicate if the selection animation should be shown
volatile int currentFriendItem = 0; // Index of the current friend item selected
volatile bool isWriteTextSelected = false;
char inputText[128] = ""; // Buffer to store the input text
volatile bool blinkState = false;
volatile bool isTextInputActive = false; // Flag to indicate if text input mode is active
volatile bool isSendButtonSelected = false;
int textScrollOffset = 0; // Tracks how much of the text is scrolled off-screen
// Define page identifiers
enum {
MAIN_MENU = 0,
ID_PAGE = 1,
FRIENDS_CHAT = 2,
CHAT_PAGE = 3
// Add more page IDs as needed for your application
};
struct Message {
String text;
bool isSent;
int friendIndex;
};
Message friendMessages[MAX_FRIENDS][MAX_MESSAGES];
int friendMessageCount[MAX_FRIENDS] = {0};
int messageStartIndex = 0; // Index of the first message displayed
// Variable to keep track of the current page
int currentPage = MAIN_MENU; // Initialize to the main menu page
void IRAM_ATTR handleUpButtonInterrupt(void* arg) {
static unsigned long lastInterruptTime = 0;
unsigned long interruptTime = millis();
if (interruptTime - lastInterruptTime > 150) { // Debounce time of 150ms
if (currentPage == FRIENDS_CHAT) {
if (currentFriendItem > 0) {
currentFriendItem--;
// Remove the blinking-related code
}
} else if (showMainMenu) {
if (currentItem > 0) {
currentItem--;
Serial.print("Current Item: ");
Serial.println(currentItem);
}
}
if (currentPage == CHAT_PAGE && messageStartIndex > 0) {
int availableHeight = main_menu_1_height - 20 - 16; // Calculate the available screen space
int totalHeight = 0;
for (int i = 0; i < friendMessageCount[currentFriendItem]; i++) {
String msg = friendMessages[currentFriendItem][i].text;
int messageWidth = u8g2.getStrWidth(msg.c_str());
int numLines = (messageWidth / 110) + (messageWidth % 110 > 0);
totalHeight += numLines * 8 + 2; // Calculate the total height of all messages
}
if (totalHeight > availableHeight) {
messageStartIndex--;
}
}
lastInterruptTime = interruptTime;
}
}
void IRAM_ATTR handleDownButtonInterrupt(void* arg) {
static unsigned long lastInterruptTime = 0;
unsigned long interruptTime = millis();
if (interruptTime - lastInterruptTime > 150) { // Debounce time of 150ms
if (currentPage == FRIENDS_CHAT) {
if (currentFriendItem < numFriends - 1) { // Scroll until the last friend
currentFriendItem++;
// Remove the blinking-related code
}
} else if (showMainMenu) {
if (currentItem < numberOfMenuItems - 1) {
currentItem++;
Serial.print("Current Item: ");
Serial.println(currentItem);
}
}
if (currentPage == CHAT_PAGE && messageStartIndex + 1 < friendMessageCount[currentFriendItem]) {
int availableHeight = main_menu_1_height - 20 - 16; // Calculate the available screen space
int totalHeight = 0;
int lastVisibleIndex = messageStartIndex;
while (lastVisibleIndex < friendMessageCount[currentFriendItem] && totalHeight < availableHeight) {
String msg = friendMessages[currentFriendItem][lastVisibleIndex].text;
int messageWidth = u8g2.getStrWidth(msg.c_str());
int numLines = (messageWidth / 110) + (messageWidth % 110 > 0);
totalHeight += numLines * 8 + 2;
lastVisibleIndex++;
}
if (lastVisibleIndex < friendMessageCount[currentFriendItem]) {
messageStartIndex++;
}
}
lastInterruptTime = interruptTime;
}
}
void IRAM_ATTR handleRightButtonInterrupt(void* arg) {
static unsigned long lastInterruptTime = 0;
unsigned long interruptTime = millis();
if (interruptTime - lastInterruptTime > 150) {
if ((currentPage == CHAT_PAGE || currentPage == FRIENDS_CHAT) && !isWriteTextSelected && !isTextInputActive) {
isWriteTextSelected = true;
isSendButtonSelected = false; // Reset send button selection
Serial.println("Right button pressed. Write Text selected.");
} else if (currentPage == CHAT_PAGE && isTextInputActive && !isSendButtonSelected) {
isSendButtonSelected = true; // Select send button
Serial.println("Right button pressed. Send button selected.");
}
lastInterruptTime = interruptTime;
}
}
void IRAM_ATTR handleLeftButtonInterrupt(void* arg) {
static unsigned long lastInterruptTime = 0;
unsigned long interruptTime = millis();
if (interruptTime - lastInterruptTime > 150) {
if ((currentPage == CHAT_PAGE || currentPage == FRIENDS_CHAT) && isWriteTextSelected && !isTextInputActive) {
isWriteTextSelected = false;
isSendButtonSelected = false; // Reset send button selection
Serial.println("Left button pressed. Send Audio selected.");
} else if (currentPage == CHAT_PAGE && isTextInputActive && isSendButtonSelected) {
isSendButtonSelected = false; // Deselect send button
Serial.println("Left button pressed. Text input selected.");
}
lastInterruptTime = interruptTime;
}
}
void IRAM_ATTR handleNewButtonInterrupt(void* arg) {
static unsigned long lastInterruptTime = 0;
unsigned long interruptTime = millis();
if (interruptTime - lastInterruptTime > 150) { // Debounce time
lastInterruptTime = interruptTime;
if (isTextInputActive) {
size_t len = strlen(inputText);
if (len < sizeof(inputText) - 1) {
inputText[len] = 'a'; // Append 'a'
inputText[len + 1] = '\0'; // Null-terminate
// Calculate width of the input text and update scroll offset
int textWidth = u8g2.getStrWidth(inputText);
if (textWidth > main_menu_1_width - 10) { // 10 is a buffer from screen edge
textScrollOffset = textWidth - (main_menu_1_width - 10);
}
}
}
}
}
void IRAM_ATTR handleSelectButtonInterrupt(void* arg) {
static unsigned long lastInterruptTime = 0;
unsigned long interruptTime = millis();
if (interruptTime - lastInterruptTime > 150) { // Debounce time of 150ms
lastInterruptTime = interruptTime;
if (currentPage == CHAT_PAGE) {
if (isTextInputActive) {
// Check if the send button is selected
if (isSendButtonSelected) {
// Send the message
sendMessage(inputText, currentFriendItem);
// Clear the input text buffer
memset(inputText, 0, sizeof(inputText));
// Keep text input mode active and reset send button selection
isTextInputActive = true;
isSendButtonSelected = false;
Serial.println("Message sent and input reset.");
}
} else if (isWriteTextSelected) {
// Enter text input mode
// Add code here to handle the text input process
Serial.println("Write Text option selected.");
// Set the flag to indicate that text input mode is active
isTextInputActive = true;
} else {
// Send audio
// Add code here to handle sending audio
Serial.println("Send Audio option selected.");
}
} else if (currentPage == FRIENDS_CHAT) { // Enter chat page from Friends Chat
pushPage(currentPage);
currentPage = CHAT_PAGE; // Switch to chat page
} else if (currentItem == 5 && currentPage != FRIENDS_CHAT) {
pushPage(currentPage); // Save the current page before switching
currentPage = FRIENDS_CHAT; // Update the current page
showMainMenu = false;
currentFriendItem = 0; // Set currentFriendItem to 0 when entering friends chat page
} else if (currentItem == 1 && currentPage != ID_PAGE) {
pushPage(currentPage); // Save the current page before switching
enterIDPage = true;
showMainMenu = false;
currentPage = ID_PAGE; // Update the current page
isSelected = true; // Set the selection effect to be true
}
}
}
void IRAM_ATTR handleHomeButtonInterrupt(void* arg) {
static unsigned long lastInterruptTime = 0;
unsigned long interruptTime = millis();
if (interruptTime - lastInterruptTime > 150) { // Debounce time of 150ms
lastInterruptTime = interruptTime;
// Always reset to the main menu, even if already there
clearStack(); // Reset the navigation stack
showMainMenu = true;
enterIDPage = false;
currentPage = MAIN_MENU;
currentItem = 0; // Reset to the first item or desired start point
}
}
void IRAM_ATTR handleReturnButtonInterrupt(void* arg) {
static unsigned long lastInterruptTime = 0;
unsigned long interruptTime = millis();
if (interruptTime - lastInterruptTime > 150) { // Debounce time of 150ms
lastInterruptTime = interruptTime;
if (currentPage == CHAT_PAGE && isTextInputActive) {
// Exit text input mode and go back to choosing between "Write Text" and "Send Audio"
isTextInputActive = false;
// Clear the input text buffer
memset(inputText, 0, sizeof(inputText));
} else {
int previousPageId = popPage(); // Pop the top of the stack to get the last page
if (previousPageId != -1) {
currentPage = previousPageId; // Update the current page based on stack
showPage(previousPageId); // Display the previous page
}
}
}
}
void IRAM_ATTR handleReceiveButtonInterrupt(void* arg) {
static unsigned long lastInterruptTime = 0;
unsigned long interruptTime = millis();
if (interruptTime - lastInterruptTime > 150) {
lastInterruptTime = interruptTime;
// Simulate a received message
const char* receivedMessage = "Simulated received message content goes really hard";
if (friendMessageCount[currentFriendItem] < MAX_MESSAGES) {
friendMessages[currentFriendItem][friendMessageCount[currentFriendItem]++] = {String(receivedMessage), false, currentFriendItem};
} else {
// Shift older messages out if buffer is full
for (int i = 1; i < MAX_MESSAGES; i++) {
friendMessages[currentFriendItem][i - 1] = friendMessages[currentFriendItem][i];
}
friendMessages[currentFriendItem][MAX_MESSAGES - 1] = {String(receivedMessage), false, currentFriendItem};
}
updateMessageStartIndex(currentFriendItem);
}
}
void setup(void) {
Serial.begin(9600);
u8g2.begin();
pinMode(upButtonPin, INPUT_PULLUP);
pinMode(downButtonPin, INPUT_PULLUP);
pinMode(rightButtonPin, INPUT_PULLUP);
pinMode(leftButtonPin, INPUT_PULLUP);
pinMode(selectButtonPin, INPUT_PULLUP);
pinMode(homeButtonPin, INPUT_PULLUP); // Setup for Home button
pinMode(returnButtonPin, INPUT_PULLUP); // Setup for Return button
pinMode(newButtonPin, INPUT_PULLUP); //setup for "a" button
pinMode(receiveButtonPin, INPUT_PULLUP); //setup for received message simulation
gpio_set_intr_type((gpio_num_t)upButtonPin, GPIO_INTR_NEGEDGE);
gpio_set_intr_type((gpio_num_t)downButtonPin, GPIO_INTR_NEGEDGE);
gpio_set_intr_type((gpio_num_t)selectButtonPin, GPIO_INTR_NEGEDGE);
gpio_set_intr_type((gpio_num_t)homeButtonPin, GPIO_INTR_NEGEDGE);
gpio_set_intr_type((gpio_num_t)returnButtonPin, GPIO_INTR_NEGEDGE);
gpio_set_intr_type((gpio_num_t)rightButtonPin, GPIO_INTR_NEGEDGE);
gpio_set_intr_type((gpio_num_t)leftButtonPin, GPIO_INTR_NEGEDGE);
gpio_set_intr_type((gpio_num_t)newButtonPin, GPIO_INTR_NEGEDGE); //setup for a button
gpio_set_intr_type((gpio_num_t)receiveButtonPin, GPIO_INTR_NEGEDGE); //setup for a received message simulation
gpio_install_isr_service(0);
gpio_isr_handler_add((gpio_num_t)upButtonPin, handleUpButtonInterrupt, NULL);
gpio_isr_handler_add((gpio_num_t)downButtonPin, handleDownButtonInterrupt, NULL);
gpio_isr_handler_add((gpio_num_t)selectButtonPin, handleSelectButtonInterrupt, NULL);
gpio_isr_handler_add((gpio_num_t)homeButtonPin, handleHomeButtonInterrupt, NULL); // Attach ISR for Home button
gpio_isr_handler_add((gpio_num_t)returnButtonPin, handleReturnButtonInterrupt, NULL); // Attach ISR for Return button
gpio_isr_handler_add((gpio_num_t)rightButtonPin, handleRightButtonInterrupt, NULL); // Attach ISR for Home button
gpio_isr_handler_add((gpio_num_t)leftButtonPin, handleLeftButtonInterrupt, NULL); // Attach ISR for Return button
gpio_isr_handler_add((gpio_num_t)newButtonPin, handleNewButtonInterrupt, NULL); // Attach ISR for "a" button
gpio_isr_handler_add((gpio_num_t)receiveButtonPin, handleReceiveButtonInterrupt, NULL); // Attach ISR for the received button simulation button
}
void loop() {
u8g2.firstPage();
do {
if (enterIDPage) {
drawIDPage(); // Priority to ID page
} else if (currentPage == FRIENDS_CHAT) {
drawFriendsChat();
} else if (currentPage == CHAT_PAGE) {
drawChatPage();
updateBlinkState();
} else if (showMainMenu) {
drawMainMenu(); // This will now show the main menu with currentItem set to 0
drawActiveElements(); // Use the isSelected flag for visual feedback
drawDynamicText();
drawScrollbar();
}
isSelected = false; // Reset isSelected after drawing it once
} while (u8g2.nextPage());
}
void handleUpButtonInterrupt() {
static unsigned long lastInterruptTime = 0;
unsigned long interruptTime = millis();
if (interruptTime - lastInterruptTime > 150) { // Debounce time of 150ms
if (currentItem > 0) {
currentItem--;
}
lastInterruptTime = interruptTime;
}
}
void handleDownButtonInterrupt() {
static unsigned long lastInterruptTime = 0;
unsigned long interruptTime = millis();
if (interruptTime - lastInterruptTime > 150) { // Debounce time of 150ms
if (currentItem < numberOfMenuItems - 1) {
currentItem++;
}
lastInterruptTime = interruptTime;
}
}
void drawMainMenu() {
// Choix du bitmap à afficher en fonction de l'index de l'élément courant
const uint8_t* bitmap_to_display;
if (currentItem <= 2) { // Items 0, 1, 2
bitmap_to_display = main_menu_1_bits;
} else if (currentItem <= 5) { // Items 3, 4, 5
bitmap_to_display = main_menu_2_bits;
} else if (currentItem <= 8) { // Items 6, 7, 8
bitmap_to_display = main_menu_3_bits;
} else { // Items 9, 10
bitmap_to_display = main_menu_4_bits;
}
// Affiche le bitmap sélectionné
u8g2.drawXBMP(0, 0, main_menu_1_width, main_menu_1_height, bitmap_to_display);
}
void drawActiveElements() {
static unsigned long lastBlinkTime = 0;
static bool blinkState = false;
const int blinkInterval = 500; // Blink interval in milliseconds
int rectangleX = 17;
int itemsPerPage = 3; // Number of items per page
int relativeIndex = currentItem % itemsPerPage; // Relative index within the current page
int rectangleY = 4 + (relativeIndex * 21);
int rectangleWidth = 103;
int rectangleHeight = 14;
// Check if it's time to toggle the blink state
if (millis() - lastBlinkTime >= blinkInterval) {
blinkState = !blinkState;
lastBlinkTime = millis();
}
// Draw the background for the selected item
if (blinkState) {
u8g2.setDrawColor(0); // Draw black on white
u8g2.drawBox(rectangleX, rectangleY, rectangleWidth, rectangleHeight); // Invert the color inside the rectangle
u8g2.setDrawColor(1); // Reset to draw white on black
}
// Draw the frame around the menu item
u8g2.drawFrame(rectangleX, rectangleY, rectangleWidth, rectangleHeight);
// Draw an additional vertical line on the left side for extra thickness
u8g2.drawVLine(rectangleX + 1, rectangleY, rectangleHeight);
// Optionally reset the drawing state
u8g2.setDrawColor(1); // Ensure normal drawing mode is active
}
void drawDynamicText() {
// Draw dynamic text, such as battery level or user ID
// Placeholder for drawing dynamic text
}
void drawScrollbar() {
int scrollIndicatorWidth = 1; // Width of the scroll indicator
int scrollIndicatorHeight = 5; // Height of the scroll indicator
int scrollbarX = 125; // X position of the scrollbar (near the right side of the screen)
int scrollbarY = 4; // Y position of the scrollbar (4 pixels from the top)
int scrollbarEndY = main_menu_1_height - 5; // Ending Y position of the scrollbar (5 pixels from the bottom)
// Calculate the total height available for the scrollbar
int totalScrollableHeight = scrollbarEndY - scrollbarY - scrollIndicatorHeight;
// Determine the number of possible positions for the scroll indicator
float stepSize = static_cast<float>(totalScrollableHeight) / (numberOfMenuItems - 1);
int indicatorY;
if (currentItem == 0) {
indicatorY = scrollbarY; // Start exactly 4 pixels from the top
} else if (currentItem == numberOfMenuItems - 1) {
indicatorY = scrollbarEndY - scrollIndicatorHeight; // End exactly 5 pixels from the bottom
} else {
indicatorY = scrollbarY + static_cast<int>(currentItem * stepSize); // Calculate position for other items
}
// Draw the scroll indicator rectangle
u8g2.drawBox(scrollbarX, indicatorY, scrollIndicatorWidth, scrollIndicatorHeight);
}
void drawIDPage() {
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_5x8_tf);
u8g2.drawStr(0, 30, "Conversation");
u8g2.drawStr(64, 30, "");
u8g2.sendBuffer();
}
void pushPage(int pageId) {
if (stackTop < MAX_PAGES - 1) {
stackTop++;
pageStack[stackTop] = pageId;
} else {
throw std::runtime_error("Navigation stack full"); // Throw exception
}
}
int popPage() {
if (stackTop > -1) {
int pageId = pageStack[stackTop];
stackTop--;
return pageId;
} else {
return -1; // Return an invalid page ID for handling
}
}
void showPage(int pageId) {
switch (pageId) {
case MAIN_MENU:
showMainMenu = true;
enterIDPage = false;
break;
case ID_PAGE:
enterIDPage = true;
showMainMenu = false;
break;
// Handle other cases similarly
}
currentPage = pageId; // Update the current page state
}
void navigateToPage(int newPageId) {
if (currentPage != newPageId) {
pushPage(currentPage); // Only push if the page is actually changing
currentPage = newPageId;
showPage(newPageId);
}
}
void clearStack() {
while (stackTop >= 0) {
stackTop--; // Just decrement the stack pointer effectively clearing the stack
}
}
void drawFriendsChat() {
unsigned long startTime = millis();
u8g2.firstPage();
do {
u8g2.clearBuffer();
// Draw the bitmap as background
u8g2.drawXBMP(0, 0, main_menu_1_width, main_menu_1_height, friends_chat_window);
// Set font for names
u8g2.setFont(u8g2_font_5x8_tf);
int startY = 18; // Start drawing names from y = 18
int stepY = 14; // Space between names
// Calculate the starting index based on the current friend item
int startIndex = (currentFriendItem / 4) * 4;
// Draw the visible friend names
for (int i = 0; i < 4 && startIndex + i < numFriends; i++) {
int nameWidth = u8g2.getStrWidth(friendNames[startIndex + i]);
int nameX = (main_menu_1_width - nameWidth) / 2; // Calculate x position to center the name
u8g2.drawStr(nameX, startY + i * stepY, friendNames[startIndex + i]); // Draw each name centered
}
// Draw the active friend selection
drawActiveFriends();
// Draw the scrollwheel based on the number of friends
drawScrollbarFriends();
u8g2.sendBuffer();
} while (u8g2.nextPage());
unsigned long duration = millis() - startTime;
}
void drawActiveFriends() {
static unsigned long lastBlinkTime = 0;
static bool blinkState = false;
const int blinkInterval = 100; // Blink interval in milliseconds
int itemsPerPage = 4; // Number of items per page
int relativeIndex = currentFriendItem % itemsPerPage; // Relative index within the current page
int nameY = 18 + relativeIndex * 14; // Adjust startY to 18px and step by 14px per item
// Check if it's time to toggle the blink state
if (millis() - lastBlinkTime >= blinkInterval) {
blinkState = !blinkState;
lastBlinkTime = millis();
}
if (currentFriendItem < numFriends) { // Ensure the currentFriendItem index is valid
int nameWidth = u8g2.getStrWidth(friendNames[currentFriendItem]);
int nameX = (main_menu_1_width - nameWidth) / 2; // Calculate x position to center the name
// Calculate position for the hyphen to appear right before the name
int hyphenX = nameX - u8g2.getStrWidth("-") - 2; // Adjust by the width of the hyphen and some padding
// Draw the hyphen if blink state is on and the currentFriendItem index is valid
if (blinkState && currentFriendItem < numFriends) {
u8g2.setDrawColor(1); // Set the drawing color to white
u8g2.drawStr(hyphenX, nameY, "-"); // Draw hyphen
}
}
}
void drawScrollbarFriends() {
int scrollIndicatorWidth = 1; // Width of the scroll indicator
int scrollIndicatorHeight = 5; // Height of the scroll indicator
int scrollbarX = 125; // X position of the scrollbar (near the right side of the screen)
int scrollbarY = 4; // Y position of the scrollbar (4 pixels from the top)
int scrollbarEndY = main_menu_1_height - 5; // Ending Y position of the scrollbar (5 pixels from the bottom)
// Calculate the total height available for the scrollbar
int totalScrollableHeight = scrollbarEndY - scrollbarY - scrollIndicatorHeight;
// Determine the number of possible positions for the scroll indicator
float stepSize = static_cast<float>(totalScrollableHeight) / (numFriends - 1);
int indicatorY;
if (currentFriendItem == 0) {
indicatorY = scrollbarY; // Start exactly 4 pixels from the top
} else if (currentFriendItem == numFriends - 1) {
indicatorY = scrollbarEndY - scrollIndicatorHeight; // End exactly 5 pixels from the bottom
} else {
indicatorY = scrollbarY + static_cast<int>(currentFriendItem * stepSize); // Calculate position for other items
}
// Draw the scroll indicator rectangle
u8g2.drawBox(scrollbarX, indicatorY, scrollIndicatorWidth, scrollIndicatorHeight);
}
void updateBlinkState() {
static unsigned long lastBlinkTime = 0;
const unsigned long blinkInterval = 500; // Blink interval in milliseconds
if (millis() - lastBlinkTime >= blinkInterval) {
blinkState = !blinkState;
lastBlinkTime = millis();
}
}
void drawChatPage() {
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_5x8_tf);
// Construct the title with the friend's name
char chatTitle[50]; // Adjust size as needed
if (currentFriendItem < numFriends) {
snprintf(chatTitle, sizeof(chatTitle), "Chat with: %s", friendNames[currentFriendItem]);
int titleWidth = u8g2.getStrWidth(chatTitle);
int titleX = (main_menu_1_width - titleWidth) / 2;
u8g2.drawStr(titleX, 7, chatTitle); // Draw title at the top
u8g2.drawLine(0, 9, main_menu_1_width, 9); // Divider line
}
// Draw messages
drawMessages(); // You'll want to keep or adjust your message drawing logic
// Draw the rectangles at the bottom
int rectangleHeight = 12;
int rectangleY = main_menu_1_height - rectangleHeight - 2;
if (isTextInputActive) {
// Draw a single rectangle for text input
u8g2.drawFrame(2, rectangleY, main_menu_1_width - 4, rectangleHeight);
// Text scrolling implementation
int textWidth = u8g2.getStrWidth(inputText);
int textOffset = max(0, textWidth + 3 - (main_menu_1_width - 4)); // Ensure some padding
// Draw input text, adjust the Y position to draw it 2 pixels higher
u8g2.drawStr(4, rectangleY + rectangleHeight - 4, inputText);
// Draw a blinking cursor at the end of the input text or at the start if no text is entered
if (!isSendButtonSelected) { // Only draw cursor if send button is not selected
int cursorX = 5 + max(textWidth, 0) - textOffset;
int cursorY = rectangleY + rectangleHeight - 4;
if (blinkState) { // Always display the cursor when blinking
u8g2.drawLine(cursorX, cursorY - 5, cursorX, cursorY);
}
}
// Draw the send button square
int sendButtonSize = 12;
int sendButtonX = main_menu_1_width - sendButtonSize - 2;
int sendButtonY = rectangleY;
if (isSendButtonSelected && blinkState) {
u8g2.drawBox(sendButtonX, sendButtonY, sendButtonSize, sendButtonSize);
u8g2.setDrawColor(0);
u8g2.drawStr(sendButtonX + 4, sendButtonY + sendButtonSize - 3, ">");
u8g2.setDrawColor(1);
} else {
u8g2.drawFrame(sendButtonX, sendButtonY, sendButtonSize, sendButtonSize);
u8g2.drawStr(sendButtonX + 4, sendButtonY + sendButtonSize - 3, ">");
}
} else {
// Draw rectangles for "Send Audio" and "Write Text"
int rectangleWidth = (main_menu_1_width - 4) / 2;
int rectangle1X = 2;
int rectangle2X = rectangle1X + rectangleWidth + 2;
if (!isWriteTextSelected && blinkState) {
u8g2.drawBox(rectangle1X, rectangleY, rectangleWidth, rectangleHeight);
u8g2.setDrawColor(0);
u8g2.drawStr(rectangle1X + 2, rectangleY + rectangleHeight - 2, "Send Audio");
u8g2.setDrawColor(1);
} else {
u8g2.drawFrame(rectangle1X, rectangleY, rectangleWidth, rectangleHeight);
u8g2.drawStr(rectangle1X + 2, rectangleY + rectangleHeight - 2, "Send Audio");
}
if (isWriteTextSelected && blinkState) {
u8g2.drawBox(rectangle2X, rectangleY, rectangleWidth, rectangleHeight);
u8g2.setDrawColor(0);
u8g2.drawStr(rectangle2X + 2, rectangleY + rectangleHeight - 2, "Write Text");
u8g2.setDrawColor(1);
} else {
u8g2.drawFrame(rectangle2X, rectangleY, rectangleWidth, rectangleHeight);
u8g2.drawStr(rectangle2X + 2, rectangleY + rectangleHeight - 2, "Write Text");
}
}
u8g2.sendBuffer();
}
void sendMessage(const char* message, int friendIndex) {
if (strlen(message) > 0) {
Serial.print("Sending message to friend ");
Serial.print(friendIndex);
Serial.print(": ");
Serial.println(message);
// Add message to storage
if (friendMessageCount[friendIndex] < MAX_MESSAGES) {
friendMessages[friendIndex][friendMessageCount[friendIndex]++] = {String(message), true, friendIndex};
} else {
// Shift messages up if the buffer is full
for (int i = 1; i < MAX_MESSAGES; i++) {
friendMessages[friendIndex][i - 1] = friendMessages[friendIndex][i];
}
friendMessages[friendIndex][MAX_MESSAGES - 1] = {String(message), true, friendIndex};
}
// Update start index to show the latest message
updateMessageStartIndex(friendIndex);
}
memset(inputText, 0, sizeof(inputText));
isSendButtonSelected = false;
isTextInputActive = true;
}
void drawMessages() {
int startY = 17;
int currentY = startY;
const int lineHeight = 8;
const int lineSpacing = 0;
const int maxWidth = 110; // Maximum pixel width for a single line of text
const int screenMargin = 2; // Margin for the start and end of text on the screen
for (int i = messageStartIndex; i < friendMessageCount[currentFriendItem]; i++) {
String msg = friendMessages[currentFriendItem][i].text;
bool isSent = friendMessages[currentFriendItem][i].isSent;
int messageWidth = u8g2.getStrWidth(msg.c_str());
int numLines = (messageWidth / maxWidth) + (messageWidth % maxWidth > 0);
for (int line = 0; line < numLines; line++) {
int startChar = line * maxWidth / 6;
int endChar = std::min((line + 1) * maxWidth / 6, static_cast<int>(msg.length()));
String part = msg.substring(startChar, endChar);
int partWidth = u8g2.getStrWidth(part.c_str());
int lineY = currentY + (line * (lineHeight + lineSpacing));
if (isSent) {
// Append "<" to the first line of a sent message
if (line == 0) { // Add "<" only at the beginning of the first line
part += "<";
partWidth = u8g2.getStrWidth(part.c_str()); // Update width after adding "<"
}
u8g2.drawStr(main_menu_1_width - partWidth - screenMargin, lineY, part.c_str());
} else {
// Received messages are left-aligned
if (line == 0) { // Only add ">" before the first line
part = "> " + part;
partWidth = u8g2.getStrWidth(part.c_str()); // Update width after adding ">"
}
u8g2.drawStr(screenMargin, lineY, part.c_str());
}
}
currentY += numLines * (lineHeight + lineSpacing);
}
}
void updateMessageStartIndex(int friendIndex) {
const int lineHeight = 8; // Height of each line of text
const int lineSpacing = 1; // Space between lines
const int uiReservedHeight = 20; // Height reserved for the UI at the bottom and possibly the top
const int availableHeight = main_menu_1_height - uiReservedHeight; // Adjust this as necessary
int totalHeight = 0;
int visibleMessages = 0;
for (int i = friendMessageCount[friendIndex] - 1; i >= 0; i--) {
String msg = friendMessages[friendIndex][i].text;
int messageWidth = u8g2.getStrWidth(msg.c_str());
int numLines = (messageWidth / 110) + (messageWidth % 110 > 0);
int messageHeight = numLines * (lineHeight + lineSpacing) - lineSpacing;
if (totalHeight + messageHeight > availableHeight) break;
totalHeight += messageHeight;
visibleMessages++;
}
messageStartIndex = max(0, friendMessageCount[friendIndex] - visibleMessages);
}
Loading
esp32-c3-devkitm-1
esp32-c3-devkitm-1
Loading
ssd1306
ssd1306