/*
* Very simple menu on an OLED display (with 8 lines of text).
* Displays menu items from the array menu. Max. number of items is 7.
*
* This sketch uses the library "U8g2", "Bounce2" and uses 3 buttons (up/down/select).
*
*/
#include <U8g2lib.h>
#define P_ENC_A 25
#define P_ENC_B 26
#define P_ENC_SW 27
U8X8_SSD1306_128X64_NONAME_HW_I2C display(U8X8_PIN_NONE);
#define MENU_SIZE 10
#define MENU_ROWS 3
char *menu[MENU_SIZE] = {
"Den je moc",
"Za dvermi",
"Mesto",
"Soused",
"Karlin",
"Vres",
"Klidne se me",
"Jeste me drz",
"Jeste kousek",
"Svatojanska"
};
int cursor = 0;
bool selected = false;
struct Encoder {
bool a;
bool b;
int delta;
};
Encoder enc = {false, false, 0};
void IRAM_ATTR enc_isr_a() {
bool b = digitalRead(P_ENC_B) == HIGH;
if (b != enc.b) {
enc.b = b;
if (enc.a) {
enc.delta += b ? -1 : 1;
}
}
}
void IRAM_ATTR enc_isr_b() {
bool a = digitalRead(P_ENC_A) == HIGH;
if (a != enc.a) {
enc.a = a;
}
}
void setup() {
pinMode(P_ENC_A, INPUT);
pinMode(P_ENC_B, INPUT);
pinMode(P_ENC_SW, INPUT_PULLUP);
enc.a = digitalRead(P_ENC_A) == HIGH;
enc.b = digitalRead(P_ENC_B) == HIGH;
attachInterrupt(digitalPinToInterrupt(P_ENC_A), enc_isr_a, CHANGE);
attachInterrupt(digitalPinToInterrupt(P_ENC_B), enc_isr_b, CHANGE);
display.begin();
display.setPowerSave(0);
renderMenu();
}
void loop() {
if (enc.delta != 0) {
cursor = max(0, min(MENU_SIZE - 1, cursor + enc.delta));
enc.delta = 0;
selected = false;
renderMenu();
} else if (!selected && digitalRead(P_ENC_SW) == LOW) {
selected = true;
renderCurrent();
}
delay(50);
}
void renderMenu() {
int offset = max(0, min(MENU_SIZE - MENU_ROWS, cursor - 1));
display.clearDisplay();
display.setFont(u8x8_font_7x14B_1x2_f);
char* line = (char*) malloc(17);
for (int i = 0; i < MENU_ROWS; ++i) {
sprintf(line, "%02d %-13.13s", i + offset + 1, menu[i + offset]);
display.setInverseFont(i + offset == cursor);
display.drawString(0, 3 * i, line);
}
free(line);
}
void renderCurrent() {
char* line = (char*) malloc(17);
char* sp;
display.clearDisplay();
display.setInverseFont(0);
sprintf(line, "%02d", cursor + 1);
display.setFont(u8x8_font_7x14B_1x2_f);
display.drawString(0, 0, line);
display.setFont(u8x8_font_courB18_2x3_f);
if (strlen(menu[cursor]) <= 8) {
sprintf(line, "%-8.8s", menu[cursor]);
display.drawString(0, 2, line);
} else {
sp = strstr(menu[cursor], " ");
if (sp == NULL) {
sp = menu[cursor] + 8;
} else {
++sp;
}
sprintf(line, "%-*.*s", sp - menu[cursor], sp - menu[cursor], menu[cursor]);
display.drawString(0, 2, line);
sprintf(line, "%-8.8s", sp);
display.drawString(0, 5, line);
}
free(line);
}
esp:VIN
esp:GND.2
esp:D13
esp:D12
esp:D14
esp:D27
esp:D26
esp:D25
esp:D33
esp:D32
esp:D35
esp:D34
esp:VN
esp:VP
esp:EN
esp:3V3
esp:GND.1
esp:D15
esp:D2
esp:D4
esp:RX2
esp:TX2
esp:D5
esp:D18
esp:D19
esp:D21
esp:RX0
esp:TX0
esp:D22
esp:D23
ssd1306:DATA
ssd1306:CLK
ssd1306:DC
ssd1306:RST
ssd1306:CS
ssd1306:3V3
ssd1306:VIN
ssd1306:GND
enc:CLK
enc:DT
enc:SW
enc:VCC
enc:GND