agrobot_base/Firmware/Modulos/BombaPressurizadoraModel.h

219 lines
6.5 KiB
C++

#include "SerialService.h"
#include "SensorPressaoModel.h"
#include "Pinout.h"
#include "Utils.h"
#include <PID_v1.h>
#ifndef BombaPressurizadoraModel
#define BombaPressurizadoraModel
class BombaPressurizadora {
public:
static void InicializarLista(std::vector<BombaPressurizadora*>& lista, const String& parametros, const String& Mod_ID, std::vector<SensorPressao*>& sensoresPressao);
BombaPressurizadora(String _modID, String _id) {
Mod_ID = _modID;
_ID = _id;
}
String Mod_ID;
String _ID;
PinoModel _pinoEN;
PinoModel _pinoCS;
PinoModel _pinoINA;
PinoModel _pinoINB;
PinoModel _pinoPWM;
int _canal = 0;
double _Kp = 3.0;
double _Ki = 2.2;
double _Kd = 0.5;
const int histerese = -5;
bool bombaDesligadaPorPressao = false;
PID* _PID = nullptr;
SensorPressao* sensorPressao;
int ZeroRampa = 0;
int RampaMax = 1023;
bool Iniciado = false;
// Consumo
Estado EstadoLeitura = Desligado;
double PotenciaLeitura = 0;
double PercentualPotenciaLeitura = 0;
// Entrada de dados
Estado _EstadoControle = Desligado;
double _PressaoSP = 0;
void Inicializar() {
if (Iniciado) {
PrintTela(_ID + " ja inicializado");
return;
}
_EstadoControle = Desligado;
_pinoEN.Conectar(_EstadoControle);
AtualizarLeitura();
_pinoCS.Conectar();
_pinoINA.Conectar(false);
_pinoINB.Conectar(true);
if (_pinoPWM.Definido()) {
ledcSetup(_canal, 1000, 10);
ledcAttachPin(_pinoPWM.num, _canal);
PotenciaLeitura = 0;
_PressaoSP = 0;
ledcWrite(_canal, _PressaoSP);
}
_PID = new PID(&sensorPressao->Pressao, &PotenciaLeitura, &_PressaoSP, _Kp, _Ki, _Kd, DIRECT);
_PID->SetOutputLimits(ZeroRampa, RampaMax);
_PID->SetMode(AUTOMATIC);
PrintTela(_ID + " Iniciado");
Iniciado = true;
}
void Desligar() {
if (!Iniciado) {
PrintTela(_ID + " nao esta inicializado");
return;
}
delete _PID;
_PID = nullptr;
// Redefinir as configurações para os valores iniciais
_pinoPWM.Desconectar();
_pinoEN.Desconectar();
_pinoCS.Desconectar();
_pinoINA.Desconectar();
_pinoINB.Desconectar();
_pinoPWM.Desconectar();
PrintTela(_ID + " Desligado");
Iniciado = false;
}
void AtualizarLeitura() {
EstadoLeitura = _pinoEN.get() == 1 ? Ligado : Desligado;
PercentualPotenciaLeitura = (PotenciaLeitura / RampaMax) * 100;
}
void AlterarStatusBomba() {
bool status = _EstadoControle == Ligado;
_pinoEN.set(status);
AtualizarLeitura();
}
void Loop() {
if (sensorPressao != nullptr) {
sensorPressao->AferirPressao();
double _PressaoAtual = sensorPressao->Pressao; // Obtém a leitura mais recente
if (Iniciado) {
// Supondo que PressaoAtual seja atualizado em AtualizarStatusSensor()
if (_PressaoAtual >= (_PressaoSP + histerese)) {
// Desliga a bomba se a pressão estiver acima do set point + histerese
bombaDesligadaPorPressao = true;
} else if (_PressaoAtual <= (_PressaoSP - histerese) && bombaDesligadaPorPressao) {
// Permite que o PID atue novamente se a pressão cair abaixo do set point - histerese
bombaDesligadaPorPressao = false;
}
if (_EstadoControle == Desligado || bombaDesligadaPorPressao) {
PotenciaLeitura = ZeroRampa;
} else {
_PID->Compute();
// Ajusta PotenciaAtual com base no PID
}
ledcWrite(_canal, PotenciaLeitura);
AtualizarLeitura();
}
}
}
};
// Função para inicializar as bombas pressurizadoras com IDs e pinos específicos
void BombaPressurizadora::InicializarLista(std::vector<BombaPressurizadora*>& lista, const String& parametros, const String& Mod_ID, std::vector<SensorPressao*>& sensoresPressao) {
// Verifica se há sensores já na lista
if (!lista.empty()) {
PrintTela("Limpando lista de bombas pressurizadoras existente...");
for (auto* sensor : lista) {
sensor->Desligar(); // Desliga cada sensor antes de remover
PrintTela("Bomba Pressurizadora " + sensor->_ID + " desligada.");
delete sensor;
}
lista.clear(); // Limpa a lista após desligar todos os itens
}
int idx = 0;
if (parametros.length() > 0) {
if (idx < sensoresPressao.size()) {
std::vector<String> _config = SplitString(parametros, SplitConfig); // Divide a configuração por *
for (const String& config : _config) {
std::vector<String> partes = SplitString(config, SplitSubParams); // Divide cada configuração pelo '~'
if (partes.size() == 13) {
String id = partes[0];
bool conectar = partes[1] == "1";
double pressaoSP = partes[2].toDouble();
TiposBarramentos enB = (TiposBarramentos)partes[3].toInt();
int pinoEN = partes[4].toInt();
TiposBarramentos csB = (TiposBarramentos)partes[5].toInt();
int pinoCS = partes[6].toInt();
TiposBarramentos inaB = (TiposBarramentos)partes[7].toInt();
int pinoINA = partes[8].toInt();
TiposBarramentos inbB = (TiposBarramentos)partes[9].toInt();
int pinoINB = partes[10].toInt();
TiposBarramentos pwmB = (TiposBarramentos)partes[11].toInt();
int pinoPWM = partes[12].toInt();
if (conectar) {
BombaPressurizadora* bomba = new BombaPressurizadora(Mod_ID, id);
bomba->_PressaoSP = pressaoSP;
bomba->_pinoEN = PinoModel(pinoEN, enB, _OUTPUT);
bomba->_pinoCS = PinoModel(pinoCS, csB, _INPUT, DIGITAL);
bomba->_pinoINA = PinoModel(pinoINA, inaB, _OUTPUT);
bomba->_pinoINB = PinoModel(pinoINB, inbB, _OUTPUT);
bomba->_pinoPWM = PinoModel(pinoPWM, pwmB, _PWM);
bomba->sensorPressao = sensoresPressao[idx];
bomba->Inicializar();
lista.push_back(bomba);
PrintTela("Bomba " + id + " inicializado com pressao SP " + String(pressaoSP) + " e sensor de pressao " + sensoresPressao[idx]->_ID);
}
} else {
PrintTela("Configuração inválida para bomba pressurizadora: " + config);
}
idx++;
}
} else {
PrintTela("Impossivel inicializar Bomba sem um sensor de pressao inicializado.");
}
} else {
PrintTela("Configuração de bomba pressurizadora não encontrada.");
}
}
#endif