#include "datasave.h" #include LITTLEFSGuard::LITTLEFSGuard() { if (!LittleFS.begin(true, "/littlefs", 10, "littlefs")) { LOG_ERROR("Failed to mount LittleFS"); } else { LOG_INFO("LittleFS mounted successfully"); LOG_INFO("LittleFS Free KBytes:", (LittleFS.totalBytes() - LittleFS.usedBytes()) / 1024); } } LITTLEFSGuard::~LITTLEFSGuard() { LittleFS.end(); LOG_INFO("LittleFS unmounted successfully"); } void ignitionBoxStatusFiltered::filter(int32_t &old, const int32_t value, const uint32_t k) { float alpha = 1.0f / (float)k; old = old + (int32_t)(alpha * (float)(value - old)); } void ignitionBoxStatusFiltered::filter(float &old, const float value, const uint32_t k) { float alpha = 1.0f / (float)k; old = old + (float)(alpha * (float)(value - old)); } void ignitionBoxStatusFiltered::reset() { m_last = ignitionBoxStatus(); m_count = 0; m_data_valid = false; } void ignitionBoxStatusFiltered::update(const ignitionBoxStatus &new_status) { if (m_count == 0 && !m_data_valid) { m_last = new_status; } m_count++; // simple moving average calculation m_last.timestamp = new_status.timestamp; // keep timestamp of latest status m_last.coils12.n_events = new_status.coils12.n_events; // sum events instead of averaging m_last.coils12.n_missed_firing = new_status.coils12.n_missed_firing; // sum missed firings instead of averaging m_last.coils12.spark_status = new_status.coils12.spark_status; // take latest spark status m_last.coils12.sstart_status = new_status.coils12.sstart_status; // take latest soft start status filter(m_last.coils12.spark_delay, new_status.coils12.spark_delay, m_max_count); // incremental average calculation filter(m_last.coils12.peak_p_in, new_status.coils12.peak_p_in, m_max_count); // incremental average calculation filter(m_last.coils12.peak_n_in, new_status.coils12.peak_n_in, m_max_count); // incremental average calculation filter(m_last.coils12.peak_p_out, new_status.coils12.peak_p_out, m_max_count); // incremental average calculation filter(m_last.coils12.peak_n_out, new_status.coils12.peak_n_out, m_max_count); // incremental average calculation m_last.coils34.n_events = new_status.coils34.n_events; // sum events instead of averaging m_last.coils34.n_missed_firing = new_status.coils34.n_missed_firing; // sum missed firings instead of averaging m_last.coils34.spark_status = new_status.coils34.spark_status; // take latest spark status m_last.coils34.sstart_status = new_status.coils34.sstart_status; // take latest soft start status filter(m_last.coils34.spark_delay, new_status.coils34.spark_delay, m_max_count); // incremental average calculation filter(m_last.coils34.peak_p_in, new_status.coils34.peak_p_in, m_max_count); // incremental average calculation filter(m_last.coils34.peak_n_in, new_status.coils34.peak_n_in, m_max_count); // incremental average calculation filter(m_last.coils34.peak_p_out, new_status.coils34.peak_p_out, m_max_count); // incremental average calculation filter(m_last.coils34.peak_n_out, new_status.coils34.peak_n_out, m_max_count); // incremental average calculation filter(m_last.eng_rpm, new_status.eng_rpm, m_max_count); // incremental average calculation // incremental average calculation filter(m_last.adc_read_time, m_last.adc_read_time, m_max_count); // incremental average calculation m_last.n_queue_errors = new_status.n_queue_errors; if (m_count >= m_max_count) { m_count = 0; // reset count after reaching max samples to average m_data_valid = true; // set data valid flag after first average is calculated } } const bool ignitionBoxStatusFiltered::get(ignitionBoxStatus &status) const { if (m_data_valid) { status = m_last; } return m_data_valid; } const ArduinoJson::JsonDocument ignitionBoxStatusFiltered::toJson() const { ArduinoJson::JsonDocument doc; if (m_data_valid) { doc["timestamp"] = m_last.timestamp; doc["datavalid"] = m_data_valid ? "TRUE" : "FALSE"; doc["coils12"]["n_events"] = m_last.coils12.n_events; doc["coils12"]["n_missed_firing"] = m_last.coils12.n_missed_firing; doc["coils12"]["spark_delay"] = m_last.coils12.spark_delay; doc["coils12"]["spark_status"] = sparkStatusNames.at(m_last.coils12.spark_status); doc["coils12"]["peak_p_in"] = m_last.coils12.peak_p_in; doc["coils12"]["peak_n_in"] = m_last.coils12.peak_n_in; doc["coils12"]["peak_p_out"] = m_last.coils12.peak_p_out; doc["coils12"]["peak_n_out"] = m_last.coils12.peak_n_out; doc["coils12"]["sstart_status"] = softStartStatusNames.at(m_last.coils12.sstart_status); doc["coils34"]["n_events"] = m_last.coils34.n_events; doc["coils34"]["n_missed_firing"] = m_last.coils34.n_missed_firing; doc["coils34"]["spark_delay"] = m_last.coils34.spark_delay; doc["coils34"]["spark_status"] = sparkStatusNames.at(m_last.coils34.spark_status); doc["coils34"]["peak_p_in"] = m_last.coils34.peak_p_in; doc["coils34"]["peak_n_in"] = m_last.coils34.peak_n_in; doc["coils34"]["peak_p_out"] = m_last.coils34.peak_p_out; doc["coils34"]["peak_n_out"] = m_last.coils34.peak_n_out; doc["coils34"]["sstart_status"] = softStartStatusNames.at(m_last.coils34.sstart_status); doc["eng_rpm"] = m_last.eng_rpm; doc["adc_read_time"] = m_last.adc_read_time; doc["n_queue_errors"] = m_last.n_queue_errors; } return doc; }