92 lines
3.2 KiB
C++
92 lines
3.2 KiB
C++
#include "pwmclass.h"
|
|
#include "fifo.h"
|
|
#include "player.h"
|
|
#include "GsmDecoder.h"
|
|
#include "oneway.h"
|
|
#include "gpio.h"
|
|
#include "adc.h"
|
|
#include "spline.h"
|
|
////////////////////////////////////////////////////////
|
|
/* Skutečně měří teplotu NTC termistorem. Výstup je PWM
|
|
* na pinu PA2 24kHz, enable PB1. Odvozeno z teploměru na
|
|
* https://github.com/Kizarm/TTSCP_Client/tree/main/kecal/stm
|
|
*/
|
|
////////////////////////////////////////////////////////
|
|
static constexpr Pair measured [] = { // pár hodnota ADC, teplota ve °C
|
|
{ +133.9, 125.000 },
|
|
{ +152.2, 120.000 },
|
|
{ +198.3, 110.000 },
|
|
{ +260.0, 100.000 },
|
|
{ +343.6, 90.000 },
|
|
{ +456.9, 80.000 },
|
|
{ +609.9, 70.000 },
|
|
{ +814.5, 60.000 },
|
|
{ +1082.6, 50.000 },
|
|
{ +1421.2, 40.000 },
|
|
{ +2047.5, 25.000 },
|
|
{ +2729.0, 10.000 },
|
|
{ +3139.8, 0.000 },
|
|
{ +3472.7, -10.000 },
|
|
{ +3715.6, -20.000 },
|
|
{ +3876.9, -30.000 },
|
|
{ +3960.2, -38.000 },
|
|
{ +3976.0, -40.000 },
|
|
};
|
|
class Average : public OneWay<uint16_t> {
|
|
FIFO<uint32_t, FIFOLEN> & ring;
|
|
uint32_t y, w;
|
|
public:
|
|
explicit Average (FIFO<uint32_t, FIFOLEN> & r) : OneWay(), ring(r), y(0u), w(0u) {}
|
|
unsigned int Send(uint16_t * const ptr, const unsigned int len) override {
|
|
unsigned suma = 0u;
|
|
for (unsigned n=0u; n<len; n++) {
|
|
suma += ptr [n];
|
|
}
|
|
y += suma - w; // ustálení teploty trvá dost dlouho, takže lze posílat klouzavý
|
|
w = y >> 4; // průměr s postupným zapomínáním. Hodnota je násobena délkou
|
|
// bufferu, t.j. 128 (posun doleva o 7)
|
|
if (w < (134 * 128)) return len; // skip limits - nezobrazuj mimo rozsah -40 až 120
|
|
if (w > (3976 * 128)) return len;
|
|
ring.Write (w);
|
|
return len;
|
|
}
|
|
};
|
|
static unsigned abs_diff (const int a, const int b) {
|
|
const int d = a - b;
|
|
return d > 0 ? +d : -d;
|
|
}
|
|
////////////////////////////////////////////////////////
|
|
static GpioClass led (GPIOB, 8u);
|
|
static PwmClass pwm;
|
|
static FIFO<uint32_t, FIFOLEN> fifo;
|
|
static TextPlayer player (fifo, led);
|
|
static GsmDecoder decoder(fifo);
|
|
|
|
static GpioClass button (GPIOA, 0u, (GPIO_Speed_In | GPIO_UPDI_MPPO));
|
|
static FIFO<uint32_t, FIFOLEN> avgring;
|
|
static AdcDma adc;
|
|
static Average avg (avgring);
|
|
static const SPLINE<array_size(measured)> spline (measured, false);
|
|
|
|
int main () {
|
|
led << true;
|
|
pwm.attach (decoder);
|
|
adc.attach (avg);
|
|
int old_value = 0;
|
|
uint32_t average;
|
|
for (;;) {
|
|
if (avgring.Read(average)) {
|
|
// average je de facto posunuta doleva o 7, potřebujeme o 16 - rozdíl je tedy 9
|
|
const int32_t ivalue = static_cast<int32_t>(average << 9);
|
|
const real rt = spline.interpolate(real(ivalue));
|
|
const int temperature = 100 * rt.x >> 16;
|
|
const unsigned delta = abs_diff (temperature, old_value);
|
|
if (delta >= 50u or !button) {
|
|
old_value = temperature;
|
|
player.say(old_value, 2); // s rozlišením na setiny
|
|
player.say(sayed_texts.units);
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|