ligado o enfileiramento da mensageria

This commit is contained in:
Diego Freitas 2024-04-26 16:34:58 -03:00
parent 96c375ee16
commit 3252ad2a99
79 changed files with 2973 additions and 274 deletions

5
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,5 @@
{
"files.associations": {
"vector": "cpp"
}
}

Binary file not shown.

View File

@ -21,7 +21,7 @@ namespace AgroBase.Forms
public frmInstancial()
{
InitializeComponent();
FilaService.Inicializar(false);
FilaService.Inicializar(true);
}
private void frmInstancial_Shown(object sender, EventArgs e)

View File

@ -244,11 +244,12 @@ namespace AgroBase.Models.Modules
List<string> Config = BicosPulverizadores.Select(x => x.ProtocoloConfiguracaoBico(Conectar)).ToList();
Config.Add(BombaPressurizadora.ProtocoloConfiguracaoBomba(Conectar));
Config.AddRange(Sensores.Select(x => x.ProtocoloConfiguracaoSensor(Pinout, Conectar)).ToList());
string ProtocoloMOD = ((int)F_Code.Cfg).ToString() +
"MD".PadRight(5, ' ') + ";" + // 0 ~ 4
(Conectar ? "1" : "0") + ";" + // 6
_TaxaAmostragem.ToString("00000") + ";" + // 8 ~ 12
(AtuacaoNivelAlto ? "1" : "0"); // 14
string ProtocoloMOD =
((int)F_Code.Cfg).ToString() + SerialService.SplitMessage +
"MD" + SerialService.SplitParams +
(Conectar ? "1" : "0") + SerialService.SplitParams +
_TaxaAmostragem.ToString() + SerialService.SplitParams +
(AtuacaoNivelAlto ? "1" : "0");
Config.Add(ProtocoloMOD);
return Config;
}
@ -456,12 +457,14 @@ namespace AgroBase.Models.Modules
Pinos = AtuadorModel.Pinout.Pinos.ToList(),
};
_pinout.Pinos = _pinout.Pinos.Where(x => x.ComponenteID == ID).ToList();
return ((int)F_Code.Cfg).ToString() +
ID.PadRight(5, ' ') + ";" + // 0 ~ 2
(Conectar ? "1" : "0") + ";" + // 4
(Comandar ? "1" : "0") + ";" + // 6
Posicao.ToString("00") + ";" + // 8 ~ 9
PinoutModel.PinoProtocolo(_pinout, Funcoes); // 11 ~ 13
string Protocolo = ((int)F_Code.Cfg).ToString() + SerialService.SplitMessage +
ID + SerialService.SplitParams +
(Conectar ? "1" : "0") + SerialService.SplitParams +
(Comandar ? "1" : "0") + SerialService.SplitParams +
Posicao.ToString() + SerialService.SplitParams +
PinoutModel.PinoProtocolo(_pinout, Funcoes);
return Protocolo;
}
public string ProtocoloComando()
@ -469,9 +472,9 @@ namespace AgroBase.Models.Modules
if (Comandar)
{
string ProtocoloBico =
((int)F_Code.Cmd).ToString() +
ID.PadRight(5, ' ') + ";" + // 0 ~ 4
(Atuado ? "1" : "0"); // 6
((int)F_Code.Cmd).ToString() + SerialService.SplitMessage +
ID + SerialService.SplitParams +
(Atuado ? "1" : "0");
return ProtocoloBico;
}
return "";
@ -482,8 +485,8 @@ namespace AgroBase.Models.Modules
if (Comandar)
{
string ProtocoloBico =
((int)F_Code.Tst).ToString() +
ID.PadRight(5, ' '); // 0 ~ 4;
((int)F_Code.Tst).ToString() + SerialService.SplitMessage +
ID;
return ProtocoloBico;
}
return "";
@ -532,12 +535,14 @@ namespace AgroBase.Models.Modules
Pinos = AtuadorModel.Pinout.Pinos.ToList(),
};
_pinout.Pinos = _pinout.Pinos.Where(x => x.ComponenteID == ID).ToList();
return ((int)F_Code.Cfg).ToString() +
ID.PadRight(5, ' ') + ";" + // 0 ~ 4
(Conectar ? "1" : "0") + ";" + // 6
(Comandar ? "1" : "0") + ";" + // 8
PressaoSP.ToString("000") + ";" + // 10 ~ 12
PinoutModel.PinoProtocolo(_pinout, Funcoes); // 14 ~ 32
string Protocolo = ((int)F_Code.Cfg).ToString() + SerialService.SplitMessage +
ID + SerialService.SplitParams +
(Conectar ? "1" : "0") + SerialService.SplitParams +
(Comandar ? "1" : "0") + SerialService.SplitParams +
PressaoSP.ToString("000") + SerialService.SplitParams +
PinoutModel.PinoProtocolo(_pinout, Funcoes);
return Protocolo;
}
public string ProtocoloComando()
@ -545,10 +550,10 @@ namespace AgroBase.Models.Modules
if (Comandar)
{
string ProtocoloBomba =
((int)F_Code.Cmd).ToString() +
ID.PadRight(5, ' ') + ";" + // 0 ~ 4
(BombaAtuada ? "1" : "0") + ";" + // 6
PressaoSP.ToString("000"); // 8 ~ 10
((int)F_Code.Cmd).ToString() + SerialService.SplitMessage +
ID.PadRight(5, ' ') + SerialService.SplitParams +
(BombaAtuada ? "1" : "0") + SerialService.SplitParams +
PressaoSP.ToString();
return ProtocoloBomba;
}
return "";
@ -559,8 +564,8 @@ namespace AgroBase.Models.Modules
if (Comandar)
{
string ProtocoloBomba =
((int)F_Code.Tst).ToString() +
ID.PadRight(5, ' '); // 0 ~ 4;
((int)F_Code.Tst).ToString() + SerialService.SplitMessage +
ID;
return ProtocoloBomba;
}
return "";

View File

@ -137,14 +137,15 @@ namespace AgroBase.Models.Modules
public List<string> ProtocoloConfiguracao(bool Conectar)
{
List<string> Config = Motores.Select(x => x.ProtocoloConfiguracaoMotor(Conectar)).ToList();
string ProtocoloMOD = ((int)F_Code.Cfg).ToString() + (FilaService.FeatureAtivada ? ";" : "") +
"MD" + ";" + // 0 ~ 1
(Conectar ? "1" : "0") + ";" + // 3
_TaxaAmostragem.ToString("00000") + ";" + // 5 ~ 9
(AA_Ref000 ? "1" : "0") + ";" + // 11
(AA_Ref090 ? "1" : "0") + ";" + // 13
(AA_Ref270 ? "1" : "0") + ";" + // 15
PinoutModel.PinoProtocolo(Pinout, Funcoes); // 17 ~ 18
string ProtocoloMOD =
((int)F_Code.Cfg).ToString() + SerialService.SplitMessage +
"MD" + SerialService.SplitParams +
(Conectar ? "1" : "0") + SerialService.SplitParams +
_TaxaAmostragem.ToString("00000") + SerialService.SplitParams +
(AA_Ref000 ? "1" : "0") + SerialService.SplitParams +
(AA_Ref090 ? "1" : "0") + SerialService.SplitParams +
(AA_Ref270 ? "1" : "0") + SerialService.SplitParams +
PinoutModel.PinoProtocolo(Pinout, Funcoes);
Config.Add(ProtocoloMOD);
return Config;
}
@ -356,15 +357,19 @@ namespace AgroBase.Models.Modules
Pinos = DirecionalModel.Pinout.Pinos.ToList(),
};
_pinout.Pinos = _pinout.Pinos.Where(x => x.ComponenteID == ID).ToList();
return ((int)F_Code.Cfg).ToString() + (FilaService.FeatureAtivada ? ";" : "") +
ID + ";" + // 0 ~ 1
(Conectar ? "1" : "0") + ";" + // 3
Canal.ToString() + ";" + // 5
(Comandar ? "1" : "0") + ";" + // 7
(Estabilizar ? "1" : "0") + ";" + // 9
(Referenciar ? "1" : "0") + ";" + // 11
Angulo_Offset.ToString(Angulo_Offset < 0 ? "000" : "0000") + ";" + // 13 ~ 16
PinoutModel.PinoProtocolo(_pinout, Funcoes); // 18 ~ 48
string Protocolo =
((int)F_Code.Cfg).ToString() + SerialService.SplitMessage +
ID + SerialService.SplitParams +
(Conectar ? "1" : "0") + SerialService.SplitParams +
Canal.ToString() + SerialService.SplitParams +
(Comandar ? "1" : "0") + SerialService.SplitParams +
(Estabilizar ? "1" : "0") + SerialService.SplitParams +
(Referenciar ? "1" : "0") + SerialService.SplitParams +
Angulo_Offset.ToString() + SerialService.SplitParams +
PinoutModel.PinoProtocolo(_pinout, Funcoes);
return Protocolo;
}
public string ProtocoloComando(Direcao Direcao, bool _Ref = false)
@ -382,13 +387,13 @@ namespace AgroBase.Models.Modules
Velocidade = GeneralJoystick.Velocidade;
string ProtocoloMotor =
((int)F_Code.Cmd).ToString() +
ID + ";" + // 0 ~ 1
((int)Sentido_SP).ToString() + ";" + // 3
Angulo_SP.ToString(Angulo_SP < 0 ? "00" : "000") + ";" + // 5 ~ 7
Velocidade.ToString("000") + ";" + // 9 ~ 11
(_Ref ? "1" : "0") + ";" + // 13
Angulo_Offset.ToString(Angulo_Offset < 0 ? "000" : "0000"); // 15 ~ 18
((int)F_Code.Cmd).ToString() + SerialService.SplitMessage +
ID + SerialService.SplitParams +
((int)Sentido_SP).ToString() + SerialService.SplitParams +
Angulo_SP.ToString() + SerialService.SplitParams +
Velocidade.ToString() + SerialService.SplitParams +
(_Ref ? "1" : "0") + SerialService.SplitParams +
Angulo_Offset.ToString();
return ProtocoloMotor;
}
return "";
@ -399,8 +404,8 @@ namespace AgroBase.Models.Modules
if (Comandar)
{
string ProtocoloMotor =
((int)F_Code.Tst).ToString() +
ID; // 0 ~ 1;
((int)F_Code.Tst).ToString() + SerialService.SplitMessage +
ID;
return ProtocoloMotor;
}
return "";

View File

@ -148,16 +148,17 @@ namespace AgroBase.Models
public List<string> ProtocoloConfiguracao(bool Conectar)
{
List<string> Config = Motores.Select(x => x.ProtocoloConfiguracaoMotor(Conectar)).ToList();
string ProtocoloMOD = ((int)F_Code.Cfg).ToString() +
"MD" + ";" + // 0 ~ 1
(Conectar ? "1" : "0") + ";" + // 3
_TaxaAmostragem.ToString("00000") + ";" + // 5 ~ 9
RampaMin.ToString("0000") + ";" + // 11 ~ 14
RampaMax.ToString("0000") + ";" + // 16 ~ 19
PulsosPorRevolucao.ToString("000") + ";" + // 21 ~ 23
_DelayBalanceamento.ToString("00000") + ";" + // 25 ~ 29
_MargemRPM.ToString("00") + ";" + // 31 ~ 32
_MaxOffsetRPM.ToString("00"); // 34 ~ 35
string ProtocoloMOD =
((int)F_Code.Cfg).ToString() + SerialService.SplitMessage +
"MD" + SerialService.SplitParams +
(Conectar ? "1" : "0") + SerialService.SplitParams +
_TaxaAmostragem.ToString() + SerialService.SplitParams +
RampaMin.ToString() + SerialService.SplitParams +
RampaMax.ToString() + SerialService.SplitParams +
PulsosPorRevolucao.ToString() + SerialService.SplitParams +
_DelayBalanceamento.ToString() + SerialService.SplitParams +
_MargemRPM.ToString() + SerialService.SplitParams +
_MaxOffsetRPM.ToString();
Config.Add(ProtocoloMOD);
return Config;
}
@ -459,17 +460,19 @@ namespace AgroBase.Models
Pinos = MovimentacaoModel.Pinout.Pinos.ToList(),
};
_pinout.Pinos = _pinout.Pinos.Where(x => x.ComponenteID == ID).ToList();
return ((int)F_Code.Cfg).ToString() +
ID + ";" + // 0 ~ 1
(Conectar ? "1" : "0") + ";" + // 3
Canal.ToString() + ";" + // 5
(Alarme ? "1" : "0") + ";" + // 7
(Comandar ? "1" : "0") + ";" + // 9
MovimentacaoModel.Kp.ToString("0.000").Replace(",", ".") + "," + // 11 ~ 15
MovimentacaoModel.Ki.ToString("0.000").Replace(",", ".") + "," + // 17 ~ 21
MovimentacaoModel.Kd.ToString("0.000").Replace(",", ".") + "," + // 23 ~ 27
string Protocolo =
((int)F_Code.Cfg).ToString() + SerialService.SplitMessage +
ID + SerialService.SplitParams +
(Conectar ? "1" : "0") + SerialService.SplitParams +
Canal.ToString() + SerialService.SplitParams +
(Alarme ? "1" : "0") + SerialService.SplitParams +
(Comandar ? "1" : "0") + SerialService.SplitParams +
MovimentacaoModel.Kp.ToString().Replace(",", ".") + SerialService.SplitParams +
MovimentacaoModel.Ki.ToString().Replace(",", ".") + SerialService.SplitParams +
MovimentacaoModel.Kd.ToString().Replace(",", ".") + SerialService.SplitParams +
PinoutModel.PinoProtocolo(_pinout, Funcoes); // 29 ~ 51
return Protocolo;
}
public string ProtocoloComando(Direcao DirecaoAtual, bool CmdAlarme = false)
@ -514,11 +517,11 @@ namespace AgroBase.Models
}
ProtocoloMotor =
((int)F_Code.Cmd).ToString() +
ID + ";" + // 0 ~ 1
((int)Sentido_SP).ToString() + ";" + // 3
RPM_SP.ToString("000") + ";" + // 5 ~ 7
(Alarme ? "1" : "0"); // 9
((int)F_Code.Cmd).ToString() + SerialService.SplitMessage +
ID + SerialService.SplitParams +
((int)Sentido_SP).ToString() + SerialService.SplitParams +
RPM_SP.ToString() + SerialService.SplitParams +
(Alarme ? "1" : "0");
if (Sentido_SP != Sentido.Parado)
{
@ -535,7 +538,7 @@ namespace AgroBase.Models
if (Comandar)
{
string ProtocoloMotor =
((int)F_Code.Tst).ToString() +
((int)F_Code.Tst).ToString() + SerialService.SplitMessage +
ID;
return ProtocoloMotor;
}

View File

@ -1,4 +1,5 @@
using Newtonsoft.Json;
using AgroBase.Services;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
@ -282,39 +283,22 @@ namespace AgroBase.Models.Modules
{
if (i > 0)
{
Pinos += ",";
Pinos += SerialService.SplitParams;
}
var pino = _pinout.Pinos.FirstOrDefault(x => x.Funcao == funcao);
if (pino != null && (pino.Barramento == TiposBarramentos.CONTROLADOR || (pino.Barramento == TiposBarramentos.EXPANSORI2C && _pinout.ExpansorGPIO)))
{
Pinos += (int)pino.Barramento + pino.Pino.ToString("00");
Pinos += ((int)pino.Barramento).ToString() + SerialService.SplitParams + pino.Pino.ToString();
}
else
{
Pinos += "0-1";
Pinos += ((int)TiposBarramentos.CONTROLADOR).ToString() + SerialService.SplitParams + "-1";
}
i++;
}
return Pinos;
}
public static string PinoSensorProtocolo2(PinoutDataModel _pinout)
{
string pin = "0-1";
string pin2 = "0-1";
var comp = _pinout.Pinos.FirstOrDefault(x => x.Funcao != FuncoesPinout.NaoConectado);
var p2 = _pinout.Pinos.FirstOrDefault(x => PinoutUtils.PinosSecundarios.Any(y => y == x.Funcao));
if (comp != null && (comp.Barramento == TiposBarramentos.CONTROLADOR || (comp.Barramento == TiposBarramentos.EXPANSORI2C && _pinout.ExpansorGPIO)))
{
pin = (int)comp.Barramento + comp.Pino.ToString("00");
}
if (p2 != null && (p2.Barramento == TiposBarramentos.CONTROLADOR || (p2.Barramento == TiposBarramentos.EXPANSORI2C && _pinout.ExpansorGPIO)))
{
pin2 = (int)p2.Barramento + p2.Pino.ToString("00");
}
return pin + ";" + pin2;
}
}
public enum TiposControladores

View File

@ -8,6 +8,7 @@ using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static AgroBase.Models.Enuns;
namespace AgroBase.Models.Modules
@ -55,7 +56,8 @@ namespace AgroBase.Models.Modules
Funcoes = new List<FuncoesPinout>()
{
FuncoesPinout.Sinaleiro,
}
},
Comportamento = Variaveis.ComportamentoPorStatus(StatusOperacao.NaoIniciado)
},
new SensorSinaleiroModel()
{
@ -65,7 +67,8 @@ namespace AgroBase.Models.Modules
Funcoes = new List<FuncoesPinout>()
{
FuncoesPinout.Sinaleiro,
}
},
Comportamento = Variaveis.ComportamentoPorStatus(StatusOperacao.NaoIniciado)
},
new SensorSinaleiroModel()
{
@ -75,7 +78,8 @@ namespace AgroBase.Models.Modules
Funcoes = new List<FuncoesPinout>()
{
FuncoesPinout.Sinaleiro,
}
},
Comportamento = Variaveis.ComportamentoPorStatus(StatusOperacao.NaoIniciado)
},
},
Sensores = new List<SensorModel>()
@ -302,7 +306,7 @@ namespace AgroBase.Models.Modules
},
new SensorModel()
{
ID = "SMAG ",
ID = "SMAG",
Descricao = "Sensor Magnetômetro",
Prioridade = 15,
Componente = S_Code.sMAG,
@ -352,12 +356,12 @@ namespace AgroBase.Models.Modules
{
List<string> Config = Sensores.Where(x => x.Aferir).Select(x => x.ProtocoloConfiguracaoSensor(Pinout, Conectar)).ToList();
Config.AddRange(Sinaleiros.Select(x => x.ProtocoloConfiguracaoSinaleiro(Pinout, Conectar)).ToList());
string ProtocoloMOD = ((int)F_Code.Cfg).ToString() +
"MD".PadRight(5, ' ') + ";" + // 0 ~ 4
(Conectar ? "1" : "0") + ";" + // 6
_TaxaAmostragem.ToString("00000") + // 8 ~ 12
(Pinout.Pinos.Any(x => x.Funcao == FuncoesPinout.SDA) ? Pinout.Pinos.FirstOrDefault(x => x.Funcao == FuncoesPinout.SDA).Pino.ToString("00") : "-1") + ";" + // 14 ~ 15
(Pinout.Pinos.Any(x => x.Funcao == FuncoesPinout.SCL) ? Pinout.Pinos.FirstOrDefault(x => x.Funcao == FuncoesPinout.SCL).Pino.ToString("00") : "-1"); // 17 ~ 18
string ProtocoloMOD =
((int)F_Code.Cfg).ToString() + SerialService.SplitMessage +
"MD" + SerialService.SplitParams +
(Conectar ? "1" : "0") + SerialService.SplitParams +
_TaxaAmostragem.ToString() + SerialService.SplitParams +
PinoutModel.PinoProtocolo(Pinout, Funcoes);
Config.Add(ProtocoloMOD);
return Config;
}
@ -376,7 +380,7 @@ namespace AgroBase.Models.Modules
}
S_Code TipoSensor = (S_Code)(cod);
SensorModel Sensor = Sensores.FirstOrDefault(x => x.ID.Trim() == Dados[1].Trim());
SensorModel Sensor = Sensores.FirstOrDefault(x => x.ID == Dados[1]);
if (Sensor == null)
{
if (Dados[1] == "MD")
@ -785,17 +789,18 @@ namespace AgroBase.Models.Modules
Pinos = Pinout.Pinos.ToList(),
};
_pinout.Pinos = _pinout.Pinos.Where(x => x.ComponenteID == ID).ToList();
string Protocolo = ((int)F_Code.Cfg).ToString() +
ID.PadRight(5, ' ') + ";" + // 0 ~ 4
(Conectar ? "1" : "0") + ";" + // 6
((int)Componente).ToString() + ";" + // 8 ~ 10
(Aferir ? "1" : "0") + ";" + // 12
DelayAmostragem.ToString("00000") + ";" + // 14 ~ 18
Prioridade.ToString("00") + ";" + // 20 ~ 21
PinoutModel.PinoProtocolo(_pinout, Funcoes); // 23 ~ 25 / 27 ~ 29
string Protocolo =
((int)F_Code.Cfg).ToString() + SerialService.SplitMessage +
ID + SerialService.SplitParams +
(Conectar ? "1" : "0") + SerialService.SplitParams +
((int)Componente).ToString() + SerialService.SplitParams +
(Aferir ? "1" : "0") + SerialService.SplitParams +
DelayAmostragem.ToString() + SerialService.SplitParams +
Prioridade.ToString() + SerialService.SplitParams +
PinoutModel.PinoProtocolo(_pinout, Funcoes);
foreach (var Parametro in Parametros)
{
Protocolo += ";" + Parametro[1].PadRight(6, ' ');
Protocolo += SerialService.SplitParams + Parametro[1];
}
return Protocolo;
}
@ -818,22 +823,22 @@ namespace AgroBase.Models.Modules
Pinos = Pinout.Pinos.ToList(),
};
_pinout.Pinos = _pinout.Pinos.Where(x => x.ComponenteID == ID).ToList();
string Protocolo = ((int)F_Code.Cfg).ToString() +
ID.PadRight(5, ' ') + ";" + // 0 ~ 4
(Conectar ? "1" : "0") + ";" + // 6
PinoutModel.PinoProtocolo(_pinout, Funcoes); // 8 ~ 10
string Protocolo = ((int)F_Code.Cfg).ToString() + SerialService.SplitMessage +
ID + SerialService.SplitParams +
(Conectar ? "1" : "0") + SerialService.SplitParams +
PinoutModel.PinoProtocolo(_pinout, Funcoes);
return Protocolo;
}
public string ProtocoloComando()
{
string ProtocoloSinaleiro =
((int)F_Code.Cmd).ToString() +
ID.PadRight(5, ' ') + ";" + // 0 ~ 4
(int)Comportamento.statusLED + ";" + // 6
Comportamento.QtdPiscadas.ToString() + ";" + // 8
Comportamento.TempoMs.ToString("0000") + ";" + // 10 ~ 13
Comportamento.PausaMs.ToString("0000"); // 15 ~ 18
((int)F_Code.Cmd).ToString() + SerialService.SplitMessage +
ID + SerialService.SplitParams +
(int)Comportamento.statusLED + SerialService.SplitParams +
Comportamento.QtdPiscadas.ToString() + SerialService.SplitParams +
Comportamento.TempoMs.ToString() + SerialService.SplitParams +
Comportamento.PausaMs.ToString();
return ProtocoloSinaleiro;
}

View File

@ -15,7 +15,6 @@ using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using static AgroBase.Models.Enuns;
using static AgroBase.Models.Operacoes.OperacaoMapaGPSModel;
namespace AgroBase.Models
{
@ -254,6 +253,8 @@ namespace AgroBase.Models
var DirConectado = (DispositivosService<DirecionalModel>)Variaveis.DispositivosConectados.FirstOrDefault(x => x.Dispositivo == T_Code.Dir);
var AtuConectado = (DispositivosService<AtuadorModel>)Variaveis.DispositivosConectados.FirstOrDefault(x => x.Dispositivo == T_Code.Atu);
Variaveis.OperacaoEmAndamento.tmrLogs.Stop();
OperacaoModel OperacaoCarregar = new OperacaoModel(Modo)
{
Iniciado = false,
@ -410,10 +411,11 @@ namespace AgroBase.Models
if (OperacaoCarregar.DispSen != null && OperacaoCarregar.DispSen.Dados.Conectado)
{
OperacaoCarregar.DispSen.Dados.Sinaleiros.ForEach(x => x.Comportamento = Variaveis.ComportamentoPorStatus(StatusOperacao.Concluido));
OperacaoCarregar.DispSen.Dados.Sinaleiros.ForEach(x => x.Comportamento = Variaveis.ComportamentoPorStatus(StatusOperacao.NaoIniciado));
OperacaoCarregar.DispSen.Dados.Sinaleiros.First(x => x.ID == (Modo == ModoOperacao.Manual ? "LEDMN" : "LEDAT")).Comportamento.statusLED = StatusLED.Aceso;
OperacaoCarregar.DispSen.Dados.Sinaleiros.First(x => x.ID == "LEDOP").Comportamento = Variaveis.ComportamentoPorStatus();
SensorSinaleiroModel Sinaleiro = OperacaoCarregar.DispSen.Dados.Sinaleiros.First(x => x.ID == (Modo == ModoOperacao.Manual ? "LEDMN" : "LEDAT"));
Sinaleiro.Comportamento.statusLED = StatusLED.Aceso;
OperacaoCarregar.DispSen.Dados.Sinaleiros.ForEach(x => OperacaoCarregar.DispSen.AdicionarMensagemFila(x.ProtocoloComando()));
}
@ -672,9 +674,11 @@ namespace AgroBase.Models
{
if (DispSen != null && DispSen.Dados.Conectado)
{
var Sinaleiro = DispSen.Dados.Sinaleiros.FirstOrDefault(x => x.ID == "LEDOP");
Sinaleiro.Comportamento = Variaveis.ComportamentoPorStatus();
DispSen.AdicionarMensagemFila(Sinaleiro.ProtocoloComando());
DispSen.Dados.Sinaleiros.FirstOrDefault(x => x.ID == "LEDOP").Comportamento = Variaveis.ComportamentoPorStatus();
DispSen.Dados.Sinaleiros.FirstOrDefault(x => x.ID == "LEDAT").Comportamento.statusLED = Modo == ModoOperacao.MapaGPS ? StatusLED.Aceso : StatusLED.Apagado;
DispSen.Dados.Sinaleiros.FirstOrDefault(x => x.ID == "LEDMN").Comportamento.statusLED = Modo == ModoOperacao.Manual ? StatusLED.Aceso : StatusLED.Apagado;
DispSen.Dados.Sinaleiros.ForEach(x => DispSen.AdicionarMensagemFila(x.ProtocoloComando()));
}
}

View File

@ -191,8 +191,6 @@ namespace AgroBase.Comum
}
}
Dados += SerialService.EndLine;
AtualizarConsole("> " + DateTime.Now.ToString("HH:mm:ss:fff") + " - " + Dados);
try

View File

@ -27,15 +27,18 @@ namespace AgroBase.Services
public static void AdicionarMensagemFila(T_Code Dispositivo, string Mensagem)
{
MensagensFila.Add(new MensagemFilaModel()
if (Mensagem != "")
{
Id = MensagensFila.Count + 1,
Dispositivo = Dispositivo,
Mensagem = Mensagem,
AdicionadoEm = DateTime.Now,
Enviado = false,
Recebido = false,
});
MensagensFila.Add(new MensagemFilaModel()
{
Id = MensagensFila.Count + 1,
Dispositivo = Dispositivo,
Mensagem = Mensagem,
AdicionadoEm = DateTime.Now,
Enviado = false,
Recebido = false,
});
}
}
private static void MarcarMensagemEnviada(int Id)
@ -69,7 +72,13 @@ namespace AgroBase.Services
{
try
{
Dispositivo.EnviarDadosSerial(Mensagem.Id + ";" + Mensagem.Mensagem);
Dispositivo.EnviarDadosSerial(
SerialService.BeginLine +
Mensagem.Id +
SerialService.SplitMessage +
Mensagem.Mensagem +
SerialService.EndLine
);
return true;
}
catch (Exception ex)
@ -80,7 +89,10 @@ namespace AgroBase.Services
}
else
{
Dispositivo.EnviarDadosSerial(Mensagem.Mensagem);
Dispositivo.EnviarDadosSerial(
Mensagem.Mensagem +
SerialService.EndLine
);
MarcarMensagemRecebida(Mensagem.Id);
return true;
}

View File

@ -14,8 +14,12 @@ namespace AgroBase.Services
{
public class SerialService
{
public static string BeginLine = "@";
public static string EndLine = "$";
public static string BeginSensor = "#";
public static string SplitMessage = ";";
public static string SplitParams = ",";
public static string ProtocoloCheck = BeginLine + SplitMessage + 0 + SplitMessage + ((int)F_Code.Chk).ToString() + SplitMessage + "check" + EndLine;
public static List<T_Code> DispositivosMotores = new List<T_Code>() { T_Code.Mov, T_Code.Dir };
public class DispositivoDetalhesModel
@ -86,7 +90,7 @@ namespace AgroBase.Services
SerialPort _Porta = new SerialPort() { PortName = PortaCom, BaudRate = 115200 };
_Porta.DataReceived -= _Porta_DataReceived;
_Porta.DataReceived += _Porta_DataReceived;
string CodigoTest = (FilaService.FeatureAtivada ? "-1;" + ((int)F_Code.Chk).ToString() + ";check" : ((int)F_Code.Chk).ToString() + "check") + EndLine;
string CodigoTest = ProtocoloCheck;
try
{
_Porta.Open();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
[{"Momento":"2024-04-26T14:12:00.737473-03:00","VelocidadeMedia":0.0,"PorcentagemBateria":67.999999999999972,"BateriaConsumida":0.0,"DistanciaPercorrida":[],"DistanciaEsquerda":0.0,"DistanciaDireita":0.0,"AnguloCarro":0.0,"AnguloCarroBussola":0.0,"SonarFrontal":null},{"Momento":"2024-04-26T14:12:05.7460321-03:00","VelocidadeMedia":0.0,"PorcentagemBateria":67.999999999999972,"BateriaConsumida":0.0,"DistanciaPercorrida":[],"DistanciaEsquerda":0.0,"DistanciaDireita":0.0,"AnguloCarro":0.0,"AnguloCarroBussola":0.0,"SonarFrontal":null},{"Momento":"2024-04-26T14:12:10.7373419-03:00","VelocidadeMedia":0.0,"PorcentagemBateria":68.333333333333357,"BateriaConsumida":0.0,"DistanciaPercorrida":[0.0],"DistanciaEsquerda":0.0,"DistanciaDireita":0.0,"AnguloCarro":0.0,"AnguloCarroBussola":0.0,"SonarFrontal":null},{"Momento":"2024-04-26T14:12:15.764538-03:00","VelocidadeMedia":0.0,"PorcentagemBateria":68.333333333333357,"BateriaConsumida":0.0,"DistanciaPercorrida":[0.0],"DistanciaEsquerda":0.0,"DistanciaDireita":0.0,"AnguloCarro":0.0,"AnguloCarroBussola":0.0,"SonarFrontal":null},{"Momento":"2024-04-26T14:12:20.7392636-03:00","VelocidadeMedia":0.0,"PorcentagemBateria":68.333333333333357,"BateriaConsumida":0.0,"DistanciaPercorrida":[0.0],"DistanciaEsquerda":0.0,"DistanciaDireita":0.0,"AnguloCarro":0.0,"AnguloCarroBussola":0.0,"SonarFrontal":null},{"Momento":"2024-04-26T14:12:25.7568496-03:00","VelocidadeMedia":0.0,"PorcentagemBateria":68.333333333333357,"BateriaConsumida":0.0,"DistanciaPercorrida":[0.0],"DistanciaEsquerda":0.0,"DistanciaDireita":0.0,"AnguloCarro":0.0,"AnguloCarroBussola":0.0,"SonarFrontal":null},{"Momento":"2024-04-26T14:12:30.736528-03:00","VelocidadeMedia":0.0,"PorcentagemBateria":68.333333333333357,"BateriaConsumida":0.0,"DistanciaPercorrida":[0.0],"DistanciaEsquerda":0.0,"DistanciaDireita":0.0,"AnguloCarro":0.0,"AnguloCarroBussola":0.0,"SonarFrontal":null},{"Momento":"2024-04-26T14:12:35.7553758-03:00","VelocidadeMedia":0.0,"PorcentagemBateria":68.333333333333357,"BateriaConsumida":0.0,"DistanciaPercorrida":[0.0],"DistanciaEsquerda":0.0,"DistanciaDireita":0.0,"AnguloCarro":0.0,"AnguloCarroBussola":0.0,"SonarFrontal":null},{"Momento":"2024-04-26T14:12:40.750683-03:00","VelocidadeMedia":0.0,"PorcentagemBateria":68.333333333333357,"BateriaConsumida":0.0,"DistanciaPercorrida":[0.0],"DistanciaEsquerda":0.0,"DistanciaDireita":0.0,"AnguloCarro":0.0,"AnguloCarroBussola":0.0,"SonarFrontal":null},{"Momento":"2024-04-26T14:12:45.7494255-03:00","VelocidadeMedia":0.0,"PorcentagemBateria":68.333333333333357,"BateriaConsumida":0.0,"DistanciaPercorrida":[0.0],"DistanciaEsquerda":0.0,"DistanciaDireita":0.0,"AnguloCarro":0.0,"AnguloCarroBussola":0.0,"SonarFrontal":null},{"Momento":"2024-04-26T14:12:50.7532517-03:00","VelocidadeMedia":0.0,"PorcentagemBateria":66.666666666666671,"BateriaConsumida":0.0,"DistanciaPercorrida":[0.0],"DistanciaEsquerda":0.0,"DistanciaDireita":0.0,"AnguloCarro":0.0,"AnguloCarroBussola":0.0,"SonarFrontal":null},{"Momento":"2024-04-26T14:12:55.7476568-03:00","VelocidadeMedia":0.0,"PorcentagemBateria":66.666666666666671,"BateriaConsumida":0.0,"DistanciaPercorrida":[0.0],"DistanciaEsquerda":0.0,"DistanciaDireita":0.0,"AnguloCarro":0.0,"AnguloCarroBussola":0.0,"SonarFrontal":null}

View File

@ -0,0 +1 @@
[{"Latitude":0.0,"Longitude":0.0,"DataHora":"0001-01-01T00:00:00","Altitude":0.0,"Velocidade":0.0,"NumeroSatelites":0,"PrecisaoHorizontal":99.99,"Orientacao":0.0},{"Latitude":0.0,"Longitude":0.0,"DataHora":"0001-01-01T00:00:00","Altitude":0.0,"Velocidade":0.0,"NumeroSatelites":0,"PrecisaoHorizontal":99.99,"Orientacao":0.0},{"Latitude":0.0,"Longitude":0.0,"DataHora":"0001-01-01T00:00:00","Altitude":0.0,"Velocidade":0.0,"NumeroSatelites":0,"PrecisaoHorizontal":99.99,"Orientacao":0.0},{"Latitude":0.0,"Longitude":0.0,"DataHora":"0001-01-01T00:00:00","Altitude":0.0,"Velocidade":0.0,"NumeroSatelites":0,"PrecisaoHorizontal":99.99,"Orientacao":0.0},{"Latitude":0.0,"Longitude":0.0,"DataHora":"0001-01-01T00:00:00","Altitude":0.0,"Velocidade":0.0,"NumeroSatelites":0,"PrecisaoHorizontal":99.99,"Orientacao":0.0},{"Latitude":0.0,"Longitude":0.0,"DataHora":"0001-01-01T00:00:00","Altitude":0.0,"Velocidade":0.0,"NumeroSatelites":0,"PrecisaoHorizontal":99.99,"Orientacao":0.0},{"Latitude":0.0,"Longitude":0.0,"DataHora":"0001-01-01T00:00:00","Altitude":0.0,"Velocidade":0.0,"NumeroSatelites":0,"PrecisaoHorizontal":99.99,"Orientacao":0.0},{"Latitude":0.0,"Longitude":0.0,"DataHora":"0001-01-01T00:00:00","Altitude":0.0,"Velocidade":0.0,"NumeroSatelites":0,"PrecisaoHorizontal":99.99,"Orientacao":0.0},{"Latitude":0.0,"Longitude":0.0,"DataHora":"0001-01-01T00:00:00","Altitude":0.0,"Velocidade":0.0,"NumeroSatelites":0,"PrecisaoHorizontal":99.99,"Orientacao":0.0},{"Latitude":0.0,"Longitude":0.0,"DataHora":"0001-01-01T00:00:00","Altitude":0.0,"Velocidade":0.0,"NumeroSatelites":0,"PrecisaoHorizontal":99.99,"Orientacao":0.0},{"Latitude":0.0,"Longitude":0.0,"DataHora":"0001-01-01T00:00:00","Altitude":0.0,"Velocidade":0.0,"NumeroSatelites":0,"PrecisaoHorizontal":99.99,"Orientacao":0.0},{"Latitude":0.0,"Longitude":0.0,"DataHora":"0001-01-01T00:00:00","Altitude":0.0,"Velocidade":0.0,"NumeroSatelites":0,"PrecisaoHorizontal":99.99,"Orientacao":0.0}]

View File

@ -0,0 +1 @@
[{"Momento":"2024-04-26T14:22:38.6663841-03:00","VelocidadeMedia":0.0,"PorcentagemBateria":68.333333333333357,"BateriaConsumida":0.0,"DistanciaPercorrida":[],"DistanciaEsquerda":0.0,"DistanciaDireita":0.0,"AnguloCarro":0.0,"AnguloCarroBussola":0.0,"SonarFrontal":null},{"Momento":"2024-04-26T14:22:43.6865232-03:00","VelocidadeMedia":0.0,"PorcentagemBateria":68.333333333333357,"BateriaConsumida":0.0,"DistanciaPercorrida":[],"DistanciaEsquerda":0.0,"DistanciaDireita":0.0,"AnguloCarro":0.0,"AnguloCarroBussola":0.0,"SonarFrontal":null},{"Momento":"2024-04-26T14:22:48.6638675-03:00","VelocidadeMedia":0.0,"PorcentagemBateria":66.000000000000014,"BateriaConsumida":0.0,"DistanciaPercorrida":[0.0],"DistanciaEsquerda":0.0,"DistanciaDireita":0.0,"AnguloCarro":0.0,"AnguloCarroBussola":0.0,"SonarFrontal":null},{"Momento":"2024-04-26T14:22:53.6614259-03:00","VelocidadeMedia":0.0,"PorcentagemBateria":66.000000000000014,"BateriaConsumida":0.0,"DistanciaPercorrida":[0.0],"DistanciaEsquerda":0.0,"DistanciaDireita":0.0,"AnguloCarro":0.0,"AnguloCarroBussola":0.0,"SonarFrontal":null},{"Momento":"2024-04-26T14:22:58.6807198-03:00","VelocidadeMedia":0.0,"PorcentagemBateria":66.3333333333334,"BateriaConsumida":0.0,"DistanciaPercorrida":[0.0],"DistanciaEsquerda":0.0,"DistanciaDireita":0.0,"AnguloCarro":0.0,"AnguloCarroBussola":0.0,"SonarFrontal":null},{"Momento":"2024-04-26T14:23:03.664448-03:00","VelocidadeMedia":0.0,"PorcentagemBateria":67.999999999999972,"BateriaConsumida":0.0,"DistanciaPercorrida":[0.0],"DistanciaEsquerda":0.0,"DistanciaDireita":0.0,"AnguloCarro":0.0,"AnguloCarroBussola":0.0,"SonarFrontal":null},{"Momento":"2024-04-26T14:23:08.6820245-03:00","VelocidadeMedia":0.0,"PorcentagemBateria":67.999999999999972,"BateriaConsumida":0.0,"DistanciaPercorrida":[0.0],"DistanciaEsquerda":0.0,"DistanciaDireita":0.0,"AnguloCarro":0.0,"AnguloCarroBussola":0.0,"SonarFrontal":null},{"Momento":"2024-04-26T14:23:13.6859067-03:00","VelocidadeMedia":0.0,"PorcentagemBateria":67.999999999999972,"BateriaConsumida":0.0,"DistanciaPercorrida":[0.0],"DistanciaEsquerda":0.0,"DistanciaDireita":0.0,"AnguloCarro":0.0,"AnguloCarroBussola":0.0,"SonarFrontal":null}

View File

@ -0,0 +1 @@
[{"Latitude":0.0,"Longitude":0.0,"DataHora":"0001-01-01T00:00:00","Altitude":0.0,"Velocidade":0.0,"NumeroSatelites":0,"PrecisaoHorizontal":99.99,"Orientacao":0.0},{"Latitude":0.0,"Longitude":0.0,"DataHora":"0001-01-01T00:00:00","Altitude":0.0,"Velocidade":0.0,"NumeroSatelites":0,"PrecisaoHorizontal":99.99,"Orientacao":0.0},{"Latitude":0.0,"Longitude":0.0,"DataHora":"0001-01-01T00:00:00","Altitude":0.0,"Velocidade":0.0,"NumeroSatelites":0,"PrecisaoHorizontal":99.99,"Orientacao":0.0},{"Latitude":0.0,"Longitude":0.0,"DataHora":"0001-01-01T00:00:00","Altitude":0.0,"Velocidade":0.0,"NumeroSatelites":0,"PrecisaoHorizontal":99.99,"Orientacao":0.0},{"Latitude":0.0,"Longitude":0.0,"DataHora":"0001-01-01T00:00:00","Altitude":0.0,"Velocidade":0.0,"NumeroSatelites":0,"PrecisaoHorizontal":99.99,"Orientacao":0.0},{"Latitude":0.0,"Longitude":0.0,"DataHora":"0001-01-01T00:00:00","Altitude":0.0,"Velocidade":0.0,"NumeroSatelites":0,"PrecisaoHorizontal":99.99,"Orientacao":0.0},{"Latitude":0.0,"Longitude":0.0,"DataHora":"0001-01-01T00:00:00","Altitude":0.0,"Velocidade":0.0,"NumeroSatelites":0,"PrecisaoHorizontal":99.99,"Orientacao":0.0},{"Latitude":0.0,"Longitude":0.0,"DataHora":"0001-01-01T00:00:00","Altitude":0.0,"Velocidade":0.0,"NumeroSatelites":0,"PrecisaoHorizontal":99.99,"Orientacao":0.0}]

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -25,7 +25,7 @@
<meta name="viewport" content="width=device-width,
initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<style>
#map_8347d9cd271667ca189c0f390ba735d0 {
#map_ca8b7d223851d008fcfc3af66a91f69a {
position: relative;
width: 100.0%;
height: 100.0%;
@ -39,14 +39,14 @@
<body>
<div class="folium-map" id="map_8347d9cd271667ca189c0f390ba735d0" ></div>
<div class="folium-map" id="map_ca8b7d223851d008fcfc3af66a91f69a" ></div>
</body>
<script>
var map_8347d9cd271667ca189c0f390ba735d0 = L.map(
"map_8347d9cd271667ca189c0f390ba735d0",
var map_ca8b7d223851d008fcfc3af66a91f69a = L.map(
"map_ca8b7d223851d008fcfc3af66a91f69a",
{
center: [0.0, 0.0],
crs: L.CRS.EPSG3857,
@ -60,13 +60,13 @@
var tile_layer_f0504d85580d46e4af996c2f88d5f7b3 = L.tileLayer(
var tile_layer_5648b0260ba418c1f4a1476413b7ab03 = L.tileLayer(
"https://tile.openstreetmap.org/{z}/{x}/{y}.png",
{"attribution": "\u0026copy; \u003ca href=\"https://www.openstreetmap.org/copyright\"\u003eOpenStreetMap\u003c/a\u003e contributors", "detectRetina": false, "maxNativeZoom": 19, "maxZoom": 19, "minZoom": 0, "noWrap": false, "opacity": 1, "subdomains": "abc", "tms": false}
);
tile_layer_f0504d85580d46e4af996c2f88d5f7b3.addTo(map_8347d9cd271667ca189c0f390ba735d0);
tile_layer_5648b0260ba418c1f4a1476413b7ab03.addTo(map_ca8b7d223851d008fcfc3af66a91f69a);
</script>
@ -87,7 +87,7 @@
}
trajeto_json_add({"features": []});
trajeto_json.addTo(map_8347d9cd271667ca189c0f390ba735d0);
trajeto_json.addTo(map_ca8b7d223851d008fcfc3af66a91f69a);
function adicionarGeometria(novaGeometria) {
trajeto_json.addData(novaGeometria);
@ -136,7 +136,7 @@
markerColor: 'red',
prefix: 'glyphicon'
})
}).addTo(map_8347d9cd271667ca189c0f390ba735d0);
}).addTo(map_ca8b7d223851d008fcfc3af66a91f69a);
// Conectar ao broker MQTT
const client = mqtt.connect('ws://localhost:9001'); // Use wss para conexão segura
@ -165,7 +165,7 @@
var novaPosicao = [novaLatitude, novaLongitude];
marcadorDinamico.setLatLng(novaPosicao);
adicionarCoordenada("Tj", [novaLongitude, novaLatitude]);
map_8347d9cd271667ca189c0f390ba735d0.setView(novaPosicao, map_8347d9cd271667ca189c0f390ba735d0.getZoom());
map_ca8b7d223851d008fcfc3af66a91f69a.setView(novaPosicao, map_ca8b7d223851d008fcfc3af66a91f69a.getZoom());
});
</script>
</html>

View File

@ -1 +1 @@
{"Conectado":false,"QuantidadeBicos":4,"DensidadeHerbicida":1.05,"CapacidadeReservatorio":30.0,"AtuacaoNivelAlto":true,"BicosPulverizadores":[{"ID":"B01","Posicao":1,"Atuado":true,"Comandar":true,"Inicializado":false,"Testando":false,"Funcoes":[21],"StatusBico":false,"MediaNivelFluxo":34.42987713140743},{"ID":"B02","Posicao":2,"Atuado":false,"Comandar":true,"Inicializado":false,"Testando":false,"Funcoes":[21],"StatusBico":false,"MediaNivelFluxo":14.876485059544191},{"ID":"B03","Posicao":3,"Atuado":false,"Comandar":true,"Inicializado":false,"Testando":false,"Funcoes":[21],"StatusBico":false,"MediaNivelFluxo":18.103588945512129},{"ID":"B04","Posicao":4,"Atuado":false,"Comandar":true,"Inicializado":false,"Testando":false,"Funcoes":[21],"StatusBico":false,"MediaNivelFluxo":18.437319738098896},{"ID":"B05","Posicao":5,"Atuado":false,"Comandar":false,"Inicializado":false,"Testando":false,"Funcoes":[21],"StatusBico":false,"MediaNivelFluxo":0.0},{"ID":"B06","Posicao":6,"Atuado":false,"Comandar":false,"Inicializado":false,"Testando":false,"Funcoes":[21],"StatusBico":false,"MediaNivelFluxo":0.0},{"ID":"B07","Posicao":7,"Atuado":false,"Comandar":false,"Inicializado":false,"Testando":false,"Funcoes":[21],"StatusBico":false,"MediaNivelFluxo":0.0},{"ID":"B08","Posicao":8,"Atuado":false,"Comandar":false,"Inicializado":false,"Testando":false,"Funcoes":[21],"StatusBico":false,"MediaNivelFluxo":0.0},{"ID":"B09","Posicao":9,"Atuado":false,"Comandar":false,"Inicializado":false,"Testando":false,"Funcoes":[21],"StatusBico":false,"MediaNivelFluxo":0.0},{"ID":"B10","Posicao":10,"Atuado":false,"Comandar":false,"Inicializado":false,"Testando":false,"Funcoes":[21],"StatusBico":false,"MediaNivelFluxo":0.0}],"BombaPressurizadora":{"ID":"BOMBA","BombaAtuada":false,"Ligado":false,"Comandar":true,"Inicializado":false,"Testando":false,"Funcoes":[14,35,36,37,5],"PressaoSP":85.0,"Pressao":82.01,"Potencia":0.0},"Sensores":[{"LogGrafico":[],"ID":"FLXLN","Prioridade":23,"Descricao":"Fluxo na linha principal","Componente":198,"Aferir":true,"DelayAmostragem":300,"Inicializado":false,"Testando":false,"Funcoes":[25],"Parametros":[],"UnidadeMedida":"mL/s","Leituras":[0.0,0.0],"ValorMinimo":0.0,"ValorMaximo":25222.0,"LimiteMaximo":0.0,"LimiteMinimo":0.0},{"LogGrafico":[],"ID":"MASRS","Prioridade":3,"Descricao":"Massa do reservatório de herbicida","Componente":532,"Aferir":true,"DelayAmostragem":1000,"Inicializado":false,"Testando":false,"Funcoes":[22,23],"Parametros":[],"UnidadeMedida":"Kg","Leituras":[1117263.12],"ValorMinimo":-1.281631101976581E+32,"ValorMaximo":2.8836731440342142E+24,"LimiteMaximo":50.0,"LimiteMinimo":5.0},{"LogGrafico":[],"ID":"PRSLN","Prioridade":3,"Descricao":"Pressão na linha principal","Componente":333,"Aferir":true,"DelayAmostragem":1000,"Inicializado":false,"Testando":false,"Funcoes":[24],"Parametros":[["Vmin","000.00"],["Vmax","004.50"],["Pmax","174.04"]],"UnidadeMedida":"psi","Leituras":[82.01],"ValorMinimo":0.0,"ValorMaximo":127.63,"LimiteMaximo":120.0,"LimiteMinimo":60.0}],"PercentualInicioPulverizacao":0.3,"ScriptDeteccaoErvas":"weed-detector-v7.py","_MassaRef":0.8,"_MassaLeituraRef":40876.37,"_MassaLeituraExtra":1895800.0,"_MassaLeitura":1117263.12,"MassaReservatorio":15.236908365395459,"VolumeReservatorio":14.511341300376627,"PercentualReservatorio":48.371137667922085,"VolumeVazaoAferido":102.0,"_FluxoMlRef":102.0,"_FluxoPulsoRef":80.0,"_LeituraPulsos":0,"_LeituraPeriodo":0,"VazaoFluxoMLpS":0.0,"VolumeVazaoML":0.0,"_PressaoVmin":0.0,"_PressaoVmax":4.5,"_PressaoMax":174.045,"_LeituraPressao":2631.0,"PressaoLinha":82.01,"PressaoLinhaCalc":82.0030336996337}
{"Conectado":false,"QuantidadeBicos":4,"DensidadeHerbicida":1.05,"CapacidadeReservatorio":30.0,"AtuacaoNivelAlto":true,"BicosPulverizadores":[{"ID":"B01","Posicao":1,"Atuado":false,"Comandar":true,"Inicializado":false,"Testando":false,"Funcoes":[21],"StatusBico":false,"MediaNivelFluxo":34.42987713140743},{"ID":"B02","Posicao":2,"Atuado":false,"Comandar":true,"Inicializado":false,"Testando":false,"Funcoes":[21],"StatusBico":false,"MediaNivelFluxo":14.876485059544191},{"ID":"B03","Posicao":3,"Atuado":false,"Comandar":true,"Inicializado":false,"Testando":false,"Funcoes":[21],"StatusBico":false,"MediaNivelFluxo":18.103588945512129},{"ID":"B04","Posicao":4,"Atuado":false,"Comandar":true,"Inicializado":false,"Testando":false,"Funcoes":[21],"StatusBico":false,"MediaNivelFluxo":18.437319738098896},{"ID":"B05","Posicao":5,"Atuado":false,"Comandar":false,"Inicializado":false,"Testando":false,"Funcoes":[21],"StatusBico":false,"MediaNivelFluxo":0.0},{"ID":"B06","Posicao":6,"Atuado":false,"Comandar":false,"Inicializado":false,"Testando":false,"Funcoes":[21],"StatusBico":false,"MediaNivelFluxo":0.0},{"ID":"B07","Posicao":7,"Atuado":false,"Comandar":false,"Inicializado":false,"Testando":false,"Funcoes":[21],"StatusBico":false,"MediaNivelFluxo":0.0},{"ID":"B08","Posicao":8,"Atuado":false,"Comandar":false,"Inicializado":false,"Testando":false,"Funcoes":[21],"StatusBico":false,"MediaNivelFluxo":0.0},{"ID":"B09","Posicao":9,"Atuado":false,"Comandar":false,"Inicializado":false,"Testando":false,"Funcoes":[21],"StatusBico":false,"MediaNivelFluxo":0.0},{"ID":"B10","Posicao":10,"Atuado":false,"Comandar":false,"Inicializado":false,"Testando":false,"Funcoes":[21],"StatusBico":false,"MediaNivelFluxo":0.0}],"BombaPressurizadora":{"ID":"BOMBA","BombaAtuada":false,"Ligado":false,"Comandar":true,"Inicializado":false,"Testando":false,"Funcoes":[14,35,36,37,5],"PressaoSP":85.0,"Pressao":82.01,"Potencia":0.0},"Sensores":[{"LogGrafico":[],"ID":"FLXLN","Prioridade":23,"Descricao":"Fluxo na linha principal","Componente":198,"Aferir":true,"DelayAmostragem":300,"Inicializado":false,"Testando":false,"Funcoes":[25],"Parametros":[],"UnidadeMedida":"mL/s","Leituras":[0.0,0.0],"ValorMinimo":0.0,"ValorMaximo":25222.0,"LimiteMaximo":0.0,"LimiteMinimo":0.0},{"LogGrafico":[],"ID":"MASRS","Prioridade":3,"Descricao":"Massa do reservatório de herbicida","Componente":532,"Aferir":true,"DelayAmostragem":1000,"Inicializado":false,"Testando":false,"Funcoes":[22,23],"Parametros":[],"UnidadeMedida":"Kg","Leituras":[1117263.12],"ValorMinimo":-1.281631101976581E+32,"ValorMaximo":2.8836731440342142E+24,"LimiteMaximo":50.0,"LimiteMinimo":5.0},{"LogGrafico":[],"ID":"PRSLN","Prioridade":3,"Descricao":"Pressão na linha principal","Componente":333,"Aferir":true,"DelayAmostragem":1000,"Inicializado":false,"Testando":false,"Funcoes":[24],"Parametros":[["Vmin","000.00"],["Vmax","004.50"],["Pmax","174.04"]],"UnidadeMedida":"psi","Leituras":[82.01],"ValorMinimo":0.0,"ValorMaximo":127.63,"LimiteMaximo":120.0,"LimiteMinimo":60.0}],"PercentualInicioPulverizacao":0.3,"ScriptDeteccaoErvas":"weed-detector-v7.py","_MassaRef":0.8,"_MassaLeituraRef":40876.37,"_MassaLeituraExtra":1895800.0,"_MassaLeitura":1117263.12,"MassaReservatorio":15.236908365395459,"VolumeReservatorio":14.511341300376627,"PercentualReservatorio":48.371137667922085,"VolumeVazaoAferido":102.0,"_FluxoMlRef":102.0,"_FluxoPulsoRef":80.0,"_LeituraPulsos":0,"_LeituraPeriodo":0,"VazaoFluxoMLpS":0.0,"VolumeVazaoML":0.0,"_PressaoVmin":0.0,"_PressaoVmax":4.5,"_PressaoMax":174.045,"_LeituraPressao":2631.0,"PressaoLinha":82.01,"PressaoLinhaCalc":82.0030336996337}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,8 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
"version": "0.2.0",
"configurations": [
]
}

View File

@ -0,0 +1,884 @@
// Dispositivo: Atuador
// Versão Firmware: 6
// Ultima atualização: 04/04/2024
// Atualização: Adicionado enfileiramento de mensageria
#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 "HX711.h"
#include <PID_v1.h>
#include <SimpleKalmanFilter.h>
#define D_Code Atu
#define VERSION 6
#define _pinoLED RGB_BUILTIN
long _baudRate = 115200;
bool Conectado = false;
int _TaxaAmostragem = 500;
int BicosAtivos = 10;
bool AtuacaoNivelAlto = true;
static double _PressaoAtual = 0.0;
class BicoPulverizador {
public:
// Construtor
BicoPulverizador(String desc) {
_ID = desc;
}
// Definições
String _ID;
int _posicao;
PinoModel _pinoSolenoide;
bool Iniciado = false;
bool Testando = false;
// Consumo
bool StatusBico;
// Entrada de dados
bool _BicoAtuado = !AtuacaoNivelAlto;
void Inicializar() {
if (Iniciado) {
EnviarDadosSerial(_ID + " ja inicializado");
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
return;
}
_BicoAtuado = !AtuacaoNivelAlto;
_pinoSolenoide.Conectar(_BicoAtuado);
StatusBico = _pinoSolenoide.get() == (AtuacaoNivelAlto ? 1 : 0);
xTaskCreatePinnedToCore(&BicoPulverizador::SensorTaskWrapper, "SensorTask", 5000, this, 25 - _posicao, &SensorTaskHandle, tskNO_AFFINITY);
EnviarDadosSerial(_ID + " Iniciado");
Iniciado = true;
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
}
void Desligar() {
if (!Iniciado) {
EnviarDadosSerial(_ID + " nao esta inicializado");
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
return;
}
// Parar a execução das tarefas
vTaskDelete(SensorTaskHandle);
// Redefinir as configurações para os valores iniciais
_pinoSolenoide.Desconectar();
EnviarDadosSerial(_ID + " Desligado");
Iniciado = false;
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
}
void AlterarStatusBico() {
_pinoSolenoide.set(_BicoAtuado);
StatusBico = _pinoSolenoide.get() == (AtuacaoNivelAlto ? 1 : 0);
}
private:
TaskHandle_t SensorTaskHandle = NULL;
static void SensorTaskWrapper(void *pvParameters) {
BicoPulverizador *bico = static_cast<BicoPulverizador*>(pvParameters);
bico->SensorTask();
}
void SensorTask() {
unsigned long previousMillisLeitura = millis();
while (1)
{
if (!Conectado) {
// Caso não esteja conectado, aguarda 1 segundo até a próxima verificação, liberando uso de CPU
vTaskDelay(1000);
continue;
}
unsigned long currentMillis = millis();
if ((currentMillis - previousMillisLeitura) >= _TaxaAmostragem) {
previousMillisLeitura = currentMillis;
EnviarDadosSerial(MontarProtocoloSensor(sBIC, _ID, MontarDadosProtocoloBicoPulverizador(StatusBico)));
}
vTaskDelay(1);
}
}
};
class BombaPressurizadora {
public:
// Construtor
BombaPressurizadora(String desc) {
_ID = desc;
}
// Definições
String _ID;
PinoModel _pinoEN;
PinoModel _pinoCS;
PinoModel _pinoINA;
PinoModel _pinoINB;
PinoModel _pinoPWM;
double _Kp = 3.0;
double _Ki = 2.2;
double _Kd = 0.5;
PID* _PID = nullptr;
int ZeroRampa = 0;
int RampaMax = 1023;
bool Iniciado = false;
bool Testando = false;
int _canal = 0;
// Consumo
bool Ligado;
double PotenciaAtual = 0;
// Entrada de dados
double _PressaoSP = 0;
bool _BombaAtuada = false;
void Inicializar() {
if (Iniciado) {
EnviarDadosSerial(_ID + " ja inicializado");
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
return;
}
_BombaAtuada = false;
_pinoEN.Conectar(_BombaAtuada);
Ligado = _pinoEN.get() == 1;
_pinoCS.Conectar();
_pinoINA.Conectar(false);
_pinoINB.Conectar(true);
if (_pinoPWM.Definido()) {
ledcSetup(_canal, 1000, 10);
ledcAttachPin(_pinoPWM.num, _canal);
PotenciaAtual = 0;
_PressaoSP = 0;
ledcWrite(_canal, PotenciaAtual);
}
_PID = new PID(&_PressaoAtual, &PotenciaAtual, &_PressaoSP, _Kp, _Ki, _Kd, DIRECT);
_PID->SetOutputLimits(ZeroRampa, RampaMax);
_PID->SetMode(AUTOMATIC);
xTaskCreatePinnedToCore(&BombaPressurizadora::SensorTaskWrapper, "SensorTask", 15000, this, 25, &SensorTaskHandle, tskNO_AFFINITY);
EnviarDadosSerial(_ID + " Iniciado");
Iniciado = true;
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
}
void Desligar() {
if (!Iniciado) {
EnviarDadosSerial(_ID + " nao esta inicializado");
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
return;
}
// Parar a execução das tarefas
vTaskDelete(SensorTaskHandle);
// Redefinir as configurações para os valores iniciais
_pinoPWM.Desconectar();
_pinoEN.Desconectar();
_pinoCS.Desconectar();
_pinoINA.Desconectar();
_pinoINB.Desconectar();
_pinoPWM.Desconectar();
// Outras redefinições de variáveis de estado, se necessário
delete _PID;
EnviarDadosSerial(_ID + " Desligado");
Iniciado = false;
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
}
void AlterarStatusBomba() {
_pinoEN.set(_BombaAtuada);
Ligado = _pinoEN.get() == 1;
}
private:
TaskHandle_t SensorTaskHandle = NULL;
static void SensorTaskWrapper(void *pvParameters) {
BombaPressurizadora *bomba = static_cast<BombaPressurizadora*>(pvParameters);
bomba->SensorTask();
}
void SensorTask() {
unsigned long previousMillisLeitura = millis();
const int histerese = -5; // Valor de histerese em unidades de pressão
bool bombaDesligadaPorPressao = false;
while (1)
{
if (!Conectado) {
// Caso não esteja conectado, aguarda 1 segundo até a próxima verificação, liberando uso de CPU
vTaskDelay(1000);
continue;
}
// 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 (!_BombaAtuada || bombaDesligadaPorPressao) {
PotenciaAtual = ZeroRampa;
} else {
_PID->Compute();
// Ajusta PotenciaAtual com base no PID
}
ledcWrite(_canal, PotenciaAtual);
unsigned long currentMillis = millis();
if ((currentMillis - previousMillisLeitura) >= _TaxaAmostragem) {
previousMillisLeitura = currentMillis;
AtualizarStatusSensor();
}
vTaskDelay(1);
}
}
void AtualizarStatusSensor() {
Ligado = _pinoEN.get() == 1;
float PercentualPotencia = (PotenciaAtual / RampaMax) * 100;
EnviarDadosSerial(MontarProtocoloSensor(sBMB, _ID, MontarDadosProtocoloBombaPressurizadora(Ligado, PercentualPotencia)));
}
};
class SensorFluxo {
public:
SensorFluxo(String desc) {
_ID = desc;
}
// Definições
String _ID;
S_Code _componente = sFLX;
PinoModel _pino;
int _delayAmostragem;
int _prioridade;
float _calibragem;
bool Iniciado = false;
// Consumo
volatile int ultimaLeitura = 0;
volatile unsigned int tempoAnterior = 0;
void Inicializar() {
if (Iniciado) {
EnviarDadosSerial(_ID + " ja inicializado");
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
return;
}
_pino.Conectar();
ultimaLeitura = _pino.get();
tempoAnterior = 0;
xTaskCreatePinnedToCore(&SensorFluxo::SFTaskWrapper, "SFTask", 10000, this, _prioridade, &SFTaskHandle, tskNO_AFFINITY);
EnviarDadosSerial(_ID + " Iniciado");
Iniciado = true;
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
}
void Desligar() {
if (!Iniciado) {
EnviarDadosSerial(_ID + " nao esta inicializado");
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
return;
}
// Parar a execução das tarefas
vTaskDelete(SFTaskHandle);
// Redefinir as configurações para os valores iniciais
_pino.Desconectar();
EnviarDadosSerial(_ID + " Desligado");
Iniciado = false;
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
}
private:
TaskHandle_t SFTaskHandle = NULL;
static void SFTaskWrapper(void *pvParameters) {
SensorFluxo *sensor = static_cast<SensorFluxo*>(pvParameters);
sensor->SFTask();
}
void SFTask() {
unsigned long firstMilis = millis();
volatile int pulsos = 0;
volatile int pulsosA = 0;
volatile float periodo = 0;
volatile float periodoTotal = 0;
while (1)
{
if (!Conectado) {
// Caso não esteja conectado, aguarda 1 segundo até a próxima verificação, liberando uso de CPU
vTaskDelay(1000);
continue;
}
bool Leitura = _pino.get() == 1;
if (Leitura != ultimaLeitura) {
ultimaLeitura = Leitura;
pulsos++;
// Calcular o período em microssegundos
unsigned long tempoAtual = micros();
unsigned long periodoUs = pulsos == 1 ? 0 : (tempoAtual - tempoAnterior);
periodo = periodoUs / 1000.0; // Converte de us para ms (2300 us para 2,3 ms)
periodoTotal += periodo;
//CalcularFluxo(periodo);
tempoAnterior = tempoAtual;
}
long intMillis = (millis() - firstMilis);
int Tempo = _TaxaAmostragem + _delayAmostragem;
// A cada _TaxaAmostragem, enviar os dados para o software
if (intMillis >= Tempo) {
if (pulsos == pulsosA) {
periodoTotal = 0;
pulsos = 0;
}
EnviarDadosSerial(MontarProtocoloSensor(sFLX, _ID, MontarDadosProtocoloFluxo(pulsos, periodoTotal)));
pulsosA = pulsos;
firstMilis = millis();
}
// Aguarda metade do menor período possível entre leituras
vTaskDelay(1);
}
}
};
class SensorMassa {
public:
SensorMassa(String desc) {
_ID = desc;
}
// Definições
String _ID;
S_Code _componente = sMAS;
PinoModel _pinoDT;
PinoModel _pinoSCK;
int _delayAmostragem;
int _prioridade;
HX711* balanca = nullptr;
SimpleKalmanFilter* filtro = nullptr;
bool Iniciado = false;
void Inicializar() {
if (Iniciado) {
EnviarDadosSerial(_ID + " ja inicializado");
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
return;
}
if (_pinoDT.Definido() && _pinoSCK.Definido()) {
balanca = new HX711();
filtro = new SimpleKalmanFilter(2, 2, 0.01);
balanca->begin(_pinoDT.num, _pinoSCK.num);
balanca->set_scale();
//balanca->tare();
}
xTaskCreatePinnedToCore(&SensorMassa::SMTaskWrapper, "SMTask", 5000, this, _prioridade, &SMTaskHandle, tskNO_AFFINITY);
EnviarDadosSerial(_ID + " Iniciado");
Iniciado = true;
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
}
void Desligar() {
if (!Iniciado) {
EnviarDadosSerial(_ID + " nao esta inicializado");
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
return;
}
delete balanca;
delete filtro;
// Parar a execução das tarefas
vTaskDelete(SMTaskHandle);
// Redefinir as configurações para os valores iniciais
_pinoDT.Desconectar();
_pinoSCK.Desconectar();
EnviarDadosSerial(_ID + " Desligado");
Iniciado = false;
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
}
private:
TaskHandle_t SMTaskHandle = NULL;
static void SMTaskWrapper(void *pvParameters) {
SensorMassa *sensor = static_cast<SensorMassa*>(pvParameters);
sensor->SMTask();
}
void SMTask() {
unsigned long firstMilis = millis();
while (1)
{
if (!Conectado) {
// Caso não esteja conectado, aguarda 1 segundo até a próxima verificação, liberando uso de CPU
vTaskDelay(1000);
continue;
}
long intMillis = (millis() - firstMilis);
// A cada _TaxaAmostragem, enviar os dados para o software
if (intMillis >= (_TaxaAmostragem + _delayAmostragem)) {
AferirMassa();
firstMilis = millis();
}
// Aguarda metade do menor período possível entre leituras
vTaskDelay(1);
}
}
void AferirMassa() {
float leitura = balanca->get_units(5);
double leituraNormalizada = filtro->updateEstimate(leitura);
EnviarDadosSerial(MontarProtocoloSensor(sMAS, _ID, MontarDadosProtocoloMassa(leituraNormalizada)));
}
};
class SensorPressao {
public:
SensorPressao(String desc) {
_ID = desc;
}
// Definições
String _ID;
S_Code _componente = sPRS;
PinoModel _pino;
int _delayAmostragem;
int _prioridade;
double _Vmin = 0.0;
double _Vmax = 4.5;
double _Pmax = 174.045;
SimpleKalmanFilter* filtro = nullptr;
bool Iniciado = false;
void Inicializar() {
if (Iniciado) {
EnviarDadosSerial(_ID + " ja inicializado");
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
return;
}
_pino.Conectar();
filtro = new SimpleKalmanFilter(2, 2, 0.01);
xTaskCreatePinnedToCore(&SensorPressao::SPTaskWrapper, "SPTask", 5000, this, _prioridade, &SPTaskHandle, tskNO_AFFINITY);
EnviarDadosSerial(_ID + " Iniciado");
Iniciado = true;
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
}
void Desligar() {
if (!Iniciado) {
EnviarDadosSerial(_ID + " nao esta inicializado");
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
return;
}
delete filtro;
// Parar a execução das tarefas
vTaskDelete(SPTaskHandle);
// Redefinir as configurações para os valores iniciais
_pino.Desconectar();
EnviarDadosSerial(_ID + " Desligado");
Iniciado = false;
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
}
private:
double leituraNormalizada = 0.0;
TaskHandle_t SPTaskHandle = NULL;
static void SPTaskWrapper(void *pvParameters) {
SensorPressao *sensor = static_cast<SensorPressao*>(pvParameters);
sensor->SPTask();
}
void SPTask() {
unsigned long firstMilis = millis();
while (1)
{
if (!Conectado) {
// Caso não esteja conectado, aguarda 1 segundo até a próxima verificação, liberando uso de CPU
vTaskDelay(1000);
continue;
}
AferirPressao();
long intMillis = (millis() - firstMilis);
// A cada _TaxaAmostragem, enviar os dados para o software
if (intMillis >= (_TaxaAmostragem + _delayAmostragem)) {
EnviarDadosSerial(MontarProtocoloSensor(sPRS, _ID, MontarDadosProtocoloPressao(_PressaoAtual, leituraNormalizada)));
firstMilis = millis();
}
// Aguarda metade do menor período possível entre leituras
vTaskDelay(1);
}
}
void AferirPressao() {
int leitura = _pino.get();
leituraNormalizada = filtro->updateEstimate(leitura);
double tensao = fmap(leituraNormalizada, 0.0, 4095.0, 0.0, 3300.0) / 1000.0;
_PressaoAtual = fmap(tensao, _Vmin, _Vmax, 0.0, _Pmax);
}
};
BicoPulverizador B_01("B01");
BicoPulverizador B_02("B02");
BicoPulverizador B_03("B03");
BicoPulverizador B_04("B04");
BicoPulverizador B_05("B05");
BicoPulverizador B_06("B06");
BicoPulverizador B_07("B07");
BicoPulverizador B_08("B08");
BicoPulverizador B_09("B09");
BicoPulverizador B_10("B10");
BombaPressurizadora BOMBA("BOMBA");
SensorFluxo SenFlx("FLXLN");
SensorMassa SenMas("MASRS");
SensorPressao SenPrs("PRSLN");
BicoPulverizador* BicoPorID(String ID) {
BicoPulverizador* _bico =
ID == "B01" ? &B_01 :
ID == "B02" ? &B_02 :
ID == "B03" ? &B_03 :
ID == "B04" ? &B_04 :
ID == "B05" ? &B_05 :
ID == "B06" ? &B_06 :
ID == "B07" ? &B_07 :
ID == "B08" ? &B_08 :
ID == "B09" ? &B_09 :
ID == "B10" ? &B_10 :
nullptr;
return _bico;
}
BombaPressurizadora* BombaPorID(String ID) {
BombaPressurizadora* _bomba =
ID == "BOMBA" ? &BOMBA :
nullptr;
return _bomba;
}
SensorFluxo* SFPorID(String ID) {
SensorFluxo* _sensor =
ID == "FLXLN" ? &SenFlx :
nullptr;
return _sensor;
}
SensorMassa* SMPorID(String ID) {
SensorMassa* _sensor =
ID == "MASRS" ? &SenMas :
nullptr;
return _sensor;
}
SensorPressao* SPPorID(String ID) {
SensorPressao* _sensor =
ID == "PRSLN" ? &SenPrs :
nullptr;
return _sensor;
}
void ZerarPinos() {
//const int gpios[] = {2, 4, 5, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 25, 26, 27, 32, 33};
const int gpios[] = {4, 5, 6, 7, 15, 16, 17, 18, 8, 3, 46, 9, 10, 11, 12, 13, 14, 19, 20, 21, 47, 48, 45, 0, 35, 36, 37, 38, 39, 40, 41, 42, 2, 1};
for (int i = 0; i < sizeof(gpios) / sizeof(gpios[0]); i++) {
pinMode(gpios[i], OUTPUT);
digitalWrite(gpios[i], !AtuacaoNivelAlto);
}
}
void setup() {
Serial.begin(_baudRate);
ZerarPinos();
}
void loop() {
std::vector<ProtocoloSerial> protocolos = LerBufferSerialFila();
for (int i = 0; i < protocolos.size(); i++) {
ProcessarProtocolo(protocolos[i].protocolo, protocolos[i].funcao, protocolos[i].idMensagem);
}
}
void ProcessarProtocolo(String Protocolo, F_Code _funcao, int idMensagem) {
if (_funcao == Chk) {
EnviarDadosSerial(MontarProtocoloVerificacao(D_Code, VERSION));
}
else if (_funcao == Cfg) {
std::vector<String> Partes = SplitString(Protocolo, (char*)",");
String ID = Partes[0];
bool Conectar = Partes[1] == "1";
if (ID == "MD") {
_TaxaAmostragem = Partes[2].toInt();
bool _AtuaNivelAlto = Partes[3] == "1";
AtuacaoNivelAlto = _AtuaNivelAlto;
EnviarDadosSerial(MontarProtocoloSensor(sCFG, "MD", Conectar ? "1" : "0"));
vTaskDelay(pdMS_TO_TICKS(100));
Conectado = Conectar;
}
else {
BicoPulverizador* _bico = BicoPorID(ID);
BombaPressurizadora* _bomba = BombaPorID(ID);
if (_bico != nullptr) {
bool bico_ativado = Partes[2] == "1";
int posicao = Partes[3].toInt();
TiposBarramentos solenoideB = (TiposBarramentos)Partes[4].toInt();
int solenoide = Partes[5].toInt();
if (bico_ativado) {
if (Conectar) {
_bico->_posicao = posicao;
_bico->_pinoSolenoide = PinoModel(solenoide, solenoideB, _OUTPUT);
_bico->Inicializar();
}
else {
_bico->Desligar();
}
vTaskDelay(pdMS_TO_TICKS(500));
}
}
else if (_bomba != nullptr) {
bool bomba_ativada = Partes[2] == "1";
double pressaoSP = Partes[3].toDouble();
TiposBarramentos enB = (TiposBarramentos)Partes[4].toInt();
int pinoEN = Partes[5].toInt();
TiposBarramentos csB = (TiposBarramentos)Partes[6].toInt();
int pinoCS = Partes[7].toInt();
TiposBarramentos inaB = (TiposBarramentos)Partes[8].toInt();
int pinoINA = Partes[9].toInt();
TiposBarramentos inbB = (TiposBarramentos)Partes[10].toInt();
int pinoINB = Partes[11].toInt();
TiposBarramentos pwmB = (TiposBarramentos)Partes[12].toInt();
int pinoPWM = Partes[13].toInt();
if (bomba_ativada) {
if (Conectar) {
_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->Inicializar();
}
else {
_bomba->Desligar();
}
vTaskDelay(pdMS_TO_TICKS(500));
}
}
else {
S_Code componente = (S_Code)Partes[2].toInt();
bool sensor_ativado = Partes[3] == "1";
int delayAmostragem = Partes[4].toInt();
int prioridade = Partes[5].toInt();
TiposBarramentos pinoB = (TiposBarramentos)Partes[6].toInt();
int pino = Partes[7].toInt();
switch (componente) {
case sFLX: {
SensorFluxo* _sensor = SFPorID(ID);
if (sensor_ativado) {
if (Conectar) {
_sensor->_pino = PinoModel(pino, pinoB, _INPUT, DIGITAL);
_sensor->_prioridade = prioridade;
_sensor->_delayAmostragem = delayAmostragem;
_sensor->Inicializar();
}
else {
_sensor->Desligar();
}
}
break;
}
case sMAS: {
SensorMassa* _sensor = SMPorID(ID);
if (sensor_ativado) {
TiposBarramentos pino2B = (TiposBarramentos)Partes[8].toInt();
int pino2 = Partes[9].toInt();
if (Conectar) {
_sensor->_pinoDT = PinoModel(pino, pinoB, _INPUT, DIGITAL);
_sensor->_pinoSCK = PinoModel(pino2, pino2B, _INPUT, DIGITAL);
_sensor->_prioridade = prioridade;
_sensor->_delayAmostragem = delayAmostragem;
_sensor->Inicializar();
}
else {
_sensor->Desligar();
}
}
break;
}
case sPRS: {
SensorPressao* _sensor = SPPorID(ID);
if (sensor_ativado) {
double Vmin = Partes[8].toDouble();
double Vmax = Partes[9].toDouble();
double Pmax = Partes[10].toDouble();
if (Conectar) {
_sensor->_Vmin = Vmin;
_sensor->_Vmax = Vmax;
_sensor->_Pmax = Pmax;
_sensor->_pino = PinoModel(pino, pinoB, _INPUT, ANALOGICO);
_sensor->_prioridade = prioridade;
_sensor->_delayAmostragem = delayAmostragem;
_sensor->Inicializar();
}
else {
_sensor->Desligar();
}
}
break;
}
}
}
}
}
else if (_funcao == Cmd) {
std::vector<String> Partes = SplitString(Protocolo, (char*)",");
String ID = Partes[0];
BicoPulverizador* _bico = BicoPorID(ID);
BombaPressurizadora* _bomba = BombaPorID(ID);
if (_bico != nullptr) {
_bico->_BicoAtuado = Partes[1] == (AtuacaoNivelAlto ? "1" : "0");
_bico->AlterarStatusBico();
}
else if (_bomba != nullptr) {
_bomba->_BombaAtuada = Partes[1] == "1";
_bomba->_PressaoSP = Partes[2].toDouble();
_bomba->AlterarStatusBomba();
}
}
else if (_funcao == Tst) {
std::vector<String> Partes = SplitString(Protocolo, (char*)",");
String ID = Partes[0];
BicoPulverizador* _bico = BicoPorID(ID);
bool EmTeste = _bico->Testando;
if (!EmTeste) {
//_motor->Testar();
}
}
EnviarDadosSerial(MontarProtocoloMensagemRecebida(idMensagem));
}

View File

@ -1,6 +1,6 @@
// Dispositivo: Direcional
// Versão Firmware: 6
// Ultima atualização: 23/04/2024
// Ultima atualização: 26/04/2024
// Atualização: Adicionado enfileiramento de mensageria
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SerialService.h"
@ -466,11 +466,9 @@ void setup() {
}
void loop() {
ProtocoloSerial protocolos[MAX_PROTOCOLS];
int numProtocolos = LerBufferSerialID(protocolos);
std::vector<ProtocoloSerial> protocolos = LerBufferSerialFila();
// Processa cada protocolo após a leitura completa
for (int i = 0; i < numProtocolos; i++) {
for (int i = 0; i < protocolos.size(); i++) {
ProcessarProtocolo(protocolos[i].protocolo, protocolos[i].funcao, protocolos[i].idMensagem);
}
}
@ -478,94 +476,89 @@ void loop() {
void ProcessarProtocolo(String Protocolo, F_Code _funcao, int idMensagem) {
if (_funcao == Chk) {
EnviarDadosSerial(MontarProtocoloVerificacao(D_Code, VERSION));
EnviarDadosSerial(MontarProtocoloVerificacao(D_Code, VERSION));
}
else if (_funcao == Cfg) {
std::vector<String> Partes = SplitString(Protocolo, (char*)",");
String ID = Partes[0];
bool Conectar = Partes[1] == "1";
if (ID == "MD") {
_TaxaAmostragem = Partes[2].toInt();
AA_Ref000 = Partes[3] == "1";
AA_Ref090 = Partes[4] == "1";
AA_Ref270 = Partes[5] == "1";
TiposBarramentos _barramento = (TiposBarramentos)Partes[6].toInt();
int _num = Partes[7].toInt();
_pinoGeral = PinoModel(_num, _barramento, _OUTPUT);
EnviarDadosSerial(MontarProtocoloMensagemRecebida(idMensagem));
if (_funcao == Cfg) {
String ID = ((String)Protocolo[0] + (String)Protocolo[1]);
bool Conectar = (String)Protocolo[3] == "1";
if (ID == "MD") {
_TaxaAmostragem = ((String)Protocolo[5] + (String)Protocolo[6] + (String)Protocolo[7] + (String)Protocolo[8] + (String)Protocolo[9]).toInt();
AA_Ref000 = (String)Protocolo[11] == "1";
AA_Ref090 = (String)Protocolo[13] == "1";
AA_Ref270 = (String)Protocolo[15] == "1";
TiposBarramentos _barramento = (TiposBarramentos)((String)Protocolo[17]).toInt();
int _num = ((String)Protocolo[18] + (String)Protocolo[19]).toInt();
_pinoGeral = PinoModel(_num, _barramento, _OUTPUT);
if (_pinoGeral.Definido()) {
_pinoGeral.set(true);
}
vTaskDelay(pdMS_TO_TICKS(100));
Conectado = Conectar;
EnviarDadosSerial(MontarProtocoloSensor(sCFG, "MD", Conectado ? "1" : "0"));
if (_pinoGeral.Definido()) {
_pinoGeral.set(true);
}
else {
Motor* _motor = MotorPorID(ID);
int canal = ((String)Protocolo[5]).toInt();
bool motor_ativado = ((String)Protocolo[7]) == "1";
bool estabilizar = ((String)Protocolo[9]) == "1";
bool referenciar = ((String)Protocolo[11]) == "1";
int _offset = ((String)Protocolo[13] + (String)Protocolo[14] + (String)Protocolo[15] + (String)Protocolo[16]).toInt();
TiposBarramentos pulB = (TiposBarramentos)((String)Protocolo[18]).toInt();
int pul = ((String)Protocolo[19] + (String)Protocolo[20]).toInt();
TiposBarramentos dirB = (TiposBarramentos)((String)Protocolo[22]).toInt();
int dir = ((String)Protocolo[23] + (String)Protocolo[24]).toInt();
TiposBarramentos enaB = (TiposBarramentos)((String)Protocolo[26]).toInt();
int ena = ((String)Protocolo[27] + (String)Protocolo[28]).toInt();
TiposBarramentos encAB = (TiposBarramentos)((String)Protocolo[30]).toInt();
int encoderA = ((String)Protocolo[31] + (String)Protocolo[32]).toInt();
TiposBarramentos encBB = (TiposBarramentos)((String)Protocolo[34]).toInt();
int encoderB = ((String)Protocolo[35] + (String)Protocolo[36]).toInt();
TiposBarramentos ref0B = (TiposBarramentos)((String)Protocolo[38]).toInt();
int ref0 = ((String)Protocolo[39] + (String)Protocolo[40]).toInt();
TiposBarramentos ref90B = (TiposBarramentos)((String)Protocolo[42]).toInt();
int ref90 = ((String)Protocolo[43] + (String)Protocolo[44]).toInt();
TiposBarramentos ref270B = (TiposBarramentos)((String)Protocolo[46]).toInt();
int ref270 = ((String)Protocolo[47] + (String)Protocolo[48]).toInt();
EnviarDadosSerial(MontarProtocoloSensor(sCFG, "MD", Conectar ? "1" : "0"));
vTaskDelay(pdMS_TO_TICKS(100));
Conectado = Conectar;
}
else {
Motor* _motor = MotorPorID(ID);
int canal = Partes[2].toInt();
bool motor_ativado = Partes[3] == "1";
bool estabilizar = Partes[4] == "1";
bool referenciar = Partes[5] == "1";
int _offset = Partes[6].toInt();
TiposBarramentos pulB = (TiposBarramentos)Partes[7].toInt();
int pul = Partes[8].toInt();
TiposBarramentos dirB = (TiposBarramentos)Partes[9].toInt();
int dir = Partes[10].toInt();
TiposBarramentos enaB = (TiposBarramentos)Partes[11].toInt();
int ena = Partes[12].toInt();
TiposBarramentos encAB = (TiposBarramentos)Partes[13].toInt();
int encoderA = Partes[14].toInt();
TiposBarramentos encBB = (TiposBarramentos)Partes[15].toInt();
int encoderB = Partes[16].toInt();
TiposBarramentos ref0B = (TiposBarramentos)Partes[17].toInt();
int ref0 = Partes[18].toInt();
TiposBarramentos ref90B = (TiposBarramentos)Partes[19].toInt();
int ref90 = Partes[20].toInt();
TiposBarramentos ref270B = (TiposBarramentos)Partes[21].toInt();
int ref270 = Partes[22].toInt();
if (motor_ativado) {
if (Conectar) {
_motor->_canal = canal;
_motor->_Estabilizar = estabilizar;
_motor->_Referenciar = referenciar;
_motor->_Angulo_Offset = _offset;
_motor->_pinoPUL = PinoModel(pul, pulB, _PWM);
_motor->_pinoDIR = PinoModel(dir, dirB, _OUTPUT);
_motor->_pinoENA = PinoModel(ena, enaB, _OUTPUT);
_motor->_pinoEncoderA = PinoModel(encoderA, encAB, _INPUT, DIGITAL);
_motor->_pinoEncoderB = PinoModel(encoderB, encBB, _INPUT, DIGITAL);
_motor->_pinoRef000 = PinoModel(ref0, ref0B, _INPUT, DIGITAL);
_motor->_pinoRef090 = PinoModel(ref90, ref90B, _INPUT, DIGITAL);
_motor->_pinoRef270 = PinoModel(ref270, ref270B, _INPUT, DIGITAL);
_motor->Inicializar();
}
else {
_motor->Desligar();
}
vTaskDelay(500);
if (motor_ativado) {
if (Conectar) {
_motor->_canal = canal;
_motor->_Estabilizar = estabilizar;
_motor->_Referenciar = referenciar;
_motor->_Angulo_Offset = _offset;
_motor->_pinoPUL = PinoModel(pul, pulB, _PWM);
_motor->_pinoDIR = PinoModel(dir, dirB, _OUTPUT);
_motor->_pinoENA = PinoModel(ena, enaB, _OUTPUT);
_motor->_pinoEncoderA = PinoModel(encoderA, encAB, _INPUT, DIGITAL);
_motor->_pinoEncoderB = PinoModel(encoderB, encBB, _INPUT, DIGITAL);
_motor->_pinoRef000 = PinoModel(ref0, ref0B, _INPUT, DIGITAL);
_motor->_pinoRef090 = PinoModel(ref90, ref90B, _INPUT, DIGITAL);
_motor->_pinoRef270 = PinoModel(ref270, ref270B, _INPUT, DIGITAL);
_motor->Inicializar();
}
else {
_motor->Desligar();
}
vTaskDelay(500);
}
}
}
else if (_funcao == Cmd) {
//canal;sentido;angulo
//0;0;000.00
String ID = ((String)Protocolo[0] + (String)Protocolo[1]);
std::vector<String> Partes = SplitString(Protocolo, (char*)",");
String ID = Partes[0];
Motor* _motor = MotorPorID(ID);
Sentido sentido = (Sentido)((String)Protocolo[3]).toInt();
int angulo = ((String)Protocolo[5] + (String)Protocolo[6] + (String)Protocolo[7]).toInt();
int porcentagem = ((String)Protocolo[9] + (String)Protocolo[10] + (String)Protocolo[11]).toInt();
Sentido sentido = (Sentido)Partes[1].toInt();
int angulo = Partes[2].toInt();
int porcentagem = Partes[3].toInt();
double frequencia = (porcentagem / 100.0) * FrequenciaMaxima;
bool referenciar = ((String)Protocolo[13]) == "1";
int _offset = ((String)Protocolo[15] + (String)Protocolo[16] + (String)Protocolo[17] + (String)Protocolo[18]).toInt();
bool referenciar = Partes[4] == "1";
int _offset = Partes[5].toInt();
_frequencia = frequencia;
@ -583,15 +576,18 @@ void ProcessarProtocolo(String Protocolo, F_Code _funcao, int idMensagem) {
}
}
else if (_funcao == Tst) {
String ID = ((String)Protocolo[0] + (String)Protocolo[1]);
std::vector<String> Partes = SplitString(Protocolo, (char*)",");
String ID = Partes[0];
Motor* _motor = MotorPorID(ID);
Motor* _motor = MotorPorID(ID);
bool EmTeste = _motor->Testando;
if (!EmTeste) {
_motor->Testar();
}
bool EmTeste = _motor->Testando;
if (!EmTeste) {
_motor->Testar();
}
}
EnviarDadosSerial(MontarProtocoloMensagemRecebida(idMensagem));
}

View File

@ -1,8 +1,10 @@
#include "Enuns.h"
#include <vector>
#ifndef SerialService
#define SerialService
const char BeginLine = '@';
const char EndLine = '$';
const char BeginSensor = '#';
const int MAX_PROTOCOLS = 20;
@ -42,41 +44,57 @@ int LerBufferSerial(ProtocoloSerial (&protocolos)[MAX_PROTOCOLS]) {
return protocolCount; // Retorna o número de protocolos lidos
}
int LerBufferSerialID(ProtocoloSerial (&protocolos)[MAX_PROTOCOLS]) {
int protocolCount = 0; // Contador de protocolos
if (Serial.available() > 0) {
String protocoloAtual = "";
F_Code _funcaoAtual = Nda;
int _id = 0;
std::vector<String> SplitString(String message, const char *delimiter) {
std::vector<String> partes;
char messageArray[256];
message.toCharArray(messageArray, sizeof(messageArray));
char *token = strtok(messageArray, delimiter);
while (token != nullptr) {
partes.push_back(String(token));
token = strtok(nullptr, delimiter);
}
return partes;
}
std::vector<ProtocoloSerial> LerBufferSerialFila() {
std::vector<ProtocoloSerial> protocolos;
if (Serial.available() > 0) {
bool ProtocoloIniciado = false;
String protocoloAtual = "";
while (Serial.available()) {
char entrada = (char)Serial.read();
if (entrada == EndLine) {
if (protocoloAtual.length() > 0 && protocolCount < MAX_PROTOCOLS) {
protocolos[protocolCount].funcao = _funcaoAtual;
protocolos[protocolCount].protocolo = protocoloAtual;
protocolos[protocolCount].idMensagem = _id;
protocolCount++;
//protocoloAtual = ""; // Reseta o protocolo atual
//_funcaoAtual = Nda;
if (entrada == BeginLine) {
ProtocoloIniciado = true;
}
else if (entrada == EndLine) {
ProtocoloIniciado = false;
if (protocoloAtual.length() > 0) {
std::vector<String> partes = SplitString(protocoloAtual, (char*)";");
if (partes.size() == 3) {
ProtocoloSerial objeto;
objeto.idMensagem = partes[0].toInt();
objeto.funcao = (F_Code)(partes[1].toInt());
objeto.protocolo = partes[2];
protocolos.push_back(objeto);
}
break;
}
} else if ((String)entrada == ";" && _id == 0) {
_id = protocoloAtual.toInt();
protocoloAtual = "";
} else if ((String)entrada == ";" && _funcaoAtual == Nda) {
_funcaoAtual = (F_Code)(protocoloAtual.toInt());
protocoloAtual = "";
}
else {
} else if (ProtocoloIniciado) {
protocoloAtual += entrada;
}
}
}
return protocolCount; // Retorna o número de protocolos lidos
return protocolos;
}
void EnviarDadosSerial(String Mensagem) {
Serial.println(Mensagem);
Serial.flush();

View File

@ -0,0 +1,607 @@
// Dispositivo: Movimentação
// Versão Firmware: 18
// Ultima atualização: 26/04/2024
// Atualização: Adicionado enfileiramento de mensageria
#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 <PID_v1.h>
#define D_Code Mov
#define VERSION 18
#define _pinoLED RGB_BUILTIN
long _baudRate = 115200;
bool Conectado = false;
int _TaxaAmostragem = 500;
int PPR = 22; // Pulsos por revolução
int RampaMin = 0;
int ZeroRampa = 0;
int RampaMax = 1023;
const int RpmMax = 650; // RPM Máximo aferir
float RelacaoPPR = 0;
float MenorPeriodo = 0;
int delayBalanceamento = 5000;
float RPM_Offset_Max = 25.0;
float RPM_Margem = 5.0;
float RPM_SetPoint = 0.0;
float RPM_Medio = 0.0;
bool RPM_Estavel = true;
class Motor {
public:
// Construtor
Motor(String desc) {
_ID = desc;
}
// Definições
String _ID;
int _canal;
PinoModel _pinoPWM;
PinoModel _pinoDIR;
PinoModel _pinoBRK;
PinoModel _pinoSTP;
PinoModel _pinoHLA;
PinoModel _pinoHLB;
PinoModel _pinoHLC;
double _Kp;
double _Ki;
double _Kd;
PID* _PID = nullptr;
bool Iniciado = false;
bool Testando = false;
bool Revertendo = false;
bool SentidoContrario = false;
StatusMotor Aceleracao = Estavel;
StatusMotor AceleracaoA = Estavel;
// Consumo
const int leituras = 5;
volatile float RPM_arr[5];
volatile bool Hall_arr[5][3];
double RPM;
double PotenciaAtual;
volatile int ultimaLeituraHallA = 0;
volatile int ultimaLeituraHallB = 0;
volatile int ultimaLeituraHallC = 0;
volatile unsigned int tempoAnterior = 0;
volatile float periodo = 0;
// Entrada de dados
bool _MalhaFechada = true;
int _PotMap;
double _RPM_SP;
Sentido _SentidoSP = Parado;
Sentido _Sentido = Parado;
Sentido _SentidoU = Parado;
int _US_Addr;
bool _Alarme = false;
bool _Freio = false;
int _Margem = 2;
double _RPM_Offset = 0;
void Inicializar() {
if (Iniciado) {
EnviarDadosSerial(_ID + " ja inicializado");
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
return;
}
if (_pinoPWM.Definido()) {
ledcSetup(_canal, 1000, 10);
ledcAttachPin(_pinoPWM.num, _canal);
PotenciaAtual = ZeroRampa;
_PotMap = PotenciaAtual;
_RPM_SP = 0;
ledcWrite(_canal, _PotMap);
}
_pinoDIR.Conectar(false);
_SentidoU = Parado;
_pinoBRK.Conectar(_Freio);
_pinoSTP.Conectar(true);
if (_pinoHLA.Definido()) {
_pinoHLA.Conectar();
ultimaLeituraHallA = _pinoHLA.get();
RPM = 0;
periodo = 0;
tempoAnterior = 0;
xTaskCreatePinnedToCore(&Motor::RPMTaskWrapper, "RPMTask", 15000, this, 25 - _canal, &RPMTaskHandle, tskNO_AFFINITY);
ReiniciarAceleracaoArr();
ReiniciarHallArr();
_PID = new PID(&RPM, &PotenciaAtual, &_RPM_SP, _Kp, _Ki, _Kd, DIRECT);
_PID->SetOutputLimits(RampaMin, RampaMax);
_PID->SetMode(AUTOMATIC);
}
_pinoHLB.Conectar();
ultimaLeituraHallB = _pinoHLB.get();
_pinoHLC.Conectar();
ultimaLeituraHallC = _pinoHLC.get();
xTaskCreatePinnedToCore(&Motor::RampaTaskWrapper, "RampaTask", 5000, this, 21 - _canal + 4, &RampaTaskHandle, tskNO_AFFINITY);
EnviarDadosSerial(_ID + " Iniciado");
Iniciado = true;
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
}
void Desligar() {
if (!Iniciado) {
EnviarDadosSerial(_ID + " nao esta inicializado");
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
return;
}
// Parar a execução das tarefas
vTaskDelete(RampaTaskHandle);
if (_pinoHLA.Definido()) {
vTaskDelete(RPMTaskHandle);
}
// Redefinir as configurações para os valores iniciais
_pinoPWM.Desconectar();
_pinoPWM.Desconectar();
_pinoDIR.Desconectar();
_pinoBRK.Desconectar();
_pinoSTP.Desconectar();
_pinoHLA.Desconectar();
_pinoHLB.Desconectar();
_pinoHLC.Desconectar();
// Outras redefinições de variáveis de estado, se necessário
delete _PID;
EnviarDadosSerial(_ID + " Desligado");
Iniciado = false;
EnviarDadosSerial(MontarProtocoloSensor(sCFG, _ID, Iniciado ? "1" : "0"));
}
void ReiniciarAceleracaoArr() {
for (int i = 0; i < leituras; i++) {
RPM_arr[i] = -1.0;
}
}
void ReiniciarHallArr() {
for (int i = 0; i < leituras; i++) {
Hall_arr[i][0] = false;
Hall_arr[i][1] = false;
Hall_arr[i][2] = false;
}
}
private:
TaskHandle_t RPMTaskHandle = NULL;
static void RPMTaskWrapper(void *pvParameters) {
Motor *motor = static_cast<Motor*>(pvParameters);
motor->RPMTask();
}
void RPMTask() {
unsigned long firstMilis = millis();
int pulsos = 0;
while (1)
{
if (!Conectado) {
// Caso não esteja conectado, aguarda 1 segundo até a próxima verificação, liberando uso de CPU
vTaskDelay(1000);
continue;
}
// Medir RPM apenas quando ocorrer um pulso no sensor HALL
int LeituraHa = _pinoHLA.get();
if (LeituraHa != ultimaLeituraHallA) {
ultimaLeituraHallA = LeituraHa;
pulsos++;
// Calcular o período em microssegundos
unsigned long tempoAtual = micros();
unsigned long periodoUs = tempoAtual - tempoAnterior;
periodo = periodoUs / 1000.0; // Converte de us para ms (2300 us para 2,3 ms)
// Salva o valor do RPM anterior
double RPM_A = RPM;
// Se o período entre pulsos for menor que o tempo mínimo entre pulsos em ms, significa que o sensor está em uma posição em que existe oscilação de leitura,
// pois o RPM estaria acima do máximo, logo, assumir o valor de RPM aferido anteriormente
if (periodo < MenorPeriodo) {
RPM = RPM_A;
}
// Calcular RPM se houve variação de tempo entre o pulso atual e o pulso anterior
else if (periodo != 0) {
// RPM = 60 / (Pulsos por Revolução * Período em segundos)
// A fórmula foi adaptada para otimizar processamento
RPM = RelacaoPPR / periodo;
}
// Se não houve alteração no período, então o motor não se moveu
else {
RPM = 0;
}
CalcularSentidoGiro(RPM);
// Reiniciar variáveis
tempoAnterior = tempoAtual;
}
CorrigirPotenciaMotor();
long intMillis = (millis() - firstMilis);
// A cada _TaxaAmostragem, enviar os dados para o software
if (intMillis >= _TaxaAmostragem) {
if (pulsos == 0) {
RPM = 0;
periodo = 0;
CalcularSentidoGiro(RPM);
}
pulsos = 0;
double PotAtual = fmap(PotenciaAtual, RampaMin, RampaMax, 0.0, 100.0);
EnviarDadosSerial(MontarProtocoloSensor(sRPM, _ID, MontarDadosProtocoloRPM(RPM, PotAtual, Aceleracao, _Sentido, Revertendo, _RPM_Offset)));
firstMilis = millis();
}
// Aguarda metade do menor período possível entre leituras
vTaskDelay(1);
}
}
void CalcularSentidoGiro(float _RPM) {
if (!_pinoHLA.Definido() || !_pinoHLB.Definido() || !_pinoHLC.Definido()) {
CalculaAceleracao(_RPM);
return;
}
bool LeituraHa = ultimaLeituraHallA == 1;
bool LeituraHb = _pinoHLB.get() == 1;
bool LeituraHc = _pinoHLC.get() == 1;
for (int i = 1; i < leituras; i++) {
Hall_arr[i - 1][0] = Hall_arr[i][0];
Hall_arr[i - 1][1] = Hall_arr[i][1];
Hall_arr[i - 1][2] = Hall_arr[i][2];
}
Hall_arr[leituras - 1][0] = LeituraHa;
Hall_arr[leituras - 1][1] = LeituraHb;
Hall_arr[leituras - 1][2] = LeituraHc;
// Leituras dos sensores Hall nas leituras anteriores
bool LeituraAnteriorHa = Hall_arr[leituras - 2][0];
bool LeituraAnteriorHb = Hall_arr[leituras - 2][1];
bool LeituraAnteriorHc = Hall_arr[leituras - 2][2];
// Comparação das leituras atuais com as leituras anteriores
if (LeituraHa == LeituraAnteriorHc && LeituraHc == LeituraAnteriorHa) {
_Sentido = Antihorario;
}
else if (LeituraHa == LeituraAnteriorHb && LeituraHb == LeituraAnteriorHa) {
_Sentido = Horario;
}
else {
// Outros casos (não determinados)
}
CalculaAceleracao(_RPM);
}
void CalculaAceleracao(float _RPM) {
float RPM_total = _RPM;
int Desconsiderar = 0;
// Salvar as ultimas leituras
for (int i = 1; i < leituras; i++) {
RPM_arr[i - 1] = RPM_arr[i];
RPM_total += RPM_arr[i - 1] < 0 ? 0 : RPM_arr[i - 1];
Desconsiderar += RPM_arr[i - 1] < 0 ? 1 : 0;
}
RPM_arr[leituras - 1] = _RPM;
float RPM_medio = RPM_total / (leituras - Desconsiderar);
AceleracaoA = Aceleracao;
if (_SentidoSP == Parado && _RPM == 0) {
Aceleracao = Estavel;
} else if (RPM_arr[leituras - 3] < (RPM_arr[leituras - 2] - _Margem) && RPM_arr[leituras - 2] < (_RPM - _Margem)) {
Aceleracao = Acelerando;
} else if (RPM_arr[leituras - 3] > (RPM_arr[leituras - 2] + _Margem) && RPM_arr[leituras - 2] > (_RPM + _Margem)) {
Aceleracao = Desacelerando;
} else {
Aceleracao = Estavel;
}
}
void CorrigirPotenciaMotor() {
if (_MalhaFechada && !Revertendo && _SentidoSP != Parado) {
if (_pinoHLA.Definido() && _pinoHLB.Definido() && _pinoHLC.Definido()) {
SentidoContrario = _Sentido != _SentidoSP;
}
if (SentidoContrario) {
RPM = RPM * -1;
}
/*else if (Aceleracao == Desacelerando && AceleracaoA == Estavel) {
RPM = 0;
}*/
float _rpmA = RPM;
if (RPM_Estavel) {
RPM = RPM + _RPM_Offset;
}
_PID->Compute();
RPM = _rpmA;
}
}
TaskHandle_t RampaTaskHandle = NULL;
static void RampaTaskWrapper(void *pvParameters) {
Motor *motor = static_cast<Motor*>(pvParameters);
motor->RampaTask();
}
void RampaTask() {
unsigned long firstMilis = millis();
while (1)
{
if (!Conectado) {
// Caso não esteja conectado, aguarda 1 segundo até a próxima verificação, liberando uso de CPU
vTaskDelay(1000);
continue;
}
Atualizar();
vTaskDelay(1);
}
}
void Atualizar() {
bool Travado = _PotMap > ZeroRampa && RPM_arr[leituras - 1] == 0 && RPM_arr[leituras - 2] > 0 && RPM_arr[leituras - 3] > 0 && _Sentido != Parado;
if (_pinoPWM.Definido() && Travado) {
_PotMap = ZeroRampa;
ledcWrite(_canal, _PotMap);
vTaskDelay(400);
_PotMap = PotenciaAtual;
}
if (_pinoDIR.Definido()) {
bool ReleAtuado = _SentidoSP == Horario;
if (_SentidoSP != _SentidoU && ReleAtuado) {
_pinoDIR.set(ReleAtuado);
vTaskDelay(1000);
}
_pinoDIR.set(ReleAtuado);
_SentidoU = _SentidoSP;
}
if (_pinoBRK.Definido()) {
_pinoBRK.set(_Freio);
}
if (_pinoSTP.Definido()) {
_pinoSTP.set(HIGH);
}
if (_pinoPWM.Definido()) {
if (_SentidoSP == Parado) {
_PotMap = ZeroRampa;
}
else {
_PotMap = PotenciaAtual;
}
ledcWrite(_canal, _PotMap);
}
}
};
Motor M1("ET");
Motor M2("EF");
Motor M3("DT");
Motor M4("DF");
Motor* MotorPorID(String ID) {
Motor* _motor =
ID == "ET" ? &M1 :
ID == "EF" ? &M2 :
ID == "DT" ? &M3 :
ID == "DF" ? &M4 :
nullptr;
return _motor;
}
void BalanceamentoTask(void *pvParameters);
TaskHandle_t BalanceamentoTaskHandle = NULL;
void setup() {
Serial.begin(_baudRate);
delay(10);
xTaskCreatePinnedToCore(BalanceamentoTask, "BalanceamentoTask", 8000, NULL, 5, &BalanceamentoTaskHandle, tskNO_AFFINITY);
RecalcularRelacaoPPR();
}
void loop() {
std::vector<ProtocoloSerial> protocolos = LerBufferSerialFila();
for (int i = 0; i < protocolos.size(); i++) {
ProcessarProtocolo(protocolos[i].protocolo, protocolos[i].funcao, protocolos[i].idMensagem);
}
}
void ProcessarProtocolo(String Protocolo, F_Code _funcao, int idMensagem) {
if (_funcao == Chk) {
EnviarDadosSerial(MontarProtocoloVerificacao(D_Code, VERSION));
}
else if (_funcao == Cfg) {
std::vector<String> Partes = SplitString(Protocolo, (char*)",");
String ID = Partes[0];
bool Conectar = Partes[1] == "1";
if (ID == "MD") {
_TaxaAmostragem = Partes[2].toInt();
int _RampaMin = Partes[3].toInt();
int _RampaMax = Partes[4].toInt();
int _PPR = Partes[5].toInt();
int _delayBalanceamento = Partes[6].toInt();
int _margemRPM = Partes[7].toInt();
int _maxOffsetRPM = Partes[8].toInt();
RampaMin = _RampaMin;
RampaMax = _RampaMax;
PPR = _PPR;
delayBalanceamento = _delayBalanceamento;
RPM_Margem = _margemRPM;
RPM_Offset_Max = _maxOffsetRPM;
RecalcularRelacaoPPR();
EnviarDadosSerial(MontarProtocoloSensor(sCFG, "MD", Conectar ? "1" : "0"));
vTaskDelay(pdMS_TO_TICKS(100));
Conectado = Conectar;
}
else {
int canal = Partes[2].toInt();
bool _alarme = Partes[3] == "1";
bool motor_ativado = Partes[4] == "1";
double _Kp = Partes[5].toDouble();
double _Ki = Partes[6].toDouble();
double _Kd = Partes[7].toDouble();
TiposBarramentos pwmB = (TiposBarramentos)Partes[8].toInt();
int pwm = Partes[9].toInt();
TiposBarramentos dirB = (TiposBarramentos)Partes[10].toInt();
int dir = Partes[11].toInt();
TiposBarramentos brkB = (TiposBarramentos)Partes[12].toInt();
int brk = Partes[13].toInt();
TiposBarramentos stpB = (TiposBarramentos)Partes[14].toInt();
int stp = Partes[15].toInt();
TiposBarramentos hlAB = (TiposBarramentos)Partes[16].toInt();
int hallA = Partes[17].toInt();
TiposBarramentos hlBB = (TiposBarramentos)Partes[18].toInt();
int hallB = Partes[19].toInt();
TiposBarramentos hlCB = (TiposBarramentos)Partes[20].toInt();
int hallC = Partes[21].toInt();
Motor* _motor = MotorPorID(ID);
if (motor_ativado) {
if (Conectar) {
_motor->_canal = canal;
_motor->_pinoPWM = PinoModel(pwm, pwmB, _PWM);
_motor->_pinoDIR = PinoModel(dir, dirB, _OUTPUT);
_motor->_pinoBRK = PinoModel(brk, brkB, _OUTPUT);
_motor->_pinoSTP = PinoModel(stp, stpB, _OUTPUT);
_motor->_pinoHLA = PinoModel(hallA, hlAB, _INPUT, DIGITAL);
_motor->_pinoHLB = PinoModel(hallB, hlBB, _INPUT, DIGITAL);
_motor->_pinoHLC = PinoModel(hallC, hlCB, _INPUT, DIGITAL);
_motor->_Alarme = _alarme;
_motor->_Kp = _Kp;
_motor->_Ki = _Ki;
_motor->_Kd = _Kd;
_motor->Inicializar();
}
else {
_motor->Desligar();
}
vTaskDelay(pdMS_TO_TICKS(500));
}
}
}
else if (_funcao == Cmd) {
std::vector<String> Partes = SplitString(Protocolo, (char*)",");
String ID = Partes[0];
Motor* _motor = MotorPorID(ID);
_motor->_SentidoSP = (Sentido)Partes[1].toInt();
_motor->_RPM_SP = Partes[2].toInt();
_motor->_Alarme = Partes[3] == "1";
_motor->ReiniciarAceleracaoArr();
}
else if (_funcao == Tst) {
std::vector<String> Partes = SplitString(Protocolo, (char*)",");
String ID = Partes[0];
Motor* _motor = MotorPorID(ID);
bool EmTeste = _motor->Testando;
if (!EmTeste) {
//_motor->Testar();
}
}
EnviarDadosSerial(MontarProtocoloMensagemRecebida(idMensagem));
}
void RecalcularRelacaoPPR() {
RelacaoPPR = (60 / PPR) * 1000; // Multiplicador do cálculo de RPM (período em ms)
MenorPeriodo = RelacaoPPR / RpmMax; // Tempo mínimo de leitura
}
void BalanceamentoTask(void *pvParameters) {
while (1)
{
int _delay = delayBalanceamento > 0 ? delayBalanceamento : 5000;
if (Conectado && delayBalanceamento > 0) {
BalancearCargasMotores();
}
vTaskDelay(_delay);
}
}
void BalancearCargasMotores() {
RPM_Medio = (M1.RPM + M2.RPM + M3.RPM + M4.RPM) / 4.0;
RPM_SetPoint = (M1._RPM_SP + M2._RPM_SP + M3._RPM_SP + M4._RPM_SP) / 4.0;
RPM_Estavel = (RPM_Medio >= (RPM_SetPoint - RPM_Margem)) && (RPM_Medio <= (RPM_SetPoint + RPM_Margem));
double M1_Pot = M1.PotenciaAtual;
double M2_Pot = M2.PotenciaAtual;
double M3_Pot = M3.PotenciaAtual;
double M4_Pot = M4.PotenciaAtual;
double mediaPotencia = (M1_Pot + M2_Pot + M3_Pot + M4_Pot) / 4.0;
// Certifique-se de verificar se a potência atual não é zero antes de dividir
double offsetM1_RPM = (M1_Pot != 0 ? (M1.RPM * (mediaPotencia - M1_Pot)) / M1_Pot : 0) * -1;
double offsetM2_RPM = (M2_Pot != 0 ? (M2.RPM * (mediaPotencia - M2_Pot)) / M2_Pot : 0) * -1;
double offsetM3_RPM = (M3_Pot != 0 ? (M3.RPM * (mediaPotencia - M3_Pot)) / M3_Pot : 0) * -1;
double offsetM4_RPM = (M4_Pot != 0 ? (M4.RPM * (mediaPotencia - M4_Pot)) / M4_Pot : 0) * -1;
// Aplica o offset com limitação
M1._RPM_Offset = fmin(fmax(offsetM1_RPM, -RPM_Offset_Max), RPM_Offset_Max);
M2._RPM_Offset = fmin(fmax(offsetM2_RPM, -RPM_Offset_Max), RPM_Offset_Max);
M3._RPM_Offset = fmin(fmax(offsetM3_RPM, -RPM_Offset_Max), RPM_Offset_Max);
M4._RPM_Offset = fmin(fmax(offsetM4_RPM, -RPM_Offset_Max), RPM_Offset_Max);
}

View File

@ -0,0 +1,8 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
"version": "0.2.0",
"configurations": [
]
}

File diff suppressed because it is too large Load Diff