474 lines
18 KiB
C#
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;
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
}
|