ajustes de fluxo e insercao do ultrassom
This commit is contained in:
parent
957fc8f30c
commit
3098cbd04b
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -406,6 +406,7 @@
|
|||
<Compile Include="Models\MapasModel.cs" />
|
||||
<Compile Include="Models\MensagemFilaModel.cs" />
|
||||
<Compile Include="Models\MKS057DModel.cs" />
|
||||
<Compile Include="Models\ModbusModel.cs" />
|
||||
<Compile Include="Models\Modules\AtuadorModel.cs" />
|
||||
<Compile Include="Models\Modules\DirecionalModel.cs" />
|
||||
<Compile Include="Models\Modules\DispositivoBaseModel.cs" />
|
||||
|
|
@ -423,6 +424,7 @@
|
|||
<Compile Include="Models\PIDModel.cs" />
|
||||
<Compile Include="Models\PZEMModel.cs" />
|
||||
<Compile Include="Models\SonarModel.cs" />
|
||||
<Compile Include="Models\UltrasonicA05Model.cs" />
|
||||
<Compile Include="Models\Variaveis.cs" />
|
||||
<Compile Include="Models\Visualizador3DModel.cs" />
|
||||
<Compile Include="Models\WT901CModel.cs" />
|
||||
|
|
@ -455,6 +457,7 @@
|
|||
<Compile Include="Services\RS485Service.cs" />
|
||||
<Compile Include="Services\SerialService.cs" />
|
||||
<Compile Include="Services\SocketService.cs" />
|
||||
<Compile Include="Services\UltrasonicA05Service.cs" />
|
||||
<Compile Include="Services\Visualizador3DService.cs" />
|
||||
<Compile Include="Services\WT901CService.cs" />
|
||||
<Content Include="Python\Output\Mont.mtl">
|
||||
|
|
|
|||
|
|
@ -224,8 +224,15 @@ namespace AgroBase.Forms.Sensoriamento
|
|||
else
|
||||
{
|
||||
PZEMService.ModoLeitura = true;
|
||||
var Comando = PZEMService.ComandoGetParametro(PZEMService.Parametros[cmbBateriaParametro.Text]);
|
||||
PZEMService.EnviarComando(ModbusService._PortaModbus, Comando);
|
||||
|
||||
var Comando = new ModbusComandoModel()
|
||||
{
|
||||
Dispositivo = T_Code.Pzm,
|
||||
Endereco = PZEMService.slaveAddress,
|
||||
Comando = PZEMService.ComandoGetParametro(PZEMService.Parametros[cmbBateriaParametro.Text])
|
||||
};
|
||||
ModbusService.AdicionarComandoNaFila(Comando);
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
|
|
@ -244,15 +251,25 @@ namespace AgroBase.Forms.Sensoriamento
|
|||
}
|
||||
else
|
||||
{
|
||||
var Comando = PZEMService.ComandoSetParametro(PZEMService.Parametros[cmbBateriaParametro.Text], Convert.ToInt32(nudBateriaValor.Value));
|
||||
PZEMService.EnviarComando(ModbusService._PortaModbus, Comando);
|
||||
var Comando = new ModbusComandoModel()
|
||||
{
|
||||
Dispositivo = T_Code.Pzm,
|
||||
Endereco = PZEMService.slaveAddress,
|
||||
Comando = PZEMService.ComandoSetParametro(PZEMService.Parametros[cmbBateriaParametro.Text], Convert.ToInt32(nudBateriaValor.Value))
|
||||
};
|
||||
ModbusService.AdicionarComandoNaFila(Comando);
|
||||
}
|
||||
}
|
||||
|
||||
private void btnBateriaCalibrar_Click(object sender, EventArgs e)
|
||||
{
|
||||
var Comando = PZEMService.ComandoCalibragem();
|
||||
PZEMService.EnviarComando(ModbusService._PortaModbus, Comando);
|
||||
var Comando = new ModbusComandoModel()
|
||||
{
|
||||
Dispositivo = T_Code.Pzm,
|
||||
Endereco = PZEMService.slaveAddress,
|
||||
Comando = PZEMService.ComandoCalibragem()
|
||||
};
|
||||
ModbusService.AdicionarComandoNaFila(Comando);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -113,6 +113,9 @@ namespace AgroBase.Forms
|
|||
this.lblEFA_SP = new System.Windows.Forms.Label();
|
||||
this.lblM_EF = new System.Windows.Forms.Label();
|
||||
this.picEF = new System.Windows.Forms.PictureBox();
|
||||
this.lblUL_Pzm = new System.Windows.Forms.Label();
|
||||
this.lblUL_Wit = new System.Windows.Forms.Label();
|
||||
this.lblUL_A05 = new System.Windows.Forms.Label();
|
||||
this.pnlFundo.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.chartET)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.chartDT)).BeginInit();
|
||||
|
|
@ -129,6 +132,9 @@ namespace AgroBase.Forms
|
|||
//
|
||||
this.pnlFundo.AutoScroll = true;
|
||||
this.pnlFundo.BackColor = System.Drawing.Color.White;
|
||||
this.pnlFundo.Controls.Add(this.lblUL_A05);
|
||||
this.pnlFundo.Controls.Add(this.lblUL_Wit);
|
||||
this.pnlFundo.Controls.Add(this.lblUL_Pzm);
|
||||
this.pnlFundo.Controls.Add(this.lblB12V);
|
||||
this.pnlFundo.Controls.Add(this.lblB7V2);
|
||||
this.pnlFundo.Controls.Add(this.lblB5V);
|
||||
|
|
@ -952,6 +958,39 @@ namespace AgroBase.Forms
|
|||
this.picEF.TabIndex = 90;
|
||||
this.picEF.TabStop = false;
|
||||
//
|
||||
// lblUL_Pzm
|
||||
//
|
||||
this.lblUL_Pzm.AutoSize = true;
|
||||
this.lblUL_Pzm.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.lblUL_Pzm.Location = new System.Drawing.Point(656, 731);
|
||||
this.lblUL_Pzm.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.lblUL_Pzm.Name = "lblUL_Pzm";
|
||||
this.lblUL_Pzm.Size = new System.Drawing.Size(126, 12);
|
||||
this.lblUL_Pzm.TabIndex = 178;
|
||||
this.lblUL_Pzm.Text = "Ultima Leitura PZM: 00:00:00";
|
||||
//
|
||||
// lblUL_Wit
|
||||
//
|
||||
this.lblUL_Wit.AutoSize = true;
|
||||
this.lblUL_Wit.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.lblUL_Wit.Location = new System.Drawing.Point(656, 743);
|
||||
this.lblUL_Wit.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.lblUL_Wit.Name = "lblUL_Wit";
|
||||
this.lblUL_Wit.Size = new System.Drawing.Size(122, 12);
|
||||
this.lblUL_Wit.TabIndex = 179;
|
||||
this.lblUL_Wit.Text = "Ultima Leitura WIT: 00:00:00";
|
||||
//
|
||||
// lblUL_A05
|
||||
//
|
||||
this.lblUL_A05.AutoSize = true;
|
||||
this.lblUL_A05.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.lblUL_A05.Location = new System.Drawing.Point(656, 755);
|
||||
this.lblUL_A05.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.lblUL_A05.Name = "lblUL_A05";
|
||||
this.lblUL_A05.Size = new System.Drawing.Size(122, 12);
|
||||
this.lblUL_A05.TabIndex = 180;
|
||||
this.lblUL_A05.Text = "Ultima Leitura A05: 00:00:00";
|
||||
//
|
||||
// frmAcompanhamento
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
|
|
@ -1054,5 +1093,8 @@ namespace AgroBase.Forms
|
|||
public System.Windows.Forms.Label lblB5V;
|
||||
public System.Windows.Forms.Label lblB3V;
|
||||
private System.Windows.Forms.Label lblEFM_Tensao;
|
||||
public System.Windows.Forms.Label lblUL_Wit;
|
||||
public System.Windows.Forms.Label lblUL_Pzm;
|
||||
public System.Windows.Forms.Label lblUL_A05;
|
||||
}
|
||||
}
|
||||
|
|
@ -337,6 +337,9 @@ namespace AgroBase.Forms
|
|||
Texto.Contains("5V") ? lblB5V :
|
||||
Texto.Contains("7V2") ? lblB7V2 :
|
||||
Texto.Contains("12V") ? lblB12V :
|
||||
Texto.Contains("PZM") ? lblUL_Pzm :
|
||||
Texto.Contains("WIT") ? lblUL_Wit :
|
||||
Texto.Contains("A05") ? lblUL_A05 :
|
||||
new Label();
|
||||
if (lbl.InvokeRequired)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ namespace AgroBase.Forms
|
|||
FilaService.Inicializar();
|
||||
BLD300RService.IniciarRotinas();
|
||||
MKS057DService.IniciarRotinas();
|
||||
ModbusService.IniciarRotinas();
|
||||
}
|
||||
|
||||
private void frmInstancial_Shown(object sender, EventArgs e)
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ namespace AgroBase.Models
|
|||
Mks = 111,
|
||||
Cam = 112,
|
||||
Knt = 113,
|
||||
A05 = 114,
|
||||
}
|
||||
|
||||
public enum F_Code
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
using OpenTK.Platform.Windows;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static AgroBase.Models.Enums;
|
||||
|
||||
namespace AgroBase.Models
|
||||
{
|
||||
public class ModbusModel
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class ModbusParametrosModel
|
||||
{
|
||||
public DateTime UltimaRequisicao { get; set; } = DateTime.MaxValue;
|
||||
public string Descricao { get; set; }
|
||||
public string Chave { get; set; }
|
||||
public byte FuncaoGet { get; set; }
|
||||
public byte FuncaoSet { get; set; }
|
||||
public byte Registro { get; set; }
|
||||
public byte N_Registros { get; set; }
|
||||
public bool LeituraLoop { get; set; }
|
||||
public bool LeituraGeral { get; set; }
|
||||
public double Escala { get; set; }
|
||||
public byte[] Valor { get; set; }
|
||||
}
|
||||
|
||||
public class ModbusComandoModel
|
||||
{
|
||||
public DateTime Momento { get; set; } = DateTime.Now;
|
||||
public T_Code Dispositivo { get; set; }
|
||||
public byte Endereco { get; set; }
|
||||
public byte[] Comando { get; set; }
|
||||
public bool Enviado { get; set; } = false;
|
||||
public int TamanhoEsperado { get; set; } = 3;
|
||||
public int TimeoutResposta { get; set; } = 500;
|
||||
public byte[] Resposta { get; set; }
|
||||
public DateTime RespondidoEm { get; set; } = DateTime.MinValue;
|
||||
public bool Verificacao { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AgroBase.Models
|
||||
{
|
||||
public class UltrasonicA05Model
|
||||
{
|
||||
public DateTime Momento { get; set; }
|
||||
public byte Endereco { get; set; }
|
||||
public int U1 { get; set; }
|
||||
public int U2 { get; set; }
|
||||
public int U3 { get; set; }
|
||||
public int U4 { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ namespace AgroBase.Models
|
|||
{
|
||||
public class WT901CModel
|
||||
{
|
||||
public DateTime Momento { get; set; }
|
||||
public string Versao { get; set; }
|
||||
public DateTime DataHora { get; set; }
|
||||
public double AccX { get; set; }
|
||||
|
|
|
|||
|
|
@ -517,19 +517,25 @@ namespace AgroBase.Services
|
|||
Parametro.Valor = bytes_resposta;
|
||||
|
||||
Parametro.UltimaRequisicao = DateTime.MaxValue;
|
||||
|
||||
ParametroLeitura.Valor = Parametro.Valor;
|
||||
Leitura.UltimoComandoRecebido = DateTime.Now;
|
||||
return true;
|
||||
}
|
||||
else if (Parametros.Any(x => x.FuncaoSet == resposta[1]))
|
||||
{
|
||||
Parametro.Valor = resposta.Skip(4).Take(2).ToArray();
|
||||
|
||||
ParametroLeitura.Valor = Parametro.Valor;
|
||||
Leitura.UltimoComandoRecebido = DateTime.Now;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
RegisrarErrosComunicacao(Addr, $"Resposta inválida ou código de função incorreto. {BitConverter.ToString(resposta)}");
|
||||
}
|
||||
|
||||
ParametroLeitura.Valor = Parametro.Valor;
|
||||
Leitura.UltimoComandoRecebido = DateTime.Now;
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
RegisrarErrosComunicacao(Addr, $"Resposta inválida. {BitConverter.ToString(resposta)}");
|
||||
|
|
|
|||
|
|
@ -1,19 +1,21 @@
|
|||
using AgroBase.Forms;
|
||||
using AgroBase.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Ports;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using static AgroBase.Models.Enums;
|
||||
|
||||
namespace AgroBase.Services
|
||||
{
|
||||
public class ModbusService
|
||||
{
|
||||
public static readonly object _lock = new object();
|
||||
|
||||
public static int TaxaAmostragem { get; set; } = 500;
|
||||
public static bool Verificando { get; set; } = false;
|
||||
public static bool EnvioLiberado { get; set; } = true;
|
||||
public static bool FilaEmEspera { get; set; } = false;
|
||||
|
||||
public static SerialPort _PortaModbus;
|
||||
public static bool Iniciado
|
||||
|
|
@ -39,33 +41,231 @@ namespace AgroBase.Services
|
|||
}
|
||||
}
|
||||
|
||||
public static List<ModbusComandoModel> FilaComandos = new List<ModbusComandoModel>();
|
||||
private static readonly object FilaLock = new object();
|
||||
private static System.Windows.Forms.Timer tmrLoopComandos = new System.Windows.Forms.Timer() { Interval = 100 };
|
||||
|
||||
public static async Task EnviarComando(byte[] Comando)
|
||||
|
||||
public static void IniciarRotinas()
|
||||
{
|
||||
while (!EnvioLiberado || Verificando)
|
||||
Task.Run(() => ReceberDados());
|
||||
if (!tmrLoopComandos.Enabled)
|
||||
{
|
||||
await Task.Delay(FilaEmEspera ? 200 : 100);
|
||||
FilaEmEspera = true;
|
||||
tmrLoopComandos.Tick += TmrLoopComandos_Tick;
|
||||
tmrLoopComandos.Start();
|
||||
}
|
||||
}
|
||||
|
||||
public static void DefinirPortaCOM(SerialPort Porta)
|
||||
{
|
||||
if (!Iniciado)
|
||||
{
|
||||
Porta.Close();
|
||||
}
|
||||
|
||||
FilaEmEspera = false;
|
||||
|
||||
if (frmInstancial.Fechando)
|
||||
if (_PortaModbus == null || !Iniciado)
|
||||
{
|
||||
EnvioLiberado = true;
|
||||
return;
|
||||
lock (_lock)
|
||||
{
|
||||
_PortaModbus = new SerialPort();
|
||||
_PortaModbus.BaudRate = 9600;
|
||||
_PortaModbus.PortName = Porta.PortName;
|
||||
}
|
||||
}
|
||||
|
||||
if (_PortaModbus != null && !_PortaModbus.IsOpen)
|
||||
{
|
||||
_PortaModbus.Open();
|
||||
}
|
||||
}
|
||||
|
||||
public static void LimparDadosPorta()
|
||||
{
|
||||
_PortaModbus.Close();
|
||||
_PortaModbus = null;
|
||||
}
|
||||
|
||||
private static void DescartarDadosBuffer()
|
||||
{
|
||||
_PortaModbus.DiscardInBuffer();
|
||||
_PortaModbus.DiscardOutBuffer();
|
||||
}
|
||||
|
||||
private static async Task<bool> ReceberDados()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
await Task.Delay(TaxaAmostragem);
|
||||
|
||||
if (!Iniciado)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (PZEMService.Iniciado && !PZEMService.ModoLeitura)
|
||||
{
|
||||
AdicionarComandoNaFila(new ModbusComandoModel()
|
||||
{
|
||||
Dispositivo = T_Code.Pzm,
|
||||
Endereco = PZEMService.slaveAddress,
|
||||
Comando = PZEMService.ComandoAquisicaoDados(),
|
||||
Verificacao = false,
|
||||
TamanhoEsperado = 16,
|
||||
TimeoutResposta = 1000,
|
||||
});
|
||||
}
|
||||
if (WT901CService.Iniciado)
|
||||
{
|
||||
AdicionarComandoNaFila(new ModbusComandoModel()
|
||||
{
|
||||
Dispositivo = T_Code.Wit,
|
||||
Endereco = WT901CService.slaveAddress,
|
||||
Comando = WT901CService.ComandoAquisicaoDados(),
|
||||
Verificacao = false,
|
||||
TamanhoEsperado = 101,
|
||||
TimeoutResposta = 1000,
|
||||
});
|
||||
}
|
||||
if (UltrasonicA05Service.Iniciado)
|
||||
{
|
||||
AdicionarComandoNaFila(new ModbusComandoModel()
|
||||
{
|
||||
Dispositivo = T_Code.A05,
|
||||
Endereco = UltrasonicA05Service.slaveAddress,
|
||||
Comando = UltrasonicA05Service.ComandoAquisicaoDados(),
|
||||
Verificacao = false,
|
||||
TamanhoEsperado = 11,
|
||||
TimeoutResposta = 1000,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void TmrLoopComandos_Tick(object sender, EventArgs e)
|
||||
{
|
||||
if (EnvioLiberado && !Verificando && !frmInstancial.Fechando)
|
||||
{
|
||||
Task.Run(() => LoopEnvioComandos());
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task LoopEnvioComandos()
|
||||
{
|
||||
EnvioLiberado = false;
|
||||
|
||||
if (Iniciado)
|
||||
try
|
||||
{
|
||||
_PortaModbus.Write(Comando, 0, Comando.Length);
|
||||
List<ModbusComandoModel> comandosParaEnviar;
|
||||
|
||||
await Task.Delay(200);
|
||||
lock (FilaLock)
|
||||
{
|
||||
comandosParaEnviar = FilaComandos.Where(x => !x.Enviado).OrderByDescending(x => x.Verificacao).ThenBy(x => x.Momento).ToList();
|
||||
}
|
||||
|
||||
foreach (var Comando in comandosParaEnviar)
|
||||
{
|
||||
await EnviarComando(Comando);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
RegisrarErrosComunicacao(T_Code.Mbs, 0, $"Erro ao processar fila de comandos. Erro={ex.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
EnvioLiberado = true;
|
||||
}
|
||||
}
|
||||
|
||||
private static void RegisrarErrosComunicacao(T_Code dispositivo, byte addr, string mensagem)
|
||||
{
|
||||
var Caminho = Variaveis.CaminhoLogsDispositivos;
|
||||
if (!Directory.Exists(Caminho))
|
||||
{
|
||||
Directory.CreateDirectory(Caminho);
|
||||
}
|
||||
|
||||
EnvioLiberado = true;
|
||||
var Arquivo = dispositivo.ToString() + "_err.txt";
|
||||
Caminho += "/" + Arquivo;
|
||||
|
||||
mensagem = DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss:fff") + " - Porta " + (_PortaModbus?.PortName ?? "COM") + " - " + addr + ": " + mensagem + Environment.NewLine;
|
||||
|
||||
if (!File.Exists(Caminho))
|
||||
{
|
||||
File.WriteAllText(Caminho, mensagem);
|
||||
}
|
||||
else
|
||||
{
|
||||
File.AppendAllText(Caminho, mensagem);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void AdicionarComandoNaFila(ModbusComandoModel Comando)
|
||||
{
|
||||
lock (FilaLock)
|
||||
{
|
||||
if (!FilaComandos.Any(x => x.Dispositivo == Comando.Dispositivo && x.Comando.SequenceEqual(Comando.Comando) && !x.Enviado))
|
||||
{
|
||||
FilaComandos.Add(Comando);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task EnviarComando(ModbusComandoModel Comando)
|
||||
{
|
||||
if (_PortaModbus != null && _PortaModbus.IsOpen)
|
||||
{
|
||||
try
|
||||
{
|
||||
//await Task.Delay(100);
|
||||
DescartarDadosBuffer();
|
||||
|
||||
_PortaModbus.Write(Comando.Comando, 0, Comando.Comando.Length);
|
||||
Comando.Enviado = true;
|
||||
|
||||
Comando.Resposta = await SerialService.LerDadosDaPortaSerialAsync(_PortaModbus, Comando.TamanhoEsperado, Comando.TimeoutResposta);
|
||||
|
||||
Comando.RespondidoEm = DateTime.Now;
|
||||
|
||||
ProcessarResposta(Comando);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
RegisrarErrosComunicacao(Comando.Dispositivo, Comando.Endereco, $"Erro ao processar fila de comandos. Erro={ex.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
DescartarDadosBuffer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void ProcessarResposta(ModbusComandoModel Comando)
|
||||
{
|
||||
bool sucesso = false;
|
||||
|
||||
switch (Comando.Dispositivo)
|
||||
{
|
||||
case T_Code.Pzm:
|
||||
{
|
||||
sucesso = PZEMService.ProcessarResposta(Comando.Resposta);
|
||||
frmInstancial.frmAcompanhamento.AtualizarSensores("Ultima Leitura PZM: " + PZEMService.UltimaLeitura.DataHora.ToString("HH:mm:ss"));
|
||||
break;
|
||||
}
|
||||
case T_Code.Wit:
|
||||
{
|
||||
sucesso = WT901CService.ProcessarResposta(Comando.Resposta);
|
||||
frmInstancial.frmAcompanhamento.AtualizarSensores("Ultima Leitura WIT: " + WT901CService.DadosLeitura.Momento.ToString("HH:mm:ss"));
|
||||
break;
|
||||
}
|
||||
case T_Code.A05:
|
||||
{
|
||||
sucesso = UltrasonicA05Service.DecifrarRespostaAquisicao(Comando.Resposta);
|
||||
frmInstancial.frmAcompanhamento.AtualizarSensores("Ultima Leitura A05: " + UltrasonicA05Service.DadosLeitura.Momento.ToString("HH:mm:ss"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -261,18 +461,4 @@ namespace AgroBase.Services
|
|||
|
||||
}
|
||||
|
||||
public class ModbusParametrosModel
|
||||
{
|
||||
public DateTime UltimaRequisicao { get; set; } = DateTime.MaxValue;
|
||||
public string Descricao { get; set; }
|
||||
public string Chave { get; set; }
|
||||
public byte FuncaoGet { get; set; }
|
||||
public byte FuncaoSet { get; set; }
|
||||
public byte Registro { get; set; }
|
||||
public byte N_Registros { get; set; }
|
||||
public bool LeituraLoop { get; set; }
|
||||
public bool LeituraGeral { get; set; }
|
||||
public double Escala { get; set; }
|
||||
public byte[] Valor { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ namespace AgroBase.Services
|
|||
{
|
||||
public static bool Iniciado { get; set; }
|
||||
public static int TaxaAmostragem { get; set; } = 500;
|
||||
private static byte slaveAddress = 0x01;
|
||||
public static byte slaveAddress = 0x01;
|
||||
|
||||
public static PZEMModel UltimaLeitura = new PZEMModel();
|
||||
public static PZEMModel PenultimaLeitura = new PZEMModel();
|
||||
|
|
@ -51,60 +51,40 @@ namespace AgroBase.Services
|
|||
|
||||
public static async Task<bool> VerificaPortaPZEM(SerialPort porta)
|
||||
{
|
||||
ModbusService.Verificando = true;
|
||||
ModbusService.DefinirPortaCOM(porta);
|
||||
|
||||
porta.BaudRate = 9600;
|
||||
|
||||
var comando = ComandoGetParametro(Parametros["AlarmeTensaoMaxima"]);
|
||||
EnviarComando(porta, comando);
|
||||
var resposta = SerialService.LerDadosDaPortaSerial(porta, 7, 1000);
|
||||
//var resposta = SerialService.VerificarRespostaPortasDesconhecidas(porta);
|
||||
|
||||
ModbusService.Verificando = false;
|
||||
|
||||
Iniciado = DecifrarRespostaAquisicao(resposta) != null;
|
||||
|
||||
if (resposta.Length > 3 && resposta[1] == CodigosFuncoes["LeituraParametro"] && Iniciado)
|
||||
var Comando = new ModbusComandoModel()
|
||||
{
|
||||
AtualizarPortaCOM(porta);
|
||||
Dispositivo = T_Code.Pzm,
|
||||
Endereco = slaveAddress,
|
||||
Comando = ComandoAquisicaoDados(),
|
||||
Verificacao = true,
|
||||
TamanhoEsperado = 16
|
||||
};
|
||||
|
||||
ModbusService.AdicionarComandoNaFila(Comando);
|
||||
|
||||
while (Comando.RespondidoEm == DateTime.MinValue)
|
||||
{
|
||||
await Task.Delay(200);
|
||||
}
|
||||
|
||||
Iniciado = DecifrarRespostaAquisicao(Comando.Resposta);
|
||||
|
||||
if (Iniciado)
|
||||
{
|
||||
DefinirDispositivo();
|
||||
return Iniciado;
|
||||
}
|
||||
|
||||
if (!ModbusService.Iniciado)
|
||||
{
|
||||
porta.Close();
|
||||
ModbusService.LimparDadosPorta();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void AtualizarPortaCOM(SerialPort Porta)
|
||||
{
|
||||
if (ModbusService._PortaModbus == null || !ModbusService.Iniciado)
|
||||
{
|
||||
lock (ModbusService._lock)
|
||||
{
|
||||
ModbusService._PortaModbus = new SerialPort();
|
||||
ModbusService._PortaModbus.BaudRate = Porta.BaudRate;
|
||||
ModbusService._PortaModbus.PortName = Porta.PortName;
|
||||
}
|
||||
}
|
||||
|
||||
if (ModbusService._PortaModbus != null && !ModbusService._PortaModbus.IsOpen)
|
||||
{
|
||||
Porta.Close();
|
||||
}
|
||||
|
||||
if (Iniciado)
|
||||
{
|
||||
bool i = ModbusService.Iniciado;
|
||||
DefinirDispositivo();
|
||||
ContadorCarga = new CoulombCounterService(VariaveisEquipamento.BateriaMax);
|
||||
ReceberDados().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static void DefinirDispositivo()
|
||||
{
|
||||
if (Iniciado)
|
||||
|
|
@ -119,216 +99,13 @@ namespace AgroBase.Services
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public static void EnviarComando(SerialPort _Porta, byte[] Comando)
|
||||
{
|
||||
if (_Porta != null)
|
||||
{
|
||||
if (!_Porta.IsOpen)
|
||||
{
|
||||
_Porta.Open();
|
||||
}
|
||||
if (_Porta.IsOpen)
|
||||
{
|
||||
_Porta.Write(Comando, 0, Comando.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<bool> ReceberDados()
|
||||
{
|
||||
if (!ModbusService.Iniciado)
|
||||
{
|
||||
Iniciado = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
PenultimaLeitura = new PZEMModel()
|
||||
{
|
||||
AlarmeTensaoMax = UltimaLeitura.AlarmeTensaoMax,
|
||||
AlarmeTensaoMin = UltimaLeitura.AlarmeTensaoMin,
|
||||
Corrente = UltimaLeitura.Corrente,
|
||||
DataHora = UltimaLeitura.DataHora,
|
||||
Energia = UltimaLeitura.Energia,
|
||||
Potencia = UltimaLeitura.Potencia,
|
||||
Tensao = UltimaLeitura.Tensao
|
||||
};
|
||||
|
||||
await ModbusService.EnviarComando(ComandoAquisicaoDados());
|
||||
|
||||
byte[] resposta = SerialService.VerificarRespostaPortasDesconhecidas(ModbusService._PortaModbus);
|
||||
|
||||
DecifrarRespostaAquisicao(resposta);
|
||||
|
||||
ContadorCarga.AtualizarConsumo();
|
||||
|
||||
double percent = FuncoesMatematicas.Map(UltimaLeitura.Tensao, TensaoMinima, TensaoMaxima, 0, 100);
|
||||
Variaveis.OperacaoEmAndamento.Sensoriamento.PorcentagemBateria = percent;
|
||||
frmInstancial.frmAcompanhamento.AtualizarSensores("Bateria: " + UltimaLeitura.Tensao.ToString("0.00") + " V - " + UltimaLeitura.Corrente.ToString("0.00") + " A - " + UltimaLeitura.Potencia.ToString("0.00") + " W");
|
||||
Variaveis.OperacaoEmAndamento.Sensoriamento.BateriaConsumida = ContadorCarga.PercentualConsumido;
|
||||
|
||||
|
||||
await Task.Delay(TaxaAmostragem);
|
||||
|
||||
if (ModbusService.Iniciado)
|
||||
{
|
||||
return await ReceberDados();
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#region Comandos
|
||||
|
||||
public static byte[] ComandoAquisicaoDados()
|
||||
{
|
||||
byte functionCode = CodigosFuncoes["AquisicaoDados"];
|
||||
ushort startAddress = 0x0000;
|
||||
ushort numOfRegisters = 0x0008;
|
||||
|
||||
List<byte> command = new List<byte>();
|
||||
command.Add(slaveAddress);
|
||||
command.Add(functionCode);
|
||||
command.AddRange(BitConverter.GetBytes(startAddress).Reverse()); // Big endian
|
||||
command.AddRange(BitConverter.GetBytes(numOfRegisters).Reverse()); // Big endian
|
||||
|
||||
byte[] crc = Crc16(command.ToArray()); // Supondo que você tenha a implementação do CRC16
|
||||
command.AddRange(crc);
|
||||
|
||||
return command.ToArray();
|
||||
}
|
||||
|
||||
public static byte[] ComandoSetParametro(byte Parametro, float valor)
|
||||
{
|
||||
// Convertendo o valor para o formato correto (LSB = 0.01)
|
||||
int valorInt = (int)(valor * 100); // Convertendo para inteiro conforme a resolução
|
||||
byte functionCode = CodigosFuncoes["GravacaoParametro"];
|
||||
ushort registerAddress = Parametro;
|
||||
|
||||
// Construindo o comando
|
||||
List<byte> command = new List<byte>();
|
||||
command.Add(slaveAddress);
|
||||
command.Add(functionCode);
|
||||
command.AddRange(BitConverter.GetBytes(registerAddress).Reverse()); // Little endian
|
||||
command.AddRange(BitConverter.GetBytes((ushort)valorInt).Reverse()); // Little endian
|
||||
|
||||
byte[] crc = Crc16(command.ToArray()); // Supondo que você tenha a implementação do CRC16
|
||||
command.AddRange(crc);
|
||||
|
||||
return command.ToArray();
|
||||
}
|
||||
|
||||
public static byte[] ComandoGetParametro(byte Parametro)
|
||||
{
|
||||
byte functionCode = CodigosFuncoes["LeituraParametro"];
|
||||
ushort registerAddress = Parametro;
|
||||
ushort numberOfRegisters = 0x0001; // Lendo apenas um registro
|
||||
|
||||
// Construindo o comando
|
||||
List<byte> command = new List<byte>();
|
||||
command.Add(slaveAddress);
|
||||
command.Add(functionCode);
|
||||
command.AddRange(BitConverter.GetBytes(registerAddress).Reverse()); // Big endian
|
||||
command.AddRange(BitConverter.GetBytes(numberOfRegisters).Reverse()); // Big endian
|
||||
|
||||
byte[] crc = Crc16(command.ToArray()); // Supondo que você tenha a implementação do CRC16
|
||||
command.AddRange(crc);
|
||||
|
||||
return command.ToArray();
|
||||
}
|
||||
|
||||
public static byte[] ComandoResetEnergia()
|
||||
{
|
||||
// Código de função específico para reset de energia
|
||||
byte functionCode = CodigosFuncoes["ResetEnergia"];
|
||||
|
||||
// Construindo o comando
|
||||
List<byte> command = new List<byte>();
|
||||
command.Add(slaveAddress);
|
||||
command.Add(functionCode);
|
||||
|
||||
// Adicionando o CRC ao comando
|
||||
byte[] crc = Crc16(command.ToArray()); // Supondo que você tenha a implementação do CRC16
|
||||
command.AddRange(crc);
|
||||
|
||||
return command.ToArray();
|
||||
}
|
||||
|
||||
public static byte[] ComandoCalibragem()
|
||||
{
|
||||
byte functionCode = CodigosFuncoes["Calibrar"];
|
||||
|
||||
// Bytes fixos para o comando de calibragem
|
||||
byte[] bytesComando = new byte[] { 0xF8, functionCode, 0x37, 0x21 };
|
||||
|
||||
// Calculando o CRC para os bytes do comando
|
||||
byte[] crc = Crc16(bytesComando);
|
||||
|
||||
// Adicionando o CRC ao comando
|
||||
List<byte> comandoCalibragem = new List<byte>(bytesComando);
|
||||
comandoCalibragem.AddRange(crc);
|
||||
|
||||
return comandoCalibragem.ToArray();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public static byte[] Crc16(byte[] data)
|
||||
{
|
||||
ushort crc = 0xFFFF;
|
||||
foreach (byte pos in data)
|
||||
{
|
||||
crc ^= pos;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if ((crc & 1) != 0)
|
||||
{
|
||||
crc >>= 1;
|
||||
crc ^= 0xA001;
|
||||
}
|
||||
else
|
||||
{
|
||||
crc >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new byte[] { (byte)crc, (byte)(crc >> 8) };
|
||||
}
|
||||
|
||||
public static bool VerificarCrc(string respostaHex)
|
||||
{
|
||||
byte[] respostaBytes = HexStringToByteArray(respostaHex);
|
||||
byte[] crcRecebido = new byte[] { respostaBytes[respostaBytes.Length - 2], respostaBytes[respostaBytes.Length - 1] };
|
||||
byte[] dados = new byte[respostaBytes.Length - 2];
|
||||
Array.Copy(respostaBytes, 0, dados, 0, dados.Length);
|
||||
byte[] crcCalculado = Crc16(dados);
|
||||
return crcRecebido[0] == crcCalculado[0] && crcRecebido[1] == crcCalculado[1];
|
||||
}
|
||||
|
||||
public static byte[] HexStringToByteArray(string hex)
|
||||
{
|
||||
int NumberChars = hex.Length;
|
||||
byte[] bytes = new byte[NumberChars / 2];
|
||||
for (int i = 0; i < NumberChars; i += 2)
|
||||
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static PZEMModel DecifrarRespostaAquisicao(byte[] resposta)
|
||||
public static bool DecifrarRespostaAquisicao(byte[] resposta)
|
||||
{
|
||||
try
|
||||
{
|
||||
/*if (!VerificarCrc(resposta))
|
||||
{
|
||||
Console.Write("CRC inválido. A resposta pode estar corrompida.");
|
||||
return null;
|
||||
}*/
|
||||
|
||||
if (!resposta.Any())
|
||||
{
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (resposta[1] == CodigosFuncoes["AquisicaoDados"])
|
||||
|
|
@ -355,7 +132,7 @@ namespace AgroBase.Services
|
|||
|
||||
UltimaLeitura = modelo;
|
||||
|
||||
return modelo;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -392,16 +169,138 @@ namespace AgroBase.Services
|
|||
Console.WriteLine("Resposta inválida ou código de função incorreto.");
|
||||
}
|
||||
|
||||
return new PZEMModel();
|
||||
return false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ProcessarResposta(byte[] Resposta)
|
||||
{
|
||||
PenultimaLeitura = new PZEMModel()
|
||||
{
|
||||
AlarmeTensaoMax = UltimaLeitura.AlarmeTensaoMax,
|
||||
AlarmeTensaoMin = UltimaLeitura.AlarmeTensaoMin,
|
||||
Corrente = UltimaLeitura.Corrente,
|
||||
DataHora = UltimaLeitura.DataHora,
|
||||
Energia = UltimaLeitura.Energia,
|
||||
Potencia = UltimaLeitura.Potencia,
|
||||
Tensao = UltimaLeitura.Tensao
|
||||
};
|
||||
|
||||
bool Sucesso = DecifrarRespostaAquisicao(Resposta);
|
||||
|
||||
ContadorCarga.AtualizarConsumo();
|
||||
|
||||
double percent = FuncoesMatematicas.Map(UltimaLeitura.Tensao, TensaoMinima, TensaoMaxima, 0, 100);
|
||||
Variaveis.OperacaoEmAndamento.Sensoriamento.PorcentagemBateria = percent;
|
||||
frmInstancial.frmAcompanhamento.AtualizarSensores("Bateria: " + UltimaLeitura.Tensao.ToString("0.00") + " V - " + UltimaLeitura.Corrente.ToString("0.00") + " A - " + UltimaLeitura.Potencia.ToString("0.00") + " W");
|
||||
Variaveis.OperacaoEmAndamento.Sensoriamento.BateriaConsumida = ContadorCarga.PercentualConsumido;
|
||||
|
||||
return Sucesso;
|
||||
}
|
||||
|
||||
#region Comandos
|
||||
|
||||
public static byte[] ComandoAquisicaoDados()
|
||||
{
|
||||
byte functionCode = CodigosFuncoes["AquisicaoDados"];
|
||||
ushort startAddress = 0x0000;
|
||||
ushort numOfRegisters = 0x0008;
|
||||
|
||||
List<byte> command = new List<byte>();
|
||||
command.Add(slaveAddress);
|
||||
command.Add(functionCode);
|
||||
command.AddRange(BitConverter.GetBytes(startAddress).Reverse()); // Big endian
|
||||
command.AddRange(BitConverter.GetBytes(numOfRegisters).Reverse()); // Big endian
|
||||
|
||||
byte[] crc = ModbusService.Crc16(command.ToArray()); // Supondo que você tenha a implementação do CRC16
|
||||
command.AddRange(crc);
|
||||
|
||||
return command.ToArray();
|
||||
}
|
||||
|
||||
public static byte[] ComandoSetParametro(byte Parametro, float valor)
|
||||
{
|
||||
// Convertendo o valor para o formato correto (LSB = 0.01)
|
||||
int valorInt = (int)(valor * 100); // Convertendo para inteiro conforme a resolução
|
||||
byte functionCode = CodigosFuncoes["GravacaoParametro"];
|
||||
ushort registerAddress = Parametro;
|
||||
|
||||
// Construindo o comando
|
||||
List<byte> command = new List<byte>();
|
||||
command.Add(slaveAddress);
|
||||
command.Add(functionCode);
|
||||
command.AddRange(BitConverter.GetBytes(registerAddress).Reverse()); // Little endian
|
||||
command.AddRange(BitConverter.GetBytes((ushort)valorInt).Reverse()); // Little endian
|
||||
|
||||
byte[] crc = ModbusService.Crc16(command.ToArray()); // Supondo que você tenha a implementação do CRC16
|
||||
command.AddRange(crc);
|
||||
|
||||
return command.ToArray();
|
||||
}
|
||||
|
||||
public static byte[] ComandoGetParametro(byte Parametro)
|
||||
{
|
||||
byte functionCode = CodigosFuncoes["LeituraParametro"];
|
||||
ushort registerAddress = Parametro;
|
||||
ushort numberOfRegisters = 0x0001; // Lendo apenas um registro
|
||||
|
||||
// Construindo o comando
|
||||
List<byte> command = new List<byte>();
|
||||
command.Add(slaveAddress);
|
||||
command.Add(functionCode);
|
||||
command.AddRange(BitConverter.GetBytes(registerAddress).Reverse()); // Big endian
|
||||
command.AddRange(BitConverter.GetBytes(numberOfRegisters).Reverse()); // Big endian
|
||||
|
||||
byte[] crc = ModbusService.Crc16(command.ToArray()); // Supondo que você tenha a implementação do CRC16
|
||||
command.AddRange(crc);
|
||||
|
||||
return command.ToArray();
|
||||
}
|
||||
|
||||
public static byte[] ComandoResetEnergia()
|
||||
{
|
||||
// Código de função específico para reset de energia
|
||||
byte functionCode = CodigosFuncoes["ResetEnergia"];
|
||||
|
||||
// Construindo o comando
|
||||
List<byte> command = new List<byte>();
|
||||
command.Add(slaveAddress);
|
||||
command.Add(functionCode);
|
||||
|
||||
// Adicionando o CRC ao comando
|
||||
byte[] crc = ModbusService.Crc16(command.ToArray()); // Supondo que você tenha a implementação do CRC16
|
||||
command.AddRange(crc);
|
||||
|
||||
return command.ToArray();
|
||||
}
|
||||
|
||||
public static byte[] ComandoCalibragem()
|
||||
{
|
||||
byte functionCode = CodigosFuncoes["Calibrar"];
|
||||
|
||||
// Bytes fixos para o comando de calibragem
|
||||
byte[] bytesComando = new byte[] { 0xF8, functionCode, 0x37, 0x21 };
|
||||
|
||||
// Calculando o CRC para os bytes do comando
|
||||
byte[] crc = ModbusService.Crc16(bytesComando);
|
||||
|
||||
// Adicionando o CRC ao comando
|
||||
List<byte> comandoCalibragem = new List<byte>(bytesComando);
|
||||
comandoCalibragem.AddRange(crc);
|
||||
|
||||
return comandoCalibragem.ToArray();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ namespace AgroBase.Services
|
|||
public static string SplitParams = ",";
|
||||
public static List<T_Code> DispositivosMotores = new List<T_Code>() { T_Code.Mov, T_Code.Dir };
|
||||
public static List<T_Code> DispositivosConexaoInicial = new List<T_Code>() { T_Code.Mvd, T_Code.Atu, T_Code.Sen };
|
||||
public static List<T_Code> DispositivosModbus = new List<T_Code>() { T_Code.Pzm, T_Code.Wit };
|
||||
public static List<T_Code> DispositivosModbus = new List<T_Code>() { T_Code.Pzm, T_Code.Wit, T_Code.A05 };
|
||||
public static List<T_Code> DispositivosMultiplos = new List<T_Code>() { T_Code.Bld, T_Code.Mks, T_Code.Mvd };
|
||||
|
||||
public class DispositivoDetalhesModel
|
||||
|
|
@ -49,6 +49,10 @@ namespace AgroBase.Services
|
|||
{
|
||||
DispositivoConectado = PZEMService.Iniciado;
|
||||
}
|
||||
else if (Dispositivo == T_Code.A05)
|
||||
{
|
||||
DispositivoConectado = UltrasonicA05Service.Iniciado;
|
||||
}
|
||||
else if (Dispositivo == T_Code.Lra)
|
||||
{
|
||||
DispositivoConectado = LoRaService.Iniciado;
|
||||
|
|
@ -497,6 +501,16 @@ namespace AgroBase.Services
|
|||
return Encontrado;
|
||||
}
|
||||
}
|
||||
if (!UltrasonicA05Service.Iniciado || !DispositivosMapeados.Any(x => x.Dispositivo == T_Code.A05))
|
||||
{
|
||||
AtualizarConsole("Procurando dispositivo A05");
|
||||
Encontrado = await UltrasonicA05Service.VerificaPortaA05(ModbusService.Iniciado ? ModbusService._PortaModbus : porta);
|
||||
if (Encontrado && PararAoEncontrar)
|
||||
{
|
||||
AtualizarConsole("Dispositivo A05 encontrado");
|
||||
return Encontrado;
|
||||
}
|
||||
}
|
||||
/*if (Variaveis.OperacaoEmAndamento.DispMvd != null && Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.Any(x => !x.MovMotor.DadosDriver.Iniciado))
|
||||
{
|
||||
foreach (var Modulo in Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.Where(x => !x.MovMotor.DadosDriver.Iniciado))
|
||||
|
|
|
|||
|
|
@ -0,0 +1,149 @@
|
|||
using AgroBase.Forms;
|
||||
using AgroBase.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO.Ports;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static AgroBase.Models.Enums;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace AgroBase.Services
|
||||
{
|
||||
public class UltrasonicA05Service
|
||||
{
|
||||
public static bool Iniciado { get; set; }
|
||||
public static int TaxaAmostragem { get; set; } = 500;
|
||||
public static byte slaveAddress = 0x01;
|
||||
|
||||
public static UltrasonicA05Model DadosLeitura = new UltrasonicA05Model();
|
||||
|
||||
public static async Task<bool> VerificaPortaA05(SerialPort porta)
|
||||
{
|
||||
ModbusService.DefinirPortaCOM(porta);
|
||||
|
||||
var Comando = new ModbusComandoModel()
|
||||
{
|
||||
Dispositivo = T_Code.A05,
|
||||
Endereco = slaveAddress,
|
||||
Comando = ComandoAquisicaoDados(),
|
||||
Verificacao = true,
|
||||
TamanhoEsperado = 11,
|
||||
TimeoutResposta = 1000,
|
||||
};
|
||||
|
||||
ModbusService.AdicionarComandoNaFila(Comando);
|
||||
|
||||
while (Comando.RespondidoEm == DateTime.MinValue)
|
||||
{
|
||||
await Task.Delay(200);
|
||||
}
|
||||
|
||||
Iniciado = DecifrarRespostaAquisicao(Comando.Resposta);
|
||||
|
||||
if (Iniciado)
|
||||
{
|
||||
DefinirDispositivo();
|
||||
return Iniciado;
|
||||
}
|
||||
|
||||
if (!ModbusService.Iniciado)
|
||||
{
|
||||
ModbusService.LimparDadosPorta();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void DefinirDispositivo()
|
||||
{
|
||||
if (Iniciado)
|
||||
{
|
||||
SerialService.DispositivosMapeados.Add(new SerialService.DispositivoDetalhesModel()
|
||||
{
|
||||
PortaCOM = ModbusService._PortaModbus.PortName,
|
||||
Dispositivo = T_Code.A05,
|
||||
Erro = !Iniciado,
|
||||
Versao = "1"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] ComandoAquisicaoDados()
|
||||
{
|
||||
byte functionCode = 0x03;
|
||||
byte startAddress = 0x0001;
|
||||
byte firstRegister = 0x0006;
|
||||
byte numOfRegisters = 0x0004;
|
||||
|
||||
List<byte> command = new List<byte>() { slaveAddress, functionCode, startAddress, firstRegister, 0x00, numOfRegisters };
|
||||
|
||||
byte[] crc = ModbusService.Crc16(command.ToArray()); // Supondo que você tenha a implementação do CRC16
|
||||
command.AddRange(crc);
|
||||
|
||||
return command.ToArray();
|
||||
}
|
||||
|
||||
public static bool DecifrarRespostaAquisicao(byte[] resposta)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (resposta == null || !resposta.Any())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (resposta.Length >= 18)
|
||||
{
|
||||
resposta = resposta.Skip(5).ToArray();
|
||||
}
|
||||
|
||||
if (resposta[1] == 0x03)
|
||||
{
|
||||
int numBytes = resposta[2];
|
||||
if (numBytes == 8) // Se o número de bytes de dados for 8
|
||||
{
|
||||
// Decifrar os valores dos sensores
|
||||
int u1 = (resposta[3] << 8) + resposta[4];
|
||||
int u2 = (resposta[5] << 8) + resposta[6];
|
||||
int u3 = (resposta[7] << 8) + resposta[8];
|
||||
int u4 = (resposta[9] << 8) + resposta[10];
|
||||
|
||||
UltrasonicA05Model modelo = new UltrasonicA05Model()
|
||||
{
|
||||
Momento = DateTime.Now,
|
||||
Endereco = resposta[0],
|
||||
U1 = u1,
|
||||
U2 = u2,
|
||||
U3 = u3,
|
||||
U4 = u4
|
||||
};
|
||||
|
||||
DadosLeitura = modelo;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Número de bytes de dados não esperado.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Resposta inválida ou código de função incorreto.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Erro ao decifrar a resposta: " + ex.Message);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -20,108 +20,45 @@ namespace AgroBase.Services
|
|||
public static byte slaveAddress = 0x50;
|
||||
private static Dictionary<string, object> DadosSensor { get; } = new Dictionary<string, object>();
|
||||
public static WT901CModel DadosLeitura { get; set; } = new WT901CModel();
|
||||
private static byte[] ComandoAquisicao = new byte[8] { slaveAddress, 0x03, 0x00, 0x30, 0x00, 0x30, 0x48, 0x50 };
|
||||
public static byte[] ComandoAquisicao = new byte[8] { slaveAddress, 0x03, 0x00, 0x30, 0x00, 0x30, 0x48, 0x50 };
|
||||
|
||||
public static async Task<bool> VerificaPortaWT901C(SerialPort porta)
|
||||
{
|
||||
ModbusService.Verificando = true;
|
||||
ModbusService.DefinirPortaCOM(porta);
|
||||
|
||||
porta.BaudRate = 9600;
|
||||
|
||||
var comando = ModbusService.ComandoGetParametro(slaveAddress, new ModbusParametrosModel() { FuncaoGet = 0x03, N_Registros = 2, Registro = 0x2e });
|
||||
|
||||
EnviarComando(porta, comando);
|
||||
var resposta = SerialService.LerDadosDaPortaSerial(porta, 7, 1000);
|
||||
//var resposta = SerialService.VerificarRespostaPortasDesconhecidas(porta);
|
||||
|
||||
ModbusService.Verificando = false;
|
||||
|
||||
Iniciado = DecifrarRespostaAquisicao(comando, resposta);
|
||||
|
||||
if (resposta.Length > 3 && resposta[1] == 0x03 && Iniciado)
|
||||
var Comando = new ModbusComandoModel()
|
||||
{
|
||||
var magType = ModbusService.ComandoGetParametro(slaveAddress, new ModbusParametrosModel() { FuncaoGet = 0x03, N_Registros = 2, Registro = 0x72 });
|
||||
Dispositivo = T_Code.Wit,
|
||||
Endereco = slaveAddress,
|
||||
Comando = ComandoAquisicaoDados(),
|
||||
Verificacao = true,
|
||||
TamanhoEsperado = 101,
|
||||
TimeoutResposta = 1000
|
||||
};
|
||||
|
||||
EnviarComando(porta, magType);
|
||||
ModbusService.AdicionarComandoNaFila(Comando);
|
||||
|
||||
while (Comando.RespondidoEm == DateTime.MinValue)
|
||||
{
|
||||
await Task.Delay(200);
|
||||
var res = SerialService.VerificarRespostaPortasDesconhecidas(porta);
|
||||
DecifrarRespostaAquisicao(magType, res);
|
||||
}
|
||||
|
||||
AtualizarPortaCOM(porta);
|
||||
Iniciado = DecifrarRespostaAquisicao(Comando.Resposta);
|
||||
|
||||
if (Iniciado)
|
||||
{
|
||||
DefinirDispositivo();
|
||||
return Iniciado;
|
||||
}
|
||||
|
||||
if (!ModbusService.Iniciado)
|
||||
{
|
||||
porta.Close();
|
||||
ModbusService.LimparDadosPorta();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void AtualizarPortaCOM(SerialPort Porta)
|
||||
{
|
||||
if (ModbusService._PortaModbus == null || !ModbusService.Iniciado)
|
||||
{
|
||||
lock (ModbusService._lock)
|
||||
{
|
||||
ModbusService._PortaModbus = new SerialPort();
|
||||
ModbusService._PortaModbus.BaudRate = Porta.BaudRate;
|
||||
ModbusService._PortaModbus.PortName = Porta.PortName;
|
||||
}
|
||||
}
|
||||
|
||||
if (ModbusService._PortaModbus != null && !ModbusService._PortaModbus.IsOpen)
|
||||
{
|
||||
Porta.Close();
|
||||
}
|
||||
|
||||
if (Iniciado)
|
||||
{
|
||||
bool i = ModbusService.Iniciado;
|
||||
DefinirDispositivo();
|
||||
ReceberDados().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<bool> ReceberDados()
|
||||
{
|
||||
if (!ModbusService.Iniciado)
|
||||
{
|
||||
Iniciado = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
await ModbusService.EnviarComando(ComandoAquisicao);
|
||||
|
||||
byte[] resposta = SerialService.LerDadosDaPortaSerial(ModbusService._PortaModbus, 101);
|
||||
//await Task.Delay(100);
|
||||
//Iniciado = DecifrarRespostaAquisicao(ComandoAquisicao, resposta);
|
||||
DecifrarRespostaAquisicao(ComandoAquisicao, resposta);
|
||||
|
||||
if (Iniciado)
|
||||
{
|
||||
PreencherDadosLeitura();
|
||||
|
||||
Variaveis.OperacaoEmAndamento.Sensoriamento.InclinacaoX = DadosLeitura.AngleX;
|
||||
Variaveis.OperacaoEmAndamento.Sensoriamento.InclinacaoY = DadosLeitura.AngleY;
|
||||
Variaveis.OperacaoEmAndamento.Sensoriamento.InclinacaoZ = DadosLeitura.AngleZ;
|
||||
Variaveis.OperacaoEmAndamento.Sensoriamento.AnguloCarroBussola = DadosLeitura.AngleZ * -1;
|
||||
}
|
||||
|
||||
|
||||
await Task.Delay(TaxaAmostragem);
|
||||
|
||||
if (ModbusService.Iniciado)
|
||||
{
|
||||
return await ReceberDados();
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static void DefinirDispositivo()
|
||||
{
|
||||
if (Iniciado)
|
||||
|
|
@ -136,24 +73,32 @@ namespace AgroBase.Services
|
|||
}
|
||||
}
|
||||
|
||||
public static void EnviarComando(SerialPort _Porta, byte[] Comando)
|
||||
public static bool ProcessarResposta(byte[] Resposta)
|
||||
{
|
||||
if (_Porta != null)
|
||||
bool Sucesso = DecifrarRespostaAquisicao(Resposta);
|
||||
|
||||
if (Iniciado)
|
||||
{
|
||||
if (!_Porta.IsOpen)
|
||||
{
|
||||
_Porta.Open();
|
||||
}
|
||||
if (_Porta.IsOpen)
|
||||
{
|
||||
_Porta.Write(Comando, 0, Comando.Length);
|
||||
}
|
||||
PreencherDadosLeitura();
|
||||
|
||||
Variaveis.OperacaoEmAndamento.Sensoriamento.InclinacaoX = DadosLeitura.AngleX;
|
||||
Variaveis.OperacaoEmAndamento.Sensoriamento.InclinacaoY = DadosLeitura.AngleY;
|
||||
Variaveis.OperacaoEmAndamento.Sensoriamento.InclinacaoZ = DadosLeitura.AngleZ;
|
||||
Variaveis.OperacaoEmAndamento.Sensoriamento.AnguloCarroBussola = DadosLeitura.AngleZ * -1;
|
||||
}
|
||||
|
||||
return Sucesso;
|
||||
}
|
||||
|
||||
private static bool DecifrarRespostaAquisicao(byte[] comando, byte[] resposta)
|
||||
public static byte[] ComandoAquisicaoDados()
|
||||
{
|
||||
return ComandoAquisicao;
|
||||
}
|
||||
|
||||
private static bool DecifrarRespostaAquisicao(byte[] resposta)
|
||||
{
|
||||
byte[] modbusBytes;
|
||||
byte[] comando = ComandoAquisicaoDados();
|
||||
if (comando != null && resposta != null && resposta.Length >= 7 && ModbusService.FindModbus(comando, resposta, out modbusBytes))
|
||||
{
|
||||
int readReg = comando[2] << 8 | comando[3];
|
||||
|
|
@ -167,6 +112,8 @@ namespace AgroBase.Services
|
|||
DadosSensor[key] = value;
|
||||
}
|
||||
|
||||
DadosLeitura.Momento = DateTime.Now;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
|
@ -176,6 +123,8 @@ namespace AgroBase.Services
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static dynamic GetDeviceData(string key)
|
||||
{
|
||||
if (DadosSensor.ContainsKey(key))
|
||||
|
|
|
|||
Binary file not shown.
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,2 @@
|
|||
22/08/2024 14:49:56:227 - Porta COM29 - 0: Erro ao processar fila de comandos. Erro=Value cannot be null.
|
||||
22/08/2024 15:59:48:813 - Porta COM3 - 0: Erro ao processar fila de comandos. Erro=The port is closed.
|
||||
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
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
|
|
@ -1 +1 @@
|
|||
2c241a8042a47f4b7f12cdb88ec84cae700bfb617404a8de188de541b0438c6f
|
||||
ff68edbc961306d3db9a64f9fb7f5d615c8594a326799b9c62341ff2f37258f0
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,80 @@
|
|||
import serial
|
||||
import struct
|
||||
import time
|
||||
|
||||
def calculate_crc(data):
|
||||
crc = 0xFFFF
|
||||
for pos in data:
|
||||
crc ^= pos
|
||||
for _ in range(8):
|
||||
if (crc & 1) != 0:
|
||||
crc >>= 1
|
||||
crc ^= 0xA001
|
||||
else:
|
||||
crc >>= 1
|
||||
return crc
|
||||
|
||||
def send_command(ser, command):
|
||||
# Calcular o checksum
|
||||
crc = calculate_crc(command)
|
||||
command.append(crc & 0xFF) # CRC Low byte
|
||||
command.append((crc >> 8) & 0xFF) # CRC High byte
|
||||
|
||||
# Enviar o comando via serial
|
||||
ser.write(command)
|
||||
|
||||
# Ler a resposta
|
||||
response = ser.read(13) # Ler a resposta completa, 13 bytes no caso de todos os sensores
|
||||
return response
|
||||
|
||||
def parse_response(response):
|
||||
if len(response) < 11:
|
||||
print(f"Resposta incompleta ou inválida. Tamanho recebido: {len(response)}")
|
||||
return None
|
||||
|
||||
sensor_values = []
|
||||
try:
|
||||
for i in range(3, 11, 2):
|
||||
value = (response[i] << 8) + response[i + 1]
|
||||
sensor_values.append(value)
|
||||
except IndexError:
|
||||
print("Erro ao processar a resposta. Dados insuficientes.")
|
||||
sensor_values.append(-1)
|
||||
|
||||
return sensor_values
|
||||
|
||||
def main():
|
||||
# Configurar a porta serial para COM29
|
||||
ser = serial.Serial('COM29', 9600, timeout=1)
|
||||
|
||||
# Comando para requisitar dados de todos os sensores (1, 2, 3, e 4)
|
||||
command_all_sensors = [0x01, 0x03, 0x01, 0x06, 0x00, 0x04]
|
||||
|
||||
try:
|
||||
while True:
|
||||
# Enviar o comando e receber a resposta
|
||||
response_all = send_command(ser, command_all_sensors)
|
||||
|
||||
print(response_all.hex())
|
||||
|
||||
# Converter a resposta para milímetros
|
||||
sensor_values_all = parse_response(response_all)
|
||||
|
||||
# Exibir a saída formatada
|
||||
if sensor_values_all and len(sensor_values_all) == 4:
|
||||
print(f"S1: {sensor_values_all[0]} mm S2: {sensor_values_all[1]} mm S3: {sensor_values_all[2]} mm S4: {sensor_values_all[3]} mm")
|
||||
else:
|
||||
print("Dados incompletos ou inválidos recebidos dos sensores.")
|
||||
|
||||
# Esperar 1 segundo antes da próxima requisição
|
||||
time.sleep(1)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("Parando a execução...")
|
||||
|
||||
finally:
|
||||
# Fechar a conexão serial
|
||||
ser.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
Reference in New Issue