#pragma once #include #include "config.h" #include "thermal_controller.h" struct SensorReading { float temperatureC = NAN; float humidityPct = NAN; bool valid = false; }; void printCsvHeader() { Serial.println( F("csv_hdr,ms,target_c,avg_c,min_c,max_c,spread_c,heatlim_pct,heater_pct,fan_pct," "cutoff,failsafe,ch2_t,ch2_h,ch3_t,ch3_h,ch4_t,ch4_h,ch5_t,ch5_h")); } inline void printCsvField(float value, uint8_t decimals) { Serial.print(value, decimals); } void printCsvRow(uint32_t nowMs, const ThermalController &thermal, const SensorReading *sensors, uint8_t sensorCount, float avgTemp, float minTemp, float maxTemp) { Serial.print(F("csv,")); Serial.print(nowMs); Serial.print(','); Serial.print(thermal.target(), 1); Serial.print(','); printCsvField(avgTemp, 2); Serial.print(','); printCsvField(minTemp, 2); Serial.print(','); printCsvField(maxTemp, 2); Serial.print(','); printCsvField(thermal.cornerSpread(), 2); Serial.print(','); Serial.print(thermal.heaterAllowance(), 0); Serial.print(','); printCsvField(thermal.heaterDutyPercent(), 1); Serial.print(','); Serial.print((thermal.fanPwm() * 100) / 255); Serial.print(','); Serial.print(thermal.isCutoffActive() ? 1 : 0); Serial.print(','); Serial.print(thermal.isFailSafeActive() ? 1 : 0); for (uint8_t i = 0; i < sensorCount; ++i) { Serial.print(','); if (sensors[i].valid) { printCsvField(sensors[i].temperatureC, 2); Serial.print(','); printCsvField(sensors[i].humidityPct, 1); } else { Serial.print(','); } } Serial.println(); }