agrobot_base/Firmware/Modulos/Atuador/Atuador.ino

330 lines
9.2 KiB
Arduino
Raw Normal View History

2024-01-03 10:52:37 +00:00
// Dispositivo: Atuador
// Versão Firmware: 8
// Ultima atualização: 29/11/2024
// Atualização: Implementado MQTT
#include <ArduinoJson.h>
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\MqttService.h"
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\WifiService.h"
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\EepromService.h"
2024-01-23 17:10:34 +00:00
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SerialService.h"
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\Utils.h"
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\Pinout.h"
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\ReleModel.h"
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\BombaPressurizadoraModel.h"
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SensorFluxoModel.h"
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SensorMassaModel.h"
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SensorPressaoModel.h"
2024-01-03 10:52:37 +00:00
// Configurações do IP estático
IPAddress local_IP(192, 168, String(WIFI_FAIXA).toInt(), 13); // IP fixo para o ESP
IPAddress gateway(192, 168, String(WIFI_FAIXA).toInt(), 1); // Gateway padrão
IPAddress subnet(255, 255, 255, 0); // Máscara de sub-rede
IPAddress primaryDNS(8, 8, 8, 8); // Servidor DNS primário (opcional)
// Instancia o serviço MQTT
MqttService mqttService;
#define D_Code Atu
#define VERSION 8
const String Mod_ID = "Atu";
2024-01-03 10:52:37 +00:00
#define _pinoLED RGB_BUILTIN
long _baudRate = 115200;
bool Conectado = false;
bool Verificando = false;
int _TaxaAmostragem = 1000;
volatile bool RequisitarDados = false;
int latenciaLoop = 0;
std::vector<Rele*> listaBicos;
std::vector<BombaPressurizadora*> listaBombas;
std::vector<SensorFluxo*> listaSensoresFluxo;
std::vector<SensorMassa*> listaSensoresMassa;
std::vector<SensorPressao*> listaSensoresPressao;
void InicializarComunicacaoMQTT(bool RenovarConexao) {
if (RenovarConexao) {
mqttService.unsubscribe(TopicoRecepcao);
delay(1000);
}
mqttService.setModID(Mod_ID);
mqttService.InicializarComunicacaoMqtt();
mqttService.setMessageCallback(ProcessarProtocolo);
}
2024-01-03 10:52:37 +00:00
void setup() {
Serial.begin(_baudRate);
InicializarConexaoWifi(local_IP, gateway, subnet, primaryDNS);
if (!WifiIsConnected) {
connectToWiFi();
if (WifiIsConnected) {
PrintTela("Conectado com sucesso");
}
else {
PrintTela("Erro ao se conectar ao wifi");
ESP.restart();
}
}
delay(100);
if (WifiIsConnected) {
InicializarComunicacaoMQTT(false);
}
}
void loop() {
unsigned long startLoop = millis();
if (!RequisitarDados) {
enviarLogsPeriodicamente();
}
mqttService.loop();
for (auto* bomba : listaBombas) {
bomba->Loop();
}
for (auto* sensor : listaSensoresFluxo) {
sensor->Loop();
}
delay(1);
latenciaLoop = millis() - startLoop;
}
// Função para enviar logs do sensor periodicamente via MQTT
unsigned long ultimoEnvioLogs = 0;
const unsigned long intervaloEnvioLogs = 1000; // 1 segundo
void enviarLogsPeriodicamente() {
unsigned long tempoAtual = millis();
// Verifica se o intervalo de 5 segundos já passou
if (tempoAtual - ultimoEnvioLogs >= intervaloEnvioLogs) {
ultimoEnvioLogs = tempoAtual; // Atualiza o tempo do último envio
enviarDadosSensores(); // Chama o método que já envia os dados do sensor via MQTT
}
}
void enviarDadosSensores() {
if (Conectado && !Verificando) {
PrintTela("Atualizando dados dos sensores...");
// Aferir dados dos sensores
for (auto* bico : listaBicos) {
bico->AtualizarLeitura();
}
// Aferir dados dos sensores
for (auto* sensor : listaSensoresFluxo) {
sensor->AtualizarLeitura();
}
// Aferir dados dos sensores
for (auto* sensor : listaSensoresMassa) {
sensor->RequisitarDados();
}
// Aferir dados dos sensores
for (auto* sensor : listaSensoresPressao) {
sensor->RequisitarDados();
}
String jsonString = MontarMensagemSensores() + String(EndLine);
mqttService.EnviarDados(Mod_ID, jsonString);
}
}
String MontarMensagemSensores() {
// Criação de um objeto JSON dinâmico com tamanho adequado
DynamicJsonDocument jsonDoc(2048);
// Adicionar campos gerais
jsonDoc["Conectado"] = Conectado;
jsonDoc["Mod_ID"] = Mod_ID;
jsonDoc["QualidadeWifi"] = WiFi.RSSI();
jsonDoc["LatenciaLoop"] = latenciaLoop;
// Array JSON para bicos pulverizadores
JsonArray bicosArray = jsonDoc.createNestedArray("BicosPulverizadores");
for (const auto* sensor : listaBicos) {
JsonObject sensorData = bicosArray.createNestedObject();
sensorData["Id"] = sensor->_ID;
sensorData["Iniciado"] = sensor->Iniciado;
sensorData["Leitura"] = sensor->_Status;
}
2024-01-03 10:52:37 +00:00
// Array JSON para bombas pressurizadoras
JsonArray bombasArray = jsonDoc.createNestedArray("BombasPressurizadoras");
for (const auto* sensor : listaBombas) {
JsonObject sensorData = bombasArray.createNestedObject();
sensorData["Id"] = sensor->_ID;
sensorData["Iniciado"] = sensor->Iniciado;
sensorData["Estado"] = sensor->EstadoLeitura;
sensorData["Potencia"] = sensor->PercentualPotenciaLeitura;
sensorData["PressaoSP"] = sensor->_PressaoSP;
sensorData["Pressao"] = sensor->sensorPressao->Pressao;
}
2024-01-03 10:52:37 +00:00
// Array JSON para sensores de fluxo
JsonArray sensoresFluxoArray = jsonDoc.createNestedArray("SensoresFluxo");
for (const auto* sensor : listaSensoresFluxo) {
JsonObject sensorData = sensoresFluxoArray.createNestedObject();
sensorData["Id"] = sensor->_ID;
sensorData["Iniciado"] = sensor->Iniciado;
sensorData["Pulsos"] = sensor->_PulsosLeitura;
sensorData["Periodo"] = sensor->_PeriodoTotalLeitura;
}
2024-01-03 10:52:37 +00:00
// Array JSON para sensores de massa
JsonArray sensoresMassaArray = jsonDoc.createNestedArray("SensoresMassa");
for (const auto* sensor : listaSensoresMassa) {
JsonObject sensorData = sensoresMassaArray.createNestedObject();
sensorData["Id"] = sensor->_ID;
sensorData["Iniciado"] = sensor->Iniciado;
sensorData["Leitura"] = sensor->leituraMassa;
}
2024-01-03 10:52:37 +00:00
// Array JSON para sensores de pressao
JsonArray sensoresPressaoArray = jsonDoc.createNestedArray("SensoresPressao");
for (const auto* sensor : listaSensoresPressao) {
JsonObject sensorData = sensoresPressaoArray.createNestedObject();
sensorData["Id"] = sensor->_ID;
sensorData["Iniciado"] = sensor->Iniciado;
sensorData["Pressao"] = sensor->Pressao;
sensorData["Leitura"] = sensor->leitura;
}
2024-01-03 10:52:37 +00:00
// Serializa o JSON para uma string
String jsonString;
serializeJson(jsonDoc, jsonString);
2024-01-03 10:52:37 +00:00
int messageSize = jsonString.length();
PrintTela("Tamanho da mensagem: ", false);
PrintTela((String)messageSize);
2024-01-03 10:52:37 +00:00
return jsonString;
}
2024-01-03 10:52:37 +00:00
void ProcessarProtocolo(ProtocoloSerial Mensagem) {
switch (Mensagem.funcao) {
case Chk:
ProcessarChk(Mensagem);
break;
case Cfg:
ProcessarCfg(Mensagem);
break;
case Cmd:
ProcessarCmd(Mensagem);
break;
case Req:
ProcessarReq(Mensagem);
break;
}
if (Mensagem.idMensagem > 0) {
EnviarDadosSerial(Mod_ID, MontarProtocoloMensagemRecebida(Mensagem.idMensagem));
}
}
void ProcessarChk(ProtocoloSerial Mensagem) {
Verificando = true;
mqttService.EnviarDados(Mod_ID, MontarProtocoloVerificacao(D_Code, VERSION, Conectado));
delay(2000);
Verificando = false;
}
void ProcessarCfg(ProtocoloSerial Mensagem) {
std::vector<String> Partes = SplitString(Mensagem.protocolo, SplitParams);
T_Code Tipo = (T_Code)(Partes[0].toInt());
if (Tipo == Mod) {
bool Conectar = Partes[1] == "1";
_TaxaAmostragem = Partes[2].toInt();
RequisitarDados = Partes[3] == "1";
vTaskDelay(pdMS_TO_TICKS(100));
Conectado = Conectar;
Verificando = false;
enviarDadosSensores();
}
else {
S_Code componente = (S_Code)Partes[1].toInt();
String config = Partes[2];
switch (componente) {
case sBIC: {
Rele::InicializarLista(listaBicos, config, Mod_ID);
break;
}
case sBMB: {
BombaPressurizadora::InicializarLista(listaBombas, config, Mod_ID, listaSensoresPressao);
break;
}
case sFLX: {
SensorFluxo::InicializarLista(listaSensoresFluxo, config, Mod_ID);
break;
}
case sMAS: {
SensorMassa::InicializarLista(listaSensoresMassa, config, Mod_ID);
break;
}
case sPRS: {
SensorPressao::InicializarLista(listaSensoresPressao, config, Mod_ID);
break;
}
}
}
}
void ProcessarCmd(ProtocoloSerial Mensagem) {
std::vector<String> Partes = SplitString(Mensagem.protocolo, SplitParams);
String ID = Partes[0];
S_Code componente = (S_Code)Partes[1].toInt();
switch (componente) {
case sBIC: {
for (auto* _rele : listaBicos) {
if (_rele->_ID == ID) {
Estado novoEstado = (Estado)Partes[2].toInt();
_rele->AtualizarStatus(novoEstado);
2024-01-03 10:52:37 +00:00
}
}
break;
2024-01-03 10:52:37 +00:00
}
case sBMB: {
for (auto* _bomba : listaBombas) {
if (_bomba->_ID == ID) {
_bomba->_EstadoControle = (Estado)(Partes[2].toInt());
_bomba->_PressaoSP = Partes[3].toDouble();
_bomba->AlterarStatusBomba();
}
2024-01-03 10:52:37 +00:00
}
break;
2024-01-03 10:52:37 +00:00
}
}
}
void ProcessarReq(ProtocoloSerial Mensagem) {
enviarDadosSensores();
}