#include "SerialService.h" #include "Pinout.h" #include "Utils.h" #include "IComponenteCAN.h" #include "SensorPressaoModel_v2.h" #ifndef BombaPressurizadoraModel_v2_h #define BombaPressurizadoraModel_v2_h class BombaPressurizadora_v2 : public ComponenteCAN { public: BombaPressurizadora_v2( const String& id, uint8_t idNum, int pinoIN1, int canalIN1, int pinoIN2, int canalIN2, TiposBarramentos barramento = CONTROLADOR, Sentido sentido = Sentido::Horario, SensorPressao_v2* sensor = nullptr ) : _ID(id), ID_Num(idNum), _pinoIN1(pinoIN1, barramento, _PWM), _pinoIN2(pinoIN2, barramento, _PWM), _canalIN1(canalIN1), _canalIN2(canalIN2), _sentido(sentido), sensorPressao(sensor) { } String _ID; uint8_t ID_Num = 0; PinoModel _pinoIN1; PinoModel _pinoIN2; int _canalIN1 = 1; int _canalIN2 = 2; Sentido _sentido = Sentido::Horario; bool Iniciado = false; bool MalhaFechada = false; bool bombaDesligadaPorPressao = false; SensorPressao_v2* sensorPressao = nullptr; Estado EstadoLeitura = Estado::Desligado; double PWM_SP = 0; double PWM_Set = 0; double PercentualPotenciaLeitura = 0; Estado _EstadoControle = Estado::Desligado; double _PressaoSP = 0; double _PotenciaSP = 0; void VincularSensorPressao(SensorPressao_v2* sensor) { sensorPressao = sensor; MalhaFechada = (sensorPressao != nullptr); } void Inicializar() { if (Iniciado) { MostrarLog("Bomba ja inicializada"); return; } MalhaFechada = (sensorPressao != nullptr); _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; PWM_Set = RampaMax; PWM_SP = ZeroRampa; PercentualPotenciaLeitura = 0; EstadoLeitura = Estado::Desligado; bombaDesligadaPorPressao = false; MostrarLog(String("Bomba iniciada | malha ") + (MalhaFechada ? "fechada" : "aberta")); } else { MostrarLog("Falha ao iniciar bomba"); } } void Desligar() { if (!Iniciado) { MostrarLog("Bomba nao esta inicializada"); return; } _EstadoControle = Estado::Desligado; ledcWrite(_canalIN1, 0); ledcWrite(_canalIN2, 0); _pinoIN1.Desconectar(); _pinoIN2.Desconectar(); PWM_Set = ZeroRampa; PWM_SP = ZeroRampa; PercentualPotenciaLeitura = 0; EstadoLeitura = Estado::Desligado; bombaDesligadaPorPressao = false; Iniciado = false; MostrarLog("Bomba desligada"); } void AtualizarControle(Estado novoEstado, double potenciaSP = -1, double pressaoSP = -1) { if (!Iniciado) { MostrarLog("Ignorando comando: bomba nao iniciada"); return; } _EstadoControle = novoEstado; if (potenciaSP >= 0) { _PotenciaSP = constrain(potenciaSP, 0, 100); PWM_Set = int((_PotenciaSP / 100.0) * RampaMax); } if (pressaoSP >= 0 && MalhaFechada) { _PressaoSP = pressaoSP; } } void Loop() { if (!Iniciado) return; double pressaoAtual = 0; bool ligado = _EstadoControle == Estado::Ligado; if (ligado && MalhaFechada && sensorPressao != nullptr) { sensorPressao->RequisitarDados(); pressaoAtual = sensorPressao->Pressao; if (pressaoAtual >= (_PressaoSP + histerese)) { bombaDesligadaPorPressao = true; } else if (pressaoAtual <= (_PressaoSP - histerese)) { bombaDesligadaPorPressao = false; } } if (!ligado) { PWM_SP = ZeroRampa; } else { if (MalhaFechada) { PWM_SP = bombaDesligadaPorPressao ? ZeroRampa : PWM_Set; } else { PWM_SP = PWM_Set; } } AplicarSaida(ligado, PWM_SP); AtualizarLeitura(); } void RequisitarDados() { AtualizarLeitura(); } bool ProcessarComando(const std::vector& data) { if (data.size() < 3) { 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 = (data.size() > 3) ? (double)data[3] : -1; double pressao = (data.size() > 4) ? (double)data[4] : -1; AtualizarControle(novoEstado, potencia, pressao); 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); data.push_back(MalhaFechada ? 1 : 0); break; } case CanMessagePosicaoDados::Dados1: { AtualizarLeitura(); data.push_back(static_cast(EstadoLeitura)); data.push_back(static_cast((int)_PotenciaSP)); data.push_back(static_cast((int)PercentualPotenciaLeitura)); data.push_back(static_cast((int)_PressaoSP)); int pressaoAtual = 0; if (sensorPressao != nullptr) { pressaoAtual = (int)sensorPressao->Pressao; } data.push_back(static_cast(pressaoAtual)); break; } } return data; } private: bool DebugMode = false; int histerese = 3; 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 ? _canalIN1 : _canalIN2); PercentualPotenciaLeitura = (duty / (double)RampaMax) * 100.0; EstadoLeitura = (duty > 5) ? Estado::Ligado : Estado::Desligado; } void MostrarLog(String mensagem) { if (DebugMode) { PrintTela("[BMB " + _ID + "] " + mensagem); } } }; #endif