Merge pull request #372 from bobbycar-graz/setup-screen-361
This commit is contained in:
Submodule components/FastLED-idf updated: 3f4d71050e...6a64e87bc3
Submodule components/TFT_eSPI updated: 4dacb617be...39dd567a9e
Submodule components/arduino-esp32 updated: 07f43ec91c...1acd16f991
Submodule components/bobbycar-protocol updated: 701243ad89...0734d65146
Submodule components/esp-gui-lib updated: ab946208e5...0f89f6c994
Submodule components/espconfiglib updated: 6129681a6d...64af48aca0
Submodule components/espwifistack updated: 2bf332f3eb...980a4acd11
@ -1,20 +1,20 @@
|
||||
set(BOBBY_APP_NAME bobbyquad_comred_new)
|
||||
set(BOBBY_DEFAULT_USERNAME comred_new)
|
||||
|
||||
add_definitions(
|
||||
-DUSER_SETUP_LOADED=1
|
||||
-DLOAD_GLCD=1
|
||||
-DLOAD_FONT2=1
|
||||
-DLOAD_FONT4=1
|
||||
-DLOAD_FONT7=1
|
||||
-DILI9341_DRIVER=1
|
||||
-DTFT_MOSI=13
|
||||
-DTFT_SCLK=15
|
||||
-DTFT_CS=14
|
||||
-DTFT_DC=12
|
||||
-DTFT_RST=2
|
||||
-DSPI_FREQUENCY=40000000
|
||||
)
|
||||
# add_definitions(
|
||||
# -DUSER_SETUP_LOADED=1
|
||||
# -DLOAD_GLCD=1
|
||||
# -DLOAD_FONT2=1
|
||||
# -DLOAD_FONT4=1
|
||||
# -DLOAD_FONT7=1
|
||||
# -DILI9341_DRIVER=1
|
||||
# -DTFT_MOSI=13
|
||||
# -DTFT_SCLK=15
|
||||
# -DTFT_CS=14
|
||||
# -DTFT_DC=12
|
||||
# -DTFT_RST=2
|
||||
# -DSPI_FREQUENCY=40000000
|
||||
# )
|
||||
|
||||
set(BOBBYCAR_BUILDFLAGS
|
||||
# Pins
|
||||
|
@ -180,6 +180,7 @@ CONFIG_SOC_WIFI_WAPI_SUPPORT=y
|
||||
CONFIG_SOC_WIFI_CSI_SUPPORT=y
|
||||
CONFIG_SOC_WIFI_MESH_SUPPORT=y
|
||||
CONFIG_SOC_BLE_SUPPORTED=y
|
||||
CONFIG_SOC_BLE_MESH_SUPPORTED=y
|
||||
CONFIG_SOC_BT_CLASSIC_SUPPORTED=y
|
||||
CONFIG_IDF_CMAKE=y
|
||||
CONFIG_IDF_TARGET_ARCH_XTENSA=y
|
||||
@ -665,6 +666,7 @@ CONFIG_SPI_SLAVE_ISR_IN_IRAM=y
|
||||
# MCPWM Configuration
|
||||
#
|
||||
# CONFIG_MCPWM_ISR_IRAM_SAFE is not set
|
||||
# CONFIG_MCPWM_CTRL_FUNC_IN_IRAM is not set
|
||||
# CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set
|
||||
# CONFIG_MCPWM_ENABLE_DEBUG_LOG is not set
|
||||
# end of MCPWM Configuration
|
||||
@ -1733,8 +1735,8 @@ CONFIG_TFT_ILI9341_DRIVER=y
|
||||
# CONFIG_TFT_SSD1963_800ALT_DRIVER is not set
|
||||
# CONFIG_TFT_ILI9225_DRIVER is not set
|
||||
# CONFIG_TFT_GC9A01_DRIVER is not set
|
||||
CONFIG_TFT_RGB_ORDER=y
|
||||
# CONFIG_TFT_BGR_ORDER is not set
|
||||
# CONFIG_TFT_RGB_ORDER is not set
|
||||
CONFIG_TFT_BGR_ORDER=y
|
||||
# CONFIG_TFT_M5STACK is not set
|
||||
CONFIG_TFT_INVERSION_DISABLE=y
|
||||
# CONFIG_TFT_INVERSION_ON is not set
|
||||
@ -1766,12 +1768,13 @@ CONFIG_TFT_RST=2
|
||||
#
|
||||
# CONFIG_TFT_LOAD_GLCD is not set
|
||||
CONFIG_TFT_LOAD_FONT2=y
|
||||
# CONFIG_TFT_LOAD_FONT4 is not set
|
||||
CONFIG_TFT_LOAD_FONT4=y
|
||||
CONFIG_TFT_LOAD_FONT6=y
|
||||
CONFIG_TFT_LOAD_FONT7=y
|
||||
CONFIG_TFT_LOAD_FONT8=y
|
||||
CONFIG_TFT_LOAD_GFXFF=y
|
||||
CONFIG_TFT_SMOOTH_FONT=y
|
||||
# CONFIG_TFT_IS_AUTOBAHN is not set
|
||||
# end of Fonts
|
||||
|
||||
#
|
||||
|
@ -180,6 +180,7 @@ CONFIG_SOC_WIFI_WAPI_SUPPORT=y
|
||||
CONFIG_SOC_WIFI_CSI_SUPPORT=y
|
||||
CONFIG_SOC_WIFI_MESH_SUPPORT=y
|
||||
CONFIG_SOC_BLE_SUPPORTED=y
|
||||
CONFIG_SOC_BLE_MESH_SUPPORTED=y
|
||||
CONFIG_SOC_BT_CLASSIC_SUPPORTED=y
|
||||
CONFIG_IDF_CMAKE=y
|
||||
CONFIG_IDF_TARGET_ARCH_XTENSA=y
|
||||
@ -665,6 +666,7 @@ CONFIG_SPI_SLAVE_ISR_IN_IRAM=y
|
||||
# MCPWM Configuration
|
||||
#
|
||||
# CONFIG_MCPWM_ISR_IRAM_SAFE is not set
|
||||
# CONFIG_MCPWM_CTRL_FUNC_IN_IRAM is not set
|
||||
# CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set
|
||||
# CONFIG_MCPWM_ENABLE_DEBUG_LOG is not set
|
||||
# end of MCPWM Configuration
|
||||
@ -1773,6 +1775,7 @@ CONFIG_TFT_LOAD_FONT7=y
|
||||
CONFIG_TFT_LOAD_FONT8=y
|
||||
CONFIG_TFT_LOAD_GFXFF=y
|
||||
CONFIG_TFT_SMOOTH_FONT=y
|
||||
# CONFIG_TFT_IS_AUTOBAHN is not set
|
||||
# end of Fonts
|
||||
|
||||
#
|
||||
|
@ -4,6 +4,6 @@ dependencies:
|
||||
source:
|
||||
type: idf
|
||||
version: 5.1.0
|
||||
manifest_hash: 61ebe3a040bdb7a8bb7b582261db12d83b6028789124b5f6ddacb4104628daa6
|
||||
manifest_hash: 9a4f2dfb2ab76ca07dad44e92970eea272a02162afa87b1dc511d285966e0252
|
||||
target: esp32
|
||||
version: 1.0.0
|
||||
|
2
esp-idf
2
esp-idf
Submodule esp-idf updated: 756de87ccf...036e4cc64b
Submodule esp-protocols updated: 49e1369ae9...d8db56f89e
@ -1,4 +1,4 @@
|
||||
set(headers
|
||||
set(BOBBY_HEADERS
|
||||
accessorhelpers.h
|
||||
accessors/globalaccessors.h
|
||||
accessors/settingsaccessors.h
|
||||
@ -26,6 +26,7 @@ set(headers
|
||||
actions/rebootaction.h
|
||||
actions/resetnvsaction.h
|
||||
actions/savesettingsaction.h
|
||||
actions/setupactions.h
|
||||
actions/switchprofileaction.h
|
||||
actions/tempomatmodeapplycurrentpeedaction.h
|
||||
actions/updateswapfrontbackaction.h
|
||||
@ -72,7 +73,6 @@ set(headers
|
||||
displays/bobbymenudisplay.h
|
||||
displays/bobbypopupdisplay.h
|
||||
displays/bobbysplitgraphdisplay.h
|
||||
displays/buttoncalibratedisplay.h
|
||||
displays/calibratevoltagedisplay.h
|
||||
displays/confiscationdisplay.h
|
||||
displays/gameoflifedisplay.h
|
||||
@ -159,6 +159,13 @@ set(headers
|
||||
displays/qrcodedebug.h
|
||||
displays/qrdisplay.h
|
||||
displays/qrimportdisplay.h
|
||||
displays/setup/ask_calibrate_other_buttons.h
|
||||
displays/setup/ask_setup_clouds.h
|
||||
displays/setup/basic_buttons.h
|
||||
displays/setup/calibrate_potis.h
|
||||
displays/setup/final_information.h
|
||||
displays/setup/information.h
|
||||
displays/setup/setup_cloud.h
|
||||
displays/speedinfodisplay.h
|
||||
displays/spirodisplay.h
|
||||
displays/starfielddisplay.h
|
||||
@ -233,6 +240,7 @@ set(headers
|
||||
serial_bobby.h
|
||||
settingspersister.h
|
||||
settingsutils.h
|
||||
setup.h
|
||||
softpwmlimiter.h
|
||||
statistics.h
|
||||
statustexthelper.h
|
||||
@ -259,7 +267,7 @@ set(headers
|
||||
wifiguiutils.h
|
||||
)
|
||||
|
||||
set(sources
|
||||
set(BOBBY_SOURCES
|
||||
accessors/wifistaconfigaccessors.cpp
|
||||
actions/assertaction.cpp
|
||||
actions/bluetoothbeginaction.cpp
|
||||
@ -282,6 +290,7 @@ set(sources
|
||||
actions/rebootaction.cpp
|
||||
actions/resetnvsaction.cpp
|
||||
actions/savesettingsaction.cpp
|
||||
actions/setupactions.cpp
|
||||
actions/switchprofileaction.cpp
|
||||
actions/tempomatmodeapplycurrentpeedaction.cpp
|
||||
actions/updateswapfrontbackaction.cpp
|
||||
@ -325,7 +334,6 @@ set(sources
|
||||
displays/bobbymenudisplay.cpp
|
||||
displays/bobbypopupdisplay.cpp
|
||||
displays/bobbysplitgraphdisplay.cpp
|
||||
displays/buttoncalibratedisplay.cpp
|
||||
displays/calibratevoltagedisplay.cpp
|
||||
displays/confiscationdisplay.cpp
|
||||
displays/gameoflifedisplay.cpp
|
||||
@ -410,6 +418,13 @@ set(sources
|
||||
displays/qrcodedebug.cpp
|
||||
displays/qrdisplay.cpp
|
||||
displays/qrimportdisplay.cpp
|
||||
displays/setup/ask_calibrate_other_buttons.cpp
|
||||
displays/setup/ask_setup_clouds.cpp
|
||||
displays/setup/basic_buttons.cpp
|
||||
displays/setup/calibrate_potis.cpp
|
||||
displays/setup/final_information.cpp
|
||||
displays/setup/information.cpp
|
||||
displays/setup/setup_cloud.cpp
|
||||
displays/speedinfodisplay.cpp
|
||||
displays/spirodisplay.cpp
|
||||
displays/starfielddisplay.cpp
|
||||
@ -485,6 +500,7 @@ set(sources
|
||||
serial_bobby.cpp
|
||||
settingspersister.cpp
|
||||
settingsutils.cpp
|
||||
setup.cpp
|
||||
softpwmlimiter.cpp
|
||||
statistics.cpp
|
||||
statustexthelper.cpp
|
||||
@ -519,8 +535,8 @@ set(dependencies
|
||||
|
||||
idf_component_register(
|
||||
SRCS
|
||||
${headers}
|
||||
${sources}
|
||||
${BOBBY_HEADERS}
|
||||
${BOBBY_SOURCES}
|
||||
INCLUDE_DIRS
|
||||
.
|
||||
REQUIRES
|
||||
@ -538,14 +554,31 @@ execute_process(
|
||||
COMMAND git rev-parse --abbrev-ref HEAD
|
||||
OUTPUT_VARIABLE GIT_BRANCH
|
||||
)
|
||||
execute_process(
|
||||
COMMAND git status --short
|
||||
OUTPUT_VARIABLE GIT_STATUS
|
||||
)
|
||||
|
||||
if (NOT GIT_STATUS STREQUAL "")
|
||||
set(GIT_STATUS "dirty")
|
||||
else()
|
||||
set(GIT_STATUS "clean")
|
||||
endif()
|
||||
|
||||
string(STRIP "${GIT_REV}" GIT_REV)
|
||||
string(SUBSTRING "${GIT_REV}" 1 7 GIT_SHORT_REV)
|
||||
string(STRIP "${GIT_MESSAGE}" GIT_MESSAGE)
|
||||
string(REPLACE "\n" " " GIT_MESSAGE "${GIT_MESSAGE}")
|
||||
string(REPLACE "\"" "\\\"" GIT_MESSAGE "${GIT_MESSAGE}")
|
||||
string(SUBSTRING "${GIT_MESSAGE}" 0 100 GIT_MESSAGE)
|
||||
string(STRIP "${GIT_BRANCH}" GIT_BRANCH)
|
||||
|
||||
message(WARNING "Git revision: ${GIT_REV}")
|
||||
message(WARNING "Git short revision: ${GIT_SHORT_REV}")
|
||||
message(WARNING "Git message: ${GIT_MESSAGE}")
|
||||
message(WARNING "Git branch: ${GIT_BRANCH}")
|
||||
message(WARNING "Git status: ${GIT_STATUS}")
|
||||
|
||||
if(NOT DEFINED BOBBY_DEFAULT_USERNAME)
|
||||
message(FATAL_ERROR "Please define BOBBY_DEFAULT_USERNAME")
|
||||
endif()
|
||||
|
@ -32,7 +32,6 @@ private:
|
||||
std::string m_msg;
|
||||
};
|
||||
|
||||
template<typename TMenu>
|
||||
class PushQrImportDisplayAction : public virtual espgui::ActionInterface
|
||||
{
|
||||
public:
|
||||
@ -41,7 +40,7 @@ public:
|
||||
|
||||
void triggered() override
|
||||
{
|
||||
espgui::pushScreen<QrImportDisplay<TMenu>>(std::move(m_nvskey));
|
||||
espgui::pushScreen<QrImportDisplay>(std::move(m_nvskey));
|
||||
}
|
||||
private:
|
||||
std::string m_nvskey;
|
||||
|
@ -1,11 +0,0 @@
|
||||
#include "resetnvsaction.h"
|
||||
|
||||
// system includes
|
||||
#include <esp_system.h>
|
||||
#include <nvs_flash.h>
|
||||
|
||||
void ResetNVSAction::triggered()
|
||||
{
|
||||
nvs_flash_erase();
|
||||
esp_restart();
|
||||
}
|
||||
|
@ -1,10 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
// system includes
|
||||
#include <esp_system.h>
|
||||
|
||||
// 3rdparty lib includes
|
||||
#include <actioninterface.h>
|
||||
#include <tftinstance.h>
|
||||
|
||||
// local includes
|
||||
#include "newsettings.h"
|
||||
|
||||
template<bool reboot>
|
||||
class ResetNVSAction : public virtual espgui::ActionInterface
|
||||
{
|
||||
public:
|
||||
void triggered() override;
|
||||
void triggered() override
|
||||
{
|
||||
if (reboot)
|
||||
{
|
||||
espgui::tft.fillScreen(TFT_BLACK);
|
||||
espgui::tft.setTextColor(TFT_YELLOW);
|
||||
|
||||
espgui::tft.drawString("Reboot", 5, 5, 4);
|
||||
|
||||
espgui::tft.fillRect(0, 34, espgui::tft.width(), 3, TFT_WHITE);
|
||||
|
||||
espgui::tft.setTextColor(TFT_WHITE);
|
||||
espgui::tft.drawString("Rebooting now...", 0, 50, 4);
|
||||
|
||||
configs.reset();
|
||||
|
||||
esp_restart();
|
||||
}
|
||||
else
|
||||
{
|
||||
configs.reset();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
26
main/actions/setupactions.cpp
Normal file
26
main/actions/setupactions.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
#include "setupactions.h"
|
||||
|
||||
// 3rdparty lib includes
|
||||
#include <screenmanager.h>
|
||||
|
||||
// local includes
|
||||
#include "displays/setup/basic_buttons.h"
|
||||
#include "displays/setup/calibrate_potis.h"
|
||||
|
||||
PushButtonCalibrateDisplayAction::PushButtonCalibrateDisplayAction(const bool early_return) :
|
||||
m_early_return{early_return}
|
||||
{}
|
||||
|
||||
void PushButtonCalibrateDisplayAction::triggered()
|
||||
{
|
||||
espgui::pushScreen<SetupBasicButtonsDisplay>(m_early_return);
|
||||
}
|
||||
|
||||
PushPotiCalibrateDisplayAction::PushPotiCalibrateDisplayAction(const bool early_return) :
|
||||
m_early_return{early_return}
|
||||
{}
|
||||
|
||||
void PushPotiCalibrateDisplayAction::triggered()
|
||||
{
|
||||
// espgui::pushScreen<SetupCalibratePotisDisplay>(m_early_return); // commented out until implemented
|
||||
}
|
24
main/actions/setupactions.h
Normal file
24
main/actions/setupactions.h
Normal file
@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
// 3rdparty lib includes
|
||||
#include <actioninterface.h>
|
||||
|
||||
class PushButtonCalibrateDisplayAction : public virtual espgui::ActionInterface
|
||||
{
|
||||
public:
|
||||
explicit PushButtonCalibrateDisplayAction(bool early_return);
|
||||
|
||||
void triggered() override;
|
||||
private:
|
||||
const bool m_early_return;
|
||||
};
|
||||
|
||||
class PushPotiCalibrateDisplayAction : public virtual espgui::ActionInterface
|
||||
{
|
||||
public:
|
||||
explicit PushPotiCalibrateDisplayAction(bool early_return);
|
||||
|
||||
void triggered() override;
|
||||
private:
|
||||
const bool m_early_return;
|
||||
};
|
@ -590,7 +590,7 @@ void updateCloud()
|
||||
lastCloudSend = now;
|
||||
}
|
||||
|
||||
if (!lastHeartbeat || now - *lastHeartbeat >= 1500ms)
|
||||
if (!lastHeartbeat || now - *lastHeartbeat >= 1500ms && !configs.cloudSettings.cloudKey.value().empty())
|
||||
{
|
||||
cloudHeartbeat();
|
||||
lastHeartbeat = now;
|
||||
@ -743,7 +743,7 @@ void cloudSend()
|
||||
|
||||
const auto timeout = std::chrono::ceil<espcpputils::ticks>(espchrono::milliseconds32{configs.cloudSettings.cloudTransmitTimeout.value()}).count();
|
||||
|
||||
if (!hasAnnouncedItself && configs.cloudSettings.cloudEnabled.value())
|
||||
if (!hasAnnouncedItself && configs.cloudSettings.cloudEnabled.value() && !configs.cloudSettings.cloudKey.value().empty())
|
||||
{
|
||||
std::string helloWorld = getLoginMessage();
|
||||
ESP_LOGW(TAG, "=====> %s", helloWorld.c_str());
|
||||
|
@ -38,7 +38,7 @@ void BobbyGraphDisplay<COUNT>::rawButtonReleased(uint8_t button)
|
||||
template<size_t COUNT>
|
||||
void BobbyGraphDisplay<COUNT>::buttonPressed(espgui::Button button)
|
||||
{
|
||||
//Base::buttonPressed(button);
|
||||
Base::buttonPressed(button);
|
||||
buttonPressedCommon(button);
|
||||
}
|
||||
|
||||
|
@ -1,221 +0,0 @@
|
||||
#include "buttoncalibratedisplay.h"
|
||||
|
||||
// esp-idf includes
|
||||
#include <esp_log.h>
|
||||
|
||||
// 3rdparty lib includes
|
||||
#include <tftinstance.h>
|
||||
#include <fmt/core.h>
|
||||
#include <screenmanager.h>
|
||||
|
||||
// local includes
|
||||
#include "bobbyerrorhandler.h"
|
||||
#include "displays/statusdisplay.h"
|
||||
#include "newsettings.h"
|
||||
|
||||
namespace {
|
||||
constexpr const char TAG[] = "BUTTON";
|
||||
} // namespace
|
||||
|
||||
std::string ButtonCalibrateDisplay::text() const
|
||||
{
|
||||
return "Button calibrate";
|
||||
}
|
||||
|
||||
void ButtonCalibrateDisplay::start()
|
||||
{
|
||||
Base::start();
|
||||
|
||||
m_oldMode = currentMode;
|
||||
currentMode = &m_mode;
|
||||
m_lastButton = std::nullopt;
|
||||
m_status = WaitingLeft;
|
||||
|
||||
m_finished = false;
|
||||
}
|
||||
|
||||
void ButtonCalibrateDisplay::initScreen()
|
||||
{
|
||||
Base::initScreen();
|
||||
|
||||
m_labelInstruction.start();
|
||||
m_labelLeft.start();
|
||||
m_labelRight.start();
|
||||
m_labelUp.start();
|
||||
m_labelDown.start();
|
||||
m_labelEnd.start();
|
||||
}
|
||||
|
||||
void ButtonCalibrateDisplay::update()
|
||||
{
|
||||
Base::update();
|
||||
|
||||
if (m_finished)
|
||||
{
|
||||
m_finished = false;
|
||||
|
||||
if (auto result = configs.write_config(configs.dpadMappingLeft, m_leftButton); !result)
|
||||
{
|
||||
BobbyErrorHandler{}.errorOccurred(std::move(result).error());
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGI(TAG, "Left button set to %d", m_leftButton);
|
||||
}
|
||||
|
||||
if (auto result = configs.write_config(configs.dpadMappingRight, m_rightButton); !result)
|
||||
{
|
||||
BobbyErrorHandler{}.errorOccurred(std::move(result).error());
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGI(TAG, "Right button set to %d", m_rightButton);
|
||||
}
|
||||
if (auto result = configs.write_config(configs.dpadMappingUp, m_upButton); !result)
|
||||
{
|
||||
BobbyErrorHandler{}.errorOccurred(std::move(result).error());
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGI(TAG, "Up button set to %d", m_upButton);
|
||||
}
|
||||
if (auto result = configs.write_config(configs.dpadMappingDown, m_downButton); !result)
|
||||
{
|
||||
BobbyErrorHandler{}.errorOccurred(std::move(result).error());
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGI(TAG, "Down button set to %d", m_downButton);
|
||||
}
|
||||
|
||||
if (espgui::displayStack.empty())
|
||||
{
|
||||
espgui::switchScreen<StatusDisplay>();
|
||||
}
|
||||
else
|
||||
espgui::popScreen();
|
||||
}
|
||||
}
|
||||
|
||||
void ButtonCalibrateDisplay::redraw()
|
||||
{
|
||||
Base::redraw();
|
||||
|
||||
espgui::tft.setTextColor(TFT_WHITE, TFT_BLACK);
|
||||
|
||||
switch (m_status)
|
||||
{
|
||||
case WaitingLeft:
|
||||
if (m_lastButton)
|
||||
m_labelInstruction.redraw("Press LEFT again");
|
||||
else
|
||||
m_labelInstruction.redraw("Press LEFT");
|
||||
break;
|
||||
case WaitingRight:
|
||||
if (m_lastButton)
|
||||
m_labelInstruction.redraw("Press RIGHT again");
|
||||
else
|
||||
m_labelInstruction.redraw("Press RIGHT");
|
||||
break;
|
||||
case WaitingUp:
|
||||
if (m_lastButton)
|
||||
m_labelInstruction.redraw("Press UP again");
|
||||
else
|
||||
m_labelInstruction.redraw("Press UP");
|
||||
break;
|
||||
case WaitingDown:
|
||||
if (m_lastButton)
|
||||
m_labelInstruction.redraw("Press DOWN again");
|
||||
else
|
||||
m_labelInstruction.redraw("Press DOWN");
|
||||
break;
|
||||
case Finished:
|
||||
m_labelInstruction.redraw("Finished");
|
||||
break;
|
||||
}
|
||||
|
||||
m_labelLeft.redraw(m_status > WaitingLeft ? fmt::format("Left: {}", m_leftButton) : std::string{});
|
||||
m_labelRight.redraw(m_status > WaitingRight ? fmt::format("Right: {}", m_rightButton) : std::string{});
|
||||
m_labelUp.redraw(m_status > WaitingUp ? fmt::format("Up: {}", m_upButton) : std::string{});
|
||||
m_labelDown.redraw(m_status > WaitingDown ? fmt::format("Down: {}", m_downButton) : std::string{});
|
||||
|
||||
m_labelEnd.redraw(m_status == Finished ? "Press RIGHT to save" : "");
|
||||
}
|
||||
|
||||
void ButtonCalibrateDisplay::stop()
|
||||
{
|
||||
Base::stop();
|
||||
|
||||
if (currentMode == &m_mode)
|
||||
{
|
||||
// to avoid crash after deconstruction
|
||||
m_mode.stop();
|
||||
lastMode = nullptr;
|
||||
|
||||
currentMode = m_oldMode;
|
||||
}
|
||||
}
|
||||
|
||||
void ButtonCalibrateDisplay::rawButtonPressed(uint8_t button)
|
||||
{
|
||||
//Base::rawButtonPressed(button);
|
||||
|
||||
if (m_status == Finished)
|
||||
{
|
||||
if (button == m_rightButton)
|
||||
{
|
||||
ESP_LOGI(TAG, "correct button");
|
||||
m_finished = true;
|
||||
}
|
||||
else
|
||||
ESP_LOGI(TAG, "wrong button");
|
||||
}
|
||||
else if (!m_lastButton || *m_lastButton != button)
|
||||
m_lastButton = button;
|
||||
else
|
||||
{
|
||||
switch (m_status)
|
||||
{
|
||||
case WaitingLeft:
|
||||
m_leftButton = button;
|
||||
m_lastButton = std::nullopt;
|
||||
m_status = WaitingRight;
|
||||
break;
|
||||
case WaitingRight:
|
||||
m_rightButton = button;
|
||||
m_lastButton = std::nullopt;
|
||||
m_status = WaitingUp;
|
||||
break;
|
||||
case WaitingUp:
|
||||
m_upButton = button;
|
||||
m_lastButton = std::nullopt;
|
||||
m_status = WaitingDown;
|
||||
break;
|
||||
case WaitingDown:
|
||||
m_downButton = button;
|
||||
m_lastButton = std::nullopt;
|
||||
m_status = Finished;
|
||||
break;
|
||||
case Finished:;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ButtonCalibrateDisplay::rawButtonReleased(uint8_t button)
|
||||
{
|
||||
//Base::rawButtonReleased(button);
|
||||
}
|
||||
|
||||
void ButtonCalibrateDisplay::buttonPressed(espgui::Button button)
|
||||
{
|
||||
//Base::buttonPressed(button);
|
||||
}
|
||||
|
||||
void ButtonCalibrateDisplay::buttonReleased(espgui::Button button)
|
||||
{
|
||||
//Base::buttonReleased(button);
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// 3rdparty lib includes
|
||||
#include <displaywithtitle.h>
|
||||
#include <widgets/label.h>
|
||||
|
||||
// local includes
|
||||
#include "globals.h"
|
||||
#include "modeinterface.h"
|
||||
#include "modes/ignoreinputmode.h"
|
||||
|
||||
class ButtonCalibrateDisplay : public espgui::DisplayWithTitle
|
||||
{
|
||||
using Base = espgui::DisplayWithTitle;
|
||||
|
||||
public:
|
||||
ButtonCalibrateDisplay() = default;
|
||||
explicit ButtonCalibrateDisplay(bool bootup) : m_bootup{bootup} {}
|
||||
|
||||
std::string text() const override;
|
||||
void start() override;
|
||||
void initScreen() override;
|
||||
void update() override;
|
||||
void redraw() override;
|
||||
void stop() override;
|
||||
|
||||
void rawButtonPressed(uint8_t button) override;
|
||||
void rawButtonReleased(uint8_t button) override;
|
||||
void buttonPressed(espgui::Button button) override;
|
||||
void buttonReleased(espgui::Button button) override;
|
||||
|
||||
private:
|
||||
const bool m_bootup{false};
|
||||
ModeInterface *m_oldMode;
|
||||
IgnoreInputMode m_mode{0, bobbycar::protocol::ControlType::FieldOrientedControl, bobbycar::protocol::ControlMode::Torque};
|
||||
|
||||
std::optional<uint8_t> m_lastButton;
|
||||
|
||||
enum { WaitingLeft, WaitingRight, WaitingUp, WaitingDown, Finished } m_status;
|
||||
|
||||
espgui::Label m_labelInstruction{25, 72};
|
||||
|
||||
espgui::Label m_labelLeft{25, 100};
|
||||
espgui::Label m_labelRight{25, 125};
|
||||
espgui::Label m_labelUp{25, 150};
|
||||
espgui::Label m_labelDown{25, 175};
|
||||
|
||||
espgui::Label m_labelEnd{25, 225};
|
||||
|
||||
uint8_t m_leftButton, m_rightButton, m_upButton, m_downButton;
|
||||
|
||||
bool m_finished;
|
||||
};
|
@ -106,10 +106,7 @@ void Lockscreen::redraw()
|
||||
{
|
||||
if (isValid1stPin(m_numbers))
|
||||
{
|
||||
if (!gas || !brems || *gas > 200.f || *brems > 200.f)
|
||||
espgui::switchScreen<PotisCalibrateDisplay>(true);
|
||||
else
|
||||
espgui::popScreen();
|
||||
espgui::popScreen();
|
||||
#ifdef LOCKSCREEN_PLUGIN
|
||||
#include LOCKSCREEN_PLUGIN
|
||||
LOCKSCREEN_PLUGIN_FIXES_1
|
||||
@ -118,10 +115,7 @@ LOCKSCREEN_PLUGIN_FIXES_1
|
||||
}
|
||||
else if(isValid2ndPin(m_numbers))
|
||||
{
|
||||
if (!gas || !brems || *gas > 200.f || *brems > 200.f)
|
||||
espgui::switchScreen<PotisCalibrateDisplay>(true);
|
||||
else
|
||||
espgui::popScreen();
|
||||
espgui::popScreen();
|
||||
#ifdef LOCKSCREEN_PLUGIN_FIXES_2
|
||||
LOCKSCREEN_PLUGIN_FIXES_2
|
||||
#endif
|
||||
|
@ -88,7 +88,6 @@ BatteryMenu::BatteryMenu()
|
||||
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_BATTERY_WHKM, BatteryWHperKMAccessor>, PushScreenAction<BatteryWHperKMChangeScreen>>>();
|
||||
constructMenuItem<PushScreenTypeSafeChangeMenuItem<BatteryCellType, TEXT_SELECT_CELL_TYPE>>(&configs.battery.cellType);
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SHOW_BATTERY_GRAPH>, PushScreenAction<BatteryGraphDisplay>, StaticMenuItemIcon<&bobbyicons::graph>>>();
|
||||
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
|
||||
constructMenuItem<makeComponent<MenuItem, WhStatisticsText, DummyAction>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERY_CALIBRATE>, PushScreenAction<CalibrateVoltageDisplay>, StaticMenuItemIcon<&bobbyicons::settings>>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, PopScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>();
|
||||
|
@ -11,9 +11,9 @@
|
||||
|
||||
// local includes
|
||||
#include "accessors/settingsaccessors.h"
|
||||
#include "actions/setupactions.h"
|
||||
#include "bobbycheckbox.h"
|
||||
#include "displays/bobbychangevaluedisplay.h"
|
||||
#include "displays/buttoncalibratedisplay.h"
|
||||
#include "displays/menus/extrabuttoncalibratemenu.h"
|
||||
#include "displays/menus/lockscreensettingsmenu.h"
|
||||
#include "displays/menus/setupquickactionsmenu.h"
|
||||
@ -192,12 +192,12 @@ using namespace espgui;
|
||||
BoardcomputerHardwareSettingsMenu::BoardcomputerHardwareSettingsMenu()
|
||||
{
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LOCKSCREENSETTINGS>, PushScreenAction<LockscreenSettingsMenu>, StaticMenuItemIcon<&bobbyicons::lock>>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BUTTONCALIBRATE>, PushScreenAction<ButtonCalibrateDisplay>>>();
|
||||
constructMenuItem<makeComponentArgs<MenuItem, PushButtonCalibrateDisplayAction, StaticText<TEXT_BUTTONCALIBRATE>>>(true);
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_EXTRABUTTONCALIBRATE>, PushScreenAction<ExtraButtonCalibrateMenu>>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_QUICKACTIONS>, PushScreenAction<SetupQuickActionsMenu>>>();
|
||||
constructMenuItem<makeComponent<MenuItem, GasText, DisabledColor, StaticFont<2>, DummyAction>>();
|
||||
constructMenuItem<makeComponent<MenuItem, BremsText, DisabledColor, StaticFont<2>, DummyAction>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_POTISCALIBRATE>, PushScreenAction<PotisCalibrateDisplay>>>();
|
||||
constructMenuItem<makeComponentArgs<MenuItem, PushPotiCalibrateDisplayAction, StaticText<TEXT_POTISCALIBRATE>>>(true);
|
||||
#ifdef FEATURE_JOYSTICK
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_JOYSTICK>, PushScreenAction<JoystickDebugDisplay>>>();
|
||||
#endif
|
||||
|
@ -13,8 +13,10 @@
|
||||
#include "actions/loadsettingsaction.h"
|
||||
#include "actions/savesettingsaction.h"
|
||||
#include "actions/erasenvsaction.h"
|
||||
#include "actions/resetnvsaction.h"
|
||||
#include "icons/lock.h"
|
||||
#include "icons/battery.h"
|
||||
#include "icons/info.h"
|
||||
#include "debugcolorhelpers.h"
|
||||
#include "esptexthelpers.h"
|
||||
#include "accessors/settingsaccessors.h"
|
||||
@ -57,6 +59,7 @@ constexpr char TEXT_TOGGLECLOUDDEBUG[] = "Cloud Debug";
|
||||
constexpr char TEXT_LOADSETTINGS[] = "Load settings (old)";
|
||||
constexpr char TEXT_SAVESETTINGS[] = "Save settings (old)";
|
||||
constexpr char TEXT_ERASENVS[] = "Erase NVS (old)";
|
||||
constexpr char TEXT_RESET_NVS_NEW[] = "Reset NVS (new)";
|
||||
constexpr char TEXT_DYNAMICMENU[] = "GUI experiments";
|
||||
constexpr char TEXT_BACK[] = "Back";
|
||||
} // namespace
|
||||
@ -99,6 +102,8 @@ DebugMenu::DebugMenu()
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LOADSETTINGS>, LoadSettingsAction>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SAVESETTINGS>, SaveSettingsAction>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ERASENVS>, EraseNvsAction>>();
|
||||
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_RESET_NVS_NEW>, ResetNVSAction<true>, StaticMenuItemIcon<&bobbyicons::info>>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_DYNAMICMENU>, PushScreenAction<DynamicDebugMenu>>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, PopScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>();
|
||||
}
|
||||
|
@ -15,6 +15,8 @@
|
||||
|
||||
namespace {
|
||||
constexpr char TEXT_GRAPHS[] = "Graphs";
|
||||
constexpr char TEXT_RAW_GAS[] = "Raw Gas";
|
||||
constexpr char TEXT_RAW_BREMS[] = "Raw Brems";
|
||||
constexpr char TEXT_GAS[] = "Gas";
|
||||
constexpr char TEXT_BREMS[] = "Brems";
|
||||
constexpr char TEXT_POTIS[] = "Potis";
|
||||
@ -32,6 +34,20 @@ constexpr char TEXT_MOTORCURRENTS[] = "Motor currents";
|
||||
constexpr char TEXT_RSSI[] = "RSSI";
|
||||
constexpr char TEXT_BACK[] = "Back";
|
||||
|
||||
using RawGasGraphDisplay = espgui::makeComponent<
|
||||
BobbyGraphDisplay<1>,
|
||||
espgui::StaticText<TEXT_RAW_GAS>,
|
||||
espgui::SingleGraphAccessor<RawGasStatistics>,
|
||||
espgui::ConfirmActionInterface<espgui::PopScreenAction>,
|
||||
espgui::BackActionInterface<espgui::PopScreenAction>
|
||||
>;
|
||||
using RawBremsGraphDisplay = espgui::makeComponent<
|
||||
BobbyGraphDisplay<1>,
|
||||
espgui::StaticText<TEXT_RAW_BREMS>,
|
||||
espgui::SingleGraphAccessor<RawBremsStatistics>,
|
||||
espgui::ConfirmActionInterface<espgui::PopScreenAction>,
|
||||
espgui::BackActionInterface<espgui::PopScreenAction>
|
||||
>;
|
||||
using GasGraphDisplay = espgui::makeComponent<
|
||||
BobbyGraphDisplay<1>,
|
||||
espgui::StaticText<TEXT_GAS>,
|
||||
@ -173,6 +189,8 @@ using RssiGraphDisplay = espgui::makeComponent<
|
||||
GraphsMenu::GraphsMenu()
|
||||
{
|
||||
using namespace espgui;
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_RAW_GAS>, PushScreenAction<RawGasGraphDisplay>>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_RAW_BREMS>, PushScreenAction<RawBremsGraphDisplay>>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_GAS>, PushScreenAction<GasGraphDisplay>>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BREMS>, PushScreenAction<BremsGraphDisplay>>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_POTIS>, PushScreenAction<PotisGraphDisplay>>>();
|
||||
|
@ -81,7 +81,7 @@ GreenPassMenu::GreenPassMenu()
|
||||
}
|
||||
else
|
||||
{
|
||||
constructMenuItem<makeComponentArgs<MenuItem, PushQrImportDisplayAction<GreenPassMenu>, StaticText<TEXT_ADDCERT>>>(std::move(nvs_key));
|
||||
constructMenuItem<makeComponentArgs<MenuItem, PushQrImportDisplayAction, StaticText<TEXT_ADDCERT>>>(std::move(nvs_key));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ RecoveryMenu::RecoveryMenu()
|
||||
configs.callForEveryFeature([&](ConfiguredFeatureFlag &feature){
|
||||
constructMenuItem<BasicFeatureFlagMenuItem>(feature);
|
||||
});
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_RESET_NVS>, ResetNVSAction, StaticMenuItemIcon<&bobbyicons::info>>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_RESET_NVS>, ResetNVSAction<false>, StaticMenuItemIcon<&bobbyicons::info>>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_REBOOT>, RebootAction, StaticMenuItemIcon<&bobbyicons::reboot>>>();
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ public:
|
||||
- converted.hours()
|
||||
- converted.minutes()
|
||||
- converted.seconds();
|
||||
return fmt::format("Up: {:02d}:{:02d}:{:02d}&s&7.{:03d}",
|
||||
return fmt::format("Up: {:02d}:{:02d}:{:02d}&s&7.{:01d}",
|
||||
converted.hours().count(),
|
||||
converted.minutes().count(),
|
||||
converted.seconds().count(),
|
||||
@ -93,7 +93,7 @@ public:
|
||||
- converted.hours()
|
||||
- converted.minutes()
|
||||
- converted.seconds();
|
||||
return fmt::format("Drive: {:02d}:{:02d}:{:02d}&s&7.{:03d}",
|
||||
return fmt::format("Drive: {:02d}:{:02d}:{:02d}&s&7.{:02d}",
|
||||
converted.hours().count(),
|
||||
converted.minutes().count(),
|
||||
converted.seconds().count(),
|
||||
|
@ -16,6 +16,7 @@ namespace {
|
||||
constexpr char TEXT_CALIBRATE[] = "Potis Calibrate";
|
||||
} // namespace
|
||||
|
||||
/*
|
||||
std::string PotisCalibrateDisplay::text() const
|
||||
{
|
||||
return TEXT_CALIBRATE;
|
||||
@ -320,3 +321,4 @@ void PotisCalibrateDisplay::copyToSettings()
|
||||
configs.write_config(configs.bremsMin, m_bremsMin);
|
||||
configs.write_config(configs.bremsMax, m_bremsMax);
|
||||
}
|
||||
*/
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "modeinterface.h"
|
||||
#include "modes/ignoreinputmode.h"
|
||||
|
||||
/*
|
||||
class PotisCalibrateDisplay : public BobbyDisplayWithTitle
|
||||
{
|
||||
using Base = BobbyDisplayWithTitle;
|
||||
@ -90,3 +91,4 @@ private:
|
||||
;
|
||||
std::optional<float> m_gas, m_brems;
|
||||
};
|
||||
*/
|
||||
|
@ -0,0 +1,92 @@
|
||||
#include "qrimportdisplay.h"
|
||||
|
||||
namespace {
|
||||
constexpr const char * const TAG = "qrimport";
|
||||
}
|
||||
|
||||
void QrImportDisplay::start()
|
||||
{
|
||||
using namespace espgui;
|
||||
Base::start();
|
||||
|
||||
m_statuslabel.start();
|
||||
|
||||
qrimport::setup_request();
|
||||
|
||||
if (const auto result = qrimport::start_qr_request(); result)
|
||||
{
|
||||
ESP_LOGI(TAG, "started request, waiting for result");
|
||||
m_waitingForResult = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG, "could not start request: %.*s", result.error().size(), result.error().data());
|
||||
m_result = tl::make_unexpected(std::move(result).error());
|
||||
}
|
||||
}
|
||||
|
||||
void QrImportDisplay::update()
|
||||
{
|
||||
using namespace espgui;
|
||||
Base::update();
|
||||
|
||||
if (!m_waitingForResult)
|
||||
return;
|
||||
|
||||
if (qrimport::get_request_running())
|
||||
return;
|
||||
|
||||
m_waitingForResult = false;
|
||||
|
||||
m_result = qrimport::check_request();
|
||||
if (m_result)
|
||||
{
|
||||
ESP_LOGI(TAG, "%.*s => %.*s", m_nvs_key.size(), m_nvs_key.data(), m_result->size(), m_result->data());
|
||||
if (const auto result = qrimport::set_qr_code(m_nvs_key, *m_result); !result)
|
||||
m_result = tl::make_unexpected(fmt::format("saving qr failed: {}", esp_err_to_name(result.error())));
|
||||
}
|
||||
else
|
||||
ESP_LOGW(TAG, "failed %.*s => %.*s", m_nvs_key.size(), m_nvs_key.data(), m_result.error().size(), m_result.error().data());
|
||||
}
|
||||
|
||||
void QrImportDisplay::redraw()
|
||||
{
|
||||
using namespace espgui;
|
||||
Base::redraw();
|
||||
|
||||
if (m_waitingForResult)
|
||||
{
|
||||
tft.setTextColor(TFT_YELLOW, TFT_BLACK);
|
||||
m_statuslabel.redraw("In progress");
|
||||
}
|
||||
else if (!m_result && !m_result.error().empty())
|
||||
{
|
||||
tft.setTextColor(TFT_RED, TFT_BLACK);
|
||||
BobbyErrorHandler{}.errorOccurred(fmt::format("Error: {}", m_result.error()));
|
||||
m_result.error().clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
tft.setTextColor(TFT_GREEN, TFT_BLACK);
|
||||
m_statuslabel.redraw("OK");
|
||||
popScreen();
|
||||
}
|
||||
}
|
||||
|
||||
void QrImportDisplay::buttonPressed(espgui::Button button)
|
||||
{
|
||||
using namespace espgui;
|
||||
Base::buttonPressed(button);
|
||||
|
||||
switch (button)
|
||||
{
|
||||
using espgui::Button;
|
||||
case Button::Left:
|
||||
if (!m_waitingForResult)
|
||||
popScreen();
|
||||
else
|
||||
ESP_LOGW(TAG, "tried to leave while waiting for result");
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
#pragma once
|
||||
constexpr const char * const TAG = "qrimport";
|
||||
|
||||
// 3rd party includes
|
||||
#include <esp_log.h>
|
||||
#include <widgets/label.h>
|
||||
#include <fmt/core.h>
|
||||
#include <tftinstance.h>
|
||||
#include <tl/expected.hpp>
|
||||
#include <fmt/core.h>
|
||||
#include <widgets/label.h>
|
||||
|
||||
// local includes
|
||||
#include "bobbydisplay.h"
|
||||
@ -14,7 +13,6 @@ constexpr const char * const TAG = "qrimport";
|
||||
#include "qrimport.h"
|
||||
#include "screenmanager.h"
|
||||
|
||||
template<typename TMenu>
|
||||
class QrImportDisplay : public BobbyDisplay
|
||||
{
|
||||
using Base = BobbyDisplay;
|
||||
@ -23,92 +21,10 @@ public:
|
||||
explicit QrImportDisplay(const std::string &nvs_key) : m_nvs_key{nvs_key} {}
|
||||
explicit QrImportDisplay(std::string &&nvs_key) : m_nvs_key{std::move(nvs_key)} {}
|
||||
|
||||
void start() override
|
||||
{
|
||||
using namespace espgui;
|
||||
Base::start();
|
||||
|
||||
m_statuslabel.start();
|
||||
|
||||
qrimport::setup_request();
|
||||
|
||||
if (const auto result = qrimport::start_qr_request(); result)
|
||||
{
|
||||
ESP_LOGI(TAG, "started request, waiting for result");
|
||||
m_waitingForResult = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG, "could not start request: %.*s", result.error().size(), result.error().data());
|
||||
m_result = tl::make_unexpected(std::move(result).error());
|
||||
}
|
||||
}
|
||||
|
||||
void update() override
|
||||
{
|
||||
using namespace espgui;
|
||||
Base::update();
|
||||
|
||||
if (!m_waitingForResult)
|
||||
return;
|
||||
|
||||
if (qrimport::get_request_running())
|
||||
return;
|
||||
|
||||
m_waitingForResult = false;
|
||||
|
||||
m_result = qrimport::check_request();
|
||||
if (m_result)
|
||||
{
|
||||
ESP_LOGI(TAG, "%.*s => %.*s", m_nvs_key.size(), m_nvs_key.data(), m_result->size(), m_result->data());
|
||||
if (const auto result = qrimport::set_qr_code(m_nvs_key, *m_result); !result)
|
||||
m_result = tl::make_unexpected(fmt::format("saving qr failed: {}", esp_err_to_name(result.error())));
|
||||
}
|
||||
else
|
||||
ESP_LOGW(TAG, "failed %.*s => %.*s", m_nvs_key.size(), m_nvs_key.data(), m_result.error().size(), m_result.error().data());
|
||||
}
|
||||
|
||||
void redraw() override
|
||||
{
|
||||
using namespace espgui;
|
||||
Base::redraw();
|
||||
|
||||
if (m_waitingForResult)
|
||||
{
|
||||
tft.setTextColor(TFT_YELLOW, TFT_BLACK);
|
||||
m_statuslabel.redraw("In progress");
|
||||
}
|
||||
else if (!m_result && !m_result.error().empty())
|
||||
{
|
||||
tft.setTextColor(TFT_RED, TFT_BLACK);
|
||||
BobbyErrorHandler{}.errorOccurred(fmt::format("Error: {}", m_result.error()));
|
||||
m_result.error().clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
tft.setTextColor(TFT_GREEN, TFT_BLACK);
|
||||
m_statuslabel.redraw("OK");
|
||||
popScreen();
|
||||
}
|
||||
}
|
||||
|
||||
void buttonPressed(espgui::Button button) override
|
||||
{
|
||||
using namespace espgui;
|
||||
Base::buttonPressed(button);
|
||||
|
||||
switch (button)
|
||||
{
|
||||
using espgui::Button;
|
||||
case Button::Left:
|
||||
if (!m_waitingForResult)
|
||||
popScreen();
|
||||
else
|
||||
ESP_LOGW(TAG, "tried to leave while waiting for result");
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
}
|
||||
void start() override;
|
||||
void update() override;
|
||||
void redraw() override;
|
||||
void buttonPressed(espgui::Button button) override;
|
||||
|
||||
private:
|
||||
bool m_waitingForResult{false};
|
||||
|
56
main/displays/setup/ask_calibrate_other_buttons.cpp
Normal file
56
main/displays/setup/ask_calibrate_other_buttons.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
#include "ask_calibrate_other_buttons.h"
|
||||
|
||||
// 3rdparty lib includes
|
||||
#include <screenmanager.h>
|
||||
|
||||
// local includes
|
||||
#include "displays/menus/extrabuttoncalibratemenu.h"
|
||||
#include "displays/setup/final_information.h"
|
||||
#include "setup.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace {
|
||||
constexpr char const askSetupOtherButtonsText[] = "Do you want to setup other\nbuttons?\n(Blinker, Profile Buttons, etc.)\n\nPress LEFT to skip other buttons.\nPress RIGHT to setup buttons.";
|
||||
} // namespace
|
||||
|
||||
void SetupAskCalibrateOtherButtonsDisplay::initScreen()
|
||||
{
|
||||
Base::initScreen();
|
||||
|
||||
drawLargeText(askSetupOtherButtonsText);
|
||||
}
|
||||
|
||||
void SetupAskCalibrateOtherButtonsDisplay::start()
|
||||
{
|
||||
if (m_next_screen)
|
||||
{
|
||||
espgui::switchScreen<SetupFinalInformationDisplay>();
|
||||
return;
|
||||
}
|
||||
|
||||
Base::start();
|
||||
|
||||
setup::lock();
|
||||
}
|
||||
|
||||
void SetupAskCalibrateOtherButtonsDisplay::buttonPressed(espgui::Button button)
|
||||
{
|
||||
switch (button)
|
||||
{
|
||||
case espgui::Left:
|
||||
espgui::switchScreen<SetupFinalInformationDisplay>();
|
||||
return;
|
||||
case espgui::Right:
|
||||
m_next_screen = true;
|
||||
espgui::pushScreen<ExtraButtonCalibrateMenu>();
|
||||
return;
|
||||
default:;
|
||||
}
|
||||
|
||||
Base::buttonPressed(button);
|
||||
}
|
||||
|
||||
std::string SetupAskCalibrateOtherButtonsDisplay::text() const
|
||||
{
|
||||
return "Other Buttons";
|
||||
}
|
18
main/displays/setup/ask_calibrate_other_buttons.h
Normal file
18
main/displays/setup/ask_calibrate_other_buttons.h
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
// local includes
|
||||
#include "displays/bobbydisplaywithtitle.h"
|
||||
|
||||
class SetupAskCalibrateOtherButtonsDisplay : public virtual BobbyDisplayWithTitle
|
||||
{
|
||||
using Base = BobbyDisplayWithTitle;
|
||||
public:
|
||||
void initScreen() override;
|
||||
void start() override;
|
||||
|
||||
void buttonPressed(espgui::Button button) override;
|
||||
|
||||
[[nodiscard]] std::string text() const override;
|
||||
private:
|
||||
bool m_next_screen{false};
|
||||
};
|
53
main/displays/setup/ask_setup_clouds.cpp
Normal file
53
main/displays/setup/ask_setup_clouds.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
#include "ask_setup_clouds.h"
|
||||
|
||||
// 3rdparty lib includes
|
||||
#include <screenmanager.h>
|
||||
|
||||
// local includes
|
||||
#include "displays/setup/ask_calibrate_other_buttons.h"
|
||||
#include "displays/setup/setup_cloud.h"
|
||||
#include "setup.h"
|
||||
#include "taskmanager.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace {
|
||||
constexpr char const askCloudText[] = "Do you want to setup cloud?\nWith this, you will be able\nto send data to graphana,\nremote control things like Buttons\nand NVS and more!\n\nPress LEFT to skip cloud.\nPress RIGHT to setup cloud.";
|
||||
} // namespace
|
||||
|
||||
void SetupAskSetupCloudsDisplay::initScreen()
|
||||
{
|
||||
Base::initScreen();
|
||||
|
||||
drawLargeText(askCloudText);
|
||||
}
|
||||
|
||||
void SetupAskSetupCloudsDisplay::start()
|
||||
{
|
||||
Base::start();
|
||||
|
||||
setup::lock();
|
||||
}
|
||||
|
||||
void SetupAskSetupCloudsDisplay::buttonPressed(espgui::Button button)
|
||||
{
|
||||
switch (button)
|
||||
{
|
||||
case espgui::Left: // skip cloud setup
|
||||
espgui::switchScreen<SetupAskCalibrateOtherButtonsDisplay>();
|
||||
return;
|
||||
case espgui::Right: // enter cloud setup
|
||||
configs.write_config(configs.feature.cloud.isEnabled, true);
|
||||
configs.write_config(configs.feature.udpcloud.isEnabled, true);
|
||||
|
||||
reload_tasks();
|
||||
espgui::switchScreen<SetupCloudDisplay>();
|
||||
default:;
|
||||
}
|
||||
|
||||
Base::buttonPressed(button);
|
||||
}
|
||||
|
||||
std::string SetupAskSetupCloudsDisplay::text() const
|
||||
{
|
||||
return "Cloud Setup";
|
||||
}
|
16
main/displays/setup/ask_setup_clouds.h
Normal file
16
main/displays/setup/ask_setup_clouds.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
// local includes
|
||||
#include "displays/bobbydisplaywithtitle.h"
|
||||
|
||||
class SetupAskSetupCloudsDisplay : public virtual BobbyDisplayWithTitle
|
||||
{
|
||||
using Base = BobbyDisplayWithTitle;
|
||||
public:
|
||||
void initScreen() override;
|
||||
void start() override;
|
||||
|
||||
void buttonPressed(espgui::Button button) override;
|
||||
|
||||
[[nodiscard]] std::string text() const override;
|
||||
};
|
230
main/displays/setup/basic_buttons.cpp
Normal file
230
main/displays/setup/basic_buttons.cpp
Normal file
@ -0,0 +1,230 @@
|
||||
#include "basic_buttons.h"
|
||||
|
||||
// system includes
|
||||
#include <esp_log.h>
|
||||
|
||||
// 3rdparty lib includes
|
||||
#include <screenmanager.h>
|
||||
#include <tftinstance.h>
|
||||
|
||||
// local includes
|
||||
#include "bobbyerrorhandler.h"
|
||||
#include "displays/setup/calibrate_potis.h"
|
||||
#include "setup.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace {
|
||||
constexpr char const buttonText[] = "Please press the highlighted\n buttons!";
|
||||
constexpr const char * const TAG = "SETUP-BUTTONS";
|
||||
}
|
||||
|
||||
void SetupBasicButtonsDisplay::initScreen()
|
||||
{
|
||||
Base::initScreen();
|
||||
|
||||
drawLargeText(buttonText);
|
||||
drawButtons(m_button_cal_status);
|
||||
}
|
||||
|
||||
void SetupBasicButtonsDisplay::start()
|
||||
{
|
||||
Base::start();
|
||||
|
||||
setup::lock();
|
||||
|
||||
m_lastButton = std::nullopt;
|
||||
m_button_cal_status = LEFT;
|
||||
m_button_cal_finished = false;
|
||||
}
|
||||
|
||||
void SetupBasicButtonsDisplay::update()
|
||||
{
|
||||
if (m_button_cal_finished)
|
||||
{
|
||||
m_button_cal_finished = false;
|
||||
saveButtons();
|
||||
|
||||
if (m_early_return)
|
||||
{
|
||||
setup::unlock();
|
||||
espgui::popScreen();
|
||||
}
|
||||
else
|
||||
{
|
||||
espgui::switchScreen<SetupCalibratePotisDisplay>();
|
||||
}
|
||||
}
|
||||
|
||||
Base::update();
|
||||
}
|
||||
|
||||
void SetupBasicButtonsDisplay::redraw()
|
||||
{
|
||||
Base::redraw();
|
||||
}
|
||||
|
||||
void SetupBasicButtonsDisplay::rawButtonPressed(uint8_t button)
|
||||
{
|
||||
if (m_button_cal_status == FINISHED)
|
||||
{
|
||||
if (button == m_rightButton)
|
||||
{
|
||||
m_button_cal_finished = true;
|
||||
}
|
||||
}
|
||||
else if (!m_lastButton || *m_lastButton != button)
|
||||
m_lastButton = button;
|
||||
else
|
||||
{
|
||||
switch (m_button_cal_status)
|
||||
{
|
||||
case LEFT:
|
||||
m_leftButton = button;
|
||||
m_lastButton = std::nullopt;
|
||||
m_button_cal_status = RIGHT;
|
||||
break;
|
||||
case RIGHT:
|
||||
m_rightButton = button;
|
||||
m_lastButton = std::nullopt;
|
||||
m_button_cal_status = UP;
|
||||
break;
|
||||
case UP:
|
||||
m_upButton = button;
|
||||
m_lastButton = std::nullopt;
|
||||
m_button_cal_status = DOWN;
|
||||
break;
|
||||
case DOWN:
|
||||
m_downButton = button;
|
||||
m_lastButton = std::nullopt;
|
||||
m_button_cal_status = FINISHED;
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
||||
drawButtons(m_button_cal_status);
|
||||
|
||||
Base::rawButtonPressed(button);
|
||||
}
|
||||
|
||||
void SetupBasicButtonsDisplay::rawButtonReleased(uint8_t button)
|
||||
{
|
||||
// Base::rawButtonReleased(button);
|
||||
}
|
||||
|
||||
void SetupBasicButtonsDisplay::buttonPressed(espgui::Button button)
|
||||
{
|
||||
// Base::buttonPressed(button);
|
||||
}
|
||||
|
||||
void SetupBasicButtonsDisplay::buttonReleased(espgui::Button button)
|
||||
{
|
||||
// Base::buttonReleased(button);
|
||||
}
|
||||
|
||||
std::string SetupBasicButtonsDisplay::text() const
|
||||
{
|
||||
return "Calibrate Buttons";
|
||||
}
|
||||
|
||||
void SetupBasicButtonsDisplay::saveButtons() const
|
||||
{
|
||||
if (auto result = configs.write_config(configs.dpadMappingLeft, m_leftButton); !result)
|
||||
{
|
||||
BobbyErrorHandler{}.errorOccurred(std::move(result).error());
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGI(TAG, "Left button set to %d", m_leftButton);
|
||||
}
|
||||
|
||||
if (auto result = configs.write_config(configs.dpadMappingRight, m_rightButton); !result)
|
||||
{
|
||||
BobbyErrorHandler{}.errorOccurred(std::move(result).error());
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGI(TAG, "Right button set to %d", m_rightButton);
|
||||
}
|
||||
if (auto result = configs.write_config(configs.dpadMappingUp, m_upButton); !result)
|
||||
{
|
||||
BobbyErrorHandler{}.errorOccurred(std::move(result).error());
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGI(TAG, "Up button set to %d", m_upButton);
|
||||
}
|
||||
if (auto result = configs.write_config(configs.dpadMappingDown, m_downButton); !result)
|
||||
{
|
||||
BobbyErrorHandler{}.errorOccurred(std::move(result).error());
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGI(TAG, "Down button set to %d", m_downButton);
|
||||
}
|
||||
}
|
||||
|
||||
void SetupBasicButtonsDisplay::drawButtons(const SetupBasicButtonsDisplay::CurrentButton button)
|
||||
{
|
||||
using namespace espgui;
|
||||
|
||||
const int16_t x_mid = tft.width() / 2;
|
||||
const int16_t y_mid = tft.height() / 2;
|
||||
|
||||
const auto offset = 40;
|
||||
const auto radius = 15;
|
||||
const auto subtract = 2;
|
||||
|
||||
const auto up_x = x_mid;
|
||||
const auto up_y = y_mid - offset;
|
||||
|
||||
const auto down_x = x_mid;
|
||||
const auto down_y = y_mid + offset;
|
||||
|
||||
const auto left_x = x_mid - offset;
|
||||
const auto left_y = y_mid;
|
||||
|
||||
const auto right_x = x_mid + offset;
|
||||
const auto right_y = y_mid;
|
||||
|
||||
tft.fillCircle(up_x, up_y, radius-subtract, TFT_BLACK);
|
||||
tft.fillCircle(down_x, down_y, radius-subtract, TFT_BLACK);
|
||||
tft.fillCircle(left_x, left_y, radius-subtract, TFT_BLACK);
|
||||
tft.fillCircle(right_x, right_y, radius-subtract, TFT_BLACK);
|
||||
|
||||
tft.drawCircle(up_x, up_y, radius, TFT_WHITE);
|
||||
tft.drawCircle(down_x, down_y, radius, TFT_WHITE);
|
||||
tft.drawCircle(left_x, left_y, radius, TFT_WHITE);
|
||||
tft.drawCircle(right_x, right_y, radius, TFT_WHITE);
|
||||
|
||||
if (m_button_cal_finished)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch(button)
|
||||
{
|
||||
case UP:
|
||||
tft.fillCircle(up_x, up_y, radius-subtract, m_lastButton ? TFT_YELLOW : TFT_WHITE);
|
||||
break;
|
||||
case DOWN:
|
||||
tft.fillCircle(down_x, down_y, radius-subtract, m_lastButton ? TFT_YELLOW : TFT_WHITE);
|
||||
break;
|
||||
case LEFT:
|
||||
tft.fillCircle(left_x, left_y, radius-subtract, m_lastButton ? TFT_YELLOW : TFT_WHITE);
|
||||
break;
|
||||
case RIGHT:
|
||||
tft.fillCircle(right_x, right_y, radius-subtract, m_lastButton ? TFT_YELLOW : TFT_WHITE);
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
|
||||
if (m_button_cal_status == FINISHED)
|
||||
{
|
||||
tft.fillCircle(right_x, right_y, radius-subtract, TFT_GREEN);
|
||||
}
|
||||
}
|
51
main/displays/setup/basic_buttons.h
Normal file
51
main/displays/setup/basic_buttons.h
Normal file
@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
// system includes
|
||||
#include <optional>
|
||||
|
||||
// local includes
|
||||
#include "displays/bobbydisplaywithtitle.h"
|
||||
|
||||
class SetupBasicButtonsDisplay : public virtual BobbyDisplayWithTitle
|
||||
{
|
||||
using Base = BobbyDisplayWithTitle;
|
||||
|
||||
enum CurrentButton : int8_t
|
||||
{
|
||||
UP,
|
||||
DOWN,
|
||||
LEFT,
|
||||
RIGHT,
|
||||
FINISHED
|
||||
}; // button calibration
|
||||
public:
|
||||
explicit SetupBasicButtonsDisplay(bool early_return = false) :
|
||||
m_early_return{early_return}
|
||||
{}
|
||||
|
||||
void initScreen() override;
|
||||
void start() override;
|
||||
void update() override;
|
||||
void redraw() override;
|
||||
|
||||
void rawButtonPressed(uint8_t button) override;
|
||||
void rawButtonReleased(uint8_t button) override;
|
||||
void buttonPressed(espgui::Button button) override;
|
||||
void buttonReleased(espgui::Button button) override;
|
||||
|
||||
[[nodiscard]] std::string text() const override;
|
||||
private:
|
||||
const bool m_early_return;
|
||||
|
||||
std::optional<uint8_t> m_lastButton;
|
||||
|
||||
CurrentButton m_button_cal_status;
|
||||
|
||||
uint8_t m_leftButton, m_rightButton, m_upButton, m_downButton;
|
||||
|
||||
bool m_button_cal_finished;
|
||||
|
||||
void saveButtons() const;
|
||||
|
||||
void drawButtons(CurrentButton button);
|
||||
};
|
309
main/displays/setup/calibrate_potis.cpp
Normal file
309
main/displays/setup/calibrate_potis.cpp
Normal file
@ -0,0 +1,309 @@
|
||||
#include "calibrate_potis.h"
|
||||
|
||||
// 3rdparty lib includes
|
||||
#include <cpputils.h>
|
||||
#include <screenmanager.h>
|
||||
#include <tftinstance.h>
|
||||
|
||||
// local includes
|
||||
#include "displays/setup/ask_setup_clouds.h"
|
||||
#include "globals.h"
|
||||
#include "setup.h"
|
||||
|
||||
using namespace espgui;
|
||||
|
||||
void SetupCalibratePotisDisplay::initScreen()
|
||||
{
|
||||
Base::initScreen();
|
||||
|
||||
tft.setTextFont(4);
|
||||
tft.setTextColor(TFT_WHITE, TFT_BLACK);
|
||||
|
||||
tft.drawString("gas:", 25, 47);
|
||||
tft.drawString("brems:", 25, 147);
|
||||
|
||||
for (auto &label : m_labels)
|
||||
label.start();
|
||||
|
||||
for (auto &progressBar : m_progressBars)
|
||||
progressBar.start();
|
||||
|
||||
m_renderedButton = -1;
|
||||
}
|
||||
|
||||
void SetupCalibratePotisDisplay::start()
|
||||
{
|
||||
Base::start();
|
||||
|
||||
setup::lock();
|
||||
|
||||
m_selectedButton = 0;
|
||||
m_status = Status::Begin;
|
||||
copyFromSettings();
|
||||
m_gas = std::nullopt;
|
||||
m_brems = std::nullopt;
|
||||
}
|
||||
void SetupCalibratePotisDisplay::update()
|
||||
{
|
||||
Base::update();
|
||||
|
||||
if (raw_gas)
|
||||
m_gas = cpputils::mapValueClamped<float>(*raw_gas, m_gasMin, m_gasMax, 0.f, 1000.f);
|
||||
else
|
||||
m_gas = std::nullopt;
|
||||
|
||||
if (raw_brems)
|
||||
m_brems = cpputils::mapValueClamped<float>(*raw_brems, m_bremsMin, m_bremsMax, 0.f, 1000.f);
|
||||
else
|
||||
m_brems = std::nullopt;
|
||||
}
|
||||
|
||||
void SetupCalibratePotisDisplay::redraw()
|
||||
{
|
||||
Base::redraw();
|
||||
|
||||
m_labels[0].redraw(m_gas ? fmt::format("{:.02f}", *m_gas) : "?");
|
||||
m_labels[1].redraw(raw_gas ? std::to_string(*raw_gas) : "?");
|
||||
if (m_status == Status::GasMin)
|
||||
espgui::tft.setTextColor(TFT_RED, TFT_BLACK);
|
||||
m_labels[2].redraw(std::to_string(m_gasMin));
|
||||
if (m_status == Status::GasMin)
|
||||
espgui::tft.setTextColor(TFT_WHITE, TFT_BLACK);
|
||||
if (m_status == Status::GasMax)
|
||||
espgui::tft.setTextColor(TFT_RED, TFT_BLACK);
|
||||
m_labels[3].redraw(std::to_string(m_gasMax));
|
||||
if (m_status == Status::GasMax)
|
||||
espgui::tft.setTextColor(TFT_WHITE, TFT_BLACK);
|
||||
|
||||
m_progressBars[0].redraw(m_gas ? *m_gas : 0);
|
||||
|
||||
m_labels[4].redraw(m_brems ? fmt::format("{:.02f}", *m_brems) : "?");
|
||||
m_labels[5].redraw(raw_brems ? std::to_string(*raw_brems) : "?");
|
||||
if (m_status == Status::BremsMin)
|
||||
espgui::tft.setTextColor(TFT_RED, TFT_BLACK);
|
||||
m_labels[6].redraw(std::to_string(m_bremsMin));
|
||||
if (m_status == Status::BremsMin)
|
||||
espgui::tft.setTextColor(TFT_WHITE, TFT_BLACK);
|
||||
if (m_status == Status::BremsMax)
|
||||
espgui::tft.setTextColor(TFT_RED, TFT_BLACK);
|
||||
m_labels[7].redraw(std::to_string(m_bremsMax));
|
||||
if (m_status == Status::BremsMax)
|
||||
espgui::tft.setTextColor(TFT_WHITE, TFT_BLACK);
|
||||
|
||||
m_progressBars[1].redraw(m_brems ? *m_brems : 0);
|
||||
|
||||
m_labels[8].redraw([&](){
|
||||
switch (m_status)
|
||||
{
|
||||
case Status::Begin: return "Start calibrating?";
|
||||
#ifdef FEATURE_JOYSTICK
|
||||
case Status::Mitte: return "Release joystick";
|
||||
#endif
|
||||
case Status::GasMin: return "Release gas";
|
||||
case Status::GasMax: return "Press gas";
|
||||
case Status::BremsMin: return "Release brems";
|
||||
case Status::BremsMax: return "Press brems";
|
||||
case Status::Confirm: return "Verify";
|
||||
}
|
||||
__builtin_unreachable();
|
||||
}());
|
||||
|
||||
{
|
||||
const auto failed = !m_gas || !m_brems || (m_status == Status::Confirm && (*m_gas > 100 || *m_brems > 100));
|
||||
const auto color = failed ? TFT_DARKGREY : TFT_WHITE;
|
||||
espgui::tft.setTextColor(color, TFT_BLACK);
|
||||
m_labels[9].redraw([&](){
|
||||
switch (m_status)
|
||||
{
|
||||
case Status::Begin: return "Yes";
|
||||
#ifdef FEATURE_JOYSTICK
|
||||
case Status::Mitte:
|
||||
#endif
|
||||
case Status::GasMin:
|
||||
case Status::GasMax:
|
||||
case Status::BremsMin:
|
||||
case Status::BremsMax: return "Next";
|
||||
case Status::Confirm: return "Save";
|
||||
}
|
||||
__builtin_unreachable();
|
||||
}());
|
||||
|
||||
if (m_selectedButton != m_renderedButton && (m_selectedButton == 0 || m_renderedButton == 0))
|
||||
espgui::tft.drawRect(3, 275, 100, 27, m_selectedButton == 0 ? color : TFT_BLACK);
|
||||
}
|
||||
|
||||
espgui::tft.setTextColor(TFT_WHITE, TFT_BLACK);
|
||||
m_labels[10].redraw([&](){
|
||||
switch (m_status)
|
||||
{
|
||||
case Status::Begin: return "No";
|
||||
#ifdef FEATURE_JOYSTICK
|
||||
case Status::Mitte:
|
||||
#endif
|
||||
case Status::GasMin:
|
||||
case Status::GasMax:
|
||||
case Status::BremsMin:
|
||||
case Status::BremsMax:
|
||||
case Status::Confirm: return "Abort";
|
||||
}
|
||||
__builtin_unreachable();
|
||||
}());
|
||||
|
||||
if (m_selectedButton != m_renderedButton && (m_selectedButton == 1 || m_renderedButton == 1))
|
||||
espgui::tft.drawRect(123, 275, 100, 27, m_selectedButton == 1 ? TFT_WHITE : TFT_BLACK);
|
||||
|
||||
m_renderedButton = m_selectedButton;
|
||||
}
|
||||
|
||||
void SetupCalibratePotisDisplay::stop()
|
||||
{
|
||||
if (m_early_return)
|
||||
{
|
||||
setup::unlock();
|
||||
}
|
||||
|
||||
Base::stop();
|
||||
}
|
||||
|
||||
void SetupCalibratePotisDisplay::buttonPressed(espgui::Button button)
|
||||
{
|
||||
Base::buttonPressed(button);
|
||||
|
||||
switch (button)
|
||||
{
|
||||
using espgui::Button;
|
||||
case Button::Up:
|
||||
m_selectedButton--;
|
||||
|
||||
if (m_selectedButton < 0)
|
||||
m_selectedButton = 1;
|
||||
|
||||
break;
|
||||
case Button::Down:
|
||||
m_selectedButton++;
|
||||
|
||||
if (m_selectedButton > 1)
|
||||
m_selectedButton = 0;
|
||||
|
||||
break;
|
||||
case Button::Left:
|
||||
back:
|
||||
switch (m_status)
|
||||
{
|
||||
case Status::Begin:
|
||||
if (m_early_return)
|
||||
espgui::popScreen();
|
||||
else
|
||||
espgui::switchScreen<SetupAskSetupCloudsDisplay>();
|
||||
break;
|
||||
#ifdef FEATURE_JOYSTICK
|
||||
case Status::Mitte:
|
||||
#endif
|
||||
case Status::GasMin:
|
||||
case Status::GasMax:
|
||||
case Status::BremsMin:
|
||||
case Status::BremsMax:
|
||||
case Status::Confirm:
|
||||
m_selectedButton = 0;
|
||||
m_status = Status::Begin;
|
||||
copyFromSettings();
|
||||
}
|
||||
|
||||
break;
|
||||
case Button::Right:
|
||||
switch (m_selectedButton)
|
||||
{
|
||||
case 0: // left button pressed
|
||||
if (!raw_gas || !raw_brems || !m_gas || !m_brems)
|
||||
return;
|
||||
|
||||
switch (m_status)
|
||||
{
|
||||
#ifndef FEATURE_JOYSTICK
|
||||
case Status::Begin:
|
||||
m_status = Status::GasMin;
|
||||
break;
|
||||
#else
|
||||
case Status::Begin:
|
||||
m_status = Status::Mitte;
|
||||
break;
|
||||
|
||||
case Status::Mitte:
|
||||
m_gasMitte = *raw_gas;
|
||||
m_bremsMitte = *raw_brems;
|
||||
m_status = Status::GasMin;
|
||||
break;
|
||||
#endif
|
||||
case Status::GasMin:
|
||||
m_gasMin = *raw_gas;
|
||||
m_status = Status::GasMax;
|
||||
break;
|
||||
case Status::GasMax:
|
||||
m_gasMax = *raw_gas;
|
||||
m_status = Status::BremsMin;
|
||||
{
|
||||
const auto dead = (m_gasMax - m_gasMin)/20;
|
||||
m_gasMin += dead;
|
||||
m_gasMax -= dead;
|
||||
}
|
||||
break;
|
||||
case Status::BremsMin:
|
||||
m_bremsMin = *raw_brems;
|
||||
m_status = Status::BremsMax;
|
||||
break;
|
||||
case Status::BremsMax:
|
||||
m_bremsMax = *raw_brems;
|
||||
m_status = Status::Confirm;
|
||||
{
|
||||
const auto dead = (m_bremsMax - m_bremsMin)/20;
|
||||
m_bremsMin += dead;
|
||||
m_bremsMax -= dead;
|
||||
}
|
||||
break;
|
||||
case Status::Confirm:
|
||||
if (*m_gas > 100 || *m_brems > 100)
|
||||
return;
|
||||
|
||||
copyToSettings();
|
||||
|
||||
if (m_early_return)
|
||||
espgui::popScreen();
|
||||
else
|
||||
espgui::switchScreen<SetupAskSetupCloudsDisplay>();
|
||||
}
|
||||
break;
|
||||
case 1: // right button pressed
|
||||
goto back;
|
||||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
std::string SetupCalibratePotisDisplay::text() const
|
||||
{
|
||||
return "Calibrate Potis";
|
||||
}
|
||||
|
||||
void SetupCalibratePotisDisplay::copyFromSettings()
|
||||
{
|
||||
#ifdef FEATURE_JOYSTICK
|
||||
m_gasMitte = configs.gasMitte.value();
|
||||
m_bremsMitte = configs.bremsMitte.value();
|
||||
#endif
|
||||
m_gasMin = configs.gasMin.value();
|
||||
m_gasMax = configs.gasMax.value();
|
||||
m_bremsMin = configs.bremsMin.value();
|
||||
m_bremsMax = configs.bremsMax.value();
|
||||
}
|
||||
|
||||
void SetupCalibratePotisDisplay::copyToSettings() const
|
||||
{
|
||||
#ifdef FEATURE_JOYSTICK
|
||||
configs.write_config(configs.gasMitte, m_gasMitte);
|
||||
configs.write_config(configs.bremsMitte, m_bremsMitte);
|
||||
#endif
|
||||
configs.write_config(configs.gasMin, m_gasMin);
|
||||
configs.write_config(configs.gasMax, m_gasMax);
|
||||
configs.write_config(configs.bremsMin, m_bremsMin);
|
||||
configs.write_config(configs.bremsMax, m_bremsMax);
|
||||
}
|
86
main/displays/setup/calibrate_potis.h
Normal file
86
main/displays/setup/calibrate_potis.h
Normal file
@ -0,0 +1,86 @@
|
||||
#pragma once
|
||||
|
||||
// system includes
|
||||
#include <array>
|
||||
#include <optional>
|
||||
|
||||
// 3rdparty lib includes
|
||||
#include <widgets/label.h>
|
||||
#include <widgets/progressbar.h>
|
||||
|
||||
// local includes
|
||||
#include "displays/bobbydisplaywithtitle.h"
|
||||
|
||||
class SetupCalibratePotisDisplay : public virtual BobbyDisplayWithTitle
|
||||
{
|
||||
using Base = BobbyDisplayWithTitle;
|
||||
public:
|
||||
explicit SetupCalibratePotisDisplay(bool early_return = false) :
|
||||
m_early_return{early_return}
|
||||
{}
|
||||
|
||||
void initScreen() override;
|
||||
void start() override;
|
||||
void update() override;
|
||||
void redraw() override;
|
||||
void stop() override;
|
||||
|
||||
void buttonPressed(espgui::Button button) override;
|
||||
|
||||
[[nodiscard]] std::string text() const override;
|
||||
|
||||
private:
|
||||
void copyFromSettings();
|
||||
void copyToSettings() const;
|
||||
|
||||
const bool m_early_return;
|
||||
|
||||
std::array<espgui::Label, 11> m_labels {{
|
||||
espgui::Label{25, 72}, // 100, 23
|
||||
espgui::Label{145, 72}, // 100, 23
|
||||
espgui::Label{25, 97}, // 100, 23
|
||||
espgui::Label{145, 97}, // 100, 23
|
||||
|
||||
espgui::Label{25, 172}, // 100, 23
|
||||
espgui::Label{145, 172}, // 100, 23
|
||||
espgui::Label{25, 197}, // 100, 23
|
||||
espgui::Label{145, 197}, // 100, 23
|
||||
|
||||
espgui::Label{25, 247}, // 190, 23
|
||||
|
||||
espgui::Label{25, 277}, // 100, 23
|
||||
espgui::Label{145, 277}, // 100, 23
|
||||
}};
|
||||
|
||||
std::array<espgui::ProgressBar, 2> m_progressBars {{
|
||||
espgui::ProgressBar{20, 129, 200, 10, 0, 1000},
|
||||
espgui::ProgressBar{20, 229, 200, 10, 0, 1000}
|
||||
}};
|
||||
|
||||
enum Status {
|
||||
Begin,
|
||||
#ifdef FEATURE_JOYSTICK
|
||||
Mitte,
|
||||
#endif
|
||||
GasMin,
|
||||
GasMax,
|
||||
BremsMin,
|
||||
BremsMax,
|
||||
Confirm
|
||||
};
|
||||
|
||||
int8_t m_selectedButton, m_renderedButton;
|
||||
|
||||
Status m_status;
|
||||
int16_t
|
||||
m_gasMin,
|
||||
m_gasMax,
|
||||
m_bremsMin,
|
||||
m_bremsMax
|
||||
#ifdef FEATURE_JOYSTICK
|
||||
,m_gasMitte
|
||||
,m_bremsMitte
|
||||
#endif
|
||||
;
|
||||
std::optional<float> m_gas, m_brems;
|
||||
};
|
58
main/displays/setup/final_information.cpp
Normal file
58
main/displays/setup/final_information.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
#include "final_information.h"
|
||||
|
||||
// 3rdparty lib includes
|
||||
#include <screenmanager.h>
|
||||
|
||||
// local includes
|
||||
#include "displays/menus/extrabuttoncalibratemenu.h"
|
||||
#include "displays/statusdisplay.h"
|
||||
#include "newsettings.h"
|
||||
#include "setup.h"
|
||||
#include "utils.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
namespace {
|
||||
constexpr char const finalInformationText[] = "Setup is done!\nIf cloud is setup, go to\nhttps://service.bobbycar.cloud/\nand register this bobbycar!\nThis is also used\nto setup udp cloud.\nPress any button to exit.";
|
||||
} // namespace
|
||||
|
||||
void SetupFinalInformationDisplay::initScreen()
|
||||
{
|
||||
Base::initScreen();
|
||||
|
||||
drawLargeText(finalInformationText);
|
||||
}
|
||||
|
||||
void SetupFinalInformationDisplay::start()
|
||||
{
|
||||
Base::start();
|
||||
|
||||
setup::lock();
|
||||
}
|
||||
|
||||
void SetupFinalInformationDisplay::stop()
|
||||
{
|
||||
Base::stop();
|
||||
|
||||
setup::unlock();
|
||||
}
|
||||
|
||||
void SetupFinalInformationDisplay::buttonPressed(espgui::Button button)
|
||||
{
|
||||
configs.write_config(configs.boardcomputerHardware.setupFinished, true);
|
||||
if (espgui::displayStack.empty())
|
||||
{
|
||||
espgui::switchScreen<StatusDisplay>();
|
||||
}
|
||||
else
|
||||
{
|
||||
espgui::popScreen();
|
||||
}
|
||||
|
||||
Base::buttonPressed(button);
|
||||
}
|
||||
|
||||
std::string SetupFinalInformationDisplay::text() const
|
||||
{
|
||||
return "All done!";
|
||||
}
|
20
main/displays/setup/final_information.h
Normal file
20
main/displays/setup/final_information.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
// 3rdparty lib includes
|
||||
#include <espchrono.h>
|
||||
|
||||
// local includes
|
||||
#include "displays/bobbydisplaywithtitle.h"
|
||||
|
||||
class SetupFinalInformationDisplay : public virtual BobbyDisplayWithTitle
|
||||
{
|
||||
using Base = BobbyDisplayWithTitle;
|
||||
public:
|
||||
void initScreen() override;
|
||||
void start() override;
|
||||
void stop() override;
|
||||
|
||||
void buttonPressed(espgui::Button button) override;
|
||||
|
||||
[[nodiscard]] std::string text() const override;
|
||||
};
|
64
main/displays/setup/information.cpp
Normal file
64
main/displays/setup/information.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
#include "information.h"
|
||||
|
||||
// 3rdparty lib includes
|
||||
#include <screenmanager.h>
|
||||
|
||||
// local includes
|
||||
#include "displays/setup/basic_buttons.h"
|
||||
#include "setup.h"
|
||||
#include "utils.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
namespace {
|
||||
constexpr char const informationText[] = "Congratulations on your new\nbobbycar! This guide will help\nyou through initial setup,\ncalibrate everything and\nget you ready!";
|
||||
} // namespace
|
||||
|
||||
void SetupInformationDisplay::initScreen()
|
||||
{
|
||||
Base::initScreen();
|
||||
|
||||
m_init_text_progressbar.start();
|
||||
|
||||
drawLargeText(informationText);
|
||||
}
|
||||
|
||||
void SetupInformationDisplay::start()
|
||||
{
|
||||
Base::start();
|
||||
|
||||
setup::lock();
|
||||
|
||||
m_menu_opened_timestamp = espchrono::millis_clock::now();
|
||||
}
|
||||
|
||||
void SetupInformationDisplay::update()
|
||||
{
|
||||
if (espchrono::ago(m_menu_opened_timestamp) > 5s)
|
||||
{
|
||||
espgui::switchScreen<SetupBasicButtonsDisplay>();
|
||||
}
|
||||
|
||||
Base::update();
|
||||
}
|
||||
|
||||
void SetupInformationDisplay::redraw()
|
||||
{
|
||||
m_init_text_progressbar.redraw(espchrono::ago(m_menu_opened_timestamp) / 50ms);
|
||||
|
||||
Base::redraw();
|
||||
}
|
||||
|
||||
void SetupInformationDisplay::buttonPressed(espgui::Button button)
|
||||
{
|
||||
if (espchrono::ago(m_menu_opened_timestamp) > 500ms)
|
||||
{
|
||||
espgui::switchScreen<SetupBasicButtonsDisplay>();
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string SetupInformationDisplay::text() const
|
||||
{
|
||||
return "First Steps";
|
||||
}
|
||||
|
26
main/displays/setup/information.h
Normal file
26
main/displays/setup/information.h
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
// 3rdparty lib includes
|
||||
#include <espchrono.h>
|
||||
#include <tftinstance.h>
|
||||
#include <widgets/progressbar.h>
|
||||
|
||||
// local includes
|
||||
#include "displays/bobbydisplaywithtitle.h"
|
||||
|
||||
class SetupInformationDisplay : public virtual BobbyDisplayWithTitle
|
||||
{
|
||||
using Base = BobbyDisplayWithTitle;
|
||||
public:
|
||||
void initScreen() override;
|
||||
void start() override;
|
||||
void update() override;
|
||||
void redraw() override;
|
||||
|
||||
void buttonPressed(espgui::Button button) override;
|
||||
|
||||
[[nodiscard]] std::string text() const override;
|
||||
private:
|
||||
espchrono::millis_clock::time_point m_menu_opened_timestamp;
|
||||
espgui::ProgressBar m_init_text_progressbar{10, espgui::tft.height()/2, espgui::tft.width()-20, 30, 0, 100};
|
||||
};
|
103
main/displays/setup/setup_cloud.cpp
Normal file
103
main/displays/setup/setup_cloud.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
#include "setup_cloud.h"
|
||||
|
||||
// 3rdparty lib includes
|
||||
#include <actions/popscreenaction.h>
|
||||
#include <actions/pushscreenaction.h>
|
||||
#include <changevaluedisplay_string.h>
|
||||
|
||||
// local includes
|
||||
#include "accessors/settingsaccessors.h"
|
||||
#include "bobbycheckbox.h"
|
||||
#include "displays/bobbychangevaluedisplay.h"
|
||||
#include "displays/setup/ask_calibrate_other_buttons.h"
|
||||
#include "setup.h"
|
||||
|
||||
using namespace espgui;
|
||||
|
||||
namespace {
|
||||
constexpr const char TEXT_ENABLE_CLOUD[] = "Enable Cloud";
|
||||
constexpr const char TEXT_CLOUD_USERNAME[] = "Cloud Username";
|
||||
constexpr const char TEXT_CLOUD_URL[] = "Cloud URL";
|
||||
constexpr const char TEXT_CLOUD_KEY[] = "Cloud Key";
|
||||
constexpr const char TEXT_DONE[] = "Done";
|
||||
|
||||
using CloudUsernameChangeScreen = espgui::makeComponent<
|
||||
BobbyChangeValueDisplay<std::string>,
|
||||
espgui::StaticText<TEXT_CLOUD_USERNAME>,
|
||||
UsernameAccessor,
|
||||
espgui::ConfirmActionInterface<espgui::PopScreenAction>,
|
||||
espgui::BackActionInterface<espgui::PopScreenAction>
|
||||
>;
|
||||
|
||||
using CloudURLChangeScreen = espgui::makeComponent<
|
||||
BobbyChangeValueDisplay<std::string>,
|
||||
espgui::StaticText<TEXT_CLOUD_URL>,
|
||||
CloudURLAccessor,
|
||||
espgui::ConfirmActionInterface<espgui::PopScreenAction>,
|
||||
espgui::BackActionInterface<espgui::PopScreenAction>
|
||||
>;
|
||||
|
||||
using CloudKeyChangeScreen = espgui::makeComponent<
|
||||
BobbyChangeValueDisplay<std::string>,
|
||||
espgui::StaticText<TEXT_CLOUD_KEY>,
|
||||
CloudKeyAccessor,
|
||||
espgui::ConfirmActionInterface<espgui::PopScreenAction>,
|
||||
espgui::BackActionInterface<espgui::PopScreenAction>
|
||||
>; // cloud setup
|
||||
|
||||
template<bool early_return>
|
||||
class CloudSetupFinishedAction : public virtual ActionInterface
|
||||
{
|
||||
public:
|
||||
void triggered() override
|
||||
{
|
||||
if (early_return)
|
||||
{
|
||||
espgui::popScreen();
|
||||
}
|
||||
else
|
||||
{
|
||||
espgui::switchScreen<SetupAskCalibrateOtherButtonsDisplay>();
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
|
||||
SetupCloudDisplay::SetupCloudDisplay(const bool early_return) : m_early_return{early_return}
|
||||
{
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ENABLE_CLOUD>, BobbyCheckbox, CloudEnabledAccessor>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_CLOUD_USERNAME>, PushScreenAction<CloudUsernameChangeScreen>>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_CLOUD_URL>, PushScreenAction<CloudURLChangeScreen>>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_CLOUD_KEY>, PushScreenAction<CloudKeyChangeScreen>>>();
|
||||
|
||||
if (early_return)
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_DONE>, CloudSetupFinishedAction<true>>>();
|
||||
else
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_DONE>, CloudSetupFinishedAction<false>>>();
|
||||
}
|
||||
|
||||
void SetupCloudDisplay::start()
|
||||
{
|
||||
Base::start();
|
||||
|
||||
setup::lock();
|
||||
}
|
||||
|
||||
void SetupCloudDisplay::stop()
|
||||
{
|
||||
if (m_early_return)
|
||||
{
|
||||
setup::unlock();
|
||||
}
|
||||
|
||||
Base::stop();
|
||||
}
|
||||
|
||||
void SetupCloudDisplay::back()
|
||||
{}
|
||||
|
||||
std::string SetupCloudDisplay::text() const
|
||||
{
|
||||
return "WebSocket Cloud";
|
||||
}
|
||||
|
20
main/displays/setup/setup_cloud.h
Normal file
20
main/displays/setup/setup_cloud.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
// local includes
|
||||
#include "displays/bobbymenudisplay.h"
|
||||
|
||||
class SetupCloudDisplay : public virtual BobbyMenuDisplay
|
||||
{
|
||||
using Base = BobbyMenuDisplay;
|
||||
public:
|
||||
explicit SetupCloudDisplay(bool early_return = false);
|
||||
|
||||
void start() override;
|
||||
void stop() override;
|
||||
|
||||
void back() override;
|
||||
|
||||
[[nodiscard]] std::string text() const override;
|
||||
private:
|
||||
const bool m_early_return;
|
||||
};
|
@ -31,14 +31,20 @@ using namespace std::chrono_literals;
|
||||
#else
|
||||
#include "modes/defaultmode.h"
|
||||
#endif
|
||||
#include "displays/buttoncalibratedisplay.h"
|
||||
#include "displays/lockscreen.h"
|
||||
#include "displays/menus/recoverymenu.h"
|
||||
#include "displays/potiscalibratedisplay.h"
|
||||
#include "displays/setup/information.h"
|
||||
#include "displays/setup/basic_buttons.h"
|
||||
#include "displays/setup/calibrate_potis.h"
|
||||
#include "displays/statusdisplay.h"
|
||||
#include "newsettings.h"
|
||||
#include "taskmanager.h"
|
||||
|
||||
#define BOOT_PROGRESS(s) \
|
||||
bootLabel.redraw(s); \
|
||||
ESP_LOGI("BOOT", "%s", s);
|
||||
|
||||
namespace {
|
||||
espchrono::millis_clock::time_point lastStatsPush;
|
||||
std::optional<espchrono::millis_clock::time_point> lastStatsUpdate;
|
||||
@ -94,7 +100,7 @@ extern "C" void app_main()
|
||||
recovery = true;
|
||||
}
|
||||
|
||||
bootLabel.redraw("settings");
|
||||
BOOT_PROGRESS("settings");
|
||||
|
||||
if (const auto result = configs.init("bobbycar"); result != ESP_OK)
|
||||
ESP_LOGE(TAG, "config_init_settings() failed with %s", esp_err_to_name(result));
|
||||
@ -117,7 +123,7 @@ extern "C" void app_main()
|
||||
{
|
||||
if (checkEnabledByName(task.name()))
|
||||
{
|
||||
bootLabel.redraw(task.name());
|
||||
BOOT_PROGRESS(task.name());
|
||||
task.setup(false);
|
||||
}
|
||||
}
|
||||
@ -128,33 +134,43 @@ extern "C" void app_main()
|
||||
currentMode = &modes::defaultMode;
|
||||
#endif
|
||||
|
||||
bootLabel.redraw("switchScreen");
|
||||
BOOT_PROGRESS("switchScreen");
|
||||
|
||||
if (configs.dpadMappingLeft.value() == INPUT_MAPPING_NONE ||
|
||||
configs.dpadMappingRight.value() == INPUT_MAPPING_NONE ||
|
||||
configs.dpadMappingUp.value() == INPUT_MAPPING_NONE ||
|
||||
configs.dpadMappingDown.value() == INPUT_MAPPING_NONE)
|
||||
if (const auto result = checkIfInCalibration(); result)
|
||||
{
|
||||
espgui::switchScreen<ButtonCalibrateDisplay>(true);
|
||||
switch(*result)
|
||||
{
|
||||
case SetupStep::INFORMATION:
|
||||
BOOT_PROGRESS("Calibtration");
|
||||
espgui::switchScreen<SetupInformationDisplay>();
|
||||
break;
|
||||
case SetupStep::BASIC_BUTTONS:
|
||||
BOOT_PROGRESS("Calibtration");
|
||||
espgui::switchScreen<SetupBasicButtonsDisplay>(true);
|
||||
break;
|
||||
case SetupStep::CALIBRATE_POTIS:
|
||||
espgui::switchScreen<SetupCalibratePotisDisplay>(true);
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
}
|
||||
else if (configs.lockscreen.keepLockedAfterReboot.value() && configs.lockscreen.locked.value())
|
||||
{
|
||||
BOOT_PROGRESS("Locked");
|
||||
espgui::switchScreen<StatusDisplay>();
|
||||
espgui::pushScreen<Lockscreen>();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!gas || !brems || *gas > 200.f || *brems > 200.f)
|
||||
espgui::switchScreen<PotisCalibrateDisplay>(true);
|
||||
else
|
||||
{
|
||||
espgui::switchScreen<StatusDisplay>();
|
||||
}
|
||||
BOOT_PROGRESS("StatusDisplay")
|
||||
espgui::switchScreen<StatusDisplay>();
|
||||
}
|
||||
|
||||
esp_chip_info(&chip_info);
|
||||
esp_pm_get_configuration(&pm_config);
|
||||
|
||||
ESP_LOGI(TAG, "Entering main loop...");
|
||||
|
||||
while (true)
|
||||
{
|
||||
const auto now = espchrono::millis_clock::now();
|
||||
|
@ -364,7 +364,8 @@ public:
|
||||
ConfigWrapperLegacy<int16_t> cloudSendRate {1, DoReset, {}, "cloudSendRate" };
|
||||
ConfigWrapperLegacy<int16_t> udpSendRateMs {65, DoReset, {}, "udpSendRate" };
|
||||
} timersSettings;
|
||||
ConfigWrapperLegacy<bool> flipScreen {false, DoReset, {}, "flipScreen" };
|
||||
ConfigWrapperLegacy<bool> flipScreen {false, NoReset, {}, "flipScreen" };
|
||||
ConfigWrapperLegacy<bool> setupFinished {false, DoReset, {}, "setupFinished" };
|
||||
} boardcomputerHardware;
|
||||
|
||||
struct {
|
||||
@ -487,6 +488,8 @@ public:
|
||||
ConfigWrapperLegacy<bool> bleFenceEnabled {false, DoReset, {}, "bleFenceEnabled" };
|
||||
} bleSettings;
|
||||
|
||||
ConfigWrapperLegacy<bool> setupDone {false, DoReset, {}, "setupDone" };
|
||||
|
||||
#define NEW_SETTINGS(x) \
|
||||
x(baseMacAddressOverride) \
|
||||
x(hostname) \
|
||||
@ -710,9 +713,10 @@ public:
|
||||
x(boardcomputerHardware.timersSettings.statsUpdateRate) \
|
||||
x(boardcomputerHardware.timersSettings.cloudCollectRate) \
|
||||
x(boardcomputerHardware.timersSettings.cloudSendRate) \
|
||||
x(boardcomputerHardware.timersSettings.udpSendRateMs) \
|
||||
x(boardcomputerHardware.timersSettings.udpSendRateMs) \
|
||||
\
|
||||
x(boardcomputerHardware.flipScreen) \
|
||||
x(boardcomputerHardware.setupFinished) \
|
||||
\
|
||||
x(cloudSettings.cloudEnabled) \
|
||||
x(cloudSettings.cloudTransmitTimeout) \
|
||||
|
@ -73,6 +73,18 @@ void readPotis()
|
||||
// sum += analogRead(pin);
|
||||
// return sum / sampleCount;
|
||||
// };
|
||||
constexpr auto sampleMultipleTimes = [](adc_channel_t channel){
|
||||
int sum{};
|
||||
const auto sampleCount = configs.sampleCount.value();
|
||||
for (int i = 0; i < sampleCount; i++)
|
||||
{
|
||||
int value;
|
||||
if (const auto result = adc_oneshot_read(adc1_handle, channel, &value); result != ESP_OK)
|
||||
ESP_LOGE(TAG, "adc_oneshot_read_channel() failed with %s", esp_err_to_name(result));
|
||||
sum += value;
|
||||
}
|
||||
return sum / sampleCount;
|
||||
};
|
||||
|
||||
raw_gas = std::nullopt;
|
||||
raw_brems = std::nullopt;
|
||||
@ -100,19 +112,13 @@ void readPotis()
|
||||
#ifdef FEATURE_ADC_IN
|
||||
if (!raw_gas)
|
||||
{
|
||||
int raw;
|
||||
if (const auto result = adc_oneshot_read(adc1_handle, ADC_CHANNEL_GAS, &raw); result == ESP_OK)
|
||||
raw_gas = raw;
|
||||
else
|
||||
ESP_LOGE(TAG, "adc_oneshot_read() failed with %s", esp_err_to_name(result));
|
||||
raw_gas = sampleMultipleTimes(ADC_CHANNEL_GAS);
|
||||
ESP_LOGD(TAG, "raw_gas: %d", *raw_gas);
|
||||
}
|
||||
if (!raw_brems)
|
||||
{
|
||||
int raw;
|
||||
if (const auto result = adc_oneshot_read(adc1_handle, ADC_CHANNEL_BREMS, &raw); result == ESP_OK)
|
||||
raw_brems = raw;
|
||||
else
|
||||
ESP_LOGE(TAG, "adc_oneshot_read() failed with %s", esp_err_to_name(result));
|
||||
raw_brems = sampleMultipleTimes(ADC_CHANNEL_BREMS);
|
||||
ESP_LOGD(TAG, "raw_brems: %d", *raw_brems);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
39
main/setup.cpp
Normal file
39
main/setup.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
#include "setup.h"
|
||||
|
||||
// local includes
|
||||
#include "globals.h"
|
||||
|
||||
namespace setup {
|
||||
bool currently_locked;
|
||||
ModeInterface* oldMode;
|
||||
IgnoreInputMode setup_mode{0, bobbycar::protocol::ControlType::FieldOrientedControl, bobbycar::protocol::ControlMode::Torque};
|
||||
|
||||
void lock()
|
||||
{
|
||||
if (currently_locked)
|
||||
return;
|
||||
|
||||
oldMode = currentMode;
|
||||
currentMode = &setup_mode;
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
if (!currently_locked)
|
||||
return;
|
||||
|
||||
if (currentMode == &setup_mode)
|
||||
{
|
||||
// to avoid crash after deconstruction
|
||||
setup_mode.stop();
|
||||
lastMode = nullptr;
|
||||
|
||||
currentMode = oldMode;
|
||||
}
|
||||
}
|
||||
|
||||
bool isLocked()
|
||||
{
|
||||
return currently_locked;
|
||||
}
|
||||
} // namespace setup
|
23
main/setup.h
Normal file
23
main/setup.h
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
// local includes
|
||||
#include "bobbytypesafeenum.h"
|
||||
#include "modeinterface.h"
|
||||
#include "modes/ignoreinputmode.h"
|
||||
|
||||
#define SetupStepValues(x) \
|
||||
x(INFORMATION) \
|
||||
x(BASIC_BUTTONS) \
|
||||
x(CALIBRATE_POTIS)
|
||||
|
||||
DECLARE_BOBBYTYPESAFE_ENUM(SetupStep, : uint8_t, SetupStepValues);
|
||||
|
||||
namespace setup {
|
||||
extern bool currently_locked;
|
||||
extern ModeInterface* oldMode;
|
||||
extern IgnoreInputMode setup_mode;
|
||||
|
||||
void lock();
|
||||
void unlock();
|
||||
bool isLocked();
|
||||
} // namespace setup
|
@ -1,7 +1,7 @@
|
||||
#include "statistics.h"
|
||||
|
||||
namespace statistics {
|
||||
ContainerType gas, brems, avgSpeed, avgSpeedKmh, sumCurrent, frontVoltage, backVoltage, frontLeftCurrent, frontRightCurrent, backLeftCurrent, backRightCurrent,
|
||||
ContainerType raw_gas, raw_brems, gas, brems, avgSpeed, avgSpeedKmh, sumCurrent, frontVoltage, backVoltage, frontLeftCurrent, frontRightCurrent, backLeftCurrent, backRightCurrent,
|
||||
#ifdef FEATURE_BMS
|
||||
bmsVoltage, bmsCurrent, bmsPower,
|
||||
#endif
|
||||
@ -10,6 +10,10 @@ ContainerType gas, brems, avgSpeed, avgSpeedKmh, sumCurrent, frontVoltage, backV
|
||||
|
||||
void pushStats()
|
||||
{
|
||||
if (raw_gas)
|
||||
statistics::raw_gas.push_back(*raw_gas);
|
||||
if (raw_brems)
|
||||
statistics::raw_brems.push_back(*raw_brems);
|
||||
if (gas)
|
||||
statistics::gas.push_back(*gas);
|
||||
if (brems)
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
namespace statistics {
|
||||
using ContainerType = ring_buffer<float, 200>;
|
||||
extern ContainerType gas, brems, avgSpeed, avgSpeedKmh, sumCurrent, frontVoltage, backVoltage, frontLeftCurrent, frontRightCurrent, backLeftCurrent, backRightCurrent,
|
||||
extern ContainerType raw_gas, raw_brems, gas, brems, avgSpeed, avgSpeedKmh, sumCurrent, frontVoltage, backVoltage, frontLeftCurrent, frontRightCurrent, backLeftCurrent, backRightCurrent,
|
||||
#ifdef FEATURE_BMS
|
||||
bmsVoltage, bmsCurrent, bmsPower,
|
||||
#endif
|
||||
@ -33,6 +33,8 @@ public:
|
||||
const statistics::ContainerType &getBuffer() const override { return T; }
|
||||
};
|
||||
|
||||
using RawGasStatistics = BufferAccessorImpl<statistics::raw_gas>;
|
||||
using RawBremsStatistics = BufferAccessorImpl<statistics::raw_brems>;
|
||||
using GasStatistics = BufferAccessorImpl<statistics::gas>;
|
||||
using BremsStatistics = BufferAccessorImpl<statistics::brems>;
|
||||
using AvgSpeedStatistics = BufferAccessorImpl<statistics::avgSpeed>;
|
||||
|
@ -115,7 +115,7 @@ void sched_pushStats(bool printTasks)
|
||||
ESP_LOGI(TAG, "end listing tasks");
|
||||
}
|
||||
|
||||
tl::expected<bool, std::string> checkInitializedByName(std::string name)
|
||||
tl::expected<bool, std::string> checkInitializedByName(const std::string& name)
|
||||
{
|
||||
for (auto &schedulerTask : schedulerTasks)
|
||||
{
|
||||
@ -126,7 +126,7 @@ tl::expected<bool, std::string> checkInitializedByName(std::string name)
|
||||
return tl::make_unexpected("Task not found: " + std::string{name});
|
||||
}
|
||||
|
||||
bool checkEnabledByName(std::string name) {
|
||||
bool checkEnabledByName(const std::string& name) {
|
||||
bool enabled = true;
|
||||
// iterate over all feature flags (runForEveryFeature())
|
||||
configs.callForEveryFeature([&](ConfiguredFeatureFlag &feature) {
|
||||
@ -135,3 +135,14 @@ bool checkEnabledByName(std::string name) {
|
||||
});
|
||||
return enabled;
|
||||
}
|
||||
|
||||
void reload_tasks()
|
||||
{
|
||||
for (auto &task : schedulerTasks)
|
||||
{
|
||||
if (checkEnabledByName(task.name()) && !task.isInitialized())
|
||||
{
|
||||
task.setup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,8 @@ extern const BobbySchedulerTask &drivingModeTask;
|
||||
|
||||
void sched_pushStats(bool printTasks);
|
||||
|
||||
tl::expected<bool, std::string> checkInitializedByName(std::string name);
|
||||
tl::expected<bool, std::string> checkInitializedByName(const std::string& name);
|
||||
|
||||
bool checkEnabledByName(std::string name);
|
||||
bool checkEnabledByName(const std::string& name);
|
||||
|
||||
void reload_tasks();
|
||||
|
@ -241,8 +241,6 @@ void sendUdpCloudPacket()
|
||||
ESP_LOGE(TAG, "send to cloud failed: %.*s (ip=%s)", result.error().size(), result.error().data(), wifi_stack::toString(udpCloudIp.u_addr.ip4).c_str());
|
||||
}
|
||||
|
||||
// ESP_LOGI(TAG, "%s", buf.c_str());
|
||||
|
||||
visualSendUdpPacket = !visualSendUdpPacket;
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,9 @@
|
||||
// system includes
|
||||
#include <utility>
|
||||
|
||||
// 3rdparty lib includes
|
||||
#include <tftinstance.h>
|
||||
|
||||
// local includes
|
||||
#include "globals.h"
|
||||
#include "newsettings.h"
|
||||
@ -380,3 +383,58 @@ std::string toString(esp_chip_model_t esp_chip_model)
|
||||
return "invalid";
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<SetupStep> checkIfInCalibration()
|
||||
{
|
||||
if (!configs.boardcomputerHardware.setupFinished.value())
|
||||
{
|
||||
return SetupStep::INFORMATION;
|
||||
}
|
||||
else if (
|
||||
configs.dpadMappingLeft.value() == INPUT_MAPPING_NONE ||
|
||||
configs.dpadMappingRight.value() == INPUT_MAPPING_NONE ||
|
||||
configs.dpadMappingUp.value() == INPUT_MAPPING_NONE ||
|
||||
configs.dpadMappingDown.value() == INPUT_MAPPING_NONE
|
||||
)
|
||||
{
|
||||
return SetupStep::BASIC_BUTTONS;
|
||||
}
|
||||
else if (!gas || !brems || *gas > 200.f || *brems > 200.f)
|
||||
{
|
||||
return SetupStep::CALIBRATE_POTIS;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void drawLargeText(const std::string&& text)
|
||||
{
|
||||
using namespace espgui;
|
||||
|
||||
const auto topMargin = 50;
|
||||
const uint8_t leftMargin = 8;
|
||||
const auto rightMargin = leftMargin;
|
||||
const auto bottomMargin = leftMargin;
|
||||
|
||||
int x = leftMargin + 5;
|
||||
int y = topMargin + 5;
|
||||
|
||||
tft.setTextColor(TFT_WHITE);
|
||||
|
||||
for (char c : text)
|
||||
{
|
||||
if (c == '\n' || x > tft.width() - rightMargin - 10)
|
||||
{
|
||||
x = leftMargin + 5;
|
||||
y += tft.fontHeight(2);
|
||||
}
|
||||
|
||||
if (c != '\n')
|
||||
{
|
||||
const auto addedWidth = tft.drawChar(tft.decodeUTF8(c), x, y, 2);
|
||||
x += addedWidth;
|
||||
}
|
||||
|
||||
if (y >= tft.height() - bottomMargin)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,7 @@
|
||||
#ifdef DPAD_BOARDCOMPUTER_V2
|
||||
#include "dpad_boardcomputer_v2.h"
|
||||
#endif
|
||||
#include "setup.h"
|
||||
|
||||
extern bool currentlyReverseBeeping;
|
||||
extern bool reverseBeepToggle;
|
||||
@ -101,6 +102,8 @@ float float_map(float x, float in_min, float in_max, float out_min, float out_ma
|
||||
bool is_valid_timestamp(espchrono::utc_clock::time_point timestamp);
|
||||
|
||||
std::string toString(esp_chip_model_t esp_chip_model);
|
||||
std::optional<SetupStep> checkIfInCalibration();
|
||||
void drawLargeText(const std::string&& text);
|
||||
|
||||
namespace bobbydpad {
|
||||
#ifdef FEATURE_DPAD
|
||||
|
Reference in New Issue
Block a user