Basic multi profile implementation
This commit is contained in:
@@ -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 =
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
35
src/main.cpp
35
src/main.cpp
@@ -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)
|
||||||
|
@@ -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()
|
||||||
|
@@ -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));
|
@@ -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()
|
||||||
|
@@ -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();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user