From 3fa6902418677b30a3b1252b2d0826d84657f1f6 Mon Sep 17 00:00:00 2001 From: Jens Nolte <jens@nightmarestudio.de> Date: Thu, 11 Jun 2020 00:42:08 +0200 Subject: [PATCH] Improve oled log and status icons --- qthing/oled.cpp | 162 +++++++++++++++++++++++++++++++++++------- qthing/oled_symbols.h | 38 ++++++++-- 2 files changed, 169 insertions(+), 31 deletions(-) diff --git a/qthing/oled.cpp b/qthing/oled.cpp index e7f6342..9abe2bb 100644 --- a/qthing/oled.cpp +++ b/qthing/oled.cpp @@ -1,30 +1,70 @@ #include <qthing.h> #include "oled.h" -#include "oled_symbols.h" #include "event.h" #include "Arduino.h" #include "SSD1306Wire.h" +#include <time.h> + +#include "oled_symbols.h" + +//SSD1306Wire display(0x3c, GPIO_NUM_5, GPIO_NUM_4); +SSD1306Wire display = SSD1306Wire(0x3c, GPIO_NUM_4, GPIO_NUM_15); + +#define OLED_LOG_MAX_LENGTH 5 +std::string oled_log_messages[OLED_LOG_MAX_LENGTH]; +uint8_t oled_log_first_message = 0; +uint8_t oled_log_message_count = 0; -SSD1306Wire display(0x3c, GPIO_NUM_5, GPIO_NUM_4); +volatile long redraw_time = 1; -std::string oled_log = ""; +#define FRAME_TIME_MS 100 -void draw_network_status(uint8_t x, uint8_t y) { +#define RESET_AFTER_MS 10000 +long last_reset = 0; + +void redraw() { + redraw_time = millis(); +} + +void redraw_at_time(long time_in_ms) { + if (redraw_time == 0 || time_in_ms < redraw_time) { + redraw_time = time_in_ms; + } +} + +void redraw_after_timespan(long timespan_in_ms) { + redraw_at_time(millis() + timespan_in_ms); +} + +void draw_network_status(uint16_t& x, uint16_t y) { + x -= 10; connection_status_t wlan_status = get_wlan_connection_status(); if (wlan_status == connected) { display.drawFastImage(x, y, 10, 8, wlan_connected_symbol); } else if (wlan_status == connecting) { - display.drawFastImage(x, y, 10, 8, wlan_connecting_symbol); + #define ICON_UPDATE_RATE 200 + int m = millis() / ICON_UPDATE_RATE % 3; + if (m == 0) { + display.drawFastImage(x, y, 10, 8, wlan_connecting_symbol_1); + } + else if (m == 1) { + display.drawFastImage(x, y, 10, 8, wlan_connecting_symbol_2); + } + else { + display.drawFastImage(x, y, 10, 8, wlan_connecting_symbol_3); + } + redraw_after_timespan(ICON_UPDATE_RATE); } else if (wlan_status == disconnected) { display.drawFastImage(x, y, 10, 8, wlan_disconnected_symbol); } } -void draw_mqtt_status(uint8_t x, uint8_t y) { +void draw_mqtt_status(uint16_t& x, uint16_t y) { + x -= 8; connection_status_t mqtt_status = get_mqtt_connection_status(); if (mqtt_status == connected) { display.drawFastImage(x, y, 8, 8, mqtt_connected_symbol); @@ -37,37 +77,111 @@ void draw_mqtt_status(uint8_t x, uint8_t y) { } } +void draw_text_indicator (uint16_t& x, uint16_t y, String text) { + int width = display.getStringWidth(text); + x -= width; + // offset of -2 to align with symbols (font has height 10, symbols 8) + display.drawString(x, y - 2, text); +} + +bool draw_clock(uint16_t& x, uint16_t y) { + time_t t = time(0); + tm *now = localtime(&t); + if (now->tm_year < 100) { + return false; + } + + auto hour = now->tm_hour; + auto minute = now->tm_min; + + char time[6]; + time[0] = '0' + hour / 10; + time[1] = '0' + hour % 10; + time[2] = ':'; + time[3] = '0' + minute / 10; + time[4] = '0' + minute % 10; + time[5] = 0; + + draw_text_indicator(x, y, time); + redraw_after_timespan((60 - now->tm_sec) * 1000); + + return true; +} + void display_status() { - uint8_t iconPosition = 128; - iconPosition -= 10; - draw_network_status(iconPosition, 0); - iconPosition -= 2; - iconPosition -= 8; - draw_mqtt_status(iconPosition, 0); + uint16_t x = 128; + const uint16_t y = 2; - display.setFont(ArialMT_Plain_10); - display.setTextAlignment(TEXT_ALIGN_LEFT); - display.drawString(0, 10, "much wow, very secure"); - display.drawString(0, 20, oled_log.c_str()); + bool clock = draw_clock(x, y); + if (clock) { + x -= 2; + } + + draw_network_status(x, y); + x -= 2; + draw_mqtt_status(x, y); + x -= 2; +} + +void display_log() { + //display.setFont(ArialMT_Plain_10); + //display.setTextAlignment(TEXT_ALIGN_LEFT); + for (uint8_t i = 0; i < oled_log_message_count; i += 1) { + uint8_t line = (i + oled_log_first_message) % OLED_LOG_MAX_LENGTH; + display.drawString(0, 10 + (i * 10), oled_log_messages[line].c_str()); + } } void oled_task(void *pvParameters) { while (true) { - display.clear(); + long time_ms = millis(); + bool reset = last_reset + RESET_AFTER_MS < time_ms; - display_status(); + if (reset || (redraw_time > 0 && redraw_time <= time_ms)) { + redraw_time = 0; - display.setFont(ArialMT_Plain_10); - display.setTextAlignment(TEXT_ALIGN_RIGHT); - display.drawString(0, 20, String(millis())); - display.display(); + if (reset) { + display.resetDisplay(); + last_reset = time_ms; + } + else { + display.clear(); + } - delay(100); + display_log(); + display_status(); + + // display.setFont(ArialMT_Plain_10); + // display.setTextAlignment(TEXT_ALIGN_RIGHT); + // display.drawString(64, 0, String(millis())); + + display.display(); + } + + vTaskDelay(pdMS_TO_TICKS(FRAME_TIME_MS)); } } +void oled_log(const std::string& message) { + if (oled_log_message_count < OLED_LOG_MAX_LENGTH) { + oled_log_messages[oled_log_message_count] = message; + oled_log_message_count += 1; + } + else { + oled_log_messages[oled_log_first_message] = message; + oled_log_first_message += 1; + oled_log_first_message %= OLED_LOG_MAX_LENGTH; + } + redraw(); +} + void enable_oled() { - set_oled_log_callback([](const std::string& message) {oled_log = message;}); + oled_log("qthing"); + oled_log("much wow, very secure"); + + //display = SSD1306Wire(0x3c, GPIO_NUM_4, GPIO_NUM_15); + + set_oled_log_callback(oled_log); display.init(); display.flipScreenVertically(); display.setFont(ArialMT_Plain_10); diff --git a/qthing/oled_symbols.h b/qthing/oled_symbols.h index c9ed614..8ebb1c0 100644 --- a/qthing/oled_symbols.h +++ b/qthing/oled_symbols.h @@ -12,18 +12,42 @@ const uint8_t wlan_connected_symbol[] PROGMEM = { B00001001, B00000010 }; -const uint8_t wlan_connecting_symbol[] PROGMEM = { - B00000000, - B00000000, - B00000000, - B00000000, - B11000000, - B11000000, +const uint8_t wlan_connecting_symbol_1[] PROGMEM = { B00000000, B00000000, + B00100000, + B00010000, + B11010000, + B11010000, + B00010000, + B00100000, B00000000, B00000000 }; +const uint8_t wlan_connecting_symbol_2[] PROGMEM = { + B00000000, + B00001000, + B00000100, + B00000100, + B11000100, + B11000100, + B00000100, + B00000100, + B00001000, + B00000000 +}; +const uint8_t wlan_connecting_symbol_3[] PROGMEM = { + B00000010, + B00000001, + B00000001, + B00000001, + B11000001, + B11000001, + B00000001, + B00000001, + B00000001, + B00000010 +}; const uint8_t wlan_disconnected_symbol[] PROGMEM = { B00000000, B00000000, -- GitLab