#include "SerialService.h" #include "Pinout.h" #include "Utils.h" #include "IComponenteCAN.h" #ifndef SinaleiroModel #define SinaleiroModel class Sinaleiro : public ComponenteCAN { public: 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; int _StatusID = 99; StatusLED _Status = Apagado; StatusLED _StatusLeitura = Apagado; int _Qtd = 0; int _TempoMs = 0; int _PausaMs = 0; void Inicializar() { if (Iniciado) { MostrarLog("Sinaleiro ja inicializado"); return; } _pino.Conectar(false); Iniciado = _pino.Definido(); if (Iniciado) { xTaskCreatePinnedToCore(&Sinaleiro::LEDTaskWrapper, "LEDTask", 5000, this, 1, &LEDTaskHandle, tskNO_AFFINITY); MostrarLog("Sinaleiro Iniciado"); } else { MostrarLog("Sinaleiro nao Iniciado"); } } void Desligar() { if (!Iniciado) { MostrarLog("Sinaleiro nao esta inicializado"); return; } // Parar a execução das tarefas vTaskDelete(LEDTaskHandle); // Redefinir as configurações para os valores iniciais _pino.Desconectar(); MostrarLog("Sinaleiro 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(static_cast(posicao)); data.push_back(ID_Num); switch (posicao) { case CanMessagePosicaoDados::Status: { data.push_back(Iniciado ? 1 : 0); break; } case CanMessagePosicaoDados::Dados1: { data.push_back(static_cast(_StatusID)); data.push_back(static_cast(_StatusLeitura)); break; } } return data; } static std::vector ConfigurarSinaleiro(std::vector& lista, std::vector& data, const String& Mod_ID) { std::vector status; if (data.size() < 2) return status; CanMessagePosicaoDados posicao = (CanMessagePosicaoDados)data[0]; uint8_t idNum = data[1]; auto it = std::find_if(lista.begin(), lista.end(), [idNum](Sinaleiro* s) { return s->ID_Num == idNum; }); bool jaExiste = it != lista.end(); Sinaleiro* sensor; switch (posicao) { case CanMessagePosicaoDados::Config1: { if (data.size() < 6) return status; bool conectar = data[3] == 1; TiposBarramentos tipoBarramento = (TiposBarramentos)data[4]; int pino = data[5]; if (conectar) { if (!jaExiste) { sensor = new Sinaleiro(Mod_ID, "sLED_" + String(idNum)); } else { sensor = *it; } if (!sensor->Iniciado) { sensor->ID_Num = idNum; sensor->_pino = PinoModel(pino, tipoBarramento, _OUTPUT); sensor->Inicializar(); if (!jaExiste) { lista.push_back(sensor); sensor->MostrarLog("Sinaleiro adicionado via CAN: sLED_" + String(idNum)); } } status = sensor->MontarMensagemCAN(CanMessagePosicaoDados::Status); } else { if (jaExiste) { sensor = *it; sensor->Desligar(); status = sensor->MontarMensagemCAN(CanMessagePosicaoDados::Status); sensor->MostrarLog("Sinaleiro removido via CAN: sLED_" + String(idNum)); delete sensor; lista.erase(it); } } break; } } return status; } static void ComandarSinaleiro(std::vector& lista, std::vector& data) { if (data.size() < 7) return; CanMessagePosicaoDados posicao = (CanMessagePosicaoDados)data[0]; uint8_t idNum = data[1]; for (auto* _led : lista) { if (_led->ID_Num == idNum) { switch (posicao) { case CanMessagePosicaoDados::Command1: { int statusId = data[2]; StatusLED novoStatus = (StatusLED)data[3]; int novaQtd = data[4]; uint16_t novoTempo = (uint16_t)data[5] * 10; uint16_t novaPausa = (uint16_t)data[6] * 10; _led->_StatusID = statusId; _led->_Status = novoStatus; _led->_Qtd = novaQtd; _led->_TempoMs = novoTempo; _led->_PausaMs = novaPausa; break; } } return; } } } private: bool DebugMode = false; void MostrarLog(String mensagem) { if (DebugMode) { PrintTela("[LED " + _ID + "]" + mensagem); } } 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 } } }; #endif