#include "SerialService.h" #include "Pinout.h" #include "Utils.h" #include "IComponenteCAN.h" #ifndef AgitadorCalda_h #define AgitadorCalda_h class AgitadorCalda : public ComponenteCAN { public: AgitadorCalda( const String& id, uint8_t idNum, int pinoIN1, int canalIN1, int pinoIN2, int canalIN2, TiposBarramentos barramento = CONTROLADOR, Sentido sentido = Sentido::Horario ) : _ID(id), ID_Num(idNum), _pinoIN1(pinoIN1, barramento, _PWM), _pinoIN2(pinoIN2, barramento, _PWM), _canalIN1(canalIN1), _canalIN2(canalIN2), _sentido(sentido) { } String _ID; uint8_t ID_Num = 0; PinoModel _pinoIN1; PinoModel _pinoIN2; int _canalIN1 = 1; int _canalIN2 = 2; Sentido _sentido = Sentido::Horario; bool Iniciado = false; Estado EstadoLeitura = Estado::Desligado; double PercentualPotenciaLeitura = 0; Estado _EstadoControle = Estado::Desligado; double _PotenciaSP = 0; void Inicializar() { if (Iniciado) { MostrarLog("Agitador ja inicializado"); return; } _pinoIN1.Conectar(0); if (_pinoIN1.Definido()) { ledcSetup(_canalIN1, 1000, 10); ledcAttachPin(_pinoIN1.num, _canalIN1); ledcWrite(_canalIN1, 0); } _pinoIN2.Conectar(0); if (_pinoIN2.Definido()) { ledcSetup(_canalIN2, 1000, 10); ledcAttachPin(_pinoIN2.num, _canalIN2); ledcWrite(_canalIN2, 0); } Iniciado = _pinoIN1.Definido() && _pinoIN2.Definido(); if (Iniciado) { _EstadoControle = Estado::Desligado; PercentualPotenciaLeitura = 0; EstadoLeitura = Estado::Desligado; MostrarLog("Agitador de calda iniciado"); } else { MostrarLog("Falha ao iniciar agitador"); } } void Desligar() { if (!Iniciado) { MostrarLog("Agitador nao esta inicializado"); return; } _EstadoControle = Estado::Desligado; ledcWrite(_canalIN1, 0); ledcWrite(_canalIN2, 0); _pinoIN1.Desconectar(); _pinoIN2.Desconectar(); PercentualPotenciaLeitura = 0; EstadoLeitura = Estado::Desligado; Iniciado = false; MostrarLog("Agitador desligado"); } void AtualizarControle(Estado novoEstado, double potenciaSP) { if (!Iniciado) { MostrarLog("Ignorando comando: agitador nao iniciado"); return; } _EstadoControle = novoEstado; _PotenciaSP = potenciaSP; if (_EstadoControle == Estado::Desligado) { AplicarSaida(false, 0); } else { int pwm = int((_PotenciaSP / 100.0) * RampaMax); AplicarSaida(true, pwm); } AtualizarLeitura(); } void RequisitarDados() { AtualizarLeitura(); } bool ProcessarComando(const std::vector& data) { if (data.size() < 4) { MostrarLog("Comando invalido"); return false; } CanMessagePosicaoDados posicao = (CanMessagePosicaoDados)data[0]; uint8_t idNum = data[1]; if (idNum != ID_Num) { return false; } switch (posicao) { case CanMessagePosicaoDados::Command1: { Estado novoEstado = (Estado)data[2]; double potencia = (double)data[3]; AtualizarControle(novoEstado, potencia); return true; } default: return false; } } 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: { AtualizarLeitura(); data.push_back(static_cast(EstadoLeitura)); data.push_back(static_cast((int)PercentualPotenciaLeitura)); break; } } return data; } private: bool DebugMode = false; int ZeroRampa = 0; int RampaMax = 1023; void AplicarSaida(bool ligado, int pwm) { if (!Iniciado && pwm != 0) return; if (!ligado) { pwm = 0; } pwm = LimitarPWM(pwm); ledcWrite(_canalIN1, _sentido == Sentido::Horario ? pwm : 0); ledcWrite(_canalIN2, _sentido == Sentido::Horario ? 0 : pwm); } int LimitarPWM(int valor) { if (valor < ZeroRampa) return ZeroRampa; if (valor > RampaMax) return RampaMax; return valor; } void AtualizarLeitura() { if (!Iniciado) return; uint32_t duty = ledcRead(_sentido == Sentido::Horario ? _pinoIN1.num : _pinoIN2.num); PercentualPotenciaLeitura = (duty / (double)RampaMax) * 100.0; EstadoLeitura = (duty > 5) ? Estado::Ligado : Estado::Desligado; } void MostrarLog(String mensagem) { if (DebugMode) { PrintTela("[AGT " + _ID + "] " + mensagem); } } }; #endif