Committed existing project
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
.pio
|
||||
platformio.pro*
|
2
.gitmodules
vendored
@ -1,3 +1,3 @@
|
||||
[submodule "bobbycar-protocol"]
|
||||
path = bobbycar-protocol
|
||||
path = src/bobbycar-protocol
|
||||
url = git@github.com:bobbycar-graz/bobbycar-protocol.git
|
||||
|
67
.travis.yml
Normal file
@ -0,0 +1,67 @@
|
||||
# Continuous Integration (CI) is the practice, in software
|
||||
# engineering, of merging all developer working copies with a shared mainline
|
||||
# several times a day < https://docs.platformio.org/page/ci/index.html >
|
||||
#
|
||||
# Documentation:
|
||||
#
|
||||
# * Travis CI Embedded Builds with PlatformIO
|
||||
# < https://docs.travis-ci.com/user/integration/platformio/ >
|
||||
#
|
||||
# * PlatformIO integration with Travis CI
|
||||
# < https://docs.platformio.org/page/ci/travis.html >
|
||||
#
|
||||
# * User Guide for `platformio ci` command
|
||||
# < https://docs.platformio.org/page/userguide/cmd_ci.html >
|
||||
#
|
||||
#
|
||||
# Please choose one of the following templates (proposed below) and uncomment
|
||||
# it (remove "# " before each line) or use own configuration according to the
|
||||
# Travis CI documentation (see above).
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# Template #1: General project. Test it using existing `platformio.ini`.
|
||||
#
|
||||
|
||||
# language: python
|
||||
# python:
|
||||
# - "2.7"
|
||||
#
|
||||
# sudo: false
|
||||
# cache:
|
||||
# directories:
|
||||
# - "~/.platformio"
|
||||
#
|
||||
# install:
|
||||
# - pip install -U platformio
|
||||
# - platformio update
|
||||
#
|
||||
# script:
|
||||
# - platformio run
|
||||
|
||||
|
||||
#
|
||||
# Template #2: The project is intended to be used as a library with examples.
|
||||
#
|
||||
|
||||
# language: python
|
||||
# python:
|
||||
# - "2.7"
|
||||
#
|
||||
# sudo: false
|
||||
# cache:
|
||||
# directories:
|
||||
# - "~/.platformio"
|
||||
#
|
||||
# env:
|
||||
# - PLATFORMIO_CI_SRC=path/to/test/file.c
|
||||
# - PLATFORMIO_CI_SRC=examples/file.ino
|
||||
# - PLATFORMIO_CI_SRC=path/to/test/directory
|
||||
#
|
||||
# install:
|
||||
# - pip install -U platformio
|
||||
# - platformio update
|
||||
#
|
||||
# script:
|
||||
# - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N
|
6
bobbycar.csv
Normal file
@ -0,0 +1,6 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
nvs, data, nvs, 0x9000, 0x5000,
|
||||
otadata, data, ota, 0xe000, 0x2000,
|
||||
app0, app, ota_0, 0x10000, 0x250000,
|
||||
app1, app, ota_1, 0x260000, 0x250000,
|
||||
spiffs, data, spiffs, 0x520000, 0x250000,
|
|
BIN
icons/back.png
Normal file
After Width: | Height: | Size: 9.5 KiB |
BIN
icons/bluetooth.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
icons/buzzer.png
Normal file
After Width: | Height: | Size: 8.9 KiB |
BIN
icons/checked.png
Normal file
After Width: | Height: | Size: 9.9 KiB |
BIN
icons/demos.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
icons/graph.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
icons/info.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
icons/lock.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
icons/logo.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
icons/modes.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
icons/poweroff.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
icons/presets.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
icons/reboot.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
icons/scan.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
icons/settings.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
icons/unchecked.png
Normal file
After Width: | Height: | Size: 7.1 KiB |
BIN
icons/wifi.png
Normal file
After Width: | Height: | Size: 11 KiB |
39
include/README
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
This directory is intended for project header files.
|
||||
|
||||
A header file is a file containing C declarations and macro definitions
|
||||
to be shared between several project source files. You request the use of a
|
||||
header file in your project source file (C, C++, etc) located in `src` folder
|
||||
by including it, with the C preprocessing directive `#include'.
|
||||
|
||||
```src/main.c
|
||||
|
||||
#include "header.h"
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Including a header file produces the same results as copying the header file
|
||||
into each source file that needs it. Such copying would be time-consuming
|
||||
and error-prone. With a header file, the related declarations appear
|
||||
in only one place. If they need to be changed, they can be changed in one
|
||||
place, and programs that include the header file will automatically use the
|
||||
new version when next recompiled. The header file eliminates the labor of
|
||||
finding and changing all the copies as well as the risk that a failure to
|
||||
find one copy will result in inconsistencies within a program.
|
||||
|
||||
In C, the usual convention is to give header files names that end with `.h'.
|
||||
It is most portable to use only letters, digits, dashes, and underscores in
|
||||
header file names, and at most one dot.
|
||||
|
||||
Read more about using header files in official GCC documentation:
|
||||
|
||||
* Include Syntax
|
||||
* Include Operation
|
||||
* Once-Only Headers
|
||||
* Computed Includes
|
||||
|
||||
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
160
platformio.ini
Normal file
@ -0,0 +1,160 @@
|
||||
;PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[env:bobbycar_usb]
|
||||
platform = espressif32
|
||||
board = esp32dev
|
||||
framework = arduino
|
||||
board_build.partitions = bobbycar.csv
|
||||
|
||||
upload_speed = 921600
|
||||
upload_port = /dev/ttyUSB*
|
||||
|
||||
lib_deps =
|
||||
TFT_eSPI
|
||||
https://github.com/Ferdi265/cxx-ring-buffer
|
||||
|
||||
lib_compat_mode = strict
|
||||
build_unflags =
|
||||
-std=gnu++11
|
||||
-Os
|
||||
|
||||
build_flags =
|
||||
-std=gnu++17
|
||||
-O3
|
||||
-DUSER_SETUP_LOADED=1
|
||||
-DILI9341_DRIVER=1
|
||||
-DTFT_MOSI=13
|
||||
-DTFT_SCLK=15
|
||||
-DTFT_CS=14
|
||||
-DTFT_DC=12
|
||||
-DTFT_RST=2
|
||||
-DLOAD_GLCD=1
|
||||
-DLOAD_FONT2=1
|
||||
-DLOAD_FONT4=1
|
||||
-DLOAD_FONT7=1
|
||||
-DSPI_FREQUENCY=27000000
|
||||
-DSPI_READ_FREQUENCY=20000000
|
||||
-DSPI_TOUCH_FREQUENCY=2500000
|
||||
-DPINS_RX1=4
|
||||
-DPINS_TX1=5
|
||||
-DPINS_RX2=25
|
||||
-DPINS_TX2=26
|
||||
-DPINS_GAS=35
|
||||
-DPINS_BREMS=33
|
||||
-DFEATURE_3WIRESW
|
||||
-DPINS_3WIRESW_OUT=0
|
||||
-DPINS_3WIRESW_IN1=16
|
||||
-DPINS_3WIRESW_IN2=27
|
||||
; -DFEATURE_ROTARY
|
||||
; -DPINS_ROTARY_CLK=16
|
||||
; -DPINS_ROTARY_DT=27
|
||||
; -DPINS_ROTARY_SW=0
|
||||
|
||||
[env:bobbycar_ota]
|
||||
platform = espressif32
|
||||
board = esp32dev
|
||||
framework = arduino
|
||||
board_build.partitions = bobbycar.csv
|
||||
|
||||
upload_protocol = espota
|
||||
upload_port = 192.168.127.171
|
||||
|
||||
lib_deps =
|
||||
TFT_eSPI
|
||||
https://github.com/Ferdi265/cxx-ring-buffer
|
||||
|
||||
lib_compat_mode = strict
|
||||
build_unflags =
|
||||
-std=gnu++11
|
||||
-Os
|
||||
|
||||
build_flags =
|
||||
-std=gnu++17
|
||||
-O3
|
||||
-DUSER_SETUP_LOADED=1
|
||||
-DILI9341_DRIVER=1
|
||||
-DTFT_MOSI=13
|
||||
-DTFT_SCLK=15
|
||||
-DTFT_CS=14
|
||||
-DTFT_DC=12
|
||||
-DTFT_RST=2
|
||||
-DLOAD_GLCD=1
|
||||
-DLOAD_FONT2=1
|
||||
-DLOAD_FONT4=1
|
||||
-DLOAD_FONT7=1
|
||||
-DSPI_FREQUENCY=27000000
|
||||
-DSPI_READ_FREQUENCY=20000000
|
||||
-DSPI_TOUCH_FREQUENCY=2500000
|
||||
-DPINS_RX1=4
|
||||
-DPINS_TX1=5
|
||||
-DPINS_RX2=25
|
||||
-DPINS_TX2=26
|
||||
-DPINS_GAS=35
|
||||
-DPINS_BREMS=33
|
||||
-DFEATURE_3WIRESW
|
||||
-DPINS_3WIRESW_OUT=0
|
||||
-DPINS_3WIRESW_IN1=16
|
||||
-DPINS_3WIRESW_IN2=27
|
||||
; -DFEATURE_ROTARY
|
||||
; -DPINS_ROTARY_CLK=16
|
||||
; -DPINS_ROTARY_DT=27
|
||||
; -DPINS_ROTARY_SW=0
|
||||
|
||||
[env:testbench]
|
||||
platform = espressif32
|
||||
board = esp32dev
|
||||
framework = arduino
|
||||
|
||||
board_build.partitions = bobbycar.csv
|
||||
|
||||
upload_port = /dev/ttyUSB*
|
||||
upload_speed = 921600
|
||||
|
||||
lib_deps =
|
||||
TFT_eSPI
|
||||
https://github.com/Ferdi265/cxx-ring-buffer
|
||||
|
||||
lib_compat_mode = strict
|
||||
build_unflags =
|
||||
-std=gnu++11
|
||||
-Os
|
||||
|
||||
build_flags =
|
||||
-std=gnu++17
|
||||
-O3
|
||||
-DUSER_SETUP_LOADED=1
|
||||
-DILI9341_DRIVER=1
|
||||
-DTFT_MOSI=22
|
||||
-DTFT_SCLK=21
|
||||
-DTFT_CS=27
|
||||
-DTFT_DC=32
|
||||
-DTFT_RST=25
|
||||
-DLOAD_GLCD=1
|
||||
-DLOAD_FONT2=1
|
||||
-DLOAD_FONT4=1
|
||||
-DLOAD_FONT7=1
|
||||
-DSPI_FREQUENCY=27000000
|
||||
-DSPI_READ_FREQUENCY=20000000
|
||||
-DSPI_TOUCH_FREQUENCY=2500000
|
||||
-DPINS_RX1=18
|
||||
-DPINS_TX1=19
|
||||
-DPINS_RX2=23
|
||||
-DPINS_TX2=34
|
||||
-DPINS_GAS=35
|
||||
-DPINS_BREMS=33
|
||||
; -DFEATURE_3WIRESW
|
||||
; -DPINS_3WIRESW_OUT=17
|
||||
; -DPINS_3WIRESW_IN1=4
|
||||
; -DPINS_3WIRESW_IN2=16
|
||||
; -DFEATURE_ROTARY
|
||||
; -DPINS_ROTARY_CLK=4
|
||||
; -DPINS_ROTARY_DT=16
|
||||
; -DPINS_ROTARY_SW=17
|
21
src/accessorinterface.h
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
namespace {
|
||||
template<typename T>
|
||||
struct AccessorInterface
|
||||
{
|
||||
virtual T getValue() const = 0;
|
||||
virtual void setValue(T value) = 0;
|
||||
};
|
||||
|
||||
//! A special type of AccessorInterface that allows for simple variable read/write operations
|
||||
//! Can be used to read and write global settings for example.
|
||||
template<typename T>
|
||||
struct RefAccessor : public virtual AccessorInterface<T>
|
||||
{
|
||||
virtual T& getRef() const = 0;
|
||||
|
||||
T getValue() const override { return getRef(); };
|
||||
void setValue(T value) override { getRef() = value; };
|
||||
};
|
||||
}
|
11
src/actioninterface.h
Normal file
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
namespace {
|
||||
class ActionInterface
|
||||
{
|
||||
public:
|
||||
virtual void triggered() = 0;
|
||||
};
|
||||
}
|
21
src/actions/bluetoothbeginaction.h
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <HardwareSerial.h>
|
||||
|
||||
#include "actioninterface.h"
|
||||
#include "globals.h"
|
||||
|
||||
namespace {
|
||||
class BluetoothBeginAction : public virtual ActionInterface
|
||||
{
|
||||
public:
|
||||
void triggered() override
|
||||
{
|
||||
if (!bluetoothSerial.begin("bobbyquad"))
|
||||
{
|
||||
Serial.println("Could not begin bluetooth");
|
||||
// TODO: better error handling
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
21
src/actions/bluetoothbeginmasteraction.h
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <HardwareSerial.h>
|
||||
|
||||
#include "actioninterface.h"
|
||||
#include "globals.h"
|
||||
|
||||
namespace {
|
||||
class BluetoothBeginMasterAction : public virtual ActionInterface
|
||||
{
|
||||
public:
|
||||
void triggered() override
|
||||
{
|
||||
if (!bluetoothSerial.begin("bobbyquad", true))
|
||||
{
|
||||
Serial.println("Could not begin bluetooth master");
|
||||
// TODO: better error handling
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
22
src/actions/bluetoothconnectbmsaction.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <HardwareSerial.h>
|
||||
|
||||
#include "actioninterface.h"
|
||||
#include "globals.h"
|
||||
|
||||
namespace {
|
||||
class BluetoothConnectBmsAction : public virtual ActionInterface
|
||||
{
|
||||
public:
|
||||
void triggered() override
|
||||
{
|
||||
uint8_t remoteAddress[ESP_BD_ADDR_LEN] = {0xAA, 0xBB, 0xCC, 0xA1, 0x23, 0x45};
|
||||
if (!bluetoothSerial.connect(remoteAddress))
|
||||
{
|
||||
Serial.println("Could not connect bluetooth to bms");
|
||||
// TODO: better error handling
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
21
src/actions/bluetoothdisconnectaction.h
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <HardwareSerial.h>
|
||||
|
||||
#include "actioninterface.h"
|
||||
#include "globals.h"
|
||||
|
||||
namespace {
|
||||
class BluetoothDisconnectAction : public virtual ActionInterface
|
||||
{
|
||||
public:
|
||||
void triggered() override
|
||||
{
|
||||
if (!bluetoothSerial.disconnect())
|
||||
{
|
||||
Serial.println("Could not disconnect bluetooth");
|
||||
// TODO: better error handling
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
15
src/actions/bluetoothendaction.h
Normal file
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "actioninterface.h"
|
||||
#include "globals.h"
|
||||
|
||||
namespace {
|
||||
class BluetoothEndAction : public virtual ActionInterface
|
||||
{
|
||||
public:
|
||||
void triggered() override
|
||||
{
|
||||
bluetoothSerial.end();
|
||||
}
|
||||
};
|
||||
}
|
15
src/actions/bluetoothflushaction.h
Normal file
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "actioninterface.h"
|
||||
#include "globals.h"
|
||||
|
||||
namespace {
|
||||
class BluetoothFlushAction : public virtual ActionInterface
|
||||
{
|
||||
public:
|
||||
void triggered() override
|
||||
{
|
||||
bluetoothSerial.flush();
|
||||
}
|
||||
};
|
||||
}
|
19
src/actions/bmsturnoffchargeaction.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "actioninterface.h"
|
||||
#include "bmsutils.h"
|
||||
|
||||
namespace {
|
||||
class BmsTurnOffChargeAction : public virtual ActionInterface
|
||||
{
|
||||
public:
|
||||
void triggered() override
|
||||
{
|
||||
if (!bms::send6Bit(42405, 250, 0))
|
||||
{
|
||||
Serial.println("Could not turn off charge mosfet");
|
||||
// TODO: better error handling
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
19
src/actions/bmsturnoffdischargeaction.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "actioninterface.h"
|
||||
#include "bmsutils.h"
|
||||
|
||||
namespace {
|
||||
class BmsTurnOffDischargeAction : public virtual ActionInterface
|
||||
{
|
||||
public:
|
||||
void triggered() override
|
||||
{
|
||||
if (!bms::send6Bit(42405, 249, 0))
|
||||
{
|
||||
Serial.println("Could not turn off discharge mosfet");
|
||||
// TODO: better error handling
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
19
src/actions/bmsturnonchargeaction.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "actioninterface.h"
|
||||
#include "bmsutils.h"
|
||||
|
||||
namespace {
|
||||
class BmsTurnOnChargeAction : public virtual ActionInterface
|
||||
{
|
||||
public:
|
||||
void triggered() override
|
||||
{
|
||||
if (!bms::send6Bit(42405, 250, 1))
|
||||
{
|
||||
Serial.println("Could not turn on charge mosfet");
|
||||
// TODO: better error handling
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
19
src/actions/bmsturnondischargeaction.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "actioninterface.h"
|
||||
#include "bmsutils.h"
|
||||
|
||||
namespace {
|
||||
class BmsTurnOnDischargeAction : public virtual ActionInterface
|
||||
{
|
||||
public:
|
||||
void triggered() override
|
||||
{
|
||||
if (!bms::send6Bit(42405, 249, 1))
|
||||
{
|
||||
Serial.println("Could not turn on discharge mosfet");
|
||||
// TODO: better error handling
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
11
src/actions/dummyaction.h
Normal file
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "actioninterface.h"
|
||||
|
||||
namespace {
|
||||
class DummyAction : public virtual ActionInterface
|
||||
{
|
||||
public:
|
||||
void triggered() override {}
|
||||
};
|
||||
}
|
12
src/actions/loadsettingsaction.h
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "actioninterface.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace {
|
||||
class LoadSettingsAction : public virtual ActionInterface
|
||||
{
|
||||
public:
|
||||
void triggered() override { loadSettings(); }
|
||||
};
|
||||
}
|
35
src/actions/multiaction.h
Normal file
@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include "actioninterface.h"
|
||||
|
||||
namespace {
|
||||
template<typename ...T>
|
||||
class MultiAction;
|
||||
|
||||
template<typename T>
|
||||
class MultiAction<T> : public virtual ActionInterface
|
||||
{
|
||||
public:
|
||||
void triggered() override
|
||||
{
|
||||
m_action.triggered();
|
||||
}
|
||||
|
||||
private:
|
||||
T m_action;
|
||||
};
|
||||
|
||||
template<typename T, typename ...Tmore>
|
||||
class MultiAction<T, Tmore...> : public virtual MultiAction<Tmore...>
|
||||
{
|
||||
public:
|
||||
void triggered() override
|
||||
{
|
||||
m_action.triggered();
|
||||
MultiAction<Tmore...>::triggered();
|
||||
}
|
||||
|
||||
private:
|
||||
T m_action;
|
||||
};
|
||||
}
|
28
src/actions/rebootaction.h
Normal file
@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include <Esp.h>
|
||||
|
||||
#include "actioninterface.h"
|
||||
#include "globals.h"
|
||||
#include "texts.h"
|
||||
|
||||
namespace {
|
||||
class RebootAction : public virtual ActionInterface
|
||||
{
|
||||
public:
|
||||
void triggered() override
|
||||
{
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
tft.setTextColor(TFT_YELLOW);
|
||||
|
||||
tft.drawString(TEXT_REBOOT, 5, 5, 4);
|
||||
|
||||
tft.fillRect(0, 34, tft.width(), 3, TFT_WHITE);
|
||||
|
||||
tft.setTextColor(TFT_WHITE);
|
||||
tft.drawString("Rebooting now...", 0, 50, 4);
|
||||
|
||||
ESP.restart();
|
||||
}
|
||||
};
|
||||
}
|
12
src/actions/savesettingsaction.h
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "actioninterface.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace {
|
||||
class SaveSettingsAction : public virtual ActionInterface
|
||||
{
|
||||
public:
|
||||
void triggered() override { saveSettings(); }
|
||||
};
|
||||
}
|
13
src/actions/switchscreenaction.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "actioninterface.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace {
|
||||
template<typename Tscreen, typename ...Targs>
|
||||
class SwitchScreenAction : public virtual ActionInterface
|
||||
{
|
||||
public:
|
||||
void triggered() override { switchScreen<Tscreen>(std::make_unique<Targs>()...); }
|
||||
};
|
||||
}
|
15
src/actions/toggleboolaction.h
Normal file
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "actioninterface.h"
|
||||
#include "accessorinterface.h"
|
||||
|
||||
namespace {
|
||||
class ToggleBoolAction : public virtual ActionInterface, public virtual AccessorInterface<bool>
|
||||
{
|
||||
public:
|
||||
void triggered() override
|
||||
{
|
||||
setValue(!getValue());
|
||||
}
|
||||
};
|
||||
}
|
12
src/actions/updateswapfrontbackaction.h
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "actioninterface.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace {
|
||||
class UpdateSwapFrontBackAction : public virtual ActionInterface
|
||||
{
|
||||
public:
|
||||
void triggered() override { updateSwapFrontBack(); }
|
||||
};
|
||||
}
|
21
src/actions/wifidisconnectaction.h
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <HardwareSerial.h>
|
||||
#include <WiFi.h>
|
||||
|
||||
#include "actioninterface.h"
|
||||
|
||||
namespace {
|
||||
class WifiDisconnectAction : public virtual ActionInterface
|
||||
{
|
||||
public:
|
||||
void triggered() override
|
||||
{
|
||||
if (!WiFi.disconnect())
|
||||
{
|
||||
Serial.println("Could not disconnect WiFi");
|
||||
// TODO: better error handling
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
21
src/actions/wifienableipv6action.h
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <HardwareSerial.h>
|
||||
#include <WiFi.h>
|
||||
|
||||
#include "actioninterface.h"
|
||||
|
||||
namespace {
|
||||
class WifiEnableIpV6Action : public virtual ActionInterface
|
||||
{
|
||||
public:
|
||||
void triggered() override
|
||||
{
|
||||
if (!WiFi.enableIpV6())
|
||||
{
|
||||
Serial.println("Could not enableIpV6 WiFi");
|
||||
// TODO: better error handling
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
21
src/actions/wifireconnectaction.h
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <HardwareSerial.h>
|
||||
#include <WiFi.h>
|
||||
|
||||
#include "actioninterface.h"
|
||||
|
||||
namespace {
|
||||
class WifiReconnectAction : public virtual ActionInterface
|
||||
{
|
||||
public:
|
||||
void triggered() override
|
||||
{
|
||||
if (!WiFi.reconnect())
|
||||
{
|
||||
Serial.println("Could not reconnect WiFi");
|
||||
// TODO: better error handling
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
21
src/actions/wifisoftapenableipv6action.h
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <HardwareSerial.h>
|
||||
#include <WiFi.h>
|
||||
|
||||
#include "actioninterface.h"
|
||||
|
||||
namespace {
|
||||
class WifiSoftApEnableIpV6Action : public virtual ActionInterface
|
||||
{
|
||||
public:
|
||||
void triggered() override
|
||||
{
|
||||
if (!WiFi.softAPenableIpV6())
|
||||
{
|
||||
Serial.println("Could not softAPenableIpV6 WiFi");
|
||||
// TODO: better error handling
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
37
src/bluetoothtexthelpers.h
Normal file
@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include "textinterface.h"
|
||||
#include "globals.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace {
|
||||
template<const char *Ttext, typename TreturnType, TreturnType (BluetoothSerial::*Tmethod)()>
|
||||
using BluetoothStatusTextHelper = StatusTextHelper<Ttext, BluetoothSerial, &bluetoothSerial, TreturnType, Tmethod>;
|
||||
|
||||
constexpr char TEXT_BLUETOOTHAVAILABLE[] = "Available: ";
|
||||
using BluetoothAvailableText = BluetoothStatusTextHelper<TEXT_BLUETOOTHAVAILABLE, int, &BluetoothSerial::available>;
|
||||
|
||||
constexpr char TEXT_BLUETOOTHHASCLIENT[] = "Has client: ";
|
||||
using BluetoothHasClientText = BluetoothStatusTextHelper<TEXT_BLUETOOTHHASCLIENT, bool, &BluetoothSerial::hasClient>;
|
||||
|
||||
//constexpr char TEXT_BLUETOOTHCONNECTED[] = "Connected: ";
|
||||
//using BluetoothConnectedText = BluetoothStatusTextHelper<TEXT_BLUETOOTHCONNECTED, bool, &BluetoothSerial::connected>;
|
||||
struct BluetoothConnectedText : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"connected: "} + toString(bluetoothSerial.connected()); }
|
||||
};
|
||||
|
||||
//constexpr char TEXT_BLUETOOTHISREADY[] = "Is ready: ";
|
||||
//using BluetoothIsReadyText = BluetoothStatusTextHelper<TEXT_BLUETOOTHISREADY, bool, &BluetoothSerial::isReady>;
|
||||
struct BluetoothIsReadyText : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"isReady: "} + toString(bluetoothSerial.isReady()); }
|
||||
};
|
||||
|
||||
//constexpr char TEXT_BLUETOOTHISREADYMASTER[] = "Is ready (M): ";
|
||||
//using BluetoothIsReadyMasterText = BluetoothStatusTextHelper<TEXT_BLUETOOTHISREADYMASTER, bool, &BluetoothSerial::isReady>;
|
||||
class BluetoothIsReadyMasterText : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"isReady (M): "} + toString(bluetoothSerial.isReady(true)); }
|
||||
};
|
||||
}
|
122
src/bmsutils.h
Normal file
@ -0,0 +1,122 @@
|
||||
#pragma once
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
namespace {
|
||||
namespace bms {
|
||||
constexpr auto autoReconnect = false; // causes hangs when not available
|
||||
|
||||
bool lastConnected;
|
||||
unsigned long lastSend;
|
||||
unsigned long lastReceive;
|
||||
|
||||
float voltage;
|
||||
float current;
|
||||
float capacity;
|
||||
int8_t soc;
|
||||
float cycle;
|
||||
int16_t power;
|
||||
float batt[12];
|
||||
|
||||
bool send6Bit(int zhen_tou, int address, int data)
|
||||
{
|
||||
uint8_t buffer[6];
|
||||
buffer[0] = (char)((zhen_tou>>8)&255);
|
||||
buffer[1] = (char)(zhen_tou&255);
|
||||
buffer[2] = (char)(address&255);
|
||||
buffer[3] = (char)((data>>8)&255);
|
||||
buffer[4] = (char)(data&255);
|
||||
buffer[5] = (char)(buffer[2]+buffer[3]+buffer[4]);
|
||||
|
||||
const auto sent = bluetoothSerial.write(buffer, 6);
|
||||
if (sent != 6)
|
||||
Serial.printf("send: %lu\r\n", sent);
|
||||
return sent == 6;
|
||||
}
|
||||
|
||||
void update()
|
||||
{
|
||||
const auto now = millis();
|
||||
|
||||
if (bluetoothSerial.hasClient() != lastConnected)
|
||||
{
|
||||
lastSend = 0;
|
||||
lastConnected = bluetoothSerial.hasClient();
|
||||
}
|
||||
|
||||
if (bluetoothSerial.hasClient())
|
||||
{
|
||||
if (bluetoothSerial.available() >= 140)
|
||||
{
|
||||
uint8_t buffer[140];
|
||||
const auto read = bluetoothSerial.readBytes(buffer, 140);
|
||||
if (read != 140)
|
||||
{
|
||||
Serial.printf("bms read buffer too short %lu\r\n", read);
|
||||
|
||||
for (int i = 0; i < read; i++)
|
||||
Serial.printf("%i ", buffer[i]);
|
||||
Serial.println();
|
||||
|
||||
goto after_read;
|
||||
}
|
||||
|
||||
if (buffer[0] != 170 ||
|
||||
buffer[1] != 85 ||
|
||||
buffer[2] != 170 ||
|
||||
buffer[3] != 255)
|
||||
{
|
||||
Serial.println("bms read buffer wrong sequence");
|
||||
|
||||
for (const auto &x : buffer)
|
||||
Serial.printf("%i ", x);
|
||||
Serial.println();
|
||||
|
||||
goto after_read;
|
||||
}
|
||||
|
||||
lastReceive = now;
|
||||
|
||||
voltage = static_cast<int16_t>((buffer[4] << 8) | buffer[5]) / 10.f;
|
||||
current = static_cast<int16_t>((buffer[72] << 8) | buffer[73]) / 10.f;
|
||||
capacity = static_cast<int32_t>((((((buffer[79] << 8) | buffer[80]) << 8) | buffer[81]) << 8) | buffer[82]) / 1000.f;
|
||||
soc = buffer[74];
|
||||
cycle = static_cast<int32_t>((((((buffer[83] << 8) | buffer[84]) << 8) | buffer[85]) << 8) | buffer[86]) / 1000.f;
|
||||
power = (buffer[113] << 8) | buffer[114];
|
||||
|
||||
for (int i = 0; i < 12; i++)
|
||||
batt[i] = ((buffer[(i*2)+6] * 256) + buffer[(i*2)+7]) / 1000.f;
|
||||
}
|
||||
// else if (bluetoothSerial.available())
|
||||
// {
|
||||
// Serial.printf("available() = %i\r\n", bluetoothSerial.available());
|
||||
// while (bluetoothSerial.available())
|
||||
// Serial.printf("%i ", bluetoothSerial.read());
|
||||
// Serial.println();
|
||||
// }
|
||||
|
||||
after_read:
|
||||
|
||||
if (!lastSend || now-lastSend >= 1000)
|
||||
{
|
||||
Serial.println("requresting bms live values");
|
||||
if (!send6Bit(56283, 0, 0))
|
||||
Serial.println("could not request bms live values");
|
||||
lastSend = now;
|
||||
}
|
||||
}
|
||||
else if (autoReconnect)
|
||||
{
|
||||
if (!lastSend || now-lastSend >= 500)
|
||||
{
|
||||
uint8_t remoteAddress[ESP_BD_ADDR_LEN] = {0xAA, 0xBB, 0xCC, 0xA1, 0x23, 0x45};
|
||||
Serial.println("connect()");
|
||||
const auto result = bluetoothSerial.connect(remoteAddress);
|
||||
Serial.printf("connect() returned %s\r\n", result?"true":"false");
|
||||
|
||||
lastSend = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
122
src/bobbycar-protocol/protocol.h
Normal file
@ -0,0 +1,122 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace {
|
||||
|
||||
enum class ControlType : uint8_t {
|
||||
Commutation,
|
||||
Sinusoidal,
|
||||
FieldOrientedControl
|
||||
};
|
||||
|
||||
enum class ControlMode : uint8_t {
|
||||
OpenMode,
|
||||
Voltage,
|
||||
Speed, // Only with FieldOrientedControl
|
||||
Torque // Only with FieldOrientedControl
|
||||
};
|
||||
|
||||
struct MotorState {
|
||||
bool enable = false;
|
||||
int16_t pwm = 0;
|
||||
ControlType ctrlTyp = ControlType::FieldOrientedControl;
|
||||
ControlMode ctrlMod = ControlMode::OpenMode;
|
||||
int16_t iMotMax = 15; // [A] Maximum motor current limit
|
||||
int16_t iDcMax = 17; // [A] Maximum DC Link current limit (This is the final current protection. Above this value, current chopping is applied. To avoid this make sure that I_DC_MAX = I_MOT_MAX + 2A)
|
||||
int16_t nMotMax = 1000; // [rpm] Maximum motor speed limit
|
||||
int16_t fieldWeakMax = 10; // [A] Maximum Field Weakening D axis current (only for FOC). Higher current results in higher maximum speed.
|
||||
int16_t phaseAdvMax = 40; // [deg] Maximum Phase Advance angle (only for SIN). Higher angle results in higher maximum speed.
|
||||
};
|
||||
|
||||
uint16_t calculateChecksum(MotorState state) {
|
||||
return
|
||||
uint16_t(state.enable) ^
|
||||
state.pwm ^
|
||||
uint16_t(state.ctrlTyp) ^
|
||||
uint16_t(state.ctrlMod) ^
|
||||
state.iMotMax ^
|
||||
state.iDcMax ^
|
||||
state.nMotMax ^
|
||||
state.fieldWeakMax ^
|
||||
state.phaseAdvMax;
|
||||
}
|
||||
|
||||
struct BuzzerState {
|
||||
uint8_t freq = 0;
|
||||
uint8_t pattern = 0;
|
||||
};
|
||||
|
||||
uint16_t calculateChecksum(BuzzerState state) {
|
||||
return state.freq ^ state.pattern;
|
||||
}
|
||||
|
||||
struct Command {
|
||||
static constexpr uint16_t VALID_HEADER = 0xAAAA;
|
||||
static constexpr uint16_t INVALID_HEADER = 0xFFFF;
|
||||
|
||||
uint16_t start;
|
||||
|
||||
MotorState left, right;
|
||||
|
||||
BuzzerState buzzer;
|
||||
|
||||
bool poweroff = false;
|
||||
bool led = false;
|
||||
|
||||
uint16_t checksum;
|
||||
};
|
||||
|
||||
uint16_t calculateChecksum(Command command) {
|
||||
return command.start ^
|
||||
calculateChecksum(command.left) ^
|
||||
calculateChecksum(command.right) ^
|
||||
calculateChecksum(command.buzzer) ^
|
||||
command.poweroff ^
|
||||
command.led;
|
||||
}
|
||||
|
||||
struct MotorFeedback {
|
||||
int16_t angle = 0;
|
||||
int16_t speed = 0;
|
||||
uint8_t error = 0;
|
||||
int16_t current = 0;
|
||||
uint32_t chops = 0;
|
||||
bool hallA = false,
|
||||
hallB = false,
|
||||
hallC = false;
|
||||
};
|
||||
|
||||
uint16_t calculateChecksum(MotorFeedback feedback) {
|
||||
return feedback.angle ^ feedback.speed ^
|
||||
feedback.error ^ feedback.current ^
|
||||
feedback.chops ^
|
||||
feedback.hallA ^ feedback.hallB ^ feedback.hallC;
|
||||
}
|
||||
|
||||
struct Feedback {
|
||||
static constexpr uint16_t VALID_HEADER = 0xAAAA;
|
||||
static constexpr uint16_t INVALID_HEADER = 0xFFFF;
|
||||
|
||||
uint16_t start;
|
||||
|
||||
MotorFeedback left, right;
|
||||
|
||||
int16_t batVoltage = 0;
|
||||
int16_t boardTemp = 0;
|
||||
|
||||
int16_t timeoutCntSerial = 0;
|
||||
|
||||
uint16_t checksum;
|
||||
};
|
||||
|
||||
uint16_t calculateChecksum(Feedback feedback) {
|
||||
return feedback.start ^
|
||||
calculateChecksum(feedback.left) ^
|
||||
calculateChecksum(feedback.right) ^
|
||||
feedback.batVoltage ^
|
||||
feedback.boardTemp ^
|
||||
feedback.timeoutCntSerial;
|
||||
}
|
||||
|
||||
}
|
150
src/changevaluedisplay.h
Normal file
@ -0,0 +1,150 @@
|
||||
#pragma once
|
||||
|
||||
#include "display.h"
|
||||
#include "textinterface.h"
|
||||
#include "actioninterface.h"
|
||||
#include "accessorinterface.h"
|
||||
#include "widgets/label.h"
|
||||
#include "globals.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace {
|
||||
class ChangeValueDisplayInterface : public Display, public virtual TextInterface, public virtual ActionInterface
|
||||
{
|
||||
public:
|
||||
void initScreen() override;
|
||||
|
||||
ChangeValueDisplayInterface *asChangeValueDisplayInterface() override { return this; }
|
||||
const ChangeValueDisplayInterface *asChangeValueDisplayInterface() const override { return this; }
|
||||
|
||||
virtual int shownValue() const = 0;
|
||||
virtual void setShownValue(int value) = 0;
|
||||
|
||||
virtual void confirm() = 0;
|
||||
|
||||
protected:
|
||||
Label m_titleLabel{5, 5}; // 230, 25
|
||||
Label m_valueLabel{26, 81}; // 188, 53
|
||||
};
|
||||
|
||||
template<typename Tvalue>
|
||||
class ChangeValueDisplaySettingsInterface
|
||||
{
|
||||
public:
|
||||
virtual Tvalue step() const { return 1; };
|
||||
};
|
||||
|
||||
template<typename Tvalue, typename Tratio>
|
||||
class RatioNumberStep : public virtual ChangeValueDisplaySettingsInterface<Tvalue>
|
||||
{
|
||||
public:
|
||||
Tvalue step() const override { return Tvalue(Tratio::num) / Tratio::den; }
|
||||
};
|
||||
|
||||
template<typename Tvalue>
|
||||
class ChangeValueDisplay : public ChangeValueDisplayInterface, public virtual AccessorInterface<Tvalue>, public virtual ChangeValueDisplaySettingsInterface<Tvalue>
|
||||
{
|
||||
using Base = ChangeValueDisplayInterface;
|
||||
|
||||
public:
|
||||
void start() override;
|
||||
void update() override;
|
||||
void redraw() override;
|
||||
|
||||
void rotate(int offset) override;
|
||||
void button() override;
|
||||
|
||||
int shownValue() const { return m_value; }
|
||||
void setShownValue(int value) { m_value = value; }
|
||||
|
||||
void confirm() override;
|
||||
|
||||
private:
|
||||
Tvalue m_value{};
|
||||
|
||||
int m_rotateOffset;
|
||||
bool m_pressed{};
|
||||
};
|
||||
|
||||
void ChangeValueDisplayInterface::initScreen()
|
||||
{
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
|
||||
m_titleLabel.start();
|
||||
|
||||
tft.fillRect(0, 34, tft.width(), 3, TFT_WHITE);
|
||||
|
||||
tft.drawRect(25, 75, 190, 65, TFT_WHITE);
|
||||
m_valueLabel.start();
|
||||
|
||||
tft.setTextFont(4);
|
||||
tft.setTextColor(TFT_WHITE);
|
||||
tft.drawString("Change value and", 10, 160);
|
||||
tft.drawString("press button to", 10, 185);
|
||||
tft.drawString("confirm and go", 10, 210);
|
||||
tft.drawString("back.", 10, 235);
|
||||
}
|
||||
|
||||
template<typename Tvalue>
|
||||
void ChangeValueDisplay<Tvalue>::start()
|
||||
{
|
||||
m_value = static_cast<AccessorInterface<Tvalue>*>(this)->getValue();
|
||||
|
||||
m_rotateOffset = 0;
|
||||
m_pressed = false;
|
||||
}
|
||||
|
||||
template<typename Tvalue>
|
||||
void ChangeValueDisplay<Tvalue>::update()
|
||||
{
|
||||
if (!m_pressed)
|
||||
{
|
||||
const auto rotateOffset = m_rotateOffset;
|
||||
m_rotateOffset = 0;
|
||||
|
||||
m_value -= rotateOffset * static_cast<ChangeValueDisplaySettingsInterface<Tvalue>*>(this)->step();
|
||||
}
|
||||
else
|
||||
{
|
||||
static_cast<AccessorInterface<Tvalue>*>(this)->setValue(m_value);
|
||||
triggered();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Tvalue>
|
||||
void ChangeValueDisplay<Tvalue>::redraw()
|
||||
{
|
||||
tft.setTextFont(4);
|
||||
tft.setTextColor(TFT_YELLOW);
|
||||
m_titleLabel.redraw(text());
|
||||
|
||||
tft.setTextColor(TFT_WHITE, TFT_BLACK);
|
||||
tft.setTextFont(7);
|
||||
m_valueLabel.redraw(String{m_value});
|
||||
}
|
||||
|
||||
template<typename Tvalue>
|
||||
void ChangeValueDisplay<Tvalue>::rotate(int offset)
|
||||
{
|
||||
m_rotateOffset += offset;
|
||||
}
|
||||
|
||||
template<typename Tvalue>
|
||||
void ChangeValueDisplay<Tvalue>::button()
|
||||
{
|
||||
m_pressed = true;
|
||||
}
|
||||
|
||||
template<typename Tvalue>
|
||||
void ChangeValueDisplay<Tvalue>::confirm()
|
||||
{
|
||||
m_pressed = true;
|
||||
}
|
||||
}
|
||||
|
||||
#include "changevaluedisplay_bool.h"
|
||||
#include "changevaluedisplay_controlmode.h"
|
||||
#include "changevaluedisplay_controltype.h"
|
||||
#include "changevaluedisplay_larsmmode_mode.h"
|
||||
#include "changevaluedisplay_wifi_mode_t.h"
|
||||
#include "changevaluedisplay_wifi_power_t.h"
|
52
src/changevaluedisplay_bool.h
Normal file
@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include "changevaluedisplay.h"
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "actioninterface.h"
|
||||
#include "utils.h"
|
||||
#include "actions/dummyaction.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
|
||||
namespace {
|
||||
template<>
|
||||
class ChangeValueDisplay<bool> :
|
||||
public MenuDisplay,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, StaticText<TEXT_TRUE>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_FALSE>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, DummyAction, StaticMenuItemIcon<&icons::back>>
|
||||
>,
|
||||
public virtual AccessorInterface<bool>,
|
||||
public virtual ActionInterface
|
||||
{
|
||||
using Base = MenuDisplay;
|
||||
|
||||
public:
|
||||
void start() override;
|
||||
|
||||
void itemPressed(int index) override;
|
||||
};
|
||||
|
||||
void ChangeValueDisplay<bool>::start()
|
||||
{
|
||||
Base::start();
|
||||
|
||||
if (getValue() == true)
|
||||
setSelectedIndex(0);
|
||||
else if (getValue() == false)
|
||||
setSelectedIndex(1);
|
||||
}
|
||||
|
||||
void ChangeValueDisplay<bool>::itemPressed(int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: setValue(true); break;
|
||||
case 1: setValue(false); break;
|
||||
}
|
||||
|
||||
triggered();
|
||||
}
|
||||
}
|
64
src/changevaluedisplay_controlmode.h
Normal file
@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
|
||||
#include "changevaluedisplay.h"
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "utils.h"
|
||||
#include "actions/dummyaction.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
|
||||
namespace {
|
||||
template<>
|
||||
class ChangeValueDisplay<ControlMode> :
|
||||
public MenuDisplay,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, StaticText<TEXT_OPENMODE>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_VOLTAGE>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SPEED>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_TORQUE>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, DummyAction, StaticMenuItemIcon<&icons::back>>
|
||||
>,
|
||||
public virtual AccessorInterface<ControlMode>,
|
||||
public virtual ActionInterface
|
||||
{
|
||||
using Base = MenuDisplay;
|
||||
|
||||
public:
|
||||
void start() override;
|
||||
|
||||
void itemPressed(int index) override;
|
||||
};
|
||||
|
||||
void ChangeValueDisplay<ControlMode>::start()
|
||||
{
|
||||
Base::start();
|
||||
|
||||
if (getValue() == ControlMode::OpenMode)
|
||||
setSelectedIndex(0);
|
||||
else if (getValue() == ControlMode::Voltage)
|
||||
setSelectedIndex(1);
|
||||
else if (getValue() == ControlMode::Speed)
|
||||
setSelectedIndex(2);
|
||||
else if (getValue() == ControlMode::Torque)
|
||||
setSelectedIndex(3);
|
||||
else
|
||||
{
|
||||
Serial.printf("Unknown ControlMode: %i", int(getValue()));
|
||||
setSelectedIndex(4);
|
||||
}
|
||||
}
|
||||
|
||||
void ChangeValueDisplay<ControlMode>::itemPressed(int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: setValue(ControlMode::OpenMode); break;
|
||||
case 1: setValue(ControlMode::Voltage); break;
|
||||
case 2: setValue(ControlMode::Speed); break;
|
||||
case 3: setValue(ControlMode::Torque); break;
|
||||
}
|
||||
|
||||
triggered();
|
||||
}
|
||||
}
|
60
src/changevaluedisplay_controltype.h
Normal file
@ -0,0 +1,60 @@
|
||||
#pragma once
|
||||
|
||||
#include "changevaluedisplay.h"
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "utils.h"
|
||||
#include "actions/dummyaction.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
|
||||
namespace {
|
||||
template<>
|
||||
class ChangeValueDisplay<ControlType> :
|
||||
public MenuDisplay,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, StaticText<TEXT_COMMUTATION>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SINUSOIDAL>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_FIELDORIENTEDCONTROL>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, DummyAction, StaticMenuItemIcon<&icons::back>>
|
||||
>,
|
||||
public virtual AccessorInterface<ControlType>,
|
||||
public virtual ActionInterface
|
||||
{
|
||||
using Base = MenuDisplay;
|
||||
|
||||
public:
|
||||
void start() override;
|
||||
|
||||
void itemPressed(int index) override;
|
||||
};
|
||||
|
||||
void ChangeValueDisplay<ControlType>::start()
|
||||
{
|
||||
Base::start();
|
||||
|
||||
if (getValue() == ControlType::Commutation)
|
||||
setSelectedIndex(0);
|
||||
else if (getValue() == ControlType::Sinusoidal)
|
||||
setSelectedIndex(1);
|
||||
else if (getValue() == ControlType::FieldOrientedControl)
|
||||
setSelectedIndex(2);
|
||||
else
|
||||
{
|
||||
Serial.printf("Unknown ControlType: %i", int(getValue()));
|
||||
setSelectedIndex(3);
|
||||
}
|
||||
}
|
||||
|
||||
void ChangeValueDisplay<ControlType>::itemPressed(int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: setValue(ControlType::Commutation); break;
|
||||
case 1: setValue(ControlType::Sinusoidal); break;
|
||||
case 2: setValue(ControlType::FieldOrientedControl); break;
|
||||
}
|
||||
|
||||
triggered();
|
||||
}
|
||||
}
|
65
src/changevaluedisplay_larsmmode_mode.h
Normal file
@ -0,0 +1,65 @@
|
||||
#pragma once
|
||||
|
||||
#include "changevaluedisplay.h"
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "utils.h"
|
||||
#include "actions/dummyaction.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
#include "modes/larsmmode.h"
|
||||
|
||||
namespace {
|
||||
template<>
|
||||
class ChangeValueDisplay<LarsmModeMode> :
|
||||
public MenuDisplay,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, StaticText<TEXT_LARSMMODE1>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_LARSMMODE2>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_LARSMMODE3>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_LARSMMODE4>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, DummyAction, StaticMenuItemIcon<&icons::back>>
|
||||
>,
|
||||
public virtual AccessorInterface<LarsmModeMode>,
|
||||
public virtual ActionInterface
|
||||
{
|
||||
using Base = MenuDisplay;
|
||||
|
||||
public:
|
||||
void start() override;
|
||||
|
||||
void itemPressed(int index) override;
|
||||
};
|
||||
|
||||
void ChangeValueDisplay<LarsmModeMode>::start()
|
||||
{
|
||||
Base::start();
|
||||
|
||||
if (getValue() == LarsmModeMode::Mode1)
|
||||
setSelectedIndex(0);
|
||||
else if (getValue() == LarsmModeMode::Mode2)
|
||||
setSelectedIndex(1);
|
||||
else if (getValue() == LarsmModeMode::Mode3)
|
||||
setSelectedIndex(2);
|
||||
else if (getValue() == LarsmModeMode::Mode4)
|
||||
setSelectedIndex(3);
|
||||
else
|
||||
{
|
||||
Serial.printf("Unknown LarsmModeMode: %i", int(getValue()));
|
||||
setSelectedIndex(4);
|
||||
}
|
||||
}
|
||||
|
||||
void ChangeValueDisplay<LarsmModeMode>::itemPressed(int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: setValue(LarsmModeMode::Mode1); break;
|
||||
case 1: setValue(LarsmModeMode::Mode2); break;
|
||||
case 2: setValue(LarsmModeMode::Mode3); break;
|
||||
case 3: setValue(LarsmModeMode::Mode4); break;
|
||||
}
|
||||
|
||||
triggered();
|
||||
}
|
||||
}
|
66
src/changevaluedisplay_wifi_mode_t.h
Normal file
@ -0,0 +1,66 @@
|
||||
#pragma once
|
||||
|
||||
#include <esp_wifi_types.h>
|
||||
|
||||
#include "changevaluedisplay.h"
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "utils.h"
|
||||
#include "actions/dummyaction.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
|
||||
namespace {
|
||||
template<>
|
||||
class ChangeValueDisplay<wifi_mode_t> :
|
||||
public MenuDisplay,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, StaticText<TEXT_WIFI_MODE_NULL>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_WIFI_MODE_STA>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_WIFI_MODE_AP>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_WIFI_MODE_APSTA>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, DummyAction, StaticMenuItemIcon<&icons::back>>
|
||||
>,
|
||||
public virtual AccessorInterface<wifi_mode_t>,
|
||||
public virtual ActionInterface
|
||||
{
|
||||
using Base = MenuDisplay;
|
||||
|
||||
public:
|
||||
void start() override;
|
||||
|
||||
void itemPressed(int index) override;
|
||||
};
|
||||
|
||||
void ChangeValueDisplay<wifi_mode_t>::start()
|
||||
{
|
||||
Base::start();
|
||||
|
||||
if (getValue() == WIFI_MODE_NULL)
|
||||
setSelectedIndex(0);
|
||||
else if (getValue() == WIFI_MODE_STA)
|
||||
setSelectedIndex(1);
|
||||
else if (getValue() == WIFI_MODE_AP)
|
||||
setSelectedIndex(2);
|
||||
else if (getValue() == WIFI_MODE_APSTA)
|
||||
setSelectedIndex(3);
|
||||
else
|
||||
{
|
||||
Serial.printf("Unknown wifi_mode_t: %i", int(getValue()));
|
||||
setSelectedIndex(4);
|
||||
}
|
||||
}
|
||||
|
||||
void ChangeValueDisplay<wifi_mode_t>::itemPressed(int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: setValue(WIFI_MODE_NULL); break;
|
||||
case 1: setValue(WIFI_MODE_STA); break;
|
||||
case 2: setValue(WIFI_MODE_AP); break;
|
||||
case 3: setValue(WIFI_MODE_APSTA); break;
|
||||
}
|
||||
|
||||
triggered();
|
||||
}
|
||||
}
|
98
src/changevaluedisplay_wifi_power_t.h
Normal file
@ -0,0 +1,98 @@
|
||||
#pragma once
|
||||
|
||||
#include <WiFiGeneric.h>
|
||||
|
||||
#include "changevaluedisplay.h"
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "utils.h"
|
||||
#include "actions/dummyaction.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
|
||||
namespace {
|
||||
template<>
|
||||
class ChangeValueDisplay<wifi_power_t> :
|
||||
public MenuDisplay,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, StaticText<TEXT_WIFI_POWER_19_5dBm>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_WIFI_POWER_19dBm>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_WIFI_POWER_18_5dBm>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_WIFI_POWER_17dBm>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_WIFI_POWER_15dBm>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_WIFI_POWER_13dBm>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_WIFI_POWER_11dBm>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_WIFI_POWER_8_5dBm>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_WIFI_POWER_7dBm>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_WIFI_POWER_5dBm>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_WIFI_POWER_2dBm>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_WIFI_POWER_MINUS_1dBm>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, DummyAction, StaticMenuItemIcon<&icons::back>>
|
||||
>,
|
||||
public virtual AccessorInterface<wifi_power_t>,
|
||||
public virtual ActionInterface
|
||||
{
|
||||
using Base = MenuDisplay;
|
||||
|
||||
public:
|
||||
void start() override;
|
||||
|
||||
void itemPressed(int index) override;
|
||||
};
|
||||
|
||||
void ChangeValueDisplay<wifi_power_t>::start()
|
||||
{
|
||||
Base::start();
|
||||
|
||||
if (getValue() == WIFI_POWER_19_5dBm)
|
||||
setSelectedIndex(0);
|
||||
else if (getValue() == WIFI_POWER_19dBm)
|
||||
setSelectedIndex(1);
|
||||
else if (getValue() == WIFI_POWER_18_5dBm)
|
||||
setSelectedIndex(2);
|
||||
else if (getValue() == WIFI_POWER_17dBm)
|
||||
setSelectedIndex(3);
|
||||
else if (getValue() == WIFI_POWER_15dBm)
|
||||
setSelectedIndex(4);
|
||||
else if (getValue() == WIFI_POWER_13dBm)
|
||||
setSelectedIndex(5);
|
||||
else if (getValue() == WIFI_POWER_11dBm)
|
||||
setSelectedIndex(6);
|
||||
else if (getValue() == WIFI_POWER_8_5dBm)
|
||||
setSelectedIndex(7);
|
||||
else if (getValue() == WIFI_POWER_7dBm)
|
||||
setSelectedIndex(8);
|
||||
else if (getValue() == WIFI_POWER_5dBm)
|
||||
setSelectedIndex(9);
|
||||
else if (getValue() == WIFI_POWER_2dBm)
|
||||
setSelectedIndex(10);
|
||||
else if (getValue() == WIFI_POWER_MINUS_1dBm)
|
||||
setSelectedIndex(11);
|
||||
else
|
||||
{
|
||||
Serial.printf("Unknown wifi_power_t: %i", int(getValue()));
|
||||
setSelectedIndex(12);
|
||||
}
|
||||
}
|
||||
|
||||
void ChangeValueDisplay<wifi_power_t>::itemPressed(int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: setValue(WIFI_POWER_19_5dBm); break;
|
||||
case 1: setValue(WIFI_POWER_19dBm); break;
|
||||
case 2: setValue(WIFI_POWER_18_5dBm); break;
|
||||
case 3: setValue(WIFI_POWER_17dBm); break;
|
||||
case 4: setValue(WIFI_POWER_15dBm); break;
|
||||
case 5: setValue(WIFI_POWER_13dBm); break;
|
||||
case 6: setValue(WIFI_POWER_11dBm); break;
|
||||
case 7: setValue(WIFI_POWER_8_5dBm); break;
|
||||
case 8: setValue(WIFI_POWER_7dBm); break;
|
||||
case 9: setValue(WIFI_POWER_5dBm); break;
|
||||
case 10: setValue(WIFI_POWER_2dBm); break;
|
||||
case 11: setValue(WIFI_POWER_MINUS_1dBm); break;
|
||||
}
|
||||
|
||||
triggered();
|
||||
}
|
||||
}
|
17
src/checkboxicon.h
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "menuitem.h"
|
||||
#include "accessorinterface.h"
|
||||
#include "icons/checked.h"
|
||||
#include "icons/unchecked.h"
|
||||
|
||||
namespace {
|
||||
class CheckboxIcon : public virtual MenuItemIconInterface, public virtual AccessorInterface<bool>
|
||||
{
|
||||
public:
|
||||
const MenuItemIcon *icon() const override
|
||||
{
|
||||
return getValue() ? &icons::checked : &icons::unchecked;
|
||||
}
|
||||
};
|
||||
}
|
32
src/colorinterface.h
Normal file
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include "TFT_eSPI.h"
|
||||
|
||||
namespace {
|
||||
class ColorInterface {
|
||||
public:
|
||||
virtual int color() const { return TFT_WHITE; };
|
||||
};
|
||||
|
||||
template<int TColor>
|
||||
class StaticColor : public virtual ColorInterface
|
||||
{
|
||||
public:
|
||||
static constexpr int STATIC_COLOR = TColor;
|
||||
|
||||
int color() const override { return TColor; }
|
||||
};
|
||||
|
||||
using DefaultColor = StaticColor<TFT_WHITE>;
|
||||
using DisabledColor = StaticColor<TFT_DARKGREY>;
|
||||
|
||||
class ChangeableColor : public virtual ColorInterface
|
||||
{
|
||||
public:
|
||||
int color() const override { return m_color; }
|
||||
void setColor(const int &color) { m_color = color; }
|
||||
|
||||
private:
|
||||
int m_color;
|
||||
};
|
||||
}
|
28
src/controller.h
Normal file
@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "bobbycar-protocol/protocol.h"
|
||||
|
||||
#include "feedbackparser.h"
|
||||
|
||||
class HardwareSerial;
|
||||
|
||||
namespace {
|
||||
struct Controller {
|
||||
Controller(HardwareSerial &serial, bool &enableLeft, bool &enableRight, bool &invertLeft, bool &invertRight) :
|
||||
serial{serial}, enableLeft{enableLeft}, enableRight{enableRight}, invertLeft{invertLeft}, invertRight{invertRight}
|
||||
{
|
||||
}
|
||||
|
||||
std::reference_wrapper<HardwareSerial> serial;
|
||||
bool &enableLeft, &enableRight, &invertLeft, &invertRight;
|
||||
|
||||
Command command{};
|
||||
|
||||
bool feedbackValid{};
|
||||
Feedback feedback{};
|
||||
|
||||
FeedbackParser parser{serial, feedbackValid, feedback};
|
||||
};
|
||||
}
|
15
src/debugcolorhelpers.h
Normal file
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "colorinterface.h"
|
||||
#include "globals.h"
|
||||
|
||||
namespace {
|
||||
template<Controller &Tcontroller, int TsuccessColor>
|
||||
class FeedbackColor : public virtual ColorInterface { public: int color() const { return Tcontroller.feedbackValid ? TsuccessColor : TFT_RED; } };
|
||||
|
||||
template<int TsuccessColor>
|
||||
using FrontFeedbackColor = FeedbackColor<front, TsuccessColor>;
|
||||
|
||||
template<int TsuccessColor>
|
||||
using BackFeedbackColor = FeedbackColor<back, TsuccessColor>;
|
||||
}
|
90
src/debugtexthelpers.h
Normal file
@ -0,0 +1,90 @@
|
||||
#pragma once
|
||||
|
||||
#include "textinterface.h"
|
||||
#include "globals.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace {
|
||||
template<Controller &controller>
|
||||
struct ControllerTexts
|
||||
{
|
||||
ControllerTexts() = delete;
|
||||
~ControllerTexts() = delete;
|
||||
|
||||
struct BuzzerFreqText : public virtual TextInterface { public: String text() const override { return String{"buzzerFreq: "} + toString(controller.command.buzzer.freq); } };
|
||||
struct BuzzerPatternText : public virtual TextInterface { public: String text() const override { return String{"buzzerPattern: "} + toString(controller.command.buzzer.pattern); } };
|
||||
struct PoweroffText : public virtual TextInterface { public: String text() const override { return String{"poweroff: "} + toString(controller.command.poweroff); } };
|
||||
struct LedText : public virtual TextInterface { public: String text() const override { return String{"led: "} + toString(controller.command.led); } };
|
||||
|
||||
struct LeftCommand
|
||||
{
|
||||
LeftCommand() = delete;
|
||||
~LeftCommand() = delete;
|
||||
|
||||
struct EnableText : public virtual TextInterface { public: String text() const override { return String{"enable: "} + toString(controller.command.left.enable); } };
|
||||
struct PwmText : public virtual TextInterface { public: String text() const override { return String{"pwm: "} + toString(controller.command.left.pwm); } };
|
||||
struct CtrlTypText : public virtual TextInterface { public: String text() const override { return String{"ctrlTyp: "} + toString(controller.command.left.ctrlTyp); } };
|
||||
struct CtrlModText : public virtual TextInterface { public: String text() const override { return String{"ctrlMod: "} + toString(controller.command.left.ctrlMod); } };
|
||||
struct IMotMaxText : public virtual TextInterface { public: String text() const override { return String{"iMotMax: "} + toString(controller.command.left.iMotMax); } };
|
||||
struct IDcMaxText : public virtual TextInterface { public: String text() const override { return String{"iDcMax: "} + toString(controller.command.left.iDcMax); } };
|
||||
struct NMotMaxText : public virtual TextInterface { public: String text() const override { return String{"nMotMax: "} + toString(controller.command.left.nMotMax); } };
|
||||
struct FieldWeakMaxText : public virtual TextInterface { public: String text() const override { return String{"fieldWeakMax: "} + toString(controller.command.left.fieldWeakMax); } };
|
||||
struct PhaseAdvMaxText : public virtual TextInterface { public: String text() const override { return String{"phaseAdvMax: "} + toString(controller.command.left.phaseAdvMax); } };
|
||||
};
|
||||
|
||||
struct RightCommand
|
||||
{
|
||||
RightCommand() = delete;
|
||||
~RightCommand() = delete;
|
||||
|
||||
struct EnableText : public virtual TextInterface { public: String text() const override { return String{"enable: "} + toString(controller.command.right.enable); } };
|
||||
struct PwmText : public virtual TextInterface { public: String text() const override { return String{"pwm: "} + toString(controller.command.right.pwm); } };
|
||||
struct CtrlTypText : public virtual TextInterface { public: String text() const override { return String{"ctrlTyp: "} + toString(controller.command.right.ctrlTyp); } };
|
||||
struct CtrlModText : public virtual TextInterface { public: String text() const override { return String{"ctrlMod: "} + toString(controller.command.right.ctrlMod); } };
|
||||
struct IMotMaxText : public virtual TextInterface { public: String text() const override { return String{"iMotMax: "} + toString(controller.command.right.iMotMax); } };
|
||||
struct IDcMaxText : public virtual TextInterface { public: String text() const override { return String{"iDcMax: "} + toString(controller.command.right.iDcMax); } };
|
||||
struct NMotMaxText : public virtual TextInterface { public: String text() const override { return String{"nMotMax: "} + toString(controller.command.right.nMotMax); } };
|
||||
struct FieldWeakMaxText : public virtual TextInterface { public: String text() const override { return String{"fieldWeakMax: "} + toString(controller.command.right.fieldWeakMax); } };
|
||||
struct PhaseAdvMaxText : public virtual TextInterface { public: String text() const override { return String{"phaseAdvMax: "} + toString(controller.command.right.phaseAdvMax); } };
|
||||
};
|
||||
|
||||
struct BatVoltageText : public virtual TextInterface { public: String text() const override { auto line = String{"batVoltage: "}; if (controller.feedbackValid) line += toString(controller.feedback.batVoltage); return line; } };
|
||||
struct BatVoltageFixedText : public virtual TextInterface { public: String text() const override { auto line = String{"batVoltage: "}; if (controller.feedbackValid) line += toString(fixBatVoltage(controller.feedback.batVoltage)) + 'V'; return line; } };
|
||||
struct BoardTempText : public virtual TextInterface { public: String text() const override { auto line = String{"boardTemp: "}; if (controller.feedbackValid) line += toString(controller.feedback.boardTemp); return line; } };
|
||||
struct BoardTempFixedText : public virtual TextInterface { public: String text() const override { auto line = String{"boardTemp: "}; if (controller.feedbackValid) line += toString(fixBoardTemp(controller.feedback.boardTemp)) + 'C'; return line; } };
|
||||
struct TimeoutCntSerialText : public virtual TextInterface { public: String text() const override { auto line = String{"timeoutCntSerial: "}; if (controller.feedbackValid) line += toString(controller.feedback.timeoutCntSerial); return line; } };
|
||||
|
||||
struct LeftFeedback
|
||||
{
|
||||
LeftFeedback() = delete;
|
||||
~LeftFeedback() = delete;
|
||||
|
||||
struct AngleText : public virtual TextInterface { public: String text() const override { auto line = String{"angle: "}; if (controller.feedbackValid) line += toString(controller.feedback.left.angle); return line; } };
|
||||
struct SpeedText : public virtual TextInterface { public: String text() const override { auto line = String{"speed: "}; if (controller.feedbackValid) line += toString(controller.feedback.left.speed); return line; } };
|
||||
struct SpeedKmhText : public virtual TextInterface { public: String text() const override { auto line = String{"speed kmh: "}; if (controller.feedbackValid) line += toString(convertToKmh(controller.feedback.left.speed)); return line; } };
|
||||
struct ErrorText : public virtual TextInterface { public: String text() const override { auto line = String{"error: "}; if (controller.feedbackValid) line += toString(controller.feedback.left.error); return line; } };
|
||||
struct CurrentText : public virtual TextInterface { public: String text() const override { auto line = String{"current: "}; if (controller.feedbackValid) line += toString(controller.feedback.left.current); return line; } };
|
||||
struct CurrentFixedText : public virtual TextInterface { public: String text() const override { auto line = String{"current: "}; if (controller.feedbackValid) line += toString(fixCurrent(controller.feedback.left.current)) + 'A'; return line; } };
|
||||
struct ChopsText : public virtual TextInterface { public: String text() const override { auto line = String{"chops: "}; if (controller.feedbackValid) line += toString(controller.feedback.left.chops); return line; } };
|
||||
struct HallText : public virtual TextInterface { public: String text() const override { auto line = String{"hall: "}; if (controller.feedbackValid) line += hallString(controller.feedback.left); return line; } };
|
||||
};
|
||||
|
||||
struct RightFeedback
|
||||
{
|
||||
RightFeedback() = delete;
|
||||
~RightFeedback() = delete;
|
||||
|
||||
struct AngleText : public virtual TextInterface { public: String text() const override { auto line = String{"angle: "}; if (controller.feedbackValid) line += toString(controller.feedback.right.angle); return line; } };
|
||||
struct SpeedText : public virtual TextInterface { public: String text() const override { auto line = String{"speed: "}; if (controller.feedbackValid) line += toString(controller.feedback.right.speed); return line; } };
|
||||
struct SpeedKmhText : public virtual TextInterface { public: String text() const override { auto line = String{"speed kmh: "}; if (controller.feedbackValid) line += toString(convertToKmh(controller.feedback.right.speed)); return line; } };
|
||||
struct ErrorText : public virtual TextInterface { public: String text() const override { auto line = String{"error: "}; if (controller.feedbackValid) line += toString(controller.feedback.right.error); return line; } };
|
||||
struct CurrentText : public virtual TextInterface { public: String text() const override { auto line = String{"current: "}; if (controller.feedbackValid) line += toString(controller.feedback.right.current); return line; } };
|
||||
struct CurrentFixedText : public virtual TextInterface { public: String text() const override { auto line = String{"current: "}; if (controller.feedbackValid) line += toString(fixCurrent(controller.feedback.right.current)) + 'A'; return line; } };
|
||||
struct ChopsText : public virtual TextInterface { public: String text() const override { auto line = String{"chops: "}; if (controller.feedbackValid) line += toString(controller.feedback.right.chops); return line; } };
|
||||
struct HallText : public virtual TextInterface { public: String text() const override { auto line = String{"hall: "}; if (controller.feedbackValid) line += hallString(controller.feedback.right); return line; } };
|
||||
};
|
||||
};
|
||||
|
||||
using FrontTexts = ControllerTexts<front>;
|
||||
using BackTexts = ControllerTexts<back>;
|
||||
}
|
17
src/demodisplay.h
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "actioninterface.h"
|
||||
#include "display.h"
|
||||
|
||||
namespace {
|
||||
class DemoDisplay : public Display, public virtual ActionInterface
|
||||
{
|
||||
public:
|
||||
void button() override;
|
||||
};
|
||||
|
||||
void DemoDisplay::button()
|
||||
{
|
||||
triggered();
|
||||
}
|
||||
}
|
30
src/display.h
Normal file
@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <WString.h>
|
||||
|
||||
namespace {
|
||||
class MenuDisplay;
|
||||
class ChangeValueDisplayInterface;
|
||||
}
|
||||
|
||||
namespace {
|
||||
class Display {
|
||||
public:
|
||||
virtual ~Display() = default;
|
||||
|
||||
virtual void start() {};
|
||||
virtual void initScreen() {};
|
||||
virtual void update() {};
|
||||
virtual void redraw() {};
|
||||
virtual void stop() {}
|
||||
|
||||
virtual void rotate(int offset) {}
|
||||
virtual void button() {}
|
||||
|
||||
virtual MenuDisplay *asMenuDisplay() { return nullptr; }
|
||||
virtual const MenuDisplay *asMenuDisplay() const { return nullptr; }
|
||||
|
||||
virtual ChangeValueDisplayInterface *asChangeValueDisplayInterface() { return nullptr; }
|
||||
virtual const ChangeValueDisplayInterface *asChangeValueDisplayInterface() const { return nullptr; }
|
||||
};
|
||||
}
|
89
src/displays/bmsdisplay.h
Normal file
@ -0,0 +1,89 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "demodisplay.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "globals.h"
|
||||
#include "bmsutils.h"
|
||||
#include "widgets/label.h"
|
||||
|
||||
namespace {
|
||||
class MainMenu;
|
||||
class MetersDisplay;
|
||||
class StatusDisplay;
|
||||
}
|
||||
namespace {
|
||||
class BmsDisplay : public DemoDisplay, public SwitchScreenAction<MainMenu>
|
||||
{
|
||||
public:
|
||||
void initScreen() override;
|
||||
void redraw() override;
|
||||
|
||||
void rotate(int offset) override;
|
||||
|
||||
Label m_statusLabel{0, 0};
|
||||
|
||||
Label m_voltageLabel{105, 50};
|
||||
Label m_currentLabel{105, 75};
|
||||
Label m_capacityLabel{105, 100};
|
||||
Label m_socLabel{105, 125};
|
||||
Label m_cycleLabel{105, 150};
|
||||
Label m_powerLabel{105, 175};
|
||||
|
||||
std::array<Label, 12> m_battLabels{{
|
||||
Label{0, 225}, Label{60, 225}, Label{120, 225}, Label{180, 225},
|
||||
Label{0, 250}, Label{60, 250}, Label{120, 250}, Label{180, 250},
|
||||
Label{0, 275}, Label{60, 275}, Label{120, 275}, Label{180, 275}
|
||||
}};
|
||||
};
|
||||
|
||||
void BmsDisplay::initScreen()
|
||||
{
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
tft.setTextColor(TFT_WHITE, TFT_BLACK);
|
||||
|
||||
tft.setTextFont(2);
|
||||
m_statusLabel.start();
|
||||
m_statusLabel.redraw("init");
|
||||
|
||||
tft.setTextFont(4);
|
||||
tft.drawString("Voltage:", 0, 50);
|
||||
m_voltageLabel.start();
|
||||
tft.drawString("Current:", 0, 75);
|
||||
m_currentLabel.start();
|
||||
tft.drawString("Capacity:", 0, 100);
|
||||
m_capacityLabel.start();
|
||||
tft.drawString("SOC:", 0, 125);
|
||||
m_socLabel.start();
|
||||
tft.drawString("Cycle:", 0, 150);
|
||||
m_cycleLabel.start();
|
||||
tft.drawString("Power:", 0, 175);
|
||||
m_powerLabel.start();
|
||||
|
||||
for (auto &label : m_battLabels)
|
||||
label.start();
|
||||
}
|
||||
|
||||
void BmsDisplay::redraw()
|
||||
{
|
||||
m_statusLabel.redraw(bluetoothSerial.hasClient() ? "connected" : "not connected");
|
||||
m_voltageLabel.redraw(String{bms::voltage} + 'V');
|
||||
m_currentLabel.redraw(String{bms::current} + 'A');
|
||||
m_capacityLabel.redraw(String{int(bms::capacity)} + "mAh");
|
||||
m_socLabel.redraw(String{bms::soc} + '%');
|
||||
m_cycleLabel.redraw(String{bms::cycle} + "AH");
|
||||
m_powerLabel.redraw(String{bms::power} + 'W');
|
||||
|
||||
for (int i = 0; i < 12; i++)
|
||||
m_battLabels[i].redraw(String{bms::batt[i]});
|
||||
}
|
||||
|
||||
void BmsDisplay::rotate(int offset)
|
||||
{
|
||||
if (offset < 0)
|
||||
switchScreen<MetersDisplay>();
|
||||
else if (offset > 0)
|
||||
switchScreen<StatusDisplay>();
|
||||
}
|
||||
}
|
107
src/displays/calibratedisplay.h
Normal file
@ -0,0 +1,107 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
|
||||
#include <WString.h>
|
||||
|
||||
#include "demodisplay.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "globals.h"
|
||||
#include "texts.h"
|
||||
#include "widgets/label.h"
|
||||
#include "widgets/progressbar.h"
|
||||
#include "modes/ignoreinputmode.h"
|
||||
|
||||
namespace {
|
||||
class StatusDisplay;
|
||||
class PotiSettingsMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
class CalibrateDisplay : public DemoDisplay
|
||||
{
|
||||
using Base = DemoDisplay;
|
||||
|
||||
public:
|
||||
CalibrateDisplay() = default;
|
||||
CalibrateDisplay(bool bootup);
|
||||
|
||||
void start() override;
|
||||
void initScreen() override;
|
||||
void redraw() override;
|
||||
void stop() override;
|
||||
|
||||
void triggered() override;
|
||||
|
||||
private:
|
||||
const bool m_bootup{false};
|
||||
ModeInterface *m_oldMode;
|
||||
IgnoreInputMode m_mode{0, ControlType::FieldOrientedControl, ControlMode::Torque};
|
||||
|
||||
std::array<Label, 4> m_labels {{
|
||||
Label{25, 50}, // 100, 23
|
||||
Label{25, 75}, // 100, 23
|
||||
Label{25, 100}, // 100, 23
|
||||
Label{25, 125} // 100, 23
|
||||
}};
|
||||
|
||||
ProgressBar m_progressBar0{20, 200, 200, 10, 0, 1000};
|
||||
ProgressBar m_progressBar1{20, 230, 200, 10, 0, 1000};
|
||||
};
|
||||
|
||||
CalibrateDisplay::CalibrateDisplay(bool bootup) :
|
||||
m_bootup{bootup}
|
||||
{
|
||||
}
|
||||
|
||||
void CalibrateDisplay::start()
|
||||
{
|
||||
m_oldMode = currentMode;
|
||||
currentMode = &m_mode;
|
||||
}
|
||||
|
||||
void CalibrateDisplay::initScreen()
|
||||
{
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
tft.setTextFont(4);
|
||||
tft.setTextColor(TFT_YELLOW);
|
||||
|
||||
tft.drawString(TEXT_CALIBRATE, 5, 5, 4);
|
||||
|
||||
tft.fillRect(0, 34, tft.width(), 3, TFT_WHITE);
|
||||
|
||||
tft.setTextColor(TFT_WHITE, TFT_BLACK);
|
||||
|
||||
for (auto &label : m_labels)
|
||||
label.start();
|
||||
|
||||
m_progressBar0.start();
|
||||
m_progressBar1.start();
|
||||
}
|
||||
|
||||
void CalibrateDisplay::redraw()
|
||||
{
|
||||
m_labels[0].redraw(String{gas});
|
||||
m_labels[1].redraw(String{raw_gas});
|
||||
|
||||
m_labels[2].redraw(String{brems});
|
||||
m_labels[3].redraw(String{raw_brems});
|
||||
|
||||
m_progressBar0.redraw(gas);
|
||||
m_progressBar1.redraw(brems);
|
||||
}
|
||||
|
||||
void CalibrateDisplay::stop()
|
||||
{
|
||||
if (currentMode == &m_mode)
|
||||
currentMode = m_oldMode;
|
||||
}
|
||||
|
||||
void CalibrateDisplay::triggered()
|
||||
{
|
||||
if (m_bootup)
|
||||
switchScreen<StatusDisplay>();
|
||||
else
|
||||
switchScreen<PotiSettingsMenu>();
|
||||
}
|
||||
}
|
51
src/displays/dualgraphdisplay.h
Normal file
@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include "demodisplay.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "textinterface.h"
|
||||
#include "widgets/label.h"
|
||||
#include "widgets/graph.h"
|
||||
#include "globals.h"
|
||||
#include "statistics.h"
|
||||
|
||||
namespace {
|
||||
class GraphsMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
class DualGraphDisplay : public DemoDisplay, public SwitchScreenAction<GraphsMenu>
|
||||
{
|
||||
using Base = DemoDisplay;
|
||||
|
||||
public:
|
||||
void initScreen() override;
|
||||
void redraw() override;
|
||||
|
||||
private:
|
||||
Label m_titleLabel{5, 5}; // 230, 25
|
||||
|
||||
Graph<200, 1> m_graph0{0, 40, 133};
|
||||
Graph<200, 1> m_graph1{0, 179, 133};
|
||||
};
|
||||
|
||||
void DualGraphDisplay::initScreen()
|
||||
{
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
|
||||
m_titleLabel.start();
|
||||
tft.fillRect(0, 34, tft.width(), 3, TFT_WHITE);
|
||||
|
||||
m_graph0.start({statistics::gas});
|
||||
m_graph1.start({statistics::brems});
|
||||
}
|
||||
|
||||
void DualGraphDisplay::redraw()
|
||||
{
|
||||
tft.setTextFont(4);
|
||||
tft.setTextColor(TFT_YELLOW, TFT_BLACK);
|
||||
m_titleLabel.redraw("Gas/Brems dual");
|
||||
|
||||
m_graph0.redraw({statistics::gas});
|
||||
m_graph1.redraw({statistics::brems});
|
||||
}
|
||||
}
|
188
src/displays/gameoflifedisplay.h
Normal file
@ -0,0 +1,188 @@
|
||||
#pragma once
|
||||
|
||||
#include <bitset>
|
||||
#include <memory>
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <HardwareSerial.h>
|
||||
|
||||
#include "demodisplay.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
|
||||
namespace {
|
||||
class DemosMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
class GameOfLifeDisplay : public DemoDisplay, public SwitchScreenAction<DemosMenu>
|
||||
{
|
||||
using Base = DemoDisplay;
|
||||
|
||||
public:
|
||||
void start() override;
|
||||
void initScreen() override;
|
||||
void redraw() override;
|
||||
void stop() override;
|
||||
|
||||
private:
|
||||
|
||||
//Draws the grid on the display
|
||||
void drawGrid();
|
||||
|
||||
//Initialise Grid
|
||||
void initGrid();
|
||||
|
||||
// Check the Moore neighborhood
|
||||
int getNumberOfNeighbors(int x, int y);
|
||||
|
||||
//Compute the CA. Basically everything related to CA starts here
|
||||
void computeCA();
|
||||
|
||||
//static const constexpr auto GRIDX = 80;
|
||||
//static const constexpr auto GRIDY = 60;
|
||||
//static const constexpr auto CELLXY = 4;
|
||||
|
||||
static const constexpr auto GRIDX = 160;
|
||||
static const constexpr auto GRIDY = 120;
|
||||
static const constexpr auto CELLXY = 2;
|
||||
|
||||
static const constexpr auto GEN_DELAY = 0;
|
||||
|
||||
template<typename T> auto index(T x, T y)
|
||||
{
|
||||
if (x >= GRIDX)
|
||||
{
|
||||
Serial.printf("x: %i", x);
|
||||
return 0;
|
||||
}
|
||||
if (y >= GRIDY)
|
||||
{
|
||||
Serial.printf("y: %i", x);
|
||||
return 0;
|
||||
}
|
||||
return (x * GRIDX) + y;
|
||||
}
|
||||
|
||||
struct Data
|
||||
{
|
||||
std::bitset<GRIDX*GRIDY> grid, newgrid;
|
||||
};
|
||||
|
||||
std::unique_ptr<Data> m_data;
|
||||
|
||||
int gen = 0;
|
||||
};
|
||||
|
||||
void GameOfLifeDisplay::start()
|
||||
{
|
||||
m_data = std::make_unique<Data>();
|
||||
}
|
||||
|
||||
void GameOfLifeDisplay::initScreen()
|
||||
{
|
||||
tft.setRotation(3);
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
}
|
||||
|
||||
void GameOfLifeDisplay::redraw()
|
||||
{
|
||||
if (gen == 0)
|
||||
{
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
initGrid();
|
||||
}
|
||||
|
||||
computeCA();
|
||||
drawGrid();
|
||||
|
||||
m_data->grid = m_data->newgrid;
|
||||
// for (int16_t x = 1; x < GRIDX-1; x++) {
|
||||
// for (int16_t y = 1; y < GRIDY-1; y++) {
|
||||
// grid[index(x,y)] = m_data->newgrid[index(x,y)];
|
||||
// }
|
||||
// }
|
||||
|
||||
if (++gen == 200)
|
||||
gen = 0;
|
||||
}
|
||||
|
||||
void GameOfLifeDisplay::stop()
|
||||
{
|
||||
tft.setRotation(0);
|
||||
m_data = nullptr;
|
||||
}
|
||||
|
||||
void GameOfLifeDisplay::drawGrid()
|
||||
{
|
||||
uint16_t color = TFT_WHITE;
|
||||
for (int16_t x = 1; x < GRIDX - 1; x++) {
|
||||
for (int16_t y = 1; y < GRIDY - 1; y++) {
|
||||
if ((m_data->grid[index(x,y)]) != (m_data->newgrid[index(x,y)])) {
|
||||
if (m_data->newgrid[index(x,y)] == 1)
|
||||
color = 0xFFFF; //random(0xFFFF);
|
||||
else
|
||||
color = 0;
|
||||
tft.fillRect(CELLXY * x, CELLXY * y, CELLXY, CELLXY, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GameOfLifeDisplay::initGrid()
|
||||
{
|
||||
for (int16_t x = 0; x < GRIDX; x++) {
|
||||
for (int16_t y = 0; y < GRIDY; y++) {
|
||||
m_data->newgrid[index(x,y)] = 0;
|
||||
|
||||
if (x == 0 || x == GRIDX - 1 || y == 0 || y == GRIDY - 1)
|
||||
m_data->grid[index(x,y)] = 0;
|
||||
else
|
||||
{
|
||||
if (random(3) == 1)
|
||||
m_data->grid[index(x,y)] = 1;
|
||||
else
|
||||
m_data->grid[index(x,y)] = 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int GameOfLifeDisplay::getNumberOfNeighbors(int x, int y)
|
||||
{
|
||||
int n{};
|
||||
for (auto xOffset : {-1,0,1})
|
||||
for (auto yOffset : {-1,0,1})
|
||||
{
|
||||
if (xOffset == 0 && yOffset == 0)
|
||||
continue;
|
||||
|
||||
const auto new_x = x+xOffset;
|
||||
const auto new_y = y+yOffset;
|
||||
|
||||
if (new_x >= 0 && new_y >= 0 &&
|
||||
new_x < GRIDX && new_y < GRIDY)
|
||||
n += m_data->grid[index(new_x, new_y)];
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void GameOfLifeDisplay::computeCA()
|
||||
{
|
||||
for (int16_t x = 1; x < GRIDX; x++) {
|
||||
for (int16_t y = 1; y < GRIDY; y++) {
|
||||
int neighbors = getNumberOfNeighbors(x, y);
|
||||
if (m_data->grid[index(x,y)] == true && (neighbors == 2 || neighbors == 3 ))
|
||||
m_data->newgrid[index(x,y)] = true;
|
||||
else if (m_data->grid[index(x,y)] == 1)
|
||||
m_data->newgrid[index(x,y)] = false;
|
||||
if (m_data->grid[index(x,y)] == false && (neighbors == 3))
|
||||
m_data->newgrid[index(x,y)] = true;
|
||||
else if (m_data->grid[index(x,y)] == 0)
|
||||
m_data->newgrid[index(x,y)] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
70
src/displays/graphdisplay.h
Normal file
@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
|
||||
#include "demodisplay.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "textinterface.h"
|
||||
#include "widgets/label.h"
|
||||
#include "widgets/graph.h"
|
||||
#include "globals.h"
|
||||
#include "statistics.h"
|
||||
|
||||
namespace {
|
||||
class GraphsMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
template<size_t COUNT>
|
||||
class MultiStatisticsInterface
|
||||
{
|
||||
public:
|
||||
virtual std::array<std::reference_wrapper<const statistics::ContainerType>, COUNT> getBuffers() const = 0;
|
||||
};
|
||||
|
||||
class MultiStatisticsSingleImpl : public virtual MultiStatisticsInterface<1>, public virtual BufferAccessorInterface
|
||||
{
|
||||
public:
|
||||
std::array<std::reference_wrapper<const statistics::ContainerType>, 1> getBuffers() const
|
||||
{
|
||||
return {getBuffer()};
|
||||
}
|
||||
};
|
||||
|
||||
template<size_t COUNT>
|
||||
class GraphDisplay : public DemoDisplay, public SwitchScreenAction<GraphsMenu>, public virtual TextInterface, public virtual MultiStatisticsInterface<COUNT>
|
||||
{
|
||||
using Base = DemoDisplay;
|
||||
|
||||
public:
|
||||
void initScreen() override;
|
||||
void redraw() override;
|
||||
|
||||
private:
|
||||
static constexpr int screenHeight = 320, topMargin = 40, bottomMargin = 10, labelOffset = -5;
|
||||
static constexpr int graphHeight = screenHeight-topMargin-bottomMargin;
|
||||
|
||||
Label m_titleLabel{5, 5}; // 230, 25
|
||||
|
||||
Graph<200, COUNT> m_graph{0, 40, 270};
|
||||
};
|
||||
|
||||
template<size_t COUNT>
|
||||
void GraphDisplay<COUNT>::initScreen()
|
||||
{
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
|
||||
m_titleLabel.start();
|
||||
tft.fillRect(0, 34, tft.width(), 3, TFT_WHITE);
|
||||
|
||||
m_graph.start(static_cast<const MultiStatisticsInterface<COUNT> &>(*this).getBuffers());
|
||||
}
|
||||
|
||||
template<size_t COUNT>
|
||||
void GraphDisplay<COUNT>::redraw()
|
||||
{
|
||||
tft.setTextFont(4);
|
||||
tft.setTextColor(TFT_YELLOW, TFT_BLACK);
|
||||
m_titleLabel.redraw(text());
|
||||
|
||||
m_graph.redraw(static_cast<const MultiStatisticsInterface<COUNT> &>(*this).getBuffers());
|
||||
}
|
||||
}
|
163
src/displays/lockscreen.h
Normal file
@ -0,0 +1,163 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "display.h"
|
||||
#include "widgets/label.h"
|
||||
#include "globals.h"
|
||||
#include "utils.h"
|
||||
#include "texts.h"
|
||||
#include "modes/ignoreinputmode.h"
|
||||
|
||||
namespace {
|
||||
class MainMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
class Lockscreen : public Display
|
||||
{
|
||||
using Base = Display;
|
||||
|
||||
static constexpr auto boxWidth = 35;
|
||||
static constexpr auto boxHeight = 50;
|
||||
static constexpr auto spacing = 20;
|
||||
|
||||
public:
|
||||
void start() override;
|
||||
void initScreen() override;
|
||||
void update() override {}
|
||||
void redraw() override;
|
||||
void stop() override;
|
||||
|
||||
void button() override;
|
||||
void rotate(int offset) override;
|
||||
|
||||
private:
|
||||
void drawRect(int index, int offset, uint32_t color) const;
|
||||
|
||||
std::array<Label, 4> m_labels {{
|
||||
Label{spacing, 100}, // boxWidth, boxHeight
|
||||
Label{spacing*2+boxWidth, 100}, // boxWidth, boxHeight
|
||||
Label{spacing*3+boxWidth*2, 100}, // boxWidth, boxHeight
|
||||
Label{spacing*4+boxWidth*3, 100} // boxWidth, boxHeight
|
||||
}};
|
||||
|
||||
std::array<int8_t, 4> m_numbers;
|
||||
|
||||
uint8_t m_currentIndex{};
|
||||
|
||||
bool m_pressed;
|
||||
int m_rotated;
|
||||
|
||||
ModeInterface *m_oldMode;
|
||||
IgnoreInputMode m_mode{0, ControlType::FieldOrientedControl, ControlMode::Speed};
|
||||
};
|
||||
|
||||
void Lockscreen::start()
|
||||
{
|
||||
m_numbers = {0,0,0,0};
|
||||
m_currentIndex = 0;
|
||||
m_pressed = false;
|
||||
m_rotated = 0;
|
||||
|
||||
m_oldMode = currentMode;
|
||||
currentMode = &m_mode;
|
||||
}
|
||||
|
||||
void Lockscreen::initScreen()
|
||||
{
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
tft.setTextFont(4);
|
||||
tft.setTextColor(TFT_YELLOW);
|
||||
|
||||
tft.drawString(TEXT_LOCKVEHICLE, 5, 5);
|
||||
|
||||
tft.fillRect(0, 34, tft.width(), 3, TFT_WHITE);
|
||||
|
||||
tft.setTextColor(TFT_WHITE);
|
||||
tft.drawString("Enter code to unlock:", 0, 50);
|
||||
|
||||
tft.setTextColor(TFT_WHITE, TFT_BLACK);
|
||||
|
||||
for(int i = 0; i <= 3; i++)
|
||||
{
|
||||
drawRect(i, 3, TFT_WHITE);
|
||||
drawRect(i, 4, TFT_WHITE);
|
||||
}
|
||||
|
||||
for (auto &label : m_labels)
|
||||
label.start();
|
||||
|
||||
tft.setTextFont(7);
|
||||
|
||||
drawRect(0, 1, TFT_YELLOW);
|
||||
drawRect(0, 2, TFT_YELLOW);
|
||||
m_labels[0].redraw(String(m_numbers[0]));
|
||||
}
|
||||
|
||||
void Lockscreen::redraw()
|
||||
{
|
||||
if (m_pressed)
|
||||
{
|
||||
drawRect(m_currentIndex, 1, TFT_BLACK);
|
||||
drawRect(m_currentIndex, 2, TFT_BLACK);
|
||||
|
||||
if (++m_currentIndex>=4)
|
||||
{
|
||||
if (m_numbers == decltype(m_numbers){1,2,3,4})
|
||||
{
|
||||
switchScreen<MainMenu>();
|
||||
return;
|
||||
}
|
||||
|
||||
m_numbers = {0,0,0,0};
|
||||
m_currentIndex = 0;
|
||||
std::for_each(std::begin(m_labels) + 1, std::end(m_labels), [](auto &label){ label.redraw({}); });
|
||||
}
|
||||
|
||||
m_labels[m_currentIndex].redraw(String{m_numbers[m_currentIndex]});
|
||||
|
||||
drawRect(m_currentIndex, 1, TFT_YELLOW);
|
||||
drawRect(m_currentIndex, 2, TFT_YELLOW);
|
||||
|
||||
m_pressed = false;
|
||||
}
|
||||
|
||||
if (m_rotated)
|
||||
{
|
||||
m_numbers[m_currentIndex] -= m_rotated;
|
||||
|
||||
if (m_numbers[m_currentIndex] < 0)
|
||||
m_numbers[m_currentIndex]+=10;
|
||||
else if (m_numbers[m_currentIndex] > 9)
|
||||
m_numbers[m_currentIndex]-=10;
|
||||
|
||||
m_labels[m_currentIndex].redraw(String(m_numbers[m_currentIndex]));
|
||||
|
||||
m_rotated = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Lockscreen::stop()
|
||||
{
|
||||
Base::stop();
|
||||
|
||||
if (currentMode == &m_mode)
|
||||
currentMode = m_oldMode;
|
||||
}
|
||||
|
||||
void Lockscreen::button()
|
||||
{
|
||||
m_pressed = true;
|
||||
}
|
||||
|
||||
void Lockscreen::rotate(int offset)
|
||||
{
|
||||
m_rotated += offset;
|
||||
}
|
||||
|
||||
void Lockscreen::drawRect(int index, int offset, uint32_t color) const
|
||||
{
|
||||
tft.drawRect(m_labels[index].x()-offset, m_labels[index].y()-offset, boxWidth+(offset*2), boxHeight+(offset*2), color);
|
||||
}
|
||||
}
|
94
src/displays/matrixdisplay.h
Normal file
@ -0,0 +1,94 @@
|
||||
#pragma once
|
||||
|
||||
#include "demodisplay.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "globals.h"
|
||||
#include "utils.h"
|
||||
#include "texts.h"
|
||||
|
||||
namespace {
|
||||
class DemosMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
class MatrixDisplay : public DemoDisplay, public SwitchScreenAction<DemosMenu>
|
||||
{
|
||||
using Base = DemoDisplay;
|
||||
|
||||
public:
|
||||
void initScreen() override;
|
||||
void redraw() override;
|
||||
void stop() override;
|
||||
|
||||
private:
|
||||
int scroll_slow(int lines, int wait);
|
||||
|
||||
static constexpr auto TEXT_HEIGHT = 8; // Height of text to be printed and scrolled
|
||||
static constexpr auto BOT_FIXED_AREA = 0; // Number of lines in bottom fixed area (lines counted from bottom of screen)
|
||||
static constexpr auto TOP_FIXED_AREA = 0; // Number of lines in top fixed area (lines counted from top of screen)
|
||||
|
||||
uint16_t yStart = TOP_FIXED_AREA;
|
||||
uint16_t yArea = 320 - TOP_FIXED_AREA - BOT_FIXED_AREA;
|
||||
uint16_t yDraw = 320 - BOT_FIXED_AREA - TEXT_HEIGHT;
|
||||
byte pos[42];
|
||||
uint16_t xPos = 0;
|
||||
};
|
||||
|
||||
void MatrixDisplay::initScreen()
|
||||
{
|
||||
tft.setRotation(2);
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
setupScrollArea(TOP_FIXED_AREA, BOT_FIXED_AREA);
|
||||
|
||||
// First fill the screen with random streaks of characters
|
||||
for (int j = 0; j < 600; j += TEXT_HEIGHT)
|
||||
{
|
||||
for (int i = 0; i < 40; i++)
|
||||
{
|
||||
if (pos[i] > 20)
|
||||
pos[i] -= 3; // Rapid fade initially brightness values
|
||||
|
||||
if (pos[i] > 0)
|
||||
pos[i] -= 1; // Slow fade later
|
||||
|
||||
if ((random(20) == 1) && (j<400))
|
||||
pos[i] = 63; // ~1 in 20 probability of a new character
|
||||
|
||||
tft.setTextColor(pos[i] << 5, TFT_BLACK); // Set the green character brightness
|
||||
|
||||
if (pos[i] == 63)
|
||||
tft.setTextColor(TFT_WHITE, TFT_BLACK); // Draw white character
|
||||
|
||||
xPos += tft.drawChar(random(32, 128), xPos, yDraw, 1); // Draw the character
|
||||
}
|
||||
yDraw = scroll_slow(TEXT_HEIGHT, 14); // Scroll, 14ms per pixel line
|
||||
xPos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void MatrixDisplay::redraw()
|
||||
{
|
||||
yDraw = scroll_slow(320,5);
|
||||
}
|
||||
|
||||
void MatrixDisplay::stop()
|
||||
{
|
||||
scrollAddress(0);
|
||||
tft.setRotation(0);
|
||||
}
|
||||
|
||||
int MatrixDisplay::scroll_slow(int lines, int wait)
|
||||
{
|
||||
int yTemp = yStart;
|
||||
|
||||
for (int i = 0; i < lines; i++) {
|
||||
yStart++;
|
||||
if (yStart == 320 - BOT_FIXED_AREA)
|
||||
yStart = TOP_FIXED_AREA;
|
||||
scrollAddress(yStart);
|
||||
delay(wait);
|
||||
}
|
||||
|
||||
return yTemp;
|
||||
}
|
||||
}
|
48
src/displays/menus/aboutmenu.h
Normal file
@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "utils.h"
|
||||
#include "actions/dummyaction.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "icons/back.h"
|
||||
#include "esptexthelpers.h"
|
||||
#include "texts.h"
|
||||
|
||||
namespace {
|
||||
class SettingsMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
constexpr char TEXT_VERSION[] = "Version: 1.0";
|
||||
constexpr char TEXT_ESPINFO[] = "ESP info:";
|
||||
|
||||
class AboutMenu :
|
||||
public MenuDisplay,
|
||||
public StaticText<TEXT_ABOUT>,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, StaticText<TEXT_VERSION>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<nullptr>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_ESPINFO>, DummyAction>,
|
||||
makeComponent<MenuItem, EspHeapSizeText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, EspFreeHeapText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, EspMinFreeHeapText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, EspMaxAllocHeapText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, EspPsramSizeText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, EspFreePsramText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, EspMinFreePsramText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, EspMaxAllocPsramText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, EspChipRevisionText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, EspCpuFreqMHzText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, EspCycleCountText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, EspSdkVersionText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, EspFlashChipSizeText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, EspFlashChipSpeedText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, EspFlashChipModeText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, EspSketchSizeText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, EspSketchMd5Text, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, EspFreeSketchSpaceText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&icons::back>>
|
||||
>
|
||||
{};
|
||||
}
|
66
src/displays/menus/accesspointwifisettingsmenu.h
Normal file
@ -0,0 +1,66 @@
|
||||
#pragma once
|
||||
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "menuitem.h"
|
||||
#include "actions/dummyaction.h"
|
||||
#include "actions/wifisoftapenableipv6action.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
|
||||
namespace {
|
||||
class WifiSettingsMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
class WifiSoftApGetStationNumText : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"softAPgetStationNum: "} + WiFi.softAPgetStationNum(); }
|
||||
};
|
||||
class WifiSoftApIpText : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"softAPIP: "} + WiFi.softAPIP().toString(); }
|
||||
};
|
||||
class WifiSoftApBroadcastIpText : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"softAPBroadcastIP: "} + WiFi.softAPBroadcastIP().toString(); }
|
||||
};
|
||||
class WifiSoftApNetworkIdText : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"softAPNetworkID: "} + WiFi.softAPNetworkID().toString(); }
|
||||
};
|
||||
class WifiSoftApSubnetCidrText : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"softAPSubnetCIDR: "} + WiFi.softAPSubnetCIDR(); }
|
||||
};
|
||||
class WifiSoftApIpV6Text : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"softAPIPv6: "} + WiFi.softAPIPv6().toString(); }
|
||||
};
|
||||
class WifiSoftApHostnameText : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"softAPgetHostname: "} + WiFi.softAPgetHostname(); }
|
||||
};
|
||||
class WifiSoftApMacAddressText : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"softAPmacAddress: "} + WiFi.softAPmacAddress(); }
|
||||
};
|
||||
|
||||
class AccessPointWifiSettingsMenu :
|
||||
public MenuDisplay,
|
||||
public StaticText<TEXT_ACCESSPOINTWIFISETTINGS>,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, WifiSoftApGetStationNumText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, WifiSoftApIpText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, WifiSoftApBroadcastIpText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, WifiSoftApNetworkIdText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, WifiSoftApSubnetCidrText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_WIFISOFTAPENABLEIPV6>, WifiSoftApEnableIpV6Action>,
|
||||
makeComponent<MenuItem, WifiSoftApIpV6Text, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, WifiSoftApHostnameText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, WifiSoftApMacAddressText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<WifiSettingsMenu>, StaticMenuItemIcon<&icons::back>>
|
||||
>
|
||||
{};
|
||||
}
|
39
src/displays/menus/bluetoothsettingsmenu.h
Normal file
@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "menuitem.h"
|
||||
#include "actions/dummyaction.h"
|
||||
#include "actions/bluetoothbeginaction.h"
|
||||
#include "actions/bluetoothbeginmasteraction.h"
|
||||
#include "actions/bluetoothflushaction.h"
|
||||
#include "actions/bluetoothendaction.h"
|
||||
#include "actions/bluetoothdisconnectaction.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "bluetoothtexthelpers.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
|
||||
namespace {
|
||||
class SettingsMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
class BluetoothSettingsMenu :
|
||||
public MenuDisplay,
|
||||
public StaticText<TEXT_BLUETOOTHSETTINGS>,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, BluetoothAvailableText, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, BluetoothHasClientText, DisabledColor, DummyAction>,
|
||||
// makeComponent<MenuItem, BluetoothConnectedText, DisabledColor, DummyAction>, // crashes
|
||||
makeComponent<MenuItem, BluetoothIsReadyText, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, BluetoothIsReadyMasterText, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BLUETOOTHBEGIN>, BluetoothBeginAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BLUETOOTHBEGINMASTER>, BluetoothBeginMasterAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BLUETOOTHFLUSH>, BluetoothFlushAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BLUETOOTHEND>, BluetoothEndAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BLUETOOTHDISCONNECT>, BluetoothDisconnectAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&icons::back>>
|
||||
>
|
||||
{};
|
||||
}
|
38
src/displays/menus/bmsmenu.h
Normal file
@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "utils.h"
|
||||
#include "menuitem.h"
|
||||
#include "actions/bluetoothconnectbmsaction.h"
|
||||
#include "actions/bluetoothdisconnectaction.h"
|
||||
#include "actions/dummyaction.h"
|
||||
#include "actions/bmsturnonchargeaction.h"
|
||||
#include "actions/bmsturnoffchargeaction.h"
|
||||
#include "actions/bmsturnondischargeaction.h"
|
||||
#include "actions/bmsturnoffdischargeaction.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "bluetoothtexthelpers.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
|
||||
namespace {
|
||||
class MainMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
class BmsMenu :
|
||||
public MenuDisplay,
|
||||
public StaticText<TEXT_BMS>,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, StaticText<TEXT_CONNECTBMS>, BluetoothConnectBmsAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DISCONNECTBMS>, BluetoothDisconnectAction>,
|
||||
makeComponent<MenuItem, BluetoothHasClientText, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_TURNONCHARGE>, BmsTurnOnChargeAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_TURNOFFCHARGE>, BmsTurnOffChargeAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_TURNONDISCHARGE>, BmsTurnOnDischargeAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_TURNOFFDISCHARGE>, BmsTurnOffDischargeAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&icons::back>>
|
||||
>
|
||||
{};
|
||||
}
|
55
src/displays/menus/buzzermenu.h
Normal file
@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "utils.h"
|
||||
#include "changevaluedisplay.h"
|
||||
#include "menuitem.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "actions/toggleboolaction.h"
|
||||
#include "checkboxicon.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
#include "globals.h"
|
||||
#include "settingsaccessors.h"
|
||||
|
||||
namespace {
|
||||
class BuzzerMenu;
|
||||
class SettingsMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct FrontFreqAccessor : public RefAccessor<uint8_t> { uint8_t &getRef() const override { return front.command.buzzer.freq; } };
|
||||
using FrontFreqChangeScreen = makeComponent<ChangeValueDisplay<uint8_t>, StaticText<TEXT_FRONTFREQ>, FrontFreqAccessor, SwitchScreenAction<BuzzerMenu>>;
|
||||
|
||||
struct FrontPatternAccessor : public RefAccessor<uint8_t> { uint8_t &getRef() const override { return front.command.buzzer.pattern; } };
|
||||
using FrontPatternChangeScreen = makeComponent<ChangeValueDisplay<uint8_t>, StaticText<TEXT_FRONTPATTERN>, FrontPatternAccessor, SwitchScreenAction<BuzzerMenu>>;
|
||||
|
||||
struct BackFreqAccessor : public RefAccessor<uint8_t> { uint8_t &getRef() const override { return back.command.buzzer.freq; } };
|
||||
using BackFreqChangeScreen = makeComponent<ChangeValueDisplay<uint8_t>, StaticText<TEXT_BACKFREQ>, BackFreqAccessor, SwitchScreenAction<BuzzerMenu>>;
|
||||
|
||||
struct BackPatternAccessor : public RefAccessor<uint8_t> { uint8_t &getRef() const override { return back.command.buzzer.pattern; } };
|
||||
using BackPatternChangeScreen = makeComponent<ChangeValueDisplay<uint8_t>, StaticText<TEXT_BACKPATTERN>, BackPatternAccessor, SwitchScreenAction<BuzzerMenu>>;
|
||||
|
||||
using ReverseBeepFreq0ChangeScreen = makeComponent<ChangeValueDisplay<uint8_t>, StaticText<TEXT_REVERSEBEEPFREQ0>, ReverseBeepFreq0Accessor, SwitchScreenAction<BuzzerMenu>>;
|
||||
using ReverseBeepFreq1ChangeScreen = makeComponent<ChangeValueDisplay<uint8_t>, StaticText<TEXT_REVERSEBEEPFREQ1>, ReverseBeepFreq1Accessor, SwitchScreenAction<BuzzerMenu>>;
|
||||
using ReverseBeepDuration0ChangeScreen = makeComponent<ChangeValueDisplay<int16_t>, StaticText<TEXT_REVERSEBEEPDURATION0>, ReverseBeepDuration0Accessor, SwitchScreenAction<BuzzerMenu>>;
|
||||
using ReverseBeepDuration1ChangeScreen = makeComponent<ChangeValueDisplay<int16_t>, StaticText<TEXT_REVERSEBEEPDURATION1>, ReverseBeepDuration1Accessor, SwitchScreenAction<BuzzerMenu>>;
|
||||
|
||||
class BuzzerMenu :
|
||||
public MenuDisplay,
|
||||
public StaticText<TEXT_BUZZER>,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, StaticText<TEXT_FRONTFREQ>, SwitchScreenAction<FrontFreqChangeScreen>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_FRONTPATTERN>, SwitchScreenAction<FrontPatternChangeScreen>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACKFREQ>, SwitchScreenAction<BackFreqChangeScreen>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACKPATTERN>, SwitchScreenAction<BackPatternChangeScreen>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_REVERSEBEEP>, ToggleBoolAction, CheckboxIcon, ReverseBeepAccessor>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_REVERSEBEEPFREQ0>, SwitchScreenAction<ReverseBeepFreq0ChangeScreen>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_REVERSEBEEPFREQ1>, SwitchScreenAction<ReverseBeepFreq1ChangeScreen>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_REVERSEBEEPDURATION0>, SwitchScreenAction<ReverseBeepDuration0ChangeScreen>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_REVERSEBEEPDURATION1>, SwitchScreenAction<ReverseBeepDuration1ChangeScreen>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&icons::back>>
|
||||
>
|
||||
{};
|
||||
}
|
33
src/displays/menus/commanddebugmenu.h
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "utils.h"
|
||||
#include "menuitem.h"
|
||||
#include "actions/dummyaction.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
#include "debugtexthelpers.h"
|
||||
|
||||
namespace {
|
||||
class DebugMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
template<const char *Ttext, typename Ttexts>
|
||||
class CommandDebugMenu :
|
||||
public MenuDisplay,
|
||||
public StaticText<Ttext>,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, typename Ttexts::BuzzerFreqText, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, typename Ttexts::BuzzerPatternText, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, typename Ttexts::PoweroffText, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, typename Ttexts::LedText, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<DebugMenu>, StaticMenuItemIcon<&icons::back>>
|
||||
>
|
||||
{};
|
||||
|
||||
class FrontCommandDebugMenu : public CommandDebugMenu<TEXT_FRONTCOMMAND, FrontTexts> {};
|
||||
class BackCommandDebugMenu : public CommandDebugMenu<TEXT_BACKCOMMAND, BackTexts> {};
|
||||
}
|
63
src/displays/menus/debugmenu.h
Normal file
@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "utils.h"
|
||||
#include "menuitem.h"
|
||||
#include "actions/loadsettingsaction.h"
|
||||
#include "actions/savesettingsaction.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "actions/dummyaction.h"
|
||||
#include "actions/toggleboolaction.h"
|
||||
#include "icons/lock.h"
|
||||
#include "checkboxicon.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
#include "debugcolorhelpers.h"
|
||||
|
||||
namespace {
|
||||
class MainMenu;
|
||||
class FrontCommandDebugMenu;
|
||||
class BackCommandDebugMenu;
|
||||
class FrontLeftMotorStateDebugMenu;
|
||||
class FrontRightMotorStateDebugMenu;
|
||||
class BackLeftMotorStateDebugMenu;
|
||||
class BackRightMotorStateDebugMenu;
|
||||
class FrontFeedbackDebugMenu;
|
||||
class BackFeedbackDebugMenu;
|
||||
class FrontLeftMotorFeedbackDebugMenu;
|
||||
class FrontRightMotorFeedbackDebugMenu;
|
||||
class BackLeftMotorFeedbackDebugMenu;
|
||||
class BackRightMotorFeedbackDebugMenu;
|
||||
class DynamicDebugMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
class DebugMenu :
|
||||
public MenuDisplay,
|
||||
public StaticText<TEXT_DEBUG>,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, StaticText<TEXT_LOADSETTINGS>, LoadSettingsAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SAVESETTINGS>, SaveSettingsAction>,
|
||||
makeComponent<MenuItem, StaticText<nullptr>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_FRONTCOMMAND>, SwitchScreenAction<FrontCommandDebugMenu>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACKCOMMAND>, SwitchScreenAction<BackCommandDebugMenu>>,
|
||||
makeComponent<MenuItem, StaticText<nullptr>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_FRONTLEFTCOMMAND>, SwitchScreenAction<FrontLeftMotorStateDebugMenu>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_FRONTRIGHTCOMMAND>, SwitchScreenAction<FrontRightMotorStateDebugMenu>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACKLEFTCOMMAND>, SwitchScreenAction<BackLeftMotorStateDebugMenu>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACKRIGHTCOMMAND>, SwitchScreenAction<BackRightMotorStateDebugMenu>>,
|
||||
makeComponent<MenuItem, StaticText<nullptr>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_FRONTFEEDBACK>, SwitchScreenAction<FrontFeedbackDebugMenu>, FrontFeedbackColor<TFT_WHITE>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACKFEEDBACK>, SwitchScreenAction<BackFeedbackDebugMenu>, BackFeedbackColor<TFT_WHITE>>,
|
||||
makeComponent<MenuItem, StaticText<nullptr>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_FRONTLEFTFEEDBACK>, SwitchScreenAction<FrontLeftMotorFeedbackDebugMenu>, FrontFeedbackColor<TFT_WHITE>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_FRONTRIGHTFEEDBACK>, SwitchScreenAction<FrontRightMotorFeedbackDebugMenu>, FrontFeedbackColor<TFT_WHITE>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACKLEFTFEEDBACK>, SwitchScreenAction<BackLeftMotorFeedbackDebugMenu>, BackFeedbackColor<TFT_WHITE>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACKRIGHTFEEDBACK>, SwitchScreenAction<BackRightMotorFeedbackDebugMenu>, BackFeedbackColor<TFT_WHITE>>,
|
||||
makeComponent<MenuItem, StaticText<nullptr>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DYNAMICMENU>, SwitchScreenAction<DynamicDebugMenu>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&icons::back>>
|
||||
>
|
||||
{};
|
||||
}
|
50
src/displays/menus/defaultmodesettingsmenu.h
Normal file
@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "utils.h"
|
||||
#include "changevaluedisplay.h"
|
||||
#include "menuitem.h"
|
||||
#include "actions/toggleboolaction.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "checkboxicon.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
#include "settingsaccessors.h"
|
||||
|
||||
namespace {
|
||||
class DefaultModeSettingsMenu;
|
||||
class ModesSettingsMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
using DefaultModeCtrlTypChangeDisplay = makeComponent<ChangeValueDisplay<ControlType>, StaticText<TEXT_SETCONTROLTYPE>, DefaultModeCtrlTypAccessor, SwitchScreenAction<DefaultModeSettingsMenu>>;
|
||||
using DefaultModeCtrlModChangeDisplay = makeComponent<ChangeValueDisplay<ControlMode>, StaticText<TEXT_SETCONTROLMODE>, DefaultModeCtrlModAccessor, SwitchScreenAction<DefaultModeSettingsMenu>>;
|
||||
using DefaultModeSmoothingChangeDisplay = makeComponent<ChangeValueDisplay<int16_t>, StaticText<TEXT_SETSMOOTHING>, DefaultModeSmoothingAccessor, SwitchScreenAction<DefaultModeSettingsMenu>>;
|
||||
using DefaultModeFrontPercentageChangeDisplay = makeComponent<ChangeValueDisplay<int16_t>, StaticText<TEXT_SETFRONTPERCENTAGE>, DefaultModeFrontPercentageAccessor, SwitchScreenAction<DefaultModeSettingsMenu>>;
|
||||
using DefaultModeBackPercentageChangeDisplay = makeComponent<ChangeValueDisplay<int16_t>, StaticText<TEXT_SETBACKPERCENTAGE>, DefaultModeBackPercentageAccessor, SwitchScreenAction<DefaultModeSettingsMenu>>;
|
||||
using DefaultModeAddSchwelleChangeDisplay = makeComponent<ChangeValueDisplay<int16_t>, StaticText<TEXT_SETADDSCHWELLE>, DefaultModeAddSchwelleAccessor, SwitchScreenAction<DefaultModeSettingsMenu>>;
|
||||
using DefaultModeGas1WertChangeDisplay = makeComponent<ChangeValueDisplay<int16_t>, StaticText<TEXT_SETGAS1WERT>, DefaultModeGas1WertAccessor, SwitchScreenAction<DefaultModeSettingsMenu>>;
|
||||
using DefaultModeGas2WertChangeDisplay = makeComponent<ChangeValueDisplay<int16_t>, StaticText<TEXT_SETGAS2WERT>, DefaultModeGas2WertAccessor, SwitchScreenAction<DefaultModeSettingsMenu>>;
|
||||
using DefaultModeBrems1WertChangeDisplay = makeComponent<ChangeValueDisplay<int16_t>, StaticText<TEXT_SETBREMS1WERT>, DefaultModeBrems1WertAccessor, SwitchScreenAction<DefaultModeSettingsMenu>>;
|
||||
using DefaultModeBrems2WertChangeDisplay = makeComponent<ChangeValueDisplay<int16_t>, StaticText<TEXT_SETBREMS2WERT>, DefaultModeBrems2WertAccessor, SwitchScreenAction<DefaultModeSettingsMenu>>;
|
||||
|
||||
class DefaultModeSettingsMenu :
|
||||
public MenuDisplay,
|
||||
public StaticText<TEXT_DEFAULTMODESETTIGNS>,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, StaticText<TEXT_SETCONTROLTYPE>, SwitchScreenAction<DefaultModeCtrlTypChangeDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SETCONTROLMODE>, SwitchScreenAction<DefaultModeCtrlModChangeDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_ENABLESMOOTHING>, ToggleBoolAction, CheckboxIcon, DefaultModeEnableSmoothingAccessor>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SETSMOOTHING>, SwitchScreenAction<DefaultModeSmoothingChangeDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SETFRONTPERCENTAGE>, SwitchScreenAction<DefaultModeFrontPercentageChangeDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SETBACKPERCENTAGE>, SwitchScreenAction<DefaultModeBackPercentageChangeDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SETADDSCHWELLE>, SwitchScreenAction<DefaultModeAddSchwelleChangeDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SETGAS1WERT>, SwitchScreenAction<DefaultModeGas1WertChangeDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SETGAS2WERT>, SwitchScreenAction<DefaultModeGas2WertChangeDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SETBREMS1WERT>, SwitchScreenAction<DefaultModeBrems1WertChangeDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SETBREMS2WERT>, SwitchScreenAction<DefaultModeBrems2WertChangeDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<ModesSettingsMenu>, StaticMenuItemIcon<&icons::back>>
|
||||
>
|
||||
{};
|
||||
}
|
33
src/displays/menus/demosmenu.h
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "utils.h"
|
||||
#include "menuitem.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
|
||||
namespace {
|
||||
class StarfieldDisplay;
|
||||
class PingPongDisplay;
|
||||
class SpiroDisplay;
|
||||
class GameOfLifeDisplay;
|
||||
class MatrixDisplay;
|
||||
class MainMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
class DemosMenu :
|
||||
public MenuDisplay,
|
||||
public StaticText<TEXT_DEMOS>,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, StaticText<TEXT_STARFIELD>, SwitchScreenAction<StarfieldDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_PINGPONG>, SwitchScreenAction<PingPongDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SPIRO>, SwitchScreenAction<SpiroDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_GAMEOFLIFE>, SwitchScreenAction<GameOfLifeDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_MATRIX>, SwitchScreenAction<MatrixDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&icons::back>>
|
||||
>
|
||||
{};
|
||||
}
|
153
src/displays/menus/dynamicdebugmenu.h
Normal file
@ -0,0 +1,153 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <WString.h>
|
||||
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "utils.h"
|
||||
#include "menuitem.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "actions/dummyaction.h"
|
||||
#include "actions/toggleboolaction.h"
|
||||
#include "icons/lock.h"
|
||||
#include "checkboxicon.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
|
||||
namespace {
|
||||
class DebugMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
class RandomText : public virtual TextInterface
|
||||
{
|
||||
public:
|
||||
String text() const override
|
||||
{
|
||||
const auto now = millis();
|
||||
if (!m_nextUpdate || now >= m_nextUpdate)
|
||||
{
|
||||
m_title = String{"Dynamic text: "} + random(0, 100);
|
||||
m_nextUpdate = now + random(0, 1000);
|
||||
}
|
||||
|
||||
return m_title;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable unsigned long m_nextUpdate{};
|
||||
mutable String m_title;
|
||||
};
|
||||
|
||||
class RandomColor : public virtual ColorInterface
|
||||
{
|
||||
public:
|
||||
int color() const override
|
||||
{
|
||||
const auto now = millis();
|
||||
if (!m_nextUpdate || now >= m_nextUpdate)
|
||||
{
|
||||
const auto count = std::distance(std::begin(default_4bit_palette), std::end(default_4bit_palette));
|
||||
m_color = default_4bit_palette[random(0, count)];
|
||||
m_nextUpdate = now + random(0, 1000);
|
||||
}
|
||||
|
||||
return m_color;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable unsigned long m_nextUpdate{};
|
||||
mutable int m_color;
|
||||
};
|
||||
|
||||
class RandomFont : public virtual FontInterface
|
||||
{
|
||||
public:
|
||||
int font() const override
|
||||
{
|
||||
const auto now = millis();
|
||||
if (!m_nextUpdate || now >= m_nextUpdate)
|
||||
{
|
||||
m_font = random(1, 5);
|
||||
m_nextUpdate = now + random(0, 1000);
|
||||
}
|
||||
|
||||
return m_font;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable unsigned long m_nextUpdate{};
|
||||
mutable int m_font;
|
||||
};
|
||||
|
||||
class RandomIcon : public virtual MenuItemIconInterface
|
||||
{
|
||||
public:
|
||||
const MenuItemIcon *icon() const override
|
||||
{
|
||||
const auto now = millis();
|
||||
if (!m_nextUpdate || now >= m_nextUpdate)
|
||||
{
|
||||
if (m_icon)
|
||||
m_icon = nullptr;
|
||||
else
|
||||
m_icon = &icons::lock;
|
||||
m_nextUpdate = now + random(0, 1000);
|
||||
}
|
||||
|
||||
return m_icon;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable unsigned long m_nextUpdate{};
|
||||
mutable const Icon<24, 24> *m_icon;
|
||||
};
|
||||
|
||||
bool toggle;
|
||||
struct ToggleAccessor : public virtual RefAccessor<bool>
|
||||
{
|
||||
public:
|
||||
bool &getRef() const override { return toggle; }
|
||||
};
|
||||
|
||||
constexpr char TEXT_DUMMYITEM[] = "Dummy item";
|
||||
constexpr char TEXT_DYNAMICCOLOR[] = "Dynamic color";
|
||||
constexpr char TEXT_DYNAMICFONT[] = "Dynamic font";
|
||||
constexpr char TEXT_DYNAMICICON[] = "Dynamic icon";
|
||||
constexpr char TEXT_STATICICON[] = "Static icon";
|
||||
constexpr char TEXT_DEBUGTOGGLE[] = "Toggle";
|
||||
|
||||
class DynamicDebugMenu :
|
||||
public MenuDisplay,
|
||||
public RandomText,
|
||||
public StaticMenuDefinition<
|
||||
// dummy items to allow for scrolling
|
||||
makeComponent<MenuItem, StaticText<TEXT_DUMMYITEM>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DUMMYITEM>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DUMMYITEM>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DUMMYITEM>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DUMMYITEM>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DUMMYITEM>, DummyAction>,
|
||||
|
||||
// the interesting bits
|
||||
makeComponent<MenuItem, RandomText, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DYNAMICCOLOR>, RandomColor, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DYNAMICFONT>, RandomFont, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DYNAMICICON>, RandomIcon, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_STATICICON>, StaticMenuItemIcon<&icons::lock>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DEBUGTOGGLE>, ToggleBoolAction, CheckboxIcon, ToggleAccessor>,
|
||||
makeComponent<MenuItem, RandomText, RandomColor, RandomFont, RandomIcon, DummyAction>,
|
||||
|
||||
// more scrolling
|
||||
makeComponent<MenuItem, StaticText<TEXT_DUMMYITEM>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DUMMYITEM>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DUMMYITEM>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DUMMYITEM>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DUMMYITEM>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DUMMYITEM>, DummyAction>,
|
||||
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<DebugMenu>, StaticMenuItemIcon<&icons::back>>
|
||||
>
|
||||
{};
|
||||
}
|
30
src/displays/menus/enablemenu.h
Normal file
@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "utils.h"
|
||||
#include "menuitem.h"
|
||||
#include "actions/toggleboolaction.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "checkboxicon.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
#include "settingsaccessors.h"
|
||||
|
||||
namespace {
|
||||
class HardwareSettingsMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
class EnableMenu :
|
||||
public MenuDisplay,
|
||||
public StaticText<TEXT_SETENABLED>,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, StaticText<TEXT_ENABLEFRONTLEFT>, ToggleBoolAction, CheckboxIcon, FrontLeftEnabledAccessor>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_ENABLEFRONTRIGHT>, ToggleBoolAction, CheckboxIcon, FrontRightEnabledAccessor>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_ENABLEBACKLEFT>, ToggleBoolAction, CheckboxIcon, BackLeftEnabledAccessor>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_ENABLEBACKRIGHT>, ToggleBoolAction, CheckboxIcon, BackRightEnabledAccessor>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<HardwareSettingsMenu>, StaticMenuItemIcon<&icons::back>>
|
||||
>
|
||||
{};
|
||||
}
|
34
src/displays/menus/feedbackdebugmenu.h
Normal file
@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "utils.h"
|
||||
#include "menuitem.h"
|
||||
#include "actions/dummyaction.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
#include "debugtexthelpers.h"
|
||||
#include "debugcolorhelpers.h"
|
||||
|
||||
namespace {
|
||||
class DebugMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
template<const char *Ttext, typename Ttexts, template<int> class ColorInterface>
|
||||
class FeedbackDebugMenu :
|
||||
public MenuDisplay,
|
||||
public StaticText<Ttext>,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, typename Ttexts::BatVoltageText, ColorInterface<TFT_DARKGREY>, DummyAction>,
|
||||
makeComponent<MenuItem, typename Ttexts::BatVoltageFixedText, ColorInterface<TFT_DARKGREY>, DummyAction>,
|
||||
makeComponent<MenuItem, typename Ttexts::BoardTempText, ColorInterface<TFT_DARKGREY>, DummyAction>,
|
||||
makeComponent<MenuItem, typename Ttexts::BoardTempFixedText, ColorInterface<TFT_DARKGREY>, DummyAction>,
|
||||
makeComponent<MenuItem, typename Ttexts::TimeoutCntSerialText, StaticFont<2>, ColorInterface<TFT_DARKGREY>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<DebugMenu>, StaticMenuItemIcon<&icons::back>>
|
||||
>
|
||||
{};
|
||||
|
||||
class FrontFeedbackDebugMenu : public FeedbackDebugMenu<TEXT_FRONTFEEDBACK, FrontTexts, FrontFeedbackColor> {};
|
||||
class BackFeedbackDebugMenu : public FeedbackDebugMenu<TEXT_BACKFEEDBACK, BackTexts, FrontFeedbackColor> {}; }
|
79
src/displays/menus/genericwifisettingsmenu.h
Normal file
@ -0,0 +1,79 @@
|
||||
#pragma once
|
||||
|
||||
#include <HardwareSerial.h>
|
||||
#include <WiFi.h>
|
||||
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "changevaluedisplay.h"
|
||||
#include "menuitem.h"
|
||||
#include "actions/dummyaction.h"
|
||||
#include "actions/toggleboolaction.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "checkboxicon.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
|
||||
namespace {
|
||||
class GenericWifiSettingsMenu;
|
||||
class WifiSettingsMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct WifiStatusBitsText : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"statusBits: "} + WiFi.getStatusBits(); }
|
||||
};
|
||||
struct WifiChannelText : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"channel: "} + WiFi.channel(); }
|
||||
};
|
||||
|
||||
struct WifiModeAccessor : public virtual AccessorInterface<wifi_mode_t>
|
||||
{
|
||||
wifi_mode_t getValue() const override { return WiFi.getMode(); }
|
||||
void setValue(wifi_mode_t value) override
|
||||
{
|
||||
if (!WiFi.mode(value))
|
||||
Serial.println("Could not change WiFi mode!");
|
||||
// TODO: better error handling
|
||||
}
|
||||
};
|
||||
using WifiModeChangeScreen = makeComponent<ChangeValueDisplay<wifi_mode_t>, StaticText<TEXT_WIFICHANGEMODE>, WifiModeAccessor, SwitchScreenAction<GenericWifiSettingsMenu>>;
|
||||
|
||||
struct WifiSleepAccessor : public virtual AccessorInterface<bool>
|
||||
{
|
||||
bool getValue() const override { return WiFi.getSleep(); }
|
||||
void setValue(bool value) override
|
||||
{
|
||||
if (!WiFi.setSleep(value))
|
||||
Serial.println("Could not set WiFi sleep!");
|
||||
// TODO: better error handling
|
||||
}
|
||||
};
|
||||
|
||||
struct WifiTxPowerAccessor : public virtual AccessorInterface<wifi_power_t>
|
||||
{
|
||||
wifi_power_t getValue() const override { return WiFi.getTxPower(); }
|
||||
void setValue(wifi_power_t value) override
|
||||
{
|
||||
if (!WiFi.setTxPower(value))
|
||||
Serial.println("Could not set WiFi tx power!");
|
||||
// TODO: better error handling
|
||||
}
|
||||
};
|
||||
using WifiTxPowerChangeScreen = makeComponent<ChangeValueDisplay<wifi_power_t>, StaticText<TEXT_WIFICHANGETXPOWER>, WifiTxPowerAccessor, SwitchScreenAction<GenericWifiSettingsMenu>>;
|
||||
|
||||
class GenericWifiSettingsMenu :
|
||||
public MenuDisplay,
|
||||
public StaticText<TEXT_GENERICWIFISETTINGS>,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, WifiStatusBitsText, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, WifiChannelText, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_WIFICHANGEMODE>, SwitchScreenAction<WifiModeChangeScreen>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_WIFICHANGESLEEP>, ToggleBoolAction, CheckboxIcon, WifiSleepAccessor>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_WIFICHANGETXPOWER>, SwitchScreenAction<WifiTxPowerChangeScreen>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<WifiSettingsMenu>, StaticMenuItemIcon<&icons::back>>
|
||||
>
|
||||
{};
|
||||
}
|
69
src/displays/menus/graphsmenu.h
Normal file
@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "utils.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
#include "displays/graphdisplay.h"
|
||||
#include "statistics.h"
|
||||
|
||||
namespace {
|
||||
class MainMenu;
|
||||
class DualGraphDisplay;
|
||||
}
|
||||
|
||||
namespace {
|
||||
using GasGraphDisplay = makeComponent<GraphDisplay<1>, StaticText<TEXT_GAS>, MultiStatisticsSingleImpl, GasStatistics>;
|
||||
using BremsGraphDisplay = makeComponent<GraphDisplay<1>, StaticText<TEXT_BREMS>, MultiStatisticsSingleImpl, BremsStatistics>;
|
||||
using AvgSpeedGraphDisplay = makeComponent<GraphDisplay<1>, StaticText<TEXT_AVGSPEED>, MultiStatisticsSingleImpl, AvgSpeedStatistics>;
|
||||
using AvgSpeedKmhGraphDisplay = makeComponent<GraphDisplay<1>, StaticText<TEXT_AVGSPEEDKMH>, MultiStatisticsSingleImpl, AvgSpeedKmhStatistics>;
|
||||
using SumCurrentGraphDisplay = makeComponent<GraphDisplay<1>, StaticText<TEXT_SUMCURRENT>, MultiStatisticsSingleImpl, SumCurrentStatistics>;
|
||||
using SumAbsoluteCurrentGraphDisplay = makeComponent<GraphDisplay<1>, StaticText<TEXT_SUMABSOLUTECURRENT>, MultiStatisticsSingleImpl, SumAbsoluteCurrentStatistics>;
|
||||
using FrontVoltageGraphDisplay = makeComponent<GraphDisplay<1>, StaticText<TEXT_FRONTVOLTAGE>, MultiStatisticsSingleImpl, FrontVoltageStatistics>;
|
||||
using BackVoltageGraphDisplay = makeComponent<GraphDisplay<1>, StaticText<TEXT_BACKVOLTAGE>, MultiStatisticsSingleImpl, BackVoltageStatistics>;
|
||||
using BmsVoltageGraphDisplay = makeComponent<GraphDisplay<1>, StaticText<TEXT_BMSVOLTAGE>, MultiStatisticsSingleImpl, BmsVoltageStatistics>;
|
||||
using BmsCurrentGraphDisplay = makeComponent<GraphDisplay<1>, StaticText<TEXT_BMSCURRENT>, MultiStatisticsSingleImpl, BmsCurrentStatistics>;
|
||||
using BmsPowerGraphDisplay = makeComponent<GraphDisplay<1>, StaticText<TEXT_BMSPOWER>, MultiStatisticsSingleImpl, BmsPowerStatistics>;
|
||||
|
||||
class SumCurrentsComparisonStatistics : public virtual MultiStatisticsInterface<2>
|
||||
{
|
||||
std::array<std::reference_wrapper<const statistics::ContainerType>, 2> getBuffers() const override
|
||||
{
|
||||
return {SumCurrentStatistics{}.getBuffer(), BmsCurrentStatistics{}.getBuffer()};
|
||||
}
|
||||
};
|
||||
using SumCurrentsComparisonGraphDisplay = makeComponent<GraphDisplay<2>, StaticText<TEXT_SUMCURRENTSCOMPARISON>, SumCurrentsComparisonStatistics>;
|
||||
|
||||
class MotorCurrentsStatistics : public virtual MultiStatisticsInterface<4>
|
||||
{
|
||||
std::array<std::reference_wrapper<const statistics::ContainerType>, 4> getBuffers() const override
|
||||
{
|
||||
return {FrontLeftCurrentStatistics{}.getBuffer(), FrontRightCurrentStatistics{}.getBuffer(), BackLeftCurrentStatistics{}.getBuffer(), BackRightCurrentStatistics{}.getBuffer()};
|
||||
}
|
||||
};
|
||||
using MotorCurrentsGraphDisplay = makeComponent<GraphDisplay<4>, StaticText<TEXT_MOTORCURRENTS>, MotorCurrentsStatistics>;
|
||||
|
||||
class GraphsMenu :
|
||||
public MenuDisplay,
|
||||
public StaticText<TEXT_GRAPHS>,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, StaticText<TEXT_GAS>, SwitchScreenAction<GasGraphDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BREMS>, SwitchScreenAction<BremsGraphDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_AVGSPEED>, SwitchScreenAction<AvgSpeedGraphDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_AVGSPEEDKMH>, SwitchScreenAction<AvgSpeedKmhGraphDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SUMCURRENT>, SwitchScreenAction<SumCurrentGraphDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SUMABSOLUTECURRENT>, SwitchScreenAction<SumAbsoluteCurrentGraphDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_FRONTVOLTAGE>, SwitchScreenAction<FrontVoltageGraphDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACKVOLTAGE>, SwitchScreenAction<BackVoltageGraphDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BMSVOLTAGE>, SwitchScreenAction<BmsVoltageGraphDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BMSCURRENT>, SwitchScreenAction<BmsCurrentGraphDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BMSPOWER>, SwitchScreenAction<BmsPowerGraphDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SUMCURRENTSCOMPARISON>, SwitchScreenAction<SumCurrentsComparisonGraphDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_MOTORCURRENTS>, SwitchScreenAction<MotorCurrentsGraphDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DUALGRAPHS>, SwitchScreenAction<DualGraphDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&icons::back>>
|
||||
>
|
||||
{};
|
||||
}
|
44
src/displays/menus/hardwaresettingsmenu.h
Normal file
@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
#include <ratio>
|
||||
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "utils.h"
|
||||
#include "changevaluedisplay.h"
|
||||
#include "actions/toggleboolaction.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "checkboxicon.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
#include "globals.h"
|
||||
#include "settingsaccessors.h"
|
||||
|
||||
namespace {
|
||||
class HardwareSettingsMenu;
|
||||
class PotiSettingsMenu;
|
||||
class EnableMenu;
|
||||
class InvertMenu;
|
||||
class SettingsMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
using WheelDiameterMmChangeScreen = makeComponent<ChangeValueDisplay<int16_t>, StaticText<TEXT_WHEELDIAMETERMM>, WheelDiameterMmAccessor, SwitchScreenAction<HardwareSettingsMenu>>;
|
||||
using WheelDiameterInchChangeScreen = makeComponent<ChangeValueDisplay<float>, StaticText<TEXT_WHEELDIAMETERINCH>, WheelDiameterInchAccessor, RatioNumberStep<float, std::ratio<1,10>>, SwitchScreenAction<HardwareSettingsMenu>>;
|
||||
using NumMagnetPolesChangeScreen = makeComponent<ChangeValueDisplay<int16_t>, StaticText<TEXT_NUMMAGNETPOLES>, NumMagnetPolesAccessor, SwitchScreenAction<HardwareSettingsMenu>>;
|
||||
|
||||
class HardwareSettingsMenu :
|
||||
public MenuDisplay,
|
||||
public StaticText<TEXT_HARDWARESETTINGS>,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, StaticText<TEXT_SETENABLED>, SwitchScreenAction<EnableMenu>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SETINVERTED>, SwitchScreenAction<InvertMenu>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_POTISETTINGS>, SwitchScreenAction<PotiSettingsMenu>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_WHEELDIAMETERMM>, SwitchScreenAction<WheelDiameterMmChangeScreen>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_WHEELDIAMETERINCH>, SwitchScreenAction<WheelDiameterInchChangeScreen>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_NUMMAGNETPOLES>, SwitchScreenAction<NumMagnetPolesChangeScreen>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SWAPFRONTBACK>, ToggleBoolAction, CheckboxIcon, SwapFrontBackAccessor>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&icons::back>>
|
||||
>
|
||||
{};
|
||||
}
|
30
src/displays/menus/invertmenu.h
Normal file
@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "utils.h"
|
||||
#include "menuitem.h"
|
||||
#include "actions/toggleboolaction.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "checkboxicon.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
#include "settingsaccessors.h"
|
||||
|
||||
namespace {
|
||||
class HardwareSettingsMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
class InvertMenu :
|
||||
public MenuDisplay,
|
||||
public StaticText<TEXT_SETINVERTED>,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, StaticText<TEXT_INVERTFRONTLEFT>, ToggleBoolAction, CheckboxIcon, FrontLeftInvertedAccessor>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_INVERTFRONTRIGHT>, ToggleBoolAction, CheckboxIcon, FrontRightInvertedAccessor>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_INVERTBACKLEFT>, ToggleBoolAction, CheckboxIcon, BackLeftInvertedAccessor>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_INVERTBACKRIGHT>, ToggleBoolAction, CheckboxIcon, BackRightInvertedAccessor>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<HardwareSettingsMenu>, StaticMenuItemIcon<&icons::back>>
|
||||
>
|
||||
{};
|
||||
}
|
31
src/displays/menus/larsmmodesettingsmenu.h
Normal file
@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "utils.h"
|
||||
#include "changevaluedisplay.h"
|
||||
#include "menuitem.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
#include "settingsaccessors.h"
|
||||
|
||||
namespace {
|
||||
class LarsmModeSettingsMenu;
|
||||
class ModesSettingsMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
using LarsmModeModeChangeDisplay = makeComponent<ChangeValueDisplay<LarsmModeMode>, StaticText<TEXT_LARSMMODECHANGEMODE>, LarsmModeModeAccessor, SwitchScreenAction<LarsmModeSettingsMenu>>;
|
||||
using LarsmModeIterationsChangeDisplay = makeComponent<ChangeValueDisplay<uint8_t>, StaticText<TEXT_LARSMMODECHANGEITERATIONS>, LarsmModeIterationsAccessor, SwitchScreenAction<LarsmModeSettingsMenu>>;
|
||||
|
||||
class LarsmModeSettingsMenu :
|
||||
public MenuDisplay,
|
||||
public StaticText<TEXT_LARSMMODESETTINGS>,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, StaticText<TEXT_LARSMMODECHANGEMODE>, SwitchScreenAction<LarsmModeModeChangeDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_LARSMMODECHANGEITERATIONS>, SwitchScreenAction<LarsmModeIterationsChangeDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<ModesSettingsMenu>, StaticMenuItemIcon<&icons::back>>
|
||||
>
|
||||
{};
|
||||
}
|
39
src/displays/menus/limitssettingsmenu.h
Normal file
@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "utils.h"
|
||||
#include "changevaluedisplay.h"
|
||||
#include "menuitem.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
#include "settingsaccessors.h"
|
||||
|
||||
namespace {
|
||||
class LimitsSettingsMenu;
|
||||
class SettingsMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
using IMotMaxChangeScreen = makeComponent<ChangeValueDisplay<int16_t>, StaticText<TEXT_SETIMOTMAX>, IMotMaxAccessor, SwitchScreenAction<LimitsSettingsMenu>>;
|
||||
using IDcMaxChangeScreen = makeComponent<ChangeValueDisplay<int16_t>, StaticText<TEXT_SETIDCMAX>, IDcMaxAccessor, SwitchScreenAction<LimitsSettingsMenu>>;
|
||||
using NMotMaxKmhChangeScreen = makeComponent<ChangeValueDisplay<int16_t>, StaticText<TEXT_SETNMOTMAXKMH>, NMotMaxKmhAccessor, SwitchScreenAction<LimitsSettingsMenu>>;
|
||||
using NMotMaxRpmChangeScreen = makeComponent<ChangeValueDisplay<int16_t>, StaticText<TEXT_SETNMOTMAX>, NMotMaxRpmAccessor, SwitchScreenAction<LimitsSettingsMenu>>;
|
||||
using FieldWeakMaxChangeScreen = makeComponent<ChangeValueDisplay<int16_t>, StaticText<TEXT_SETFIELDWEAKMAX>, FieldWeakMaxAccessor, SwitchScreenAction<LimitsSettingsMenu>>;
|
||||
using PhaseAdvMaxChangeScreen = makeComponent<ChangeValueDisplay<int16_t>, StaticText<TEXT_SETPHASEADVMAX>, PhaseAdvMaxAccessor, SwitchScreenAction<LimitsSettingsMenu>>;
|
||||
|
||||
class LimitsSettingsMenu :
|
||||
public MenuDisplay,
|
||||
public StaticText<TEXT_LIMITSSETTINGS>,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, StaticText<TEXT_SETIMOTMAX>, SwitchScreenAction<IMotMaxChangeScreen>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SETIDCMAX>, SwitchScreenAction<IDcMaxChangeScreen>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SETNMOTMAXKMH>, SwitchScreenAction<NMotMaxKmhChangeScreen>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SETNMOTMAX>, SwitchScreenAction<NMotMaxRpmChangeScreen>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SETFIELDWEAKMAX>, SwitchScreenAction<FieldWeakMaxChangeScreen>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SETPHASEADVMAX>, SwitchScreenAction<PhaseAdvMaxChangeScreen>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&icons::back>>
|
||||
>
|
||||
{};
|
||||
}
|
51
src/displays/menus/mainmenu.h
Normal file
@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "menuitem.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "actions/rebootaction.h"
|
||||
#include "texts.h"
|
||||
#include "icons/back.h"
|
||||
#include "icons/modes.h"
|
||||
#include "icons/presets.h"
|
||||
#include "icons/graph.h"
|
||||
#include "icons/bms.h"
|
||||
#include "icons/settings.h"
|
||||
#include "icons/lock.h"
|
||||
#include "icons/demos.h"
|
||||
#include "icons/poweroff.h"
|
||||
#include "icons/reboot.h"
|
||||
|
||||
namespace {
|
||||
class StatusDisplay;
|
||||
class SelectModeMenu;
|
||||
class PresetsMenu;
|
||||
class GraphsMenu;
|
||||
class BmsMenu;
|
||||
class SettingsMenu;
|
||||
class Lockscreen;
|
||||
class DemosMenu;
|
||||
class PoweroffDisplay;
|
||||
class DebugMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
class MainMenu :
|
||||
public MenuDisplay,
|
||||
public StaticText<TEXT_MAINMENU>,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, StaticText<TEXT_STATUS>, SwitchScreenAction<StatusDisplay>, StaticMenuItemIcon<&icons::back>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SELECTMODE>, SwitchScreenAction<SelectModeMenu>, StaticMenuItemIcon<&icons::modes>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_PRESETS>, SwitchScreenAction<PresetsMenu>, StaticMenuItemIcon<&icons::presets>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_GRAPHS>, SwitchScreenAction<GraphsMenu>, StaticMenuItemIcon<&icons::graph>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BMS>, SwitchScreenAction<BmsMenu>, StaticMenuItemIcon<&icons::bms>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SETTINGS>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&icons::settings>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_LOCKVEHICLE>, SwitchScreenAction<Lockscreen>, StaticMenuItemIcon<&icons::lock>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DEMOS>, SwitchScreenAction<DemosMenu>, StaticMenuItemIcon<&icons::demos>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_POWEROFF>, SwitchScreenAction<PoweroffDisplay>, StaticMenuItemIcon<&icons::poweroff>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_REBOOT>, RebootAction, StaticMenuItemIcon<&icons::reboot>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DEBUG>, SwitchScreenAction<DebugMenu>>
|
||||
>
|
||||
{};
|
||||
};
|
28
src/displays/menus/modessettingsmenu.h
Normal file
@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "menuitem.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
|
||||
namespace {
|
||||
class DefaultModeSettingsMenu;
|
||||
class TempomatModeSettingsMenu;
|
||||
class LarsmModeSettingsMenu;
|
||||
class SettingsMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
class ModesSettingsMenu :
|
||||
public MenuDisplay,
|
||||
public StaticText<TEXT_MODESSETTINGS>,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, StaticText<TEXT_DEFAULTMODESETTIGNS>, SwitchScreenAction<DefaultModeSettingsMenu>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_TEMPOMATMODESETTINGS>, SwitchScreenAction<TempomatModeSettingsMenu>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_LARSMMODESETTINGS>, SwitchScreenAction<LarsmModeSettingsMenu>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&icons::back>>
|
||||
>
|
||||
{};
|
||||
}
|
40
src/displays/menus/motorfeedbackdebugmenu.h
Normal file
@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "utils.h"
|
||||
#include "menuitem.h"
|
||||
#include "actions/dummyaction.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
#include "debugtexthelpers.h"
|
||||
#include "debugcolorhelpers.h"
|
||||
|
||||
namespace {
|
||||
class DebugMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
template<const char *Ttext, typename Ttexts, template<int> class ColorInterface>
|
||||
class MotorFeedbackDebugMenu :
|
||||
public MenuDisplay,
|
||||
public StaticText<Ttext>,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, typename Ttexts::AngleText, ColorInterface<TFT_DARKGREY>, DummyAction>,
|
||||
makeComponent<MenuItem, typename Ttexts::SpeedText, ColorInterface<TFT_DARKGREY>, DummyAction>,
|
||||
makeComponent<MenuItem, typename Ttexts::SpeedKmhText, ColorInterface<TFT_DARKGREY>, DummyAction>,
|
||||
makeComponent<MenuItem, typename Ttexts::ErrorText, ColorInterface<TFT_DARKGREY>, DummyAction>,
|
||||
makeComponent<MenuItem, typename Ttexts::CurrentText, ColorInterface<TFT_DARKGREY>, DummyAction>,
|
||||
makeComponent<MenuItem, typename Ttexts::CurrentFixedText, ColorInterface<TFT_DARKGREY>, DummyAction>,
|
||||
makeComponent<MenuItem, typename Ttexts::ChopsText, ColorInterface<TFT_DARKGREY>, DummyAction>,
|
||||
makeComponent<MenuItem, typename Ttexts::HallText, ColorInterface<TFT_DARKGREY>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<DebugMenu>, StaticMenuItemIcon<&icons::back>>
|
||||
>
|
||||
{};
|
||||
|
||||
class FrontLeftMotorFeedbackDebugMenu : public MotorFeedbackDebugMenu<TEXT_FRONTLEFTFEEDBACK, FrontTexts::LeftFeedback, FrontFeedbackColor> {};
|
||||
class FrontRightMotorFeedbackDebugMenu : public MotorFeedbackDebugMenu<TEXT_FRONTRIGHTFEEDBACK, FrontTexts::RightFeedback, FrontFeedbackColor> {};
|
||||
class BackLeftMotorFeedbackDebugMenu : public MotorFeedbackDebugMenu<TEXT_BACKLEFTFEEDBACK, BackTexts::LeftFeedback, BackFeedbackColor> {};
|
||||
class BackRightMotorFeedbackDebugMenu : public MotorFeedbackDebugMenu<TEXT_BACKRIGHTFEEDBACK, BackTexts::RightFeedback, BackFeedbackColor> {};
|
||||
}
|
40
src/displays/menus/motorstatedebugmenu.h
Normal file
@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "utils.h"
|
||||
#include "menuitem.h"
|
||||
#include "actions/dummyaction.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
#include "debugtexthelpers.h"
|
||||
|
||||
namespace {
|
||||
class DebugMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
template<const char *Ttext, typename Ttexts>
|
||||
class MotorStateDebugMenu :
|
||||
public MenuDisplay,
|
||||
public StaticText<Ttext>,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, typename Ttexts::EnableText, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, typename Ttexts::PwmText, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, typename Ttexts::CtrlTypText, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, typename Ttexts::CtrlModText, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, typename Ttexts::IMotMaxText, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, typename Ttexts::IDcMaxText, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, typename Ttexts::NMotMaxText, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, typename Ttexts::FieldWeakMaxText, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, typename Ttexts::PhaseAdvMaxText, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<DebugMenu>, StaticMenuItemIcon<&icons::back>>
|
||||
>
|
||||
{};
|
||||
|
||||
class FrontLeftMotorStateDebugMenu : public MotorStateDebugMenu<TEXT_FRONTLEFTCOMMAND, FrontTexts::LeftCommand> {};
|
||||
class FrontRightMotorStateDebugMenu : public MotorStateDebugMenu<TEXT_FRONTRIGHTCOMMAND, FrontTexts::RightCommand> {};
|
||||
class BackLeftMotorStateDebugMenu : public MotorStateDebugMenu<TEXT_BACKLEFTCOMMAND, BackTexts::LeftCommand> {};
|
||||
class BackRightMotorStateDebugMenu : public MotorStateDebugMenu<TEXT_BACKRIGHTCOMMAND, BackTexts::RightCommand> {};
|
||||
}
|
50
src/displays/menus/potisettingsmenu.h
Normal file
@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "utils.h"
|
||||
#include "changevaluedisplay.h"
|
||||
#include "actions/dummyaction.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
#include "settingsaccessors.h"
|
||||
|
||||
namespace {
|
||||
class PotiSettingsMenu;
|
||||
class CalibrateDisplay;
|
||||
class HardwareSettingsMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct GasText : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"gas: "} + raw_gas + ": " + gas; }
|
||||
};
|
||||
struct BremsText : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"brems: "} + raw_brems + ": " + brems; }
|
||||
};
|
||||
|
||||
using SampleCountChangeScreen = makeComponent<ChangeValueDisplay<int16_t>, StaticText<TEXT_SETSAMPLECOUNT>, SampleCountAccessor, SwitchScreenAction<PotiSettingsMenu>>;
|
||||
using GasMinChangeScreen = makeComponent<ChangeValueDisplay<int16_t>, StaticText<TEXT_SETGASMIN>, GasMinAccessor, SwitchScreenAction<PotiSettingsMenu>>;
|
||||
using GasMaxChangeScreen = makeComponent<ChangeValueDisplay<int16_t>, StaticText<TEXT_SETGASMAX>, GasMaxAccessor, SwitchScreenAction<PotiSettingsMenu>>;
|
||||
using BremsMinChangeScreen = makeComponent<ChangeValueDisplay<int16_t>, StaticText<TEXT_SETBREMSMIN>, BremsMinAccessor, SwitchScreenAction<PotiSettingsMenu>>;
|
||||
using BremsMaxChangeScreen = makeComponent<ChangeValueDisplay<int16_t>, StaticText<TEXT_SETBREMSMAX>, BremsMaxAccessor, SwitchScreenAction<PotiSettingsMenu>>;
|
||||
|
||||
class PotiSettingsMenu :
|
||||
public MenuDisplay,
|
||||
public StaticText<TEXT_POTISETTINGS>,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, GasText, DisabledColor, StaticFont<2>, DummyAction>,
|
||||
makeComponent<MenuItem, BremsText, DisabledColor, StaticFont<2>, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_CALIBRATE>, SwitchScreenAction<CalibrateDisplay>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SETSAMPLECOUNT>, SwitchScreenAction<SampleCountChangeScreen>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SETGASMIN>, SwitchScreenAction<GasMinChangeScreen>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SETGASMAX>, SwitchScreenAction<GasMaxChangeScreen>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SETBREMSMIN>, SwitchScreenAction<BremsMinChangeScreen>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SETBREMSMAX>, SwitchScreenAction<BremsMaxChangeScreen>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<HardwareSettingsMenu>, StaticMenuItemIcon<&icons::back>>
|
||||
>
|
||||
{};
|
||||
}
|
48
src/displays/menus/presetsmenu.h
Normal file
@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include "actioninterface.h"
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "utils.h"
|
||||
#include "actions/dummyaction.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
#include "settings.h"
|
||||
#include "presets.h"
|
||||
#include "globals.h"
|
||||
|
||||
namespace {
|
||||
class MainMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
template<const Settings *preset>
|
||||
class ApplyPresetAction : public virtual ActionInterface {public: void triggered() override { settings = *preset; saveSettings(); } };
|
||||
|
||||
template<const Settings::Limits *preset>
|
||||
class ApplyLimitsPresetAction : public virtual ActionInterface {public: void triggered() override { settings.limits = *preset; saveSettings(); } };
|
||||
|
||||
template<const Settings::Hardware::Poti *preset>
|
||||
class ApplyPotiPresetAction : public virtual ActionInterface {public: void triggered() override { settings.hardware.poti = *preset; saveSettings(); } };
|
||||
|
||||
template<const Settings::Hardware *preset>
|
||||
class ApplyHardwarePresetAction : public virtual ActionInterface {public: void triggered() override { settings.hardware = *preset; saveSettings(); } };
|
||||
|
||||
class PresetsMenu :
|
||||
public MenuDisplay,
|
||||
public StaticText<TEXT_PRESETS>,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, StaticText<TEXT_DEFAULTEVERYTHING>, ApplyPresetAction<&presets::defaultSettings>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DEFAULTLIMITS>, ApplyLimitsPresetAction<&presets::defaultLimits>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_KIDSLIMITS>, ApplyLimitsPresetAction<&presets::kidsLimits>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DEFAULTPOTI>, ApplyPotiPresetAction<&presets::defaultPoti>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_DEFAULTHARDWARE>, ApplyHardwarePresetAction<&presets::defaultHardware>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_STREET>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SIDEWALK>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_POLICE>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_RACE>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&icons::back>>
|
||||
>
|
||||
{};
|
||||
}
|
63
src/displays/menus/selectmodemenu.h
Normal file
@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "utils.h"
|
||||
#include "actions/multiaction.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
#include "globals.h"
|
||||
|
||||
#include "modes/defaultmode.h"
|
||||
#include "modes/tempomatmode.h"
|
||||
#include "modes/larsmmode.h"
|
||||
|
||||
namespace {
|
||||
class MainMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
template<typename T1, T1 &target, typename T2, T2 value>
|
||||
class SetterAction : public ActionInterface
|
||||
{
|
||||
public:
|
||||
void triggered() override { target = value; }
|
||||
};
|
||||
using SetDefaultModeAction = SetterAction<ModeInterface*, currentMode, DefaultMode*, &modes::defaultMode>;
|
||||
using SetTempomatModeAction = SetterAction<ModeInterface*, currentMode, TempomatMode*, &modes::tempomatMode>;
|
||||
using SetLarsmModeAction = SetterAction<ModeInterface*, currentMode, LarsmMode*, &modes::larsmMode>;
|
||||
|
||||
class SelectModeMenu :
|
||||
public MenuDisplay,
|
||||
public StaticText<TEXT_SELECTMODE>,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, StaticText<TEXT_DEFAULT>, MultiAction<SetDefaultModeAction, SwitchScreenAction<MainMenu>>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_TEMPOMAT>, MultiAction<SetTempomatModeAction, SwitchScreenAction<MainMenu>>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_LARSM>, MultiAction<SetLarsmModeAction, SwitchScreenAction<MainMenu>>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&icons::back>>
|
||||
>
|
||||
{
|
||||
using Base = MenuDisplay;
|
||||
|
||||
public:
|
||||
void start() override;
|
||||
};
|
||||
|
||||
void SelectModeMenu::start()
|
||||
{
|
||||
Base::start();
|
||||
|
||||
if (currentMode == &modes::defaultMode)
|
||||
setSelectedIndex(0);
|
||||
else if (currentMode == &modes::tempomatMode)
|
||||
setSelectedIndex(1);
|
||||
else if (currentMode == &modes::larsmMode)
|
||||
setSelectedIndex(2);
|
||||
else
|
||||
{
|
||||
Serial.printf("Unknown mode: %s", currentMode?currentMode->displayName():"");
|
||||
setSelectedIndex(3);
|
||||
}
|
||||
}
|
||||
}
|
53
src/displays/menus/settingsmenu.h
Normal file
@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#include <HardwareSerial.h>
|
||||
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "utils.h"
|
||||
#include "actions/toggleboolaction.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "checkboxicon.h"
|
||||
#include "icons/wifi.h"
|
||||
#include "icons/bluetooth.h"
|
||||
#include "icons/hardware.h"
|
||||
#include "icons/buzzer.h"
|
||||
#include "icons/info.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
#include "globals.h"
|
||||
#include "settingsaccessors.h"
|
||||
|
||||
namespace {
|
||||
class LimitsSettingsMenu;
|
||||
class WifiSettingsMenu;
|
||||
class BluetoothSettingsMenu;
|
||||
class ModesSettingsMenu;
|
||||
class HardwareSettingsMenu;
|
||||
class BuzzerMenu;
|
||||
class AboutMenu;
|
||||
class MainMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct FrontLedAccessor : public RefAccessor<bool> { bool &getRef() const override { return front.command.led; } };
|
||||
struct BackLedAccessor : public RefAccessor<bool> { bool &getRef() const override { return back.command.led; } };
|
||||
|
||||
class SettingsMenu :
|
||||
public MenuDisplay,
|
||||
public StaticText<TEXT_SETTINGS>,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, StaticText<TEXT_LIMITSSETTINGS>, SwitchScreenAction<LimitsSettingsMenu>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_WIFISETTINGS>, SwitchScreenAction<WifiSettingsMenu>, StaticMenuItemIcon<&icons::wifi>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BLUETOOTHSETTINGS>, SwitchScreenAction<BluetoothSettingsMenu>, StaticMenuItemIcon<&icons::bluetooth>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_MODESSETTINGS>, SwitchScreenAction<ModesSettingsMenu>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_HARDWARESETTINGS>, SwitchScreenAction<HardwareSettingsMenu>, StaticMenuItemIcon<&icons::hardware>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_AUTOCONNECTBMS>, ToggleBoolAction, CheckboxIcon, AutoConnectBmsAccessor>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BUZZER>, SwitchScreenAction<BuzzerMenu>, StaticMenuItemIcon<&icons::buzzer>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_FRONTLED>, ToggleBoolAction, CheckboxIcon, FrontLedAccessor>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACKLED>, ToggleBoolAction, CheckboxIcon, BackLedAccessor>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_ABOUT>, SwitchScreenAction<AboutMenu>, StaticMenuItemIcon<&icons::info>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&icons::back>>
|
||||
>
|
||||
{};
|
||||
}
|
140
src/displays/menus/stationwifisettingsmenu.h
Normal file
@ -0,0 +1,140 @@
|
||||
#pragma once
|
||||
|
||||
#include <WiFi.h>
|
||||
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "utils.h"
|
||||
#include "menuitem.h"
|
||||
#include "actions/dummyaction.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "actions/wifireconnectaction.h"
|
||||
#include "actions/wifidisconnectaction.h"
|
||||
#include "actions/toggleboolaction.h"
|
||||
#include "actions/wifienableipv6action.h"
|
||||
#include "checkboxicon.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
|
||||
namespace {
|
||||
class WifiSettingsMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct WifiIsConnectedText : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"isConnected: "} + (WiFi.isConnected() ? "true" : "false"); }
|
||||
};
|
||||
|
||||
struct WifiAutoConnectAccessor : public virtual AccessorInterface<bool>
|
||||
{
|
||||
bool getValue() const override { return WiFi.getAutoConnect(); }
|
||||
void setValue(bool value) override
|
||||
{
|
||||
if (!WiFi.setAutoConnect(value))
|
||||
Serial.println("Could not set WiFi autoConnect!");
|
||||
// TODO: better error handling
|
||||
}
|
||||
};
|
||||
|
||||
struct WifiAutoReconnectAccessor : public virtual AccessorInterface<bool>
|
||||
{
|
||||
bool getValue() const override { return WiFi.getAutoReconnect(); }
|
||||
void setValue(bool value) override
|
||||
{
|
||||
if (!WiFi.setAutoReconnect(value))
|
||||
Serial.println("Could not set WiFi autoReconnect!");
|
||||
// TODO: better error handling
|
||||
}
|
||||
};
|
||||
|
||||
struct WifiLocalIpText : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"localIP: "} + WiFi.localIP().toString(); }
|
||||
};
|
||||
struct WifiMacAddressText : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"macAddress: "} + WiFi.macAddress(); }
|
||||
};
|
||||
struct WifiSubnetMaskText : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"subnetMask: "} + WiFi.subnetMask().toString(); }
|
||||
};
|
||||
struct WifiGatewayIpText : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"gatewayIP: "} + WiFi.gatewayIP().toString(); }
|
||||
};
|
||||
struct WifiDnsIpText : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"dnsIP: "} + WiFi.dnsIP().toString(); }
|
||||
};
|
||||
struct WifiBroadcastIpText : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"broadcastIP: "} + WiFi.broadcastIP().toString(); }
|
||||
};
|
||||
struct WifiNetworkIdText : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"networkID: "} + WiFi.networkID().toString(); }
|
||||
};
|
||||
struct WifiSubnetCIDRText : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"subnetCIDR: "} + WiFi.subnetCIDR(); }
|
||||
};
|
||||
struct WifiLocalIpV6Text : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"localIPv6: "} + WiFi.localIPv6().toString(); }
|
||||
};
|
||||
struct WifiHostnameText : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"hostname: "} + WiFi.getHostname(); }
|
||||
};
|
||||
struct WifiStatusText : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"status: "} + toString(WiFi.status()); }
|
||||
};
|
||||
struct WifiSsidText : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"SSID: "} + WiFi.SSID(); }
|
||||
};
|
||||
struct WifiPskText : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"psk: "} + WiFi.psk(); }
|
||||
};
|
||||
struct WifiBssidText : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"BSSID: "} + WiFi.BSSIDstr(); }
|
||||
};
|
||||
struct WifiRssiText : public virtual TextInterface {
|
||||
public:
|
||||
String text() const override { return String{"RSSI: "} + WiFi.RSSI(); }
|
||||
};
|
||||
|
||||
class StationWifiSettingsMenu :
|
||||
public MenuDisplay,
|
||||
public StaticText<TEXT_STATIONWIFISETTINGS>,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, StaticText<TEXT_WIFIRECONNECT>, WifiReconnectAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_WIFIDISCONNECT>, WifiDisconnectAction>,
|
||||
makeComponent<MenuItem, WifiIsConnectedText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_WIFICHANGEAUTOCONNECT>, ToggleBoolAction, CheckboxIcon, WifiAutoConnectAccessor>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_WIFICHANGEAUTORECONNECT>, ToggleBoolAction, CheckboxIcon, WifiAutoReconnectAccessor>,
|
||||
makeComponent<MenuItem, WifiLocalIpText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, WifiMacAddressText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, WifiSubnetMaskText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, WifiGatewayIpText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, WifiDnsIpText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, WifiBroadcastIpText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, WifiNetworkIdText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, WifiSubnetCIDRText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_WIFIENABLEIPV6>, WifiEnableIpV6Action>,
|
||||
makeComponent<MenuItem, WifiLocalIpV6Text, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, WifiHostnameText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, WifiStatusText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, WifiSsidText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, WifiPskText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, WifiBssidText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, WifiRssiText, StaticFont<2>, DisabledColor, DummyAction>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<WifiSettingsMenu>, StaticMenuItemIcon<&icons::back>>
|
||||
>
|
||||
{};
|
||||
}
|
31
src/displays/menus/tempomatmodesettingsmenu.h
Normal file
@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include "menudisplay.h"
|
||||
#include "staticmenudefinition.h"
|
||||
#include "utils.h"
|
||||
#include "changevaluedisplay.h"
|
||||
#include "menuitem.h"
|
||||
#include "actions/switchscreenaction.h"
|
||||
#include "icons/back.h"
|
||||
#include "texts.h"
|
||||
#include "settingsaccessors.h"
|
||||
|
||||
namespace {
|
||||
class TempomatModeSettingsMenu;
|
||||
class ModesSettingsMenu;
|
||||
}
|
||||
|
||||
namespace {
|
||||
using TempomatModeCtrlTypChangeScreen = makeComponent<ChangeValueDisplay<ControlType>, StaticText<TEXT_SETCONTROLMODE>, TempomatModeCtrlTypAccessor, SwitchScreenAction<TempomatModeSettingsMenu>>;
|
||||
using TempomatModeCtrlModChangeScreen = makeComponent<ChangeValueDisplay<ControlMode>, StaticText<TEXT_SETCONTROLMODE>, TempomatModeCtrlModAccessor, SwitchScreenAction<TempomatModeSettingsMenu>>;
|
||||
|
||||
class TempomatModeSettingsMenu :
|
||||
public MenuDisplay,
|
||||
public StaticText<TEXT_TEMPOMATMODESETTINGS>,
|
||||
public StaticMenuDefinition<
|
||||
makeComponent<MenuItem, StaticText<TEXT_SETCONTROLTYPE>, SwitchScreenAction<TempomatModeCtrlTypChangeScreen>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_SETCONTROLMODE>, SwitchScreenAction<TempomatModeCtrlModChangeScreen>>,
|
||||
makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<ModesSettingsMenu>, StaticMenuItemIcon<&icons::back>>
|
||||
>
|
||||
{};
|
||||
}
|