convert notification driven battery to lvgl timer based polling

using new poller class to simplify the battery interface and
downstream usages of battery.

tweaked poller destructor and remove the default constructor
in preference of using a unique pointer

convert simulator to use a std::thread for lvgl Tick api because
the SDL thread sleep was not true to time. (and is simplified the code...)
This commit is contained in:
Matthew Colvin 2023-08-27 20:27:46 -05:00 committed by MatthewColvin
parent ae7a7d6dab
commit 65162049b3
11 changed files with 22 additions and 77 deletions

View file

@ -1,9 +0,0 @@
#include "BatteryInterface.h"
void BatteryInterface::NotifyCurrentStatus(){
mBatteryNotification.notify(getPercentage(),isCharging());
}
void BatteryInterface::onBatteryStatusChange(std::function<void(int,bool)> batteryChangeHandler){
mBatteryNotification.onNotify(std::move(batteryChangeHandler));
}

View file

@ -2,16 +2,8 @@
#include "Notification.hpp" #include "Notification.hpp"
class BatteryInterface { class BatteryInterface {
public: public:
BatteryInterface() = default; BatteryInterface() = default;
virtual int getPercentage() = 0; virtual int getPercentage() = 0;
virtual bool isCharging() = 0; virtual bool isCharging() = 0;
/// @brief Notify on Current battery status.
void NotifyCurrentStatus();
/// @brief Register Handler to be ran on battery status change
/// @param Callable to be ran on status change (percentage, IsCharging)
void onBatteryStatusChange(std::function<void(int,bool)>);
private:
Notification<int,bool> mBatteryNotification;
}; };

View file

@ -322,19 +322,7 @@ void HardwareRevX::setupIR() {
IrReceiver.enableIRIn(); // Start the receiver IrReceiver.enableIRIn(); // Start the receiver
} }
void HardwareRevX::startTasks() { void HardwareRevX::startTasks() {}
if (xTaskCreate(&HardwareRevX::updateBatteryTask, "Battery Percent Update",
1024, nullptr, 5, &batteryUpdateTskHndl) != pdPASS) {
debugPrint("ERROR Could not Create Battery Update Task!");
}
}
void HardwareRevX::updateBatteryTask(void*){
while(true){
mInstance->battery()->NotifyCurrentStatus();
vTaskDelay(5000 / portTICK_PERIOD_MS);
}
}
void HardwareRevX::loopHandler() { void HardwareRevX::loopHandler() {
standbyTimer < 2000 ? mDisplay->sleep() : mDisplay->wake(); standbyTimer < 2000 ? mDisplay->sleep() : mDisplay->wake();

View file

@ -54,10 +54,6 @@ protected:
// Tasks // Tasks
void startTasks(); void startTasks();
/// @brief Send Battery Notification every 5 Seconds
static void updateBatteryTask(void *);
TaskHandle_t batteryUpdateTskHndl = nullptr;
private: private:
HardwareRevX(); HardwareRevX();

View file

@ -9,32 +9,17 @@
#include "SDLDisplay.hpp" #include "SDLDisplay.hpp"
HardwareSimulator::HardwareSimulator(): HardwareAbstract(),
/** mTickThread([](){
* A task to measure the elapsed time for LittlevGL while(true){
* @param data unused std::this_thread::sleep_for(std::chrono::milliseconds(2));
* @return never return lv_tick_inc(2); /*Tell lvgl that 2 milliseconds were elapsed*/
*/ }})
static int tick_thread(void * data)
{ {
(void)data;
while(1) {
SDL_Delay(5); /*Sleep for 5 millisecond*/
lv_tick_inc(5); /*Tell LittelvGL that 5 milliseconds were elapsed*/
}
return 0;
}
HardwareSimulator::HardwareSimulator(): HardwareAbstract(){
/* Tick init.
* You have to call 'lv_tick_inc()' in periodically to inform LittelvGL about how much time were elapsed
* Create an SDL thread to do this*/
mBattery = std::make_shared<BatterySimulator>(); mBattery = std::make_shared<BatterySimulator>();
mDisplay = SDLDisplay::getInstance(); mDisplay = SDLDisplay::getInstance();
mWifiHandler = std::make_shared<wifiHandlerSim>(); mWifiHandler = std::make_shared<wifiHandlerSim>();
SDL_CreateThread(tick_thread, "tick", NULL);
} }
std::shared_ptr<BatteryInterface> HardwareSimulator::battery(){ std::shared_ptr<BatteryInterface> HardwareSimulator::battery(){

View file

@ -5,6 +5,8 @@
#include "SDLDisplay.hpp" #include "SDLDisplay.hpp"
#include "wifiHandlerSim.hpp" #include "wifiHandlerSim.hpp"
#include <thread>
class HardwareSimulator : public HardwareAbstract { class HardwareSimulator : public HardwareAbstract {
public: public:
HardwareSimulator(); HardwareSimulator();
@ -23,6 +25,8 @@ public:
virtual std::shared_ptr<wifiHandlerInterface> wifi() override; virtual std::shared_ptr<wifiHandlerInterface> wifi() override;
private: private:
std::thread mTickThread;
std::shared_ptr<BatterySimulator> mBattery; std::shared_ptr<BatterySimulator> mBattery;
std::shared_ptr<SDLDisplay> mDisplay; std::shared_ptr<SDLDisplay> mDisplay;
std::shared_ptr<wifiHandlerSim> mWifiHandler; std::shared_ptr<wifiHandlerSim> mWifiHandler;

View file

@ -1,17 +1,13 @@
#include "BatteryInterface.h" #include "BatteryInterface.h"
#include <chrono> #include <chrono>
#include <thread>
#include <cmath> #include <cmath>
class BatterySimulator: public BatteryInterface{ class BatterySimulator: public BatteryInterface{
public: public:
BatterySimulator() : BatterySimulator() :
mCreationTime(std::chrono::high_resolution_clock::now()), mCreationTime(std::chrono::high_resolution_clock::now())
mBattNotifier(std::thread(&BatterySimulator::batteryNotifyThread,this))
{}; {};
~BatterySimulator(){}
~BatterySimulator(){
mBattNotifier.join();
}
virtual int getPercentage() override { virtual int getPercentage() override {
auto now = std::chrono::high_resolution_clock::now(); auto now = std::chrono::high_resolution_clock::now();
auto batteryRunTime = std::chrono::duration_cast<std::chrono::seconds>(now - mCreationTime); auto batteryRunTime = std::chrono::duration_cast<std::chrono::seconds>(now - mCreationTime);
@ -20,15 +16,8 @@ class BatterySimulator: public BatteryInterface{
return std::floor(fakeBattPercentage < 100 ? fakeBattPercentage : 0); return std::floor(fakeBattPercentage < 100 ? fakeBattPercentage : 0);
} }
virtual bool isCharging() override { return true; } virtual bool isCharging() override { return false; }
private: private:
void batteryNotifyThread(){
while (true){
NotifyCurrentStatus();
std::this_thread::sleep_for(std::chrono::seconds(5));
}
}
std::chrono::_V2::system_clock::time_point mCreationTime; std::chrono::_V2::system_clock::time_point mCreationTime;
std::thread mBattNotifier;
}; };

View file

@ -116,7 +116,7 @@ void OmoteUI::create_status_bar(){
lv_obj_align(this->objBattIcon, LV_ALIGN_RIGHT_MID, 8, 0); lv_obj_align(this->objBattIcon, LV_ALIGN_RIGHT_MID, 8, 0);
lv_obj_set_style_text_font(this->objBattIcon, &lv_font_montserrat_16, LV_PART_MAIN); lv_obj_set_style_text_font(this->objBattIcon, &lv_font_montserrat_16, LV_PART_MAIN);
batteryPoller = poller([&batteryIcon = objBattIcon, battery = mHardware->battery()](){ batteryPoller = std::make_unique<poller>([&batteryIcon = objBattIcon, battery = mHardware->battery()](){
auto percent = battery->getPercentage(); auto percent = battery->getPercentage();
if(percent > 95) lv_label_set_text(batteryIcon, LV_SYMBOL_BATTERY_FULL); if(percent > 95) lv_label_set_text(batteryIcon, LV_SYMBOL_BATTERY_FULL);
else if(percent > 75) lv_label_set_text(batteryIcon, LV_SYMBOL_BATTERY_3); else if(percent > 75) lv_label_set_text(batteryIcon, LV_SYMBOL_BATTERY_3);

View file

@ -76,7 +76,7 @@ private:
static std::shared_ptr<OmoteUI> mInstance; static std::shared_ptr<OmoteUI> mInstance;
std::shared_ptr<HardwareAbstract> mHardware; std::shared_ptr<HardwareAbstract> mHardware;
poller batteryPoller; std::unique_ptr<poller> batteryPoller;
void reset_settings_menu(); void reset_settings_menu();
void attach_keyboard(lv_obj_t* textarea); void attach_keyboard(lv_obj_t* textarea);

View file

@ -13,6 +13,7 @@ poller::poller(std::function<void()> aOnPollCb, milliseconds aPollTime):mIntermi
poller::~poller(){ poller::~poller(){
if(mTimer){ if(mTimer){
lv_timer_del(mTimer); lv_timer_del(mTimer);
mTimer = nullptr;
} }
} }

View file

@ -5,7 +5,6 @@
class poller{ class poller{
public: public:
poller(){};
poller(std::function<void()> aOnPollCb, std::chrono::milliseconds pollTime = std::chrono::seconds(5)); poller(std::function<void()> aOnPollCb, std::chrono::milliseconds pollTime = std::chrono::seconds(5));
virtual ~poller(); virtual ~poller();