File PotMonitor.h¶
File List > external-docs > libDaisy > src > ui > PotMonitor.h
Go to the documentation of this file
Source Code¶
#pragma once
#include <stdint.h>
#include "UiEventQueue.h"
#include "../sys/system.h"
namespace daisy
{
template <typename BackendType, uint32_t numPots>
class PotMonitor
{
public:
PotMonitor()
: queue_(nullptr),
backend_(nullptr),
deadBand_(1.0 / (1 << 12)),
deadBandIdle_(1.0 / (1 << 10)),
timeout_(0)
{
}
void Init(UiEventQueue& queueToAddEventsTo,
BackendType& backend,
uint16_t idleTimeoutMs = 500,
float deadBandIdle = 1.0 / (1 << 10),
float deadBand = 1.0 / (1 << 12))
{
queue_ = &queueToAddEventsTo;
deadBand_ = deadBand;
backend_ = &backend;
deadBandIdle_ = deadBandIdle;
timeout_ = idleTimeoutMs;
for(uint32_t i = 0; i < numPots; i++)
{
lastValue_[i] = 0.0;
timeoutCounterMs_[i] = 0;
}
lastCallSysTime_ = System::GetNow();
}
void Process()
{
const auto now = System::GetNow();
const auto timeDiff = now - lastCallSysTime_;
lastCallSysTime_ = now;
for(uint32_t i = 0; i < numPots; i++)
ProcessPot(i, backend_->GetPotValue(i), timeDiff);
}
bool IsMoving(uint16_t potId) const
{
if(potId >= numPots)
return false;
else
return timeoutCounterMs_[potId] < timeout_;
}
float GetCurrentPotValue(uint16_t potId) const
{
if(potId >= numPots)
return -1.0f;
else
return lastValue_[potId];
}
BackendType& GetBackend() { return backend_; }
uint16_t GetNumPotsMonitored() const { return numPots; }
private:
void ProcessPot(uint16_t id, float value, uint32_t timeDiffMs)
{
// currently moving?
if(timeoutCounterMs_[id] < timeout_)
{
// check if pot has left the deadband. If so, add a new message
// to the queue.
float delta = lastValue_[id] - value;
if((delta > deadBand_) || (delta < -deadBand_))
{
lastValue_[id] = value;
queue_->AddPotMoved(id, value);
timeoutCounterMs_[id] = 0;
}
// no movement, increment timeout counter
else
{
timeoutCounterMs_[id] += timeDiffMs;
// post activity changed event after timeout expired.
if(timeoutCounterMs_[id] == timeout_)
{
queue_->AddPotActivityChanged(id, false);
}
}
}
// not moving right now
else
{
// check if pot has left the idle deadband. If so, add a new message
// to the queue and restart the timeout
float delta = lastValue_[id] - value;
if((delta > deadBandIdle_) || (delta < -deadBandIdle_))
{
lastValue_[id] = value;
queue_->AddPotActivityChanged(id, true);
queue_->AddPotMoved(id, value);
timeoutCounterMs_[id] = 0;
}
}
}
PotMonitor(const PotMonitor&) = delete;
PotMonitor& operator=(const PotMonitor&) = delete;
UiEventQueue* queue_;
BackendType* backend_;
float deadBand_;
float deadBandIdle_;
uint16_t timeout_;
float lastValue_[numPots];
uint16_t timeoutCounterMs_[numPots];
uint32_t lastCallSysTime_;
};
} // namespace daisy