#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 { FIFO & ring; uint32_t y, w; public: explicit Average (FIFO & 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> 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 fifo; static TextPlayer player (fifo, led); static GsmDecoder decoder(fifo); static GpioClass button (GPIOA, 0u, (GPIO_Speed_In | GPIO_UPDI_MPPO)); static FIFO avgring; static AdcDma adc; static Average avg (avgring); static const SPLINE 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(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; }