#pragma once // C++ system level #include <vector> // #include <cstring> // memset, strncmp // #include <cstdlib> // TODO: is this for memcpy? // #include <functional> // ESP32 specific #include "esp_log.h" #include "driver/ledc.h" // project specific #include <SpiderLib.hpp> #include "Service.hpp" #include "../Hardware/MAX31856.hpp" // qthing stuff #include "SiliconTorch/FxCyanRGB8.hpp" // #include <qthing> // misc #include <nlohmann/json.hpp> namespace SiliconTorch { namespace Service { namespace SpiderFurnace { constexpr u8 PWM_BITS = 12; constexpr u32 PWM_FREQ = 10000; // Hz constexpr u8 TICK_FREQ = 10; // Hz constexpr u8 SlidingWindowLength = 8; constexpr f32 MaxTempChangePerSecond = 1000; // K // TODO: formally set to 100 but triggers too often?! constexpr f32 MAX_TEMP = 1320.0f; // °C constexpr f32 MAX_PWM = 0.5f; // p% // TODO: Make configurable" constexpr u8 IO_CS = 26; constexpr u8 IO_MISO = 17; constexpr u8 IO_MOSI = 16; constexpr u8 IO_SCLK = 27; constexpr u8 IO_HEATER = 25; // enum FurnaceState { // RUNNING, // PAUSED, // STOPPED // }; // TODO: ??? // Compile-time config constexpr bool CFG_EN_PIDTask = false; // !! constexpr bool CFG_EN_MQTT_PIDvals = true; class SpiderFurnace : public ServiceManager::Service, public SpiderLib::HasMQTT { public: void init(); void start(); virtual nlohmann::json getConfigJSON() const; bool hasFault() const; f32 temperature() const; void setTargetTemperature(f32 t); // TODO: should we block copy/assignment by default…? SpiderFurnace() {}; SpiderFurnace(const SpiderFurnace&) = delete; SpiderFurnace& operator=(SpiderFurnace const&) = delete; private: f32 kP = 0.0f; f32 kI = 0.0f; f32 kD = 0.0f; f32 targetTemperature = 0.0f; // FurnaceState state = RUNNING; ledc_channel_t pwmCh; MAX31856::SR faultReg; u64 tc0age = 0; // ms MAX31856::MAX31856* tc0; SlidingWindow<f32>* tc0dat = new SlidingWindow<f32>(SlidingWindowLength); SpiderLib::Util::LambdaTask* pidTask = NULL; f32 pwmVal = 0.0f; void setPWM(f32 value); }; } } }