code format

update visual studio solution to build all versions properly

Pull pin defs into config file
use config file to allow USE_SIMULATOR checks in OmoteUI
this will allow the sim to compile in specific code within the UI
This commit is contained in:
Matthew Colvin 2023-07-26 15:16:04 -05:00
parent e7da8f63fb
commit 8af4b276cf
12 changed files with 2473 additions and 4558 deletions

View file

@ -11,6 +11,8 @@
#include <Windows.h> #include <Windows.h>
#include <string> #include <string>
#include "resource.h" #include "resource.h"
#include "omoteconfig.h"
#include "HardwareSimulator.hpp" #include "HardwareSimulator.hpp"
#include "OmoteUI.hpp" #include "OmoteUI.hpp"

View file

@ -47,6 +47,7 @@
<ClInclude Include="..\..\Platformio\include\OmoteUI\HardwareAbstractionInterface.h" /> <ClInclude Include="..\..\Platformio\include\OmoteUI\HardwareAbstractionInterface.h" />
<ClInclude Include="..\..\Platformio\include\OmoteUI\OmoteUI.hpp" /> <ClInclude Include="..\..\Platformio\include\OmoteUI\OmoteUI.hpp" />
<ClInclude Include="HardwareSimulator.hpp" /> <ClInclude Include="HardwareSimulator.hpp" />
<ClInclude Include="omoteconfig.h" />
<ClInclude Include="lv_conf.h" /> <ClInclude Include="lv_conf.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View file

@ -12,6 +12,7 @@
<ClInclude Include="..\..\Platformio\include\OmoteUI\OmoteUI.hpp"> <ClInclude Include="..\..\Platformio\include\OmoteUI\OmoteUI.hpp">
<Filter>OmoteUI</Filter> <Filter>OmoteUI</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="omoteconfig.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Manifest Include="LVGL.Simulator.manifest" /> <Manifest Include="LVGL.Simulator.manifest" />
@ -41,7 +42,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Filter Include="OmoteUI"> <Filter Include="OmoteUI">
<UniqueIdentifier>{99618779-7582-48d0-b4c5-921283dc84e0}</UniqueIdentifier> <UniqueIdentifier>{0b1f99aa-73cb-482d-9d62-20e17f93b890}</UniqueIdentifier>
</Filter> </Filter>
</ItemGroup> </ItemGroup>
</Project> </Project>

View file

@ -0,0 +1,3 @@
#pragma once
#define IS_SIMULATOR true

File diff suppressed because it is too large Load diff

View file

@ -1,11 +1,13 @@
#pragma once #pragma once
#include <string>
#include <lvgl.h> #include <lvgl.h>
class HardwareAbstractionInterface #include <string>
{
class HardwareAbstractionInterface {
public: public:
typedef void (*display_flush_cb)(struct _lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p); typedef void (*display_flush_cb)(struct _lv_disp_drv_t *disp_drv,
typedef void (*touch_pad_read)(struct _lv_indev_drv_t *indev_drv, lv_indev_data_t *data); const lv_area_t *area, lv_color_t *color_p);
typedef void (*touch_pad_read)(struct _lv_indev_drv_t *indev_drv,
lv_indev_data_t *data);
HardwareAbstractionInterface() = default; HardwareAbstractionInterface() = default;

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,39 @@
#pragma once
#define IS_SIMULATOR false
#define ENABLE_WIFI // Comment out to disable connected features
// Pin assignment
// -----------------------------------------------------------------------------------------------------------------------
#define LCD_DC 9 // defined in TFT_eSPI User_Setup.h
#define LCD_CS 5
#define LCD_MOSI 23
#define LCD_SCK 18
#define LCD_BL 4
#define LCD_EN 10
#define USER_LED 2
#define SW_1 32 // 1...5: Output
#define SW_2 26
#define SW_3 27
#define SW_4 14
#define SW_5 12
#define SW_A 37 // A...E: Input
#define SW_B 38
#define SW_C 39
#define SW_D 34
#define SW_E 35
#define IR_RX 15 // IR receiver input
#define ADC_BAT 36 // Battery voltage sense input (1/2 divider)
#define IR_VCC 25 // IR receiver power
#define IR_LED 33 // IR LED output
#define SCL 22
#define SDA 19
#define ACC_INT 20
#define CRG_STAT 21 // battery charger feedback

View file

@ -7,29 +7,22 @@
#define screenWidth 240 #define screenWidth 240
#define screenHeight 320 #define screenHeight 320
class HardwareRevX : public HardwareAbstractionInterface class HardwareRevX : public HardwareAbstractionInterface {
{
public: public:
HardwareRevX() : HardwareAbstractionInterface(){}; HardwareRevX() : HardwareAbstractionInterface(){};
virtual void debugPrint(std::string aDebugMessage) override virtual void debugPrint(std::string aDebugMessage) override {}
{
}
virtual void sendIR() override virtual void sendIR() override {}
{
}
virtual void MQTTPublish(const char *topic, const char *payload) override virtual void MQTTPublish(const char *topic, const char *payload) override {}
{
}
virtual void initLVGL(display_flush_cb aDisplayFlushCb, virtual void initLVGL(display_flush_cb aDisplayFlushCb,
touch_pad_read aTouchPadReadCb) touch_pad_read aTouchPadReadCb) {
{
lv_init(); lv_init();
lv_disp_draw_buf_init(&mdraw_buf, mbufA, mbufB, screenWidth * screenHeight / 10); lv_disp_draw_buf_init(&mdraw_buf, mbufA, mbufB,
screenWidth * screenHeight / 10);
// Initialize the display driver // Initialize the display driver
static lv_disp_drv_t disp_drv; static lv_disp_drv_t disp_drv;

View file

@ -1,47 +1,45 @@
#include "OmoteUI.hpp" #include "OmoteUI.hpp"
#include "omoteconfig.h"
#include <functional> #include <functional>
std::shared_ptr<OmoteUI> OmoteUI::mInstance = nullptr; std::shared_ptr<OmoteUI> OmoteUI::mInstance = nullptr;
// Set the page indicator scroll position relative to the tabview scroll position // Set the page indicator scroll position relative to the tabview scroll
void OmoteUI::store_scroll_value_event_cb(lv_event_t *e) // position
{ void OmoteUI::store_scroll_value_event_cb(lv_event_t *e) {
float bias = (150.0 + 8.0) / 240.0; float bias = (150.0 + 8.0) / 240.0;
int offset = 240 / 2 - 150 / 2 - 8 - 50 - 3; int offset = 240 / 2 - 150 / 2 - 8 - 50 - 3;
lv_obj_t *screen = lv_event_get_target(e); lv_obj_t *screen = lv_event_get_target(e);
lv_obj_scroll_to_x(panel, lv_obj_get_scroll_x(screen) * bias - offset, LV_ANIM_OFF); lv_obj_scroll_to_x(panel, lv_obj_get_scroll_x(screen) * bias - offset,
LV_ANIM_OFF);
} }
// Update current device when the tabview page is changes // Update current device when the tabview page is changes
void OmoteUI::tabview_device_event_cb(lv_event_t *e) void OmoteUI::tabview_device_event_cb(lv_event_t *e) {
{
currentDevice = lv_tabview_get_tab_act(lv_event_get_target(e)); currentDevice = lv_tabview_get_tab_act(lv_event_get_target(e));
} }
// Slider Event handler // Slider Event handler
void OmoteUI::bl_slider_event_cb(lv_event_t *e) void OmoteUI::bl_slider_event_cb(lv_event_t *e) {
{
lv_obj_t *slider = lv_event_get_target(e); lv_obj_t *slider = lv_event_get_target(e);
backlight_brightness = std::clamp(lv_slider_get_value(slider), 60, 255); backlight_brightness = std::clamp(lv_slider_get_value(slider), 60, 255);
} }
// Apple Key Event handler // Apple Key Event handler
void OmoteUI::appleKey_event_cb(lv_event_t *e) void OmoteUI::appleKey_event_cb(lv_event_t *e) {
{
// Send IR command based on the event user data // Send IR command based on the event user data
mHardware->sendIR(); mHardware->sendIR();
mHardware->debugPrint(std::to_string(50 + (int)e->user_data)); mHardware->debugPrint(std::to_string(50 + (int)e->user_data));
} }
// Wakeup by IMU Switch Event handler // Wakeup by IMU Switch Event handler
void OmoteUI::WakeEnableSetting_event_cb(lv_event_t *e) void OmoteUI::WakeEnableSetting_event_cb(lv_event_t *e) {
{ wakeupByIMUEnabled =
wakeupByIMUEnabled = lv_obj_has_state(lv_event_get_target(e), LV_STATE_CHECKED); lv_obj_has_state(lv_event_get_target(e), LV_STATE_CHECKED);
} }
// Smart Home Toggle Event handler // Smart Home Toggle Event handler
void OmoteUI::smartHomeToggle_event_cb(lv_event_t *e) void OmoteUI::smartHomeToggle_event_cb(lv_event_t *e) {
{
char payload[8]; char payload[8];
if (lv_obj_has_state(lv_event_get_target(e), LV_STATE_CHECKED)) if (lv_obj_has_state(lv_event_get_target(e), LV_STATE_CHECKED))
strcpy(payload, "true"); strcpy(payload, "true");
@ -55,8 +53,7 @@ void OmoteUI::smartHomeToggle_event_cb(lv_event_t *e)
} }
// Smart Home Toggle Event handler // Smart Home Toggle Event handler
void OmoteUI::smartHomeSlider_event_cb(lv_event_t *e) void OmoteUI::smartHomeSlider_event_cb(lv_event_t *e) {
{
lv_obj_t *slider = lv_event_get_target(e); lv_obj_t *slider = lv_event_get_target(e);
char payload[8]; char payload[8];
auto sliderValue = lv_slider_get_value(slider); auto sliderValue = lv_slider_get_value(slider);
@ -73,20 +70,19 @@ void OmoteUI::smartHomeSlider_event_cb(lv_event_t *e)
mHardware->MQTTPublish("bulb2_setbrightness", payload); mHardware->MQTTPublish("bulb2_setbrightness", payload);
} }
void OmoteUI::virtualKeypad_event_cb(lv_event_t *e) void OmoteUI::virtualKeypad_event_cb(lv_event_t *e) {
{
lv_obj_t *target = lv_event_get_target(e); lv_obj_t *target = lv_event_get_target(e);
lv_obj_t *cont = lv_event_get_current_target(e); lv_obj_t *cont = lv_event_get_current_target(e);
if (target == cont) if (target == cont)
return; return;
char buffer[100]; char buffer[100];
sprintf(buffer, "check it out: %d\n", virtualKeyMapTechnisat[(int)target->user_data]); sprintf(buffer, "check it out: %d\n",
virtualKeyMapTechnisat[(int)target->user_data]);
mHardware->debugPrint(buffer); mHardware->debugPrint(buffer);
} }
void OmoteUI::layout_UI() void OmoteUI::layout_UI() {
{
// --- LVGL UI Configuration --- // --- LVGL UI Configuration ---
@ -95,9 +91,12 @@ void OmoteUI::layout_UI()
// Setup a scrollable tabview for devices and settings // Setup a scrollable tabview for devices and settings
lv_obj_t *tabview; lv_obj_t *tabview;
tabview = lv_tabview_create(lv_scr_act(), LV_DIR_TOP, 0); // Hide tab labels by setting their height to 0 tabview =
lv_tabview_create(lv_scr_act(), LV_DIR_TOP,
0); // Hide tab labels by setting their height to 0
lv_obj_set_style_bg_color(tabview, lv_color_black(), LV_PART_MAIN); lv_obj_set_style_bg_color(tabview, lv_color_black(), LV_PART_MAIN);
lv_obj_set_size(tabview, mHardware->getScreenWidth(), 270); // 270 = screenHeight(320) - panel(30) - statusbar(20) lv_obj_set_size(tabview, mHardware->getScreenWidth(),
270); // 270 = screenHeight(320) - panel(30) - statusbar(20)
lv_obj_align(tabview, LV_ALIGN_TOP_MID, 0, 20); lv_obj_align(tabview, LV_ALIGN_TOP_MID, 0, 20);
// Add 4 tabs (names are irrelevant since the labels are hidden) // Add 4 tabs (names are irrelevant since the labels are hidden)
@ -107,8 +106,11 @@ void OmoteUI::layout_UI()
lv_obj_t *tab4 = lv_tabview_add_tab(tabview, "Smart Home"); lv_obj_t *tab4 = lv_tabview_add_tab(tabview, "Smart Home");
// Configure number button grid // Configure number button grid
static lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST}; // equal x distribution static lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1),
static lv_coord_t row_dsc[] = {52, 52, 52, 52, LV_GRID_TEMPLATE_LAST}; // manual y distribution to compress the grid a bit LV_GRID_TEMPLATE_LAST}; // equal x distribution
static lv_coord_t row_dsc[] = {
52, 52, 52, 52, LV_GRID_TEMPLATE_LAST}; // manual y distribution to
// compress the grid a bit
// Create a container with grid for tab2 // Create a container with grid for tab2
lv_obj_set_style_pad_all(tab2, 0, LV_PART_MAIN); lv_obj_set_style_pad_all(tab2, 0, LV_PART_MAIN);
@ -127,40 +129,42 @@ void OmoteUI::layout_UI()
lv_obj_t *obj; lv_obj_t *obj;
// Iterate through grid buttons and configure them // Iterate through grid buttons and configure them
for (int i = 0; i < 12; i++) for (int i = 0; i < 12; i++) {
{
uint8_t col = i % 3; uint8_t col = i % 3;
uint8_t row = i / 3; uint8_t row = i / 3;
// Create the button object // Create the button object
if ((row == 3) && ((col == 0) || (col == 2))) if ((row == 3) && ((col == 0) || (col == 2)))
continue; // Do not create a complete fourth row, only a 0 button continue; // Do not create a complete fourth row, only a 0 button
obj = lv_btn_create(cont); obj = lv_btn_create(cont);
lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, col, 1, LV_GRID_ALIGN_STRETCH, row, 1); lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, col, 1,
LV_GRID_ALIGN_STRETCH, row, 1);
lv_obj_set_style_bg_color(obj, color_primary, LV_PART_MAIN); lv_obj_set_style_bg_color(obj, color_primary, LV_PART_MAIN);
lv_obj_set_style_radius(obj, 14, LV_PART_MAIN); lv_obj_set_style_radius(obj, 14, LV_PART_MAIN);
lv_obj_add_flag(obj, LV_OBJ_FLAG_EVENT_BUBBLE); // Clicking a button causes a event in its container lv_obj_add_flag(obj, LV_OBJ_FLAG_EVENT_BUBBLE); // Clicking a button causes
// a event in its container
// Create Labels for each button // Create Labels for each button
buttonLabel = lv_label_create(obj); buttonLabel = lv_label_create(obj);
if (i < 9) if (i < 9) {
{ lv_label_set_text_fmt(buttonLabel, std::to_string(i + 1).c_str(), col,
lv_label_set_text_fmt(buttonLabel, std::to_string(i + 1).c_str(), col, row); row);
lv_obj_set_user_data(obj, (void *)i); // Add user data so we can identify which button caused the container event lv_obj_set_user_data(obj,
} (void *)i); // Add user data so we can identify which
else // button caused the container event
{ } else {
lv_label_set_text_fmt(buttonLabel, "0", col, row); lv_label_set_text_fmt(buttonLabel, "0", col, row);
lv_obj_set_user_data(obj, (void *)9); lv_obj_set_user_data(obj, (void *)9);
} }
lv_obj_set_style_text_font(buttonLabel, &lv_font_montserrat_14, LV_PART_MAIN); lv_obj_set_style_text_font(buttonLabel, &lv_font_montserrat_14,
LV_PART_MAIN);
lv_obj_center(buttonLabel); lv_obj_center(buttonLabel);
} }
// Create a shared event for all button inside container // Create a shared event for all button inside container
lv_obj_add_event_cb( lv_obj_add_event_cb(
cont, [](lv_event_t *e) cont, [](lv_event_t *e) { mInstance->virtualKeypad_event_cb(e); },
{ mInstance->virtualKeypad_event_cb(e); },
LV_EVENT_CLICKED, NULL); LV_EVENT_CLICKED, NULL);
// Only for the LVGL PC Simulator !!! // Only for the LVGL PC Simulator !!!
#if defined(IS_SIMULATOR) && (IS_SIMULATOR == true)
appleTvIcon.header.cf = LV_IMG_CF_TRUE_COLOR; appleTvIcon.header.cf = LV_IMG_CF_TRUE_COLOR;
appleTvIcon.header.always_zero = 0; appleTvIcon.header.always_zero = 0;
appleTvIcon.header.reserved = 0; appleTvIcon.header.reserved = 0;
@ -168,7 +172,6 @@ void OmoteUI::layout_UI()
appleTvIcon.header.h = 42; appleTvIcon.header.h = 42;
appleTvIcon.data_size = 3822 * LV_COLOR_SIZE / 8; appleTvIcon.data_size = 3822 * LV_COLOR_SIZE / 8;
appleTvIcon.data = appleTvIcon_map; appleTvIcon.data = appleTvIcon_map;
appleDisplayIcon.header.cf = LV_IMG_CF_ALPHA_8BIT; appleDisplayIcon.header.cf = LV_IMG_CF_ALPHA_8BIT;
appleDisplayIcon.header.always_zero = 0; appleDisplayIcon.header.always_zero = 0;
appleDisplayIcon.header.reserved = 0; appleDisplayIcon.header.reserved = 0;
@ -185,6 +188,8 @@ void OmoteUI::layout_UI()
appleBackIcon.data_size = 325; appleBackIcon.data_size = 325;
appleBackIcon.data = appleBackIcon_map; appleBackIcon.data = appleBackIcon_map;
#endif
// Add content to the Apple TV tab (3) // Add content to the Apple TV tab (3)
// Add a nice apple tv logo // Add a nice apple tv logo
lv_obj_t *appleImg = lv_img_create(tab3); lv_obj_t *appleImg = lv_img_create(tab3);
@ -197,8 +202,7 @@ void OmoteUI::layout_UI()
lv_obj_set_style_radius(button, 30, LV_PART_MAIN); lv_obj_set_style_radius(button, 30, LV_PART_MAIN);
lv_obj_set_style_bg_color(button, color_primary, LV_PART_MAIN); lv_obj_set_style_bg_color(button, color_primary, LV_PART_MAIN);
lv_obj_add_event_cb( lv_obj_add_event_cb(
button, [](lv_event_t *e) button, [](lv_event_t *e) { mInstance->appleKey_event_cb(e); },
{ mInstance->appleKey_event_cb(e); },
LV_EVENT_CLICKED, (void *)1); LV_EVENT_CLICKED, (void *)1);
appleImg = lv_img_create(button); appleImg = lv_img_create(button);
@ -213,8 +217,7 @@ void OmoteUI::layout_UI()
lv_obj_set_style_radius(button, 30, LV_PART_MAIN); lv_obj_set_style_radius(button, 30, LV_PART_MAIN);
lv_obj_set_style_bg_color(button, color_primary, LV_PART_MAIN); lv_obj_set_style_bg_color(button, color_primary, LV_PART_MAIN);
lv_obj_add_event_cb( lv_obj_add_event_cb(
button, [](lv_event_t *e) button, [](lv_event_t *e) { mInstance->appleKey_event_cb(e); },
{ mInstance->appleKey_event_cb(e); },
LV_EVENT_CLICKED, (void *)2); LV_EVENT_CLICKED, (void *)2);
appleImg = lv_img_create(button); appleImg = lv_img_create(button);
@ -224,7 +227,8 @@ void OmoteUI::layout_UI()
lv_obj_align(appleImg, LV_ALIGN_CENTER, 0, 0); lv_obj_align(appleImg, LV_ALIGN_CENTER, 0, 0);
// Add content to the settings tab // Add content to the settings tab
// With a flex layout, setting groups/boxes will position themselves automatically // With a flex layout, setting groups/boxes will position themselves
// automatically
lv_obj_set_layout(tab1, LV_LAYOUT_FLEX); lv_obj_set_layout(tab1, LV_LAYOUT_FLEX);
lv_obj_set_flex_flow(tab1, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_flow(tab1, LV_FLEX_FLOW_COLUMN);
lv_obj_set_scrollbar_mode(tab1, LV_SCROLLBAR_MODE_ACTIVE); lv_obj_set_scrollbar_mode(tab1, LV_SCROLLBAR_MODE_ACTIVE);
@ -264,7 +268,8 @@ void OmoteUI::layout_UI()
lv_slider_set_range(slider, 60, 255); lv_slider_set_range(slider, 60, 255);
lv_obj_set_style_bg_color(slider, lv_color_white(), LV_PART_KNOB); lv_obj_set_style_bg_color(slider, lv_color_white(), LV_PART_KNOB);
lv_obj_set_style_bg_opa(slider, LV_OPA_COVER, LV_PART_MAIN); lv_obj_set_style_bg_opa(slider, LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_bg_color(slider, lv_color_lighten(color_primary, 50), LV_PART_MAIN); lv_obj_set_style_bg_color(slider, lv_color_lighten(color_primary, 50),
LV_PART_MAIN);
lv_slider_set_value(slider, backlight_brightness, LV_ANIM_OFF); lv_slider_set_value(slider, backlight_brightness, LV_ANIM_OFF);
lv_obj_set_size(slider, lv_pct(66), 10); lv_obj_set_size(slider, lv_pct(66), 10);
lv_obj_align(slider, LV_ALIGN_TOP_MID, 0, 3); lv_obj_align(slider, LV_ALIGN_TOP_MID, 0, 3);
@ -274,8 +279,7 @@ void OmoteUI::layout_UI()
lv_obj_set_style_img_recolor_opa(brightnessIcon, LV_OPA_COVER, LV_PART_MAIN); lv_obj_set_style_img_recolor_opa(brightnessIcon, LV_OPA_COVER, LV_PART_MAIN);
lv_obj_align(brightnessIcon, LV_ALIGN_TOP_RIGHT, 0, -1); lv_obj_align(brightnessIcon, LV_ALIGN_TOP_RIGHT, 0, -1);
lv_obj_add_event_cb( lv_obj_add_event_cb(
slider, [](lv_event_t *e) slider, [](lv_event_t *e) { mInstance->bl_slider_event_cb(e); },
{ mInstance->bl_slider_event_cb(e); },
LV_EVENT_VALUE_CHANGED, NULL); LV_EVENT_VALUE_CHANGED, NULL);
menuLabel = lv_label_create(menuBox); menuLabel = lv_label_create(menuBox);
@ -284,10 +288,11 @@ void OmoteUI::layout_UI()
lv_obj_t *wakeToggle = lv_switch_create(menuBox); lv_obj_t *wakeToggle = lv_switch_create(menuBox);
lv_obj_set_size(wakeToggle, 40, 22); lv_obj_set_size(wakeToggle, 40, 22);
lv_obj_align(wakeToggle, LV_ALIGN_TOP_RIGHT, 0, 29); lv_obj_align(wakeToggle, LV_ALIGN_TOP_RIGHT, 0, 29);
lv_obj_set_style_bg_color(wakeToggle, lv_color_lighten(color_primary, 50), LV_PART_MAIN); lv_obj_set_style_bg_color(wakeToggle, lv_color_lighten(color_primary, 50),
LV_PART_MAIN);
lv_obj_add_event_cb( lv_obj_add_event_cb(
wakeToggle, [](lv_event_t *e) wakeToggle,
{ mInstance->WakeEnableSetting_event_cb(e); }, [](lv_event_t *e) { mInstance->WakeEnableSetting_event_cb(e); },
LV_EVENT_VALUE_CHANGED, NULL); LV_EVENT_VALUE_CHANGED, NULL);
if (wakeupByIMUEnabled) if (wakeupByIMUEnabled)
lv_obj_add_state(wakeToggle, LV_STATE_CHECKED); // set default state lv_obj_add_state(wakeToggle, LV_STATE_CHECKED); // set default state
@ -305,9 +310,12 @@ void OmoteUI::layout_UI()
lv_obj_set_style_pad_top(drop, 1, LV_PART_MAIN); lv_obj_set_style_pad_top(drop, 1, LV_PART_MAIN);
lv_obj_set_style_bg_color(drop, color_primary, LV_PART_MAIN); lv_obj_set_style_bg_color(drop, color_primary, LV_PART_MAIN);
lv_obj_set_style_border_width(drop, 0, LV_PART_MAIN); lv_obj_set_style_border_width(drop, 0, LV_PART_MAIN);
lv_obj_set_style_bg_color(lv_dropdown_get_list(drop), color_primary, LV_PART_MAIN); lv_obj_set_style_bg_color(lv_dropdown_get_list(drop), color_primary,
LV_PART_MAIN);
lv_obj_set_style_border_width(lv_dropdown_get_list(drop), 1, LV_PART_MAIN); lv_obj_set_style_border_width(lv_dropdown_get_list(drop), 1, LV_PART_MAIN);
lv_obj_set_style_border_color(lv_dropdown_get_list(drop), lv_color_darken(color_primary, 40), LV_PART_MAIN); lv_obj_set_style_border_color(lv_dropdown_get_list(drop),
lv_color_darken(color_primary, 40),
LV_PART_MAIN);
// Add another label, then a settings box for WiFi // Add another label, then a settings box for WiFi
menuLabel = lv_label_create(tab1); menuLabel = lv_label_create(tab1);
@ -339,12 +347,9 @@ void OmoteUI::layout_UI()
// Add content to the smart home tab (4) // Add content to the smart home tab (4)
// Only for the LVGL PC Simulator !!! // Only for the LVGL PC Simulator !!!
lightbulb.header.cf = LV_IMG_CF_ALPHA_8BIT, lightbulb.header.cf = LV_IMG_CF_ALPHA_8BIT, lightbulb.header.always_zero = 0,
lightbulb.header.always_zero = 0, lightbulb.header.reserved = 0, lightbulb.header.w = 12,
lightbulb.header.reserved = 0, lightbulb.header.h = 20, lightbulb.data_size = 240,
lightbulb.header.w = 12,
lightbulb.header.h = 20,
lightbulb.data_size = 240,
lightbulb.data = lightbulb_map; lightbulb.data = lightbulb_map;
lv_obj_set_layout(tab4, LV_LAYOUT_FLEX); lv_obj_set_layout(tab4, LV_LAYOUT_FLEX);
@ -372,27 +377,31 @@ void OmoteUI::layout_UI()
lv_obj_t *lightToggleA = lv_switch_create(menuBox); lv_obj_t *lightToggleA = lv_switch_create(menuBox);
lv_obj_set_size(lightToggleA, 40, 22); lv_obj_set_size(lightToggleA, 40, 22);
lv_obj_align(lightToggleA, LV_ALIGN_TOP_RIGHT, 0, 0); lv_obj_align(lightToggleA, LV_ALIGN_TOP_RIGHT, 0, 0);
lv_obj_set_style_bg_color(lightToggleA, lv_color_lighten(color_primary, 50), LV_PART_MAIN); lv_obj_set_style_bg_color(lightToggleA, lv_color_lighten(color_primary, 50),
LV_PART_MAIN);
lv_obj_set_style_bg_color(lightToggleA, color_primary, LV_PART_INDICATOR); lv_obj_set_style_bg_color(lightToggleA, color_primary, LV_PART_INDICATOR);
lv_obj_add_event_cb( lv_obj_add_event_cb(
lightToggleA, [](lv_event_t *e) lightToggleA,
{ mInstance->smartHomeToggle_event_cb(e); }, [](lv_event_t *e) { mInstance->smartHomeToggle_event_cb(e); },
LV_EVENT_VALUE_CHANGED, (void *)1); LV_EVENT_VALUE_CHANGED, (void *)1);
slider = lv_slider_create(menuBox); slider = lv_slider_create(menuBox);
lv_slider_set_range(slider, 60, 255); lv_slider_set_range(slider, 60, 255);
lv_obj_set_style_bg_color(slider, lv_color_lighten(lv_color_black(), 30), LV_PART_INDICATOR); lv_obj_set_style_bg_color(slider, lv_color_lighten(lv_color_black(), 30),
lv_obj_set_style_bg_grad_color(slider, lv_color_lighten(lv_palette_main(LV_PALETTE_AMBER), 180), LV_PART_INDICATOR); LV_PART_INDICATOR);
lv_obj_set_style_bg_grad_color(
slider, lv_color_lighten(lv_palette_main(LV_PALETTE_AMBER), 180),
LV_PART_INDICATOR);
lv_obj_set_style_bg_grad_dir(slider, LV_GRAD_DIR_HOR, LV_PART_INDICATOR); lv_obj_set_style_bg_grad_dir(slider, LV_GRAD_DIR_HOR, LV_PART_INDICATOR);
lv_obj_set_style_bg_color(slider, lv_color_white(), LV_PART_KNOB); lv_obj_set_style_bg_color(slider, lv_color_white(), LV_PART_KNOB);
lv_obj_set_style_bg_opa(slider, 255, LV_PART_MAIN); lv_obj_set_style_bg_opa(slider, 255, LV_PART_MAIN);
lv_obj_set_style_bg_color(slider, lv_color_lighten(color_primary, 50), LV_PART_MAIN); lv_obj_set_style_bg_color(slider, lv_color_lighten(color_primary, 50),
LV_PART_MAIN);
lv_slider_set_value(slider, 255, LV_ANIM_OFF); lv_slider_set_value(slider, 255, LV_ANIM_OFF);
lv_obj_set_size(slider, lv_pct(90), 10); lv_obj_set_size(slider, lv_pct(90), 10);
lv_obj_align(slider, LV_ALIGN_TOP_MID, 0, 37); lv_obj_align(slider, LV_ALIGN_TOP_MID, 0, 37);
lv_obj_add_event_cb( lv_obj_add_event_cb(
slider, [](lv_event_t *e) slider, [](lv_event_t *e) { mInstance->smartHomeSlider_event_cb(e); },
{ mInstance->smartHomeSlider_event_cb(e); },
LV_EVENT_VALUE_CHANGED, (void *)1); LV_EVENT_VALUE_CHANGED, (void *)1);
// Add another menu box for a second appliance // Add another menu box for a second appliance
@ -413,27 +422,31 @@ void OmoteUI::layout_UI()
lv_obj_t *lightToggleB = lv_switch_create(menuBox); lv_obj_t *lightToggleB = lv_switch_create(menuBox);
lv_obj_set_size(lightToggleB, 40, 22); lv_obj_set_size(lightToggleB, 40, 22);
lv_obj_align(lightToggleB, LV_ALIGN_TOP_RIGHT, 0, 0); lv_obj_align(lightToggleB, LV_ALIGN_TOP_RIGHT, 0, 0);
lv_obj_set_style_bg_color(lightToggleB, lv_color_lighten(color_primary, 50), LV_PART_MAIN); lv_obj_set_style_bg_color(lightToggleB, lv_color_lighten(color_primary, 50),
LV_PART_MAIN);
lv_obj_set_style_bg_color(lightToggleB, color_primary, LV_PART_INDICATOR); lv_obj_set_style_bg_color(lightToggleB, color_primary, LV_PART_INDICATOR);
lv_obj_add_event_cb( lv_obj_add_event_cb(
lightToggleB, [](lv_event_t *e) lightToggleB,
{ mInstance->smartHomeToggle_event_cb(e); }, [](lv_event_t *e) { mInstance->smartHomeToggle_event_cb(e); },
LV_EVENT_VALUE_CHANGED, (void *)2); LV_EVENT_VALUE_CHANGED, (void *)2);
slider = lv_slider_create(menuBox); slider = lv_slider_create(menuBox);
lv_slider_set_range(slider, 60, 255); lv_slider_set_range(slider, 60, 255);
lv_obj_set_style_bg_color(slider, lv_color_lighten(lv_color_black(), 30), LV_PART_INDICATOR); lv_obj_set_style_bg_color(slider, lv_color_lighten(lv_color_black(), 30),
lv_obj_set_style_bg_grad_color(slider, lv_color_lighten(lv_palette_main(LV_PALETTE_AMBER), 180), LV_PART_INDICATOR); LV_PART_INDICATOR);
lv_obj_set_style_bg_grad_color(
slider, lv_color_lighten(lv_palette_main(LV_PALETTE_AMBER), 180),
LV_PART_INDICATOR);
lv_obj_set_style_bg_grad_dir(slider, LV_GRAD_DIR_HOR, LV_PART_INDICATOR); lv_obj_set_style_bg_grad_dir(slider, LV_GRAD_DIR_HOR, LV_PART_INDICATOR);
lv_obj_set_style_bg_color(slider, lv_color_white(), LV_PART_KNOB); lv_obj_set_style_bg_color(slider, lv_color_white(), LV_PART_KNOB);
lv_obj_set_style_bg_opa(slider, 255, LV_PART_MAIN); lv_obj_set_style_bg_opa(slider, 255, LV_PART_MAIN);
lv_obj_set_style_bg_color(slider, lv_color_lighten(color_primary, 50), LV_PART_MAIN); lv_obj_set_style_bg_color(slider, lv_color_lighten(color_primary, 50),
LV_PART_MAIN);
lv_slider_set_value(slider, 255, LV_ANIM_OFF); lv_slider_set_value(slider, 255, LV_ANIM_OFF);
lv_obj_set_size(slider, lv_pct(90), 10); lv_obj_set_size(slider, lv_pct(90), 10);
lv_obj_align(slider, LV_ALIGN_TOP_MID, 0, 37); lv_obj_align(slider, LV_ALIGN_TOP_MID, 0, 37);
lv_obj_add_event_cb( lv_obj_add_event_cb(
slider, [](lv_event_t *e) slider, [](lv_event_t *e) { mInstance->smartHomeSlider_event_cb(e); },
{ mInstance->smartHomeSlider_event_cb(e); },
LV_EVENT_VALUE_CHANGED, (void *)2); LV_EVENT_VALUE_CHANGED, (void *)2);
// Add another room (empty for now) // Add another room (empty for now)
@ -450,7 +463,8 @@ void OmoteUI::layout_UI()
// Create a page indicator // Create a page indicator
panel = lv_obj_create(lv_scr_act()); panel = lv_obj_create(lv_scr_act());
lv_obj_clear_flag(panel, LV_OBJ_FLAG_CLICKABLE); // this indicator will not be clickable lv_obj_clear_flag(
panel, LV_OBJ_FLAG_CLICKABLE); // this indicator will not be clickable
lv_obj_set_size(panel, mHardware->getScreenWidth(), 30); lv_obj_set_size(panel, mHardware->getScreenWidth(), 30);
lv_obj_set_flex_flow(panel, LV_FLEX_FLOW_ROW); lv_obj_set_flex_flow(panel, LV_FLEX_FLOW_ROW);
lv_obj_align(panel, LV_ALIGN_BOTTOM_MID, 0, 0); lv_obj_align(panel, LV_ALIGN_BOTTOM_MID, 0, 0);
@ -504,12 +518,11 @@ void OmoteUI::layout_UI()
// Make the indicator scroll together with the tabs by creating a scroll event // Make the indicator scroll together with the tabs by creating a scroll event
lv_obj_add_event_cb( lv_obj_add_event_cb(
lv_tabview_get_content(tabview), [](lv_event_t *e) lv_tabview_get_content(tabview),
{ mInstance->store_scroll_value_event_cb(e); }, [](lv_event_t *e) { mInstance->store_scroll_value_event_cb(e); },
LV_EVENT_SCROLL, NULL); LV_EVENT_SCROLL, NULL);
lv_obj_add_event_cb( lv_obj_add_event_cb(
tabview, [](lv_event_t *e) tabview, [](lv_event_t *e) { mInstance->tabview_device_event_cb(e); },
{ mInstance->tabview_device_event_cb(e); },
LV_EVENT_VALUE_CHANGED, NULL); LV_EVENT_VALUE_CHANGED, NULL);
// Initialize scroll position for the indicator // Initialize scroll position for the indicator
lv_event_send(lv_tabview_get_content(tabview), LV_EVENT_SCROLL, NULL); lv_event_send(lv_tabview_get_content(tabview), LV_EVENT_SCROLL, NULL);
@ -565,7 +578,8 @@ void OmoteUI::layout_UI()
lv_obj_t *objBattPercentage = lv_label_create(statusbar); lv_obj_t *objBattPercentage = lv_label_create(statusbar);
lv_label_set_text(objBattPercentage, ""); lv_label_set_text(objBattPercentage, "");
lv_obj_align(objBattPercentage, LV_ALIGN_RIGHT_MID, -16, 0); lv_obj_align(objBattPercentage, LV_ALIGN_RIGHT_MID, -16, 0);
lv_obj_set_style_text_font(objBattPercentage, &lv_font_montserrat_14, LV_PART_MAIN); lv_obj_set_style_text_font(objBattPercentage, &lv_font_montserrat_14,
LV_PART_MAIN);
lv_obj_t *objBattIcon = lv_label_create(statusbar); lv_obj_t *objBattIcon = lv_label_create(statusbar);
lv_label_set_text(objBattIcon, LV_SYMBOL_BATTERY_EMPTY); lv_label_set_text(objBattIcon, LV_SYMBOL_BATTERY_EMPTY);

File diff suppressed because it is too large Load diff

View file

@ -1,59 +1,27 @@
// OMOTE firmware for ESP32 // OMOTE firmware for ESP32
// 2023 Maximilian Kern // 2023 Maximilian Kern
#include <TFT_eSPI.h> // Hardware-specific library
#include <Keypad.h> // modified for inverted logic
#include <Preferences.h>
#include "SparkFunLIS3DH.h" #include "SparkFunLIS3DH.h"
#include "WiFi.h"
#include "Wire.h" #include "Wire.h"
#include "driver/ledc.h"
#include <Adafruit_FT6206.h>
#include <IRrecv.h>
#include <IRremoteESP8266.h> #include <IRremoteESP8266.h>
#include <IRsend.h> #include <IRsend.h>
#include <IRrecv.h>
#include <IRutils.h> #include <IRutils.h>
#include <lvgl.h> #include <Keypad.h> // modified for inverted logic
#include "WiFi.h" #include <Preferences.h>
#include <Adafruit_FT6206.h>
#include "driver/ledc.h"
#include <PubSubClient.h> #include <PubSubClient.h>
#include "OmoteUI/OmoteUI.hpp" #include <TFT_eSPI.h> // Hardware-specific library
#include <lvgl.h>
#include "HardwareRevX.hpp" #include "HardwareRevX.hpp"
#include "OmoteUI/OmoteUI.hpp"
#include "omoteconfig.h"
#define ENABLE_WIFI // Comment out to diable connected features // Variables and Object declarations
// ------------------------------------------------------------------------------------------------------
// Pin assignment -----------------------------------------------------------------------------------------------------------------------
#define LCD_DC 9 // defined in TFT_eSPI User_Setup.h
#define LCD_CS 5
#define LCD_MOSI 23
#define LCD_SCK 18
#define LCD_BL 4
#define LCD_EN 10
#define USER_LED 2
#define SW_1 32 // 1...5: Output
#define SW_2 26
#define SW_3 27
#define SW_4 14
#define SW_5 12
#define SW_A 37 // A...E: Input
#define SW_B 38
#define SW_C 39
#define SW_D 34
#define SW_E 35
#define IR_RX 15 // IR receiver input
#define ADC_BAT 36 // Battery voltage sense input (1/2 divider)
#define IR_VCC 25 // IR receiver power
#define IR_LED 33 // IR LED output
#define SCL 22
#define SDA 19
#define ACC_INT 20
#define CRG_STAT 21 // battery charger feedback
// Variables and Object declarations ------------------------------------------------------------------------------------------------------
// Battery declares // Battery declares
int battery_voltage = 0; int battery_voltage = 0;
@ -62,7 +30,8 @@ bool battery_ischarging = false;
// IMU declarations // IMU declarations
int motion = 0; int motion = 0;
#define SLEEP_TIMEOUT 20000 // time until device enters sleep mode in milliseconds #define SLEEP_TIMEOUT \
20000 // time until device enters sleep mode in milliseconds
#define MOTION_THRESHOLD 50 // motion above threshold keeps device awake #define MOTION_THRESHOLD 50 // motion above threshold keeps device awake
int standbyTimer = SLEEP_TIMEOUT; int standbyTimer = SLEEP_TIMEOUT;
bool wakeupByIMUEnabled = true; bool wakeupByIMUEnabled = true;
@ -103,18 +72,23 @@ char hexaKeys[ROWS][COLS] = {
{'>', 'o', 'b', 'u', 'l'}, // forward, off, back, up, left {'>', 'o', 'b', 'u', 'l'}, // forward, off, back, up, left
{'?', 'p', 'c', '<', '='} // ?, play, config, rewind, stop {'?', 'p', 'c', '<', '='} // ?, play, config, rewind, stop
}; };
byte rowPins[ROWS] = {SW_A, SW_B, SW_C, SW_D, SW_E}; // connect to the row pinouts of the keypad byte rowPins[ROWS] = {SW_A, SW_B, SW_C, SW_D,
byte colPins[COLS] = {SW_1, SW_2, SW_3, SW_4, SW_5}; // connect to the column pinouts of the keypad SW_E}; // connect to the row pinouts of the keypad
Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); byte colPins[COLS] = {SW_1, SW_2, SW_3, SW_4,
#define BUTTON_PIN_BITMASK 0b1110110000000000000000000010000000000000 // IO34+IO35+IO37+IO38+IO39(+IO13) SW_5}; // connect to the column pinouts of the keypad
byte keyMapTechnisat[ROWS][COLS] = { Keypad customKeypad =
{0x69, 0x20, 0x11, 0x0D, 0x56}, Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
#define BUTTON_PIN_BITMASK \
0b1110110000000000000000000010000000000000 // IO34+IO35+IO37+IO38+IO39(+IO13)
byte keyMapTechnisat[ROWS][COLS] = {{0x69, 0x20, 0x11, 0x0D, 0x56},
{0x4F, 0x37, 0x10, 0x57, 0x51}, {0x4F, 0x37, 0x10, 0x57, 0x51},
{0x6E, 0x21, 0x6B, 0x6D, 0x6C}, {0x6E, 0x21, 0x6B, 0x6D, 0x6C},
{0x34, 0x0C, 0x22, 0x50, 0x55}, {0x34, 0x0C, 0x22, 0x50, 0x55},
{'?', 0x35, 0x2F, 0x32, 0x36}}; {'?', 0x35, 0x2F, 0x32, 0x36}};
byte virtualKeyMapTechnisat[10] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x0}; byte virtualKeyMapTechnisat[10] = {0x1, 0x2, 0x3, 0x4, 0x5,
byte currentDevice = 1; // Current Device to control (allows switching mappings between devices) 0x6, 0x7, 0x8, 0x9, 0x0};
byte currentDevice =
1; // Current Device to control (allows switching mappings between devices)
// IR declarations // IR declarations
IRsend IrSender(IR_LED, true); IRsend IrSender(IR_LED, true);
@ -122,12 +96,7 @@ IRrecv IrReceiver(IR_RX);
// Other declarations // Other declarations
byte wakeup_reason; byte wakeup_reason;
enum Wakeup_reasons enum Wakeup_reasons { WAKEUP_BY_RESET, WAKEUP_BY_IMU, WAKEUP_BY_KEYPAD };
{
WAKEUP_BY_RESET,
WAKEUP_BY_IMU,
WAKEUP_BY_KEYPAD
};
Preferences preferences; Preferences preferences;
#define WIFI_SSID "YOUR_WIFI_SSID" #define WIFI_SSID "YOUR_WIFI_SSID"
@ -137,11 +106,12 @@ lv_obj_t *WifiLabel;
WiFiClient espClient; WiFiClient espClient;
PubSubClient client(espClient); PubSubClient client(espClient);
// Helper Functions ----------------------------------------------------------------------------------------------------------------------- // Helper Functions
// -----------------------------------------------------------------------------------------------------------------------
// Display flushing // Display flushing
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area,
{ lv_color_t *color_p) {
uint32_t w = (area->x2 - area->x1 + 1); uint32_t w = (area->x2 - area->x1 + 1);
uint32_t h = (area->y2 - area->y1 + 1); uint32_t h = (area->y2 - area->y1 + 1);
@ -154,25 +124,20 @@ void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color
} }
// Read the touchpad // Read the touchpad
void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data) void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data) {
{
// int16_t touchX, touchY; // int16_t touchX, touchY;
touchPoint = touch.getPoint(); touchPoint = touch.getPoint();
int16_t touchX = touchPoint.x; int16_t touchX = touchPoint.x;
int16_t touchY = touchPoint.y; int16_t touchY = touchPoint.y;
bool touched = false; bool touched = false;
if ((touchX > 0) || (touchY > 0)) if ((touchX > 0) || (touchY > 0)) {
{
touched = true; touched = true;
standbyTimer = SLEEP_TIMEOUT; standbyTimer = SLEEP_TIMEOUT;
} }
if (!touched) if (!touched) {
{
data->state = LV_INDEV_STATE_REL; data->state = LV_INDEV_STATE_REL;
} } else {
else
{
data->state = LV_INDEV_STATE_PR; data->state = LV_INDEV_STATE_PR;
// Set the coordinates // Set the coordinates
@ -188,8 +153,7 @@ void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
} }
} }
void activityDetection() void activityDetection() {
{
static int accXold; static int accXold;
static int accYold; static int accYold;
static int accZold; static int accZold;
@ -213,8 +177,7 @@ void activityDetection()
accZold = accZ; accZold = accZ;
} }
void configIMUInterrupts() void configIMUInterrupts() {
{
uint8_t dataToWrite = 0; uint8_t dataToWrite = 0;
// LIS3DH_INT1_CFG // LIS3DH_INT1_CFG
@ -267,8 +230,7 @@ void configIMUInterrupts()
} }
// Enter Sleep Mode // Enter Sleep Mode
void enterSleep() void enterSleep() {
{
// Save settings to internal flash memory // Save settings to internal flash memory
preferences.putBool("wkpByIMU", wakeupByIMUEnabled); preferences.putBool("wkpByIMU", wakeupByIMUEnabled);
preferences.putUChar("blBrightness", backlight_brightness); preferences.putUChar("blBrightness", backlight_brightness);
@ -332,43 +294,36 @@ void enterSleep()
#ifdef ENABLE_WIFI #ifdef ENABLE_WIFI
// WiFi status event // WiFi status event
void WiFiEvent(WiFiEvent_t event) void WiFiEvent(WiFiEvent_t event) {
{
// Serial.printf("[WiFi-event] event: %d\n", event); // Serial.printf("[WiFi-event] event: %d\n", event);
if (event == ARDUINO_EVENT_WIFI_STA_GOT_IP) if (event == ARDUINO_EVENT_WIFI_STA_GOT_IP) {
{
client.setServer(MQTT_SERVER, 1883); // MQTT initialization client.setServer(MQTT_SERVER, 1883); // MQTT initialization
client.connect("OMOTE"); // Connect using a client id client.connect("OMOTE"); // Connect using a client id
} }
// Set status bar icon based on WiFi status // Set status bar icon based on WiFi status
if (event == ARDUINO_EVENT_WIFI_STA_GOT_IP || event == ARDUINO_EVENT_WIFI_STA_GOT_IP6) if (event == ARDUINO_EVENT_WIFI_STA_GOT_IP ||
{ event == ARDUINO_EVENT_WIFI_STA_GOT_IP6) {
lv_label_set_text(WifiLabel, LV_SYMBOL_WIFI); lv_label_set_text(WifiLabel, LV_SYMBOL_WIFI);
} } else {
else
{
lv_label_set_text(WifiLabel, ""); lv_label_set_text(WifiLabel, "");
} }
} }
#endif #endif
// Setup ---------------------------------------------------------------------------------------------------------------------------------- // Setup
// ----------------------------------------------------------------------------------------------------------------------------------
void setup() void setup() {
{
setCpuFrequencyMhz(240); // Make sure ESP32 is running at full speed setCpuFrequencyMhz(240); // Make sure ESP32 is running at full speed
// Find out wakeup cause // Find out wakeup cause
if (esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_EXT1) if (esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_EXT1) {
{
if (log(esp_sleep_get_ext1_wakeup_status()) / log(2) == 13) if (log(esp_sleep_get_ext1_wakeup_status()) / log(2) == 13)
wakeup_reason = WAKEUP_BY_IMU; wakeup_reason = WAKEUP_BY_IMU;
else else
wakeup_reason = WAKEUP_BY_KEYPAD; wakeup_reason = WAKEUP_BY_KEYPAD;
} } else {
else
{
wakeup_reason = WAKEUP_BY_RESET; wakeup_reason = WAKEUP_BY_RESET;
} }
@ -444,8 +399,7 @@ void setup()
// Restore settings from internal flash memory // Restore settings from internal flash memory
preferences.begin("settings", false); preferences.begin("settings", false);
if (preferences.getBool("alreadySetUp")) if (preferences.getBool("alreadySetUp")) {
{
wakeupByIMUEnabled = preferences.getBool("wkpByIMU"); wakeupByIMUEnabled = preferences.getBool("wkpByIMU");
backlight_brightness = preferences.getUChar("blBrightness"); backlight_brightness = preferences.getUChar("blBrightness");
currentDevice = preferences.getUChar("currentDevice"); currentDevice = preferences.getUChar("currentDevice");
@ -455,8 +409,7 @@ void setup()
// Slowly charge the VSW voltage to prevent a brownout // Slowly charge the VSW voltage to prevent a brownout
// Workaround for hardware rev 1! // Workaround for hardware rev 1!
for (int i = 0; i < 100; i++) for (int i = 0; i < 100; i++) {
{
digitalWrite(LCD_EN, HIGH); // LCD Logic off digitalWrite(LCD_EN, HIGH); // LCD Logic off
delayMicroseconds(1); delayMicroseconds(1);
digitalWrite(LCD_EN, LOW); // LCD Logic on digitalWrite(LCD_EN, LOW); // LCD Logic on
@ -470,7 +423,8 @@ void setup()
tft.setSwapBytes(true); tft.setSwapBytes(true);
// Setup touchscreen // Setup touchscreen
Wire.begin(SDA, SCL, 400000); // Configure i2c pins and set frequency to 400kHz Wire.begin(SDA, SCL,
400000); // Configure i2c pins and set frequency to 400kHz
touch.begin(128); // Initialize touchscreen and set sensitivity threshold touch.begin(128); // Initialize touchscreen and set sensitivity threshold
auto hal = std::make_shared<HardwareRevX>(); auto hal = std::make_shared<HardwareRevX>();
@ -488,7 +442,8 @@ void setup()
#endif #endif
// Setup IMU // Setup IMU
IMU.settings.accelSampleRate = 50; // Hz. Can be: 0,1,10,25,50,100,200,400,1600,5000 Hz IMU.settings.accelSampleRate =
50; // Hz. Can be: 0,1,10,25,50,100,200,400,1600,5000 Hz
IMU.settings.accelRange = 2; // Max G force readable. Can be: 2, 4, 8, 16 IMU.settings.accelRange = 2; // Max G force readable. Can be: 2, 4, 8, 16
IMU.settings.adcEnabled = 0; IMU.settings.adcEnabled = 0;
IMU.settings.tempEnabled = 0; IMU.settings.tempEnabled = 0;
@ -511,19 +466,17 @@ void setup()
Serial.println("ms."); Serial.println("ms.");
} }
// Loop ------------------------------------------------------------------------------------------------------------------------------------ // Loop
// ------------------------------------------------------------------------------------------------------------------------------------
void loop() void loop() {
{
// Update Backlight brightness // Update Backlight brightness
static int fadeInTimer = millis(); // fadeInTimer = time after setup static int fadeInTimer = millis(); // fadeInTimer = time after setup
if (millis() < fadeInTimer + backlight_brightness) if (millis() <
{ // Fade in the backlight brightness fadeInTimer + backlight_brightness) { // Fade in the backlight brightness
ledcWrite(5, millis() - fadeInTimer); ledcWrite(5, millis() - fadeInTimer);
} } else { // Dim Backlight before entering standby
else
{ // Dim Backlight before entering standby
if (standbyTimer < 2000) if (standbyTimer < 2000)
ledcWrite(5, 85); // Backlight dim ledcWrite(5, 85); // Backlight dim
else else
@ -538,11 +491,9 @@ void loop()
// Refresh IMU data at 10Hz // Refresh IMU data at 10Hz
static unsigned long IMUTaskTimer = millis(); static unsigned long IMUTaskTimer = millis();
if (millis() - IMUTaskTimer >= 100) if (millis() - IMUTaskTimer >= 100) {
{
activityDetection(); activityDetection();
if (standbyTimer == 0) if (standbyTimer == 0) {
{
Serial.println("Entering Sleep Mode. Goodbye."); Serial.println("Entering Sleep Mode. Goodbye.");
enterSleep(); enterSleep();
} }
@ -550,21 +501,20 @@ void loop()
} }
// Update battery stats at 1Hz // Update battery stats at 1Hz
static unsigned long batteryTaskTimer = millis() + 1000; // add 1s to start immediately static unsigned long batteryTaskTimer =
if (millis() - batteryTaskTimer >= 1000) millis() + 1000; // add 1s to start immediately
{ if (millis() - batteryTaskTimer >= 1000) {
battery_voltage = analogRead(ADC_BAT) * 2 * 3300 / 4095 + 350; // 350mV ADC offset battery_voltage =
battery_percentage = constrain(map(battery_voltage, 3700, 4200, 0, 100), 0, 100); analogRead(ADC_BAT) * 2 * 3300 / 4095 + 350; // 350mV ADC offset
battery_percentage =
constrain(map(battery_voltage, 3700, 4200, 0, 100), 0, 100);
batteryTaskTimer = millis(); batteryTaskTimer = millis();
battery_ischarging = !digitalRead(CRG_STAT); battery_ischarging = !digitalRead(CRG_STAT);
// Check if battery is charging, fully charged or disconnected // Check if battery is charging, fully charged or disconnected
if (battery_ischarging || (!battery_ischarging && battery_voltage > 4350)) if (battery_ischarging || (!battery_ischarging && battery_voltage > 4350)) {
{
lv_label_set_text(objBattPercentage, ""); lv_label_set_text(objBattPercentage, "");
lv_label_set_text(objBattIcon, LV_SYMBOL_USB); lv_label_set_text(objBattIcon, LV_SYMBOL_USB);
} } else {
else
{
// Update status bar battery indicator // Update status bar battery indicator
// lv_label_set_text_fmt(objBattPercentage, "%d%%", battery_percentage); // lv_label_set_text_fmt(objBattPercentage, "%d%%", battery_percentage);
if (battery_percentage > 95) if (battery_percentage > 95)
@ -582,16 +532,18 @@ void loop()
// Keypad Handling // Keypad Handling
customKeypad.getKey(); // Populate key list customKeypad.getKey(); // Populate key list
for (int i = 0; i < LIST_MAX; i++) for (int i = 0; i < LIST_MAX;
{ // Handle multiple keys (Not really necessary in this case) i++) { // Handle multiple keys (Not really necessary in this case)
if (customKeypad.key[i].kstate == PRESSED || customKeypad.key[i].kstate == HOLD) if (customKeypad.key[i].kstate == PRESSED ||
{ customKeypad.key[i].kstate == HOLD) {
standbyTimer = SLEEP_TIMEOUT; // Reset the sleep timer when a button is pressed standbyTimer =
SLEEP_TIMEOUT; // Reset the sleep timer when a button is pressed
int keyCode = customKeypad.key[i].kcode; int keyCode = customKeypad.key[i].kcode;
Serial.println(customKeypad.key[i].kchar); Serial.println(customKeypad.key[i].kchar);
// Send IR codes depending on the current device (tabview page) // Send IR codes depending on the current device (tabview page)
if (currentDevice == 1) if (currentDevice == 1)
IrSender.sendRC5(IrSender.encodeRC5X(0x00, keyMapTechnisat[keyCode / ROWS][keyCode % ROWS])); IrSender.sendRC5(IrSender.encodeRC5X(
0x00, keyMapTechnisat[keyCode / ROWS][keyCode % ROWS]));
else if (currentDevice == 2) else if (currentDevice == 2)
IrSender.sendSony((keyCode / ROWS) * (keyCode % ROWS), 15); IrSender.sendSony((keyCode / ROWS) * (keyCode % ROWS), 15);
} }