#include "SerialService.h" #include "Pinout.h" #ifndef SensorFluxoModel #define SensorFluxoModel class SensorFluxo { public: static std::vector ConfigurarSensor(std::vector& lista, std::vector& data, const String& Mod_ID); SensorFluxo(String _modID, String _id) { Mod_ID = _modID; _ID = _id; } // Definições String Mod_ID = ""; String _ID; int ID_Num; PinoModel _pino; unsigned long tempoAnterior = 0; unsigned int _Pulsos = 0; unsigned long _PeriodoTotal = 0; bool ultimaLeitura = false; bool Iniciado = false; // Consumo unsigned int _PulsosLeitura = 0; unsigned long _PeriodoTotalLeitura = 0; float _Vazao = 0; void Inicializar() { if (Iniciado) { PrintTela(_ID + " ja inicializado"); return; } _pino.Conectar(); Iniciado = _pino.Definido(); if (Iniciado) { ResetarEstado(); PrintTela(_ID + " iniciado"); } else { PrintTela(_ID + " nao iniciado"); } } void Desligar() { if (!Iniciado) { PrintTela(_ID + " nao esta inicializado"); return; } // Redefinir as configurações para os valores iniciais _pino.Desconectar(); ResetarEstado(); PrintTela(_ID + " Desligado"); Iniciado = false; } void RequisitarDados() { AtualizarLeitura(); } void Loop() { if (Iniciado) { bool Leitura = _pino.get() == 1; if (Leitura != ultimaLeitura) { if (Leitura && !ultimaLeitura) { unsigned long tempoAtual = millis(); unsigned long intervalo = (unsigned long)(tempoAtual - tempoAnterior); // Garante cálculo correto tempoAnterior = tempoAtual; _Pulsos++; _PeriodoTotal += intervalo; } ultimaLeitura = Leitura; } } } std::vector MontarMensagemCAN(CanMessagePosicaoDados posicao) { std::vector data; data.push_back(ID_Num); data.push_back(static_cast(posicao)); switch (posicao) { case CanMessagePosicaoDados::Status: { data.push_back(Iniciado ? 1 : 0); break; } case CanMessagePosicaoDados::Dados1: { uint16_t vazaoEscalada = (uint16_t)(_Vazao * 100); data.push_back(vazaoEscalada >> 8); data.push_back(vazaoEscalada & 0xFF); break; } } return data; } private: void AtualizarLeitura() { if (Iniciado) { _PulsosLeitura = _Pulsos; _PeriodoTotalLeitura = _PeriodoTotal; _Vazao = CalcularVazao(_Pulsos, _PeriodoTotal); ReiniciarAmostragem(); } } // Reseta o estado do sensor void ResetarEstado() { _Pulsos = 0; _PeriodoTotal = 0; tempoAnterior = millis(); ultimaLeitura = _pino.get() == 1; } // Reinicia amostragem void ReiniciarAmostragem() { // Reseta os valores para a próxima amostragem _Pulsos = 0; _PeriodoTotal = 0; } float CalcularVazao(uint16_t pulsos, unsigned long periodoMs) { if (periodoMs == 0) return 0; float frequencia = (float)pulsos / (float)periodoMs * 1000.0; // Hz const float Rh = 0.0047; // raio interno do tubo const float Rt = 0.0037; // raio interno do rotor float vazao_m3s = frequencia * 2.0 * PI * Rh * PI * (Rt * Rt); // m³/s float vazao_ml_s = vazao_m3s * 1e6; // ml/s return vazao_ml_s; } }; std::vector SensorFluxo::ConfigurarSensor(std::vector& lista, std::vector& data, const String& Mod_ID) { std::vector status; if (data.size() < 3) return status; uint8_t idNum = data[1]; CanMessagePosicaoDados posicao = (CanMessagePosicaoDados)data[2]; switch (posicao) { case CanMessagePosicaoDados::Config1: { if (data.size() < 6) return status; bool conectar = data[4] == 1; int pino = data[5]; auto it = std::find_if(lista.begin(), lista.end(), [idNum](SensorFluxo* s) { return s->ID_Num == idNum; }); if (conectar) { if (it == lista.end()) { SensorFluxo* sensor = new SensorFluxo(Mod_ID, "sFLX_" + String(idNum)); sensor->ID_Num = idNum; sensor->_pino = PinoModel(pino, CONTROLADOR, _INPUT, DIGITAL); sensor->Inicializar(); lista.push_back(sensor); PrintTela("Sensor de Fluxo adicionado via CAN: sFLX_" + String(idNum)); status = sensor->MontarMensagemCAN(CanMessagePosicaoDados::Status); } } else { if (it != lista.end()) { SensorFluxo* sensor = *it; sensor->Desligar(); status = sensor->MontarMensagemCAN(CanMessagePosicaoDados::Status); delete sensor; lista.erase(it); PrintTela("Sensor de Fluxo removido via CAN: sFLX_" + String(idNum)); } } break; } } return status; } #endif