From e2138764acb4ca1709212ef13994e5aac0cb36c4 Mon Sep 17 00:00:00 2001 From: Thomas Bittner Date: Thu, 10 Aug 2023 20:41:55 +0200 Subject: [PATCH] Added new interface abstract classes --- Platformio/HAL/Interface/BatteryInterface.h | 9 + Platformio/HAL/Interface/DisplayInterface.h | 18 ++ .../HAL/Interface/wifiHandlerInterface.h | 15 + .../HAL/Targets/ESP32/battery/battery.cpp | 38 +++ .../HAL/Targets/ESP32/battery/battery.hpp | 62 ++++ .../HAL/Targets/ESP32/display/display.cpp | 0 .../HAL/Targets/ESP32/display/display.hpp | 305 ++++++++++++++++++ .../Targets/ESP32/wifiHandler/wifihandler.cpp | 150 +++++++++ .../Targets/ESP32/wifiHandler/wifihandler.hpp | 114 +++++++ 9 files changed, 711 insertions(+) create mode 100644 Platformio/HAL/Interface/BatteryInterface.h create mode 100644 Platformio/HAL/Interface/DisplayInterface.h create mode 100644 Platformio/HAL/Interface/wifiHandlerInterface.h create mode 100644 Platformio/HAL/Targets/ESP32/battery/battery.cpp create mode 100644 Platformio/HAL/Targets/ESP32/battery/battery.hpp create mode 100644 Platformio/HAL/Targets/ESP32/display/display.cpp create mode 100644 Platformio/HAL/Targets/ESP32/display/display.hpp create mode 100644 Platformio/HAL/Targets/ESP32/wifiHandler/wifihandler.cpp create mode 100644 Platformio/HAL/Targets/ESP32/wifiHandler/wifihandler.hpp diff --git a/Platformio/HAL/Interface/BatteryInterface.h b/Platformio/HAL/Interface/BatteryInterface.h new file mode 100644 index 0000000..60a9a3f --- /dev/null +++ b/Platformio/HAL/Interface/BatteryInterface.h @@ -0,0 +1,9 @@ + +class BatteryInterface { + public: + virtual void setup(DisplayInterface& display, int adc_pin, int charging_pin) = 0; + virtual int getPercentage() = 0; + virtual bool isCharging() = 0; + virtual bool isConnected() = 0; + virtual void update() = 0; +}; \ No newline at end of file diff --git a/Platformio/HAL/Interface/DisplayInterface.h b/Platformio/HAL/Interface/DisplayInterface.h new file mode 100644 index 0000000..a9d79da --- /dev/null +++ b/Platformio/HAL/Interface/DisplayInterface.h @@ -0,0 +1,18 @@ +#pragma once + +class DisplayInterface +{ + public: + virtual void setup() = 0; + virtual void setup_ui() = 0; + virtual void flush() = 0; + virtual void wifi_scan_complete(unsigned int size) = 0; + virtual void clear_wifi_networks() = 0; + virtual void update_wifi(bool connected) = 0; + virtual void hide_keyboard() = 0; + virtual void show_keyboard() = 0; + virtual void updated() = 0; + virtual void reset_settings_menu() = 0; + virtual void update_battery(int percentage, bool isCharging, bool isConnected) = 0; + virtual void turnOff() = 0; +} \ No newline at end of file diff --git a/Platformio/HAL/Interface/wifiHandlerInterface.h b/Platformio/HAL/Interface/wifiHandlerInterface.h new file mode 100644 index 0000000..b69db91 --- /dev/null +++ b/Platformio/HAL/Interface/wifiHandlerInterface.h @@ -0,0 +1,15 @@ +#pragma once +#include +#include "DisplayInterface.h" + +class wifiHandlerInterface{ + public: + virtual void begin(DisplayInterface& display) = 0; + virtual void connect(const char* SSID, const char* password) = 0; + virtual void disconnect() = 0; + virtual bool isConnected() = 0; + virtual void turnOff() = 0; + virtual void scan() = 0; + virtual char* getSSID() = 0; + virtual String getIP() = 0; +}; \ No newline at end of file diff --git a/Platformio/HAL/Targets/ESP32/battery/battery.cpp b/Platformio/HAL/Targets/ESP32/battery/battery.cpp new file mode 100644 index 0000000..9901741 --- /dev/null +++ b/Platformio/HAL/Targets/ESP32/battery/battery.cpp @@ -0,0 +1,38 @@ +#include "battery.hpp" +#include + +void Battery::setup(DisplayInterface& display, int adc_pin, int charging_pin) +{ + this->display = display; + this->adc_pin = adc_pin; + this->charging_pin = charging_pin; + // Power Pin Definition + pinMode(this->charging_pin, INPUT_PULLUP); + pinMode(this->adc_pin, INPUT); +} + +int Battery::getPercentage() +{ + return constrain(map(this->getVoltage(), 3700, 4200, 0, 100), 0, 100); +} + +bool Battery::isCharging() +{ + return !digitalRead(this->charging_pin); +} + +bool Battery::isConnected() +{ + return ((!this->isCharging()) && (this->getVoltage() < 4350)); +} + +int Battery::getVoltage() +{ + return analogRead(this->adc_pin)*2*3300/4095 + 350; +} + +void Battery::update() +{ + display.update_battery(this->getPercentage(), this->isCharging(), this->isConnected()); + +} \ No newline at end of file diff --git a/Platformio/HAL/Targets/ESP32/battery/battery.hpp b/Platformio/HAL/Targets/ESP32/battery/battery.hpp new file mode 100644 index 0000000..df56e63 --- /dev/null +++ b/Platformio/HAL/Targets/ESP32/battery/battery.hpp @@ -0,0 +1,62 @@ +#pragma once +#include "BatteryInterface.h" +#include "DisplayInterface.h" + +class Battery: public BatteryInterface { + public: + + + + void setup(DisplayInterface& display, int adc_pin, int charging_pin); + /** + * @brief Get the Percentage of the battery + * + * @return int Percentage of the battery + */ + int getPercentage(); + + /** + * @brief Function to determine if the battery is charging or not + * + * @return true Battery is currently charging + * @return false Battery is currently not charging + */ + bool isCharging(); + + /** + * @brief Function to determine if the battery is connected + * + * @return true Battery is connected + * @return false Battery is not connected + */ + bool isConnected(); + + /** + * @brief Function to update the battery status. This should be called on a regular basis + * + */ + void update(); + private: + Battery(); + /** + * @brief Function to get the current voltage of the battery + * + * @return int Voltage of the battery in mV + */ + int getVoltage(); + + /** + * @brief Variable to store which pin should be used for ADC + * + */ + int adc_pin; + + /** + * @brief Variable to store which pin is used to inidicate if the battery is currently charging or not + * + */ + int charging_pin; + + + DisplayInterface& display; +}; \ No newline at end of file diff --git a/Platformio/HAL/Targets/ESP32/display/display.cpp b/Platformio/HAL/Targets/ESP32/display/display.cpp new file mode 100644 index 0000000..e69de29 diff --git a/Platformio/HAL/Targets/ESP32/display/display.hpp b/Platformio/HAL/Targets/ESP32/display/display.hpp new file mode 100644 index 0000000..fd08c9d --- /dev/null +++ b/Platformio/HAL/Targets/ESP32/display/display.hpp @@ -0,0 +1,305 @@ +#pragma once +#include "DisplayInterface.h" +#include +#include +#include +#include "driver/ledc.h" + +class Display:public DisplayInterface +{ + public: + static Display* getInstance(); + /** + * @brief Function to setup the display. + * + */ + void setup(); + + /** + * @brief Function to setup the user interface. This function has to be called after setup. + * + */ + void setup_ui(); + + /** + * @brief Function to flush the display (update what is shown on the LCD). This function is called within + * the LVGL callback function + * + * @param disp + * @param area + * @param color_p + */ + void flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p ); + + + /** + * @brief API function to inform display that wifi scan is completed + * + * @param size number of wifi networks found + */ + void wifi_scan_complete(unsigned int size); + + /** + * @brief Clear the wifi networks listed in the wifi selection page. This function is called before new wifi + * networks are added to the list to avoid double listing + * + */ + void clear_wifi_networks(); + + /** + * @brief Update the wifi status. This function will update the wifi label in the status bar according to the + * parameter. + * + * @param connected Boolean parameter to indicate if a wifi connection is established or not. + */ + void update_wifi(bool connected); + + + /** + * @brief API function which needs to be called regularly to update the display + * + */ + void update(); + + + /** + * @brief Function to update the battery indicator on the display + * + * @param percentage Battery percentage + * @param isCharging True if the battery is charging. False otherwise + * @param isConnected True if a battery is connected, false otherwise + */ + void update_battery(int percentage, bool isCharging, bool isConnected); + + void turnOff(); + private: + /** + * @brief Function to change the settings menu to main page again. + * + */ + void reset_settings_menu(); + /** + * @brief Function to hide the keyboard. If the keyboard is attached to a text area, it will be hidden when the + * text area is defocused. This function can be used if the keyboard need to be hidden due to some script event. + * + */ + void hide_keyboard(); + + /** + * @brief Function to show the keyboard. If a text area needs the keybaord, it should be attached to the text area + * using the approbiate function. The keyboard will then show up when the text area is focused. This function is + * needed if the keyboard should be shown due to some script or other trigger. + * + */ + void show_keyboard(); + Display(); + /** + * @brief Pin used for LCD backlight control + * + */ + int backlight_pin; + + /** + * @brief Pin used to enable the LCD + * + */ + int enable_pin; + + /** + * @brief Width of the display in pixel + * + */ + int width; + + /** + * @brief Height of the display in pixel + * + */ + int height; + + /** + * @brief Pointer to the buffer used for drawing on the screen + * + */ + lv_color_t *bufA; + + /** + * @brief Pointer to the buffer used for drawing on the screen + * + */ + lv_color_t *bufB; + + /** + * @brief Object of the touch input driver + * + */ + Adafruit_FT6206 touch; + /** + * @brief Keyboard object used whenever a keyboard is needed. + * + */ + lv_obj_t* kb; + + /** + * @brief Variable to store the primary color + * + */ + lv_color_t primary_color; + + /** + * @brief Object of the TFT driver + * + */ + TFT_eSPI tft; + + /** + * @brief Set the up settings object + * + * @param parent + */ + void setup_settings(lv_obj_t* parent); + + /** + * @brief Function to create the keyboard object which can then be attached to different text areas. + * + */ + void create_keyboard(); + + /** + * @brief Function to attach the keyboard to a text area. If the text area is selected, the keyboard + * is shown and if the textarea is defocused, the keyboard will be hidden again. + * + * @param textarea Textarea where the keyboard should be attached to. + */ + void attach_keyboard(lv_obj_t* textarea); + + /** + * @brief LVGL Menu for settings pages as needed. + * + */ + lv_obj_t* settingsMenu; + + /** + * @brief Main page of the settings menu + * + */ + lv_obj_t* settingsMainPage; + + /** + * @brief Battery percentage label + * + */ + lv_obj_t* objBattPercentage; + + /** + * @brief Battery icon object in the status bar + * + */ + lv_obj_t* objBattIcon; + +/************************************** WIFI Settings Menu *******************************************************/ + /** + * @brief Container within the wifi selection page + */ + lv_obj_t* wifi_setting_cont; + + /** + * @brief Wifi settings entry point on the settings tab + * + */ + lv_obj_t* wifiOverview; + + /** + * @brief Label in the wifi password page. This label is updated with the selected SSID when the credentials for + * a wifi network is entered. + * + */ + lv_obj_t* wifi_password_label; + + /** + * @brief Menu Subpage for the wifi password + */ + lv_obj_t* wifi_password_page; + + /** + * @brief Menu Subpage for wifi selection + */ + lv_obj_t* wifi_selection_page; + + /** + * @brief Wifi Label shown in the top status bar + */ + lv_obj_t* WifiLabel; + + /** + * @brief Number of wifi subpage needed to display the found wifi networks + * + */ + unsigned int no_subpages; + + /** + * @brief number of wifi networks found + * + */ + unsigned int no_wifi_networks; + + + /** + * @brief callback function to get next wifi subpage. This callback can be used to get the next or previous page + * + * @param e lvgl event object + */ + void next_wifi_selection_subpage(lv_event_t* e); + + /** + * @brief Create a wifi selection sub page object + * + * @param menu LVGL Menu where the sub page should be added to + * @return lv_obj_t* Menu sub page object pointer + */ + lv_obj_t* create_wifi_selection_page(lv_obj_t* menu); + + /** + * @brief Method to create the wifi password sub page + * + * @param menu Menu where the sub page should be created + * @return lv_obj_t* menu sub page object pointer + */ + lv_obj_t* create_wifi_password_page(lv_obj_t* menu); + + /** + * @brief Method to create the wifi settings on the main page + * + * @param parent lv object parent where the main settings page should be added to + */ + void create_wifi_main_page(lv_obj_t* parent); + + /** + * @brief Method to create wifi settings. This method will call the create_wifi_selection_page, + * the create_wifi_password_page, and the create_wifi_main_page + * + * @param menu Settings menu where the sub pages should be added to + * @param parent lv object parent where the main settings page should be added to + */ + void create_wifi_settings(lv_obj_t* menu, lv_obj_t* parent); + + /** + * @brief Function to update the wifi selection sub page + * + * @param page index of the page to display + */ + void update_wifi_selection_subpage(int page); + +/************************************** Display settings menu ********************************************************/ + /** + * Variable to store the current backlight brightness level + */ + unsigned int backlight_brightness; + + /** + * @brief Function to create the display settings page. + * + * @param parent LVGL object acting as a parent for the display settings page + */ + void display_settings(lv_obj_t* parent); +}; \ No newline at end of file diff --git a/Platformio/HAL/Targets/ESP32/wifiHandler/wifihandler.cpp b/Platformio/HAL/Targets/ESP32/wifiHandler/wifihandler.cpp new file mode 100644 index 0000000..38ec360 --- /dev/null +++ b/Platformio/HAL/Targets/ESP32/wifiHandler/wifihandler.cpp @@ -0,0 +1,150 @@ +#include "wifihandler.hpp" +#include +#include + +wifiHandler* mInstance; + +// WiFi status event +void wifiHandler::WiFiEvent(WiFiEvent_t event){ + int no_networks = 0; + switch (event) + { + case ARDUINO_EVENT_WIFI_SCAN_DONE: + Serial.println("WIFI scan done\n"); + no_networks = WiFi.scanComplete(); + if (no_networks < 0) + { + Serial.println("Scan failed"); + } + else + { + this->display.clear_wifi_networks(); + Serial.print(no_networks); + Serial.print(" found\n"); + this->display.wifi_scan_complete( no_networks); + } + break; + case ARDUINO_EVENT_WIFI_STA_GOT_IP: + case ARDUINO_EVENT_WIFI_STA_GOT_IP6: + display.update_wifi(true); + this->update_credentials(temporary_ssid, temporary_password); + break; + case ARDUINO_EVENT_WIFI_STA_DISCONNECTED: + case ARDUINO_EVENT_WIFI_STA_LOST_IP: + case ARDUINO_EVENT_WIFI_STA_STOP: + display.update_wifi(false); + default: + break; + } +} + +wifiHandler* wifiHandler::getInstance() +{ + if(instance == nullptr) + { + instance = new wifiHandler(); + } + + return instance; +} + +String wifiHandler::getFoundSSID(unsigned int index) +{ + return WiFi.SSID(index); +} + +int wifiHandler::getFoundRSSI(unsigned int index) +{ + return WiFi.RSSI(index); +} + +wifiHandler::wifiHandler() +{ + this->password[0] = '\0'; + this->SSID[0] = '\0'; +} + +void wifiHandler::update_credentials(const char* temporary_ssid, const char* temporary_password) +{ + if (strcmp(temporary_password, wifiHandler::password) != 0 || strcmp(temporary_ssid, wifiHandler::SSID) != 0) + { + strcpy(wifiHandler::password, temporary_password); + strcpy(wifiHandler::SSID, temporary_ssid); + + Preferences preferences; + preferences.begin("wifiSettings", false); + String tempString = wifiHandler::password; + preferences.putString("password", tempString); + tempString = wifiHandler::SSID; + preferences.putString("SSID", tempString); + preferences.end(); + } +} + +void wifiHandler::scan() +{ + WiFi.scanNetworks(true); +} + +void wifiHandler::begin(DisplayInterface& display) +{ + this->display = display; + mInstance = wifiHandler::getInstance(); + WiFi.setHostname("OMOTE"); + WiFi.mode(WIFI_STA); + WiFi.onEvent([] (WiFiEvent_t event) {mInstance->WiFiEvent(event);}); + + Preferences preferences; + preferences.begin("wifiSettings",false); + String ssid = preferences.getString("SSID"); + String password = preferences.getString("password"); + preferences.end(); + + /* If the SSID is not empty, there was a value stored in the preferences and we try to use it.*/ + if (!ssid.isEmpty()) + { + Serial.print("Connecting to wifi "); + Serial.println(ssid); + strcpy(this->SSID, ssid.c_str()); + strcpy(this->password, password.c_str()); + this->connect(this->SSID, this->password); + } + else + { + Serial.println("no SSID or password stored"); + /*Set first character to \0 indicates an empty string*/ + this->SSID[0] = '\0'; + this->password[0] = '\0'; + WiFi.disconnect(); + } + + WiFi.setSleep(true); +} + +void wifiHandler::connect(const char* SSID, const char* password) +{ + strncpy(this->temporary_password, password, STRING_SIZE); + strncpy(this->temporary_ssid, SSID, STRING_SIZE); + WiFi.begin(SSID, password); +} + +void wifiHandler::turnOff() +{ + WiFi.disconnect(); + WiFi.mode(WIFI_OFF); +} + +bool wifiHandler::isConnected() +{ + return WiFi.isConnected(); +} + +char* wifiHandler::getSSID() +{ + return this->SSID; +} + +String wifiHandler::getIP() +{ + return WiFi.localIP().toString(); +} \ No newline at end of file diff --git a/Platformio/HAL/Targets/ESP32/wifiHandler/wifihandler.hpp b/Platformio/HAL/Targets/ESP32/wifiHandler/wifihandler.hpp new file mode 100644 index 0000000..7b2f734 --- /dev/null +++ b/Platformio/HAL/Targets/ESP32/wifiHandler/wifihandler.hpp @@ -0,0 +1,114 @@ +#pragma once +#include "wifiHandlerInterface.h" +#include + +#define STRING_SIZE 50 + +class wifiHandler: public wifiHandlerInterface { + public: + static wifiHandler* getInstance(); + /** + * @brief Function to initialize the wifi handler + * + */ + void begin(DisplayInterface& display); + + /** + * @brief Connect to the wifi using the provided credetials + * + * @param SSID + * @param password + */ + void connect(const char* SSID, const char* password); + + /** + * @brief Function to disconnect from the network + * + */ + void disconnect(); + + /** + * @brief Get the SSID of the found wifi + * + * @param index index of the found wifi + * @return String SSID of the wifi + */ + String getFoundSSID(unsigned int index); + + /** + * @brief Get the RSSI of the found wifi + * + * @param index index of the found wifi + * @return int RSSI value of the found wifi + */ + int getFoundRSSI(unsigned int index); + + /** + * @brief Function to determine wether or not we are connected to a network + * + * @return true Device is connected to wifi network + * @return false Device is not connected to wifi network + */ + bool isConnected(); + + /** + * @brief Function to turn off wifi + * + */ + void turnOff(); + + /** + * @brief function to trigger asynchronous scan for wifi networks + * + */ + void scan(); + + /** + * @brief Function to get SSID of the currently connected wifi network + * + * @return char* SSID of the currently connected network + */ + char* getSSID(); + + /** + * @brief Function to update the wifi credentials. This function is called in the wifi event callback function + * after a connection is established. Only then is the new credentials stored and the old stored credentials + * overwritten. + * + * @param temporary_ssid + * @param temporary_password + */ + static void update_credentials(const char* temporary_ssid, const char* temporary_password); + + void WiFiEvent(WiFiEvent_t event); + + /** + * @brief Function to get the IP address of this device + * + * @return String IP Address of the device + */ + String getIP(); + private: + + static wifiHandler* instance; + + static char temporary_password[STRING_SIZE]; + static char temporary_ssid[STRING_SIZE]; + + DisplayInterface& display; + + wifiHandler(); + + /** + * @brief Internal variable to store the wifi password + * + */ + static char password[STRING_SIZE]; + + /** + * @brief Internal variable to store the wifi SSID + * + */ + static char SSID[STRING_SIZE]; + +}; \ No newline at end of file