From 21a703902f57db86d4a12ae007d085827930e8d8 Mon Sep 17 00:00:00 2001 From: Matthew Colvin <35540398+Mc067415@users.noreply.github.com> Date: Sat, 29 Jul 2023 08:58:13 -0500 Subject: [PATCH] Pull wifi and IR into Hardware RevX pull last bit of global variables into hardware rev --- Platformio/include/OmoteUI/OmoteUI.hpp | 12 ++ Platformio/include/omoteconfig.h | 3 + Platformio/src/HardwareRevX.cpp | 119 +++++++++++++++ Platformio/src/HardwareRevX.hpp | 64 ++++++++- Platformio/src/main.cpp | 191 +------------------------ 5 files changed, 202 insertions(+), 187 deletions(-) diff --git a/Platformio/include/OmoteUI/OmoteUI.hpp b/Platformio/include/OmoteUI/OmoteUI.hpp index a141587..9e80a95 100644 --- a/Platformio/include/OmoteUI/OmoteUI.hpp +++ b/Platformio/include/OmoteUI/OmoteUI.hpp @@ -58,6 +58,18 @@ private: int backlight_brightness = 255; lv_color_t color_primary = lv_color_hex(0x303030); // gray bool wakeupByIMUEnabled = true; + + // TODO Figure out best way to have images added + + // LV_IMG_DECLARE(gradientLeft); + // LV_IMG_DECLARE(gradientRight); + // LV_IMG_DECLARE(appleTvIcon); + // LV_IMG_DECLARE(appleDisplayIcon); + // LV_IMG_DECLARE(appleBackIcon); + // LV_IMG_DECLARE(high_brightness); + // LV_IMG_DECLARE(low_brightness); + // LV_IMG_DECLARE(lightbulb); + lv_img_dsc_t low_brightness; lv_img_dsc_t high_brightness; lv_img_dsc_t appleBackIcon; diff --git a/Platformio/include/omoteconfig.h b/Platformio/include/omoteconfig.h index 1df0fce..48f227e 100644 --- a/Platformio/include/omoteconfig.h +++ b/Platformio/include/omoteconfig.h @@ -4,6 +4,9 @@ // Comment out to disable connected features #define ENABLE_WIFI +#define WIFI_SSID "YOUR_WIFI_SSID" +#define WIFI_PASSWORD "YOUR_WIFI_PASSWORD" +#define MQTT_SERVER "YOUR_MQTT_SERVER_IP" // time until device enters sleep mode in milliseconds #define SLEEP_TIMEOUT 20000 diff --git a/Platformio/src/HardwareRevX.cpp b/Platformio/src/HardwareRevX.cpp index 0886d95..dfffa64 100644 --- a/Platformio/src/HardwareRevX.cpp +++ b/Platformio/src/HardwareRevX.cpp @@ -77,6 +77,7 @@ void HardwareRevX::init() { setupBacklight(); setupTFT(); setupIMU(); + setupIR(); initLVGL(); } @@ -361,4 +362,122 @@ void HardwareRevX::slowDisplayWakeup() { } delay(100); // Wait for the LCD driver to power on +} + +void HardwareRevX::handleWifiEvent(WiFiEvent_t event){ + // Serial.printf("[WiFi-event] event: %d\n", event); + if (event == ARDUINO_EVENT_WIFI_STA_GOT_IP) { + client.setServer(MQTT_SERVER, 1883); // MQTT initialization + client.connect("OMOTE"); // Connect using a client id + } + // Set status bar icon based on WiFi status + // TODO allow UI to register a Handler for these events + + // if (event == ARDUINO_EVENT_WIFI_STA_GOT_IP || + // event == ARDUINO_EVENT_WIFI_STA_GOT_IP6) { + // lv_label_set_text(WifiLabel, LV_SYMBOL_WIFI); + // } else { + // lv_label_set_text(WifiLabel, ""); + // } +} + +void HardwareRevX::setupIR(){ + // Setup IR + IrSender.begin(); + digitalWrite(IR_VCC, HIGH); // Turn on IR receiver + IrReceiver.enableIRIn(); // Start the receiver +} + +void HardwareRevX::setupWifi(){ +#ifdef ENABLE_WIFI + // Setup WiFi + WiFi.setHostname("OMOTE"); // define hostname + WiFi.onEvent(WiFiEvent); + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); + WiFi.setSleep(true); +#endif +} + +void HardwareRevX::handleLoop(){ + // Update Backlight brightness + static int fadeInTimer = millis(); // fadeInTimer = time after setup + if (millis() < + fadeInTimer + + backlight_brightness) { // Fade in the backlight brightness + ledcWrite(5, millis() - fadeInTimer); + } else { // Dim Backlight before entering standby + if (standbyTimer < 2000) + ledcWrite(5, 85); // Backlight dim + else + ledcWrite(5, backlight_brightness); // Backlight on + } + + // Update LVGL UI + lv_timer_handler(); + + // Blink debug LED at 1 Hz + digitalWrite(USER_LED, millis() % 1000 > 500); + + // Refresh IMU data at 10Hz + static unsigned long IMUTaskTimer = millis(); + if (millis() - IMUTaskTimer >= 100) { + activityDetection(); + if (standbyTimer == 0) { + Serial.println("Entering Sleep Mode. Goodbye."); + enterSleep(); + } + IMUTaskTimer = millis(); + } + + // Update battery stats at 1Hz + static unsigned long batteryTaskTimer = + millis() + 1000; // add 1s to start immediately + if (millis() - batteryTaskTimer >= 1000) { + battery_voltage = + analogRead(ADC_BAT) * 2 * 3300 / 4095 + 350; // 350mV ADC offset + battery_percentage = + constrain(map(battery_voltage, 3700, 4200, 0, 100), 0, 100); + batteryTaskTimer = millis(); + battery_ischarging = !digitalRead(CRG_STAT); + // Check if battery is charging, fully charged or disconnected + } + // TODO Create batter change notification for UI + + // if (battery_ischarging || (!battery_ischarging && battery_voltage > 4350)) { + // lv_label_set_text(objBattPercentage, ""); + // lv_label_set_text(objBattIcon, LV_SYMBOL_USB); + // } else { + // // Update status bar battery indicator + // // lv_label_set_text_fmt(objBattPercentage, "%d%%", battery_percentage); + // if (battery_percentage > 95) + // lv_label_set_text(objBattIcon, LV_SYMBOL_BATTERY_FULL); + // else if (battery_percentage > 75) + // lv_label_set_text(objBattIcon, LV_SYMBOL_BATTERY_3); + // else if (battery_percentage > 50) + // lv_label_set_text(objBattIcon, LV_SYMBOL_BATTERY_2); + // else if (battery_percentage > 25) + // lv_label_set_text(objBattIcon, LV_SYMBOL_BATTERY_1); + // else + // lv_label_set_text(objBattIcon, LV_SYMBOL_BATTERY_EMPTY); + // } + // } + + // Keypad Handling + customKeypad.getKey(); // Populate key list + for (int i = 0; i < LIST_MAX; i++) { // Handle multiple keys (Not really necessary in this case) + if (customKeypad.key[i].kstate == PRESSED || + customKeypad.key[i].kstate == HOLD) { + standbyTimer = + SLEEP_TIMEOUT; // Reset the sleep timer when a button is pressed + int keyCode = customKeypad.key[i].kcode; + Serial.println(customKeypad.key[i].kchar); + // Send IR codes depending on the current device (tabview page) + if (currentDevice == 1){ + IrSender.sendRC5(IrSender.encodeRC5X(0x00, keyMapTechnisat[keyCode / ROWS][keyCode % ROWS])); + } + else if (currentDevice == 2){ + IrSender.sendSony((keyCode / ROWS) * (keyCode % ROWS), 15); + } + } + } } \ No newline at end of file diff --git a/Platformio/src/HardwareRevX.hpp b/Platformio/src/HardwareRevX.hpp index b230bdf..417b690 100644 --- a/Platformio/src/HardwareRevX.hpp +++ b/Platformio/src/HardwareRevX.hpp @@ -6,8 +6,14 @@ #include "Wire.h" #include "lvgl.h" #include +#include +#include +#include +#include +#include #include #include // Hardware-specific library +#include // modified for inverted logic #include #include @@ -23,6 +29,9 @@ public: } return mInstance; } + static std::weak_ptr getRefrence(){ + return getInstance(); + } HardwareRevX() : HardwareAbstractionInterface(){}; @@ -63,7 +72,17 @@ public: void slowDisplayWakeup(); + void setupWifi(); + + void setupIR(); + + void handleWifiEvent(WiFiEvent_t event); + public: + + static void WiFiEvent(WiFiEvent_t event){ + mInstance->handleWifiEvent(event); + } static void displayFlushImpl(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) { mInstance->displayFlush(disp, area, color_p); @@ -73,7 +92,8 @@ public: mInstance->touchPadRead(indev_driver, data); } - int standbyTimer = SLEEP_TIMEOUT; + WiFiClient espClient; + PubSubClient client = PubSubClient(espClient); Adafruit_FT6206 touch = Adafruit_FT6206(); TS_Point touchPoint; @@ -83,6 +103,7 @@ public: // IMU Motion Detection LIS3DH IMU = LIS3DH(I2C_MODE, 0x19); // Default constructor is I2C, addr 0x19. + int standbyTimer = SLEEP_TIMEOUT; int motion = 0; WakeReason wakeup_reason; @@ -92,10 +113,51 @@ public: byte currentDevice = 1; // Current Device to control (allows switching // mappings between devices) + // IR declarations + IRsend IrSender = IRsend(IR_LED, true); + IRrecv IrReceiver = IRrecv(IR_RX); + + int battery_voltage = 0; + int battery_percentage = 100; + bool battery_ischarging = false; + // LVGL Screen Buffers lv_disp_draw_buf_t mdraw_buf; lv_color_t mbufA[SCREEN_WIDTH * SCREEN_HEIGHT / 10]; lv_color_t mbufB[SCREEN_WIDTH * SCREEN_HEIGHT / 10]; + lv_color_t color_primary = lv_color_hex(0x303030); // gray + + // Keypad declarations + static const byte ROWS = 5; // four rows + static const byte COLS = 5; // four columns + // define the symbols on the buttons of the keypads + char hexaKeys[ROWS][COLS] = { + {'s', '^', '-', 'm', 'r'}, // source, channel+, Volume-, mute, record + {'i', 'r', '+', 'k', 'd'}, // info, right, Volume+, OK, down + {'4', 'v', '1', '3', '2'}, // blue, channel-, red, yellow, green + {'>', 'o', 'b', 'u', 'l'}, // forward, off, back, up, left + {'?', 'p', 'c', '<', '='} // ?, play, config, rewind, stop + }; + byte rowPins[ROWS] = {SW_A, SW_B, SW_C, SW_D, + SW_E}; // connect to the row pinouts of the keypad + byte colPins[COLS] = {SW_1, SW_2, SW_3, SW_4, + SW_5}; // connect to the column pinouts of the keypad + Keypad customKeypad = + Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); + + byte keyMapTechnisat[ROWS][COLS] = {{0x69, 0x20, 0x11, 0x0D, 0x56}, + {0x4F, 0x37, 0x10, 0x57, 0x51}, + {0x6E, 0x21, 0x6B, 0x6D, 0x6C}, + {0x34, 0x0C, 0x22, 0x50, 0x55}, + {'?', 0x35, 0x2F, 0x32, 0x36}}; + byte virtualKeyMapTechnisat[10] = {0x1, 0x2, 0x3, 0x4, 0x5, + 0x6, 0x7, 0x8, 0x9, 0x0}; + + + + + + static std::shared_ptr mInstance; }; \ No newline at end of file diff --git a/Platformio/src/main.cpp b/Platformio/src/main.cpp index ece3567..bd62623 100644 --- a/Platformio/src/main.cpp +++ b/Platformio/src/main.cpp @@ -1,102 +1,14 @@ // OMOTE firmware for ESP32 // 2023 Maximilian Kern -#include -#include -#include -#include -#include // modified for inverted logic -#include -#include +#include #include "HardwareRevX.hpp" #include "OmoteUI/OmoteUI.hpp" #include "omoteconfig.h" std::shared_ptr hal = nullptr; -int battery_voltage = 0; -int battery_percentage = 100; -bool battery_ischarging = false; - -// LCD declarations - -// LVGL declarations - -lv_obj_t *objBattPercentage; -lv_obj_t *objBattIcon; -LV_IMG_DECLARE(gradientLeft); -LV_IMG_DECLARE(gradientRight); -LV_IMG_DECLARE(appleTvIcon); -LV_IMG_DECLARE(appleDisplayIcon); -LV_IMG_DECLARE(appleBackIcon); -LV_IMG_DECLARE(high_brightness); -LV_IMG_DECLARE(low_brightness); -LV_IMG_DECLARE(lightbulb); -lv_obj_t *panel; -lv_color_t color_primary = lv_color_hex(0x303030); // gray - -// Keypad declarations -const byte ROWS = 5; // four rows -const byte COLS = 5; // four columns -// define the symbols on the buttons of the keypads -char hexaKeys[ROWS][COLS] = { - {'s', '^', '-', 'm', 'r'}, // source, channel+, Volume-, mute, record - {'i', 'r', '+', 'k', 'd'}, // info, right, Volume+, OK, down - {'4', 'v', '1', '3', '2'}, // blue, channel-, red, yellow, green - {'>', 'o', 'b', 'u', 'l'}, // forward, off, back, up, left - {'?', 'p', 'c', '<', '='} // ?, play, config, rewind, stop -}; -byte rowPins[ROWS] = {SW_A, SW_B, SW_C, SW_D, - SW_E}; // connect to the row pinouts of the keypad -byte colPins[COLS] = {SW_1, SW_2, SW_3, SW_4, - SW_5}; // connect to the column pinouts of the keypad -Keypad customKeypad = - Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); - -byte keyMapTechnisat[ROWS][COLS] = {{0x69, 0x20, 0x11, 0x0D, 0x56}, - {0x4F, 0x37, 0x10, 0x57, 0x51}, - {0x6E, 0x21, 0x6B, 0x6D, 0x6C}, - {0x34, 0x0C, 0x22, 0x50, 0x55}, - {'?', 0x35, 0x2F, 0x32, 0x36}}; -byte virtualKeyMapTechnisat[10] = {0x1, 0x2, 0x3, 0x4, 0x5, - 0x6, 0x7, 0x8, 0x9, 0x0}; - -// IR declarations -IRsend IrSender(IR_LED, true); -IRrecv IrReceiver(IR_RX); - -#define WIFI_SSID "YOUR_WIFI_SSID" -#define WIFI_PASSWORD "YOUR_WIFI_PASSWORD" -#define MQTT_SERVER "YOUR_MQTT_SERVER_IP" -lv_obj_t *WifiLabel; -WiFiClient espClient; -PubSubClient client(espClient); - -// Helper Functions -// ----------------------------------------------------------------------------------------------------------------------- - -#ifdef ENABLE_WIFI -// WiFi status event -void WiFiEvent(WiFiEvent_t event) { - // Serial.printf("[WiFi-event] event: %d\n", event); - if (event == ARDUINO_EVENT_WIFI_STA_GOT_IP) { - client.setServer(MQTT_SERVER, 1883); // MQTT initialization - client.connect("OMOTE"); // Connect using a client id - } - // Set status bar icon based on WiFi status - if (event == ARDUINO_EVENT_WIFI_STA_GOT_IP || - event == ARDUINO_EVENT_WIFI_STA_GOT_IP6) { - lv_label_set_text(WifiLabel, LV_SYMBOL_WIFI); - } else { - lv_label_set_text(WifiLabel, ""); - } -} -#endif - -// Setup -// ---------------------------------------------------------------------------------------------------------------------------------- - void setup() { hal = HardwareRevX::getInstance(); @@ -105,18 +17,6 @@ void setup() { auto ui = OmoteUI::getInstance(hal); ui->layout_UI(); -#ifdef ENABLE_WIFI - // Setup WiFi - WiFi.setHostname("OMOTE"); // define hostname - WiFi.onEvent(WiFiEvent); - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); - WiFi.setSleep(true); -#endif - - // Setup IR - IrSender.begin(); - digitalWrite(IR_VCC, HIGH); // Turn on IR receiver - IrReceiver.enableIRIn(); // Start the receiver lv_timer_handler(); // Run the LVGL UI once before the loop takes over @@ -125,95 +25,14 @@ void setup() { Serial.println("ms."); } -// Loop -// ------------------------------------------------------------------------------------------------------------------------------------ - void loop() { - // Update Backlight brightness - static int fadeInTimer = millis(); // fadeInTimer = time after setup - if (millis() < - fadeInTimer + - hal->backlight_brightness) { // Fade in the backlight brightness - ledcWrite(5, millis() - fadeInTimer); - } else { // Dim Backlight before entering standby - if (hal->standbyTimer < 2000) - ledcWrite(5, 85); // Backlight dim - else - ledcWrite(5, hal->backlight_brightness); // Backlight on - } - - // Update LVGL UI - lv_timer_handler(); - - // Blink debug LED at 1 Hz - digitalWrite(USER_LED, millis() % 1000 > 500); - - // Refresh IMU data at 10Hz - static unsigned long IMUTaskTimer = millis(); - if (millis() - IMUTaskTimer >= 100) { - hal->activityDetection(); - if (hal->standbyTimer == 0) { - Serial.println("Entering Sleep Mode. Goodbye."); - hal->enterSleep(); - } - IMUTaskTimer = millis(); - } - - // Update battery stats at 1Hz - static unsigned long batteryTaskTimer = - millis() + 1000; // add 1s to start immediately - if (millis() - batteryTaskTimer >= 1000) { - battery_voltage = - analogRead(ADC_BAT) * 2 * 3300 / 4095 + 350; // 350mV ADC offset - battery_percentage = - constrain(map(battery_voltage, 3700, 4200, 0, 100), 0, 100); - batteryTaskTimer = millis(); - battery_ischarging = !digitalRead(CRG_STAT); - // Check if battery is charging, fully charged or disconnected - if (battery_ischarging || (!battery_ischarging && battery_voltage > 4350)) { - lv_label_set_text(objBattPercentage, ""); - lv_label_set_text(objBattIcon, LV_SYMBOL_USB); - } else { - // Update status bar battery indicator - // lv_label_set_text_fmt(objBattPercentage, "%d%%", battery_percentage); - if (battery_percentage > 95) - lv_label_set_text(objBattIcon, LV_SYMBOL_BATTERY_FULL); - else if (battery_percentage > 75) - lv_label_set_text(objBattIcon, LV_SYMBOL_BATTERY_3); - else if (battery_percentage > 50) - lv_label_set_text(objBattIcon, LV_SYMBOL_BATTERY_2); - else if (battery_percentage > 25) - lv_label_set_text(objBattIcon, LV_SYMBOL_BATTERY_1); - else - lv_label_set_text(objBattIcon, LV_SYMBOL_BATTERY_EMPTY); - } - } - - // Keypad Handling - customKeypad.getKey(); // Populate key list - for (int i = 0; i < LIST_MAX; - i++) { // Handle multiple keys (Not really necessary in this case) - if (customKeypad.key[i].kstate == PRESSED || - customKeypad.key[i].kstate == HOLD) { - hal->standbyTimer = - SLEEP_TIMEOUT; // Reset the sleep timer when a button is pressed - int keyCode = customKeypad.key[i].kcode; - Serial.println(customKeypad.key[i].kchar); - // Send IR codes depending on the current device (tabview page) - if (hal->currentDevice == 1) - IrSender.sendRC5(IrSender.encodeRC5X( - 0x00, keyMapTechnisat[keyCode / ROWS][keyCode % ROWS])); - else if (hal->currentDevice == 2) - IrSender.sendSony((keyCode / ROWS) * (keyCode % ROWS), 15); - } - } - + HardwareRevX::getInstance()->handleLoop(); // IR Test // tft.drawString("IR Command: ", 10, 90, 1); // decode_results results; // if (IrReceiver.decode(&results)) { - // //tft.drawString(String(results.command) + " ", 80, 90, 1); - // IrReceiver.resume(); // Enable receiving of the next value - //} + // IrReceiver.resume(); // Enable receiving of the next value + //} //tft.drawString(String(results.command) + " ", 80, 90, 1); + // } \ No newline at end of file