#include "SerialService.h" #include "Pinout.h" #include "Utils.h" #ifndef SinaleiroModel #define SinaleiroModel class Sinaleiro { public: static std::vector ConfigurarSinaleiro(std::vector& lista, std::vector& data, const String& Mod_ID); static void ComandarSinaleiro(std::vector& lista, std::vector& data, uint8_t& id); Sinaleiro(String _modID, String _id, int _taxaAmostragem = 2000) { Mod_ID = _modID; _ID = _id; } String Mod_ID; String _ID; int ID_Num; PinoModel _pino; bool Iniciado = false; StatusLED _Status = Apagado; StatusLED _StatusLeitura = Apagado; int _Qtd = 0; int _TempoMs = 0; int _PausaMs = 0; void Inicializar() { if (Iniciado) { PrintTela(_ID + " ja inicializado"); return; } _pino.Conectar(false); Iniciado = _pino.Definido(); if (Iniciado) { xTaskCreatePinnedToCore(&Sinaleiro::LEDTaskWrapper, "LEDTask", 5000, this, 6, &LEDTaskHandle, tskNO_AFFINITY); PrintTela(_ID + " Iniciado"); } else { PrintTela(_ID + " nao Iniciado"); } } void Desligar() { if (!Iniciado) { PrintTela(_ID + " nao esta inicializado"); return; } // Parar a execução das tarefas vTaskDelete(LEDTaskHandle); // Redefinir as configurações para os valores iniciais _pino.Desconectar(); PrintTela(_ID + " Desligado"); Iniciado = false; } void AtualizarLeitura() { if (Iniciado) { _StatusLeitura = (StatusLED)_pino.get(); } } void RequisitarDados() { AtualizarLeitura(); } 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: { data.push_back(static_cast(_StatusLeitura)); data.push_back(static_cast(_Status)); break; } } return data; } private: TaskHandle_t LEDTaskHandle = NULL; static void LEDTaskWrapper(void *pvParameters) { Sinaleiro *led = static_cast(pvParameters); led->LEDTask(); } void LEDTask() { unsigned long lastMillis = millis(); bool ledState = false; int piscadasAtual = 0; bool emPausa = false; while (1) { unsigned long currentMillis = millis(); if (_Status != Piscando) { _pino.set(_Status == Aceso); //_StatusLeitura = (StatusLED)_pino.get(); } else if (_Status == Piscando && piscadasAtual < _Qtd) { if (!emPausa && (currentMillis - lastMillis >= _TempoMs)) { ledState = !ledState; _pino.set(ledState); lastMillis = currentMillis; if (!ledState) { // Se o LED acabou de ser desligado, incrementa o contador de piscadas piscadasAtual++; } } else if (emPausa && (currentMillis - lastMillis >= _PausaMs)) { emPausa = false; lastMillis = currentMillis; } } else if (piscadasAtual >= _Qtd) { // Se alcançou a quantidade desejada de piscadas, entra em pausa if (!emPausa) { ledState = false; _pino.set(false); // Garante que o LED está desligado emPausa = true; piscadasAtual = 0; // Reseta o contador de piscadas lastMillis = currentMillis; } } vTaskDelay(1); // Pequena pausa para liberar o CPU } } }; std::vector Sinaleiro::ConfigurarSinaleiro(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() < 7) return status; bool conectar = data[4] == 1; TiposBarramentos tipoBarramento = (TiposBarramentos)data[5]; int pino = data[6]; auto it = std::find_if(lista.begin(), lista.end(), [idNum](Sinaleiro* s) { return s->ID_Num == idNum; }); if (conectar) { if (it == lista.end()) { Sinaleiro* sensor = new Sinaleiro(Mod_ID, "sLED_" + String(idNum)); sensor->ID_Num = idNum; sensor->_pino = PinoModel(pino, tipoBarramento, _OUTPUT); sensor->Inicializar(); lista.push_back(sensor); PrintTela("Sinaleiro adicionado via CAN: sLED_" + String(idNum)); status = sensor->MontarMensagemCAN(CanMessagePosicaoDados::Status); } } else { if (it != lista.end()) { Sinaleiro* sensor = *it; sensor->Desligar(); status = sensor->MontarMensagemCAN(CanMessagePosicaoDados::Status); delete sensor; lista.erase(it); PrintTela("Sinaleiro removido via CAN: sLED_" + String(idNum)); } } break; } } return status; } void Sinaleiro::ComandarSinaleiro(std::vector& lista, std::vector& data, uint8_t& id) { if (data.size() < 7) return; for (auto* _led : lista) { if (_led->ID_Num == id) { _led->_Status = (StatusLED)data[3]; _led->_Qtd = data[4]; _led->_TempoMs = (uint16_t)data[5] * 10; _led->_PausaMs = (uint16_t)data[6] * 10; return; } } } #endif