wifi scan fixes, new config parameters

This commit is contained in:
2021-08-09 23:15:26 +02:00
parent 1504fc779a
commit e88fbfd4a7
23 changed files with 397 additions and 226 deletions

View File

@@ -32,8 +32,7 @@ struct NMotMaxRpmAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &g
struct FieldWeakMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.limits.fieldWeakMax; } }; struct FieldWeakMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.limits.fieldWeakMax; } };
struct PhaseAdvMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.limits.phaseAdvMax; } }; struct PhaseAdvMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.limits.phaseAdvMax; } };
struct AutoWifiModeAccessor : public RefAccessorSaveSettings<wifi_mode_t> { wifi_mode_t &getRef() const override { return settings.wifiSettings.autoWifiMode; } }; struct WifiEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.wifiSettings.wifiEnabled; } };
struct AutoEnableApAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.wifiSettings.autoEnableAp; } };
#ifdef FEATURE_BLUETOOTH #ifdef FEATURE_BLUETOOTH
struct AutoBluetoothModeAccessor : public RefAccessorSaveSettings<BluetoothMode> { BluetoothMode &getRef() const override { return settings.bluetoothSettings.autoBluetoothMode; } }; struct AutoBluetoothModeAccessor : public RefAccessorSaveSettings<BluetoothMode> { BluetoothMode &getRef() const override { return settings.bluetoothSettings.autoBluetoothMode; } };
@@ -65,6 +64,8 @@ struct SwapFrontBackAccessor : public RefAccessorSaveSettings<bool> {
#ifdef FEATURE_CAN #ifdef FEATURE_CAN
struct SendFrontCanCmdAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.controllerHardware.sendFrontCanCmd; } }; struct SendFrontCanCmdAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.controllerHardware.sendFrontCanCmd; } };
struct SendBackCanCmdAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.controllerHardware.sendBackCanCmd; } }; struct SendBackCanCmdAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.controllerHardware.sendBackCanCmd; } };
struct CanTransmitTimeoutAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.controllerHardware.canTransmitTimeout; } };
struct CanReceiveTimeoutAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.controllerHardware.canReceiveTimeout; } };
#endif #endif
struct SampleCountAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.sampleCount; } }; struct SampleCountAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.sampleCount; } };
@@ -89,6 +90,9 @@ struct ModeUpdateRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_
struct StatsUpdateRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.statsUpdateRate; } }; struct StatsUpdateRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.statsUpdateRate; } };
struct DisplayUpdateRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.displayUpdateRate; } }; struct DisplayUpdateRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.displayUpdateRate; } };
struct DisplayRedrawRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.displayRedrawRate; } }; struct DisplayRedrawRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.displayRedrawRate; } };
#ifdef FEATURE_CAN
struct CanReceiveRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.canReceiveRate; } };
#endif
struct DefaultModeModelModeAccessor : public RefAccessorSaveSettings<UnifiedModelMode> { UnifiedModelMode &getRef() const override { return settings.defaultMode.modelMode; } }; struct DefaultModeModelModeAccessor : public RefAccessorSaveSettings<UnifiedModelMode> { UnifiedModelMode &getRef() const override { return settings.defaultMode.modelMode; } };
struct DefaultModeSquareGasAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.defaultMode.squareGas; } }; struct DefaultModeSquareGasAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.defaultMode.squareGas; } };

View File

@@ -1,5 +1,9 @@
#pragma once #pragma once
// esp-idf includes
#include <esp_log.h>
// local includes
#include "actioninterface.h" #include "actioninterface.h"
#include "globals.h" #include "globals.h"
#include "presets.h" #include "presets.h"
@@ -14,25 +18,31 @@ public:
if (!settingsPersister.erase()) if (!settingsPersister.erase())
{ {
//Serial.println("EraseNvsAction::triggered() erase failed"); ESP_LOGE("BOBBY", "erase() failed");
return; //return;
} }
settings = presets::defaultSettings; settings = presets::defaultSettings;
if (!profile) if (!settingsPersister.openCommon())
return;
if (!settingsPersister.openProfile(*profile))
{ {
//Serial.println("EraseNvsAction::triggered() openProfile failed"); ESP_LOGE("BOBBY", "openCommon() failed");
return; //return;
}
if (profile)
{
if (!settingsPersister.openProfile(*profile))
{
ESP_LOGE("BOBBY", "openProfile(%hhu) failed", *profile);
//return;
}
} }
if (!settingsPersister.load(settings)) if (!settingsPersister.load(settings))
{ {
//Serial.println("EraseNvsAction::triggered() load failed"); ESP_LOGE("BOBBY", "load() failed");
return; //return;
} }
} }
}; };

View File

@@ -10,6 +10,7 @@
#include <Arduino.h> #include <Arduino.h>
#include <espchrono.h> #include <espchrono.h>
#include <tickchrono.h>
#include "bobbycar-can.h" #include "bobbycar-can.h"
@@ -36,7 +37,7 @@ CanButtonsState lastButtonsState;
void initCan() void initCan()
{ {
//Serial.println("initCan()"); ESP_LOGI(TAG, "called");
twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(GPIO_NUM_21, GPIO_NUM_22, TWAI_MODE_NORMAL); twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(GPIO_NUM_21, GPIO_NUM_22, TWAI_MODE_NORMAL);
twai_timing_config_t t_config TWAI_TIMING_CONFIG_250KBITS(); twai_timing_config_t t_config TWAI_TIMING_CONFIG_250KBITS();
@@ -50,29 +51,29 @@ void initCan()
if (const auto result = twai_driver_install(&g_config, &t_config, &f_config); result == ESP_OK) if (const auto result = twai_driver_install(&g_config, &t_config, &f_config); result == ESP_OK)
{ {
//Serial.printf("CAN info twai_driver_install() succeeded\r\n"); ESP_LOGI(TAG, "twai_driver_install() succeeded");
} }
else else
{ {
//Serial.printf("CAN err twai_driver_install() failed with %s\r\n", esp_err_to_name(result)); ESP_LOGE(TAG, "twai_driver_install() failed with %s", esp_err_to_name(result));
return; return;
} }
if (const auto result = twai_start(); result == ESP_OK) if (const auto result = twai_start(); result == ESP_OK)
{ {
//Serial.printf("CAN info twai_start() succeeded\r\n"); ESP_LOGI(TAG, "twai_start() succeeded");
} }
else else
{ {
//Serial.printf("CAN err twai_start() failed with %s\r\n", esp_err_to_name(result)); ESP_LOGE(TAG, "twai_start() failed with %s", esp_err_to_name(result));
if (const auto result = twai_driver_uninstall(); result == ESP_OK) if (const auto result = twai_driver_uninstall(); result == ESP_OK)
{ {
//Serial.printf("CAN info twai_driver_uninstall() succeeded\r\n"); ESP_LOGI(TAG, "twai_driver_uninstall() succeeded");
} }
else else
{ {
//Serial.printf("CAN err twai_driver_uninstall() failed with %s\r\n", esp_err_to_name(result)); ESP_LOGE(TAG, "twai_driver_uninstall() failed with %s", esp_err_to_name(result));
} }
return; return;
@@ -220,11 +221,12 @@ bool parseBoardcomputerCanMessage(const twai_message_t &message)
bool tryParseCanInput() bool tryParseCanInput()
{ {
twai_message_t message; twai_message_t message;
if (const auto result = twai_receive(&message, pdMS_TO_TICKS(10)); result != ESP_OK) const auto timeout = std::chrono::ceil<espcpputils::ticks>(espchrono::milliseconds32{settings.controllerHardware.canReceiveTimeout}).count();
if (const auto result = twai_receive(&message, timeout); result != ESP_OK)
{ {
if (result != ESP_ERR_TIMEOUT) if (result != ESP_ERR_TIMEOUT)
{ {
ESP_LOGE(TAG, "CAN err twai_receive() failed with %s", esp_err_to_name(result)); ESP_LOGE(TAG, "twai_receive() failed with %s", esp_err_to_name(result));
} }
if (espchrono::millis_clock::now() - controllers.front.lastCanFeedback > 100ms) if (espchrono::millis_clock::now() - controllers.front.lastCanFeedback > 100ms)
@@ -269,7 +271,7 @@ bool tryParseCanInput()
if (parseBoardcomputerCanMessage(message)) if (parseBoardcomputerCanMessage(message))
return true; return true;
//Serial.printf("WARNING Unknown CAN info received .identifier = %u\r\n", message.identifier); ESP_LOGW(TAG, "Unknown CAN info received .identifier = %u", message.identifier);
return true; return true;
} }
@@ -291,7 +293,8 @@ void sendCanCommands()
std::fill(std::begin(message.data), std::end(message.data), 0); std::fill(std::begin(message.data), std::end(message.data), 0);
std::memcpy(message.data, &value, sizeof(value)); std::memcpy(message.data, &value, sizeof(value));
const auto result = twai_transmit(&message, pdMS_TO_TICKS(200)); const auto timeout = std::chrono::ceil<espcpputils::ticks>(espchrono::milliseconds32{settings.controllerHardware.canTransmitTimeout}).count();
const auto result = twai_transmit(&message, timeout);
if (result != ESP_OK && result != ESP_ERR_TIMEOUT) if (result != ESP_OK && result != ESP_ERR_TIMEOUT)
{ {
ESP_LOGE(TAG, "ERROR: twai_transmit() failed with %s", esp_err_to_name(result)); ESP_LOGE(TAG, "ERROR: twai_transmit() failed with %s", esp_err_to_name(result));

View File

@@ -1,5 +1,7 @@
#pragma once #pragma once
#include <fmt/core.h>
#include "display.h" #include "display.h"
#include "textinterface.h" #include "textinterface.h"
#include "actioninterface.h" #include "actioninterface.h"
@@ -122,6 +124,18 @@ void ChangeValueDisplay<Tvalue>::redraw()
m_valueLabel.redraw(std::to_string(m_value)); m_valueLabel.redraw(std::to_string(m_value));
} }
template<>
void ChangeValueDisplay<float>::redraw()
{
tft.setTextFont(4);
tft.setTextColor(TFT_YELLOW);
m_titleLabel.redraw(text());
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setTextFont(7);
m_valueLabel.redraw(fmt::format("{:02f}", m_value));
}
template<typename Tvalue> template<typename Tvalue>
void ChangeValueDisplay<Tvalue>::rotate(int offset) void ChangeValueDisplay<Tvalue>::rotate(int offset)
{ {

View File

@@ -1,5 +1,7 @@
#pragma once #pragma once
#include <esp_log.h>
#include "changevaluedisplay.h" #include "changevaluedisplay.h"
#include "menudisplay.h" #include "menudisplay.h"
#include "utils.h" #include "utils.h"
@@ -45,7 +47,7 @@ void ChangeValueDisplay<bobbycar::protocol::ControlMode>::start()
case ControlMode::Speed: setSelectedIndex(2); break; case ControlMode::Speed: setSelectedIndex(2); break;
case ControlMode::Torque: setSelectedIndex(3); break; case ControlMode::Torque: setSelectedIndex(3); break;
default: default:
//Serial.printf("Unknown ControlMode: %i\r\n", int(value)); ESP_LOGW("BOBBY", "Unknown ControlMode: %i", int(value));
setSelectedIndex(4); setSelectedIndex(4);
} }
} }

View File

@@ -1,5 +1,7 @@
#pragma once #pragma once
#include <esp_log.h>
#include "changevaluedisplay.h" #include "changevaluedisplay.h"
#include "menudisplay.h" #include "menudisplay.h"
#include "utils.h" #include "utils.h"
@@ -43,7 +45,7 @@ void ChangeValueDisplay<bobbycar::protocol::ControlType>::start()
case ControlType::Sinusoidal: setSelectedIndex(1); break; case ControlType::Sinusoidal: setSelectedIndex(1); break;
case ControlType::FieldOrientedControl: setSelectedIndex(2); break; case ControlType::FieldOrientedControl: setSelectedIndex(2); break;
default: default:
//Serial.printf("Unknown ControlType: %i\r\n", int(value)); ESP_LOGW("BOBBY", "Unknown ControlType: %i", int(value));
setSelectedIndex(3); setSelectedIndex(3);
} }
} }

View File

@@ -1,5 +1,7 @@
#pragma once #pragma once
#include <esp_log.h>
#include "changevaluedisplay.h" #include "changevaluedisplay.h"
#include "menudisplay.h" #include "menudisplay.h"
#include "utils.h" #include "utils.h"
@@ -44,7 +46,7 @@ void ChangeValueDisplay<LarsmModeMode>::start()
case LarsmModeMode::Mode3: setSelectedIndex(2); break; case LarsmModeMode::Mode3: setSelectedIndex(2); break;
case LarsmModeMode::Mode4: setSelectedIndex(3); break; case LarsmModeMode::Mode4: setSelectedIndex(3); break;
default: default:
//Serial.printf("Unknown LarsmModeMode: %i\r\n", int(value)); ESP_LOGW("BOBBY", "Unknown LarsmModeMode: %i", int(value));
setSelectedIndex(4); setSelectedIndex(4);
} }
} }

View File

@@ -1,5 +1,7 @@
#pragma once #pragma once
#include <esp_log.h>
#include "changevaluedisplay.h" #include "changevaluedisplay.h"
#include "menudisplay.h" #include "menudisplay.h"
#include "utils.h" #include "utils.h"
@@ -46,7 +48,7 @@ void ChangeValueDisplay<UnifiedModelMode>::start()
case UnifiedModelMode::FocSpeed: setSelectedIndex(3); break; case UnifiedModelMode::FocSpeed: setSelectedIndex(3); break;
case UnifiedModelMode::FocTorque: setSelectedIndex(4); break; case UnifiedModelMode::FocTorque: setSelectedIndex(4); break;
default: default:
//Serial.printf("Unknown UnifiedModelMode: %i\r\n", int(value)); ESP_LOGW("BOBBY", "Unknown UnifiedModelMode: %i", int(value));
setSelectedIndex(5); setSelectedIndex(5);
} }
} }

View File

@@ -1,6 +1,7 @@
#pragma once #pragma once
#include <esp_wifi_types.h> #include <esp_wifi_types.h>
#include <esp_log.h>
#include "changevaluedisplay.h" #include "changevaluedisplay.h"
#include "menudisplay.h" #include "menudisplay.h"
@@ -45,7 +46,7 @@ void ChangeValueDisplay<wifi_mode_t>::start()
case WIFI_MODE_AP: setSelectedIndex(2); break; case WIFI_MODE_AP: setSelectedIndex(2); break;
case WIFI_MODE_APSTA: setSelectedIndex(3); break; case WIFI_MODE_APSTA: setSelectedIndex(3); break;
default: default:
//Serial.printf("Unknown wifi_mode_t: %i\r\n", int(value)); ESP_LOGW("BOBBY", "Unknown wifi_mode_t: %i", int(value));
setSelectedIndex(4); setSelectedIndex(4);
} }
} }

View File

@@ -46,6 +46,22 @@ using NumMagnetPolesChangeScreen = makeComponent<
BackActionInterface<SwitchScreenAction<ControllerHardwareSettingsMenu>>, BackActionInterface<SwitchScreenAction<ControllerHardwareSettingsMenu>>,
SwitchScreenAction<ControllerHardwareSettingsMenu> SwitchScreenAction<ControllerHardwareSettingsMenu>
>; >;
#ifdef FEATURE_CAN
using CanTransmitTimeoutChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_CANTRANSMITTIMEOUT>,
CanTransmitTimeoutAccessor,
BackActionInterface<SwitchScreenAction<ControllerHardwareSettingsMenu>>,
SwitchScreenAction<ControllerHardwareSettingsMenu>
>;
using CanReceiveTimeoutChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_CANRECEIVETIMEOUT>,
CanReceiveTimeoutAccessor,
BackActionInterface<SwitchScreenAction<ControllerHardwareSettingsMenu>>,
SwitchScreenAction<ControllerHardwareSettingsMenu>
>;
#endif
class ControllerHardwareSettingsMenu : class ControllerHardwareSettingsMenu :
public MenuDisplay, public MenuDisplay,
@@ -62,8 +78,10 @@ public:
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_NUMMAGNETPOLES>, SwitchScreenAction<NumMagnetPolesChangeScreen>>>(); constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_NUMMAGNETPOLES>, SwitchScreenAction<NumMagnetPolesChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SWAPFRONTBACK>, ToggleBoolAction, CheckboxIcon, SwapFrontBackAccessor>>(); constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SWAPFRONTBACK>, ToggleBoolAction, CheckboxIcon, SwapFrontBackAccessor>>();
#ifdef FEATURE_CAN #ifdef FEATURE_CAN
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_FRONTSENDCAN>, ToggleBoolAction, CheckboxIcon, SendFrontCanCmdAccessor>>(); constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_FRONTSENDCAN>, ToggleBoolAction, CheckboxIcon, SendFrontCanCmdAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACKSENDCAN>, ToggleBoolAction, CheckboxIcon, SendBackCanCmdAccessor>>(); constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACKSENDCAN>, ToggleBoolAction, CheckboxIcon, SendBackCanCmdAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_CANTRANSMITTIMEOUT>, SwitchScreenAction<CanTransmitTimeoutChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_CANRECEIVETIMEOUT>, SwitchScreenAction<CanReceiveTimeoutChangeScreen>>>();
#endif #endif
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&icons::back>>>(); constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&icons::back>>>();
} }

View File

@@ -57,6 +57,16 @@ using DisplayRedrawRateChangeDisplay = makeComponent<
SwitchScreenAction<TimersMenu> SwitchScreenAction<TimersMenu>
>; >;
#ifdef FEATURE_CAN
using CanReceiveRateChangeDisplay = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_CANRECEIVERATE>,
CanReceiveRateAccessor,
BackActionInterface<SwitchScreenAction<TimersMenu>>,
SwitchScreenAction<TimersMenu>
>;
#endif
class TimersMenu : class TimersMenu :
public MenuDisplay, public MenuDisplay,
public StaticText<TEXT_TIMERS>, public StaticText<TEXT_TIMERS>,
@@ -70,6 +80,9 @@ public:
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_STATSUPDATERATE>, SwitchScreenAction<StatsUpdateRateChangeDisplay>>>(); constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_STATSUPDATERATE>, SwitchScreenAction<StatsUpdateRateChangeDisplay>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_DISPLAYUPDATERATE>, SwitchScreenAction<DisplayUpdateRateChangeDisplay>>>(); constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_DISPLAYUPDATERATE>, SwitchScreenAction<DisplayUpdateRateChangeDisplay>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_DISPLAYREDRAWRATE>, SwitchScreenAction<DisplayRedrawRateChangeDisplay>>>(); constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_DISPLAYREDRAWRATE>, SwitchScreenAction<DisplayRedrawRateChangeDisplay>>>();
#ifdef FEATURE_CAN
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_CANRECEIVERATE>, SwitchScreenAction<CanReceiveRateChangeDisplay>>>();
#endif
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<BoardcomputerHardwareSettingsMenu>, StaticMenuItemIcon<&icons::back>>>(); constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<BoardcomputerHardwareSettingsMenu>, StaticMenuItemIcon<&icons::back>>>();
} }
}; };

View File

@@ -1,6 +1,15 @@
#pragma once #pragma once
// system includes
#include <optional>
// esp-idf includes
#include <esp_log.h>
// 3rdparty lib includes
#include <espchrono.h> #include <espchrono.h>
#include <espwifistack.h>
#include <fmt/core.h>
// local includes // local includes
#include "menudisplay.h" #include "menudisplay.h"
@@ -10,12 +19,15 @@
#include "actions/dummyaction.h" #include "actions/dummyaction.h"
#include "icons/back.h" #include "icons/back.h"
#include "texts.h" #include "texts.h"
#include "wifi_bobbycar.h"
// forward declares // forward declares
namespace { namespace {
class WifiSettingsMenu; class WifiSettingsMenu;
} // namespace } // namespace
using namespace std::chrono_literals;
namespace { namespace {
class WifiScanMenu : public MenuDisplay, public BackActionInterface<SwitchScreenAction<WifiSettingsMenu>> class WifiScanMenu : public MenuDisplay, public BackActionInterface<SwitchScreenAction<WifiSettingsMenu>>
{ {
@@ -31,7 +43,7 @@ public:
void stop() override; void stop() override;
private: private:
espchrono::millis_clock::time_point m_lastScanComplete; std::optional<espchrono::millis_clock::time_point> m_lastScanComplete;
std::vector<std::unique_ptr<makeComponent<MenuItem, ChangeableText, DummyAction>>> m_reusableItems; std::vector<std::unique_ptr<makeComponent<MenuItem, ChangeableText, DummyAction>>> m_reusableItems;
}; };
@@ -43,13 +55,13 @@ WifiScanMenu::WifiScanMenu()
std::string WifiScanMenu::text() const std::string WifiScanMenu::text() const
{ {
auto text = std::to_string(menuItemCount()-1) + " found"; const auto scanStatus = wifi_stack::get_scan_status();
//switch (WiFi.scanComplete()) auto text = wifi_stack::toString(scanStatus);
//{
//case WIFI_SCAN_RUNNING: text += " (scanning)"; break; if (scanStatus != wifi_stack::WiFiScanStatus::Scanning)
//case WIFI_SCAN_FAILED: text += " (error)"; break; if (const auto &result = wifi_stack::get_scan_result())
//} text += fmt::format(" ({} found)", result->entries.size());
text += " (not implemented)";
return text; return text;
} }
@@ -59,63 +71,73 @@ void WifiScanMenu::start()
m_lastScanComplete = {}; m_lastScanComplete = {};
//WiFi.scanNetworks(true); if (wifi_stack::get_scan_status() != wifi_stack::WiFiScanStatus::Scanning)
if (const auto result = wifi_scan(); result != ESP_OK)
ESP_LOGE("BOBBY", "wifi_scan() failed with %s", esp_err_to_name(result));
} }
void WifiScanMenu::update() void WifiScanMenu::update()
{ {
//const auto n = WiFi.scanComplete(); if (wifi_stack::get_scan_status() == wifi_stack::WiFiScanStatus::Scanning)
//if (n >= 0) {
//{ // TODO
// const auto now = espchrono::millis_clock::now(); }
// if (!m_lastScanComplete) else
// { {
// auto backButton = takeLastMenuItem(); const auto now = espchrono::millis_clock::now();
//
// for (std::size_t i = 0; i < n; i++) if (!m_lastScanComplete)
// { {
// const auto ssid = to_string(WiFi.SSID(i)); const auto &result = wifi_stack::get_scan_result();
// if (menuItemCount() <= i)
// { auto backButton = takeLastMenuItem();
// if (m_reusableItems.empty())
// { for (std::size_t i = 0; i < (result ? result->entries.size() : 0); i++)
// auto &item = constructMenuItem<makeComponent<MenuItem, ChangeableText, DummyAction>>(); {
// item.setTitle(ssid); std::string ssid{reinterpret_cast<const char*>(result->entries[i].ssid)};
// } if (menuItemCount() <= i)
// else {
// { if (m_reusableItems.empty())
// std::unique_ptr<makeComponent<MenuItem, ChangeableText, DummyAction>> ptr = std::move(m_reusableItems.back()); {
// m_reusableItems.pop_back(); auto &item = constructMenuItem<makeComponent<MenuItem, ChangeableText, DummyAction>>();
// ptr->setTitle(ssid); item.setTitle(std::move(ssid));
// emplaceMenuItem(std::move(ptr)); }
// } else
// } {
// else std::unique_ptr<makeComponent<MenuItem, ChangeableText, DummyAction>> ptr = std::move(m_reusableItems.back());
// { m_reusableItems.pop_back();
// auto &item = *(makeComponent<MenuItem, ChangeableText, DummyAction>*)(&getMenuItem(i)); ptr->setTitle(std::move(ssid));
// item.setTitle(ssid); emplaceMenuItem(std::move(ptr));
// } }
// } }
// else
// while (menuItemCount() > n) {
// m_reusableItems.emplace_back((makeComponent<MenuItem, ChangeableText, DummyAction>*)takeLastMenuItem().release()); auto &item = *(makeComponent<MenuItem, ChangeableText, DummyAction>*)(&getMenuItem(i));
// item.setTitle(std::move(ssid));
// emplaceMenuItem(std::move(backButton)); }
// }
// m_lastScanComplete = now;
// } while (menuItemCount() > (result ? result->entries.size() : 0))
// else if (now - m_lastScanComplete >= 2000) m_reusableItems.emplace_back((makeComponent<MenuItem, ChangeableText, DummyAction>*)takeLastMenuItem().release());
// {
// m_lastScanComplete = 0; emplaceMenuItem(std::move(backButton));
// WiFi.scanNetworks(true);
// } m_lastScanComplete = now;
//} }
else if (espchrono::ago(*m_lastScanComplete) >= 10s)
{
m_lastScanComplete = {};
if (const auto result = wifi_scan(); result != ESP_OK)
ESP_LOGE("BOBBY", "wifi_scan() failed with %s", esp_err_to_name(result));
}
}
Base::update(); Base::update();
} }
void WifiScanMenu::stop() void WifiScanMenu::stop()
{ {
//WiFi.scanDelete(); wifi_stack::delete_scan_result();
} }
} // namespace } // namespace

View File

@@ -24,14 +24,6 @@ class SettingsMenu;
namespace { namespace {
class WifiSettingsMenu; class WifiSettingsMenu;
using AutoWifiModeChangeDisplay = makeComponent<
ChangeValueDisplay<wifi_mode_t>,
StaticText<TEXT_AUTOWIFIMODE>,
AutoWifiModeAccessor,
BackActionInterface<SwitchScreenAction<WifiSettingsMenu>>,
SwitchScreenAction<WifiSettingsMenu>
>;
class WifiSettingsMenu : class WifiSettingsMenu :
public MenuDisplay, public MenuDisplay,
public StaticText<TEXT_WIFISETTINGS>, public StaticText<TEXT_WIFISETTINGS>,
@@ -40,8 +32,7 @@ class WifiSettingsMenu :
public: public:
WifiSettingsMenu() WifiSettingsMenu()
{ {
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_AUTOWIFIMODE>, SwitchScreenAction<AutoWifiModeChangeDisplay>>>(); constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_WIFIENABLED>, ToggleBoolAction, CheckboxIcon, WifiEnabledAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_AUTOENABLEAP>, ToggleBoolAction, CheckboxIcon, AutoEnableApAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_GENERICWIFISETTINGS>, SwitchScreenAction<GenericWifiSettingsMenu>>>(); constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_GENERICWIFISETTINGS>, SwitchScreenAction<GenericWifiSettingsMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_STATIONWIFISETTINGS>, SwitchScreenAction<StationWifiSettingsMenu>>>(); constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_STATIONWIFISETTINGS>, SwitchScreenAction<StationWifiSettingsMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_WIFISCAN>, SwitchScreenAction<WifiScanMenu>, StaticMenuItemIcon<&icons::scan>>>(); constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_WIFISCAN>, SwitchScreenAction<WifiScanMenu>, StaticMenuItemIcon<&icons::scan>>>();

View File

@@ -4,8 +4,7 @@
namespace { namespace {
namespace icons { namespace icons {
/* constexpr const Icon<240, 130> logo{{
const Icon<240, 130> logo{{
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, // 0x0010 (16) pixels 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, // 0x0010 (16) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, // 0x0020 (32) pixels 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, // 0x0020 (32) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, // 0x0030 (48) pixels 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, // 0x0030 (48) pixels
@@ -1957,6 +1956,5 @@ const Icon<240, 130> logo{{
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, // 0x79D0 (31184) pixels 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, // 0x79D0 (31184) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, // 0x79E0 (31200) pixels 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, // 0x79E0 (31200) pixels
}}; }};
*/
} }
} }

View File

@@ -180,11 +180,17 @@ extern "C" void app_main()
if (settingsPersister.init()) if (settingsPersister.init())
{ {
if (settingsPersister.openProfile(0)) if (!settingsPersister.openCommon())
{ ESP_LOGE("BOBBY", "openCommon() failed");
loadSettings();
} if (!settingsPersister.openProfile(0))
ESP_LOGE("BOBBY", "openProfile(0) failed");
loadSettings();
} }
else
ESP_LOGE("BOBBY", "init() failed");
printMemoryStats("loadSettings()"); printMemoryStats("loadSettings()");
bootLabel.redraw("deviceName"); bootLabel.redraw("deviceName");
@@ -372,8 +378,9 @@ extern "C" void app_main()
} }
#ifdef FEATURE_CAN #ifdef FEATURE_CAN
if (!lastCanParse || now - *lastCanParse >= 50ms) if (!lastCanParse || now - *lastCanParse >= 1000ms/settings.boardcomputerHardware.timersSettings.canReceiveRate)
{ {
//can::tryParseCanInput();
can::parseCanInput(); can::parseCanInput();
lastCanParse = now; lastCanParse = now;

View File

@@ -36,6 +36,8 @@ constexpr Settings::ControllerHardware defaultControllerHardware {
#ifdef FEATURE_CAN #ifdef FEATURE_CAN
.sendFrontCanCmd = true, .sendFrontCanCmd = true,
.sendBackCanCmd = true, .sendBackCanCmd = true,
.canTransmitTimeout = 200,
.canReceiveTimeout = 0,
#endif #endif
}; };
@@ -56,12 +58,13 @@ constexpr Settings::ControllerHardware mosfetsOffControllerHardware {
#ifdef FEATURE_CAN #ifdef FEATURE_CAN
.sendFrontCanCmd = true, .sendFrontCanCmd = true,
.sendBackCanCmd = true, .sendBackCanCmd = true,
.canTransmitTimeout = 200,
.canReceiveTimeout = 0,
#endif #endif
}; };
constexpr Settings::WifiSettings defaultWifiSettings { constexpr Settings::WifiSettings defaultWifiSettings {
.autoWifiMode = WIFI_MODE_APSTA, .wifiEnabled = true
.autoEnableAp = true
}; };
#ifdef FEATURE_BLUETOOTH #ifdef FEATURE_BLUETOOTH
@@ -87,6 +90,8 @@ constexpr Settings::ControllerHardware spinnerControllerHardware {
#ifdef FEATURE_CAN #ifdef FEATURE_CAN
.sendFrontCanCmd = true, .sendFrontCanCmd = true,
.sendBackCanCmd = true, .sendBackCanCmd = true,
.canTransmitTimeout = 200,
.canReceiveTimeout = 0,
#endif #endif
}; };
@@ -95,7 +100,10 @@ constexpr Settings::BoardcomputerHardware::TimersSettings defaultTimersSettings
.modeUpdateRate = 50, .modeUpdateRate = 50,
.statsUpdateRate = 50, .statsUpdateRate = 50,
.displayUpdateRate = 50, .displayUpdateRate = 50,
.displayRedrawRate = 50 .displayRedrawRate = 50,
#ifdef FEATURE_CAN
.canReceiveRate = 100,
#endif
}; };
constexpr Settings::BoardcomputerHardware defaultBoardcomputerHardware { constexpr Settings::BoardcomputerHardware defaultBoardcomputerHardware {

View File

@@ -50,7 +50,7 @@ void initScreen()
tft.fillScreen(TFT_WHITE); tft.fillScreen(TFT_WHITE);
tft.setTextColor(TFT_BLACK, TFT_WHITE); tft.setTextColor(TFT_BLACK, TFT_WHITE);
tft.setTextFont(4); tft.setTextFont(4);
//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); tft.drawString("Bobbycar-OS", 32, 200);
tft.drawString("booting...", 32, 225); tft.drawString("booting...", 32, 225);
bootLabel.start(); bootLabel.start();

View File

@@ -35,8 +35,7 @@ struct Settings
} limits; } limits;
struct WifiSettings { struct WifiSettings {
wifi_mode_t autoWifiMode; bool wifiEnabled;
bool autoEnableAp;
} wifiSettings; } wifiSettings;
#ifdef FEATURE_BLUETOOTH #ifdef FEATURE_BLUETOOTH
@@ -57,6 +56,8 @@ struct Settings
#ifdef FEATURE_CAN #ifdef FEATURE_CAN
bool sendFrontCanCmd; bool sendFrontCanCmd;
bool sendBackCanCmd; bool sendBackCanCmd;
int16_t canTransmitTimeout; // in ms
int16_t canReceiveTimeout; // in ms
#endif #endif
} controllerHardware; } controllerHardware;
@@ -77,6 +78,9 @@ struct Settings
int16_t statsUpdateRate; int16_t statsUpdateRate;
int16_t displayUpdateRate; int16_t displayUpdateRate;
int16_t displayRedrawRate; int16_t displayRedrawRate;
#ifdef FEATURE_CAN
int16_t canReceiveRate;
#endif
} timersSettings; } timersSettings;
} boardcomputerHardware; } boardcomputerHardware;
@@ -107,44 +111,24 @@ struct Settings
template<typename T> template<typename T>
void executeForEverySetting(T &&callable); void executeForEveryCommonSetting(T &&callable);
template<typename T>
void executeForEveryProfileSetting(T &&callable);
}; };
template<typename T> template<typename T>
void Settings::executeForEverySetting(T &&callable) void Settings::executeForEveryCommonSetting(T &&callable)
{ {
#ifdef FEATURE_BMS #ifdef FEATURE_BMS
callable("autoConnectBms", autoConnectBms); callable("autoConnectBms", autoConnectBms);
#endif #endif
callable("reverseBeep", reverseBeep);
callable("revBeepFreq0", reverseBeepFreq0);
callable("revBeepFreq1", reverseBeepFreq1);
callable("revBeepDur0", reverseBeepDuration0);
callable("revBeepDur1", reverseBeepDuration1);
callable("iMotMax", limits.iMotMax);
callable("iDcMax", limits.iDcMax);
callable("nMotMax", limits.nMotMax);
callable("fieldWeakMax", limits.fieldWeakMax);
callable("phaseAdvMax", limits.phaseAdvMax);
#ifdef FEATURE_BLUETOOTH #ifdef FEATURE_BLUETOOTH
callable("autoBluetoothMo", bluetoothSettings.autoBluetoothMode); callable("autoBluetoothMo", bluetoothSettings.autoBluetoothMode);
#endif #endif
callable("autoWifiMode", wifiSettings.autoWifiMode); callable("wifiEnabled", wifiSettings.wifiEnabled);
callable("autoEnableAp", wifiSettings.autoEnableAp);
callable("enableFrontLeft", controllerHardware.enableFrontLeft);
callable("enableFrontRigh", controllerHardware.enableFrontRight);
callable("enableBackLeft", controllerHardware.enableBackLeft);
callable("enableBackRight", controllerHardware.enableBackRight);
callable("invertFrontLeft", controllerHardware.invertFrontLeft);
callable("invertFrontRigh", controllerHardware.invertFrontRight);
callable("invertBackLeft", controllerHardware.invertBackLeft);
callable("invertBackRight", controllerHardware.invertBackRight);
callable("wheelDiameter", controllerHardware.wheelDiameter); callable("wheelDiameter", controllerHardware.wheelDiameter);
callable("numMagnetPoles", controllerHardware.numMagnetPoles); callable("numMagnetPoles", controllerHardware.numMagnetPoles);
@@ -152,6 +136,8 @@ void Settings::executeForEverySetting(T &&callable)
#ifdef FEATURE_CAN #ifdef FEATURE_CAN
callable("sendFrontCanCmd", controllerHardware.sendFrontCanCmd); callable("sendFrontCanCmd", controllerHardware.sendFrontCanCmd);
callable("sendBackCanCmd", controllerHardware.sendBackCanCmd); callable("sendBackCanCmd", controllerHardware.sendBackCanCmd);
callable("canTransmitTime", controllerHardware.canTransmitTimeout);
callable("canReceiveTimeo", controllerHardware.canReceiveTimeout);
#endif #endif
callable("sampleCount", boardcomputerHardware.sampleCount); callable("sampleCount", boardcomputerHardware.sampleCount);
@@ -177,6 +163,35 @@ void Settings::executeForEverySetting(T &&callable)
callable("statsUpdateRate", boardcomputerHardware.timersSettings.statsUpdateRate); callable("statsUpdateRate", boardcomputerHardware.timersSettings.statsUpdateRate);
callable("displayUpdateRa", boardcomputerHardware.timersSettings.displayUpdateRate); callable("displayUpdateRa", boardcomputerHardware.timersSettings.displayUpdateRate);
callable("displayRedrawRa", boardcomputerHardware.timersSettings.displayRedrawRate); callable("displayRedrawRa", boardcomputerHardware.timersSettings.displayRedrawRate);
#ifdef FEATURE_CAN
callable("canReceiveRate", boardcomputerHardware.timersSettings.canReceiveRate);
#endif
}
template<typename T>
void Settings::executeForEveryProfileSetting(T &&callable)
{
callable("reverseBeep", reverseBeep);
callable("revBeepFreq0", reverseBeepFreq0);
callable("revBeepFreq1", reverseBeepFreq1);
callable("revBeepDur0", reverseBeepDuration0);
callable("revBeepDur1", reverseBeepDuration1);
callable("iMotMax", limits.iMotMax);
callable("iDcMax", limits.iDcMax);
callable("nMotMax", limits.nMotMax);
callable("fieldWeakMax", limits.fieldWeakMax);
callable("phaseAdvMax", limits.phaseAdvMax);
callable("enableFrontLeft", controllerHardware.enableFrontLeft);
callable("enableFrontRigh", controllerHardware.enableFrontRight);
callable("enableBackLeft", controllerHardware.enableBackLeft);
callable("enableBackRight", controllerHardware.enableBackRight);
callable("invertFrontLeft", controllerHardware.invertFrontLeft);
callable("invertFrontRigh", controllerHardware.invertFrontRight);
callable("invertBackLeft", controllerHardware.invertBackLeft);
callable("invertBackRight", controllerHardware.invertBackRight);
callable("default.modelMo", defaultMode.modelMode); callable("default.modelMo", defaultMode.modelMode);
callable("default.enableS", defaultMode.enableSmoothing); callable("default.enableS", defaultMode.enableSmoothing);

View File

@@ -5,6 +5,10 @@
#include <nvs_flash.h> #include <nvs_flash.h>
#include <nvs.h> #include <nvs.h>
#include <esp_log.h>
#include <fmt/core.h>
#include <cpputils.h>
#include "settings.h" #include "settings.h"
#ifdef FEATURE_BLUETOOTH #ifdef FEATURE_BLUETOOTH
@@ -18,6 +22,8 @@ class SettingsPersister
public: public:
bool init(); bool init();
bool erase(); bool erase();
bool openCommon();
void closeCommon();
bool openProfile(uint8_t index); bool openProfile(uint8_t index);
void closeProfile(); void closeProfile();
bool load(Settings &settings); bool load(Settings &settings);
@@ -26,6 +32,9 @@ public:
std::optional<uint8_t> currentlyOpenProfileIndex() const; std::optional<uint8_t> currentlyOpenProfileIndex() const;
private: private:
// for common settings
nvs_handle m_handle{};
struct CurrentlyOpenProfile { struct CurrentlyOpenProfile {
nvs_handle handle; nvs_handle handle;
uint8_t profileIndex; uint8_t profileIndex;
@@ -35,17 +44,15 @@ private:
bool SettingsPersister::init() bool SettingsPersister::init()
{ {
esp_err_t err = nvs_flash_init(); if (esp_err_t result = nvs_flash_init();
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) cpputils::is_in(result, ESP_ERR_NVS_NO_FREE_PAGES, ESP_ERR_NVS_NEW_VERSION_FOUND))
{ {
//Serial.printf("nvs_flash_init() returned: %s, trying to erase\r\n", esp_err_to_name(err)); ESP_LOGE("BOBBY", "nvs_flash_init() failed with %s, trying to erase...", esp_err_to_name(result));
return erase(); return erase();
} }
else if (result != ESP_OK)
if (err != ESP_OK)
{ {
//Serial.printf("nvs_flash_init() returned: %s\r\n", esp_err_to_name(err)); ESP_LOGE("BOBBY", "nvs_flash_init() failed with %s", esp_err_to_name(result));
return false; return false;
} }
@@ -54,32 +61,61 @@ bool SettingsPersister::init()
bool SettingsPersister::erase() bool SettingsPersister::erase()
{ {
esp_err_t err = nvs_flash_erase(); closeProfile();
if (err != ESP_OK) closeCommon();
bool result{true};
if (esp_err_t result = nvs_flash_erase(); result != ESP_OK)
{ {
//Serial.printf("nvs_flash_erase() returned: %s, aborting\r\n", esp_err_to_name(err)); ESP_LOGE("BOBBY", "nvs_flash_erase() failed with %s", esp_err_to_name(result));
result = false;
}
if (esp_err_t result = nvs_flash_init(); result != ESP_OK)
{
ESP_LOGE("BOBBY", "nvs_flash_init() failed with %s", esp_err_to_name(result));
result = false;
}
return result;
}
bool SettingsPersister::openCommon()
{
closeCommon();
nvs_handle handle;
if (esp_err_t result = nvs_open("bobbycar", NVS_READWRITE, &handle); result != ESP_OK)
{
ESP_LOGE("BOBBY", "nvs_open() COMMON %s failed with %s", "bobbycar", esp_err_to_name(result));
return false; return false;
} }
err = nvs_flash_init(); m_handle = handle;
if (err != ESP_OK)
{
//Serial.printf("nvs_flash_init() returned: %s\r\n", esp_err_to_name(err));
return false;
}
return true; return true;
} }
void SettingsPersister::closeCommon()
{
if (!m_handle)
return;
nvs_close(m_handle);
m_handle = {};
}
bool SettingsPersister::openProfile(uint8_t index) bool SettingsPersister::openProfile(uint8_t index)
{ {
closeProfile(); closeProfile();
nvs_handle handle; nvs_handle handle;
esp_err_t err = nvs_open(("bobbycar"+std::to_string(index)).c_str(), NVS_READWRITE, &handle); const auto name = fmt::format("bobbycar{}", index);
if (err != ESP_OK) if (esp_err_t result = nvs_open(name.c_str(), NVS_READWRITE, &handle); result != ESP_OK)
{ {
//Serial.printf("nvs_open() returned: %s\r\n", esp_err_to_name(err)); ESP_LOGE("BOBBY", "nvs_open() PROFILE %s failed with %s", name.c_str(), esp_err_to_name(result));
return false; return false;
} }
@@ -166,23 +202,41 @@ template<> struct nvsGetterHelper<wifi_mode_t> { static esp_err_t nvs_get(nvs_ha
bool SettingsPersister::load(Settings &settings) bool SettingsPersister::load(Settings &settings)
{ {
if (!m_profile)
{
//Serial.println("SettingsPersister::load() no profile open currently!");
return false;
}
bool result{true}; bool result{true};
settings.executeForEverySetting([&](const char *key, auto &value) if (m_handle)
{ {
esp_err_t err = nvsGetterHelper<std::remove_reference_t<decltype(value)>>::nvs_get(m_profile->handle, key, &value); settings.executeForEveryCommonSetting([&](const char *key, auto &value)
if (err != ESP_OK)
{ {
//Serial.printf("nvs_get_i32() for %s returned: %s\r\n", key, esp_err_to_name(err)); if (esp_err_t result = nvsGetterHelper<std::remove_reference_t<decltype(value)>>::nvs_get(m_handle, key, &value); result != ESP_OK)
result = false; {
} ESP_LOGE("BOBBY", "nvs_get() COMMON %s failed with %s", key, esp_err_to_name(result));
}); result = false;
}
});
}
else
{
ESP_LOGW("BOBBY", "common nvs handle not valid!");
result = false;
}
if (m_profile)
{
settings.executeForEveryProfileSetting([&](const char *key, auto &value)
{
if (esp_err_t result = nvsGetterHelper<std::remove_reference_t<decltype(value)>>::nvs_get(m_profile->handle, key, &value); result != ESP_OK)
{
ESP_LOGE("BOBBY", "nvs_get() PROFILE %s failed with %s", key, esp_err_to_name(result));
result = false;
}
});
}
else
{
ESP_LOGW("BOBBY", "no profile open currently!");
result = false;
}
return result; return result;
} }
@@ -224,23 +278,41 @@ template<> struct nvsSetterHelper<wifi_mode_t> { static esp_err_t nvs_set(nvs_ha
bool SettingsPersister::save(Settings &settings) bool SettingsPersister::save(Settings &settings)
{ {
if (!m_profile)
{
//Serial.println("SettingsPersister::save() no profile open currently!");
return false;
}
bool result{true}; bool result{true};
settings.executeForEverySetting([&](const char *key, auto value) if (m_handle)
{ {
esp_err_t err = nvsSetterHelper<decltype(value)>::nvs_set(m_profile->handle, key, value); settings.executeForEveryCommonSetting([&](const char *key, auto value)
if (err != ESP_OK)
{ {
//Serial.printf("nvs_get_i32() for %s returned: %s\r\n", key, esp_err_to_name(err)); if (esp_err_t result = nvsSetterHelper<decltype(value)>::nvs_set(m_handle, key, value); result != ESP_OK)
result = false; {
} ESP_LOGE("BOBBY", "nvs_set() PROFILE %s failed with %s", key, esp_err_to_name(result));
}); result = false;
}
});
}
else
{
ESP_LOGW("BOBBY", "common nvs handle not valid!");
result = false;
}
if (m_profile)
{
settings.executeForEveryProfileSetting([&](const char *key, auto value)
{
if (esp_err_t result = nvsSetterHelper<decltype(value)>::nvs_set(m_profile->handle, key, value); result != ESP_OK)
{
ESP_LOGE("BOBBY", "nvs_set() PROFILE %s failed with %s", key, esp_err_to_name(result));
result = false;
}
});
}
else
{
ESP_LOGW("BOBBY", "no profile open currently!");
result = false;
}
return result; return result;
} }

View File

@@ -1,5 +1,8 @@
#pragma once #pragma once
// esp-idf includes
#include <esp_log.h>
// local includes // local includes
#include "globals.h" #include "globals.h"
#include "presets.h" #include "presets.h"
@@ -9,16 +12,16 @@ void switchProfile(uint8_t index)
{ {
settings = presets::defaultSettings; settings = presets::defaultSettings;
if (settingsPersister.openProfile(index)) if (!settingsPersister.openProfile(index))
{ {
if (!settingsPersister.load(settings)) ESP_LOGE("BOBBY", "openProfile() failed");
{ return;
//Serial.println("switchProfile() load failed");
}
} }
else
if (!settingsPersister.load(settings))
{ {
//Serial.println("switchProfile() openProfile failed"); ESP_LOGE("BOBBY", "load() failed");
return;
} }
} }
} }

View File

@@ -99,13 +99,14 @@ constexpr char TEXT_SWAPFRONTBACK[] = "Swap front/back";
#ifdef FEATURE_CAN #ifdef FEATURE_CAN
constexpr char TEXT_FRONTSENDCAN[] = "Front send CAN"; constexpr char TEXT_FRONTSENDCAN[] = "Front send CAN";
constexpr char TEXT_BACKSENDCAN[] = "Back send CAN"; constexpr char TEXT_BACKSENDCAN[] = "Back send CAN";
constexpr char TEXT_CANTRANSMITTIMEOUT[] = "CanTransmitTimeout";
constexpr char TEXT_CANRECEIVETIMEOUT[] = "CanReceiveTimeout";
#endif #endif
//constexpr char TEXT_BACK[] = "Back"; //constexpr char TEXT_BACK[] = "Back";
//StationWifiSettingsMenu //StationWifiSettingsMenu
constexpr char TEXT_STATIONWIFISETTINGS[] = "Station WiFi settings"; constexpr char TEXT_STATIONWIFISETTINGS[] = "Station WiFi settings";
constexpr char TEXT_AUTOWIFIMODE[] = "Auto wifi mode"; constexpr char TEXT_WIFIENABLED[] = "WiFi enabled";
constexpr char TEXT_AUTOENABLEAP[] = "Auto enable AP";
constexpr char TEXT_WIFIRECONNECT[] = "reconnect()"; constexpr char TEXT_WIFIRECONNECT[] = "reconnect()";
constexpr char TEXT_WIFIDISCONNECT[] = "disconnect()"; constexpr char TEXT_WIFIDISCONNECT[] = "disconnect()";
constexpr char TEXT_WIFICHANGEAUTOCONNECT[] = "Change auto connect"; constexpr char TEXT_WIFICHANGEAUTOCONNECT[] = "Change auto connect";
@@ -310,6 +311,9 @@ constexpr char TEXT_MODEUPDATERATE[] = "Mode update rate";
constexpr char TEXT_STATSUPDATERATE[] = "Stats update rate"; constexpr char TEXT_STATSUPDATERATE[] = "Stats update rate";
constexpr char TEXT_DISPLAYUPDATERATE[] = "Display update rate"; constexpr char TEXT_DISPLAYUPDATERATE[] = "Display update rate";
constexpr char TEXT_DISPLAYREDRAWRATE[] = "Display redraw rate"; constexpr char TEXT_DISPLAYREDRAWRATE[] = "Display redraw rate";
#ifdef FEATURE_CAN
constexpr char TEXT_CANRECEIVERATE[] = "CAN receive rate";
#endif
//constexpr char TEXT_BACK[] = "Back"; //constexpr char TEXT_BACK[] = "Back";
//ChangeValueDisplay<BluetoothMode> //ChangeValueDisplay<BluetoothMode>

View File

@@ -297,7 +297,7 @@ esp_err_t webserver_triggerItem_handler(httpd_req_t *req)
if (!menuDisplay) if (!menuDisplay)
CALL_AND_EXIT(httpd_resp_send_err, req, HTTPD_400_BAD_REQUEST, "currentDisplay is not a menu display"); CALL_AND_EXIT(httpd_resp_send_err, req, HTTPD_400_BAD_REQUEST, "currentDisplay is not a menu display");
if (index < 0 || index >= menuDisplay->menuItemCount()) if (/*index < 0 ||*/ index >= menuDisplay->menuItemCount())
CALL_AND_EXIT(httpd_resp_send_err, req, HTTPD_400_BAD_REQUEST, fmt::format("{} out of range", indexParamName).c_str()); CALL_AND_EXIT(httpd_resp_send_err, req, HTTPD_400_BAD_REQUEST, fmt::format("{} out of range", indexParamName).c_str());
menuDisplay->getMenuItem(index).triggered(); menuDisplay->getMenuItem(index).triggered();

View File

@@ -1,5 +1,8 @@
#pragma once #pragma once
// esp-idf includes
#include <esp_log.h>
// 3rdparty lib includes // 3rdparty lib includes
#include <espwifistack.h> #include <espwifistack.h>
@@ -10,7 +13,7 @@ namespace {
wifi_stack::config wifi_create_config() wifi_stack::config wifi_create_config()
{ {
static wifi_stack::config config { static wifi_stack::config config {
.wifiEnabled = true, .wifiEnabled = settings.wifiSettings.wifiEnabled,
.hostname = deviceName, .hostname = deviceName,
.sta = { .sta = {
.wifis = std::array<wifi_stack::wifi_entry, 10> { .wifis = std::array<wifi_stack::wifi_entry, 10> {
@@ -49,44 +52,21 @@ wifi_stack::config wifi_create_config()
void wifi_begin() void wifi_begin()
{ {
wifi_stack::init(wifi_create_config()); wifi_stack::init(wifi_create_config());
//bootLabel.redraw("setHostname");
//if (!WiFi.setHostname(deviceName))
//{
//Serial.println("Could not setHostname");
//}
//printMemoryStats("setHostname()");
//bootLabel.redraw("softAPsetHostname");
//if (!WiFi.softAPsetHostname(deviceName))
//{
//Serial.println("Could not softAPsetHostname");
//}
//printMemoryStats("softAPsetHostname()");
//bootLabel.redraw("WiFi mode");
//if (!WiFi.mode(settings.wifiSettings.autoWifiMode))
//{
//Serial.println("Could not set mode to WIFI_AP_STA");
//}
//printMemoryStats("WiFi.mode()");
//if (settings.wifiSettings.autoEnableAp)
//{
//bootLabel.redraw("WiFi softAp");
//WifiSoftApAction{}.triggered();
//printMemoryStats("WifiSoftApAction()");
//}
//bootLabel.redraw("WiFi begin");
//if (!WiFi.begin("realraum", "r3alraum"))
//{
//Serial.println("Could not begin WiFi");
//}
//printMemoryStats("WiFi.begin()");
} }
void wifi_update() void wifi_update()
{ {
wifi_stack::update(wifi_create_config()); wifi_stack::update(wifi_create_config());
} }
esp_err_t wifi_scan()
{
if (const auto result = wifi_stack::begin_scan(wifi_create_config()); result != ESP_OK)
{
ESP_LOGE("BOBBY", "begin_scan() failed with %s", esp_err_to_name(result));
return result;
}
return ESP_OK;
}
} // namespace } // namespace