Basic multi profile implementation

This commit is contained in:
2020-09-19 21:25:58 +02:00
parent bcb8b8c601
commit 753c55443a
7 changed files with 92 additions and 16 deletions

View File

@@ -16,6 +16,7 @@ framework = arduino
lib_deps = lib_deps =
TFT_eSPI TFT_eSPI
https://github.com/Ferdi265/cxx-ring-buffer https://github.com/Ferdi265/cxx-ring-buffer
https://github.com/TartanLlama/optional
lib_compat_mode = strict lib_compat_mode = strict
build_unflags = build_unflags =

View File

@@ -11,7 +11,7 @@
#include "display.h" #include "display.h"
#include "modeinterface.h" #include "modeinterface.h"
#include "settings.h" #include "settings.h"
#include "settingssaver.h" #include "settingspersister.h"
#include "types.h" #include "types.h"
namespace { namespace {
@@ -26,7 +26,7 @@ float avgSpeed, avgSpeedKmh, sumCurrent;
char deviceName[32]; char deviceName[32];
Settings settings; Settings settings;
SettingsSaver settingsSaver; SettingsPersister settingsPersister;
constexpr auto TFT_GREY = 0x5AEB; constexpr auto TFT_GREY = 0x5AEB;

View File

@@ -48,18 +48,22 @@ void setup()
initScreen(); initScreen();
#ifdef FEATURE_DPAD #ifdef FEATURE_DPAD
bootLabel.redraw("dpad");
dpad::init(); dpad::init();
#endif #endif
#ifdef FEATURE_DPAD_3WIRESW #ifdef FEATURE_DPAD_3WIRESW
bootLabel.redraw("dpad3wire");
dpad3wire::init(); dpad3wire::init();
#endif #endif
#ifdef FEATURE_ROTARY #ifdef FEATURE_ROTARY
bootLabel.redraw("rotary");
initRotary(); initRotary();
#endif #endif
#ifdef FEATURE_MOSFETS #ifdef FEATURE_MOSFETS
bootLabel.redraw("mosfets");
pinMode(PINS_MOSFET0, OUTPUT); pinMode(PINS_MOSFET0, OUTPUT);
pinMode(PINS_MOSFET1, OUTPUT); pinMode(PINS_MOSFET1, OUTPUT);
pinMode(PINS_MOSFET2, OUTPUT); pinMode(PINS_MOSFET2, OUTPUT);
@@ -69,45 +73,70 @@ void setup()
digitalWrite(PINS_MOSFET2, LOW); digitalWrite(PINS_MOSFET2, LOW);
#endif #endif
bootLabel.redraw("settings");
settings = presets::defaultSettings; settings = presets::defaultSettings;
if (settingsSaver.init()) if (settingsPersister.init())
loadSettings(); {
if (settingsPersister.openProfile(0))
{
loadSettings();
}
}
bootLabel.redraw("swap front back");
updateSwapFrontBack(); updateSwapFrontBack();
bootLabel.redraw("deviceName");
{ {
uint8_t macAddress[6]; uint8_t macAddress[6];
WiFi.macAddress(&macAddress[0]); WiFi.macAddress(&macAddress[0]);
std::sprintf(deviceName, STRING(DEVICE_PREFIX) "_%02hhx%02hhx%02hhx", macAddress[3], macAddress[4], macAddress[5]); std::sprintf(deviceName, STRING(DEVICE_PREFIX) "_%02hhx%02hhx%02hhx", macAddress[3], macAddress[4], macAddress[5]);
} }
bootLabel.redraw("setHostname");
if (!WiFi.setHostname(deviceName)) if (!WiFi.setHostname(deviceName))
Serial.println("Could not setHostname"); Serial.println("Could not setHostname");
bootLabel.redraw("softAPsetHostname");
if (!WiFi.softAPsetHostname(deviceName)) if (!WiFi.softAPsetHostname(deviceName))
Serial.println("Could not softAPsetHostname"); Serial.println("Could not softAPsetHostname");
bootLabel.redraw("WiFi mode");
if (!WiFi.mode(settings.wifiSettings.autoWifiMode)) if (!WiFi.mode(settings.wifiSettings.autoWifiMode))
Serial.println("Could not set mode to WIFI_AP_STA"); Serial.println("Could not set mode to WIFI_AP_STA");
if (settings.wifiSettings.autoEnableAp) if (settings.wifiSettings.autoEnableAp)
{
bootLabel.redraw("WiFi softAp");
WifiSoftApAction{}.triggered(); WifiSoftApAction{}.triggered();
}
bootLabel.redraw("WiFi begin");
if (!WiFi.begin("realraum", "r3alraum")) if (!WiFi.begin("realraum", "r3alraum"))
Serial.println("Could not begin WiFi"); Serial.println("Could not begin WiFi");
if (settings.bluetoothSettings.autoBluetoothMode == BluetoothMode::Master) if (settings.bluetoothSettings.autoBluetoothMode == BluetoothMode::Master)
{ {
bootLabel.redraw("bluetooth begin master");
BluetoothBeginMasterAction{}.triggered(); BluetoothBeginMasterAction{}.triggered();
#ifdef FEATURE_BMS #ifdef FEATURE_BMS
if (settings.autoConnectBms) if (settings.autoConnectBms)
{
bootLabel.redraw("connect BMS");
BluetoothConnectBmsAction{}.triggered(); BluetoothConnectBmsAction{}.triggered();
}
#endif #endif
} else if (settings.bluetoothSettings.autoBluetoothMode == BluetoothMode::Slave) } else if (settings.bluetoothSettings.autoBluetoothMode == BluetoothMode::Slave)
{
bootLabel.redraw("bluetooth begin");
BluetoothBeginAction{}.triggered(); BluetoothBeginAction{}.triggered();
}
bootLabel.redraw("front Serial begin");
controllers.front.serial.get().begin(38400, SERIAL_8N1, PINS_RX1, PINS_TX1); controllers.front.serial.get().begin(38400, SERIAL_8N1, PINS_RX1, PINS_TX1);
bootLabel.redraw("back Serial begin");
controllers.back.serial.get().begin(38400, SERIAL_8N1, PINS_RX2, PINS_TX2); controllers.back.serial.get().begin(38400, SERIAL_8N1, PINS_RX2, PINS_TX2);
raw_gas = 0; raw_gas = 0;
@@ -124,8 +153,10 @@ void setup()
initOta(); initOta();
#endif #endif
bootLabel.redraw("webserver");
initWebserver(); initWebserver();
bootLabel.redraw("potis");
readPotis(); readPotis();
if (gas > 200.f || brems > 200.f) if (gas > 200.f || brems > 200.f)

View File

@@ -1,5 +1,7 @@
#pragma once #pragma once
#include <include/tl/optional.hpp>
#include "displays/menus/aboutmenu.h" #include "displays/menus/aboutmenu.h"
#include "displays/menus/accesspointwifisettingsmenu.h" #include "displays/menus/accesspointwifisettingsmenu.h"
#include "displays/menus/bluetoothsettingsmenu.h" #include "displays/menus/bluetoothsettingsmenu.h"
@@ -48,9 +50,12 @@
#include "globals.h" #include "globals.h"
#include "utils.h" #include "utils.h"
#include "widgets/label.h"
#include "icons/logo.h" #include "icons/logo.h"
namespace { namespace {
Label bootLabel{32, 250, TFT_WHITE};
union X { union X {
X() {} X() {}
~X() { ((Display&)statusDisplay).~Display(); } ~X() { ((Display&)statusDisplay).~Display(); }
@@ -406,6 +411,7 @@ void initScreen()
tft.pushImage(0, 40, icons::logo.WIDTH, icons::logo.HEIGHT, icons::logo.buffer); tft.pushImage(0, 40, icons::logo.WIDTH, icons::logo.HEIGHT, icons::logo.buffer);
tft.drawString("Bobbycar-OS", 32, 200, 4); tft.drawString("Bobbycar-OS", 32, 200, 4);
tft.drawString("booting...", 32, 225, 4); tft.drawString("booting...", 32, 225, 4);
bootLabel.start();
} }
void updateDisplay() void updateDisplay()

View File

@@ -6,28 +6,32 @@
#include <nvs_flash.h> #include <nvs_flash.h>
#include <nvs.h> #include <nvs.h>
#include <include/tl/optional.hpp>
#include "settings.h" #include "settings.h"
#include "bluetoothmode.h" #include "bluetoothmode.h"
#include "unifiedmodelmode.h" #include "unifiedmodelmode.h"
namespace { namespace {
class SettingsSaver class SettingsPersister
{ {
public: public:
bool init(); bool init();
bool openProfile(uint8_t index);
bool load(Settings &settings); bool load(Settings &settings);
bool save(Settings &settings); bool save(Settings &settings);
private: private:
nvs_handle my_handle; tl::optional<nvs_handle> m_handle;
}; };
bool SettingsSaver::init() bool SettingsPersister::init()
{ {
esp_err_t err = 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) if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND)
{ {
Serial.printf("nvs_flash_init() returned: %s, trying to erase\r\n", esp_err_to_name(err)); Serial.printf("nvs_flash_init() returned: %s, trying to erase\r\n", esp_err_to_name(err));
err = nvs_flash_erase(); err = nvs_flash_erase();
if (err != ESP_OK) if (err != ESP_OK)
{ {
@@ -44,13 +48,27 @@ bool SettingsSaver::init()
return false; return false;
} }
err = nvs_open("bobbycar", NVS_READWRITE, &my_handle); return true;
}
bool SettingsPersister::openProfile(uint8_t index)
{
if (m_handle)
{
nvs_close(*m_handle);
m_handle = tl::nullopt;
}
nvs_handle handle;
esp_err_t err = nvs_open((String{"bobbycar"}+index).c_str(), NVS_READWRITE, &handle);
if (err != ESP_OK) if (err != ESP_OK)
{ {
Serial.printf("nvs_open() returned: %s\r\n", esp_err_to_name(err)); Serial.printf("nvs_open() returned: %s\r\n", esp_err_to_name(err));
return false; return false;
} }
m_handle = handle;
return true; return true;
} }
@@ -118,13 +136,19 @@ template<> struct nvsGetterHelper<wifi_mode_t> { static esp_err_t nvs_get(nvs_ha
return err; return err;
}}; }};
bool SettingsSaver::load(Settings &settings) bool SettingsPersister::load(Settings &settings)
{ {
if (!m_handle)
{
Serial.println("");
return false;
}
bool result{true}; bool result{true};
settings.executeForEverySetting([&](const char *key, auto &value) settings.executeForEverySetting([&](const char *key, auto &value)
{ {
esp_err_t err = nvsGetterHelper<std::remove_reference_t<decltype(value)>>::nvs_get(my_handle, key, &value); esp_err_t err = nvsGetterHelper<std::remove_reference_t<decltype(value)>>::nvs_get(*m_handle, key, &value);
if (err != ESP_OK) if (err != ESP_OK)
{ {
Serial.printf("nvs_get_i32() for %s returned: %s\r\n", key, esp_err_to_name(err)); Serial.printf("nvs_get_i32() for %s returned: %s\r\n", key, esp_err_to_name(err));
@@ -168,13 +192,19 @@ template<> struct nvsSetterHelper<wifi_mode_t> { static esp_err_t nvs_set(nvs_ha
return nvs_set_u8(handle, key, uint8_t(value)); return nvs_set_u8(handle, key, uint8_t(value));
}}; }};
bool SettingsSaver::save(Settings &settings) bool SettingsPersister::save(Settings &settings)
{ {
if (!m_handle)
{
Serial.println("");
return false;
}
bool result{true}; bool result{true};
settings.executeForEverySetting([&](const char *key, auto value) settings.executeForEverySetting([&](const char *key, auto value)
{ {
esp_err_t err = nvsSetterHelper<decltype(value)>::nvs_set(my_handle, key, value); esp_err_t err = nvsSetterHelper<decltype(value)>::nvs_set(*m_handle, key, value);
if (err != ESP_OK) if (err != ESP_OK)
{ {
Serial.printf("nvs_get_i32() for %s returned: %s\r\n", key, esp_err_to_name(err)); Serial.printf("nvs_get_i32() for %s returned: %s\r\n", key, esp_err_to_name(err));

View File

@@ -266,12 +266,12 @@ void updateSwapFrontBack()
void loadSettings() void loadSettings()
{ {
settingsSaver.load(settings); settingsPersister.load(settings);
} }
void saveSettings() void saveSettings()
{ {
settingsSaver.save(settings); settingsPersister.save(settings);
} }
void updateAccumulators() void updateAccumulators()

View File

@@ -8,7 +8,7 @@ namespace {
class Label class Label
{ {
public: public:
Label(int x, int y) : m_x{x}, m_y{y} {} Label(int x, int y, uint32_t backgroundColor = TFT_BLACK);
int x() const { return m_x; }; int x() const { return m_x; };
int y() const { return m_y; }; int y() const { return m_y; };
@@ -20,6 +20,7 @@ public:
private: private:
const int m_x; const int m_x;
const int m_y; const int m_y;
const uint32_t m_backgroundColor;
String m_lastStr; String m_lastStr;
int m_lastFont; int m_lastFont;
@@ -29,6 +30,13 @@ private:
int m_lastHeight; int m_lastHeight;
}; };
Label::Label(int x, int y, uint32_t backgroundColor) :
m_x{x},
m_y{y},
m_backgroundColor{backgroundColor}
{
}
void Label::start() void Label::start()
{ {
m_lastStr.clear(); m_lastStr.clear();
@@ -71,7 +79,7 @@ void Label::redraw(const String &str, bool forceRedraw)
void Label::clear() void Label::clear()
{ {
if (m_lastWidth || m_lastHeight) if (m_lastWidth || m_lastHeight)
tft.fillRect(m_x, m_y, m_lastWidth, m_lastHeight, TFT_BLACK); tft.fillRect(m_x, m_y, m_lastWidth, m_lastHeight, m_backgroundColor);
start(); start();
} }