agrobot_base/AgroBase/AgroBase/Services/BLD300RService.cs

474 lines
18 KiB
C#

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.Enuns;
using System.Windows.Forms;
using Emgu.CV.Structure;
namespace AgroBase.Services
{
public class BLD300RService
{
public BLD300RService(string _Endereco)
{
slaveAddress = Convert.ToByte(_Endereco.Replace("0x", ""), 16);
}
public bool Iniciado { get; set; }
public int TaxaAmostragem { get; set; } = 1000;
public byte slaveAddress = 0x01;
public BLD300RModel UltimaLeitura
{
get
{
// Função auxiliar para converter byte[] para int
int ConvertByteArrayToInt(byte[] bytes)
{
if (bytes == null) return 0;
if (bytes.Length == 2)
{
return BitConverter.ToInt16(bytes.Reverse().ToArray(), 0);
}
else if (bytes.Length == 4)
{
return BitConverter.ToInt32(bytes.Reverse().ToArray(), 0);
}
return 0;
}
// Função auxiliar para verificar a existência de uma chave e obter o valor correspondente
byte[] GetParametroValue(string chave)
{
var parametro = Parametros.FirstOrDefault(x => x.Chave == chave);
return parametro != null ? parametro.Valor : null;
}
// Obtenção e conversão dos parâmetros
int versao = ConvertByteArrayToInt(GetParametroValue("Versao"));
int codigoAlarme = ConvertByteArrayToInt(GetParametroValue("AlarmeCode"));
int numeroPolos = ConvertByteArrayToInt(GetParametroValue("NumPolos"));
int rpmMax = ConvertByteArrayToInt(GetParametroValue("RPM_Max"));
int rampa = ConvertByteArrayToInt(GetParametroValue("Rampa"));
int rpmSp = Convert.ToInt32(ConvertByteArrayToInt(GetParametroValue("RPM_SP")) * Parametros.First(x => x.Chave == "RPM_SP").Escala);
int rpm = Convert.ToInt32(ConvertByteArrayToInt(GetParametroValue("RPM")) * Parametros.First(x => x.Chave == "RPM").Escala);
bool controleRS485 = ConvertByteArrayToInt(GetParametroValue("ControleRS485")) == 1;
bool ativado = ConvertByteArrayToInt(GetParametroValue("Enabled")) == 1;
bool freado = ConvertByteArrayToInt(GetParametroValue("Breaked")) == 1;
Sentido direcao = ConvertByteArrayToInt(GetParametroValue("Direction")) == 1 ? Sentido.Horario : Sentido.Antihorario;
var P_V = Parametros.First(x => x.Chave == "Tensao");
double tensao = ConvertByteArrayToInt(P_V.Valor) * P_V.Escala;
var P_T = Parametros.First(x => x.Chave == "Temperatura");
double temperatura = ConvertByteArrayToInt(P_T.Valor) * P_T.Escala;
var P_A = Parametros.First(x => x.Chave == "LimiteCorrente");
double corrente = ConvertByteArrayToInt(P_A.Valor) * P_A.Escala;
// Criação do modelo com os valores obtidos
BLD300RModel model = new BLD300RModel()
{
Versao = versao,
ControleRS485 = controleRS485,
CodigoAlarme = codigoAlarme,
NumeroPolos = numeroPolos,
RPM_Max = rpmMax,
Rampa = rampa,
RPM_SP = rpmSp,
RPM = rpm,
Ativado = ativado,
Freado = freado,
Direcao = direcao,
Tensao = tensao,
Temperatura = temperatura,
CorrenteMax = FuncoesMatematicas.Map(corrente, 15780, 16799, 0, 20.6)
};
return model;
}
}
public static List<ModbusParametrosModel> Parametros = new List<ModbusParametrosModel>()
{
new ModbusParametrosModel()
{
Chave = "Versao",
Descricao = "Verifica a versão do driver",
FuncaoGet = 0x03,
FuncaoSet = 0x06,
Escala = 1,
LeituraLoop = true,
LeituraGeral = true,
N_Registros = 0x0001,
Registro = 0x00BB
},
new ModbusParametrosModel()
{
Chave = "ControleRS485",
Descricao = "Habilita/Desabilita controle através da interface RS485",
FuncaoGet = 0x03,
FuncaoSet = 0x06,
Escala = 1,
LeituraLoop = false,
LeituraGeral = true,
N_Registros = 0x0001,
Registro = 0x00B6
},
new ModbusParametrosModel()
{
Chave = "AlarmeCode",
Descricao = "Verifica o código de alarme",
FuncaoGet = 0x03,
FuncaoSet = 0x06,
Escala = 1,
LeituraLoop = true,
LeituraGeral = true,
N_Registros = 0x0001,
Registro = 0x0076
},
new ModbusParametrosModel()
{
Chave = "NumPolos",
Descricao = "Verifica/Define o número de polos do motor definido no driver",
FuncaoGet = 0x03,
FuncaoSet = 0x06,
Escala = 1,
LeituraLoop = false,
LeituraGeral = true,
N_Registros = 0x0001,
Registro = 0x0086
},
new ModbusParametrosModel()
{
Chave = "RPM_Max",
Descricao = "Verifica/Define o RPM máximo do motor através do controle",
FuncaoGet = 0x03,
FuncaoSet = 0x06,
Escala = 1,
LeituraLoop = false,
LeituraGeral = true,
N_Registros = 0x0001,
Registro = 0x0092
},
new ModbusParametrosModel()
{
Chave = "Rampa",
Descricao = "Verifica/Define o tempo de rampa de aceleração/desaceleração (x 100 ms)",
FuncaoGet = 0x03,
FuncaoSet = 0x06,
Escala = 1,
LeituraLoop = false,
LeituraGeral = true,
N_Registros = 0x0001,
Registro = 0x008A
},
new ModbusParametrosModel()
{
Chave = "RPM_SP",
Descricao = "Verifica/Define o RPM de Set Point",
FuncaoGet = 0x03,
FuncaoSet = 0x06,
Escala = 1,
LeituraLoop = false,
LeituraGeral = true,
N_Registros = 0x0001,
Registro = 0x0056
},
new ModbusParametrosModel()
{
Chave = "RPM",
Descricao = "Verifica o RPM atual do motor",
FuncaoGet = 0x03,
FuncaoSet = 0x06,
Escala = 0.27,
LeituraLoop = true,
LeituraGeral = true,
N_Registros = 0x0001,
Registro = 0x005F
},
new ModbusParametrosModel()
{
Chave = "Enabled",
Descricao = "Verifica/Define o status do motor",
FuncaoGet = 0x03,
FuncaoSet = 0x06,
Escala = 1,
LeituraLoop = true,
LeituraGeral = true,
N_Registros = 0x0001,
Registro = 0x0066
},
new ModbusParametrosModel()
{
Chave = "Breaked",
Descricao = "Verifica/Define o status do freio do motor",
FuncaoGet = 0x03,
FuncaoSet = 0x06,
Escala = 1,
LeituraLoop = true,
LeituraGeral = true,
N_Registros = 0x0001,
Registro = 0x006A
},
new ModbusParametrosModel()
{
Chave = "Direction",
Descricao = "Verifica/Define o sentido de giro do motor",
FuncaoGet = 0x03,
FuncaoSet = 0x06,
Escala = 1,
LeituraLoop = true,
LeituraGeral = true,
N_Registros = 0x0001,
Registro = 0x006D
},
new ModbusParametrosModel()
{
Chave = "LimiteCorrente",
Descricao = "Verifica o limite de corrente definido",
FuncaoGet = 0x03,
FuncaoSet = 0x06,
Escala = 0.01,
LeituraLoop = false,
LeituraGeral = true,
N_Registros = 0x0002,
Registro = 0x0096
},
new ModbusParametrosModel()
{
Chave = "Tensao",
Descricao = "Verifica a tensão de alimentação no driver",
FuncaoGet = 0x03,
FuncaoSet = 0x06,
Escala = 0.01,
LeituraLoop = true,
LeituraGeral = true,
N_Registros = 0x0002,
Registro = 0x00C8
},
new ModbusParametrosModel()
{
Chave = "Temperatura",
Descricao = "Verifica a temperatura do driver",
FuncaoGet = 0x03,
FuncaoSet = 0x06,
Escala = 0.01,
LeituraLoop = true,
LeituraGeral = true,
N_Registros = 0x0002,
Registro = 0x00d2
},
new ModbusParametrosModel()
{
Chave = "Restaurar",
Descricao = "Restaura os parâmetros de fábrica",
FuncaoGet = 0x03,
FuncaoSet = 0x06,
Escala = 1,
LeituraLoop = false,
LeituraGeral = false,
N_Registros = 0x0001,
Registro = 0x00CC
},
};
public async Task<bool> VerificaPortaBLD(SerialPort porta)
{
ModbusService.Verificando = true;
porta.BaudRate = 9600;
var Parametro = Parametros.First(x => x.Chave == "Versao");
var comando = ModbusService.ComandoGetParametro(slaveAddress, Parametro);
EnviarComando(porta, comando);
await Task.Delay(1000);
var resposta = SerialService.VerificarRespostaPortasDesconhecidas(porta);
ModbusService.Verificando = false;
Iniciado = DecifrarResposta(resposta, Parametro) != null;
if (resposta.Length >= 5 && resposta[1] == Parametro.FuncaoGet && Iniciado)
{
AtualizarPortaCOM(porta);
return Iniciado;
}
if (!ModbusService.Iniciado)
{
porta.Close();
}
return false;
}
public 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 void DefinirDispositivo()
{
if (Iniciado)
{
SerialService.DispositivosMapeados.Add(new SerialService.DispositivoDetalhesModel()
{
PortaCOM = ModbusService._PortaModbus.PortName,
Dispositivo = T_Code.Bld,
Erro = !Iniciado,
Versao = UltimaLeitura.Versao.ToString(),
Mod_ID = Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.FirstOrDefault(x => Convert.ToByte(x.MovMotor.Endereco.Replace("0x", ""), 16) == slaveAddress).Modulo_ID,
});
}
}
public void EnviarComando(SerialPort _Porta, byte[] Comando)
{
if (_Porta != null)
{
if (!_Porta.IsOpen)
{
_Porta.Open();
}
if (_Porta.IsOpen)
{
_Porta.Write(Comando, 0, Comando.Length);
}
}
}
private async Task<bool> ReceberDados()
{
foreach (var Parametro in Parametros.Where(x => x.LeituraLoop))
{
await ModbusService.EnviarComando(ModbusService.ComandoGetParametro(slaveAddress, Parametro));
byte[] resposta = SerialService.VerificarRespostaPortasDesconhecidas(ModbusService._PortaModbus);
Iniciado = DecifrarResposta(resposta, Parametro) != null;
}
var Modulo = Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.FirstOrDefault(x => Convert.ToByte(x.MovMotor.Endereco.Replace("0x", ""), 16) == slaveAddress);
if (Modulo != null)
{
Modulo.MovMotor.RPM = UltimaLeitura.RPM;
Modulo.MovMotor.TemperaturaDriver = UltimaLeitura.Temperatura;
Modulo.MovMotor.Corrente_Max = UltimaLeitura.CorrenteMax;
Modulo.MovMotor.Tensao = UltimaLeitura.Tensao;
Modulo.MovMotor.Ligado = UltimaLeitura.Ativado;
Modulo.MovMotor.Freio = UltimaLeitura.Freado;
Modulo.MovMotor.Sentido = UltimaLeitura.Direcao;
Modulo.MovMotor.CodigoAlarme = UltimaLeitura.CodigoAlarme;
Variaveis.OperacaoEmAndamento.DispMvd.Dados.RegistrarLog(Modulo);
}
await Task.Delay(TaxaAmostragem);
return await ReceberDados();
}
public BLD300RModel DecifrarResposta(byte[] resposta, ModbusParametrosModel Parametro)
{
try
{
/*if (!VerificarCrc(resposta))
{
Console.Write("CRC inválido. A resposta pode estar corrompida.");
return null;
}*/
if (resposta.Length > 3)
{
if (Parametros.Any(x => x.FuncaoGet == resposta[1]))
{
int num_registros = resposta[2];
byte[] bytes_resposta = resposta.Skip(3).Take(num_registros).ToArray();
Parametro.Valor = bytes_resposta;
Parametro.UltimaRequisicao = DateTime.MaxValue;
}
else if (Parametros.Any(x => x.FuncaoSet == resposta[1]))
{
string parametro_raw = "0x" + (resposta[2].ToString("X").Length == 1 ? "0" : "") + resposta[2].ToString("X") + (resposta[3].ToString("X").Length == 1 ? "0" : "") + resposta[3].ToString("X");
int parametro = Convert.ToInt32(parametro_raw, 16);
string valor_raw = "0x" + (resposta[4].ToString("X").Length == 1 ? "0" : "") + resposta[4].ToString("X") + (resposta[5].ToString("X").Length == 1 ? "0" : "") + resposta[5].ToString("X");
int valor = Convert.ToInt32(valor_raw, 16);
Parametros.First(x => x.Registro == parametro).Valor = resposta.Skip(4).Take(2).ToArray();
//MessageBox.Show("Parâmetro gravado com sucesso!");
}
else
{
Console.WriteLine("Resposta inválida ou código de função incorreto.");
}
}
else
{
return null;
}
return new BLD300RModel();
}
catch (Exception ex)
{
}
return null;
}
public async Task AtualizarDadosDriver()
{
await ModbusService.EnviarComando(ModbusService.ComandoSetParametro(slaveAddress, Parametros.First(x => x.Chave == "ControleRS485"), 1));
await ModbusService.EnviarComando(ModbusService.ComandoSetParametro(slaveAddress, Parametros.First(x => x.Chave == "AlarmeCode"), 0));
await ModbusService.EnviarComando(ModbusService.ComandoSetParametro(slaveAddress, Parametros.First(x => x.Chave == "NumPolos"), Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.First().MovMotor.NumeroPolos));
await ModbusService.EnviarComando(ModbusService.ComandoSetParametro(slaveAddress, Parametros.First(x => x.Chave == "RPM_Max"), Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.First().MovMotor.RPM_Max));
await ModbusService.EnviarComando(ModbusService.ComandoSetParametro(slaveAddress, Parametros.First(x => x.Chave == "Rampa"), Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.First().MovMotor.Rampa));
await ModbusService.EnviarComando(ModbusService.ComandoSetParametro(slaveAddress, Parametros.First(x => x.Chave == "ControleRS485"), 0));
foreach (var Parametro in Parametros.Where(x => x.LeituraGeral))
{
await ModbusService.EnviarComando(ModbusService.ComandoGetParametro(slaveAddress, Parametro));
byte[] resposta = SerialService.VerificarRespostaPortasDesconhecidas(ModbusService._PortaModbus);
Iniciado = DecifrarResposta(resposta, Parametro) != null;
}
}
}
}