diff --git a/board_single/main/control.cpp b/board_single/main/control.cpp index 9d9c914..7ebd887 100644 --- a/board_single/main/control.cpp +++ b/board_single/main/control.cpp @@ -12,6 +12,7 @@ extern "C" #include "config.h" #include "control.hpp" #include "chairAdjust.hpp" +#include "display.hpp" // needed for getBatteryPercent() //used definitions moved from config.h: @@ -338,6 +339,7 @@ void controlledArmchair::resetTimeout(){ // notify "power still on" when in IDLE for a very long time (prevent battery drain when forgotten to turn off) // this function has to be run repeatedly (can be slow interval) #define TIMEOUT_POWER_STILL_ON_BEEP_INTERVAL_MS 5 * 60 * 1000 // beep every 5 minutes for someone to notice +#define TIMEOUT_POWER_STILL_ON_BATTERY_THRESHOLD_PERCENT 96 // only notify/beep when below certain percentage (prevent beeping when connected to charger) // note: timeout durations are configured in config.cpp void controlledArmchair::handleTimeout() { @@ -349,6 +351,7 @@ void controlledArmchair::handleTimeout() config.timeoutSwitchToIdleMs / 1000, config.timeoutNotifyPowerStillOnMs / 1000 / 60 / 60); + // -- timeout switch to IDLE -- // timeout to IDLE when not idling already if (mode != controlMode_t::IDLE && noActivityDurationMs > config.timeoutSwitchToIdleMs) { @@ -356,15 +359,18 @@ void controlledArmchair::handleTimeout() changeMode(controlMode_t::IDLE); //TODO switch to previous status-screen when activity detected } + + // -- timeout notify "forgot to turn off" -- // repeatedly notify via buzzer when in IDLE for a very long time to prevent battery drain ("forgot to turn off") - // note: ignores user input while in IDLE - else if ((esp_log_timestamp() - timestamp_lastModeChange) > config.timeoutNotifyPowerStillOnMs) + // also battery charge-level has to be below certain threshold to prevent beeping in case connected to charger + // note: ignores user input while in IDLE (e.g. encoder rotation) + else if ((esp_log_timestamp() - timestamp_lastModeChange) > config.timeoutNotifyPowerStillOnMs && getBatteryPercent() < TIMEOUT_POWER_STILL_ON_BATTERY_THRESHOLD_PERCENT) { // beep in certain intervals if ((esp_log_timestamp() - timestamp_lastTimeoutBeep) > TIMEOUT_POWER_STILL_ON_BEEP_INTERVAL_MS) { ESP_LOGW(TAG, "timeout: [TIMEOUT] in IDLE since %.3f hours -> beeping", (float)(esp_log_timestamp() - timestamp_lastModeChange) / 1000 / 60 / 60); - // TODO dont beep at certain times ranges (e.g. at night) + // TODO dont beep at certain time ranges (e.g. at night) timestamp_lastTimeoutBeep = esp_log_timestamp(); buzzer->beep(6, 100, 50); } @@ -407,6 +413,11 @@ void controlledArmchair::changeMode(controlMode_t modeNew) { buzzer->beep(1,200,100); break; + case controlMode_t::HTTP: + ESP_LOGW(TAG, "switching from HTTP mode -> stopping wifi-ap"); + wifi_stop_ap(); + break; + case controlMode_t::MASSAGE: ESP_LOGW(TAG, "switching from MASSAGE mode -> restoring fading, reset frozen input"); //TODO: fix issue when downfading was disabled before switching to massage mode - currently it gets enabled again here... @@ -454,6 +465,11 @@ void controlledArmchair::changeMode(controlMode_t modeNew) { buzzer->beep(1, 900, 0); break; + case controlMode_t::HTTP: + ESP_LOGW(TAG, "switching to HTTP mode -> starting wifi-ap"); + wifi_start_ap(); + break; + case controlMode_t::ADJUST_CHAIR: ESP_LOGW(TAG, "switching to ADJUST_CHAIR mode: turning both motors off, beep"); idleBothMotors(); diff --git a/board_single/main/display.hpp b/board_single/main/display.hpp index 4646dc0..a4fb8c6 100644 --- a/board_single/main/display.hpp +++ b/board_single/main/display.hpp @@ -59,6 +59,9 @@ typedef enum displayStatusPage_t {STATUS_SCREEN_OVERVIEW=0, STATUS_SCREEN_SPEED, // get precise battery voltage (using lookup table) float getBatteryVoltage(); +// get battery charge level in percent (using lookup table as discharge curve) +float getBatteryPercent(); + // function to select one of the defined status screens which are shown on display when not in MENU mode void display_selectStatusPage(displayStatusPage_t newStatusPage); diff --git a/board_single/main/main.cpp b/board_single/main/main.cpp index 0a121c1..57d10c5 100644 --- a/board_single/main/main.cpp +++ b/board_single/main/main.cpp @@ -107,7 +107,6 @@ nvs_handle_t nvsHandle; //================================= //initialize spi flash filesystem (used for webserver) void init_spiffs(){ - ESP_LOGW(TAG, "initializing spiffs..."); esp_vfs_spiffs_conf_t esp_vfs_spiffs_conf = { .base_path = "/spiffs", .partition_label = NULL, @@ -194,35 +193,29 @@ extern "C" void app_main(void) { gpio_set_direction(GPIO_NUM_17, GPIO_MODE_OUTPUT); gpio_set_level(GPIO_NUM_17, 1); - //--- initialize nvs-flash and netif (needed for wifi) --- - ESP_LOGW(TAG,"initializing wifi..."); - wifi_initNvs_initNetif(); + //--- initialize nvs-flash and netif --- + ESP_LOGW(TAG,"initializing NVS..."); + wifi_initNvs(); //needed for wifi and persistent config variables + ESP_LOGW(TAG,"initializing NETIF..."); + wifi_initNetif(); // needed for wifi //--- initialize spiffs --- - init_spiffs(); + ESP_LOGW(TAG, "initializing SPIFFS..."); + init_spiffs(); // used by httpd server //--- initialize and start wifi --- - ESP_LOGW(TAG,"starting wifi..."); - //wifi_init_client(); //connect to existing wifi - wifi_init_ap(); //start access point - ESP_LOGD(TAG,"done starting wifi"); + // Note: now started only when switching to HTTP mode in control.cpp + // ESP_LOGW(TAG,"starting wifi..."); + // wifi_start_client(); //connect to existing wifi (dropped) + // wifi_start_ap(); //start access point //--- initialize encoder --- const QueueHandle_t encoderQueue = encoder_init(&encoder_config); - //--- initialize nvs-flash --- (for persistant config values) - ESP_LOGW(TAG, "initializing nvs-flash..."); - esp_err_t err = nvs_flash_init(); - if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) - { - ESP_LOGE(TAG, "NVS truncated -> deleting flash"); - // Retry nvs_flash_init - ESP_ERROR_CHECK(nvs_flash_erase()); - err = nvs_flash_init(); - } - ESP_ERROR_CHECK(err); //--- open nvs-flash --- - err = nvs_open("storage", NVS_READWRITE, &nvsHandle); + // note: nvs already initialized in wifi_initNvs() + ESP_LOGW(TAG, "opening NVS-handle..."); + esp_err_t err = nvs_open("storage", NVS_READWRITE, &nvsHandle); // this handle is passed to all tasks for accessing nvs if (err != ESP_OK) ESP_LOGE(TAG, "Error (%s) opening NVS handle!\n", esp_err_to_name(err)); diff --git a/common/wifi.c b/common/wifi.c index 27eb3db..557abfc 100644 --- a/common/wifi.c +++ b/common/wifi.c @@ -21,26 +21,45 @@ static const char *TAG = "wifi"; static esp_event_handler_instance_t instance_any_id; -//============================================ -//============ init nvs and netif ============ -//============================================ -//initialize nvs-flash and netif (needed for both AP and CLIENT) +//########################################## +//############ common functions ############ +//########################################## + +//============================ +//========= init nvs ========= +//============================ +//initialize nvs-flash (needed for both AP and CLIENT) //has to be run once at startup -void wifi_initNvs_initNetif(){ +void wifi_initNvs(){ //Initialize NVS (needed for wifi) - esp_err_t ret = nvs_flash_init(); - if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { - ESP_ERROR_CHECK(nvs_flash_erase()); - ret = nvs_flash_init(); - } + esp_err_t err = nvs_flash_init(); + if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) + { + ESP_LOGE(TAG, "NVS truncated -> deleting flash"); + // Retry nvs_flash_init + ESP_ERROR_CHECK(nvs_flash_erase()); + err = nvs_flash_init(); + } + ESP_ERROR_CHECK(err); +} + + +//============================== +//========= init netif ========= +//============================== +//initialize netif (needed for both AP and CLIENT) +//has to be run once at startup +void wifi_initNetif(){ ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); } -//=========================================== -//============ init access point ============ -//=========================================== + + +//############################################ +//############### access point ############### +//############################################ //-------------------------------------------- //------ configuration / declarations -------- @@ -66,10 +85,12 @@ static void wifi_event_handler_ap(void* arg, esp_event_base_t event_base, } } -//----------------------- -//------ init ap -------- -//----------------------- -void wifi_init_ap(void) + + +//======================== +//====== start AP ======== +//======================== +void wifi_start_ap(void) { ap = esp_netif_create_default_wifi_ap(); @@ -107,9 +128,9 @@ void wifi_init_ap(void) //============================= -//========= deinit AP ========= +//========== stop AP ========== //============================= -void wifi_deinit_ap(void) +void wifi_stop_ap(void) { ESP_ERROR_CHECK(esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, instance_any_id)); ESP_ERROR_CHECK(esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, instance_any_id)); @@ -123,9 +144,9 @@ void wifi_deinit_ap(void) -//=========================================== -//=============== init client =============== -//=========================================== +//########################################## +//################# client ################# +//########################################## //-------------------------------------------- //------ configuration / declarations -------- @@ -168,10 +189,13 @@ static void event_handler(void* arg, esp_event_base_t event_base, xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); } } -//--------------------------- -//------ init client -------- -//--------------------------- -void wifi_init_client(void) + + + +//=========================== +//====== init client ======== +//=========================== +void wifi_start_client(void) { s_wifi_event_group = xEventGroupCreate(); sta = esp_netif_create_default_wifi_sta(); @@ -249,10 +273,10 @@ void wifi_init_client(void) -//================================= -//========= deinit client ========= -//================================= -void wifi_deinit_client(void) +//=============================== +//========= stop client ========= +//=============================== +void wifi_stop_client(void) { /* The event will not be processed after unregister */ ESP_ERROR_CHECK(esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, instance_got_ip)); diff --git a/common/wifi.h b/common/wifi.h index 39eecee..d65a3bf 100644 --- a/common/wifi.h +++ b/common/wifi.h @@ -3,20 +3,20 @@ //TODO: currently wifi names and passwords are configured in wifi.c -> move this to config? //initialize nvs-flash and netif (needed for both AP and CLIENT) -//has to be run once at startup -//Note: this cant be put in wifi_init functions because this may not be in deinit functions -void wifi_initNvs_initNetif(); +//both functions have to be run once at startup +void wifi_initNvs(); +void wifi_initNetif(); -//function to start an access point -void wifi_init_ap(void); -//function to disable/deinit access point -void wifi_deinit_ap(void); +//function to start an access point (config in wifi.c) +void wifi_start_ap(void); +//function to disable/stop access point +void wifi_stop_ap(void); -//function to connect to existing wifi network -void wifi_init_client(void); +//function to connect to existing wifi network (config in wifi.c) +void wifi_start_client(void); //function to disable/deinit client -void wifi_deinit_client(void); +void wifi_stop_client(void);