#include "SerialService.h" #include "Pinout.h" #include "Utils.h" #include "IComponenteCAN.h" #ifndef SensorChaveBotaoModel #define SensorChaveBotaoModel class SensorChaveBotao : public ComponenteCAN { public: String ID; uint8_t ID_Num = 0; PinoModel _pino; bool Iniciado = false; // Leitura bruta do pino bool LeituraBruta = false; // Resultado final já considerando inversão e debounce bool Pressionado = false; // Estado anterior estável bool PressionadoAnterior = false; // Flag útil para detectar borda bool MudouEstado = false; // Configuração bool InverterLogica = true; bool UsarDebounce = true; unsigned long TempoDebounceMs = 50; SensorChaveBotao() {} SensorChaveBotao( const String& id, uint8_t idNum, int pino, TiposBarramentos tipoBarramento, int canalMux = -1, bool inverterLogica = true, bool usarDebounce = true, unsigned long tempoDebounceMs = 50 ) : ID(id), ID_Num(idNum), _pino(PinoModel(pino, tipoBarramento, _INPUT_PULLUP, DIGITAL, idNum, canalMux)), InverterLogica(inverterLogica), UsarDebounce(usarDebounce), TempoDebounceMs(tempoDebounceMs) { } void Inicializar() { if (Iniciado) { MostrarLog("Sensor ja inicializado"); return; } LeituraBruta = false; Pressionado = false; PressionadoAnterior = false; MudouEstado = false; ultimaLeituraTratada = false; ultimaLeituraInstavel = false; ultimoTempoMudanca = 0; _pino.Conectar(); Iniciado = _pino.Definido(); if (Iniciado) { RequisitarDados(); } MostrarLog(Iniciado ? "Sensor iniciado" : "Sensor nao iniciado"); } void Desligar() { if (!Iniciado) { MostrarLog("Sensor nao esta inicializado"); return; } _pino.Desconectar(); Iniciado = false; LeituraBruta = false; Pressionado = false; PressionadoAnterior = false; MudouEstado = false; MostrarLog("Sensor desligado"); } void RequisitarDados() { if (!Iniciado) return; AferirEstado(); } 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: { RequisitarDados(); data.push_back(Pressionado ? 1 : 0); data.push_back(LeituraBruta ? 1 : 0); data.push_back(MudouEstado ? 1 : 0); break; } } return data; } private: bool DebugMode = false; bool ultimaLeituraTratada = false; bool ultimaLeituraInstavel = false; unsigned long ultimoTempoMudanca = 0; void MostrarLog(String mensagem) { if (DebugMode) { PrintTela("[BTN " + ID + "] " + mensagem); } } void AferirEstado() { int leituraDigital = _pino.get(1); LeituraBruta = leituraDigital > 0; bool leituraTratada = InverterLogica ? !LeituraBruta : LeituraBruta; if (!UsarDebounce) { PressionadoAnterior = Pressionado; Pressionado = leituraTratada; MudouEstado = (Pressionado != PressionadoAnterior); return; } unsigned long agora = millis(); if (leituraTratada != ultimaLeituraInstavel) { ultimaLeituraInstavel = leituraTratada; ultimoTempoMudanca = agora; } if ((agora - ultimoTempoMudanca) >= TempoDebounceMs) { if (ultimaLeituraInstavel != ultimaLeituraTratada) { ultimaLeituraTratada = ultimaLeituraInstavel; PressionadoAnterior = Pressionado; Pressionado = ultimaLeituraTratada; MudouEstado = (Pressionado != PressionadoAnterior); } else { MudouEstado = false; } } else { MudouEstado = false; } MostrarLog("Bruto: " + String(LeituraBruta ? 1 : 0) + ", Pressionado: " + String(Pressionado ? 1 : 0) + ", Mudou: " + String(MudouEstado ? 1 : 0)); } }; #endif