#include "SerialService.h" #include "Pinout.h" #include "Utils.h" #include #ifndef SensorTemperaturaModel #define SensorTemperaturaModel class SensorTemperatura { public: static void InicializarLista(std::vector& lista, const String& parametros, const String& Mod_ID); SensorTemperatura(String _modID, String _id) { Mod_ID = _modID; _ID = _id; } // Definições String Mod_ID = ""; String _ID; int ID_Num; PinoModel _pino; double leitura = 0; double temperatura = -1; //SimpleKalmanFilter filtro = SimpleKalmanFilter(5, 15, 0.01); bool Iniciado = false; bool Checando = false; void Inicializar() { if (Iniciado) { PrintTela(_ID + " ja inicializado"); return; } leitura = 0; _pino.Conectar(); // Conecta o pino antes de criar a tarefa Iniciado = _pino.Definido(); if (Iniciado) { PrintTela(_ID + " iniciado"); } else { PrintTela(_ID + " nao iniciado"); } } void Desligar() { if (!Iniciado) { PrintTela(_ID + " nao esta inicializado"); return; } _pino.Desconectar(); // Desconecta o pino PrintTela(_ID + " Desligado"); Iniciado = false; } void AferirTemperatura() { if (Iniciado) { leitura = _pino.get(5); //leitura = filtro.updateEstimate(leitura); temperatura = CalcularTemperatura((float)leitura); } } void RequisitarDados() { AferirTemperatura(); } std::vector MontarMensagemCAN() { std::vector data; data.push_back(ID_Num); // Byte 0 - ID do sensor data.push_back(Iniciado ? 1 : 0); // Byte 1 - Status int16_t leituraInt = static_cast(round(temperatura * 100.0f)); // duas casas, com sinal data.push_back((uint8_t)(leituraInt >> 8)); // Byte 2 - parte alta data.push_back((uint8_t)(leituraInt & 0xFF)); // Byte 3 - parte baixa return data; } private: float CalcularTemperatura(float leitura, float offset = 0.0f) { const float Vs = 5.0; // Tensão de referência (divisor) const float Beta = 3950.0; // Coeficiente Beta do NTC const float To = 298.15; // 25°C em Kelvin const float Ro = 10000.0; // NTC 10k const float adcMax = 4095.0; // ADC de 12 bits if (leitura < 200) return -1.0; // ignora valores muito baixos (desconectado?) float Vout = leitura * Vs / adcMax; if (Vout <= 0.001) return -100.0; // proteção para log(0) if (Vout >= Vs) return NAN; float Rt = Ro * (Vout / (Vs - Vout)); // NTC em cima // float Rt = Ro * ((Vs - Vout) / Vout); // NTC embaixo, se for o caso float T = 1.0 / (1.0 / To + log(Rt / Ro) / Beta); float Tc = T - 273.15 + offset; return roundf(Tc * 100.0f) / 100.0f; // arredonda para 2 casas } }; // Função para inicializar os sensores de temperatura com IDs e pinos específicos void SensorTemperatura::InicializarLista(std::vector& lista, const String& parametros, const String& Mod_ID) { // Verifica se há sensores já na lista if (!lista.empty()) { PrintTela("Limpando lista de sensores de temperatura existente..."); for (auto* sensor : lista) { sensor->Desligar(); // Desliga cada sensor antes de remover PrintTela("Sensor de Temperatura " + sensor->_ID + " desligado."); delete sensor; } lista.clear(); // Limpa a lista após desligar todos os itens } if (parametros.length() > 0) { std::vector _config = SplitString(parametros, SplitConfig); // Divide a configuração por vírgulas for (const String& config : _config) { std::vector partes = SplitString(config, SplitSubParams); // Divide cada configuração pelo '-' if (partes.size() >= 4) { String id = partes[0]; bool conectar = partes[1] == "1"; TiposBarramentos pinoB = (TiposBarramentos)partes[2].toInt(); int pino = partes[3].toInt(); if (conectar) { SensorTemperatura* sensor = new SensorTemperatura(Mod_ID, id); sensor->ID_Num = lista.size(); sensor->_pino = PinoModel(pino, pinoB, _INPUT, ANALOGICO); sensor->Inicializar(); lista.push_back(sensor); PrintTela("Sensor de temperatura " + id + " inicializado no pino " + String(pino)); } } else { PrintTela("Configuração inválida para sensor de temperatura: " + config); } } } else { PrintTela("Configuração de sensor de temperatura não encontrada."); } } #endif