67 lines
1.6 KiB
C++
67 lines
1.6 KiB
C++
#include "controller.hpp"
|
|
|
|
#define ADC_INT_VECTOR
|
|
#include "adc/adc.hpp"
|
|
|
|
double Controller::m_adcSample;
|
|
double Controller::m_resistance;
|
|
double Controller::m_temperature;
|
|
uint8_t Controller::m_fanSpeed;
|
|
bool Controller::m_dataAvailable = false;
|
|
|
|
volatile uint32_t Controller::m_adcSampleSum;
|
|
volatile bool Controller::m_adcSampleReady = false;
|
|
|
|
void Controller::init()
|
|
{
|
|
m_adcPin.init(sampleCallback);
|
|
pwm::init();
|
|
pwm::setDuty(100);
|
|
}
|
|
|
|
void Controller::callback()
|
|
{
|
|
if (m_adcSampleReady) {
|
|
m_adcSample = static_cast<double>(m_adcSampleSum) / NUM_ADC_SAMPLES;
|
|
m_dataAvailable = true;
|
|
m_adcSampleReady = false;
|
|
|
|
m_resistance = m_thermistor.getResistance(m_adcSample);
|
|
m_temperature = m_thermistor.getTemperature(m_resistance);
|
|
m_fanSpeed = mapTemperature(m_temperature);
|
|
|
|
pwm::setDuty(m_fanSpeed);
|
|
}
|
|
}
|
|
|
|
uint8_t Controller::mapTemperature(double temperature)
|
|
{
|
|
[[maybe_unused]] constexpr auto linearCurve = [](double x) { return (10 * x - 200) / 3; };
|
|
constexpr auto cubicCurve = [](double x) {
|
|
if (x < 20)
|
|
return 0.0;
|
|
return 0.002246 * x * x * x - 0.09 * x * x + 0.91 * x;
|
|
};
|
|
|
|
double fanSpeed = cubicCurve(temperature);
|
|
return clamp<uint8_t>(fanSpeed, 0, 100);
|
|
}
|
|
|
|
void Controller::sampleCallback(const uint16_t &adcSample)
|
|
{
|
|
static uint32_t s_sampleSum = 0;
|
|
static auto s_sampleCounter = NUM_ADC_SAMPLES;
|
|
|
|
s_sampleSum += adcSample;
|
|
|
|
if (--s_sampleCounter <= 0) {
|
|
if (!m_adcSampleReady) {
|
|
m_adcSampleSum = s_sampleSum;
|
|
m_adcSampleReady = true;
|
|
}
|
|
// else lose this sample, which happens during long running commands like "curve", but has no impact
|
|
s_sampleSum = 0;
|
|
s_sampleCounter = NUM_ADC_SAMPLES;
|
|
}
|
|
}
|