ajustado modulo sensoriamento para CAN

This commit is contained in:
Diego Freitas 2025-04-09 18:11:40 -03:00
parent f15103bf25
commit 86cbe678c9
89 changed files with 4781 additions and 1796 deletions

Binary file not shown.

View File

@ -501,6 +501,7 @@
<Compile Include="Services\FilaService.cs" />
<Compile Include="Services\GPSService.cs" />
<Compile Include="Services\IDispositivosService.cs" />
<Compile Include="Services\IFirmwareSensorBase.cs" />
<Compile Include="Services\KinectService.cs" />
<Compile Include="Services\LoRaSerializer.cs" />
<Compile Include="Services\LoRaService.cs" />

View File

@ -11,7 +11,7 @@ namespace AgroBase.Forms.Atuador
{
public partial class frmAtuConfig : Form
{
DispositivosService<AtuadorModel> Disp = (DispositivosService<AtuadorModel>)Variaveis.DispositivosConectados.FirstOrDefault(x => x.Dispositivo == T_Code.Atu);
DispositivosService<AtuadorModel> Disp;
public frmAtuConfig()
{
@ -20,6 +20,7 @@ namespace AgroBase.Forms.Atuador
private void frmAtuConfig_Load(object sender, EventArgs e)
{
Disp = (DispositivosService<AtuadorModel>)Variaveis.DispositivosConectados.FirstOrDefault(x => x.Dispositivo == T_Code.Atu);
if (Disp == null)
{
return;

View File

@ -214,9 +214,9 @@ namespace AgroBase.Forms.Direcional
this.lblDFOffset.Location = new System.Drawing.Point(10, 76);
this.lblDFOffset.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.lblDFOffset.Name = "lblDFOffset";
this.lblDFOffset.Size = new System.Drawing.Size(35, 13);
this.lblDFOffset.Size = new System.Drawing.Size(33, 13);
this.lblDFOffset.TabIndex = 10;
this.lblDFOffset.Text = "Offset";
this.lblDFOffset.Text = "Folga";
//
// cmbDFDireita
//
@ -321,9 +321,9 @@ namespace AgroBase.Forms.Direcional
this.lblEFOffset.Location = new System.Drawing.Point(10, 76);
this.lblEFOffset.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.lblEFOffset.Name = "lblEFOffset";
this.lblEFOffset.Size = new System.Drawing.Size(35, 13);
this.lblEFOffset.Size = new System.Drawing.Size(33, 13);
this.lblEFOffset.TabIndex = 8;
this.lblEFOffset.Text = "Offset";
this.lblEFOffset.Text = "Folga";
//
// cmbEFDireita
//
@ -428,9 +428,9 @@ namespace AgroBase.Forms.Direcional
this.lblDTOffset.Location = new System.Drawing.Point(10, 76);
this.lblDTOffset.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.lblDTOffset.Name = "lblDTOffset";
this.lblDTOffset.Size = new System.Drawing.Size(35, 13);
this.lblDTOffset.Size = new System.Drawing.Size(33, 13);
this.lblDTOffset.TabIndex = 10;
this.lblDTOffset.Text = "Offset";
this.lblDTOffset.Text = "Folga";
//
// cmbDTDireita
//
@ -535,9 +535,9 @@ namespace AgroBase.Forms.Direcional
this.lblETOffset.Location = new System.Drawing.Point(10, 76);
this.lblETOffset.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.lblETOffset.Name = "lblETOffset";
this.lblETOffset.Size = new System.Drawing.Size(35, 13);
this.lblETOffset.Size = new System.Drawing.Size(33, 13);
this.lblETOffset.TabIndex = 10;
this.lblETOffset.Text = "Offset";
this.lblETOffset.Text = "Folga";
//
// cmbETDireita
//

View File

@ -74,7 +74,7 @@ namespace AgroBase.Forms.Direcional
txtEndereco.Text = Modulo.DirMotor.Endereco;
NumericUpDown nudOffset = FuncoesGlobais.FindControlRecursive<NumericUpDown>(gpbSentido, "nud" + Modulo.Modulo_ID + "Offset");
nudOffset.Value = Convert.ToInt32(Modulo.DirMotor.Angulo_Offset);
nudOffset.Value = Convert.ToInt32(Modulo.DirMotor.FolgaMecanica);
}
}
@ -117,7 +117,7 @@ namespace AgroBase.Forms.Direcional
Modulo.DirMotor.Endereco = txtEndereco.Text;
NumericUpDown nudOffset = FuncoesGlobais.FindControlRecursive<NumericUpDown>(gpbSentido, "nud" + Modulo.Modulo_ID + "Offset");
Modulo.DirMotor.Angulo_Offset = Convert.ToDouble(nudOffset.Value);
Modulo.DirMotor.FolgaMecanica = Convert.ToDouble(nudOffset.Value);
}
}

View File

@ -837,7 +837,7 @@ namespace AgroBase.Forms.IHM
bool Sucesso = false;
while (!Sucesso && Inicio.AddMilliseconds(Timeout) > DateTime.Now)
{
Dispositivo.Dados.RequisitarDadosModulo();
Dispositivo.Dados.RequisitarDadosModulo(F_Code.ReqTx);
await Task.Delay(1000);
Sucesso =
@ -1471,7 +1471,7 @@ namespace AgroBase.Forms.IHM
var novoEstado = Ligar ? Estado.Ligado : Estado.Desligado;
GeneralJoystick.EnviarComandoSensoriamento(S_Code.sRLE, Rele.ID, novoEstado);
await Task.Delay(Delay);
Dispositivo.Dados.RequisitarDadosModulo();
Dispositivo.Dados.RequisitarDadosModulo(F_Code.ReqTx);
await Task.Delay(Delay);
}
@ -1732,7 +1732,7 @@ namespace AgroBase.Forms.IHM
Comportamento.statusLED = Ligar ? StatusLED.Aceso : StatusLED.Apagado;
GeneralJoystick.EnviarComandoSensoriamento(S_Code.sLED, Sinaleiro.ID, Comportamento);
await Task.Delay(Delay);
Dispositivo.Dados.RequisitarDadosModulo();
Dispositivo.Dados.RequisitarDadosModulo(F_Code.ReqTx);
await Task.Delay(Delay);
}

View File

@ -210,7 +210,7 @@ namespace AgroBase.Forms.Operacoes
(bool sucesso, List<string> ruas) = Variaveis.OperacaoEmAndamento.CarregarParametrizacaoOperacao(frmDialogo.pnlMapa, frmDialogo.lblMapaCarregado, path);
bool condicaoOperacaoCarregada() => Variaveis.OperacaoEmAndamento.Trajetoria?.CorredorAtual != null;
bool resultado = await FuncoesGlobais.AguardarCondicaoAsync(condicaoOperacaoCarregada, 5000, 200);
bool resultado = await FuncoesGlobais.AguardarCondicaoAsync(condicaoOperacaoCarregada, 15000, 200);
if (!resultado)
{

View File

@ -61,7 +61,7 @@
this.cmbCaminho = new System.Windows.Forms.ComboBox();
this.chbRequisitarDados = new System.Windows.Forms.CheckBox();
this.lblIP = new System.Windows.Forms.Label();
this.txtIP = new System.Windows.Forms.TextBox();
this.txtEnderecoCAN = new System.Windows.Forms.TextBox();
this.lblPotenciometro = new System.Windows.Forms.Label();
this.gridsPOT = new System.Windows.Forms.DataGridView();
((System.ComponentModel.ISupportInitialize)(this.gridsTEN)).BeginInit();
@ -395,19 +395,19 @@
this.lblIP.Location = new System.Drawing.Point(1097, 579);
this.lblIP.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.lblIP.Name = "lblIP";
this.lblIP.Size = new System.Drawing.Size(17, 13);
this.lblIP.Size = new System.Drawing.Size(78, 13);
this.lblIP.TabIndex = 145;
this.lblIP.Text = "IP";
this.lblIP.Text = "Endereço CAN";
//
// txtIP
// txtEnderecoCAN
//
this.txtIP.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.txtIP.Location = new System.Drawing.Point(1100, 596);
this.txtIP.Margin = new System.Windows.Forms.Padding(2);
this.txtIP.Name = "txtIP";
this.txtIP.Size = new System.Drawing.Size(85, 20);
this.txtIP.TabIndex = 144;
this.txtIP.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.txtEnderecoCAN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.txtEnderecoCAN.Location = new System.Drawing.Point(1100, 596);
this.txtEnderecoCAN.Margin = new System.Windows.Forms.Padding(2);
this.txtEnderecoCAN.Name = "txtEnderecoCAN";
this.txtEnderecoCAN.Size = new System.Drawing.Size(85, 20);
this.txtEnderecoCAN.TabIndex = 144;
this.txtEnderecoCAN.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// lblPotenciometro
//
@ -435,7 +435,7 @@
this.Controls.Add(this.lblPotenciometro);
this.Controls.Add(this.gridsPOT);
this.Controls.Add(this.lblIP);
this.Controls.Add(this.txtIP);
this.Controls.Add(this.txtEnderecoCAN);
this.Controls.Add(this.chbRequisitarDados);
this.Controls.Add(this.gpbCameras);
this.Controls.Add(this.gpbBateria);
@ -511,7 +511,7 @@
private System.Windows.Forms.Button btnAtualizarCameras;
private System.Windows.Forms.CheckBox chbRequisitarDados;
private System.Windows.Forms.Label lblIP;
private System.Windows.Forms.TextBox txtIP;
private System.Windows.Forms.TextBox txtEnderecoCAN;
private System.Windows.Forms.Label lblPotenciometro;
private System.Windows.Forms.DataGridView gridsPOT;
}

View File

@ -52,7 +52,7 @@ namespace AgroBase.Forms.Sensoriamento
}
}
txtIP.Text = Disp.Dados.GetIP();
txtEnderecoCAN.Text = Disp.Dados._EnderecoCAN.ToString("X");
PopulaParametrosSensor();
@ -126,7 +126,7 @@ namespace AgroBase.Forms.Sensoriamento
grid.Columns.Add("clLimiteMax", "Limite Máximo");
foreach (var Parametro in Sensor.Parametros)
{
grid.Columns.Add("cl" + Parametro[0], Parametro[0]);
grid.Columns.Add("cl" + Parametro.Descricao, Parametro.Descricao);
}
}
}
@ -148,7 +148,7 @@ namespace AgroBase.Forms.Sensoriamento
for (int i = 0; i < Sensor.Parametros.Count; i++)
{
grid.Rows[novaLinhaIndex].Cells[i + ParametrosComecamEm].Value = Sensor.Parametros[i][1];
grid.Rows[novaLinhaIndex].Cells[i + ParametrosComecamEm].Value = Sensor.Parametros[i].Valor;
}
}
}
@ -183,7 +183,7 @@ namespace AgroBase.Forms.Sensoriamento
for (int i = 0; i < Sensor.Parametros.Count; i++)
{
Sensor.Parametros[i][1] = Row.Cells[i + ParametrosComecamEm].Value.ToString();
Sensor.Parametros[i].Valor = Row.Cells[i + ParametrosComecamEm].Value.ToString();
}
break;
}
@ -196,7 +196,7 @@ namespace AgroBase.Forms.Sensoriamento
case T_Code.Sen:
{
var _Disp = (DispositivosService<SensoriamentoModel>)Variaveis.DispositivosConectados.FirstOrDefault(x => x.Dispositivo == Dispositivo);
_Disp.Dados.IP = txtIP.Text;
_Disp.Dados._EnderecoCAN = Convert.ToByte(txtEnderecoCAN.Text, 16);
_Disp.Dados.RequisitarDados = chbRequisitarDados.Checked;
_Disp.Dados.Sensores = Sensores.ToList();
_Disp.Dados.CameraID_Caminho = cmbCaminho.Text;
@ -208,7 +208,7 @@ namespace AgroBase.Forms.Sensoriamento
case T_Code.Atu:
{
var _Disp = (DispositivosService<AtuadorModel>)Variaveis.DispositivosConectados.FirstOrDefault(x => x.Dispositivo == Dispositivo);
_Disp.Dados.IP = txtIP.Text;
_Disp.Dados._EnderecoCAN = Convert.ToByte(txtEnderecoCAN.Text, 16);
_Disp.Dados.RequisitarDados = chbRequisitarDados.Checked;
_Disp.Dados.Sensores = Sensores.ToList();
_Disp.SalvarParametros(_Disp.Dados);

View File

@ -2377,7 +2377,7 @@ namespace AgroBase.Forms
{
if (!CanService.IsConnected)
{
CanService.AbrirComunicacao(new SerialPort(cmbPorta.Text, Convert.ToInt32(cmbBaud.Text)));
CanService.DefinirPortaCOM(new SerialPort(cmbPorta.Text, Convert.ToInt32(cmbBaud.Text)));
}
if (CanService.IsConnected)

View File

@ -81,10 +81,10 @@ namespace AgroBase.Models
}
else
{
IDispositivosService dispositivoService = Variaveis.DispositivosConectados.FirstOrDefault(x => x.Dispositivo == Dispositivo && x.Dados.GetIP() == Endereco);
IDispositivosService dispositivoService = Variaveis.DispositivosConectados.FirstOrDefault(x => x.Dispositivo == Dispositivo && CanService._portName == Endereco);
if (dispositivoService != null)
{
return dispositivoService.Dados.GetStatusConexao();
return dispositivoService.Dados.Conectado;
}
else
{

View File

@ -65,41 +65,50 @@
public enum F_Code
{
Nda = 200,
Chk = 244,
Cfg = 258,
Tst = 288,
Cmd = 293,
Err = 404,
Msg = 655,
Req = 887,
Nda = 0,
ChkTx = 1,
ChkRx = 2,
CfgTx = 3,
CfgRx = 4,
TstTx = 5,
TstRx = 6,
CmdTx = 7,
CmdRx = 8,
ErrTx = 9,
ErrRx = 10,
MsgTx = 11,
MsgRx = 12,
ReqTx = 13,
ReqRx = 14,
}
public enum S_Code
{
sRPM = 133,
sTST = 154,
sCFG = 211,
sTMP = 411,
sENC = 111,
sCOR = 322,
sTEN = 112,
sFLX = 198,
sULT = 531,
sMAS = 532,
sBIC = 422,
sPRS = 333,
sMAG = 855,
sBMB = 325,
sLED = 445,
sSNR = 532,
sBLD = 544,
sCMD = 878,
sMVD = 477,
sATU = 478,
sRLE = 479,
sFRO = 480,
sPOT = 481,
sVZO = 0,
sRPM = 1,
sTST = 2,
sCFG = 3,
sTMP = 4,
sENC = 5,
sCOR = 6,
sTEN = 7,
sFLX = 8,
sULT = 9,
sMAS = 10,
sBIC = 11,
sPRS = 12,
sMAG = 13,
sBMB = 14,
sLED = 15,
sSNR = 16,
sBLD = 17,
sCMD = 18,
sMVD = 19,
sATU = 20,
sRLE = 21,
sFRO = 22,
sPOT = 23,
sMOD = 24,
}
public enum BotoesJoystick
@ -290,5 +299,12 @@
Corredores = 3
}
public enum INA219Corrente
{
C_3_2 = 1,
C_50 = 2,
C_100 = 3
}
}
}

View File

@ -64,7 +64,7 @@ namespace AgroBase
{
Func<bool> funcAtt = new Func<bool>(() =>
{
DispCon = Variaveis.DispositivosConectados.Where(x => x.Dados.GetStatusConexao()).ToList();
DispCon = Variaveis.DispositivosConectados.Where(x => x.Dados.Conectado).ToList();
frmInstancial.frmJoystick.lblDispositivo.Text = "Dispositivos: " + (DispCon.Count == 0 ? "N/A" : string.Join(", ", DispCon.Select(x => x._Descricao + " (" + Enum.GetName(typeof(T_Code), x.Dispositivo) + ")").ToArray()));
frmInstancial.frmPrincipal.cmbJoysticks.Items.Clear();
@ -669,6 +669,8 @@ namespace AgroBase
}
var DispAtu = Variaveis.OperacaoEmAndamento.DispAtu;
F_Code fcode = F_Code.Nda;
byte[] data = null;
switch (Componente)
{
@ -677,8 +679,7 @@ namespace AgroBase
if (Bomba != null)
{
Bomba.ComandoAtuar = Status;
string ProtocoloBomba = Bomba.ProtocoloComando();
DispAtu.AdicionarMensagemFila(DispAtu.Dados.Modulo_ID, ProtocoloBomba, true, true);
(fcode, data) = Bomba.ProtocoloComando();
}
break;
case S_Code.sBIC:
@ -686,18 +687,22 @@ namespace AgroBase
if (Bico != null)
{
Bico.ComandoAtuar = Status;
string ProtocoloBico = Bico.ProtocoloComando();
DispAtu.AdicionarMensagemFila(DispAtu.Dados.Modulo_ID, ProtocoloBico, true, false);
(fcode, data) = Bico.ProtocoloComando();
}
break;
}
DispAtu.AdicionarMensagemFila(fcode, data, false);
}
public static void EnviarComandoSensoriamento(S_Code Componente, string ID, dynamic Status)
{
var DispSen = Variaveis.OperacaoEmAndamento.DispSen;
F_Code fcode = F_Code.Nda;
byte[] data = null;
switch (Componente)
{
case S_Code.sLED:
@ -705,8 +710,7 @@ namespace AgroBase
if (Sinaleiro != null)
{
Sinaleiro.Comportamento = (SensorSinaleiroComportamentoModel)Status;
string ProtocoloSinaleiro = Sinaleiro.ProtocoloComando();
DispSen.AdicionarMensagemFila(DispSen.Dados.Modulo_ID, ProtocoloSinaleiro, true, false);
(fcode, data) = Sinaleiro.ProtocoloComando();
}
break;
case S_Code.sRLE:
@ -714,8 +718,7 @@ namespace AgroBase
if (Rele != null)
{
Rele.StatusControle = (Estado)Status;
string ProtocoloRele = Rele.ProtocoloComando();
DispSen.AdicionarMensagemFila(DispSen.Dados.Modulo_ID, ProtocoloRele, true, false);
(fcode, data) = Rele.ProtocoloComando();
}
break;
case S_Code.sFRO:
@ -723,11 +726,12 @@ namespace AgroBase
if (ServoFreio != null)
{
ServoFreio._AnguloControle = (int)Status;
string ProtocoloFreio = ServoFreio.ProtocoloComando();
DispSen.AdicionarMensagemFila(DispSen.Dados.Modulo_ID, ProtocoloFreio, true, false);
(fcode, data) = ServoFreio.ProtocoloComando();
}
break;
}
DispSen.AdicionarMensagemFila(fcode, data, false);
}
private static void AtualizaConsole(string Mensagem)

View File

@ -28,6 +28,9 @@ namespace AgroBase.Models
public void btnCarregar_Click(object sender, EventArgs e, string caminhoArquivo = "", bool monitoramento = false)
{
var Topico = Variaveis.MqttService.Topicos.FirstOrDefault(x => x.Topico == MapasVariaveisModel.TopicoSelecaoRuasMapa);
Topico.Mensagens.Clear();
TipoMapaOperacao? _tipoMapa = TipoMapa;
if (!monitoramento && string.IsNullOrEmpty(caminhoArquivo))
@ -173,6 +176,11 @@ namespace AgroBase.Models
TrajetoriaMapa.Add(new List<GPSModel>());
foreach (var ponto in rua.geometry.coordinates)
{
/*if (rua.geometry.coordinates.IndexOf(ponto) == 0 || rua.geometry.coordinates.IndexOf(ponto) == rua.geometry.coordinates.Count - 1)
{
continue;
}*/
GPSModel item = new GPSModel()
{
Longitude = ponto[0],

View File

@ -4,6 +4,7 @@ using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
@ -13,11 +14,27 @@ namespace AgroBase.Models.Modules
{
public class AtuadorModel : DispositivoBaseModel
{
public T_Code Dispositivo { get; set; } = T_Code.Atu;
public string Modulo_ID { get; set; } = T_Code.Atu.ToString();
public string IP { get; set; } = Variaveis.FaixaIPwifi + ".13";
public bool RequisitarDados { get; set; } = false;
public static int _TaxaAmostragem { get; set; } = 500;
public bool Conectado { get; set; } = false;
public byte _EnderecoCAN { get; set; } = 0x12;
public int _TaxaAmostragem { get; set; } = 1000;
public bool RequisitarDados { get; set; } = true;
public static int PingsConsiderarConexao { get; set; } = 5;
public static int TempoLimiteConexao
{
get
{
return PingsConsiderarConexao * (Variaveis.OperacaoEmAndamento?.DispSen?._TaxaAmostragem ?? 1000);
}
}
public bool Conectado
{
get
{
return DadosLeitura.UltimoComandoRespondido.AddMilliseconds(TempoLimiteConexao * 2) >= DateTime.Now; // DadosLeitura.Conectado &&
}
}
public static PinoutDataModel Pinout { get; set; }
public static List<FuncoesPinout> Funcoes { get; set; } = new List<FuncoesPinout>()
{
@ -42,6 +59,7 @@ namespace AgroBase.Models.Modules
private int _TempoReconexaoComponentes = 5;
private int _VezesLeituraReconexao = 0;
public AtuadorMensagemJsonModel DadosLeitura { get; set; } = new AtuadorMensagemJsonModel();
public AtuHandler _AtuHandler = new AtuHandler();
#region MASSA
public double _MassaRef { get; set; } = 0.8;
@ -195,16 +213,19 @@ namespace AgroBase.Models.Modules
{
AtuadorModel Atuador = new AtuadorModel()
{
_EnderecoCAN = 0x12,
_TaxaAmostragem = 1000,
RequisitarDados = true,
QuantidadeBicos = 4,
Conectado = false,
BicosPulverizadores = new List<AtuadorBicoModel>(),
BombasPressurizadoras = new List<AtuadorBombaModel>()
{
new AtuadorBombaModel()
{
ID = "BOMBA",
ID_Num = 51,
Componente = S_Code.sBMB,
Comandar = false,
Comandar = true,
Testando = false,
Funcoes = new List<FuncoesPinout>()
{
@ -221,68 +242,86 @@ namespace AgroBase.Models.Modules
new SensorModel()
{
ID = "FLXLN",
ID_Num = 61,
Descricao = "Fluxo na linha principal",
Prioridade = 23,
Componente = S_Code.sFLX,
Aferir = false,
Testando = false,
Aferir = true,
Funcoes = new List<FuncoesPinout>()
{
FuncoesPinout.Fluxo,
},
DelayAmostragem = 100,
UnidadeMedida = "mL/s",
Parametros = new List<string[]>(),
Parametros = new List<SensorParametroModel>()
},
new SensorModel()
{
ID = "MASRS",
ID_Num = 62,
Descricao = "Massa do reservatório de herbicida",
Prioridade = 3,
Componente = S_Code.sMAS,
Aferir = false,
Testando = false,
Aferir = true,
Funcoes = new List<FuncoesPinout>()
{
FuncoesPinout.DT,
FuncoesPinout.SCK,
},
DelayAmostragem = 1000,
UnidadeMedida = "Kg",
Parametros = new List<string[]>(),
Parametros = new List<SensorParametroModel>()
},
new SensorModel()
{
ID = "PRSLN",
ID_Num = 63,
Descricao = "Pressão na linha principal",
Prioridade = 3,
Componente = S_Code.sPRS,
Aferir = false,
Testando = false,
Aferir = true,
Funcoes = new List<FuncoesPinout>()
{
FuncoesPinout.Pressao,
},
DelayAmostragem = 1000,
UnidadeMedida = "psi",
Parametros = new List<string[]>()
Parametros = new List<SensorParametroModel>()
{
new string[] { "Vmin", "000.00" },
new string[] { "Vmax", "004.50" },
new string[] { "Pmax", "174.04" },
},
new SensorParametroModel()
{
Descricao = "Vmin",
Valor = "0",
QtdBytes = 1,
Escalar = false,
Enviar = true
},
new SensorParametroModel()
{
Descricao = "Vmax",
Valor = "4.5",
QtdBytes = 1,
Escalar = true,
Enviar = true
},
new SensorParametroModel()
{
Descricao = "Pmax",
Valor = "174",
QtdBytes = 1,
Escalar = false,
Enviar = true
},
}
},
},
};
for (int i = 0; i < Atuador.QuantidadeBicos; i++)
{
int posicao = (i + 1);
Atuador.BicosPulverizadores.Add(new AtuadorBicoModel()
{
ID = "B" + (i + 1).ToString("00"),
ID = "B" + posicao.ToString("00"),
ID_Num = 70 + posicao,
Componente = S_Code.sBIC,
Posicao = i + 1,
Comandar = false,
Posicao = posicao,
Comandar = true,
ComandoAtuar = false,
AtuacaoNivelAlto = true,
Funcoes = new List<FuncoesPinout>()
{
FuncoesPinout.Solenoide,
@ -296,7 +335,6 @@ namespace AgroBase.Models.Modules
public void LimparDados<T>(T _dados)
{
var Dados = _dados as AtuadorModel;
Dados.Conectado = false;
Dados.DadosLeitura = new AtuadorMensagemJsonModel();
Dados.DadosLeitura.Momento = DateTime.MinValue;
Dados.PercentualErvasTerreno = 0;
@ -337,125 +375,151 @@ namespace AgroBase.Models.Modules
Dados.InicioAtuacao = DateTime.MinValue;
}
public Dictionary<string, List<string>> ProtocoloConfiguracao(bool Conectar)
public async Task<bool> VerificaPortaATU(SerialPort porta)
{
// Inicializar o dicionário
var configDictionary = new Dictionary<string, List<string>>() { { Modulo_ID, new List<string>() } };
// Adicionar configurações dos Sensores que devem ser aferidos
var sensoresConfig = SensoresConfig(Conectar);
configDictionary[Modulo_ID].AddRange(sensoresConfig);
// Adicionar configurações dos Bicos Pulverizadores
var bicosConfig = BicosConfig(Conectar);
configDictionary[Modulo_ID].AddRange(bicosConfig);
// Adicionar configurações das Bombas Pressurizadoras
var bombasConfig = BombasConfig(Conectar);
configDictionary[Modulo_ID].AddRange(bombasConfig);
if (!Conectado || configDictionary.Any(x => x.Value.Count() > 0))
if (!CanService.IsConnected)
{
// Adicionar configuração do ProtocoloMOD
var protocoloMOD = ModConfig(Conectar);
configDictionary[Modulo_ID].Add(protocoloMOD);
CanService.DefinirPortaCOM(porta);
CanService.RegistrarHandler(Dispositivo, _AtuHandler);
}
return configDictionary;
}
private string ModConfig(bool Conectar)
{
string protocoloMOD =
((int)F_Code.Cfg).ToString() + SerialService.SplitMessage +
((int)T_Code.Mod).ToString() + SerialService.SplitParams +
(Conectar ? "1" : "0") + SerialService.SplitParams +
_TaxaAmostragem.ToString() + SerialService.SplitParams +
(RequisitarDados ? "1" : "0") + SerialService.SplitParams +
PinoutModel.PinoProtocolo(Pinout, Funcoes, SerialService.SplitParams);
return protocoloMOD;
}
private string[] SensoresConfig(bool Conectar)
{
bool configurarTodos = (Sensores.Any(x => x.Aferir && x.Inicializado) && Sensores.Any(x => x.Aferir && !x.Inicializado));
var sensoresConfig = Sensores
.Where(x => x.Aferir && (configurarTodos ? true : x.Inicializado != Conectar))
.GroupBy(x => x.Componente)
.Select(x =>
((int)F_Code.Cfg).ToString() + SerialService.SplitMessage +
((int)T_Code.Atu).ToString() + SerialService.SplitParams +
((int)x.Key).ToString() + SerialService.SplitParams +
string.Join(SerialService.SplitConfig, x.Select(y => y.ProtocoloConfiguracao(Pinout, Conectar)))
).ToArray();
return sensoresConfig;
}
private string[] BicosConfig(bool Conectar)
{
bool configurarTodos = (BicosPulverizadores.Any(x => x.Comandar && x.Inicializado) && BicosPulverizadores.Any(x => x.Comandar && !x.Inicializado));
var relesConfig = BicosPulverizadores
.Where(x => x.Comandar && (configurarTodos ? true : x.Inicializado != Conectar))
.GroupBy(x => x.Componente)
.Select(x =>
((int)F_Code.Cfg).ToString() + SerialService.SplitMessage +
((int)T_Code.Atu).ToString() + SerialService.SplitParams +
((int)x.Key).ToString() + SerialService.SplitParams +
string.Join(SerialService.SplitConfig, x.Select(y => y.ProtocoloConfiguracao(Pinout, Conectar)))
).ToArray();
return relesConfig;
}
private string[] BombasConfig(bool Conectar)
{
bool configurarTodos = (BombasPressurizadoras.Any(x => x.Comandar && x.Inicializado) && BombasPressurizadoras.Any(x => x.Comandar && !x.Inicializado));
var servosConfig = BombasPressurizadoras
.Where(x => x.Comandar && (configurarTodos ? true : x.Inicializado != Conectar))
.GroupBy(x => x.Componente)
.Select(x =>
((int)F_Code.Cfg).ToString() + SerialService.SplitMessage +
((int)T_Code.Atu).ToString() + SerialService.SplitParams +
((int)x.Key).ToString() + SerialService.SplitParams +
string.Join(SerialService.SplitConfig, x.Select(y => y.ProtocoloConfiguracao(Pinout, Conectar)))
).ToArray();
return servosConfig;
}
public string ProtocoloVerificacao(bool Completo)
{
if (Completo)
if (CanService.IsConnected)
{
string ProtocoloCheck =
//SerialService.BeginLine +
"0" + SerialService.SplitMessage +
Modulo_ID + SerialService.SplitMessage +
((int)F_Code.Chk).ToString() + SerialService.SplitMessage +
"check" +
SerialService.EndLine;
RequisitarDadosModulo(F_Code.ChkTx);
return ProtocoloCheck;
await Task.Delay(1000);
if (Conectado)
{
DefinirDispositivo();
}
}
else
{
string ProtocoloCheck = ((int)F_Code.Chk).ToString() + SerialService.SplitMessage + "check";
return false;
}
return ProtocoloCheck;
if (!CanService.Iniciado)
{
CanService.Fechar();
}
return Conectado;
}
private void DefinirDispositivo()
{
if (!SerialService.DispositivosMapeados.Any(x => x.Dispositivo == Dispositivo && x.Mod_ID == Modulo_ID))
{
SerialService.DispositivosMapeados.Add(new DispositivoDetalhesModel()
{
Endereco = CanService._portName,
Dispositivo = DadosLeitura.Dispositivo,
Erro = false,
Versao = DadosLeitura.Versao.ToString(),
Mod_ID = Modulo_ID,
});
}
}
private string ProtocoloAquisicaoDados()
public void RequisitarDadosModulo(F_Code dado)
{
string ProtocoloReq = ((int)F_Code.Req).ToString() + SerialService.SplitMessage + "req";
return ProtocoloReq;
Variaveis.OperacaoEmAndamento.DispAtu?.AdicionarMensagemFila(dado);
}
public List<byte[]> ProtocoloConfiguracao(bool Conectar)
{
// Inicializar o dicionário
List<byte[]> config = new List<byte[]>();
if (!Conectado)
{
// Adicionar configuração do ProtocoloMOD
var protocoloMOD = ModConfig(Conectar);
config.Add(protocoloMOD);
}
// Adicionar configurações dos Bicos
List<byte[]> bicosConfig = BicosConfig(Conectar);
config.AddRange(bicosConfig);
// Adicionar configurações das Bombas
List<byte[]> bombasConfig = BombasConfig(Conectar);
config.AddRange(bombasConfig);
// Adicionar configurações dos Sensores que devem ser aferidos
List<byte[]> sensoresConfig = SensoresConfig(Conectar);
config.AddRange(sensoresConfig);
return config;
}
public byte[] ModConfig(bool Conectar)
{
var pinos = PinoutModel.PinoProtocolo(Pinout, Funcoes, false);
var config = new List<byte>
{
(byte)S_Code.sMOD,
(byte)(Conectar ? 1 : 0),
(byte)(_TaxaAmostragem >> 8),
(byte)(_TaxaAmostragem & 0xFF),
(byte)(RequisitarDados ? 1 : 0),
};
config.AddRange(pinos);
return config.ToArray();
}
private List<byte[]> SensoresConfig(bool Conectar)
{
var config = new List<byte[]>();
foreach (var sensor in Sensores.Where(x => x.Aferir && x.Inicializado != Conectar))
{
byte[] payload = sensor.ProtocoloConfiguracao(Pinout, Conectar);
if (payload != null)
{
config.Add(payload);
}
}
return config;
}
private List<byte[]> BicosConfig(bool Conectar)
{
var config = new List<byte[]>();
foreach (var bico in BicosPulverizadores.Where(x => x.Comandar && x.Inicializado != Conectar))
{
var payload = bico.ProtocoloConfiguracao(Pinout, Conectar);
if (payload != null)
{
config.Add(payload);
}
}
return config;
}
private List<byte[]> BombasConfig(bool Conectar)
{
var config = new List<byte[]>();
foreach (var bomba in BombasPressurizadoras.Where(x => x.Comandar && x.Inicializado != Conectar))
{
var payload = bomba.ProtocoloConfiguracao(Pinout, Conectar);
if (payload != null)
{
config.Add(payload);
}
}
return config;
}
public void RecebeProtocoloModulo(string Protocolo)
{
try
@ -502,40 +566,10 @@ namespace AgroBase.Models.Modules
private void AtualizaDadosComponentes(AtuadorMensagemJsonModel dadosLeitura)
{
DadosLeitura = dadosLeitura;
DefineStatusConexao(Modulo_ID, true);
}
public void DefineStatusConexao(string Mod_ID, bool conecatdo)
{
if (Mod_ID == Modulo_ID)
{
Conectado = conecatdo;
}
}
public string GetTaxaAmostragem()
{
return _TaxaAmostragem.ToString("00000");
}
public void SetTaxaAmostragem(int TaxaAmostragem)
{
_TaxaAmostragem = TaxaAmostragem;
}
public bool GetStatusConexao()
{
return Conectado;
}
public string GetIP()
{
return IP;
}
public void IniciarRegistrador()
{
if (!(tmrRegistrador?.IsRunning ?? false))
@ -561,17 +595,8 @@ namespace AgroBase.Models.Modules
return;
}
if (Variaveis.OperacaoEmAndamento?.DispAtu != null)
{
await Variaveis.OperacaoEmAndamento.DispAtu.GerenciarMqttTopicos();
}
tmrRegistrador.SetInterval(_TaxaAmostragem);
bool _conectado = DadosLeitura.Conectado && DadosLeitura.Momento.AddMilliseconds(SensoriamentoModel.TempoLimiteConexao * 2) >= DateTime.Now;
DefineStatusConexao(Modulo_ID, _conectado);
if (SerialService.DispositivosMapeados.Any(x => x.Dispositivo == T_Code.Atu) && (_VezesLeituraReconexao >= _TempoReconexaoComponentes))
{
Variaveis.OperacaoEmAndamento.DispAtu?.EnviarProtocolosConfiguracao();
@ -588,22 +613,13 @@ namespace AgroBase.Models.Modules
{
if (RequisitarDados)
{
RequisitarDadosModulo();
RequisitarDadosModulo(F_Code.ReqTx);
}
VerificaControleLeitura();
}
}
public void RequisitarDadosModulo()
{
if (Variaveis.OperacaoEmAndamento.DispAtu != null)
{
string ProtocoloAquisicao = ProtocoloAquisicaoDados();
Variaveis.OperacaoEmAndamento.DispAtu.AdicionarMensagemFila(Modulo_ID, ProtocoloAquisicao, true, false);
}
}
public (bool, List<string>) StatusModulosATU()
{
@ -674,6 +690,7 @@ namespace AgroBase.Models.Modules
public class AtuadorBicoModel
{
public string ID { get; set; }
public int ID_Num { get; set; }
public int Posicao { get; set; }
public S_Code Componente { get; set; } = S_Code.sBIC;
public bool AtuacaoNivelAlto { get; set; }
@ -724,33 +741,32 @@ namespace AgroBase.Models.Modules
}
public string ProtocoloConfiguracao(PinoutDataModel Pinout, bool Conectar)
public byte[] ProtocoloConfiguracao(PinoutDataModel pinout, bool conectar)
{
var _pinout = new PinoutDataModel()
{
ExpansorGPIO = Pinout.ExpansorGPIO,
EnderecoGPIO = Pinout.EnderecoGPIO,
Pinos = Pinout.Pinos.ToList(),
};
_pinout.Pinos = _pinout.Pinos.Where(x => x.ComponenteID == ID).ToList();
string Protocolo =
ID + SerialService.SplitSubParams +
(Conectar ? "1" : "0") + SerialService.SplitSubParams +
(AtuacaoNivelAlto ? "1" : "0") + SerialService.SplitSubParams +
PinoutModel.PinoProtocolo(_pinout, Funcoes, SerialService.SplitSubParams);
var pino = pinout.Pinos.FirstOrDefault(p => p.ComponenteID == ID);
return Protocolo;
return new byte[]
{
(byte)Componente,
(byte)ID_Num,
(byte)(conectar ? 1 : 0),
(byte)(AtuacaoNivelAlto ? 1 : 0),
(byte)(pino?.Barramento ?? TiposBarramentos.CONTROLADOR),
(byte)(pino?.Pino ?? PinoutUtils.PINO_INVALIDO)
};
}
public string ProtocoloComando()
public (F_Code, byte[]) ProtocoloComando()
{
string ProtocoloRele =
((int)F_Code.Cmd).ToString() + SerialService.SplitMessage +
ID + SerialService.SplitParams +
((int)Componente) + SerialService.SplitParams +
(int)(ComandoAtuar ? Estado.Ligado : Estado.Desligado);
return ProtocoloRele;
return (
F_Code.CmdTx,
new byte[]
{
(byte)Componente,
(byte)ID_Num,
(byte)(ComandoAtuar ? Estado.Ligado : Estado.Desligado)
}
);
}
@ -795,6 +811,7 @@ namespace AgroBase.Models.Modules
Componente = Componente,
Funcoes = Funcoes,
ID = ID,
ID_Num = ID_Num,
InicioAtuacao = InicioAtuacao,
Leitura = Leitura,
MediaNivelFluxo = MediaNivelFluxo,
@ -810,6 +827,7 @@ namespace AgroBase.Models.Modules
public class AtuadorBombaModel
{
public string ID { get; set; }
public int ID_Num { get; set; }
public bool ComandoAtuar { get; set; }
public S_Code Componente { get; set; } = S_Code.sBMB;
public bool LeituraEstado
@ -867,34 +885,35 @@ namespace AgroBase.Models.Modules
public string ProtocoloConfiguracao(PinoutDataModel Pinout, bool Conectar)
public byte[] ProtocoloConfiguracao(PinoutDataModel pinout, bool conectar)
{
var _pinout = new PinoutDataModel()
{
ExpansorGPIO = Pinout.ExpansorGPIO,
EnderecoGPIO = Pinout.EnderecoGPIO,
Pinos = Pinout.Pinos.ToList(),
};
_pinout.Pinos = _pinout.Pinos.Where(x => x.ComponenteID == ID).ToList();
string Protocolo =
ID + SerialService.SplitSubParams +
(Conectar ? "1" : "0") + SerialService.SplitSubParams +
Variaveis.OperacaoEmAndamento.Controle.PressaoLinha.ToString() + SerialService.SplitSubParams +
PinoutModel.PinoProtocolo(_pinout, Funcoes, SerialService.SplitSubParams);
var pino = pinout.Pinos.FirstOrDefault(p => p.ComponenteID == ID);
byte pressaoMax = (byte)Variaveis.OperacaoEmAndamento.Controle.PressaoLinha;
return Protocolo;
return new byte[]
{
(byte)Componente,
(byte)ID_Num,
(byte)(conectar ? 1 : 0),
pressaoMax,
(byte)(pino?.Barramento ?? TiposBarramentos.CONTROLADOR),
(byte)(pino?.Pino ?? PinoutUtils.PINO_INVALIDO)
};
}
public string ProtocoloComando()
public (F_Code, byte[]) ProtocoloComando()
{
string ProtocoloBomba =
((int)F_Code.Cmd).ToString() + SerialService.SplitMessage +
ID + SerialService.SplitParams +
((int)Componente) + SerialService.SplitParams +
(int)(ComandoAtuar ? Estado.Ligado : Estado.Desligado) + SerialService.SplitParams +
Variaveis.OperacaoEmAndamento.Controle.PressaoLinha;
return ProtocoloBomba;
return (
F_Code.CmdTx,
new byte[]
{
(byte)F_Code.CmdTx,
(byte)S_Code.sBMB,
(byte)ID_Num,
(byte)(ComandoAtuar ? Estado.Ligado : Estado.Desligado),
(byte)(Variaveis.OperacaoEmAndamento.Controle.PressaoLinha)
}
);
}
@ -903,6 +922,9 @@ namespace AgroBase.Models.Modules
AtuadorBombaModel clone = new AtuadorBombaModel()
{
ID = this.ID,
Componente = this.Componente,
ID_Num = this.ID_Num,
ComandoAtuar = this.ComandoAtuar,
Comandar = this.Comandar,
Testando = this.Testando,
Funcoes = this.Funcoes,
@ -1122,6 +1144,8 @@ namespace AgroBase.Models.Modules
{
public DateTime Momento { get; set; }
public bool Conectado { get; set; }
public T_Code Dispositivo { get; set; }
public int Versao { get; set; }
public string Mod_ID { get; set; }
public int QualidadeWifi { get; set; }
public int LatenciaLoop { get; set; }
@ -1130,6 +1154,39 @@ namespace AgroBase.Models.Modules
public List<FirmwareSensorFluxo> SensoresFluxo { get; set; } = new List<FirmwareSensorFluxo>();
public List<FirmwareSensorMassa> SensoresMassa { get; set; } = new List<FirmwareSensorMassa>();
public List<FirmwareSensorPressao> SensoresPressao { get; set; } = new List<FirmwareSensorPressao>();
public DateTime UltimoComandoRespondido { get; set; }
}
public class AtuHandler : ICanMessageHandler
{
public void ProcessarMensagem(CanMessage mensagem)
{
F_Code func = (F_Code)mensagem.DataRx[0];
byte id = mensagem.Id;
var data = mensagem.DataRx;
var item = Variaveis.OperacaoEmAndamento.DispAtu.Dados.DadosLeitura;
switch (func)
{
case F_Code.ChkRx:
if (data != null && data.Length >= 4)
{
T_Code tipoModulo = (T_Code)data[1];
bool conectado = data[2] == 1;
int versao = data[3];
Console.WriteLine($"[ATU] Resposta CHK recebida. Tipo={tipoModulo}, Conectado={conectado}, Versão={versao}");
item.Conectado = conectado;
item.Dispositivo = tipoModulo;
item.Versao = versao;
}
break;
}
item.UltimoComandoRespondido = DateTime.Now;
}
}

View File

@ -29,7 +29,7 @@ namespace AgroBase.Models.Modules
}
public Sentido Sentido_SP { get; set; } = Sentido.Parado;
public double Angulo_SP { get; set; } = 0;
public double Angulo_Offset { get; set; } = 0;
public double FolgaMecanica { get; set; } = 0;
public double Velocidade_Max { get; set; } = 600;
public int Velocidade
{
@ -328,15 +328,23 @@ namespace AgroBase.Models.Modules
await Task.Delay(1000);
//await MKS057DService.EnviarComandoControle(MKS057DService.MontarComandoSetZero(Addr));
MKS057DCanService.SetZero(Addr);
await Task.Delay(500);
for (int i = 0; i < 5; i++)
{
MKS057DCanService.SetZero(Addr);
if (FuncoesMatematicas.ValorEstaEntre(Angulo, 0, 1))
{
break;
}
await Task.Delay(1000);
}
bool Sucesso = false;
bool EstadoInicial = IN1_Atuado;
bool EstadoAnterior = EstadoInicial;
double _anguloAnterior = Angulo;
double _velocidadeAnterior = 0;
int _anguloSP = 45;
int _offset = 0;
@ -429,14 +437,26 @@ namespace AgroBase.Models.Modules
//MKS057DCanService.Parar(Addr);
//await Task.Delay(1500);
int _centro = Convert.ToInt32((_anguloEntrada + _anguloSaida) / 2.0);
_sentido = _sentido == Sentido.Horario ? Sentido.Antihorario : Sentido.Horario;
double _centro = CalcularCentroCompensado(_anguloEntrada, _anguloSaida, FolgaMecanica, _sentido);
//await MKS057DService.EnviarComandoControle(MKS057DService.MontarComandoMovimento(Addr, _centro, 36, Sentido.Horario));
MKS057DCanService.Movimento(Addr, _centro, 36, Sentido.Horario);
MKS057DCanService.Movimento(Addr, _centro, VelocidadeGiro, _sentido);
await Task.Delay(2500);
//await MKS057DService.EnviarComandoControle(MKS057DService.MontarComandoSetZero(Addr));
MKS057DCanService.SetZero(Addr);
await Task.Delay(1000);
for (int i = 0; i < 5; i++)
{
MKS057DCanService.SetZero(Addr);
if (FuncoesMatematicas.ValorEstaEntre(Angulo, 0, 1))
{
break;
}
await Task.Delay(1000);
}
break;
}
@ -453,7 +473,6 @@ namespace AgroBase.Models.Modules
MKS057DCanService.Movimento(Addr, _anguloSP, VelocidadeGiro, _sentido);
}
_anguloAnterior = Angulo;
_velocidadeAnterior = VelocidadeGiro;
if (Angulo > anguloMaxVisitado)
{
@ -498,5 +517,21 @@ namespace AgroBase.Models.Modules
return VelocidadeGiro;
}
private double CalcularCentroCompensado(double entrada, double saida, double folga, Sentido sentido)
{
double centro = (entrada + saida) / 2.0;
// Determina o sentido do giro baseado na diferença
double direcao = sentido == Sentido.Horario ? 1 : -1;
double compensacao = (folga / 2.0) * direcao;
double centroCompensado = centro + compensacao;
Console.WriteLine($"Motor: {Mod_ID}, Folga: {FolgaMecanica}, Entrada: {entrada}, Saida: {saida}, Centro: {centro}, Compensacao: {compensacao}, Centro Compensado: {centroCompensado}");
return centroCompensado;
}
}
}

View File

@ -4,16 +4,13 @@ namespace AgroBase.Models
{
public interface DispositivoBaseModel
{
bool Conectado { get; }
int _TaxaAmostragem { get; set; }
byte _EnderecoCAN { get; set; }
void RecebeProtocoloModulo(string Protocolo);
void DefineStatusConexao(string Mod_ID, bool conectado);
string GetTaxaAmostragem();
void SetTaxaAmostragem(int TaxaAmostragem);
bool GetStatusConexao();
Dictionary<string, List<string>> ProtocoloConfiguracao(bool Conectar);
string ProtocoloVerificacao(bool completo);
List<byte[]> ProtocoloConfiguracao(bool Conectar);
void IniciarRegistrador();
void PararRegistrador();
string GetIP();
void LimparDados<T>(T Dados);
}

View File

@ -352,27 +352,7 @@ namespace AgroBase.Models.Modules
public string ProtocoloConfiguracao(bool Conectar)
{
var _pinout = new PinoutDataModel()
{
ExpansorGPIO = ModuloMvdModel.Pinout.ExpansorGPIO,
EnderecoGPIO = ModuloMvdModel.Pinout.EnderecoGPIO,
ExpansorADS = ModuloMvdModel.Pinout.ExpansorADS,
EnderecoADS = ModuloMvdModel.Pinout.EnderecoADS,
Pinos = ModuloMvdModel.Pinout.Pinos.ToList(),
};
_pinout.Pinos = _pinout.Pinos.Where(x => x.ComponenteID == ID).ToList();
string Protocolo =
((int)F_Code.Cfg).ToString() + SerialService.SplitMessage +
ID + SerialService.SplitParams +
(Conectar ? "1" : "0") + SerialService.SplitParams +
Endereco + SerialService.SplitParams +
NumeroPolos + SerialService.SplitParams +
Rampa + SerialService.SplitParams +
Variaveis.OperacaoEmAndamento.DispMvd.Dados.RPM_Max_MotorBLDC + SerialService.SplitParams +
PinoutModel.PinoProtocolo(_pinout, Funcoes, SerialService.SplitParams);
return Protocolo;
return "";
}
public void EnviarComandoControle(Direcao DirecaoAtual)

View File

@ -10,6 +10,9 @@ namespace AgroBase.Models.Modules
{
public class MovimentacaoUnificadaModel : DispositivoBaseModel
{
public T_Code Dispositivo { get; set; } = T_Code.Mvd;
public byte _EnderecoCAN { get; set; } = 0x00;
public bool Conectado
{
get
@ -22,7 +25,7 @@ namespace AgroBase.Models.Modules
}
}
public static int _TaxaAmostragem { get; set; } = 1000;
public int _TaxaAmostragem { get; set; } = 1000;
public double DistanciaPercorridaOperacao { get; set; } = 0;
public double TempoEmAtividade { get; set; } = 0;
@ -151,15 +154,9 @@ namespace AgroBase.Models.Modules
});
}
public Dictionary<string, List<string>> ProtocoloConfiguracao(bool Conectar)
public List<byte[]> ProtocoloConfiguracao(bool Conectar)
{
var Config = Modulos.Where(x => x.MovMotor.Comandar || x.DirMotor.Comandar).ToDictionary(x => x.Modulo_ID, x => x.ProtocoloConfiguracao(Conectar).ToList());
return Config;
}
public string ProtocoloVerificacao(bool Completo)
{
return "";
return new List<byte[]>();
}
public void RecebeProtocoloModulo(string Protocolo)
@ -192,30 +189,6 @@ namespace AgroBase.Models.Modules
}
}
public void DefineStatusConexao(string Mod_ID, bool conecatdo)
{
var Modulo = Modulos.FirstOrDefault(x => x.Modulo_ID == Mod_ID);
if (Modulo != null)
{
//Modulo.Conectado = conecatdo;
}
}
public string GetTaxaAmostragem()
{
return _TaxaAmostragem.ToString("00000");
}
public void SetTaxaAmostragem(int TaxaAmostragem)
{
_TaxaAmostragem = TaxaAmostragem;
}
public bool GetStatusConexao()
{
return Conectado;
}
public string GetIP()
{
return IP_Mov;
@ -328,7 +301,7 @@ namespace AgroBase.Models.Modules
return;
}
if (!MKS057DCanService.Iniciado && SerialService.DispositivosMapeados.Any(x => x.Dispositivo == T_Code.Mks))
if (!MKS057DCanService.Iniciado && SerialService.DispositivosMapeados.Any(x => x.Dispositivo == T_Code.Dir))
{
//await MKS057DService.InicializarEthernetService();
@ -469,42 +442,6 @@ namespace AgroBase.Models.Modules
{
List<string> Config = new List<string>();
var _pinout = new PinoutDataModel()
{
ExpansorGPIO = Pinout.ExpansorGPIO,
EnderecoGPIO = Pinout.EnderecoGPIO,
Pinos = Pinout.Pinos.ToList(),
};
_pinout.Pinos = _pinout.Pinos.Where(x => x.ComponenteID == T_Code.Mvd.ToString()).ToList();
string ProtocoloMOD =
((int)F_Code.Cfg).ToString() + SerialService.SplitMessage +
Modulo_ID + SerialService.SplitParams +
(Conectar ? "1" : "0") + SerialService.SplitParams +
MovimentacaoUnificadaModel._TaxaAmostragem.ToString() + SerialService.SplitParams +
(RequisitarDados ? "1" : "0") + SerialService.SplitParams +
PinoutModel.PinoProtocolo(_pinout, Funcoes, SerialService.SplitParams);
if (Conectar)
{
Config.Add(ProtocoloMOD);
}
if (MovMotor.Comandar)
{
Config.Add(MovMotor.ProtocoloConfiguracao(Conectar));
}
/*if (DirMotor.Comandar)
{
Config.Add(DirMotor.ProtocoloConfiguracao(Conectar));
}*/
if (!Conectar)
{
Config.Add(ProtocoloMOD);
}
Config.Add(ProtocoloVerificacao(false));
return Config;
}
@ -516,7 +453,7 @@ namespace AgroBase.Models.Modules
SerialService.BeginLine +
0 + SerialService.SplitMessage +
Modulo_ID + SerialService.SplitMessage +
((int)F_Code.Chk).ToString() + SerialService.SplitMessage +
((int)F_Code.ChkTx).ToString() + SerialService.SplitMessage +
"check" +
SerialService.EndLine;
@ -525,7 +462,7 @@ namespace AgroBase.Models.Modules
else
{
string ProtocoloCheck =
((int)F_Code.Chk).ToString() + SerialService.SplitMessage +
((int)F_Code.ChkTx).ToString() + SerialService.SplitMessage +
"check";
return ProtocoloCheck;

View File

@ -301,28 +301,32 @@ namespace AgroBase.Models.Modules
File.WriteAllText(nomeArquivo, JsonConvert.SerializeObject(newPinout));
}
public static string PinoProtocolo(PinoutDataModel _pinout, List<FuncoesPinout> _funcoes, string splitparms)
public static byte[] PinoProtocolo(PinoutDataModel _pinout, List<FuncoesPinout> _funcoes, bool barramento)
{
string Pinos = "";
List<byte> Pinos = new List<byte>();
int i = 0;
foreach (FuncoesPinout funcao in _funcoes)
{
if (i > 0)
{
Pinos += splitparms;
}
var pino = _pinout.Pinos.FirstOrDefault(x => x.Funcao == funcao);
if (pino != null && (pino.Barramento == TiposBarramentos.CONTROLADOR || (pino.Barramento == TiposBarramentos.EXPANSOR_GPIO && _pinout.ExpansorGPIO) || (pino.Barramento == TiposBarramentos.EXPANSOR_ADS && _pinout.ExpansorADS)))
{
Pinos += ((int)pino.Barramento).ToString() + splitparms + pino.Pino.ToString();
if (barramento)
{
Pinos.Add((byte)pino.Barramento);
}
Pinos.Add((byte)pino.Pino);
}
else
{
Pinos += ((int)TiposBarramentos.CONTROLADOR).ToString() + splitparms + "-1";
if (barramento)
{
Pinos.Add((byte)TiposBarramentos.CONTROLADOR);
}
Pinos.Add(PinoutUtils.PINO_INVALIDO);
}
i++;
}
return Pinos;
return Pinos.ToArray();
}
@ -395,6 +399,7 @@ namespace AgroBase.Models.Modules
public static class PinoutUtils
{
public static byte PINO_INVALIDO = 0xFF;
public static List<FuncoesPinout> PinosSecundarios = new List<FuncoesPinout>()
{
FuncoesPinout.SCK,

File diff suppressed because it is too large Load Diff

View File

@ -22,7 +22,7 @@ namespace AgroBase.Models.Operacoes
var Controle = Variaveis.OperacaoEmAndamento.Controle;
if (Variaveis.OperacaoEmAndamento.StatusAtual != StatusOperacao.EmAndamento)
if (Variaveis.OperacaoEmAndamento.StatusAtual != StatusOperacao.EmAndamento || Variaveis.OperacaoEmAndamento.Finalizando)
{
Controle.Angulo = 0;
return;
@ -140,7 +140,7 @@ namespace AgroBase.Models.Operacoes
var Controle = Variaveis.OperacaoEmAndamento.Controle;
if (Variaveis.OperacaoEmAndamento.StatusAtual != StatusOperacao.EmAndamento)
if (Variaveis.OperacaoEmAndamento.StatusAtual != StatusOperacao.EmAndamento || Variaveis.OperacaoEmAndamento.Finalizando)
{
Controle.PercentualVelocidadeSP = 0;
Controle.FiltroVelocidade.Reset(Controle.PercentualVelocidadeSP);
@ -224,9 +224,9 @@ namespace AgroBase.Models.Operacoes
double faixaVel = Controle.PercentualVelocidadeMax - Controle.PercentualVelocidadeMin;
double velocidadeFinal = Controle.PercentualVelocidadeMax - (faixaVel * penalidade);
double velocidadeRelativa = Math.Round(Math.Max(Controle.PercentualVelocidadeMin, velocidadeFinal), 2);
double velocidadeRelativa = Math.Max(Controle.PercentualVelocidadeMin, velocidadeFinal);
double velocidadeFiltrada = Controle.FiltroVelocidade.Filtrar(velocidadeRelativa);
double velocidadeFiltrada = Math.Round(Controle.FiltroVelocidade.Filtrar(velocidadeRelativa), 2);
return velocidadeFiltrada;
}
@ -240,7 +240,7 @@ namespace AgroBase.Models.Operacoes
{
var Controle = Variaveis.OperacaoEmAndamento.Controle;
if (Variaveis.OperacaoEmAndamento.StatusAtual != StatusOperacao.EmAndamento)
if (Variaveis.OperacaoEmAndamento.StatusAtual != StatusOperacao.EmAndamento || Variaveis.OperacaoEmAndamento.Finalizando)
{
var BicosNaoAtuados = new List<AtuadorBicoModel>(Variaveis.OperacaoEmAndamento.DispAtu?.Dados?.BicosPulverizadores ?? new List<AtuadorBicoModel>());
BicosNaoAtuados.ForEach(x => x.ComandoAtuar = false);

View File

@ -1272,13 +1272,13 @@ namespace AgroBase.Models
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
bool MovimentoLiberado = Variaveis.OperacaoEmAndamento.StatusAtual == StatusOperacao.EmAndamento && !MKS057DCanService.Referenciando;
bool MovimentoLiberado = Variaveis.OperacaoEmAndamento.StatusAtual == StatusOperacao.EmAndamento && !Variaveis.OperacaoEmAndamento.Finalizando && !MKS057DCanService.Referenciando;
if (MovimentoLiberado || ForcarEnvio)
if (ForcarEnvio || MovimentoLiberado)
{
foreach (var Ctrl in _Controle.TiposControle)
{
if ((Agora - Ctrl.UltimoComando).TotalMilliseconds > Ctrl.DelayEnvioComando)
if (ForcarEnvio || ((Agora - Ctrl.UltimoComando).TotalMilliseconds > Ctrl.DelayEnvioComando))
{
if (Ctrl.Tipo == T_Code.Atu && !_Controle.PulverizadorAutomatico)
{
@ -1289,7 +1289,7 @@ namespace AgroBase.Models
(IDispositivosService)Variaveis.OperacaoEmAndamento.DispAtu :
(IDispositivosService)Variaveis.OperacaoEmAndamento.DispMvd;
var Protocolos = EnviarProtocoloComando(disp, Ctrl.Tipo);
var Protocolos = EnviarProtocoloComando(disp, Ctrl.Tipo, ForcarEnvio);
Ctrl.UltimoComando = Agora;
Ctrl.Comandos.AddRange(Protocolos);
}
@ -1297,7 +1297,7 @@ namespace AgroBase.Models
}
}
public List<string> EnviarProtocoloComando(IDispositivosService Dispositivo, T_Code Tipo)
public List<string> EnviarProtocoloComando(IDispositivosService Dispositivo, T_Code Tipo, bool ForcarEnvio)
{
if (Dispositivo == null || !Variaveis.OperacaoEmAndamento.Iniciado)
{
@ -1331,7 +1331,7 @@ namespace AgroBase.Models
_Controle.Direcao = Direcao.Frente;
}
if (_Controle.RPM_SP != _ControleAnterior.RPM_SP)
if (ForcarEnvio || _Controle.RPM_SP != _ControleAnterior.RPM_SP)
{
((MovimentacaoUnificadaModel)Dispositivo.Dados).Modulos.ForEach(Mod => Mod.MovMotor.EnviarComandoControle(_Controle.Direcao));
@ -1359,7 +1359,7 @@ namespace AgroBase.Models
}
// Só enviar comando se a direção realmente mudou
if (_ControleAnterior.Angulo != _Controle.Angulo)
if (ForcarEnvio || _ControleAnterior.Angulo != _Controle.Angulo)
{
((MovimentacaoUnificadaModel)Dispositivo.Dados).Modulos.ForEach(Mod => Mod.DirMotor.EnviarComandoControle(_Controle.Direcao));
@ -1381,7 +1381,7 @@ namespace AgroBase.Models
{
Variaveis.OperacaoEmAndamento.OpMapaGPS.DefinirDadosControleAtu();
if (_ControleAnterior.BicosAtuados.Count() >= _Controle.BicosAtuados.Count())
if (ForcarEnvio || _ControleAnterior.BicosAtuados.Count() >= _Controle.BicosAtuados.Count())
{
for (int i = 0; i < _Controle.BicosAtuados.Count; i++)
{

View File

@ -750,6 +750,7 @@ namespace AgroBase.Models
);
}
}
public static void picBtn_MouseEnter(object sender, EventArgs e)
{
Task.Run(async () => await TransicaoTamanho((Control)sender, true, 5));
@ -1115,6 +1116,13 @@ namespace AgroBase.Models
};
}
public static string ConverterComandoBytesParaTexto(byte[] data)
{
string comando = string.Join("-", data.Select(x => x.ToString("X")));
return comando;
}
}

View File

@ -16,7 +16,8 @@ namespace AgroBase.Services
public DateTime Momento { get; set; }
public T_Code Dispositivo { get; set; }
public byte Id { get; set; }
public byte funcCode { get; set; }
public byte funcCodeTx { get; set; }
public byte funcCodeRx { get; set; }
public byte[] DataTx { get; set; }
public byte[] DataRx { get; set; }
public bool Enviado { get; set; }
@ -33,11 +34,18 @@ namespace AgroBase.Services
public class CanService : IDisposable
{
private static SerialPort _serialPort;
public static SerialPort _serialPort;
public static string _portName;
private static int _baudRate;
private static object _lock = new object();
public static bool IsConnected { get; private set; }
public static bool Iniciado
{
get
{
return SerialService.DispositivosCan.Any(d => SerialService.DispositivosMapeados.Any(x => x.Conectado && x.Dispositivo == d));
}
}
private static AsyncTaskTimerModel tmrEnviarCAN;
private static AsyncTaskTimerModel tmrOuvirCAN;
private static StringBuilder SerialCANBuffer = new StringBuilder();
@ -46,48 +54,49 @@ namespace AgroBase.Services
private static List<CanMessage> Mensagens = new List<CanMessage>();
public CanService()
{
}
public static void RegistrarHandler(T_Code dispositivo, ICanMessageHandler handler)
{
_roteadores[dispositivo] = handler;
}
public static void AbrirComunicacao(SerialPort porta)
public static void DefinirPortaCOM(SerialPort Porta)
{
try
if (!IsConnected)
{
porta.Close();
_portName = porta.PortName;
_baudRate = 115200;
_serialPort = new SerialPort(_portName, _baudRate, Parity.None, 8, StopBits.One);
_serialPort.Open();
EnviarComando("S6\r"); // 500Kbps
Thread.Sleep(100);
EnviarComando("O\r"); // Open CAN
Thread.Sleep(100);
tmrOuvirCAN?.Dispose();
tmrOuvirCAN = new AsyncTaskTimerModel("tmrOuvirCAN", OuvirCAN, 10);
tmrOuvirCAN.Start();
tmrEnviarCAN?.Dispose();
tmrEnviarCAN = new AsyncTaskTimerModel("tmrEnviarCAN", EnviarCAN, 10);
tmrEnviarCAN.Start();
IsConnected = true;
Porta.Close();
}
catch (Exception ex)
if (_serialPort == null || !IsConnected)
{
Console.WriteLine($"Erro ao abrir comunicacao CAN: {ex.Message}");
tmrOuvirCAN?.Dispose();
IsConnected = false;
lock (_lock)
{
_portName = Porta.PortName;
_baudRate = 115200;
_serialPort = new SerialPort(_portName, _baudRate, Parity.None, 8, StopBits.One);
_serialPort.Open();
EnviarComando("S6\r"); // 500Kbps
Thread.Sleep(100);
EnviarComando("O\r"); // Open CAN
Thread.Sleep(100);
tmrOuvirCAN?.Dispose();
tmrOuvirCAN = new AsyncTaskTimerModel("tmrOuvirCAN", OuvirCAN, 10);
tmrOuvirCAN.Start();
tmrEnviarCAN?.Dispose();
tmrEnviarCAN = new AsyncTaskTimerModel("tmrEnviarCAN", EnviarCAN, 10);
tmrEnviarCAN.Start();
IsConnected = true;
}
}
if (_serialPort != null && !_serialPort.IsOpen)
{
_serialPort.Open();
}
}
@ -140,14 +149,21 @@ namespace AgroBase.Services
byte funcCode = data[0];
var mensagem = new CanMessage();
List<CanMessage> mensagensPorID = new List<CanMessage>();
lock (Mensagens)
{
mensagem = Mensagens.OrderByDescending(x => x.EnviadoEm).FirstOrDefault(x => x.Id == id && x.funcCode == funcCode && x.Enviado && !x.Respondido);
mensagensPorID = Mensagens.Where(x => x.Id == id).ToList();
}
mensagem = mensagensPorID.OrderBy(x => x.EnviadoEm).FirstOrDefault(x => x.Id == id && x.funcCodeRx == funcCode && x.Enviado && !x.Respondido);
if (mensagem == null)
{
mensagem = mensagensPorID.OrderBy(x => x.EnviadoEm).FirstOrDefault(x => x.Id == id && x.Enviado && !x.Respondido);
}
if (mensagem == null)
{
mensagem = new CanMessage { Id = (byte)id, DataRx = data };
mensagem = new CanMessage { Id = (byte)id, DataRx = data, Dispositivo = mensagensPorID.FirstOrDefault()?.Dispositivo ?? T_Code.Vzo };
}
mensagem.DataRx = data;
@ -169,11 +185,11 @@ namespace AgroBase.Services
}
}
public static void AdicionarMensagemNaFila(T_Code Dispositivo, byte id, byte funcCode, byte[] payload = null, bool get = true)
public static void AdicionarMensagemNaFila(T_Code Dispositivo, byte id, byte funcCodeTx, byte funcCodeRx, byte[] payload = null, bool get = true)
{
if (_serialPort?.IsOpen != true) return;
var dados = new List<byte> { funcCode };
var dados = new List<byte> { funcCodeTx };
if (payload != null)
dados.AddRange(payload);
@ -187,7 +203,8 @@ namespace AgroBase.Services
Momento = DateTime.Now,
Dispositivo = Dispositivo,
Id = id,
funcCode = funcCode,
funcCodeTx = funcCodeTx,
funcCodeRx = funcCodeRx,
DataTx = dados.ToArray(),
ComResposta = get
};
@ -196,7 +213,7 @@ namespace AgroBase.Services
{
if (Mensagens.Any(x =>
x.Id == msg.Id && // do mesmo Id
x.funcCode == msg.funcCode && // da mesma funcao
x.funcCodeTx == msg.funcCodeTx && // da mesma funcao
x.DataTx.SequenceEqual(msg.DataTx) && // com os mesmos comandos
(!x.Enviado || (x.ComResposta && !x.Respondido)) // ainda nao enviadas ou que aguarda uma resposta
))
@ -294,6 +311,8 @@ namespace AgroBase.Services
if (_serialPort?.IsOpen == true)
{
_serialPort.Write(comando);
Console.WriteLine($"[CAN] Frame enviado: {comando}");
}
}
@ -301,7 +320,7 @@ namespace AgroBase.Services
{
lock (Mensagens)
{
var limite = DateTime.Now.AddSeconds(-5);
var limite = DateTime.Now.AddSeconds(-10);
Mensagens.RemoveAll(x =>
(!x.ComResposta && x.Enviado) || // mensagens enviadas que nao exigem resposta
(x.Respondido && x.RespondidoEm < limite) || // mensagens respondidas a mais de 5 segundos

View File

@ -9,10 +9,8 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using static AgroBase.Models.Enums;
using static MqttService;
namespace AgroBase.Comum
{
@ -21,6 +19,24 @@ namespace AgroBase.Comum
public T_Code Dispositivo { get; set; } = T_Code.Vzo;
public string _Nome { get; set; }
public string _Descricao { get; set; }
public byte _EnderecoCAN
{
get
{
return Dados._EnderecoCAN;
}
}
public int _TaxaAmostragem
{
get
{
return Dados._TaxaAmostragem;
}
set
{
Dados._TaxaAmostragem = value;
}
}
public DateTime CriadoEm
{
get
@ -48,109 +64,6 @@ namespace AgroBase.Comum
//public int TempoConectado { get; set; } = 0;
public MqttTopicosModel MqttTopicoEnvioComandos;
public MqttTopicosModel MqttTopicoRecebimentoDados;
public async Task GerenciarMqttTopicos()
{
MqttTopicoEnvioComandos = await Variaveis.MqttService.AdicionarNovoTopico($"disp/tx/{Dispositivo.ToString()}");
MqttTopicoRecebimentoDados = await Variaveis.MqttService.AdicionarNovoTopico($"disp/rx/{Dispositivo.ToString()}", true, 1, async (Mensagem) =>
{
ReceberDadosMqtt(Mensagem);
});
}
private void ReceberDadosMqtt(MqttTopicosMensagensModel Mensagem)
{
string Recebido = Mensagem.Mensagem;
string mensagem = "";
//Console.WriteLine(Recebido);
bool RespostaMensagem = false;
if (Recebido.Contains(SerialService.SplitMessage))
{
string Mod_ID = Recebido.Split(SerialService.SplitMessage[0])[0];
mensagem = Recebido.Substring(Mod_ID.Length + 1, Recebido.Length - Mod_ID.Length - 1);
var DadosMensagem = mensagem.Split(SerialService.SplitMessage[0]);
if (DadosMensagem.Length > 2 && int.TryParse(DadosMensagem[0], out int val))
{
try
{
F_Code funcao = (F_Code)(val);
switch (funcao)
{
case F_Code.Msg:
{
int _id = int.Parse(DadosMensagem[1]);
FilaService.MarcarMensagemRecebida(_id);
RespostaMensagem = true;
break;
}
case F_Code.Chk:
{
bool conectado = DadosMensagem[3] == "1";
Dados.DefineStatusConexao(Mod_ID, conectado);
RespostaMensagem = true;
break;
}
}
}
catch
{
}
}
}
SalvarLog(new DispositivoLogModel()
{
Momento = DateTime.Now,
Enviado = false,
Protocolo = Recebido,
});
//AtualizarConsole("< " + DateTime.Now.ToString("HH:mm:ss:fff") + " - " + Recebido);
if (!RespostaMensagem && mensagem.Trim().EndsWith(SerialService.EndLine))
{
Dados.RecebeProtocoloModulo(mensagem.Trim());
}
}
public async Task EnviarDadosMQTT(string Dados)
{
if (MqttTopicoEnvioComandos == null || string.IsNullOrEmpty(Dados))
{
throw new Exception("O tópico de envio de comandos não foi iniciado ou não foi enviado dados para envio");
}
//AtualizarConsole("> " + DateTime.Now.ToString("HH:mm:ss:fff") + " - " + Dados);
try
{
// Publique o array de bytes via MQTT
await Variaveis.MqttService.PublishAsync(
MqttTopicoEnvioComandos,
Dados
);
//Console.WriteLine("Dados enviados: " + Dados);
SalvarLog(new DispositivoLogModel()
{
Momento = DateTime.Now,
Enviado = true,
Protocolo = Dados,
ErroEnvio = false,
});
}
catch (Exception ex)
{
Console.WriteLine("Erro ao enviar comando para o tópico: " + MqttTopicoEnvioComandos.Topico + " - " + ex.Message);
throw ex;
}
}
private void SalvarLog(DispositivoLogModel Log)
{
@ -158,35 +71,21 @@ namespace AgroBase.Comum
VariaveisOperacao.RegistrarLogDispositivo(Logs, Dispositivo, ".json", 100);
}
public MqttTopicosModel GetMqttTopico(bool Envio)
public void AdicionarMensagemFila(F_Code funcao, byte[] dados = null, bool get = true, F_Code funcaoRx = F_Code.Nda)
{
return Envio ? MqttTopicoEnvioComandos : MqttTopicoRecebimentoDados;
}
public void AdicionarMensagemFila(string Mod_ID, string mensagem, bool _prioridade, bool _aguardaCallback)
{
if (Mod_ID != "" && mensagem != "")
if ((int)funcao % 2 == 1)
{
string comandoEnviar =
"0" +
SerialService.SplitMessage +
Mod_ID +
SerialService.SplitMessage +
mensagem +
SerialService.EndLine;
//FilaService.AdicionarMensagemFila(Mod_ID, Dispositivo, mensagem, _prioridade, _aguardaCallback);
Task.Run(async () =>
byte funcCodeRx = (byte)(((int)funcao) + 1);
if (funcaoRx != F_Code.Nda)
{
await EnviarDadosMQTT(comandoEnviar);
//Console.WriteLine("Comando enviado: " + comandoEnviar);
});
funcCodeRx = (byte)funcaoRx;
}
CanService.AdicionarMensagemNaFila(Dispositivo, _EnderecoCAN, (byte)funcao, funcCodeRx, dados, get);
}
}
public Control InstanciarDispositivo(int index)
{
((dynamic)Dados).Conectado = false;
frmPin = new frmPinout(Dispositivo);
gpbItem = new GroupBox()
@ -223,7 +122,7 @@ namespace AgroBase.Comum
Name = "nud" + _Nome + "Amo",
Minimum = 0,
Maximum = 99999,
Value = decimal.Parse(Dados.GetTaxaAmostragem()),
Value = Dados._TaxaAmostragem,
Location = new System.Drawing.Point() { X = 31, Y = 144 },
Size = new System.Drawing.Size() { Height = 24, Width = 89 }
};
@ -232,7 +131,7 @@ namespace AgroBase.Comum
lblStatus = new Label()
{
Name = "lbl" + _Nome + "Sta",
Text = Dados.GetStatusConexao() ? "Conectado" : "Desconectado",
Text = Dados.Conectado ? "Conectado" : "Desconectado",
Location = new System.Drawing.Point() { X = 28, Y = 231 },
Size = new System.Drawing.Size() { Height = 17, Width = 100 }
};
@ -475,12 +374,12 @@ namespace AgroBase.Comum
}
var Config = Dados.ProtocoloConfiguracao(true);
frmInstancial.frmPrincipal.lblStripErro.Text = Config.Any() ? Config.FirstOrDefault().Value.FirstOrDefault() : "";
frmInstancial.frmPrincipal.lblStripErro.Text = Config.Any() ? FuncoesGlobais.ConverterComandoBytesParaTexto(Config.First().ToArray()) : "";
}
private void nudAmostragem_ValueChanged(object sender, EventArgs e)
{
Dados.SetTaxaAmostragem((Convert.ToInt32(((NumericUpDown)sender).Value)));
Dados._TaxaAmostragem = Convert.ToInt32(((NumericUpDown)sender).Value);
}
private void txtEnvios_KeyDown(object sender, KeyEventArgs e)
@ -489,7 +388,7 @@ namespace AgroBase.Comum
{
string modId = txtEnvios.Text.Split('¬')[0];
string mensagem = txtEnvios.Text.Split('¬')[1];
AdicionarMensagemFila(modId, mensagem, false, true);
//AdicionarMensagemFila(modId, mensagem, false, true);
txtEnvios.Text = "";
txtEnvios.Focus();
}
@ -503,13 +402,15 @@ namespace AgroBase.Comum
public void EnviarProtocolosConfiguracao(bool Conectar = true)
{
Dictionary<string, List<string>> Config = Dados.ProtocoloConfiguracao(Conectar);
foreach (var ProtocoloConfiguracao in Config)
var Config = Dados.ProtocoloConfiguracao(Conectar);
foreach (var data in Config)
{
if (ProtocoloConfiguracao.Key != "" && ProtocoloConfiguracao.Value.Any())
F_Code funcCodeRx = F_Code.Nda;
if ((S_Code)data[0] == S_Code.sMOD)
{
ProtocoloConfiguracao.Value.ForEach(x => AdicionarMensagemFila(ProtocoloConfiguracao.Key, x, true, true));
funcCodeRx = F_Code.ChkRx;
}
AdicionarMensagemFila(F_Code.CfgTx, data, false, funcCodeRx);
}
}
@ -529,7 +430,18 @@ namespace AgroBase.Comum
}
var configText = File.ReadAllText(nomeArquivo);
//Console.WriteLine(configText);
var Parametros = JsonConvert.DeserializeObject<T>(configText);
T Parametros = default(T);
try
{
Parametros = JsonConvert.DeserializeObject<T>(configText);
}
catch
{
var newConfig = empty;
File.WriteAllText(nomeArquivo, JsonConvert.SerializeObject(newConfig));
return CarregarParametros(empty);
}
return Parametros;
}

View File

@ -134,7 +134,7 @@ namespace AgroBase.Services
var Dispositivo = Variaveis.DispositivosConectados.FirstOrDefault(x => x.Dispositivo == Mensagem.Dispositivo);
if (Dispositivo == null) return false;
Dispositivo.EnviarDadosMQTT(
/*Dispositivo.EnviarDadosMQTT(
//SerialService.BeginLine +
Mensagem.Id +
SerialService.SplitMessage +
@ -142,7 +142,7 @@ namespace AgroBase.Services
SerialService.SplitMessage +
Mensagem.Mensagem +
SerialService.EndLine
);
);*/
MarcarMensagemRecebida(Mensagem.Id);

View File

@ -542,6 +542,7 @@ namespace AgroBase.Services
{
if (Variaveis.IsAgroMonitor)
{
EnviarCoordenadasParaMapa(UltimaLeitura.Latitude, UltimaLeitura.Longitude, UltimaLeitura.AnguloCarroDefinido, false, Variaveis.ConexaoLoRa.parametros.address);
return;
}

View File

@ -1,9 +1,6 @@
using AgroBase.Models;
using System;
using System.Threading.Tasks;
using System.Windows.Forms;
using static AgroBase.Models.Enums;
using static MqttService;
namespace AgroBase.Services
{
@ -12,15 +9,13 @@ namespace AgroBase.Services
T_Code Dispositivo { get; set; }
string _Nome { get; set; }
string _Descricao { get; set; }
byte _EnderecoCAN { get; }
DispositivoBaseModel Dados { get; set; }
GroupBox gpbItem { get; set; }
Task GerenciarMqttTopicos();
Task EnviarDadosMQTT(string Protocolo);
MqttTopicosModel GetMqttTopico(bool Envio);
Control InstanciarDispositivo(int index);
void AtualizaIndex(int index);
void SalvarParametros(DispositivoBaseModel dados);
void AdicionarMensagemFila(string Mod_ID, string Protocolo, bool _prioridade, bool _aguardaCallback);
void AdicionarMensagemFila(F_Code funcao, byte[] dados, bool get, F_Code funcaoRx);
void EnviarProtocolosConfiguracao(bool Conectar = true);
void CarregarParametrosModulos();
}

View File

@ -0,0 +1,22 @@
using AgroBase.Models.Modules;
using static AgroBase.Models.Enums;
namespace AgroBase.Services
{
public interface IFirmwareSensorBase
{
string ID { get; set; }
bool Iniciado { get; set; }
}
public interface ISensorModelBase
{
string ID { get; set; }
int ID_Num { get; set; }
string Descricao { get; set; }
S_Code Componente { get; set; }
bool Aferir { get; set; }
bool Inicializado { get; }
byte[] ProtocoloConfiguracao(PinoutDataModel pinout, bool conectar);
}
}

View File

@ -50,7 +50,7 @@ namespace AgroBase.Services
{
if (!CanService.IsConnected)
{
CanService.AbrirComunicacao(porta);
CanService.DefinirPortaCOM(porta);
CanService.RegistrarHandler(Dispositivo, _MksHandler);
}
@ -85,7 +85,7 @@ namespace AgroBase.Services
return false;
}
if (!Iniciado)
if (!CanService.Iniciado)
{
CanService.Fechar();
}
@ -157,7 +157,7 @@ namespace AgroBase.Services
private static void EnviarComando(T_Code Dispositivo, byte id, byte funcCode, byte[] payload = null, bool get = true)
{
CanService.AdicionarMensagemNaFila(Dispositivo, id, funcCode, payload, get);
CanService.AdicionarMensagemNaFila(Dispositivo, id, funcCode, funcCode, payload, get);
}
public static void SetModoOperacao(byte id, byte modo)
@ -192,7 +192,7 @@ namespace AgroBase.Services
ushort vel = (ushort)velocidade;
byte[] VelocidadeBytes = BitConverter.GetBytes(vel);
byte acc = 2;
byte acc = 0;
if (modo == ModosControle.Pulsos)
{

View File

@ -29,6 +29,7 @@ namespace AgroBase.Services
public static List<T_Code> DispositivosConexaoInicial = new List<T_Code>() { T_Code.Mvd, T_Code.Atu, T_Code.Sen };
public static List<T_Code> DispositivosProprios = new List<T_Code>() { T_Code.Atu, T_Code.Sen };
public static List<T_Code> DispositivosModbus = new List<T_Code>() { T_Code.Pzm, T_Code.Wit, T_Code.A05 };
public static List<T_Code> DispositivosCan = new List<T_Code>() { T_Code.Mks, T_Code.Sen, T_Code.Atu };
public static List<T_Code> DispositivosMultiplos = new List<T_Code>() { T_Code.Bld, T_Code.Mks, T_Code.Mvd, T_Code.Oid, T_Code.Mov, T_Code.Dir };
public static List<DispositivoDetalhesModel> DispositivosMapeados = new List<DispositivoDetalhesModel>();
@ -253,9 +254,10 @@ namespace AgroBase.Services
}
}
bool DispMks = await ProcuraDispositivoMKS(_Porta);
if (DispMks)
bool dispositivoCan = await ProcurarDispositivosCAN(_Porta);
if (dispositivoCan)
{
_Porta.Close();
continue;
}
}
@ -286,6 +288,7 @@ namespace AgroBase.Services
await ProcurarDispositivosEthernet();
}
var DispositivosRemovidos = dispositivosMapeados.Where(x => x.Tipo == TipoConexao.PortaCOM && !Portas.Contains(x.Endereco)).ToList();
foreach (var Dispositivo in DispositivosRemovidos)
{
@ -322,6 +325,19 @@ namespace AgroBase.Services
DispositivosMapeados.Remove(DispositivosMapeados.FirstOrDefault(x => x.Dispositivo == _Disp));
}
}
if (CanService.Iniciado)
{
await ProcurarDispositivosCAN(CanService._serialPort);
}
else
{
CanService.Fechar();
foreach (var _Disp in DispositivosCan)
{
DispositivosMapeados.Remove(DispositivosMapeados.FirstOrDefault(x => x.Dispositivo == _Disp));
}
}
}
catch (Exception ex)
{
@ -403,7 +419,7 @@ namespace AgroBase.Services
Verificacao = (F_Code)check;
if (Verificacao == F_Code.Msg)
if (Verificacao == F_Code.MsgTx)
{
return true;
}
@ -418,7 +434,7 @@ namespace AgroBase.Services
{
Endereco = Porta.PortName,
Dispositivo = Dispositivo,
Erro = Verificacao == F_Code.Err,
Erro = Verificacao == F_Code.ErrRx,
Versao = Versao,
Mod_ID = Mod_ID,
});
@ -485,7 +501,6 @@ namespace AgroBase.Services
new SerialPort()
);
dispositivoService.CarregarParametrosModulos();
Task.Run(async () => await dispositivoService.GerenciarMqttTopicos());
Variaveis.DispositivosConectados.Add(dispositivoService);
dispositivoService.Dados.IniciarRegistrador();
}
@ -666,6 +681,37 @@ namespace AgroBase.Services
}
}
private static async Task<bool> ProcurarDispositivosCAN(SerialPort porta)
{
bool dispCan = false;
if (!Variaveis.OperacaoEmAndamento.DispSen.Dados.Conectado)
{
bool DispSen = await Variaveis.OperacaoEmAndamento.DispSen.Dados.VerificaPortaSEN(porta);
if (DispSen)
{
dispCan = DispSen;
}
}
if (!Variaveis.OperacaoEmAndamento.DispAtu.Dados.Conectado)
{
bool DispAtu = await Variaveis.OperacaoEmAndamento.DispAtu.Dados.VerificaPortaATU(porta);
if (DispAtu)
{
dispCan = DispAtu;
}
}
bool DispMks = await ProcuraDispositivoMKS(porta);
if (DispMks)
{
dispCan = DispMks;
}
return dispCan;
}
private static void ProcurarDispositivosUSB()
{
if (!Variaveis.IsAgroMonitor)
@ -688,18 +734,6 @@ namespace AgroBase.Services
{
bool ethernetEncontrado = false;
if (WifiService.WifiConectado)
{
foreach (T_Code disp in DispositivosProprios)
{
bool proprio = await ProcuraDispositivoProprio(disp);
if (proprio)
{
ethernetEncontrado = true;
}
}
}
/*bool DispBld = await ProcuraDispositivoBLD();
if (DispBld)
{
@ -724,78 +758,6 @@ namespace AgroBase.Services
return false;
}
private static async Task<bool> ProcuraDispositivoProprio(T_Code Disp)
{
if (!DispositivosMapeados.Any(x => x.Dispositivo == Disp))
{
var Modulo = Variaveis.DispositivosConectados.FirstOrDefault(x => x.Dispositivo == Disp);
string ProtocoloCheck = Modulo.Dados.ProtocoloVerificacao(true);
AtualizarConsole($"Procurando dispositivo {Disp.ToString()}");
DateTime MomentoEnvio = DateTime.Now;
await Modulo.EnviarDadosMQTT(ProtocoloCheck);
await Task.Delay(1000);
var topicoRx = Modulo.GetMqttTopico(false);
var Recebido = topicoRx.Mensagens.FirstOrDefault(x => x.Momento >= MomentoEnvio);
if (Recebido != null && Recebido.Mensagem.Length > 2)
{
T_Code Dispositivo = T_Code.Vzo;
F_Code Verificacao = F_Code.Nda;
string Versao = "0";
var Dados = Recebido.Mensagem.Split(SplitMessage[0]);
if (Dados.Length <= 1)
{
return false;
}
string Mod_ID = Dados[0];
int.TryParse(Dados[1], out int check);
if (check == 0)
{
return false;
}
Verificacao = (F_Code)check;
if (Verificacao == F_Code.Msg)
{
return true;
}
Dispositivo = (T_Code)(int.Parse(Dados[2]));
Versao = Dados[3];
if (Dispositivo != T_Code.Vzo && !DispositivosMapeados.Any(x => x.Dispositivo == Dispositivo && x.Mod_ID == Mod_ID))
{
DispositivosMapeados.Add(new DispositivoDetalhesModel()
{
Endereco = Modulo.Dados.GetIP(),
Dispositivo = Dispositivo,
Erro = Verificacao == F_Code.Err,
Versao = Versao,
Mod_ID = Mod_ID,
});
}
AtualizarConsole($"Dispositivo {Disp.ToString()} encontrado");
return true;
}
}
return false;
}
private static async Task<bool> ProcuraDispositivoBLD()
{
if (!BLD300RService.Iniciado || BLD300RService.DadosLeitura.Count(x => x.Iniciado) < (Variaveis.OperacaoEmAndamento.DispMvd?.Dados?.Modulos?.Count() ?? 4))

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 @@
{"tmrRegistrador":{"_uiControl":null,"State":2,"IsRunning":false,"IsStopped":true,"IsCreated":false,"Interval":500,"StackTrace":"AtuadorModel.IniciarRegistrador","Id":"tmrRegistrador_Atu","TimeTick":"00:00:00"},"Modulo_ID":"Atu","IP":"192.168.100.13","RequisitarDados":true,"Conectado":false,"QuantidadeBicos":4,"DensidadeHerbicida":1.05,"BicosPulverizadores":[{"ID":"B01","Posicao":1,"Componente":422,"AtuacaoNivelAlto":true,"ComandoAtuar":false,"Comandar":true,"Testando":false,"Funcoes":[21],"LeituraStatusBico":false,"MediaNivelFluxo":0.0,"Leitura":null,"Inicializado":false,"Atuacoes":0,"InicioAtuacao":"0001-01-01T00:00:00","TempoAtuado":0.0},{"ID":"B02","Posicao":2,"Componente":422,"AtuacaoNivelAlto":true,"ComandoAtuar":false,"Comandar":true,"Testando":false,"Funcoes":[21],"LeituraStatusBico":false,"MediaNivelFluxo":0.0,"Leitura":null,"Inicializado":false,"Atuacoes":0,"InicioAtuacao":"0001-01-01T00:00:00","TempoAtuado":0.0},{"ID":"B03","Posicao":3,"Componente":422,"AtuacaoNivelAlto":true,"ComandoAtuar":false,"Comandar":true,"Testando":false,"Funcoes":[21],"LeituraStatusBico":false,"MediaNivelFluxo":0.0,"Leitura":null,"Inicializado":false,"Atuacoes":0,"InicioAtuacao":"0001-01-01T00:00:00","TempoAtuado":0.0},{"ID":"B04","Posicao":4,"Componente":422,"AtuacaoNivelAlto":true,"ComandoAtuar":false,"Comandar":true,"Testando":false,"Funcoes":[21],"LeituraStatusBico":false,"MediaNivelFluxo":0.02674584437758935,"Leitura":null,"Inicializado":false,"Atuacoes":0,"InicioAtuacao":"0001-01-01T00:00:00","TempoAtuado":0.0}],"BombasPressurizadoras":[{"ID":"BOMBA","ComandoAtuar":false,"Componente":325,"LeituraEstado":false,"Comandar":true,"Testando":false,"Funcoes":[14,35,36,37,5],"LeituraPotencia":0.0,"LeituraPressaoSP":0.0,"LeituraPressao":0.0,"Leitura":null,"Inicializado":false}],"Sensores":[{"LogGrafico":[],"ID":"FLXLN","Prioridade":23,"Descricao":"Fluxo na linha principal","Componente":198,"Aferir":true,"DelayAmostragem":300,"Leitura":null,"Inicializado":false,"Testando":false,"Funcoes":[25],"Parametros":[],"UnidadeMedida":"mL/s","LimiteMaximo":0.0,"LimiteMinimo":0.0},{"LogGrafico":[],"ID":"MASRS","Prioridade":3,"Descricao":"Massa do reservatório de herbicida","Componente":532,"Aferir":true,"DelayAmostragem":1000,"Leitura":null,"Inicializado":false,"Testando":false,"Funcoes":[22,23],"Parametros":[],"UnidadeMedida":"Kg","LimiteMaximo":50.0,"LimiteMinimo":5.0},{"LogGrafico":[],"ID":"PRSLN","Prioridade":3,"Descricao":"Pressão na linha principal","Componente":333,"Aferir":true,"DelayAmostragem":1000,"Leitura":null,"Inicializado":false,"Testando":false,"Funcoes":[24],"Parametros":[["Vmin","000.00"],["Vmax","004.50"],["Pmax","174.04"]],"UnidadeMedida":"psi","LimiteMaximo":120.0,"LimiteMinimo":60.0}],"BombaPressurizadora":{"ID":"BOMBA","ComandoAtuar":false,"Componente":325,"LeituraEstado":false,"Comandar":true,"Testando":false,"Funcoes":[14,35,36,37,5],"LeituraPotencia":0.0,"LeituraPressaoSP":0.0,"LeituraPressao":0.0,"Leitura":null,"Inicializado":false},"ScriptDeteccaoErvas":"weed_detector_oak-1_0.py","DadosLeitura":{"Momento":"0001-01-01T00:00:00","Conectado":false,"Mod_ID":null,"QualidadeWifi":0,"LatenciaLoop":0,"BicosPulverizadores":[],"BombasPressurizadoras":[],"SensoresFluxo":[],"SensoresMassa":[],"SensoresPressao":[]},"_MassaRef":0.8,"_MassaLeituraRef":40876.37,"_MassaLeituraExtra":1895800.0,"MassaReservatorio":0.0,"VolumeReservatorio":0.0,"PercentualReservatorio":0.0,"VolumeVazaoAferido":0.0,"_FluxoMlRef":102.0,"_FluxoPulsoRef":80.0,"VazaoFluxoMLpSInstantanea":0.0,"VazaoFluxoMLpSMedia":0.0,"VolumeVazaoML":0.0,"InicioAtuacao":"0001-01-01T00:00:00","TempoAtuado":0.0,"_PressaoVmin":0.0,"_PressaoVmax":4.5,"_PressaoMax":174.045,"PressaoLinha":0.0,"PressaoLinhaCalc":0.0,"PercentualErvasTerreno":0.0}

View File

@ -1 +1 @@
{"tmrRegistrador":{"_uiControl":null,"State":2,"IsRunning":false,"IsStopped":true,"IsCreated":false,"Interval":500,"StackTrace":"AtuadorModel.IniciarRegistrador","Id":"tmrRegistrador_Atu","TimeTick":"00:00:00"},"Modulo_ID":"Atu","IP":"192.168.100.13","RequisitarDados":true,"Conectado":false,"QuantidadeBicos":4,"DensidadeHerbicida":1.05,"BicosPulverizadores":[{"ID":"B01","Posicao":1,"Componente":422,"AtuacaoNivelAlto":true,"ComandoAtuar":false,"Comandar":true,"Testando":false,"Funcoes":[21],"LeituraStatusBico":false,"MediaNivelFluxo":0.0,"Leitura":null,"Inicializado":false,"Atuacoes":0,"InicioAtuacao":"0001-01-01T00:00:00","TempoAtuado":0.0},{"ID":"B02","Posicao":2,"Componente":422,"AtuacaoNivelAlto":true,"ComandoAtuar":false,"Comandar":true,"Testando":false,"Funcoes":[21],"LeituraStatusBico":false,"MediaNivelFluxo":0.0,"Leitura":null,"Inicializado":false,"Atuacoes":0,"InicioAtuacao":"0001-01-01T00:00:00","TempoAtuado":0.0},{"ID":"B03","Posicao":3,"Componente":422,"AtuacaoNivelAlto":true,"ComandoAtuar":false,"Comandar":true,"Testando":false,"Funcoes":[21],"LeituraStatusBico":false,"MediaNivelFluxo":0.0,"Leitura":null,"Inicializado":false,"Atuacoes":0,"InicioAtuacao":"0001-01-01T00:00:00","TempoAtuado":0.0},{"ID":"B04","Posicao":4,"Componente":422,"AtuacaoNivelAlto":true,"ComandoAtuar":false,"Comandar":true,"Testando":false,"Funcoes":[21],"LeituraStatusBico":false,"MediaNivelFluxo":0.02674584437758935,"Leitura":null,"Inicializado":false,"Atuacoes":0,"InicioAtuacao":"0001-01-01T00:00:00","TempoAtuado":0.0}],"BombasPressurizadoras":[{"ID":"BOMBA","ComandoAtuar":false,"Componente":325,"LeituraEstado":false,"Comandar":true,"Testando":false,"Funcoes":[14,35,36,37,5],"LeituraPotencia":0.0,"LeituraPressaoSP":0.0,"LeituraPressao":0.0,"Leitura":null,"Inicializado":false}],"Sensores":[{"LogGrafico":[],"ID":"FLXLN","Prioridade":23,"Descricao":"Fluxo na linha principal","Componente":198,"Aferir":true,"DelayAmostragem":300,"Leitura":null,"Inicializado":false,"Testando":false,"Funcoes":[25],"Parametros":[],"UnidadeMedida":"mL/s","LimiteMaximo":0.0,"LimiteMinimo":0.0},{"LogGrafico":[],"ID":"MASRS","Prioridade":3,"Descricao":"Massa do reservatório de herbicida","Componente":532,"Aferir":true,"DelayAmostragem":1000,"Leitura":null,"Inicializado":false,"Testando":false,"Funcoes":[22,23],"Parametros":[],"UnidadeMedida":"Kg","LimiteMaximo":50.0,"LimiteMinimo":5.0},{"LogGrafico":[],"ID":"PRSLN","Prioridade":3,"Descricao":"Pressão na linha principal","Componente":333,"Aferir":true,"DelayAmostragem":1000,"Leitura":null,"Inicializado":false,"Testando":false,"Funcoes":[24],"Parametros":[["Vmin","000.00"],["Vmax","004.50"],["Pmax","174.04"]],"UnidadeMedida":"psi","LimiteMaximo":120.0,"LimiteMinimo":60.0}],"BombaPressurizadora":{"ID":"BOMBA","ComandoAtuar":false,"Componente":325,"LeituraEstado":false,"Comandar":true,"Testando":false,"Funcoes":[14,35,36,37,5],"LeituraPotencia":0.0,"LeituraPressaoSP":0.0,"LeituraPressao":0.0,"Leitura":null,"Inicializado":false},"ScriptDeteccaoErvas":"weed_detector_oak-1_0.py","DadosLeitura":{"Momento":"0001-01-01T00:00:00","Conectado":false,"Mod_ID":null,"QualidadeWifi":0,"LatenciaLoop":0,"BicosPulverizadores":[],"BombasPressurizadoras":[],"SensoresFluxo":[],"SensoresMassa":[],"SensoresPressao":[]},"_MassaRef":0.8,"_MassaLeituraRef":40876.37,"_MassaLeituraExtra":1895800.0,"MassaReservatorio":0.0,"VolumeReservatorio":0.0,"PercentualReservatorio":0.0,"VolumeVazaoAferido":0.0,"_FluxoMlRef":102.0,"_FluxoPulsoRef":80.0,"VazaoFluxoMLpSInstantanea":0.0,"VazaoFluxoMLpSMedia":0.0,"VolumeVazaoML":0.0,"InicioAtuacao":"0001-01-01T00:00:00","TempoAtuado":0.0,"_PressaoVmin":0.0,"_PressaoVmax":4.5,"_PressaoMax":174.045,"PressaoLinha":0.0,"PressaoLinhaCalc":0.0,"PercentualErvasTerreno":0.0}
{"tmrRegistrador":{"_uiControl":null,"State":2,"IsRunning":false,"IsStopped":true,"IsCreated":false,"Interval":1000,"StackTrace":"AtuadorModel.IniciarRegistrador","Id":"tmrRegistrador_Atu","TimeTick":"00:00:00"},"_AtuHandler":{},"Dispositivo":103,"Modulo_ID":"Atu","_EnderecoCAN":18,"_TaxaAmostragem":1000,"RequisitarDados":true,"Conectado":false,"QuantidadeBicos":4,"DensidadeHerbicida":1.1,"BicosPulverizadores":[{"ID":"B01","ID_Num":71,"Posicao":1,"Componente":11,"AtuacaoNivelAlto":true,"ComandoAtuar":false,"Comandar":true,"Testando":false,"Funcoes":[21],"LeituraStatusBico":false,"MediaNivelFluxo":0.0,"Leitura":null,"Inicializado":false,"Atuacoes":0,"InicioAtuacao":"0001-01-01T00:00:00","TempoAtuado":0.0},{"ID":"B02","ID_Num":72,"Posicao":2,"Componente":11,"AtuacaoNivelAlto":true,"ComandoAtuar":false,"Comandar":true,"Testando":false,"Funcoes":[21],"LeituraStatusBico":false,"MediaNivelFluxo":0.0,"Leitura":null,"Inicializado":false,"Atuacoes":0,"InicioAtuacao":"0001-01-01T00:00:00","TempoAtuado":0.0},{"ID":"B03","ID_Num":73,"Posicao":3,"Componente":11,"AtuacaoNivelAlto":true,"ComandoAtuar":false,"Comandar":true,"Testando":false,"Funcoes":[21],"LeituraStatusBico":false,"MediaNivelFluxo":0.0,"Leitura":null,"Inicializado":false,"Atuacoes":0,"InicioAtuacao":"0001-01-01T00:00:00","TempoAtuado":0.0},{"ID":"B04","ID_Num":74,"Posicao":4,"Componente":11,"AtuacaoNivelAlto":true,"ComandoAtuar":false,"Comandar":true,"Testando":false,"Funcoes":[21],"LeituraStatusBico":false,"MediaNivelFluxo":0.0,"Leitura":null,"Inicializado":false,"Atuacoes":0,"InicioAtuacao":"0001-01-01T00:00:00","TempoAtuado":0.0}],"BombasPressurizadoras":[{"ID":"BOMBA","ID_Num":51,"ComandoAtuar":false,"Componente":14,"LeituraEstado":false,"Comandar":true,"Testando":false,"Funcoes":[14,35,36,37,5],"LeituraPotencia":0.0,"LeituraPressaoSP":0.0,"LeituraPressao":0.0,"Leitura":null,"Inicializado":false}],"Sensores":[{"LogGrafico":[],"ID":"FLXLN","ID_Num":61,"Descricao":"Fluxo na linha principal","Componente":8,"Aferir":true,"Leitura":null,"Inicializado":false,"Funcoes":[25],"Parametros":[],"UnidadeMedida":"mL/s","LimiteMaximo":0.0,"LimiteMinimo":0.0},{"LogGrafico":[],"ID":"MASRS","ID_Num":62,"Descricao":"Massa do reservatório de herbicida","Componente":10,"Aferir":true,"Leitura":null,"Inicializado":false,"Funcoes":[22,23],"Parametros":[],"UnidadeMedida":"Kg","LimiteMaximo":0.0,"LimiteMinimo":0.0},{"LogGrafico":[],"ID":"PRSLN","ID_Num":63,"Descricao":"Pressão na linha principal","Componente":12,"Aferir":true,"Leitura":null,"Inicializado":false,"Funcoes":[24],"Parametros":[{"Descricao":"Vmin","Valor":"0","QtdBytes":1,"Escalar":false,"Enviar":true},{"Descricao":"Vmax","Valor":"4.5","QtdBytes":1,"Escalar":true,"Enviar":true},{"Descricao":"Pmax","Valor":"174","QtdBytes":1,"Escalar":false,"Enviar":true}],"UnidadeMedida":"psi","LimiteMaximo":0.0,"LimiteMinimo":0.0}],"BombaPressurizadora":{"ID":"BOMBA","ID_Num":51,"ComandoAtuar":false,"Componente":14,"LeituraEstado":false,"Comandar":true,"Testando":false,"Funcoes":[14,35,36,37,5],"LeituraPotencia":0.0,"LeituraPressaoSP":0.0,"LeituraPressao":0.0,"Leitura":null,"Inicializado":false},"ScriptDeteccaoErvas":"weed_detector_oak-1_0.py","DadosLeitura":{"Momento":"0001-01-01T00:00:00","Conectado":false,"Dispositivo":0,"Versao":0,"Mod_ID":null,"QualidadeWifi":0,"LatenciaLoop":0,"BicosPulverizadores":[],"BombasPressurizadoras":[],"SensoresFluxo":[],"SensoresMassa":[],"SensoresPressao":[],"UltimoComandoRespondido":"0001-01-01T00:00:00"},"_MassaRef":0.8,"_MassaLeituraRef":40876.37,"_MassaLeituraExtra":1895800.0,"MassaReservatorio":0.0,"VolumeReservatorio":0.0,"PercentualReservatorio":0.0,"VolumeVazaoAferido":0.0,"_FluxoMlRef":600.0,"_FluxoPulsoRef":538.0,"VazaoFluxoMLpSInstantanea":0.0,"VazaoFluxoMLpSMedia":0.0,"VolumeVazaoML":0.0,"InicioAtuacao":"0001-01-01T00:00:00","TempoAtuado":0.0,"_PressaoVmin":0.0,"_PressaoVmax":4.5,"_PressaoMax":174.045,"PressaoLinha":0.0,"PressaoLinhaCalc":0.0,"PercentualErvasTerreno":0.0}

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

@ -1 +1 @@
{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"Id":"1","Name":"03_04_2025_10_58_00","Length":0.0,"Dist1":0.0,"Dist2":0.0},"geometry":{"id":null,"type":"LineString","coordinates":[[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0]]}}]}
{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"Id":"1","Name":"CidadeJardimTerreno2","Length":14.558011415731592,"Dist1":14.558011415731592,"Dist2":0.0},"geometry":{"id":"0","type":"LineString","coordinates":[[-47.395205344,-22.172559531333334],[-47.395212610166666,-22.172614638833334],[-47.395219157,-22.172656417833334],[-47.395223544833335,-22.1726892105],[-47.395224140984432,-22.172693691611649],[-47.395225326538004,-22.172702654611555]]}},{"type":"Feature","properties":{"Id":"2","Name":"CidadeJardimTerreno2","Length":14.771318274761821,"Dist1":14.558011415731592,"Dist2":0.0},"geometry":{"id":"1","type":"LineString","coordinates":[[-47.395210902333332,-22.172708800833334],[-47.395206943666665,-22.172679811],[-47.395202420666664,-22.1726491015],[-47.395198865666664,-22.172615782833333],[-47.395193255833334,-22.172577132833332],[-47.395192610024395,-22.172572657695412],[-47.395191325698136,-22.172563706509337]]}},{"type":"Feature","properties":{"Id":"3","Name":"CidadeJardimTerreno2","Length":14.827915524386164,"Dist1":14.558011415731592,"Dist2":0.0},"geometry":{"id":"2","type":"LineString","coordinates":[[-47.3951762925,-22.172561603],[-47.395180824166665,-22.172591686166665],[-47.395185745333336,-22.172623080166666],[-47.395190433,-22.172656367166667],[-47.395195199,-22.172693641833334],[-47.395195769044363,-22.172698125891035],[-47.395196902671593,-22.172707094716973]]}},{"type":"Feature","properties":{"Id":"4","Name":"CidadeJardimTerreno2","Length":14.785159385903514,"Dist1":14.558011415731592,"Dist2":0.0},"geometry":{"id":"3","type":"LineString","coordinates":[[-47.395182932166669,-22.1727127985],[-47.39517819266667,-22.172680514833335],[-47.3951732595,-22.172646752833334],[-47.395168805166669,-22.1726149155],[-47.395163812333337,-22.172581167166665],[-47.395163154299318,-22.172576693573966],[-47.395161845655842,-22.172567745443878]]}},{"type":"Feature","properties":{"Id":"5","Name":"CidadeJardimTerreno2","Length":14.80117692191233,"Dist1":14.558011415731592,"Dist2":0.0},"geometry":{"id":"4","type":"LineString","coordinates":[[-47.395147317833334,-22.172566031],[-47.395151503166666,-22.172595452333333],[-47.3951561855,-22.172628011166665],[-47.395161598666668,-22.172663757333332],[-47.395166727166668,-22.172697770833334],[-47.395167397572706,-22.172702242832194],[-47.39516873082615,-22.172711187810091]]}}]}

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_d9a6f3bd9607a246d24a7e01ec3b2d9a {
#map_63de7e88b4e21b03e29d47e821dcbdd6 {
position: relative;
width: 100.0%;
height: 100.0%;
@ -39,14 +39,14 @@
<body>
<div class="folium-map" id="map_d9a6f3bd9607a246d24a7e01ec3b2d9a" ></div>
<div class="folium-map" id="map_63de7e88b4e21b03e29d47e821dcbdd6" ></div>
</body>
<script>
var map_d9a6f3bd9607a246d24a7e01ec3b2d9a = L.map(
"map_d9a6f3bd9607a246d24a7e01ec3b2d9a",
var map_63de7e88b4e21b03e29d47e821dcbdd6 = L.map(
"map_63de7e88b4e21b03e29d47e821dcbdd6",
{
center: [0.0, 0.0],
crs: L.CRS.EPSG3857,
@ -60,13 +60,13 @@
var tile_layer_ba507403276b817c230164897b95edfc = L.tileLayer(
var tile_layer_9961a3b33a81e9b26bba34e095616283 = 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_ba507403276b817c230164897b95edfc.addTo(map_d9a6f3bd9607a246d24a7e01ec3b2d9a);
tile_layer_9961a3b33a81e9b26bba34e095616283.addTo(map_63de7e88b4e21b03e29d47e821dcbdd6);
</script>
@ -87,7 +87,7 @@
}
trajeto_json_add({"features": []});
trajeto_json.addTo(map_d9a6f3bd9607a246d24a7e01ec3b2d9a);
trajeto_json.addTo(map_63de7e88b4e21b03e29d47e821dcbdd6);
function adicionarGeometria(novaGeometria) {
trajeto_json.addData(novaGeometria);
@ -145,7 +145,7 @@
var marcadorDinamico = L.marker([0, 0], {
icon: customIcon
}).addTo(map_d9a6f3bd9607a246d24a7e01ec3b2d9a);
}).addTo(map_63de7e88b4e21b03e29d47e821dcbdd6);
// Conectar ao broker MQTT
const client = mqtt.connect('ws://localhost:9001'); // Use wss para conexão segura
@ -183,7 +183,7 @@
marcadorDinamico.setRotationAngle(angulo);
adicionarCoordenada("Tj", [novaLongitude, novaLatitude]);
map_d9a6f3bd9607a246d24a7e01ec3b2d9a.setView(novaPosicao, map_d9a6f3bd9607a246d24a7e01ec3b2d9a.getZoom());
map_63de7e88b4e21b03e29d47e821dcbdd6.setView(novaPosicao, map_63de7e88b4e21b03e29d47e821dcbdd6.getZoom());
});
function calcularOrientacao(P1latitude, P1longitude, P2latitude, P2longitude) {

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_895975571795f58cc80aa1bfdf54e824 {
#map_5d2c7f135b188d679c1a4d3824a90e8f {
position: relative;
width: 100.0%;
height: 100.0%;
@ -39,16 +39,16 @@
<body>
<div class="folium-map" id="map_895975571795f58cc80aa1bfdf54e824" ></div>
<div class="folium-map" id="map_5d2c7f135b188d679c1a4d3824a90e8f" ></div>
</body>
<script>
var map_895975571795f58cc80aa1bfdf54e824 = L.map(
"map_895975571795f58cc80aa1bfdf54e824",
var map_5d2c7f135b188d679c1a4d3824a90e8f = L.map(
"map_5d2c7f135b188d679c1a4d3824a90e8f",
{
center: [0.0, 0.0],
center: [-22.172636164916668, -47.395186322185666],
crs: L.CRS.EPSG3857,
zoom: 12,
zoomControl: true,
@ -60,13 +60,13 @@
var tile_layer_01645eade339bfe02b20ad4fd3bc3378 = L.tileLayer(
var tile_layer_c3102dc310a5c0966b042ddc1d0446a2 = 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_01645eade339bfe02b20ad4fd3bc3378.addTo(map_895975571795f58cc80aa1bfdf54e824);
tile_layer_c3102dc310a5c0966b042ddc1d0446a2.addTo(map_5d2c7f135b188d679c1a4d3824a90e8f);
@ -82,7 +82,7 @@
}*/
});
}
function geo_json_f0f226a0199059fea21b2eb31e350844_onEachFeature(feature, layer) {
function geo_json_eda399b26bc88766d3547dbe170f8acd_onEachFeature(feature, layer) {
layer.on({
click: function(e) {
@ -118,20 +118,20 @@
}*/
});
};
var geo_json_f0f226a0199059fea21b2eb31e350844 = L.geoJson(null, {
onEachFeature: geo_json_f0f226a0199059fea21b2eb31e350844_onEachFeature,
var geo_json_eda399b26bc88766d3547dbe170f8acd = L.geoJson(null, {
onEachFeature: geo_json_eda399b26bc88766d3547dbe170f8acd_onEachFeature,
});
function geo_json_f0f226a0199059fea21b2eb31e350844_add (data) {
geo_json_f0f226a0199059fea21b2eb31e350844
function geo_json_eda399b26bc88766d3547dbe170f8acd_add (data) {
geo_json_eda399b26bc88766d3547dbe170f8acd
.addData(data);
}
geo_json_f0f226a0199059fea21b2eb31e350844_add({"features": [{"geometry": {"coordinates": [[0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0]], "id": null, "type": "LineString"}, "id": 0, "properties": {"Dist1": 0.0, "Dist2": 0.0, "Id": "1", "Length": 0.0, "Name": "03_04_2025_10_58_00"}, "type": "Feature"}], "type": "FeatureCollection"});
geo_json_eda399b26bc88766d3547dbe170f8acd_add({"features": [{"geometry": {"coordinates": [[-47.395205344, -22.172559531333334], [-47.395212610166666, -22.172614638833334], [-47.395219157, -22.172656417833334], [-47.395223544833335, -22.1726892105], [-47.39522414098443, -22.17269369161165], [-47.395225326538004, -22.172702654611555]], "id": "0", "type": "LineString"}, "id": 0, "properties": {"Dist1": 14.558011415731592, "Dist2": 0.0, "Id": "1", "Length": 14.558011415731592, "Name": "CidadeJardimTerreno2"}, "type": "Feature"}, {"geometry": {"coordinates": [[-47.39521090233333, -22.172708800833334], [-47.395206943666665, -22.172679811], [-47.395202420666664, -22.1726491015], [-47.395198865666664, -22.172615782833333], [-47.395193255833334, -22.172577132833332], [-47.395192610024395, -22.17257265769541], [-47.395191325698136, -22.172563706509337]], "id": "1", "type": "LineString"}, "id": 1, "properties": {"Dist1": 14.558011415731592, "Dist2": 0.0, "Id": "2", "Length": 14.771318274761821, "Name": "CidadeJardimTerreno2"}, "type": "Feature"}, {"geometry": {"coordinates": [[-47.3951762925, -22.172561603], [-47.395180824166665, -22.172591686166665], [-47.395185745333336, -22.172623080166666], [-47.395190433, -22.172656367166667], [-47.395195199, -22.172693641833334], [-47.39519576904436, -22.172698125891035], [-47.39519690267159, -22.172707094716973]], "id": "2", "type": "LineString"}, "id": 2, "properties": {"Dist1": 14.558011415731592, "Dist2": 0.0, "Id": "3", "Length": 14.827915524386164, "Name": "CidadeJardimTerreno2"}, "type": "Feature"}, {"geometry": {"coordinates": [[-47.39518293216667, -22.1727127985], [-47.39517819266667, -22.172680514833335], [-47.3951732595, -22.172646752833334], [-47.39516880516667, -22.1726149155], [-47.39516381233334, -22.172581167166665], [-47.39516315429932, -22.172576693573966], [-47.39516184565584, -22.172567745443878]], "id": "3", "type": "LineString"}, "id": 3, "properties": {"Dist1": 14.558011415731592, "Dist2": 0.0, "Id": "4", "Length": 14.785159385903514, "Name": "CidadeJardimTerreno2"}, "type": "Feature"}, {"geometry": {"coordinates": [[-47.395147317833334, -22.172566031], [-47.395151503166666, -22.172595452333333], [-47.3951561855, -22.172628011166665], [-47.39516159866667, -22.172663757333332], [-47.39516672716667, -22.172697770833334], [-47.395167397572706, -22.172702242832194], [-47.39516873082615, -22.17271118781009]], "id": "4", "type": "LineString"}, "id": 4, "properties": {"Dist1": 14.558011415731592, "Dist2": 0.0, "Id": "5", "Length": 14.80117692191233, "Name": "CidadeJardimTerreno2"}, "type": "Feature"}], "type": "FeatureCollection"});
geo_json_f0f226a0199059fea21b2eb31e350844.addTo(map_895975571795f58cc80aa1bfdf54e824);
geo_json_eda399b26bc88766d3547dbe170f8acd.addTo(map_5d2c7f135b188d679c1a4d3824a90e8f);
</script>
@ -152,7 +152,7 @@
}
trajeto_json_add({"features": []});
trajeto_json.addTo(map_895975571795f58cc80aa1bfdf54e824);
trajeto_json.addTo(map_5d2c7f135b188d679c1a4d3824a90e8f);
function adicionarGeometria(novaGeometria) {
trajeto_json.addData(novaGeometria);
@ -210,7 +210,7 @@
}
trajeto_dinamico_json_add({"features": []});
trajeto_dinamico_json.addTo(map_895975571795f58cc80aa1bfdf54e824);
trajeto_dinamico_json.addTo(map_5d2c7f135b188d679c1a4d3824a90e8f);
function adicionarGeometriaDinamica(novaGeometria) {
trajeto_dinamico_json.addData(novaGeometria);
@ -263,9 +263,9 @@
var marcadorEquipamento = L.marker([0, 0], {
icon: customIcon
}).addTo(map_895975571795f58cc80aa1bfdf54e824);
}).addTo(map_5d2c7f135b188d679c1a4d3824a90e8f);
var marcadorBase = L.marker([0, 0], {}).addTo(map_895975571795f58cc80aa1bfdf54e824);
var marcadorBase = L.marker([0, 0], {}).addTo(map_5d2c7f135b188d679c1a4d3824a90e8f);
var icon = L.AwesomeMarkers.icon(
{"extraClasses": "fa-rotate-0", "icon": "info-sign", "iconColor": "white", "markerColor": "red", "prefix": "glyphicon"}
);
@ -347,7 +347,7 @@
}
if (foco) {
map_895975571795f58cc80aa1bfdf54e824.setView(novaPosicao, map_895975571795f58cc80aa1bfdf54e824.getZoom());
map_5d2c7f135b188d679c1a4d3824a90e8f.setView(novaPosicao, map_5d2c7f135b188d679c1a4d3824a90e8f.getZoom());
}
}
@ -364,7 +364,7 @@
function atualizarSelecaoRuas(selecionadas) {
selecionadas = JSON.parse(selecionadas);
RuasSelecionadas = Array.isArray(selecionadas) ? [...selecionadas] : [];
geo_json_f0f226a0199059fea21b2eb31e350844.eachLayer(function (layer) {
geo_json_eda399b26bc88766d3547dbe170f8acd.eachLayer(function (layer) {
if (RuasSelecionadas.includes(parseInt(layer.feature.id))) {
layer.setStyle({ color: 'blue' });
} else {

View File

@ -1 +1 @@
f39b92273c9c03cda7c582e217d44bdff2f7e8f40e6698f917ed1f00569a75c7
a916f4b7a3b8728703c8d007e50dd3f8c3f77e39a6c79a9f0061bc86cd1cd2f6

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,25 @@
{
"files.associations": {
"vector": "cpp"
"vector": "cpp",
"bit": "cpp",
"compare": "cpp",
"concepts": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"cwchar": "cpp",
"exception": "cpp",
"initializer_list": "cpp",
"limits": "cpp",
"new": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"xmemory": "cpp",
"xstddef": "cpp",
"xtr1common": "cpp",
"xutility": "cpp"
}
}

Binary file not shown.

View File

@ -0,0 +1,202 @@
#include "SerialService.h"
// CanService.h
#ifndef CANSERVICE_H
#define CANSERVICE_H
/*
#include <CAN.h>
#include <Arduino.h>
class CanService {
public:
typedef void (*OnReceiveCallback)(int packetSize, int senderId, byte funcCode, byte* data, int dataLength);
CanService(uint8_t nodeId, uint32_t baudRate = 500E3) {
_baudRate = baudRate;
_nodeId = nodeId;
}
void begin() {
if (!CAN.begin(_baudRate)) {
PrintTela("[CAN] Falha ao iniciar");
return;
}
PrintTela("[CAN] Inicializado com sucesso");
CAN.onReceive(onReceiveWrapper);
instance = this;
}
void loop() {
// Apenas processa mensagens recebidas via interrupcao
}
void setReceiveCallback(OnReceiveCallback cb) {
_callback = cb;
}
bool enviarMensagem(byte funcCode, const std::vector<uint8_t>& payload) {
if (payload.size() > 7) return false;
CAN.beginPacket(_nodeId);
CAN.write(funcCode);
for (uint8_t b : payload) {
CAN.write(b);
}
return CAN.endPacket();
}
std::vector<uint8_t> MontarFrameChk(T_Code D_Code, bool Conectado, int Versao) {
std::vector<uint8_t> resposta;
resposta.push_back(static_cast<uint8_t>(D_Code)); // Tipo do módulo
resposta.push_back(Conectado ? 1 : 0); // Conectado
resposta.push_back(Versao); // Versão
return resposta;
}
private:
uint32_t _baudRate;
uint8_t _nodeId;
OnReceiveCallback _callback = nullptr;
static CanService* instance;
static void onReceiveWrapper(int packetSize) {
if (instance) instance->onReceive(packetSize);
}
void onReceive(int packetSize) {
int senderId = CAN.packetId();
byte buffer[8];
int i = 0;
while (CAN.available() && i < 8) {
buffer[i++] = CAN.read();
}
byte funcCode = buffer[0];
if (_callback != nullptr) {
_callback(packetSize, senderId, funcCode, buffer + 1, i - 1);
}
}
};
CanService* CanService::instance = nullptr;
*/
#include <Arduino.h>
#include <driver/twai.h>
class CanService {
public:
typedef void (*OnReceiveCallback)(int packetSize, int senderId, byte funcCode, byte* data, int dataLength);
CanService(uint8_t nodeId, uint32_t baudRate = 500000) {
_nodeId = nodeId;
_baudRate = baudRate;
}
void begin() {
PrintTela("[CAN] Iniciando TWAI...");
twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(GPIO_NUM_5, GPIO_NUM_4, TWAI_MODE_NORMAL); // modo sem ACK
twai_timing_config_t t_config = TWAI_TIMING_CONFIG_500KBITS();
//twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
twai_filter_config_t f_config = {
.acceptance_code = (_nodeId << 21), // Shiftado para alinhar com o padrão TWAI
.acceptance_mask = ~(0x7FF << 21), // Mascara para filtrar apenas esse ID
.single_filter = true
};
esp_err_t err;
err = twai_driver_install(&g_config, &t_config, &f_config);
if (err != ESP_OK) {
PrintTela("[CAN] Erro ao instalar driver: ", false);
PrintTela(String(err));
return;
}
err = twai_start();
if (err != ESP_OK) {
PrintTela("[CAN] Erro ao iniciar TWAI: ", false);
PrintTela(String(err));
return;
}
PrintTela("[CAN] TWAI iniciado com sucesso");
}
void loop() {
twai_message_t message;
if (twai_receive(&message, pdMS_TO_TICKS(10)) == ESP_OK) {
if (message.data_length_code == 0 || message.extd) return;
byte funcCode = message.data[0];
bool MensagemTx = (int)funcCode % 2 == 0;
Serial.print("[CAN ");
Serial.print(MensagemTx ? "TX" : "RX");
Serial.print("] ID: 0x");
Serial.print(message.identifier, HEX);
Serial.print(" Len: ");
Serial.print(message.data_length_code);
Serial.print(" Data: ");
for (int i = 0; i < message.data_length_code; i++) {
Serial.print(message.data[i], HEX);
Serial.print(" ");
}
Serial.println();
if (MensagemTx) { // funcCodes impares sao enviados pelo esp, ignorar
return;
}
if (_callback != nullptr) {
//PrintTela("Entrar no callback...");
_callback(message.data_length_code, message.identifier, funcCode, &message.data[1], message.data_length_code - 1);
}
}
}
void setReceiveCallback(OnReceiveCallback cb) {
_callback = cb;
}
bool enviarMensagem(byte funcCode, const std::vector<uint8_t>& payload) {
if (payload.size() > 7) return false;
twai_message_t msg;
msg.identifier = _nodeId;
msg.extd = 0;
msg.rtr = 0;
msg.ss = 1;
msg.data_length_code = payload.size() + 1;
msg.data[0] = funcCode;
for (uint8_t i = 0; i < payload.size(); ++i) {
msg.data[i + 1] = payload[i];
}
return twai_transmit(&msg, pdMS_TO_TICKS(10)) == ESP_OK;
}
std::vector<uint8_t> MontarFrameChk(T_Code D_Code, bool Conectado, int Versao) {
std::vector<uint8_t> resposta;
resposta.push_back(static_cast<uint8_t>(D_Code));
resposta.push_back(Conectado ? 1 : 0);
resposta.push_back(Versao);
return resposta;
}
private:
uint8_t _nodeId;
uint32_t _baudRate;
OnReceiveCallback _callback = nullptr;
};
#endif

View File

@ -22,40 +22,49 @@ enum T_Code {
};
enum F_Code {
Nda = 200,
Chk = 244,
Cfg = 258,
Tst = 288,
Cmd = 293,
Err = 404,
Msg = 655,
Req = 887,
Nda = 0,
ChkTx = 1,
ChkRx = 2,
CfgTx = 3,
CfgRx = 4,
TstTx = 5,
TstRx = 6,
CmdTx = 7,
CmdRx = 8,
ErrTx = 9,
ErrRx = 10,
MsgTx = 11,
MsgRx = 12,
ReqTx = 13,
ReqRx = 14,
};
enum S_Code {
sRPM = 133,
sTST = 154,
sCFG = 211,
sTMP = 411,
sENC = 111,
sCOR = 322,
sTEN = 112,
sFLX = 198,
sULT = 531,
sMAS = 532,
sBIC = 422,
sPRS = 333,
sMAG = 855,
sBMB = 325,
sLED = 445,
sSNR = 532,
sBLD = 544,
sCMD = 878,
sMVD = 477,
sATU = 478,
sRLE = 479,
sFRO = 480,
sPOT = 481,
sVZO = 0,
sRPM = 1,
sTST = 2,
sCFG = 3,
sTMP = 4,
sENC = 5,
sCOR = 6,
sTEN = 7,
sFLX = 8,
sULT = 9,
sMAS = 10,
sBIC = 11,
sPRS = 12,
sMAG = 13,
sBMB = 14,
sLED = 15,
sSNR = 16,
sBLD = 17,
sCMD = 18,
sMVD = 19,
sATU = 20,
sRLE = 21,
sFRO = 22,
sPOT = 23,
sMOD = 24,
};
enum Estado {

View File

@ -7,6 +7,7 @@
#ifndef Pinout
#define Pinout
#define PINO_INVALIDO 0xFF
Adafruit_MCP23X17 mcp;
Adafruit_ADS1115 ads;
bool mcpInicializado = false;
@ -19,11 +20,11 @@ class PinoModel {
TiposPinos tipo;
TiposLeituras leitura;
PinoModel(int numero = -1, TiposBarramentos barr = CONTROLADOR, TiposPinos tp = _INPUT, TiposLeituras lt = DIGITAL) : num(numero), barramento(barr), tipo(tp), leitura(lt) {
PinoModel(int numero = PINO_INVALIDO, TiposBarramentos barr = CONTROLADOR, TiposPinos tp = _INPUT, TiposLeituras lt = DIGITAL) : num(numero), barramento(barr), tipo(tp), leitura(lt) {
}
bool Definido() {
return num > -1;
return num != PINO_INVALIDO;
}
void Conectar(bool statusInicial = false) {

View File

@ -17,6 +17,7 @@ class Rele {
String Mod_ID;
String _ID;
int ID_Num;
PinoModel _pino;
bool Iniciado = false;
@ -30,12 +31,18 @@ class Rele {
return;
}
if (_pino.Definido()) {
_pino.Conectar(!AtuacaoNivelAlto);
Iniciado = true;
_pino.Conectar(!AtuacaoNivelAlto);
Iniciado = _pino.Definido();
if (Iniciado) {
PrintTela(_ID + " iniciado");
}
else
{
PrintTela(_ID + " nao iniciado");
}
}
void Desligar() {
@ -53,27 +60,39 @@ class Rele {
}
void AtualizarStatus(Estado novoEstado) {
bool status = novoEstado == Ligado;
if (!AtuacaoNivelAlto) {
status = !status;
}
if (Iniciado) {
bool status = novoEstado == Ligado;
if (!AtuacaoNivelAlto) {
status = !status;
}
PrintTela("Atualizando status do rele de ", false);
PrintTela(String(_Status), false);
PrintTela(" para ", false);
PrintTela(String(novoEstado));
_pino.set(status);
_Status = (Estado)_pino.get();
PrintTela("Atualizando status do rele de ", false);
PrintTela(String(_Status), false);
PrintTela(" para ", false);
PrintTela(String(novoEstado));
_pino.set(status);
_Status = (Estado)_pino.get();
}
}
void AtualizarLeitura() {
_Status = (Estado)_pino.get();
if (Iniciado) {
_Status = (Estado)_pino.get();
}
}
void RequisitarDados() {
AtualizarLeitura();
}
std::vector<uint8_t> MontarMensagemCAN() {
std::vector<uint8_t> data;
data.push_back(ID_Num);
data.push_back(Iniciado ? 1 : 0);
data.push_back(_Status ? 1 : 0);
return data;
}
};
// Função para inicializar os reles com IDs e pinos específicos
@ -106,6 +125,7 @@ void Rele::InicializarLista(std::vector<Rele*>& lista, const String& parametros,
if (conectar) {
Rele* sensor = new Rele(Mod_ID, id);
sensor->ID_Num = lista.size();
sensor->_pino = PinoModel(pino, pinoB, _OUTPUT);
sensor->AtuacaoNivelAlto = atuacaoAlto;
sensor->Inicializar();

View File

@ -22,6 +22,7 @@ class SensorCorrente {
// Definições
String Mod_ID = "";
String _ID;
int ID_Num;
byte _Endereco;
double _A_Shunt;
@ -36,6 +37,7 @@ class SensorCorrente {
PrintTela(_ID + " ja inicializado");
return;
}
PrintTela("Tentando iniciar o sensor de corrente no endereco " + String(_Endereco));
if (_Endereco > 0x00) {
Wire.beginTransmission(_Endereco);
byte error = Wire.endTransmission();
@ -52,6 +54,10 @@ class SensorCorrente {
else if (_A_Shunt == 100) {
sINA219.setCalibration_100A_75mV();
}
PrintTela(_ID + " iniciado");
}
else {
PrintTela(_ID + " nao iniciado!");
}
}
else {
@ -59,8 +65,9 @@ class SensorCorrente {
PrintTela(_ID + " nao iniciado, endereco " + _Endereco + " nao encontrado!");
}
}
PrintTela(_ID + " iniciado");
else {
PrintTela("Endereco incorreto!");
}
}
void Desligar() {
@ -75,16 +82,42 @@ class SensorCorrente {
}
void AferirCorrente() {
busVoltage = sINA219.getBusVoltage_V();
shuntVoltage = sINA219.getShuntVoltage_mV();
current = sINA219.getCurrent_mA();
power = sINA219.getPower_mW();
if (Iniciado) {
busVoltage = sINA219.getBusVoltage_V();
shuntVoltage = sINA219.getShuntVoltage_mV();
current = sINA219.getCurrent_mA();
power = sINA219.getPower_mW();
}
}
void RequisitarDados() {
AferirCorrente();
}
std::vector<uint8_t> MontarMensagemCAN() {
std::vector<uint8_t> data;
data.push_back(ID_Num);
data.push_back(Iniciado ? 1 : 0);
// BusVoltage com 2 bytes, precisão x100
uint16_t busVoltsInt = (uint16_t)(busVoltage * 100);
data.push_back((uint8_t)(busVoltsInt >> 8));
data.push_back((uint8_t)(busVoltsInt & 0xFF));
// Corrente com 2 bytes (em mA)
uint16_t correnteInt = (uint16_t)(current);
data.push_back((uint8_t)(correnteInt >> 8));
data.push_back((uint8_t)(correnteInt & 0xFF));
// Potência com 2 bytes
/*uint16_t potenciaInt = (uint16_t)(power);
data.push_back((uint8_t)(potenciaInt >> 8));
data.push_back((uint8_t)(potenciaInt & 0xFF));*/
return data;
}
};
// Função para inicializar os sensores de corrente com IDs e pinos específicos
@ -116,6 +149,7 @@ void SensorCorrente::InicializarLista(std::vector<SensorCorrente*>& lista, const
if (conectar) {
SensorCorrente* sensor = new SensorCorrente(Mod_ID, id);
sensor->ID_Num = lista.size();
sensor->_Endereco = stringToByte(_endereco);
sensor->_A_Shunt = _a_max;
sensor->Inicializar();

View File

@ -20,6 +20,7 @@ class SensorPotenciometro {
// Definições
String Mod_ID = "";
String _ID;
int ID_Num;
PinoModel _pino;
Rele* releControle;
@ -127,6 +128,23 @@ class SensorPotenciometro {
}
}
std::vector<uint8_t> MontarMensagemCAN() {
std::vector<uint8_t> data;
data.push_back(ID_Num);
data.push_back(Iniciado ? 1 : 0);
uint16_t leituraInt = static_cast<uint16_t>(leitura);
data.push_back((uint8_t)(leituraInt >> 8));
data.push_back((uint8_t)(leituraInt & 0xFF));
uint8_t anguloByte = static_cast<uint8_t>(angulo);
data.push_back(anguloByte);
data.push_back(sentido); // já é uint8_t pelo enum?
data.push_back(limiteExcedido ? 1 : 0);
return data;
}
};
@ -159,6 +177,7 @@ void SensorPotenciometro::InicializarLista(std::vector<SensorPotenciometro*>& li
if (conectar) {
SensorPotenciometro* sensor = new SensorPotenciometro(Mod_ID, id);
sensor->ID_Num = lista.size();
sensor->_pino = PinoModel(pino, pinoB, _INPUT, ANALOGICO);
sensor->releControle = nullptr;

View File

@ -19,9 +19,11 @@ class SensorTemperatura {
// Definições
String Mod_ID = "";
String _ID;
int ID_Num;
PinoModel _pino;
double leitura = 0;
double temperatura = -1;
//SimpleKalmanFilter filtro = SimpleKalmanFilter(5, 15, 0.01);
@ -38,9 +40,14 @@ class SensorTemperatura {
_pino.Conectar(); // Conecta o pino antes de criar a tarefa
Iniciado = true;
Iniciado = _pino.Definido();
PrintTela(_ID + " iniciado");
if (Iniciado) {
PrintTela(_ID + " iniciado");
}
else {
PrintTela(_ID + " nao iniciado");
}
}
void Desligar() {
@ -57,16 +64,55 @@ class SensorTemperatura {
}
void AferirTemperatura() {
leitura = _pino.get(5);
//leitura = filtro.updateEstimate(leitura);
if (Iniciado) {
leitura = _pino.get(5);
//leitura = filtro.updateEstimate(leitura);
temperatura = CalcularTemperatura((float)leitura);
}
}
void RequisitarDados() {
AferirTemperatura();
}
std::vector<uint8_t> MontarMensagemCAN() {
std::vector<uint8_t> data;
data.push_back(ID_Num); // Byte 0 - ID do sensor
data.push_back(Iniciado ? 1 : 0); // Byte 1 - Status
int16_t leituraInt = static_cast<int16_t>(round(temperatura * 100.0f)); // duas casas, com sinal
data.push_back((uint8_t)(leituraInt >> 8)); // Byte 2 - parte alta
data.push_back((uint8_t)(leituraInt & 0xFF)); // Byte 3 - parte baixa
return data;
}
private:
float CalcularTemperatura(float leitura, float offset = 0.0f) {
const float Vs = 5.0; // Tensão de referência (divisor)
const float Beta = 3950.0; // Coeficiente Beta do NTC
const float To = 298.15; // 25°C em Kelvin
const float Ro = 10000.0; // NTC 10k
const float adcMax = 4095.0; // ADC de 12 bits
if (leitura < 200) return -1.0; // ignora valores muito baixos (desconectado?)
float Vout = leitura * Vs / adcMax;
if (Vout <= 0.001) return -100.0; // proteção para log(0)
if (Vout >= Vs) return NAN;
float Rt = Ro * (Vout / (Vs - Vout)); // NTC em cima
// float Rt = Ro * ((Vs - Vout) / Vout); // NTC embaixo, se for o caso
float T = 1.0 / (1.0 / To + log(Rt / Ro) / Beta);
float Tc = T - 273.15 + offset;
return roundf(Tc * 100.0f) / 100.0f; // arredonda para 2 casas
}
};
// Função para inicializar os sensores de temperatura com IDs e pinos específicos
@ -98,6 +144,7 @@ void SensorTemperatura::InicializarLista(std::vector<SensorTemperatura*>& lista,
if (conectar) {
SensorTemperatura* sensor = new SensorTemperatura(Mod_ID, id);
sensor->ID_Num = lista.size();
sensor->_pino = PinoModel(pino, pinoB, _INPUT, ANALOGICO);
sensor->Inicializar();
lista.push_back(sensor);

View File

@ -76,6 +76,9 @@ std::vector<ProtocoloSerial> LerBufferSerialFila(String Mod_ID) {
}
void PrintTela(String msg, bool ln = true) {
if (!Serial) {
Serial.begin(115200);
}
if (Serial && DebugMode) {
if (ln) {
Serial.println(msg);
@ -96,7 +99,7 @@ void EnviarDadosSerial(String Mod_ID, String Mensagem) {
String MontarProtocoloMensagemRecebida(int idMensagem) {
String protocolo =
(String)Msg + SplitMessage +
(String)MsgRx + SplitMessage +
(String)idMensagem + SplitMessage +
EndLine;
return protocolo;
@ -104,7 +107,7 @@ String MontarProtocoloMensagemRecebida(int idMensagem) {
String MontarProtocoloVerificacao(T_Code D_Code, int versao, bool conectado) {
String Protocolo =
(String)Chk + SplitMessage +
(String)ChkRx + SplitMessage +
(String)D_Code + SplitMessage +
(String)versao + SplitMessage +
(conectado ? "1" : "0") + SplitMessage +
@ -115,7 +118,7 @@ String MontarProtocoloVerificacao(T_Code D_Code, int versao, bool conectado) {
String MontarProtocoloErro(T_Code D_Code) {
String Protocolo =
(String)D_Code + SplitMessage +
(String)Err + SplitMessage +
(String)ErrRx + SplitMessage +
EndLine;
return Protocolo;
}

View File

@ -18,6 +18,7 @@ class ServoFreio {
String Mod_ID;
String _ID;
int ID_Num;
PinoModel _pino;
bool Incremental = true;
@ -42,6 +43,9 @@ class ServoFreio {
PrintTela(_ID + " iniciado");
}
else {
PrintTela(_ID + " nao iniciado");
}
}
void Desligar() {
@ -61,15 +65,25 @@ class ServoFreio {
}
void AtualizarAngulo(int novoAngulo) {
_Angulo = novoAngulo;
if (Iniciado) {
_Angulo = novoAngulo;
_Servo.write(_Angulo);
_Servo.write(_Angulo);
}
}
void RequisitarDados() {
}
std::vector<uint8_t> MontarMensagemCAN() {
std::vector<uint8_t> data;
data.push_back(ID_Num);
data.push_back(Iniciado ? 1 : 0);
data.push_back((uint8_t)(_Angulo & 0xFF)); // 0 a 180
return data;
}
};
@ -103,6 +117,7 @@ void ServoFreio::InicializarLista(std::vector<ServoFreio*>& lista, const String&
if (conectar) {
ServoFreio* sensor = new ServoFreio(Mod_ID, id);
sensor->ID_Num = lista.size();
sensor->Incremental = inc;
sensor->_pino = PinoModel(pino, pinoB, _OUTPUT);
sensor->Inicializar();

View File

@ -17,6 +17,7 @@ class Sinaleiro {
String Mod_ID;
String _ID;
int ID_Num;
PinoModel _pino;
bool Iniciado = false;
@ -34,11 +35,16 @@ class Sinaleiro {
_pino.Conectar(false);
xTaskCreatePinnedToCore(&Sinaleiro::LEDTaskWrapper, "LEDTask", 5000, this, 6, &LEDTaskHandle, tskNO_AFFINITY);
Iniciado = _pino.Definido();
PrintTela(_ID + " Iniciado");
Iniciado = true;
if (Iniciado) {
xTaskCreatePinnedToCore(&Sinaleiro::LEDTaskWrapper, "LEDTask", 5000, this, 6, &LEDTaskHandle, tskNO_AFFINITY);
PrintTela(_ID + " Iniciado");
}
else {
PrintTela(_ID + " nao Iniciado");
}
}
void Desligar() {
@ -59,13 +65,24 @@ class Sinaleiro {
}
void AtualizarLeitura() {
_StatusLeitura = (StatusLED)_pino.get();
if (Iniciado) {
_StatusLeitura = (StatusLED)_pino.get();
}
}
void RequisitarDados() {
AtualizarLeitura();
}
std::vector<uint8_t> MontarMensagemCAN() {
std::vector<uint8_t> data;
data.push_back(ID_Num);
data.push_back(Iniciado ? 1 : 0);
data.push_back(_StatusLeitura ? 1 : 0);
data.push_back(_Status ? 1 : 0);
return data;
}
private:
TaskHandle_t LEDTaskHandle = NULL;
static void LEDTaskWrapper(void *pvParameters) {
@ -84,7 +101,7 @@ class Sinaleiro {
if (_Status != Piscando) {
_pino.set(_Status == Aceso);
_StatusLeitura = (StatusLED)_pino.get();
//_StatusLeitura = (StatusLED)_pino.get();
}
else if (_Status == Piscando && piscadasAtual < _Qtd) {
if (!emPausa && (currentMillis - lastMillis >= _TempoMs)) {
@ -145,6 +162,7 @@ void Sinaleiro::InicializarLista(std::vector<Sinaleiro*>& lista, const String& p
if (conectar) {
Sinaleiro* sensor = new Sinaleiro(Mod_ID, id);
sensor->ID_Num = lista.size();
sensor->_pino = PinoModel(pino, pinoB, _OUTPUT);
sensor->Inicializar();
lista.push_back(sensor);

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,435 @@
// Dispositivo: Sensoriamento
// Versão Firmware: 16
// Ultima atualização: 07/04/2025
// Atualização: Implementado comunicacao CAN
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SerialService.h"
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\CanService.h"
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\EepromService.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\SensorTemperaturaModel.h"
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SensorCorrenteModel.h"
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SinaleiroModel.h"
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\ReleModel.h"
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\ServoFreioModel.h"
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SensorPotenciometroModel.h"
// Configurações do CAN
uint8_t CanID = 0x11;
CanService canService = CanService(CanID);
#define D_Code Sen
int VERSION = 16;
String Mod_ID = "Sen";
#define _pinoLED RGB_BUILTIN
bool Conectado = false;
bool Verificando = false;
int _TaxaAmostragem = 1000;
volatile bool RequisitarDados = false;
int latenciaLoop = 0;
//PinoModel _pinoSDA = PinoModel(21, CONTROLADOR, _INPUT);
PinoModel _pinoSDA = PinoModel(1, CONTROLADOR, _INPUT);
//PinoModel _pinoSCL = PinoModel(22, CONTROLADOR, _INPUT);
PinoModel _pinoSCL = PinoModel(2, CONTROLADOR, _INPUT);
std::vector<SensorTemperatura*> listaSensoresTemperatura;
std::vector<SensorCorrente*> listaSensoresCorrente;
std::vector<Sinaleiro*> listaSinaleiros;
std::vector<Rele*> listaReles;
std::vector<ServoFreio*> listaServoFreios;
std::vector<SensorPotenciometro*> listaSensoresPotenciometros;
void setup() {
delay(5000);
iniciarMCP(D_Code, Mod_ID, _pinoSDA.num, _pinoSCL.num, 0x20, false);
iniciarADS(D_Code, Mod_ID, _pinoSDA.num, _pinoSCL.num, 0x48, false);
// Registrar callback para processar mensagens CAN recebidas
canService.setReceiveCallback([](int packetSize, int senderId, byte funcCode, byte* data, int dataLength) {
std::vector<uint8_t> fullData;
fullData.push_back(funcCode); // Primeiro byte é sempre o funcCode
for (int i = 0; i < dataLength; i++) {
fullData.push_back(data[i]);
}
ProcessarFrameCAN(fullData);
});
canService.begin();
}
void loop() {
unsigned long startLoop = millis();
if (!RequisitarDados) {
enviarLogsPeriodicamente();
}
canService.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...");
for (auto* sensor : listaSensoresTemperatura) {
if (sensor != nullptr) {
sensor->RequisitarDados();
EnviarDadosCAN(static_cast<uint8_t>(S_Code::sTMP), sensor->MontarMensagemCAN());
}
else {
PrintTela("Sensor sTMP invalido");
}
}
for (auto* sensor : listaSensoresCorrente) {
if (sensor != nullptr) {
sensor->RequisitarDados();
EnviarDadosCAN(static_cast<uint8_t>(S_Code::sCOR), sensor->MontarMensagemCAN());
}
else {
PrintTela("Sensor sCOR invalido");
}
}
for (auto* sensor : listaSinaleiros) {
if (sensor != nullptr) {
sensor->RequisitarDados();
EnviarDadosCAN(static_cast<uint8_t>(S_Code::sLED), sensor->MontarMensagemCAN());
}
else {
PrintTela("Sensor sLED invalido");
}
}
for (auto* sensor : listaReles) {
if (sensor != nullptr) {
sensor->RequisitarDados();
EnviarDadosCAN(static_cast<uint8_t>(S_Code::sRLE), sensor->MontarMensagemCAN());
}
else {
PrintTela("Sensor sRLE invalido");
}
}
for (auto* sensor : listaServoFreios) {
if (sensor != nullptr) {
sensor->RequisitarDados();
EnviarDadosCAN(static_cast<uint8_t>(S_Code::sFRO), sensor->MontarMensagemCAN());
}
else {
PrintTela("Sensor sFRO invalido");
}
}
for (auto* sensor : listaSensoresPotenciometros) {
if (sensor != nullptr) {
sensor->AferirAngulo();
EnviarDadosCAN(static_cast<uint8_t>(S_Code::sPOT), sensor->MontarMensagemCAN());
}
else {
PrintTela("Sensor sPOT invalido");
}
}
}
}
void EnviarDadosCAN(uint8_t f_code, std::vector<uint8_t> data) {
canService.enviarMensagem(f_code, data);
}
void ProcessarFrameCAN(std::vector<uint8_t> data) {
if (data.size() < 1) return;
F_Code funcao = (F_Code)data[0];
switch (funcao) {
case ChkTx: ProcessarChk(); break;
case ReqTx: ProcessarReq(); break;
case CmdTx: ProcessarCmd(data); break;
case CfgTx: ProcessarCfg(data); break;
}
}
void ProcessarChk() {
Verificando = true;
std::vector<uint8_t> data = canService.MontarFrameChk(D_Code, Conectado, VERSION);
EnviarDadosCAN(static_cast<uint8_t>(F_Code::ChkRx), data);
Verificando = false;
}
void ProcessarReq() {
enviarDadosSensores();
}
void ProcessarCmd(std::vector<uint8_t> data) {
if (data.size() < 3) return;
S_Code componente = (S_Code)data[1];
uint8_t id = data[2];
switch (componente) {
case sLED: {
if (data.size() < 7) return;
for (auto* _led : listaSinaleiros) {
if (_led->ID_Num == id) {
_led->_Status = (StatusLED)data[3];
_led->_Qtd = data[4];
_led->_TempoMs = (uint16_t)data[5] * 10;
_led->_PausaMs = (uint16_t)data[6] * 10;
return;
}
}
break;
}
case sRLE: {
if (data.size() < 4) return;
for (auto* _rele : listaReles) {
if (_rele->ID_Num == id) {
_rele->AtualizarStatus((Estado)data[3]);
return;
}
}
break;
}
case sFRO: {
if (data.size() < 4) return;
for (auto* _freio : listaServoFreios) {
if (_freio->ID_Num == id) {
_freio->AtualizarAngulo(data[3]);
return;
}
}
break;
}
default:
break;
}
}
void ProcessarCfg(std::vector<uint8_t> data) {
S_Code sensorTipo = (S_Code)data[1];
switch (sensorTipo) {
case sMOD: {
if (data.size() < 7) return;
bool conectar = data[2] == 1;
int taxa = data[3] * 10;
bool requisitar = data[4] == 1;
int pinoSDA = data[5];
int pinoSCL = data[6];
if (pinoSDA != PINO_INVALIDO && pinoSCL != PINO_INVALIDO) {
_pinoSDA = PinoModel(pinoSDA, CONTROLADOR, _INPUT);
_pinoSCL = PinoModel(pinoSCL, CONTROLADOR, _INPUT);
Wire.end();
Wire.begin(_pinoSDA.num, _pinoSCL.num);
PrintTela("I2C inicializado nos pinos SDA=" + String(pinoSDA) + " e SCL=" + String(pinoSCL));
}
vTaskDelay(pdMS_TO_TICKS(100));
_TaxaAmostragem = taxa;
RequisitarDados = requisitar;
Verificando = false;
Conectado = conectar;
ProcessarChk();
listaReles.clear();
listaSinaleiros.clear();
listaServoFreios.clear();
listaSensoresCorrente.clear();
listaSensoresTemperatura.clear();
listaSensoresPotenciometros.clear();
PrintTela("Configuracao do modulo concluida");
break;
}
case sTMP: {
if (data.size() < 6) return;
uint8_t idNum = data[2];
bool conectar = data[3] == 1;
TiposBarramentos tipoBarramento = (TiposBarramentos)data[4];
int pino = data[5];
// Verifica se sensor já existe
auto it = std::find_if(listaSensoresTemperatura.begin(), listaSensoresTemperatura.end(),
[idNum](SensorTemperatura* s) { return s->ID_Num == idNum; });
if (conectar) {
if (it == listaSensoresTemperatura.end()) {
SensorTemperatura* sensor = new SensorTemperatura(Mod_ID, "sTMP_" + String(idNum));
sensor->ID_Num = idNum;
sensor->_pino = PinoModel(pino, tipoBarramento, _INPUT, ANALOGICO);
sensor->Inicializar();
listaSensoresTemperatura.push_back(sensor);
PrintTela("Sensor de temperatura adicionado via CAN: sTMP_" + String(idNum));
}
} else {
// Desconectar sensor
if (it != listaSensoresTemperatura.end()) {
SensorTemperatura* sensor = *it;
sensor->Desligar();
delete sensor;
listaSensoresTemperatura.erase(it);
PrintTela("Sensor de temperatura removido via CAN: sTMP_" + String(idNum));
}
}
break;
}
case sCOR: {
if (data.size() < 7) return;
uint8_t idNum = data[2];
bool conectar = data[3] == 1;
uint8_t endereco = data[4];
// _a_max vem como float*100 => uint16_t
uint16_t aMaxInt = ((uint16_t)data[5] << 8) | data[6];
float aMax = aMaxInt / 100.0;
auto it = std::find_if(listaSensoresCorrente.begin(), listaSensoresCorrente.end(),
[idNum](SensorCorrente* s) { return s->ID_Num == idNum; });
if (conectar) {
if (it == listaSensoresCorrente.end()) {
SensorCorrente* sensor = new SensorCorrente(Mod_ID, "sCOR_" + String(idNum));
sensor->ID_Num = idNum;
sensor->_Endereco = endereco;
sensor->_A_Shunt = aMax;
sensor->Inicializar();
listaSensoresCorrente.push_back(sensor);
PrintTela("Sensor de corrente adicionado via CAN: sCOR_" + String(idNum));
}
} else {
if (it != listaSensoresCorrente.end()) {
SensorCorrente* sensor = *it;
sensor->Desligar();
delete sensor;
listaSensoresCorrente.erase(it);
PrintTela("Sensor de corrente removido via CAN: sCOR_" + String(idNum));
}
}
break;
}
case sLED: {
if (data.size() < 6) return;
uint8_t idNum = data[2];
bool conectar = data[3] == 1;
TiposBarramentos tipoBarramento = (TiposBarramentos)data[4];
int pino = data[5];
auto it = std::find_if(listaSinaleiros.begin(), listaSinaleiros.end(),
[idNum](Sinaleiro* s) { return s->ID_Num == idNum; });
if (conectar) {
if (it == listaSinaleiros.end()) {
Sinaleiro* sensor = new Sinaleiro(Mod_ID, "sLED_" + String(idNum));
sensor->ID_Num = idNum;
sensor->_pino = PinoModel(pino, tipoBarramento, _OUTPUT);
sensor->Inicializar();
listaSinaleiros.push_back(sensor);
PrintTela("Sinaleiro adicionado via CAN: sLED_" + String(idNum));
}
} else {
if (it != listaSinaleiros.end()) {
Sinaleiro* sensor = *it;
sensor->Desligar();
delete sensor;
listaSinaleiros.erase(it);
PrintTela("Sinaleiro removido via CAN: sLED_" + String(idNum));
}
}
break;
}
case sRLE: {
if (data.size() < 7) return;
uint8_t idNum = data[2];
bool conectar = data[3] == 1;
bool atuacaoNivelAlto = data[4] == 1;
TiposBarramentos tipoBarramento = (TiposBarramentos)data[5];
int pino = data[6];
auto it = std::find_if(listaReles.begin(), listaReles.end(),
[idNum](Rele* s) { return s->ID_Num == idNum; });
if (conectar) {
if (it == listaReles.end()) {
Rele* sensor = new Rele(Mod_ID, "sRLE_" + String(idNum));
sensor->ID_Num = idNum;
sensor->_pino = PinoModel(pino, tipoBarramento, _OUTPUT);
sensor->AtuacaoNivelAlto = atuacaoNivelAlto;
sensor->Inicializar();
listaReles.push_back(sensor);
PrintTela("Rele adicionado via CAN: sRLE_" + String(idNum));
}
} else {
if (it != listaReles.end()) {
Rele* sensor = *it;
sensor->Desligar();
delete sensor;
listaReles.erase(it);
PrintTela("Rele removido via CAN: sRLE_" + String(idNum));
}
}
break;
}
case sFRO: {
if (data.size() < 7) return;
uint8_t idNum = data[2];
bool conectar = data[3] == 1;
bool incremental = data[4] == 1;
TiposBarramentos tipoBarramento = (TiposBarramentos)data[5];
int pino = data[6];
auto it = std::find_if(listaServoFreios.begin(), listaServoFreios.end(),
[idNum](ServoFreio* s) { return s->ID_Num == idNum; });
if (conectar) {
if (it == listaServoFreios.end()) {
ServoFreio* sensor = new ServoFreio(Mod_ID, "sFRO_" + String(idNum));
sensor->ID_Num = idNum;
sensor->Incremental = incremental;
sensor->_pino = PinoModel(pino, tipoBarramento, _OUTPUT);
sensor->Inicializar();
listaServoFreios.push_back(sensor);
PrintTela("Servo Freio adicionado via CAN: sFRO_" + String(idNum));
}
} else {
if (it != listaServoFreios.end()) {
ServoFreio* sensor = *it;
sensor->Desligar();
delete sensor;
listaServoFreios.erase(it);
PrintTela("Servo Freio removido via CAN: sFRO_" + String(idNum));
}
}
break;
}
}
}

BIN
Mapas/EMPYREO_004.zip Normal file

Binary file not shown.