finalizado implementacao i2c robusta
This commit is contained in:
parent
a7cec85038
commit
f82131569d
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1219,14 +1219,14 @@ namespace AgroBase.Forms.IHM
|
|||
bool PzmConectado = SerialService.DispositivosMapeados.Any(x => x.Dispositivo == Enums.T_Code.Pzm);
|
||||
idx = PreencheDadosLinha(grid, Testes, idx, PzmConectado ? 1 : 0);
|
||||
|
||||
var S36V = ((FirmwareSensorCorrente)Modulo_Sen.Sensores.FirstOrDefault(x => x.ID == "AB36V").Leitura);
|
||||
bool S36VInicializado = S36V?.Iniciado ?? false;
|
||||
var S36V = Variaveis.OperacaoEmAndamento.Sensoriamento.Bateria;
|
||||
bool S36VInicializado = S36V.Iniciado;
|
||||
idx = PreencheDadosLinha(grid, Testes, idx, S36VInicializado ? 1 : 0);
|
||||
|
||||
double Tensao = S36VInicializado ? S36V.BusVoltage : -1;
|
||||
double Tensao = S36VInicializado ? S36V.TensaoInstantanea : -1;
|
||||
idx = PreencheDadosLinha(grid, Testes, idx, Tensao);
|
||||
|
||||
double Corrente = S36VInicializado ? S36V.Current : -1;
|
||||
double Corrente = S36VInicializado ? S36V.CorrenteInstantanea : -1;
|
||||
idx = PreencheDadosLinha(grid, Testes, idx, Corrente);
|
||||
|
||||
bool SenConectado = SerialService.DispositivosMapeados.Any(x => x.Dispositivo == T_Code.Sen);
|
||||
|
|
@ -1266,13 +1266,13 @@ namespace AgroBase.Forms.IHM
|
|||
bool GpsInicializado = GPSService.Iniciado;
|
||||
idx = PreencheDadosLinha(grid, Testes, idx, GpsInicializado ? 1 : 0);
|
||||
|
||||
double Precisao = GpsInicializado ? (int)GPSService.UltimaLeitura.QualidadeFix : -1;
|
||||
double Precisao = GpsInicializado ? (int)Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.QualidadeFix : -1;
|
||||
idx = PreencheDadosLinha(grid, Testes, idx, Precisao);
|
||||
|
||||
double Satelites = GpsInicializado ? GPSService.UltimaLeitura.NumeroSatelites : -1;
|
||||
double Satelites = GpsInicializado ? Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.NumeroSatelites : -1;
|
||||
idx = PreencheDadosLinha(grid, Testes, idx, Satelites);
|
||||
|
||||
double OrientacaoGPS = GpsInicializado ? GPSService.UltimaLeitura.CursoVerdadeiro : -1;
|
||||
double OrientacaoGPS = GpsInicializado ? Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.OrientacaoReal : -1;
|
||||
idx = PreencheDadosLinha(grid, Testes, idx, OrientacaoGPS);
|
||||
|
||||
bool A05Conectado = SerialService.DispositivosMapeados.Any(x => x.Dispositivo == Enums.T_Code.A05);
|
||||
|
|
|
|||
|
|
@ -387,10 +387,11 @@ namespace AgroBase.Forms.Operacoes
|
|||
|
||||
private void pnlAnguloMagnetometro_Paint(object sender, PaintEventArgs e)
|
||||
{
|
||||
var imu = Variaveis.OperacaoEmAndamento.Sensoriamento.IMU;
|
||||
try
|
||||
{
|
||||
double angulo = Variaveis.OperacaoEmAndamento.DispSen?.Dados?.DadosLeitura?.SensoresIMU?.FirstOrDefault()?.Yaw ?? -1;
|
||||
double anguloCorrigido = Variaveis.OperacaoEmAndamento.DispSen?.Dados?.DadosLeitura?.SensoresIMU?.FirstOrDefault()?.YawFixed ?? -1;
|
||||
double angulo = imu.Rotacao;
|
||||
double anguloCorrigido = imu.RotacaoCorrigida;
|
||||
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)angulo, -270, (float)anguloCorrigido);
|
||||
}
|
||||
catch { }
|
||||
|
|
@ -443,6 +444,10 @@ namespace AgroBase.Forms.Operacoes
|
|||
gridDados.Rows.Add("Temperatura", "", "");
|
||||
gridDados.Rows.Add("Pressao", "", "");
|
||||
gridDados.Rows.Add("Altitude", "", "");
|
||||
gridDados.Rows.Add("Temperatura ET", "", "");
|
||||
gridDados.Rows.Add("Temperatura EF", "", "");
|
||||
gridDados.Rows.Add("Temperatura DT", "", "");
|
||||
gridDados.Rows.Add("Temperatura DF", "", "");
|
||||
|
||||
AtualizarInformacoesGerais();
|
||||
}
|
||||
|
|
@ -457,7 +462,6 @@ namespace AgroBase.Forms.Operacoes
|
|||
var AB19V = _SensoresCorrente.FirstOrDefault(x => x.ID == "AB19V");
|
||||
var AB24V = _SensoresCorrente.FirstOrDefault(x => x.ID == "AB24V");
|
||||
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
|
||||
var _SensorIMU = Variaveis.OperacaoEmAndamento.DispSen.Dados.DadosLeitura.SensoresIMU.FirstOrDefault();
|
||||
|
||||
gridDados.Rows[0].Cells[1].Value = _Sensoriamento.TempoDecorrido.ToString("HH:mm:ss");
|
||||
gridDados.Rows[1].Cells[1].Value = _Sensoriamento.Movimentacao.TempoMovimento.ToString("HH:mm:ss");
|
||||
|
|
@ -487,12 +491,12 @@ namespace AgroBase.Forms.Operacoes
|
|||
gridDados.Rows[25].Cells[1].Value = _Sensoriamento.Atuador.VazaoMedia.ToString("0.00");
|
||||
gridDados.Rows[26].Cells[1].Value = _Sensoriamento.Atuador.VolumeVazaoMl.ToString("0.00");
|
||||
gridDados.Rows[27].Cells[1].Value = "";
|
||||
gridDados.Rows[28].Cells[1].Value = (_SensorIMU?.Roll ?? 0).ToString("0.00");
|
||||
gridDados.Rows[29].Cells[1].Value = (_SensorIMU?.Pitch ?? 0).ToString("0.00");
|
||||
gridDados.Rows[30].Cells[1].Value = (_SensorIMU?.Yaw ?? 0).ToString("0.00");
|
||||
gridDados.Rows[31].Cells[1].Value = (_SensorIMU?.Temperatura ?? 0).ToString("0.00");
|
||||
gridDados.Rows[32].Cells[1].Value = (_SensorIMU?.Pressao ?? 0).ToString("0.00");
|
||||
gridDados.Rows[33].Cells[1].Value = (_SensorIMU?.Altitude ?? 0).ToString("0.00");
|
||||
gridDados.Rows[28].Cells[1].Value = (_Sensoriamento.IMU.InclinacaoLateral).ToString("0.00");
|
||||
gridDados.Rows[29].Cells[1].Value = (_Sensoriamento.IMU.InclinacaoFrontal).ToString("0.00");
|
||||
gridDados.Rows[30].Cells[1].Value = (_Sensoriamento.IMU.Rotacao).ToString("0.00");
|
||||
gridDados.Rows[31].Cells[1].Value = (_Sensoriamento.IMU.Temperatura).ToString("0.00");
|
||||
gridDados.Rows[32].Cells[1].Value = (_Sensoriamento.IMU.Pressao).ToString("0.00");
|
||||
gridDados.Rows[33].Cells[1].Value = (_Sensoriamento.IMU.Altitude).ToString("0.00");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ namespace AgroBase.Forms
|
|||
AtualizarDadosSensorCorrente("AB36V", lblB36V);
|
||||
}
|
||||
|
||||
lblMagnetometro.ForeColor = (Variaveis.OperacaoEmAndamento.DispSen?.Dados?.DadosLeitura?.SensoresIMU?.DefaultIfEmpty()?.FirstOrDefault()?.Iniciado ?? false) ? Color.Green : Color.Red;
|
||||
lblMagnetometro.ForeColor = Variaveis.OperacaoEmAndamento.Sensoriamento.IMU.Iniciado ? Color.Green : Color.Red;
|
||||
|
||||
var Gps = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps;
|
||||
lblGPS.ForeColor = Gps.Inicializado ? Color.Green : Color.Red;
|
||||
|
|
@ -102,6 +102,8 @@ namespace AgroBase.Forms
|
|||
|
||||
foreach (var Modulo in DispMvd.Dados.Modulos)
|
||||
{
|
||||
var sTMP = Variaveis.OperacaoEmAndamento.DispSen?.Dados?.DadosLeitura?.SensoresTemperatura?.FirstOrDefault(x => x.ID.Contains(Modulo.Modulo_ID));
|
||||
|
||||
Label lblTitulo = pnlFundo.Controls.OfType<Label>().FirstOrDefault(ctrl => ctrl.Name == "lblM_" + Modulo.Modulo_ID);
|
||||
lblTitulo.ForeColor = Modulo.MovMotor.Comandar ? Modulo.MovMotor.Inicializado ? Color.Green : Color.Red : Color.Black;
|
||||
lblTitulo.Text = lblTitulo.Text.Split(' ')[0] + " (" + Modulo.Modulo_ID + ") - Alm: " + Modulo.MovMotor.CodigoAlarme;
|
||||
|
|
@ -117,7 +119,7 @@ namespace AgroBase.Forms
|
|||
lblM_Sentido.Text = "Sentido: " + Enum.GetName(typeof(Sentido), Modulo.MovMotor.Sentido);
|
||||
Label lblM_Temperatura = pnlFundo.Controls.OfType<Label>().FirstOrDefault(ctrl => ctrl.Name == "lbl" + Modulo.Modulo_ID + "M_Temperatura");
|
||||
lblM_Temperatura.Text = "Temperatura: " + Modulo.MovMotor.Temperatura.ToString("0.00") + "ºC";
|
||||
lblM_Temperatura.ForeColor = Modulo.MovMotor.CodigoAlarme > 0 ? Color.Red : Color.Black;
|
||||
lblM_Temperatura.ForeColor = sTMP?.Iniciado ?? false ? Color.Green : Color.Red;
|
||||
Label lblM_Corrente = pnlFundo.Controls.OfType<Label>().FirstOrDefault(ctrl => ctrl.Name == "lbl" + Modulo.Modulo_ID + "M_Corrente");
|
||||
lblM_Corrente.Text = "Corrente: " + Modulo.MovMotor.Corrente_Motor.ToString("0.00") + "A";
|
||||
Label lblM_Tensao = pnlFundo.Controls.OfType<Label>().FirstOrDefault(ctrl => ctrl.Name == "lbl" + Modulo.Modulo_ID + "M_Tensao");
|
||||
|
|
@ -376,16 +378,18 @@ namespace AgroBase.Forms
|
|||
|
||||
private void pnlOrientacaoGPS_Paint(object sender, PaintEventArgs e)
|
||||
{
|
||||
double Angulo = GPSService.UltimaLeitura.OrientacaoReal;
|
||||
double AnguloMovimento = GPSService.UltimaLeitura.OrientacaoReal;
|
||||
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
|
||||
double Angulo = _Sensoriamento.Gps.OrientacaoReal;
|
||||
double AnguloMovimento = _Sensoriamento.Gps.OrientacaoMovimento;
|
||||
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)Angulo, -90, (float)AnguloMovimento);
|
||||
}
|
||||
|
||||
private void pnlOrientacaoMagnetometro_Paint(object sender, PaintEventArgs e)
|
||||
{
|
||||
var Imu = Variaveis.OperacaoEmAndamento.DispSen?.Dados?.DadosLeitura?.SensoresIMU?.DefaultIfEmpty()?.FirstOrDefault();
|
||||
double Angulo = Imu?.Yaw ?? 0;
|
||||
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)Angulo, -90);
|
||||
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
|
||||
double Angulo = _Sensoriamento.IMU.Rotacao;
|
||||
double AnguloCorrigido = _Sensoriamento.IMU.RotacaoCorrigida;
|
||||
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)Angulo, -90, (float)AnguloCorrigido);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -41,22 +41,24 @@ namespace AgroBase.Forms
|
|||
|
||||
private async Task tmrLeitura_Tick()
|
||||
{
|
||||
lblAltitude.Text = "Altitude: " + GPSService.UltimaLeitura.Altitude.ToString("0.0") + " m";
|
||||
lblDatahora.Text = "Ultima Leitura: " + GPSService.UltimaLeitura.DataHora.ToString("HH:mm:ss");
|
||||
txtLatitude.Text = GPSService.UltimaLeitura.Latitude.ToString();
|
||||
txtLongitude.Text = GPSService.UltimaLeitura.Longitude.ToString();
|
||||
lblPrecisaoHorizontal.Text = "Precisão Horizontal: " + GPSService.UltimaLeitura.PrecisaoHorizontal.ToString("0.00");
|
||||
lblPrecisaoCm.Text = "Precisão Leitura: " + GPSService.UltimaLeitura.PrecisaoCm.ToString("0.00") + " cm";
|
||||
lblSatelites.Text = "Satélites Visíveis: " + GPSService.UltimaLeitura.NumeroSatelites.ToString();
|
||||
lblVelocidade.Text = "Velocidade: " + GPSService.UltimaLeitura.Velocidade.ToString("0.00") + " km/h";
|
||||
lblOrientacao.Text = "Orientação: " + GPSService.UltimaLeitura.OrientacaoReal.ToString("0.00") + "º (" + GPSService.UltimaLeitura.OrientacaoMovimento.ToString("0.00") + "º)";
|
||||
lblCursoVerdadeiro.Text = "Curso Verdadeiro: " + GPSService.UltimaLeitura.CursoVerdadeiro.ToString("0.00") + "º";
|
||||
lblVariacaoMagnetica.Text = "Variação Magnética: " + GPSService.UltimaLeitura.VariacaoMagnetica.ToString("0.00") + "º";
|
||||
lblFix.Text = "Correção: " + GPSService.UltimaLeitura.QualidadeFix.ToString();
|
||||
var Gps = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps;
|
||||
|
||||
lblAltitude.Text = "Altitude: " + Gps.Altitude.ToString("0.0") + " m";
|
||||
lblDatahora.Text = "Ultima Leitura: " + Gps.DataHora.ToString("HH:mm:ss");
|
||||
txtLatitude.Text = Gps.Latitude.ToString();
|
||||
txtLongitude.Text = Gps.Longitude.ToString();
|
||||
lblPrecisaoHorizontal.Text = "Precisão Horizontal: " + Gps.PrecisaoHorizontal.ToString("0.00");
|
||||
lblPrecisaoCm.Text = "Precisão Leitura: " + Gps.PrecisaoCm.ToString("0.00") + " cm";
|
||||
lblSatelites.Text = "Satélites Visíveis: " + Gps.NumeroSatelites.ToString();
|
||||
lblVelocidade.Text = "Velocidade: " + Gps.Velocidade.ToString("0.00") + " km/h";
|
||||
lblOrientacao.Text = "Orientação: " + Gps.OrientacaoReal.ToString("0.00") + "º (" + Gps.OrientacaoMovimento.ToString("0.00") + "º)";
|
||||
lblCursoVerdadeiro.Text = "Curso Verdadeiro: " + Gps.CursoVerdadeiro.ToString("0.00") + "º";
|
||||
lblVariacaoMagnetica.Text = "Variação Magnética: " + Gps.VariacaoMagnetica.ToString("0.00") + "º";
|
||||
lblFix.Text = "Correção: " + Gps.QualidadeFix.ToString();
|
||||
|
||||
if (chbSalvar.Checked)
|
||||
{
|
||||
GPSModel leitura = GPSService.UltimaLeitura.Clone();
|
||||
GPSModel leitura = Gps.Clone();
|
||||
|
||||
if (leitura.Distancia >= TrajetoriaMapaOperacaoModel.DistanciaEntrePontos)
|
||||
{
|
||||
|
|
@ -69,7 +71,7 @@ namespace AgroBase.Forms
|
|||
if (GPSService.Iniciado)
|
||||
{
|
||||
int ID = Convert.ToInt32(Variaveis.IsAgroMonitor ? Variaveis.OperacaoEmAndamento.DispSen.Dados.LoRaParametrosBase.address : Variaveis.ConexaoLoRa.parametros.address);
|
||||
GPSService.EnviarCoordenadasParaMapa(GPSService.UltimaLeitura.Latitude, GPSService.UltimaLeitura.Longitude, GPSService.UltimaLeitura.AnguloCarroDefinido, true, ID);
|
||||
GPSService.EnviarCoordenadasParaMapa(Gps.Latitude, Gps.Longitude, Gps.AnguloCarroDefinido, true, ID);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ namespace AgroBase.Forms
|
|||
|
||||
private void btnRegistrarPontos_Click(object sender, EventArgs e)
|
||||
{
|
||||
GPSModel P1 = GPSService.UltimaLeitura.Clone();
|
||||
GPSModel P1 = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.Clone();
|
||||
|
||||
if (Pontos[idxRua].Count == 0)
|
||||
{
|
||||
|
|
@ -127,8 +127,8 @@ namespace AgroBase.Forms
|
|||
{
|
||||
try
|
||||
{
|
||||
double angulo = GPSService.UltimaLeitura.AnguloCarroDefinido;
|
||||
double anguloCorredor = GPSService.UltimaLeitura.OrientacaoMovimento;
|
||||
double angulo = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.AnguloCarroDefinido;
|
||||
double anguloCorredor = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.OrientacaoMovimento;
|
||||
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)angulo, 90, (float)anguloCorredor);
|
||||
}
|
||||
catch { }
|
||||
|
|
@ -177,12 +177,14 @@ namespace AgroBase.Forms
|
|||
ultimoPonto = Pontos[Pontos.Count - 1][Pontos[Pontos.Count - 1].Count - 1];
|
||||
}
|
||||
|
||||
var Gps = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps;
|
||||
|
||||
pnlOrientacaoGps.Invalidate();
|
||||
lblStatusGPS.Text = $"GPS - Precisão: {GPSService.UltimaLeitura.PrecisaoCm} cm, " +
|
||||
$"Coreção: {GPSService.UltimaLeitura.QualidadeFix}, " +
|
||||
$"Satélites: {GPSService.UltimaLeitura.NumeroSatelites}, " +
|
||||
$"Distância: {(!add ? 0 : GPSUtils.DistanciaEntrePontos(ultimoPonto, GPSService.UltimaLeitura) ).ToString("0.00")} m, " +
|
||||
$"Orientação: {(!add ? 0 : GPSUtils.CalcularOrientacao(ultimoPonto, GPSService.UltimaLeitura)).ToString("0.00")}º";
|
||||
lblStatusGPS.Text = $"GPS - Precisão: {Gps.PrecisaoCm} cm, " +
|
||||
$"Coreção: {Gps.QualidadeFix}, " +
|
||||
$"Satélites: {Gps.NumeroSatelites}, " +
|
||||
$"Distância: {(!add ? 0 : GPSUtils.DistanciaEntrePontos(ultimoPonto, Gps) ).ToString("0.00")} m, " +
|
||||
$"Orientação: {(!add ? 0 : GPSUtils.CalcularOrientacao(ultimoPonto, Gps)).ToString("0.00")}º";
|
||||
}
|
||||
|
||||
private void dgRuas_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ namespace AgroBase.Forms
|
|||
|
||||
foreach (var Dispositivo in Dispositivos)
|
||||
{
|
||||
Dispositivo.Funcoes.ForEach(x => Pinos.Add(Dispositivo.ID + " " + Enum.GetName(typeof(FuncoesPinout), x)));
|
||||
Dispositivo.Funcoes?.ForEach(x => Pinos.Add(Dispositivo.ID + " " + Enum.GetName(typeof(FuncoesPinout), x)));
|
||||
}
|
||||
|
||||
List<ComboBox> cmbs = this.Controls.OfType<ComboBox>().Where(x => x.Name.Contains("cmb")).ToList();
|
||||
|
|
|
|||
|
|
@ -59,11 +59,11 @@ namespace AgroBase.Forms
|
|||
|
||||
private async Task tmrLeitura_Tick()
|
||||
{
|
||||
var Imu = Variaveis.OperacaoEmAndamento.DispSen?.Dados?.DadosLeitura?.SensoresIMU?.FirstOrDefault();
|
||||
AnguloX = Imu?.Roll ?? 0;
|
||||
AnguloY = Imu?.Pitch ?? 0;
|
||||
AnguloZ = Imu?.Yaw ?? 0;
|
||||
OrientacaoMagnetica = Imu?.YawFixed ?? 0;
|
||||
var Imu = Variaveis.OperacaoEmAndamento.Sensoriamento.IMU;
|
||||
AnguloX = Imu.InclinacaoLateral;
|
||||
AnguloY = Imu.InclinacaoFrontal;
|
||||
AnguloZ = Imu.Rotacao;
|
||||
OrientacaoMagnetica = Imu.RotacaoCorrigida;
|
||||
|
||||
AtualizarDadosTela();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -332,7 +332,7 @@ namespace AgroBase.Models
|
|||
|
||||
private void DrawObstacle(Graphics g, float xRobot, float yRobot, Color pointColor, Color borderColor, float angle, Obstaculo obstaculo, float PxToCm)
|
||||
{
|
||||
GPSModel posicaoRobo = GPSService.UltimaLeitura;
|
||||
GPSModel posicaoRobo = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps;
|
||||
GPSModel posicaoObstaculo = GPSUtils.GerarPontoDeslocado(posicaoRobo, angle, obstaculo.DistanciaMedia_mm / 1000);
|
||||
|
||||
float x = xRobot + (float)((posicaoObstaculo.Longitude - posicaoRobo.Longitude) * _zoom);
|
||||
|
|
|
|||
|
|
@ -2342,6 +2342,7 @@ namespace AgroBase.Models.Modules
|
|||
case S_Code.sTMP:
|
||||
{
|
||||
double temperatura = ConverterByteParaDouble(data, 2);
|
||||
Console.WriteLine("temperatura ET: " + temperatura);
|
||||
DefinirOuCriar(ID_Num, posicao, componente, new List<dynamic>() { temperatura });
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2984,6 +2984,7 @@ namespace AgroBase.Models
|
|||
return new DateTime().AddSeconds(TempoDecorridoSeg);
|
||||
}
|
||||
}
|
||||
public OperacaoSensoriamentoLogImuModel IMU { get; set; }
|
||||
public OperacaoSensoriamentoLogAtuModel Atuador { get; set; }
|
||||
public OperacaoSensoriamentoLogMvdModel Movimentacao { get; set; }
|
||||
public OperacaoSensoriamentoLogBateriaModel Bateria { get; set; }
|
||||
|
|
@ -3002,6 +3003,8 @@ namespace AgroBase.Models
|
|||
var _DispSen = Variaveis.OperacaoEmAndamento.DispSen;
|
||||
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
|
||||
|
||||
_DispMvd?.Dados?.Modulos?.ForEach(x => x.AtualizarSensoresMotor());
|
||||
|
||||
Variaveis.OperacaoEmAndamento.AtualizarDispositiviosIndividuaisConectados();
|
||||
Variaveis.OperacaoEmAndamento.AtualizarModulosConectados();
|
||||
Variaveis.OperacaoEmAndamento.AtualizarOperacaoLiberada();
|
||||
|
|
@ -3019,6 +3022,19 @@ namespace AgroBase.Models
|
|||
? _DispAtu.Dados.VolumeVazaoML / totalAtuacoes
|
||||
: 0.0;
|
||||
|
||||
var sIMU = _DispSen?.Dados?.DadosLeitura?.SensoresIMU?.FirstOrDefault();
|
||||
var dadosIMU = sIMU != null ? new OperacaoSensoriamentoLogImuModel()
|
||||
{
|
||||
Iniciado = sIMU.Iniciado,
|
||||
InclinacaoLateral = sIMU.Roll,
|
||||
InclinacaoFrontal = sIMU.Pitch,
|
||||
Rotacao = sIMU.Yaw,
|
||||
RotacaoCorrigida = sIMU.YawFixed,
|
||||
Altitude = sIMU.Altitude,
|
||||
Pressao = sIMU.Pressao,
|
||||
Temperatura = sIMU.Temperatura
|
||||
} : new OperacaoSensoriamentoLogImuModel();
|
||||
|
||||
var dadosAtuador = _DispAtu != null ? new OperacaoSensoriamentoLogAtuModel()
|
||||
{
|
||||
HerbicidaConsumido = _DispAtu.Dados.VolumeVazaoML,
|
||||
|
|
@ -3048,6 +3064,7 @@ namespace AgroBase.Models
|
|||
var S36V = _DispSen?.Dados?.DadosLeitura?.SensoresCorrente?.FirstOrDefault(x => x.ID == "AB36V");
|
||||
var dadosBateria = S36V != null ? new OperacaoSensoriamentoLogBateriaModel()
|
||||
{
|
||||
Iniciado = S36V?.Iniciado ?? false,
|
||||
_dt = S36V?._dt ?? 0,
|
||||
PorcentagemBateria = FuncoesMatematicas.Clamp(_DispSen.Dados.ContadorCarga.PercentualBateria, 0, 100),
|
||||
BateriaConsumida = FuncoesMatematicas.Clamp(_DispSen.Dados.ContadorCarga.PercentualConsumido, 0, 100),
|
||||
|
|
@ -3107,6 +3124,7 @@ namespace AgroBase.Models
|
|||
DataInicio = Variaveis.OperacaoEmAndamento.DataInicio,
|
||||
DataFim = Variaveis.OperacaoEmAndamento.DataFim,
|
||||
TempoDecorridoSeg = Variaveis.OperacaoEmAndamento.TempoDecorridoSegs,
|
||||
IMU = dadosIMU,
|
||||
Atuador = dadosAtuador,
|
||||
Movimentacao = dadosMovimentacao,
|
||||
Bateria = dadosBateria,
|
||||
|
|
@ -3143,6 +3161,18 @@ namespace AgroBase.Models
|
|||
}
|
||||
}
|
||||
|
||||
public class OperacaoSensoriamentoLogImuModel
|
||||
{
|
||||
public bool Iniciado { get; set; }
|
||||
public double InclinacaoLateral { get; set; }
|
||||
public double InclinacaoFrontal { get; set; }
|
||||
public double Rotacao { get; set; }
|
||||
public double RotacaoCorrigida { get; set; }
|
||||
public double Temperatura { get; set; }
|
||||
public double Pressao { get; set; }
|
||||
public double Altitude { get; set; }
|
||||
}
|
||||
|
||||
public class OperacaoSensoriamentoLogAtuModel
|
||||
{
|
||||
public double HerbicidaConsumido { get; set;}
|
||||
|
|
@ -3222,6 +3252,7 @@ namespace AgroBase.Models
|
|||
|
||||
public class OperacaoSensoriamentoLogBateriaModel
|
||||
{
|
||||
public bool Iniciado { get; set; }
|
||||
public double _dt { get; set; }
|
||||
public double PorcentagemBateria { get; set; }
|
||||
public double BateriaConsumida { get; set; }
|
||||
|
|
|
|||
|
|
@ -775,12 +775,12 @@ namespace AgroBase.Models
|
|||
// Supondo que a distância seja em metros e utilizando uma aproximação simples da Terra como esfera
|
||||
// para converter distância e ângulo em mudança de latitude/longitude.
|
||||
double deltaLatitude = (DistanciaMedia * Math.Cos(anguloRad)) / 111111; // Dividindo por 111111 para converter metros em graus
|
||||
double deltaLongitude = (DistanciaMedia * Math.Sin(anguloRad)) / (111111 * Math.Cos(GPSService.UltimaLeitura.Latitude * (Math.PI / 180.0)));
|
||||
double deltaLongitude = (DistanciaMedia * Math.Sin(anguloRad)) / (111111 * Math.Cos(Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.Latitude * (Math.PI / 180.0)));
|
||||
|
||||
return new GPSModel
|
||||
{
|
||||
Latitude = GPSService.UltimaLeitura.Latitude + deltaLatitude,
|
||||
Longitude = GPSService.UltimaLeitura.Longitude + deltaLongitude
|
||||
Latitude = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.Latitude + deltaLatitude,
|
||||
Longitude = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.Longitude + deltaLongitude
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,9 +32,9 @@ namespace AgroBase.Models
|
|||
public double TempoEntreLeituras { get; private set; }
|
||||
private void AtualizarTempoEntreLeituras()
|
||||
{
|
||||
double dt = Math.Min((1.0 / GPSService.TaxaAmostragemHz), (UltimaAtualizacaoDados - GPSService.UltimaLeitura.Momento).TotalSeconds);
|
||||
double dt = Math.Min((1.0 / GPSService.TaxaAmostragemHz), (UltimaAtualizacaoDados - Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.Momento).TotalSeconds);
|
||||
TempoEntreLeituras = dt;
|
||||
UltimaAtualizacaoDados = GPSService.UltimaLeitura.Momento;
|
||||
UltimaAtualizacaoDados = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.Momento;
|
||||
}
|
||||
|
||||
public List<List<GPSModel>> RuasPlantacao { get; set; }
|
||||
|
|
@ -77,8 +77,8 @@ namespace AgroBase.Models
|
|||
{
|
||||
get
|
||||
{
|
||||
double distPP = GPSUtils.DistanciaEntrePontos(GPSService.UltimaLeitura, PrimeiroPontoRuaMapa);
|
||||
double distUP = GPSUtils.DistanciaEntrePontos(GPSService.UltimaLeitura, UltimoPontoRuaMapa);
|
||||
double distPP = GPSUtils.DistanciaEntrePontos(Variaveis.OperacaoEmAndamento.Sensoriamento.Gps, PrimeiroPontoRuaMapa);
|
||||
double distUP = GPSUtils.DistanciaEntrePontos(Variaveis.OperacaoEmAndamento.Sensoriamento.Gps, UltimoPontoRuaMapa);
|
||||
|
||||
// 0 para mais próximo do primeiro ponto da rua (ENTRANDO)
|
||||
// 1 para mais próximo do último ponto da rua (SAINDO)
|
||||
|
|
@ -118,7 +118,7 @@ namespace AgroBase.Models
|
|||
{
|
||||
new PontoTrajetoriaModel(TipoPontoRua.PosicaoRobo)
|
||||
{
|
||||
Posicao = GPSService.UltimaLeitura,
|
||||
Posicao = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps,
|
||||
LarguraCorredor = 1.0,
|
||||
idxCorredor = CorredorAtual?.Idx ?? 0,
|
||||
Visitado = true
|
||||
|
|
@ -209,7 +209,7 @@ namespace AgroBase.Models
|
|||
private void AtualizarAnguloCaminho()
|
||||
{
|
||||
PontoTrajetoriaModel pontoComparar = PontoAtual.Aproximando ? PontoAtual : ProximoPonto != null ? ProximoPonto : PontoAtual;
|
||||
AnguloCaminho = GPSUtils.CalcularOrientacao(GPSService.UltimaLeitura, pontoComparar.Posicao);
|
||||
AnguloCaminho = GPSUtils.CalcularOrientacao(Variaveis.OperacaoEmAndamento.Sensoriamento.Gps, pontoComparar.Posicao);
|
||||
}
|
||||
[JsonProperty]
|
||||
public double DistanciaEsquerda { get; private set; }
|
||||
|
|
@ -217,8 +217,8 @@ namespace AgroBase.Models
|
|||
public double DistanciaDireita { get; private set; }
|
||||
private void AtualizarDistanciasLaterais()
|
||||
{
|
||||
DistanciaEsquerda = CalcularDistanciaLateral(true, GPSService.UltimaLeitura, CorredorAtual?.idxRuaEsquerda ?? 0, PontoAtual?.Direcao ?? DirecaoCarroRua.Ida);
|
||||
DistanciaDireita = CalcularDistanciaLateral(false, GPSService.UltimaLeitura, CorredorAtual?.idxRuaDireita ?? 0, PontoAtual?.Direcao ?? DirecaoCarroRua.Ida);
|
||||
DistanciaEsquerda = CalcularDistanciaLateral(true, Variaveis.OperacaoEmAndamento.Sensoriamento.Gps, CorredorAtual?.idxRuaEsquerda ?? 0, PontoAtual?.Direcao ?? DirecaoCarroRua.Ida);
|
||||
DistanciaDireita = CalcularDistanciaLateral(false, Variaveis.OperacaoEmAndamento.Sensoriamento.Gps, CorredorAtual?.idxRuaDireita ?? 0, PontoAtual?.Direcao ?? DirecaoCarroRua.Ida);
|
||||
}
|
||||
|
||||
public double CalcularDistanciaLateral(bool ladoEsquerdo, GPSModel posicaoAtual, int idxRua, DirecaoCarroRua direcaoAtual)
|
||||
|
|
@ -875,7 +875,7 @@ namespace AgroBase.Models
|
|||
idxCorredor = 0,
|
||||
idxPonto = 0,
|
||||
idxPontoCorredor = 0,
|
||||
Posicao = GPSService.UltimaLeitura,
|
||||
Posicao = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps,
|
||||
Direcao = direcaoAtual,
|
||||
Orientacao = 0,
|
||||
Visitado = true,
|
||||
|
|
@ -1151,7 +1151,7 @@ namespace AgroBase.Models
|
|||
|
||||
public void AjustarTrajetoriaParaDesvio(Obstaculo obstaculo)
|
||||
{
|
||||
GPSModel posicaoAtual = GPSService.UltimaLeitura;
|
||||
GPSModel posicaoAtual = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps;
|
||||
|
||||
double distanciaObstaculo = ((double)obstaculo.DistanciaMedia_mm / 1000);
|
||||
double larguraObstaculo = ((double)obstaculo.Largura_mm / 1000);
|
||||
|
|
@ -1392,7 +1392,7 @@ namespace AgroBase.Models
|
|||
|
||||
private void AtualizarOrientacaoAtual()
|
||||
{
|
||||
OrientacaoAtual = GPSUtils.CalcularOrientacao(GPSService.UltimaLeitura, Posicao);
|
||||
OrientacaoAtual = GPSUtils.CalcularOrientacao(Variaveis.OperacaoEmAndamento.Sensoriamento.Gps, Posicao);
|
||||
}
|
||||
|
||||
private void AtualizarOrientacaoAnterior()
|
||||
|
|
@ -1446,7 +1446,7 @@ namespace AgroBase.Models
|
|||
|
||||
private void AtualizarDistanciaAtual()
|
||||
{
|
||||
DistanciaAtual = GPSUtils.DistanciaEntrePontos(GPSService.UltimaLeitura, Posicao);
|
||||
DistanciaAtual = GPSUtils.DistanciaEntrePontos(Variaveis.OperacaoEmAndamento.Sensoriamento.Gps, Posicao);
|
||||
}
|
||||
|
||||
private void AtualizarDistanciaAnterior()
|
||||
|
|
|
|||
|
|
@ -716,10 +716,13 @@ namespace AgroBase.Services
|
|||
{
|
||||
double anguloFinal = 0.0;
|
||||
|
||||
bool witIniciado = Variaveis.OperacaoEmAndamento.DispSen.Dados?.DadosLeitura?.SensoresIMU?.FirstOrDefault()?.Iniciado ?? false;
|
||||
bool imuIniciado = Variaveis.OperacaoEmAndamento.Sensoriamento.IMU.Iniciado;
|
||||
bool gpsIniciado = Iniciado;
|
||||
|
||||
Variaveis.OperacaoEmAndamento.DispSen.Dados?.DadosLeitura?.SensoresIMU?.FirstOrDefault()?.AtualizarOffset(UltimaLeitura);
|
||||
if (imuIniciado)
|
||||
{
|
||||
Variaveis.OperacaoEmAndamento.DispSen.Dados?.DadosLeitura?.SensoresIMU?.FirstOrDefault()?.AtualizarOffset(UltimaLeitura);
|
||||
}
|
||||
|
||||
if (gpsIniciado)
|
||||
{
|
||||
|
|
@ -735,10 +738,10 @@ namespace AgroBase.Services
|
|||
|
||||
anguloFinal = anguloGPS;
|
||||
}
|
||||
else if (witIniciado)
|
||||
else if (imuIniciado)
|
||||
{
|
||||
// Apenas o WT901C está disponível
|
||||
anguloFinal = Variaveis.OperacaoEmAndamento.DispSen.Dados?.DadosLeitura?.SensoresIMU?.FirstOrDefault()?.YawFixed ?? -1;
|
||||
anguloFinal = Variaveis.OperacaoEmAndamento.Sensoriamento.IMU.RotacaoCorrigida;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -796,7 +796,7 @@ namespace AgroBase.Services
|
|||
{
|
||||
if (Iniciado && !Variaveis.IsAgroMonitor)
|
||||
{
|
||||
double TemperaturaCampo = Variaveis.OperacaoEmAndamento.DispSen.Dados?.DadosLeitura?.SensoresIMU?.FirstOrDefault()?.Temperatura ?? -1;
|
||||
double TemperaturaCampo = Variaveis.OperacaoEmAndamento.Sensoriamento.IMU.Temperatura;
|
||||
|
||||
(bool dirOperante, List<string> dirModsFalha) = Variaveis.OperacaoEmAndamento.DispMvd.Dados.StatusModulosDIR(Variaveis.OperacaoEmAndamento.Controle.TipoMovimento);
|
||||
(bool movEsqOperante, List<string> movEsqModsFalha) = Variaveis.OperacaoEmAndamento.DispMvd.Dados.StatusModulosMOV(Direcao.Esquerda);
|
||||
|
|
@ -821,8 +821,8 @@ namespace AgroBase.Services
|
|||
},
|
||||
Coordenadas = new LoRaProtocoloTransmissaoCoordenadasModel()
|
||||
{
|
||||
Latitude = GPSService.UltimaLeitura.Latitude,
|
||||
Longitude = GPSService.UltimaLeitura.Longitude,
|
||||
Latitude = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.Latitude,
|
||||
Longitude = Variaveis.OperacaoEmAndamento.Sensoriamento.Gps.Longitude,
|
||||
},
|
||||
Sensores = new LoRaProtocoloTransmissaoSensoresModel()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ namespace AgroBase.Services
|
|||
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>();
|
||||
private static Dictionary<string, int> TentativasPortas = new Dictionary<string, int>();
|
||||
private static bool VarreduraEmAndamento = false;
|
||||
|
||||
|
||||
|
|
@ -243,7 +242,7 @@ namespace AgroBase.Services
|
|||
}
|
||||
}
|
||||
|
||||
if (!ModbusService.Iniciado)
|
||||
/*if (!ModbusService.Iniciado)
|
||||
{
|
||||
AtualizarConsole($"{PortaCom} - Procurando dispositivos no barramento RS485");
|
||||
bool DispModbus = await ProcuraDispositivoModbus(_Porta);
|
||||
|
|
@ -253,7 +252,7 @@ namespace AgroBase.Services
|
|||
AtualizarConsole("Barramento RS485 encontrado");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
@ -280,7 +279,7 @@ namespace AgroBase.Services
|
|||
await ProcurarDispositivosEthernet();
|
||||
}
|
||||
|
||||
if (ModbusService.Iniciado)
|
||||
/*if (ModbusService.Iniciado)
|
||||
{
|
||||
await ProcuraDispositivoModbus(ModbusService._PortaModbus);
|
||||
}
|
||||
|
|
@ -291,7 +290,7 @@ namespace AgroBase.Services
|
|||
{
|
||||
DispositivosMapeados.Remove(DispositivosMapeados.FirstOrDefault(x => x.Dispositivo == _Disp));
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
if (CanService.Iniciado)
|
||||
{
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
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
|
|
@ -25,7 +25,7 @@
|
|||
<meta name="viewport" content="width=device-width,
|
||||
initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<style>
|
||||
#map_82b7108ea8cddae8bf3da5e9af968baa {
|
||||
#map_0a65390b914a9d20a49b9ea06134c652 {
|
||||
position: relative;
|
||||
width: 100.0%;
|
||||
height: 100.0%;
|
||||
|
|
@ -39,14 +39,14 @@
|
|||
<body>
|
||||
|
||||
|
||||
<div class="folium-map" id="map_82b7108ea8cddae8bf3da5e9af968baa" ></div>
|
||||
<div class="folium-map" id="map_0a65390b914a9d20a49b9ea06134c652" ></div>
|
||||
|
||||
</body>
|
||||
<script>
|
||||
|
||||
|
||||
var map_82b7108ea8cddae8bf3da5e9af968baa = L.map(
|
||||
"map_82b7108ea8cddae8bf3da5e9af968baa",
|
||||
var map_0a65390b914a9d20a49b9ea06134c652 = L.map(
|
||||
"map_0a65390b914a9d20a49b9ea06134c652",
|
||||
{
|
||||
center: [0.0, 0.0],
|
||||
crs: L.CRS.EPSG3857,
|
||||
|
|
@ -60,13 +60,13 @@
|
|||
|
||||
|
||||
|
||||
var tile_layer_605bd35e89ca1ea18b377645f630a519 = L.tileLayer(
|
||||
var tile_layer_46f299708219af4df3a972d14ad0e238 = 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_605bd35e89ca1ea18b377645f630a519.addTo(map_82b7108ea8cddae8bf3da5e9af968baa);
|
||||
tile_layer_46f299708219af4df3a972d14ad0e238.addTo(map_0a65390b914a9d20a49b9ea06134c652);
|
||||
|
||||
</script>
|
||||
|
||||
|
|
@ -87,7 +87,7 @@
|
|||
}
|
||||
trajeto_json_add({"features": []});
|
||||
|
||||
trajeto_json.addTo(map_82b7108ea8cddae8bf3da5e9af968baa);
|
||||
trajeto_json.addTo(map_0a65390b914a9d20a49b9ea06134c652);
|
||||
|
||||
function adicionarGeometria(novaGeometria) {
|
||||
trajeto_json.addData(novaGeometria);
|
||||
|
|
@ -145,7 +145,7 @@
|
|||
|
||||
var marcadorDinamico = L.marker([0, 0], {
|
||||
icon: customIcon
|
||||
}).addTo(map_82b7108ea8cddae8bf3da5e9af968baa);
|
||||
}).addTo(map_0a65390b914a9d20a49b9ea06134c652);
|
||||
|
||||
// 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_82b7108ea8cddae8bf3da5e9af968baa.setView(novaPosicao, map_82b7108ea8cddae8bf3da5e9af968baa.getZoom());
|
||||
map_0a65390b914a9d20a49b9ea06134c652.setView(novaPosicao, map_0a65390b914a9d20a49b9ea06134c652.getZoom());
|
||||
});
|
||||
|
||||
function calcularOrientacao(P1latitude, P1longitude, P2latitude, P2longitude) {
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -6,6 +6,7 @@
|
|||
#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\I2CService.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\ReleModel.h"
|
||||
|
|
@ -34,10 +35,6 @@ int latenciaLoop = 0;
|
|||
int qtdEnviosStatus = 0;
|
||||
int maxEnviosStatus = 5;
|
||||
|
||||
PinoModel _pinoSDA = PinoModel(1, CONTROLADOR, _INPUT);
|
||||
PinoModel _pinoSCL = PinoModel(2, CONTROLADOR, _INPUT);
|
||||
|
||||
|
||||
std::vector<Rele*> listaBicos;
|
||||
std::vector<BombaPressurizadora*> listaBombas;
|
||||
std::vector<SensorFluxo*> listaSensoresFluxo;
|
||||
|
|
@ -221,11 +218,8 @@ void ProcessarCfg(std::vector<uint8_t> data) {
|
|||
int pinoSDA = data[4];
|
||||
int pinoSCL = data[5];
|
||||
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));
|
||||
I2CService::DefinirPinos(pinoSDA, pinoSCL);
|
||||
I2CService::IniciarI2C();
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
Conectado = Conectar;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,292 @@
|
|||
#ifndef MuxService_h
|
||||
#define MuxService_h
|
||||
|
||||
#include "SerialService.h"
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_MCP23X17.h>
|
||||
#include <Adafruit_ADS1X15.h>
|
||||
#include <freertos/semphr.h>
|
||||
|
||||
class I2CService {
|
||||
public:
|
||||
static const constexpr uint8_t enderecoMux = 0x70;
|
||||
static const constexpr uint8_t enderecoMcp = 0x20;
|
||||
static const constexpr uint8_t enderecoAds = 0x48;
|
||||
static bool I2CIniciado;
|
||||
static bool MuxIniciado;
|
||||
static bool McpIniciado;
|
||||
static bool AdsIniciado;
|
||||
static int canalAtivo;
|
||||
static int idAtualUsandoI2C;
|
||||
|
||||
static Adafruit_MCP23X17 mcp;
|
||||
static Adafruit_ADS1115 ads;
|
||||
|
||||
static SemaphoreHandle_t i2cMutex;
|
||||
|
||||
static void DefinirPinos(int sda, int scl) {
|
||||
_pinoSDA = sda;
|
||||
_pinoSCL = scl;
|
||||
}
|
||||
|
||||
static bool IniciarI2C() {
|
||||
if (I2CIniciado) {
|
||||
Wire.end();
|
||||
delay(10);
|
||||
}
|
||||
I2CIniciado = Wire.begin(_pinoSDA, _pinoSCL);
|
||||
//Wire.setTimeout(50);
|
||||
PrintTela("[I2C] I2C inicializado nos pinos SDA=" + String(_pinoSDA) + " e SCL=" + String(_pinoSCL) + " - Res " + I2CIniciado);
|
||||
if (i2cMutex == nullptr) {
|
||||
i2cMutex = xSemaphoreCreateMutex();
|
||||
}
|
||||
idAtualUsandoI2C = -1;
|
||||
tempoEntradaI2C = 0;
|
||||
return I2CIniciado;
|
||||
}
|
||||
|
||||
static bool VerificaEnderecoBarramento(byte _Endereco, uint32_t timeoutMs = 50) {
|
||||
if (!I2CIniciado) return false;
|
||||
|
||||
//Wire.setTimeout(timeoutMs);
|
||||
unsigned long t0 = millis();
|
||||
|
||||
Wire.beginTransmission(_Endereco);
|
||||
byte error = Wire.endTransmission();
|
||||
|
||||
if ((millis() - t0) > timeoutMs) {
|
||||
PrintTela("[I2C] Timeout verificando endereco " + String(_Endereco));
|
||||
return false;
|
||||
}
|
||||
|
||||
return error == 0;
|
||||
}
|
||||
|
||||
static bool SolicitarAcessoI2C(int idSensor = 0, int canalMux = -1, uint32_t timeoutMs = 200) {
|
||||
if (!I2CIniciado) {
|
||||
PrintTela("[I2C] Solicitacao de acesso negada para o sensor " + String(idSensor) + " - I2C Nao inicializado");
|
||||
return false;
|
||||
}
|
||||
|
||||
TickType_t timeoutTicks = pdMS_TO_TICKS(timeoutMs);
|
||||
if (xSemaphoreTake(i2cMutex, timeoutTicks) != pdTRUE) {
|
||||
PrintTela("[I2C] Timeout ao tentar acessar o I2C - ID: " + String(idSensor));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Troca canal se necessário
|
||||
if (canalMux >= 0 && !TrocarCanalMux(canalMux)) {
|
||||
xSemaphoreGive(i2cMutex); // Libera caso a troca de canal falhe
|
||||
return false;
|
||||
}
|
||||
|
||||
idAtualUsandoI2C = idSensor;
|
||||
tempoEntradaI2C = millis();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void LiberarAcessoI2C(int idSensor = 0) {
|
||||
if (idSensor == idAtualUsandoI2C) {
|
||||
idAtualUsandoI2C = -1;
|
||||
xSemaphoreGive(i2cMutex);
|
||||
}
|
||||
}
|
||||
|
||||
static int QuemEstaUsando() {
|
||||
return idAtualUsandoI2C;
|
||||
}
|
||||
|
||||
static void VerificarI2CPreso() {
|
||||
if (idAtualUsandoI2C >= 0 && (millis() - tempoEntradaI2C > LimiteTempoI2C)) {
|
||||
PrintTela("[I2C] Semáforo preso pelo ID %d — forçando liberação!\n", idAtualUsandoI2C);
|
||||
LiberarAcessoI2C(idAtualUsandoI2C);
|
||||
IniciarI2C();
|
||||
}
|
||||
}
|
||||
|
||||
static bool LeituraSegura(uint8_t addr, uint8_t* buffer, size_t qtd, uint8_t reg = 0xFF, uint32_t timeoutMs = 50) {
|
||||
//Wire.setTimeout(timeoutMs);
|
||||
unsigned long t0 = millis();
|
||||
|
||||
if (reg != 0xFF) {
|
||||
Wire.beginTransmission(addr);
|
||||
Wire.write(reg);
|
||||
if (Wire.endTransmission(false) != 0) {
|
||||
PrintTela("[I2C] Falha ao endTransmission (leitura)");
|
||||
return false;
|
||||
}
|
||||
delay(1); // <----- ADICIONAR este delay aqui
|
||||
}
|
||||
|
||||
size_t received = Wire.requestFrom((int)addr, (int)qtd);
|
||||
if (received != qtd || (millis() - t0) > timeoutMs) {
|
||||
PrintTela("[I2C] Timeout ou leitura incompleta");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < qtd; i++) {
|
||||
if (Wire.available()) {
|
||||
buffer[i] = Wire.read();
|
||||
} else {
|
||||
PrintTela("[I2C] Dados insuficientes disponíveis");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool EscritaSegura(uint8_t addr, const uint8_t* dados, size_t qtd, uint32_t timeoutMs = 50) {
|
||||
//Wire.setTimeout(timeoutMs);
|
||||
unsigned long t0 = millis();
|
||||
|
||||
Wire.beginTransmission(addr);
|
||||
for (size_t i = 0; i < qtd; i++) {
|
||||
Wire.write(dados[i]);
|
||||
}
|
||||
|
||||
int resultado = Wire.endTransmission();
|
||||
if ((millis() - t0) > timeoutMs || resultado != 0) {
|
||||
PrintTela("[I2C] Falha na escrita ou timeout");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool TrocarCanalMux(int canalMux) {
|
||||
if (MuxIniciado && canalMux >= 0 && canalMux < 9) {
|
||||
if (canalMux != canalAtivo) {
|
||||
Wire.beginTransmission(enderecoMux);
|
||||
Wire.write(1 << canalMux);
|
||||
Wire.endTransmission();
|
||||
PrintTela("[MUX] Canal alterado de " + String(canalAtivo) + " para " + String(canalMux));
|
||||
canalAtivo = canalMux;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
PrintTela("[MUX] Nao foi possivel trocar o canal para " + String(canalMux));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static void IniciarMUX(byte endereco = enderecoMux, bool Mandatorio = false) {
|
||||
if (!I2CIniciado) {
|
||||
PrintTela("[MUX] Impossivel iniciar TCA9548A, I2C nao iniciado!");
|
||||
return;
|
||||
}
|
||||
PrintTela("[MUX] Iniciando TCA9548A...");
|
||||
if (!MuxIniciado) {
|
||||
SolicitarAcessoI2C();
|
||||
Wire.beginTransmission(endereco);
|
||||
MuxIniciado = (Wire.endTransmission() == 0);
|
||||
if (!MuxIniciado) {
|
||||
PrintTela("[MUX] TCA9548A nao Iniciado, endereco " + String(endereco) + " nao encontrado no barramento");
|
||||
if (Mandatorio) {
|
||||
PrintTela("[MUX] Conexão obrigatória, tentando novamente em 5 segundos...");
|
||||
delay(5000);
|
||||
IniciarMUX(endereco, Mandatorio);
|
||||
}
|
||||
else {
|
||||
PrintTela("[MUX] TCA9548A nao mandatorio, continuando o fluxo...");
|
||||
}
|
||||
}
|
||||
else {
|
||||
canalAtivo = -1; // Nenhum canal ativo ainda
|
||||
idAtualUsandoI2C = -1;
|
||||
i2cMutex = xSemaphoreCreateMutex();
|
||||
PrintTela("[MUX] TCA9548A Iniciado");
|
||||
}
|
||||
LiberarAcessoI2C();
|
||||
}
|
||||
else {
|
||||
PrintTela("[MUX] TCA9548A ja Iniciado");
|
||||
}
|
||||
}
|
||||
|
||||
static void IniciarMCP(byte endereco = enderecoMcp, bool Mandatorio = false) {
|
||||
if (!I2CIniciado) {
|
||||
PrintTela("[MCP] Impossivel iniciar MCP23X17, I2C nao iniciado!");
|
||||
return;
|
||||
}
|
||||
PrintTela("[MCP] Iniciando MCP23X17...");
|
||||
if (!McpIniciado) {
|
||||
SolicitarAcessoI2C();
|
||||
McpIniciado = mcp.begin_I2C(endereco, &Wire);
|
||||
if (!McpIniciado) {
|
||||
PrintTela("[MCP] Erro ao iniciar MCP23X17!");
|
||||
if (Mandatorio) {
|
||||
PrintTela("[MCP] Conexão obrigatória, tentando novamente em 5 segundos...");
|
||||
delay(5000);
|
||||
IniciarMCP(endereco, Mandatorio);
|
||||
}
|
||||
else {
|
||||
PrintTela("[MCP] MCP23X17 nao mandatorio, continuando o fluxo...");
|
||||
}
|
||||
}
|
||||
else {
|
||||
PrintTela("[MCP] MCP23X17 Iniciado");
|
||||
}
|
||||
LiberarAcessoI2C();
|
||||
}
|
||||
else {
|
||||
PrintTela("[MCP] MCP23X17 ja Iniciado");
|
||||
}
|
||||
}
|
||||
|
||||
static void IniciarADS(byte endereco = enderecoAds, bool Mandatorio = false) {
|
||||
if (!I2CIniciado) {
|
||||
PrintTela("[ADS] Impossivel iniciar ADS1115, I2C nao iniciado!");
|
||||
return;
|
||||
}
|
||||
PrintTela("[ADS] Iniciando ADS1115...");
|
||||
if (!AdsIniciado) {
|
||||
SolicitarAcessoI2C();
|
||||
AdsIniciado = ads.begin(endereco, &Wire);
|
||||
if (!AdsIniciado) {
|
||||
PrintTela("[ADS] Erro ao iniciar ADS1115!");
|
||||
if (Mandatorio) {
|
||||
PrintTela("[ADS] Conexão obrigatória, tentando novamente em 5 segundos...");
|
||||
delay(5000);
|
||||
IniciarADS(endereco, Mandatorio);
|
||||
}
|
||||
else {
|
||||
PrintTela("[ADS] ADS1115 nao mandatorio, continuando o fluxo...");
|
||||
}
|
||||
}
|
||||
else {
|
||||
ads.setGain(GAIN_ONE);
|
||||
PrintTela("[ADS] ADS1115 Iniciado");
|
||||
}
|
||||
LiberarAcessoI2C();
|
||||
}
|
||||
else {
|
||||
PrintTela("[ADS] ADS1115 ja Iniciado");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
static int _pinoSDA;
|
||||
static int _pinoSCL;
|
||||
static unsigned long tempoEntradaI2C;
|
||||
static unsigned long LimiteTempoI2C;
|
||||
|
||||
};
|
||||
|
||||
int I2CService::_pinoSDA = 1;
|
||||
int I2CService::_pinoSCL = 2;
|
||||
unsigned long I2CService::LimiteTempoI2C = 100;
|
||||
bool I2CService::I2CIniciado = false;
|
||||
bool I2CService::MuxIniciado = false;
|
||||
bool I2CService::McpIniciado = false;
|
||||
Adafruit_MCP23X17 I2CService::mcp;
|
||||
Adafruit_ADS1115 I2CService::ads;
|
||||
bool I2CService::AdsIniciado = false;
|
||||
int I2CService::canalAtivo = -1;
|
||||
int I2CService::idAtualUsandoI2C = -1;
|
||||
unsigned long I2CService::tempoEntradaI2C = 0;
|
||||
SemaphoreHandle_t I2CService::i2cMutex = nullptr;
|
||||
|
||||
#endif
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
#ifndef MuxService_h
|
||||
#define MuxService_h
|
||||
|
||||
#include "SerialService.h"
|
||||
#include <Wire.h>
|
||||
|
||||
class MuxService {
|
||||
public:
|
||||
static const uint8_t enderecoMux = 0x70; // Padrão do TCA9548A
|
||||
static bool Iniciado;
|
||||
static int canalAtivo;
|
||||
|
||||
static void IniciarMUX() {
|
||||
PrintTela("[MUX] Iniciando TCA9548A...");
|
||||
Wire.beginTransmission(enderecoMux);
|
||||
Iniciado = (Wire.endTransmission() == 0);
|
||||
if (Iniciado) {
|
||||
canalAtivo = -1; // Nenhum canal ativo ainda
|
||||
PrintTela("[MUX] TCA9548A Iniciado");
|
||||
}
|
||||
else {
|
||||
PrintTela("[MUX] TCA9548A nao Iniciado, endereco " + String(enderecoMux) + " nao encontrado no barramento");
|
||||
}
|
||||
}
|
||||
|
||||
static void SelecionarCanal(uint8_t canal) {
|
||||
if (!Iniciado) return;
|
||||
if (canalAtivo == canal) return; // Já está no canal certo
|
||||
|
||||
Wire.beginTransmission(enderecoMux);
|
||||
Wire.write(1 << canal);
|
||||
Wire.endTransmission();
|
||||
|
||||
PrintTela("[MUX] Canal alterado de " + String(canalAtivo) + " para " + String(canal));
|
||||
|
||||
canalAtivo = canal;
|
||||
}
|
||||
};
|
||||
|
||||
bool MuxService::Iniciado = false;
|
||||
int MuxService::canalAtivo = -1;
|
||||
|
||||
#endif
|
||||
|
|
@ -1,17 +1,11 @@
|
|||
#include "Enuns.h"
|
||||
#include "SerialService.h"
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_MCP23X17.h>
|
||||
#include <Adafruit_ADS1X15.h>
|
||||
#include "I2CService.h"
|
||||
|
||||
#ifndef Pinout
|
||||
#define Pinout
|
||||
|
||||
#define PINO_INVALIDO 0xFF
|
||||
Adafruit_MCP23X17 mcp;
|
||||
Adafruit_ADS1115 ads;
|
||||
bool mcpInicializado = false;
|
||||
bool adsInicializado = false;
|
||||
|
||||
class PinoModel {
|
||||
public:
|
||||
|
|
@ -38,13 +32,15 @@ class PinoModel {
|
|||
}
|
||||
}
|
||||
else if (barramento == EXPANSOR_GPIO) {
|
||||
if (mcpInicializado) {
|
||||
if (I2CService::McpIniciado) {
|
||||
I2CService::SolicitarAcessoI2C();
|
||||
if (tipo == _INPUT) {
|
||||
mcp.pinMode(num, INPUT);
|
||||
I2CService::mcp.pinMode(num, INPUT);
|
||||
} else if (tipo == _OUTPUT) {
|
||||
mcp.pinMode(num, OUTPUT);
|
||||
I2CService::mcp.pinMode(num, OUTPUT);
|
||||
set(statusInicial);
|
||||
}
|
||||
I2CService::LiberarAcessoI2C();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -59,8 +55,10 @@ class PinoModel {
|
|||
pinMode(num, INPUT);
|
||||
}
|
||||
else if (barramento == EXPANSOR_GPIO) {
|
||||
if (mcpInicializado) {
|
||||
mcp.pinMode(num, INPUT);
|
||||
if (I2CService::McpIniciado) {
|
||||
I2CService::SolicitarAcessoI2C();
|
||||
I2CService::mcp.pinMode(num, INPUT);
|
||||
I2CService::LiberarAcessoI2C();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -82,20 +80,25 @@ class PinoModel {
|
|||
}
|
||||
}
|
||||
else if (barramento == EXPANSOR_GPIO) {
|
||||
if (mcpInicializado) {
|
||||
return mcp.digitalRead(num);
|
||||
if (I2CService::McpIniciado) {
|
||||
I2CService::SolicitarAcessoI2C();
|
||||
int leitura = I2CService::mcp.digitalRead(num);
|
||||
I2CService::LiberarAcessoI2C();
|
||||
return leitura;
|
||||
}
|
||||
}
|
||||
else if (barramento == EXPANSOR_ADS) {
|
||||
if (adsInicializado) {
|
||||
double l = 0;
|
||||
if (I2CService::AdsIniciado) {
|
||||
I2CService::SolicitarAcessoI2C();
|
||||
uint16_t l = 0;
|
||||
for (int i = 0; i < leituras; i++) {
|
||||
int leituraADC = (int)(ads.readADC_SingleEnded(num));
|
||||
int leituraADC = (int)(I2CService::ads.readADC_SingleEnded(num));
|
||||
int leitura12bits = map(leituraADC, 0, 32767, 0, 4095);
|
||||
l += leitura12bits;
|
||||
delay(1);
|
||||
}
|
||||
return l / leituras;
|
||||
I2CService::LiberarAcessoI2C();
|
||||
return (int)(l / leituras);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -108,67 +111,15 @@ class PinoModel {
|
|||
digitalWrite(num, status ? HIGH : LOW);
|
||||
}
|
||||
else if (barramento == EXPANSOR_GPIO) {
|
||||
if (mcpInicializado) {
|
||||
mcp.digitalWrite(num, status ? HIGH : LOW);
|
||||
if (I2CService::McpIniciado) {
|
||||
I2CService::SolicitarAcessoI2C();
|
||||
I2CService::mcp.digitalWrite(num, status ? HIGH : LOW);
|
||||
I2CService::LiberarAcessoI2C();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
void iniciarMCP(T_Code Modulo, String Mod_ID, int sda, int scl, byte endereco, bool Mandatorio = false) {
|
||||
PrintTela("Iniciando MCP23X17...");
|
||||
if (!mcpInicializado) {
|
||||
bool init = Wire.begin(sda, scl);
|
||||
String str = "SDA " + (String)sda + " SCL " + (String)scl + " Res " + init + " - ";
|
||||
PrintTela(str, false);
|
||||
|
||||
if (!mcp.begin_I2C(endereco, &Wire)) {
|
||||
mcpInicializado = false;
|
||||
PrintTela("Erro ao iniciar MCP23X17!");
|
||||
if (Mandatorio) {
|
||||
PrintTela("Conexão obrigatória, tentando novamente em 5 segundos...");
|
||||
//EnviarDadosSerial(Mod_ID, MontarProtocoloErro(Modulo));
|
||||
delay(5000);
|
||||
iniciarMCP(Modulo, Mod_ID, sda, scl, endereco, Mandatorio);
|
||||
}
|
||||
else {
|
||||
PrintTela("MCP23X17 nao mandatorio, continuando o fluxo...");
|
||||
}
|
||||
}
|
||||
else {
|
||||
PrintTela("MCP23X17 iniciado com sucesso!");
|
||||
mcpInicializado = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void iniciarADS(T_Code Modulo, String Mod_ID, int sda, int scl, byte endereco, bool Mandatorio = false) {
|
||||
PrintTela("Iniciando ADS1115...");
|
||||
if (!adsInicializado) {
|
||||
bool init = Wire.begin(sda, scl);
|
||||
String str = "SDA " + (String)sda + " SCL " + (String)scl + " Res " + init + " - ";
|
||||
PrintTela(str, false);
|
||||
|
||||
if (!ads.begin(endereco, &Wire)) {
|
||||
adsInicializado = false;
|
||||
PrintTela("Erro ao iniciar ADS1115!");
|
||||
if (Mandatorio) {
|
||||
PrintTela("Conexão obrigatória, tentando novamente em 5 segundos...");
|
||||
//EnviarDadosSerial(Mod_ID, MontarProtocoloErro(Modulo));
|
||||
delay(5000);
|
||||
iniciarADS(Modulo, Mod_ID, sda, scl, endereco, Mandatorio);
|
||||
}
|
||||
else {
|
||||
PrintTela("ADS1115 nao mandatorio, continuando o fluxo...");
|
||||
}
|
||||
}
|
||||
else {
|
||||
ads.setGain(GAIN_ONE);
|
||||
PrintTela("ADS1115 iniciado com sucesso!");
|
||||
adsInicializado = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -2,9 +2,8 @@
|
|||
#define SensorCorrenteModel
|
||||
|
||||
#include "SerialService.h"
|
||||
#include "Pinout.h"
|
||||
#include "I2CService.h"
|
||||
#include "Utils.h"
|
||||
#include "MuxService.h"
|
||||
#include <Wire.h>
|
||||
#include <vector>
|
||||
#include <Adafruit_INA219.h>
|
||||
|
|
@ -37,19 +36,18 @@ class SensorCorrente {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!I2CService::SolicitarAcessoI2C(ID_Num, _CanalMUX)) return;
|
||||
|
||||
isINA219 = _A_Shunt == TiposShuntCorrente::INA219_3A2;
|
||||
|
||||
MuxService::SelecionarCanal(_CanalMUX);
|
||||
|
||||
Wire.beginTransmission(_Endereco);
|
||||
byte error = Wire.endTransmission();
|
||||
if (error == 0) {
|
||||
bool encontrado = I2CService::VerificaEnderecoBarramento(_Endereco);
|
||||
if (encontrado) {
|
||||
if (isINA219) {
|
||||
sINA219 = Adafruit_INA219(_Endereco);
|
||||
Iniciado = sINA219.begin();
|
||||
if (Iniciado) {
|
||||
sINA219.setCalibration_32V_2A();
|
||||
PrintTela(_ID + " iniciado");
|
||||
PrintTela(_ID + " (INA219) iniciado no canal " + String(_CanalMUX));
|
||||
}
|
||||
else {
|
||||
PrintTela(_ID + " nao iniciado!");
|
||||
|
|
@ -57,8 +55,6 @@ class SensorCorrente {
|
|||
}
|
||||
else {
|
||||
Iniciado = true;
|
||||
EscreverRegistradorINA(0x00, 0x8000); // Bit 15 = 1 → RESET
|
||||
delay(2);
|
||||
switch (_A_Shunt) {
|
||||
case TiposShuntCorrente::INA228_10A:
|
||||
currentLSB = currentLSB_10A;
|
||||
|
|
@ -70,12 +66,17 @@ class SensorCorrente {
|
|||
currentLSB = currentLSB_100A;
|
||||
break;
|
||||
}
|
||||
PrintTela(_ID + " iniciado");
|
||||
EscreverRegistradorINA(0x00, 0x8000); // Bit 15 = 1 → RESET
|
||||
uint16_t cal = (uint16_t)(0.00512 / (currentLSB * shuntLSB));
|
||||
//EscreverRegistradorINA(0xD4, cal);
|
||||
PrintTela(_ID + " (INA228) iniciado no canal " + String(_CanalMUX));
|
||||
}
|
||||
} else {
|
||||
Iniciado = false;
|
||||
PrintTela(_ID + " nao iniciado, endereco " + _Endereco + " nao encontrado!");
|
||||
}
|
||||
|
||||
I2CService::LiberarAcessoI2C(ID_Num);
|
||||
}
|
||||
|
||||
void Desligar() {
|
||||
|
|
@ -85,12 +86,18 @@ class SensorCorrente {
|
|||
}
|
||||
|
||||
Iniciado = false;
|
||||
|
||||
if (I2CService::QuemEstaUsando() == ID_Num) {
|
||||
while (I2CService::QuemEstaUsando() == ID_Num) {
|
||||
delay(10);
|
||||
}
|
||||
}
|
||||
|
||||
PrintTela(_ID + " Desligado");
|
||||
}
|
||||
|
||||
void RequisitarDados() {
|
||||
if (!Iniciado) return;
|
||||
MuxService::SelecionarCanal(_CanalMUX);
|
||||
AferirCorrente();
|
||||
}
|
||||
|
||||
|
|
@ -186,29 +193,40 @@ class SensorCorrente {
|
|||
float currentLSB = 0.0001;
|
||||
|
||||
uint32_t LerRegistradorINA(uint8_t reg, uint8_t bytes) {
|
||||
Wire.beginTransmission(_Endereco);
|
||||
Wire.write(reg);
|
||||
Wire.endTransmission(false);
|
||||
Wire.requestFrom(_Endereco, bytes);
|
||||
|
||||
uint8_t buffer[4] = {0};
|
||||
|
||||
if (bytes > 4) return 0;
|
||||
|
||||
// Aumentar timeout para garantir tempo de resposta
|
||||
if (!I2CService::LeituraSegura(_Endereco, buffer, bytes, reg)) {
|
||||
Serial.printf("[sCOR] Falha na leitura do registrador 0x%02X\n", reg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t valor = 0;
|
||||
for (uint8_t i = 0; i < bytes; i++) {
|
||||
valor = (valor << 8) | Wire.read();
|
||||
valor = (valor << 8) | buffer[i];
|
||||
}
|
||||
|
||||
return valor;
|
||||
}
|
||||
|
||||
void EscreverRegistradorINA(uint8_t reg, uint16_t valor) {
|
||||
Wire.beginTransmission(_Endereco);
|
||||
Wire.write(reg);
|
||||
Wire.write((valor >> 8) & 0xFF); // MSB
|
||||
Wire.write(valor & 0xFF); // LSB
|
||||
Wire.endTransmission();
|
||||
uint8_t dados[3];
|
||||
dados[0] = reg;
|
||||
dados[1] = (valor >> 8) & 0xFF;
|
||||
dados[2] = valor & 0xFF;
|
||||
|
||||
if (!I2CService::EscritaSegura(_Endereco, dados, 3, 50)) {
|
||||
Serial.printf("[INA] Falha ao escrever no registrador 0x%02X\n", reg);
|
||||
}
|
||||
}
|
||||
|
||||
void AferirCorrente() {
|
||||
if (!Iniciado) return;
|
||||
|
||||
if (!I2CService::SolicitarAcessoI2C(ID_Num, _CanalMUX)) return;
|
||||
|
||||
if (isINA219) {
|
||||
busVoltage = sINA219.getBusVoltage_V();
|
||||
current = sINA219.getCurrent_mA() / 10000.0;
|
||||
|
|
@ -227,6 +245,8 @@ class SensorCorrente {
|
|||
energy = rawEnergy * currentLSB * 3.125 * 16 / 3600.0;
|
||||
temperature = ((int16_t)rawTemp) * 0.0078125;
|
||||
}
|
||||
|
||||
I2CService::LiberarAcessoI2C(ID_Num);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
#ifndef SensorIMUModel
|
||||
#define SensorIMUModel
|
||||
|
||||
#include "SerialService.h"
|
||||
#include "I2CService.h"
|
||||
#include <MPU9250_asukiaaa.h>
|
||||
#include <Adafruit_BMP280.h>
|
||||
#include <MadgwickAHRS.h>
|
||||
#include <MahonyAHRS.h>
|
||||
#include <Wire.h>
|
||||
#include "SerialService.h"
|
||||
#include "Pinout.h"
|
||||
|
||||
class SensorIMU {
|
||||
public:
|
||||
|
|
@ -30,10 +30,9 @@ class SensorIMU {
|
|||
// BMP280 (Temperatura, Pressão, Altitude)
|
||||
Adafruit_BMP280 bmp;
|
||||
|
||||
Madgwick filter;
|
||||
float filterHz = 250.0f;
|
||||
float filterBeta = 0.2f;
|
||||
int filterDelay = 1000.0f / filterHz;
|
||||
Mahony filter;
|
||||
int filterHz = 100;
|
||||
TickType_t filterDelay = pdMS_TO_TICKS(roundf(1000.0f / filterHz));
|
||||
|
||||
// Leituras principais
|
||||
float AccX = 0, AccY = 0, AccZ = 0;
|
||||
|
|
@ -57,24 +56,20 @@ class SensorIMU {
|
|||
return;
|
||||
}
|
||||
|
||||
Wire.beginTransmission(_EnderecoMPU);
|
||||
byte errorMpu = Wire.endTransmission();
|
||||
MpuIniciado = errorMpu == 0;
|
||||
if (!I2CService::SolicitarAcessoI2C(ID_Num)) return;
|
||||
|
||||
MpuIniciado = I2CService::VerificaEnderecoBarramento(_EnderecoMPU);
|
||||
if (MpuIniciado) {
|
||||
mpu.setWire(&Wire);
|
||||
mpu.beginAccel();
|
||||
mpu.beginGyro();
|
||||
mpu.beginMag();
|
||||
|
||||
filter.begin(filterHz);
|
||||
filter.setBeta(filterBeta);
|
||||
//mpu.beginMag();
|
||||
PrintTela("MPU9250 iniciado");
|
||||
} else {
|
||||
PrintTela("MPU9250 nao encontrado no endereco " + String(_EnderecoMPU));
|
||||
}
|
||||
|
||||
Wire.beginTransmission(_EnderecoBMP);
|
||||
byte errorBmp = Wire.endTransmission();
|
||||
bool BmpEncontrado = errorBmp == 0;
|
||||
bool BmpEncontrado = I2CService::VerificaEnderecoBarramento(_EnderecoBMP);
|
||||
if (BmpEncontrado) {
|
||||
BmpIniciado = bmp.begin(_EnderecoBMP);
|
||||
if (BmpIniciado) {
|
||||
|
|
@ -83,6 +78,7 @@ class SensorIMU {
|
|||
Adafruit_BMP280::SAMPLING_X16,
|
||||
Adafruit_BMP280::FILTER_X16,
|
||||
Adafruit_BMP280::STANDBY_MS_500);
|
||||
PrintTela("BMP280 iniciado");
|
||||
}
|
||||
else {
|
||||
PrintTela("Erro ao iniciar BMP280");
|
||||
|
|
@ -94,9 +90,12 @@ class SensorIMU {
|
|||
|
||||
Iniciado = MpuIniciado || BmpIniciado;
|
||||
if (Iniciado) {
|
||||
filterDelay = 1000.0f / filterHz;
|
||||
xTaskCreatePinnedToCore(&SensorIMU::IMUTaskWrapper, "IMUTask", 5000, this, 20, &IMUTaskHandle, tskNO_AFFINITY);
|
||||
PrintTela(_ID + " iniciado");
|
||||
}
|
||||
|
||||
I2CService::LiberarAcessoI2C(ID_Num);
|
||||
}
|
||||
|
||||
void Desligar() {
|
||||
|
|
@ -105,6 +104,14 @@ class SensorIMU {
|
|||
return;
|
||||
}
|
||||
|
||||
Iniciado = false;
|
||||
|
||||
if (I2CService::QuemEstaUsando() == ID_Num) {
|
||||
while (I2CService::QuemEstaUsando() == ID_Num) {
|
||||
delay(10);
|
||||
}
|
||||
}
|
||||
|
||||
// Parar a execução das tarefas
|
||||
if (IMUTaskHandle != NULL) {
|
||||
vTaskDelete(IMUTaskHandle);
|
||||
|
|
@ -112,18 +119,10 @@ class SensorIMU {
|
|||
}
|
||||
|
||||
PrintTela(_ID + " Desligado");
|
||||
|
||||
Iniciado = false;
|
||||
}
|
||||
|
||||
void RequisitarDados() {
|
||||
/*Serial.print("Temp: "); Serial.println(Temp);
|
||||
Serial.print("Pressao: "); Serial.println(Pressao);
|
||||
Serial.print("Altitude: "); Serial.println(Altitude);
|
||||
Serial.print("Roll: "); Serial.println(Roll);
|
||||
Serial.print("Pitch: "); Serial.println(Pitch);
|
||||
Serial.print("Yaw: "); Serial.println(Yaw);
|
||||
Serial.println();*/
|
||||
AferirDadosTMP();
|
||||
}
|
||||
|
||||
std::vector<uint8_t> MontarMensagemCAN(CanMessagePosicaoDados posicao) {
|
||||
|
|
@ -206,64 +205,72 @@ class SensorIMU {
|
|||
}
|
||||
|
||||
void IMUTask() {
|
||||
TickType_t xLastWakeTime = xTaskGetTickCount();
|
||||
|
||||
while (1) {
|
||||
if (Iniciado) {
|
||||
AferirDados();
|
||||
AferirDadosIMU();
|
||||
vTaskDelayUntil(&xLastWakeTime, filterDelay);
|
||||
}
|
||||
else {
|
||||
vTaskDelay(1000);
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(filterDelay));
|
||||
}
|
||||
}
|
||||
|
||||
void AferirDados() {
|
||||
if (!Iniciado) return;
|
||||
void AferirDadosIMU() {
|
||||
if (!MpuIniciado) return;
|
||||
|
||||
if (MpuIniciado) {
|
||||
mpu.accelUpdate();
|
||||
mpu.gyroUpdate();
|
||||
mpu.magUpdate();
|
||||
|
||||
AccX = mpu.accelX();
|
||||
AccY = mpu.accelY();
|
||||
AccZ = mpu.accelZ();
|
||||
if (!I2CService::SolicitarAcessoI2C(ID_Num, -1, 5)) return;
|
||||
|
||||
GyroX = mpu.gyroX();
|
||||
GyroY = mpu.gyroY();
|
||||
GyroZ = mpu.gyroZ();
|
||||
mpu.accelUpdate();
|
||||
mpu.gyroUpdate();
|
||||
mpu.magUpdate();
|
||||
|
||||
MagX = mpu.magX();
|
||||
MagY = mpu.magY();
|
||||
MagZ = mpu.magZ();
|
||||
AccX = mpu.accelX();
|
||||
AccY = mpu.accelY();
|
||||
AccZ = mpu.accelZ();
|
||||
|
||||
if (true || MagX == 0 && MagY == 0 && MagZ == 0) {
|
||||
filter.updateIMU(GyroX, GyroY, GyroZ, AccX, AccY, AccZ);
|
||||
}
|
||||
else {
|
||||
filter.update(GyroX, GyroY, GyroZ, AccX, AccY, AccZ, MagX, MagY, MagZ);
|
||||
}
|
||||
GyroX = mpu.gyroX();
|
||||
GyroY = mpu.gyroY();
|
||||
GyroZ = mpu.gyroZ();
|
||||
|
||||
// Recupera os quaternions
|
||||
float q0 = filter.getQ0();
|
||||
float q1 = filter.getQ1();
|
||||
float q2 = filter.getQ2();
|
||||
float q3 = filter.getQ3();
|
||||
/*MagX = mpu.magX();
|
||||
MagY = mpu.magY();
|
||||
MagZ = mpu.magZ();*/
|
||||
|
||||
// Vetor "up"
|
||||
float upX = 2 * (q1 * q3 - q0 * q2);
|
||||
float upY = 2 * (q2 * q3 + q0 * q1);
|
||||
float upZ = 1 - 2 * (q1 * q1 + q2 * q2);
|
||||
filter.updateIMU(GyroX, GyroY, GyroZ, AccX, AccY, AccZ);
|
||||
|
||||
// Calcula os ângulos corrigidos
|
||||
Roll = atan2(upY, upZ) * RAD_TO_DEG;
|
||||
Roll = (Roll > 0) ? Roll - 180 : Roll + 180;
|
||||
Pitch = -(atan2(-upX, sqrt(upY * upY + upZ * upZ)) * RAD_TO_DEG);
|
||||
Yaw = atan2(2.0f * (q1 * q2 + q0 * q3), q0*q0 + q1*q1 - q2*q2 - q3*q3) * RAD_TO_DEG;
|
||||
}
|
||||
// Recupera os quaternions
|
||||
float q0 = filter.getQ0();
|
||||
float q1 = filter.getQ1();
|
||||
float q2 = filter.getQ2();
|
||||
float q3 = filter.getQ3();
|
||||
|
||||
// Vetor "up"
|
||||
float upX = 2 * (q1 * q3 - q0 * q2);
|
||||
float upY = 2 * (q2 * q3 + q0 * q1);
|
||||
float upZ = 1 - 2 * (q1 * q1 + q2 * q2);
|
||||
|
||||
// Calcula os ângulos corrigidos
|
||||
Roll = atan2(upY, upZ) * RAD_TO_DEG;
|
||||
Roll = (Roll > 0) ? Roll - 180 : Roll + 180;
|
||||
Pitch = -(atan2(-upX, sqrt(upY * upY + upZ * upZ)) * RAD_TO_DEG);
|
||||
Yaw = atan2(2.0f * (q1 * q2 + q0 * q3), q0*q0 + q1*q1 - q2*q2 - q3*q3) * RAD_TO_DEG;
|
||||
|
||||
if (BmpIniciado) {
|
||||
Temp = bmp.readTemperature();
|
||||
Pressao = bmp.readPressure();
|
||||
Altitude = bmp.readAltitude();
|
||||
}
|
||||
I2CService::LiberarAcessoI2C(ID_Num);
|
||||
}
|
||||
|
||||
void AferirDadosTMP() {
|
||||
if (!BmpIniciado) return;
|
||||
|
||||
if (!I2CService::SolicitarAcessoI2C(ID_Num)) return;
|
||||
|
||||
Temp = bmp.readTemperature();
|
||||
Pressao = bmp.readPressure();
|
||||
Altitude = bmp.readAltitude();
|
||||
|
||||
I2CService::LiberarAcessoI2C(ID_Num);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
#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\MuxService.h"
|
||||
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\I2CService.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"
|
||||
|
|
@ -37,10 +37,6 @@ int latenciaLoop = 0;
|
|||
int qtdEnviosStatus = 0;
|
||||
int maxEnviosStatus = 5;
|
||||
|
||||
PinoModel _pinoSDA = PinoModel(1, CONTROLADOR, _INPUT);
|
||||
PinoModel _pinoSCL = PinoModel(2, CONTROLADOR, _INPUT);
|
||||
|
||||
|
||||
std::vector<SensorTemperatura*> listaSensoresTemperatura;
|
||||
std::vector<SensorCorrente*> listaSensoresCorrente;
|
||||
std::vector<Sinaleiro*> listaSinaleiros;
|
||||
|
|
@ -48,13 +44,17 @@ std::vector<Rele*> listaReles;
|
|||
std::vector<ServoFreio*> listaServoFreios;
|
||||
std::vector<SensorIMU*> listaSensoresIMU;
|
||||
|
||||
void inicializarDependenciasI2C() {
|
||||
I2CService::IniciarI2C();
|
||||
I2CService::IniciarMUX();
|
||||
I2CService::IniciarMCP();
|
||||
I2CService::IniciarADS();
|
||||
}
|
||||
|
||||
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);
|
||||
MuxService::IniciarMUX();
|
||||
inicializarDependenciasI2C();
|
||||
|
||||
// Registrar callback para processar mensagens CAN recebidas
|
||||
canService.setReceiveCallback([](int packetSize, int senderId, byte funcCode, byte* data, int dataLength) {
|
||||
|
|
@ -78,6 +78,7 @@ void loop() {
|
|||
}
|
||||
|
||||
canService.loop();
|
||||
I2CService::VerificarI2CPreso();
|
||||
|
||||
delay(1);
|
||||
|
||||
|
|
@ -109,7 +110,9 @@ void enviarDadosSensores() {
|
|||
if (enviarStatus) {
|
||||
EnviarDadosCAN(sensor->MontarMensagemCAN(CanMessagePosicaoDados::Status));
|
||||
}
|
||||
EnviarDadosCAN(sensor->MontarMensagemCAN(CanMessagePosicaoDados::Dados1));
|
||||
if (sensor->Iniciado) {
|
||||
EnviarDadosCAN(sensor->MontarMensagemCAN(CanMessagePosicaoDados::Dados1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -119,8 +122,10 @@ void enviarDadosSensores() {
|
|||
if (enviarStatus) {
|
||||
EnviarDadosCAN(sensor->MontarMensagemCAN(CanMessagePosicaoDados::Status));
|
||||
}
|
||||
EnviarDadosCAN(sensor->MontarMensagemCAN(CanMessagePosicaoDados::Dados1));
|
||||
EnviarDadosCAN(sensor->MontarMensagemCAN(CanMessagePosicaoDados::Dados2));
|
||||
if (sensor->Iniciado) {
|
||||
EnviarDadosCAN(sensor->MontarMensagemCAN(CanMessagePosicaoDados::Dados1));
|
||||
EnviarDadosCAN(sensor->MontarMensagemCAN(CanMessagePosicaoDados::Dados2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -130,7 +135,9 @@ void enviarDadosSensores() {
|
|||
if (enviarStatus) {
|
||||
EnviarDadosCAN(sensor->MontarMensagemCAN(CanMessagePosicaoDados::Status));
|
||||
}
|
||||
EnviarDadosCAN(sensor->MontarMensagemCAN(CanMessagePosicaoDados::Dados1));
|
||||
if (sensor->Iniciado) {
|
||||
EnviarDadosCAN(sensor->MontarMensagemCAN(CanMessagePosicaoDados::Dados1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -140,7 +147,9 @@ void enviarDadosSensores() {
|
|||
if (enviarStatus) {
|
||||
EnviarDadosCAN(sensor->MontarMensagemCAN(CanMessagePosicaoDados::Status));
|
||||
}
|
||||
EnviarDadosCAN(sensor->MontarMensagemCAN(CanMessagePosicaoDados::Dados1));
|
||||
if (sensor->Iniciado) {
|
||||
EnviarDadosCAN(sensor->MontarMensagemCAN(CanMessagePosicaoDados::Dados1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -150,7 +159,9 @@ void enviarDadosSensores() {
|
|||
if (enviarStatus) {
|
||||
EnviarDadosCAN(sensor->MontarMensagemCAN(CanMessagePosicaoDados::Status));
|
||||
}
|
||||
EnviarDadosCAN(sensor->MontarMensagemCAN(CanMessagePosicaoDados::Dados1));
|
||||
if (sensor->Iniciado) {
|
||||
EnviarDadosCAN(sensor->MontarMensagemCAN(CanMessagePosicaoDados::Dados1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -160,8 +171,12 @@ void enviarDadosSensores() {
|
|||
if (enviarStatus) {
|
||||
EnviarDadosCAN(sensor->MontarMensagemCAN(CanMessagePosicaoDados::Status));
|
||||
}
|
||||
EnviarDadosCAN(sensor->MontarMensagemCAN(CanMessagePosicaoDados::Dados1));
|
||||
EnviarDadosCAN(sensor->MontarMensagemCAN(CanMessagePosicaoDados::Dados2));
|
||||
if (sensor->MpuIniciado) {
|
||||
EnviarDadosCAN(sensor->MontarMensagemCAN(CanMessagePosicaoDados::Dados1));
|
||||
}
|
||||
if (sensor->BmpIniciado) {
|
||||
EnviarDadosCAN(sensor->MontarMensagemCAN(CanMessagePosicaoDados::Dados2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -228,13 +243,8 @@ void ProcessarCfg(std::vector<uint8_t> data) {
|
|||
int pinoSDA = data[4];
|
||||
int pinoSCL = data[5];
|
||||
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("[SEN] I2C inicializado nos pinos SDA=" + String(pinoSDA) + " e SCL=" + String(pinoSCL));
|
||||
|
||||
MuxService::IniciarMUX();
|
||||
I2CService::DefinirPinos(pinoSDA, pinoSCL);
|
||||
inicializarDependenciasI2C();
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
Conectado = Conectar;
|
||||
|
|
|
|||
Loading…
Reference in New Issue