Ajuste na firmware e leitura de dados brutos
This commit is contained in:
parent
777993dfbb
commit
7554842804
|
|
@ -138,8 +138,8 @@ namespace AgroBase.Forms.Atuador
|
|||
var BombaPressurizadora = DispAtu.Dados.BombasPressurizadoras.FirstOrDefault();
|
||||
grdSensoriamento.Rows[0].Cells[1].Value = BombaPressurizadora.Inicializado;
|
||||
grdSensoriamento.Rows[1].Cells[1].Value = BombaPressurizadora.ComandoAtuar;
|
||||
grdSensoriamento.Rows[2].Cells[1].Value = BombaPressurizadora.ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.EstadoLeitura).atual.valor;
|
||||
grdSensoriamento.Rows[3].Cells[1].Value = BombaPressurizadora.ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.Potencia).atual.valor;
|
||||
grdSensoriamento.Rows[2].Cells[1].Value = BombaPressurizadora._EstadoLeitura;
|
||||
grdSensoriamento.Rows[3].Cells[1].Value = BombaPressurizadora._Potencia;
|
||||
grdSensoriamento.Rows[4].Cells[1].Value = DispAtu.Dados.PressaoLinha.ToString("0.00000");
|
||||
grdSensoriamento.Rows[5].Cells[1].Value = DispAtu.Dados.PressaoLinhaCalc.ToString("0.00000");
|
||||
grdSensoriamento.Rows[6].Cells[1].Value = DispAtu.Dados.VazaoFluxoMLpSMedia.ToString("0.00000");
|
||||
|
|
@ -178,7 +178,7 @@ namespace AgroBase.Forms.Atuador
|
|||
int circleY = pnl.Height / 4; // Posição Y do círculo (mais próximo ao topo)
|
||||
|
||||
// Desenhar o círculo
|
||||
if (DispAtu.Dados.BicosPulverizadores.First(x => x.ID == ID).ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.EstadoLeitura).atual.valor)
|
||||
if (DispAtu.Dados.BicosPulverizadores.First(x => x.ID == ID)._EstadoLeitura == Estado.Ligado)
|
||||
g.FillEllipse(Brushes.Green, circleX, circleY, circleDiameter, circleDiameter); // LED aceso (círculo preenchido)
|
||||
else
|
||||
g.DrawEllipse(Pens.Black, circleX, circleY, circleDiameter, circleDiameter); // LED apagado (círculo vazio)
|
||||
|
|
|
|||
|
|
@ -478,42 +478,42 @@ namespace AgroBase.Forms.IHM
|
|||
double Fluxo = FluxoInicializado ? Dispositivo.Dados.VazaoFluxoMLpSInstantanea : -1;
|
||||
idx = PreencheDadosLinha(grid, Testes, idx, Fluxo);
|
||||
|
||||
bool statusB01_1 = B01Inicializado && B01.ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.EstadoLeitura).atual.valor;
|
||||
bool statusB01_1 = B01Inicializado && B01._EstadoLeitura == Estado.Ligado;
|
||||
idx = PreencheDadosLinha(grid, Testes, idx, statusB01_1 ? 1 : -1);
|
||||
|
||||
await EnviarComandoBico(B01, false, 1000);
|
||||
|
||||
bool statusB01_0 = B01Inicializado && !B01.ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.EstadoLeitura).atual.valor;
|
||||
bool statusB01_0 = B01Inicializado && B01._EstadoLeitura == Estado.Desligado;
|
||||
idx = PreencheDadosLinha(grid, Testes, idx, statusB01_0 ? 0 : -1);
|
||||
|
||||
await EnviarComandoBico(B02, true, 1000);
|
||||
|
||||
bool statusB02_1 = B02Inicializado && B02.ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.EstadoLeitura).atual.valor;
|
||||
bool statusB02_1 = B02Inicializado && B02._EstadoLeitura == Estado.Ligado;
|
||||
idx = PreencheDadosLinha(grid, Testes, idx, statusB02_1 ? 1 : -1);
|
||||
|
||||
await EnviarComandoBico(B02, false, 1000);
|
||||
|
||||
bool statusB02_0 = B02Inicializado && !B02.ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.EstadoLeitura).atual.valor;
|
||||
bool statusB02_0 = B02Inicializado && B02._EstadoLeitura == Estado.Desligado;
|
||||
idx = PreencheDadosLinha(grid, Testes, idx, statusB02_0 ? 0 : -1);
|
||||
|
||||
await EnviarComandoBico(B03, true, 1000);
|
||||
|
||||
bool statusB03_1 = B03Inicializado && B03.ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.EstadoLeitura).atual.valor;
|
||||
bool statusB03_1 = B03Inicializado && B03._EstadoLeitura == Estado.Ligado;
|
||||
idx = PreencheDadosLinha(grid, Testes, idx, statusB03_1 ? 1 : -1);
|
||||
|
||||
await EnviarComandoBico(B03, false, 1000);
|
||||
|
||||
bool statusB03_0 = B03Inicializado && !B03.ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.EstadoLeitura).atual.valor;
|
||||
bool statusB03_0 = B03Inicializado && B03._EstadoLeitura == Estado.Desligado;
|
||||
idx = PreencheDadosLinha(grid, Testes, idx, statusB03_0 ? 0 : -1);
|
||||
|
||||
await EnviarComandoBico(B04, true, 1000);
|
||||
|
||||
bool statusB04_1 = B04Inicializado && B04.ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.EstadoLeitura).atual.valor;
|
||||
bool statusB04_1 = B04Inicializado && B04._EstadoLeitura == Estado.Ligado;
|
||||
idx = PreencheDadosLinha(grid, Testes, idx, statusB04_1 ? 1 : -1);
|
||||
|
||||
await EnviarComandoBico(B04, false, 1000);
|
||||
|
||||
bool statusB04_0 = B04Inicializado && B04.ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.EstadoLeitura).atual.valor;
|
||||
bool statusB04_0 = B04Inicializado && B04._EstadoLeitura == Estado.Desligado;
|
||||
idx = PreencheDadosLinha(grid, Testes, idx, statusB04_0 ? 0 : -1);
|
||||
|
||||
|
||||
|
|
@ -1765,7 +1765,7 @@ namespace AgroBase.Forms.IHM
|
|||
await EnviarComandoRele(Dispositivo, Rele, true, 1000);
|
||||
}
|
||||
|
||||
Estado Status = Rele.ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.EstadoLeitura).atual.valor;
|
||||
Estado Status = Rele._EstadoLeitura;
|
||||
idx = PreencheDadosLinha(grid, Testes, idx, Iniciado && Status == Estado.Ligado ? 1 : -1);
|
||||
|
||||
if (Iniciado)
|
||||
|
|
@ -1773,7 +1773,7 @@ namespace AgroBase.Forms.IHM
|
|||
await EnviarComandoRele(Dispositivo, Rele, false, 1000);
|
||||
}
|
||||
|
||||
Status = Rele.ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.EstadoLeitura).atual.valor;
|
||||
Status = Rele._EstadoLeitura;
|
||||
idx = PreencheDadosLinha(grid, Testes, idx, Iniciado && Status == Estado.Desligado ? 0 : -1);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -539,7 +539,7 @@ namespace AgroBase.Forms.Operacoes
|
|||
gridDados.Rows[19].Cells[1].Value = (_Barramentos.FirstOrDefault(x => x.ID == "AB24V").Tensao).ToString("0.00");
|
||||
gridDados.Rows[20].Cells[1].Value = (_Barramentos.FirstOrDefault(x => x.ID == "AB24V").Corrente).ToString("0.00");
|
||||
gridDados.Rows[21].Cells[1].Value = _Sensoriamento.Atuador.PercentualReservatorio.ToString("0.00");
|
||||
gridDados.Rows[22].Cells[1].Value = _Sensoriamento.Atuador.VolumeReservatorio.ToString("0.000");
|
||||
gridDados.Rows[22].Cells[1].Value = $"{_Sensoriamento.Atuador.VolumeReservatorio:0.000} ({Variaveis.OperacaoEmAndamento.DispAtu?.Dados?.ContadorCarga?.MassaAtual_Kg_Calc ?? 0:0.000} Kg)";
|
||||
gridDados.Rows[23].Cells[1].Value = _Sensoriamento.Atuador.LPorMetro.ToString("0.000");
|
||||
gridDados.Rows[24].Cells[1].Value = _Sensoriamento.Atuador.LPorMinuto.ToString("0.000");
|
||||
gridDados.Rows[25].Cells[1].Value = TimeSpan.FromMinutes(_Sensoriamento.Atuador.TempoEstimadoRestanteMinutos).ToString(@"hh\:mm\:ss");
|
||||
|
|
@ -547,7 +547,7 @@ namespace AgroBase.Forms.Operacoes
|
|||
gridDados.Rows[27].Cells[1].Value = _Sensoriamento.Atuador.PressaoLinha.ToString("0.00");
|
||||
gridDados.Rows[28].Cells[1].Value = _Sensoriamento.Atuador.LeituraPotenciaBomba.ToString("0.00");
|
||||
gridDados.Rows[29].Cells[1].Value = _Sensoriamento.Atuador.VazaoInstantanea.ToString("0.00");
|
||||
gridDados.Rows[30].Cells[1].Value = _Sensoriamento.Atuador.VazaoMedia.ToString("0.00");
|
||||
gridDados.Rows[30].Cells[1].Value = $"{_Sensoriamento.Atuador.VazaoMedia:0.000} ({Variaveis.OperacaoEmAndamento.DispAtu?.Dados?.VazaoFluxoMLpSInstantaneaCalc:0.000})";
|
||||
gridDados.Rows[31].Cells[1].Value = _Sensoriamento.Atuador.VolumeVazaoMl.ToString("0.00");
|
||||
gridDados.Rows[32].Cells[1].Value = _Sensoriamento.Atuador.AnguloBarraEsquerda.ToString("0.00");
|
||||
gridDados.Rows[33].Cells[1].Value = _Sensoriamento.Atuador.AnguloBarraDireita.ToString("0.00");
|
||||
|
|
@ -660,7 +660,7 @@ namespace AgroBase.Forms.Operacoes
|
|||
{
|
||||
var Atuador = Variaveis.OperacaoEmAndamento.DispAtu.Dados;
|
||||
|
||||
bool ligado = Atuador.BombasPressurizadoras.FirstOrDefault()?.ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.Potencia)?.atual?.valor > 0;
|
||||
bool ligado = Atuador.BombasPressurizadoras.FirstOrDefault()?._Potencia > 0;
|
||||
AtuadorFuncoesGerais.DesenharAtuadores(
|
||||
pnlAtuadores,
|
||||
e,
|
||||
|
|
@ -673,7 +673,7 @@ namespace AgroBase.Forms.Operacoes
|
|||
Inicializado = x.Inicializado,
|
||||
MediaNivelFluxo = x.MediaNivelFluxo,
|
||||
Posicao = x.Posicao,
|
||||
StatusBico = x.ValoresLeituras?.FirstOrDefault(y => y.funcao == FuncoesPinout.EstadoLeitura)?.atual?.valor == Estado.Ligado,
|
||||
StatusBico = x._EstadoLeitura == Estado.Ligado,
|
||||
TempoAtuado = x.TempoAtuado,
|
||||
}).ToList(),
|
||||
ligado,
|
||||
|
|
|
|||
|
|
@ -178,9 +178,9 @@ namespace AgroBase.Forms.Operacoes
|
|||
Inicializado = x.Inicializado,
|
||||
MediaNivelFluxo = x.MediaNivelFluxo,
|
||||
Posicao = x.Posicao,
|
||||
StatusBico = x.ValoresLeituras.FirstOrDefault(y => y.funcao == FuncoesPinout.EstadoLeitura).atual.valor ?? false,
|
||||
StatusBico = x._EstadoLeitura == Enums.Estado.Ligado,
|
||||
TempoAtuado = x.TempoAtuado,
|
||||
}).ToList(), Atuador.BombasPressurizadoras.FirstOrDefault().ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.Potencia)?.atual?.valor ?? 0 > 0, Atuador.PressaoLinha, Atuador.TempoAtuado);
|
||||
}).ToList(), Atuador.BombasPressurizadoras.FirstOrDefault()._Potencia > 0, Atuador.PressaoLinha, Atuador.TempoAtuado);
|
||||
}
|
||||
|
||||
private void pnlCaminho_Paint(object sender, PaintEventArgs e)
|
||||
|
|
|
|||
|
|
@ -134,6 +134,7 @@
|
|||
sIUV = 31,
|
||||
sQAR = 32,
|
||||
sCHV = 33,
|
||||
sSRV = 34,
|
||||
}
|
||||
|
||||
public enum BotoesJoystick
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ namespace AgroBase.Models.Modules
|
|||
public List<AtuadorBicoModel> BicosPulverizadores { get; set; }
|
||||
public List<AtuadorBombaModel> BombasPressurizadoras { get; set; }
|
||||
public List<SensorModel> Sensores { get; set; }
|
||||
public List<SensorServoModel> Servos { get; set; }
|
||||
public string ScriptDeteccaoErvas { get; set; } = PythonService.ScriptWeedDetector;
|
||||
|
||||
public AsyncTaskTimerModel tmrRegistrador;
|
||||
|
|
@ -95,14 +96,29 @@ namespace AgroBase.Models.Modules
|
|||
public HerbicideCounterService ContadorCarga = new HerbicideCounterService(VariaveisEquipamento.CapacidadeReservatorio, VariaveisEquipamento.DensidadeHerbicida);
|
||||
|
||||
#region VAZAO
|
||||
private SensorModel SensorFluxoLinha => Sensores.FirstOrDefault(x => x.Componente == S_Code.sFLX && x.ID == "FLXLN");
|
||||
public double VolumeVazaoAferido { get; set; } = 0;
|
||||
public double _FluxoMlRef { get; set; } = 600;
|
||||
public double _FluxoPulsoRef { get; set; } = 538;
|
||||
public double VazaoFluxoMLpSInstantanea
|
||||
public double VazaoFluxoMLpSInstantanea => SensorFluxoLinha?.ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.Fluxo)?.atual?.valor ?? 0;
|
||||
public double VazaoFluxoMLpSInstantaneaCalc
|
||||
{
|
||||
get
|
||||
{
|
||||
return Sensores.FirstOrDefault(x => x.Componente == S_Code.sFLX)?.ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.Fluxo)?.atual?.valor ?? 0;
|
||||
int pulsos = SensorFluxoLinha?.ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.QtdPulsos)?.atual?.valor ?? 0;
|
||||
int periodo = SensorFluxoLinha?.ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.Periodo)?.atual?.valor ?? 0;
|
||||
if (pulsos <= 0 || periodo <= 0) return 0.0;
|
||||
|
||||
double frequencia = (double)pulsos / (double)periodo * 1000.0; // Hz
|
||||
|
||||
// Equação do fabricante: F = 8.1*q - 3 (q em L/min)
|
||||
double q_L_min = (frequencia + 3.0) / 8.1;
|
||||
// Limites físicos do sensor (do próprio anúncio): 0.3–10 L/min
|
||||
if (q_L_min < 0) q_L_min = 0; // evita negativo perto do zero
|
||||
if (q_L_min > 10.0) q_L_min = 10.0; // opcional: clamp no máximo
|
||||
// Converte para mL/s
|
||||
double q_mL_s = q_L_min * (1000.0 / 60.0);
|
||||
return q_mL_s;
|
||||
}
|
||||
}
|
||||
private double _somaVazao; // Acumula a soma da vazão para calcular a média
|
||||
|
|
@ -139,7 +155,8 @@ namespace AgroBase.Models.Modules
|
|||
}
|
||||
public void AtualizaPercentualErvas()
|
||||
{
|
||||
double tempoTotalOperacao = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.TempoDecorridoSeg * 1000.0;
|
||||
//double tempoTotalOperacao = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.TempoDecorridoSeg * 1000.0;
|
||||
double tempoTotalOperacao = (Variaveis.OperacaoEmAndamento.Parametros?.DadosLeitura?.Movimentacao?.TempoMovimentoSegs ?? 0) * 1000.0;
|
||||
|
||||
if (tempoTotalOperacao > 0)
|
||||
{
|
||||
|
|
@ -189,26 +206,24 @@ namespace AgroBase.Models.Modules
|
|||
#endregion
|
||||
|
||||
#region PRESSAO
|
||||
public double _PressaoVmin { get; set; } = 0.0;
|
||||
public double _PressaoVmax { get; set; } = 4.5;
|
||||
public double _PressaoMax { get; set; } = 174.045; // 1,2 MPa
|
||||
public double PressaoLinha
|
||||
private SensorModel SensorPressaoLinha
|
||||
{
|
||||
get
|
||||
{
|
||||
return Sensores.FirstOrDefault(x => x.Componente == S_Code.sPRS)?.ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.Pressao)?.atual?.valor ?? 0;
|
||||
return Sensores.FirstOrDefault(x => x.Componente == S_Code.sPRS && x.ID == "PRSLN");
|
||||
}
|
||||
}
|
||||
public double _PressaoVmin { get; set; } = 0.0;
|
||||
public double _PressaoVmax { get; set; } = 4.5;
|
||||
public double _PressaoMax { get; set; } = 174.045; // 1,2 MPa
|
||||
public double PressaoLinha => SensorPressaoLinha?.ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.Pressao)?.atual?.valor ?? 0;
|
||||
public double PressaoLinhaCalc
|
||||
{
|
||||
get
|
||||
{
|
||||
//double _LeituraPressao = ((FirmwareSensorPressao)Sensores.FirstOrDefault(x => x.Componente == S_Code.sPRS)?.Leitura)?.Leitura ?? 0;
|
||||
double _LeituraPressao = 0;
|
||||
double _LeituraPressao = SensorPressaoLinha?.ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.LeituraBruta)?.atual?.valor ?? 0;
|
||||
double tensao = FuncoesMatematicas.Map(_LeituraPressao, 0, 4095, 0, 3300) / 1000.0;
|
||||
|
||||
double pressao = FuncoesMatematicas.Map(tensao, _PressaoVmin, _PressaoVmax, 0, _PressaoMax);
|
||||
|
||||
return pressao;
|
||||
}
|
||||
}
|
||||
|
|
@ -224,7 +239,7 @@ namespace AgroBase.Models.Modules
|
|||
_EnderecoCAN_Rx = 0x12,
|
||||
_TaxaAmostragem = 1000,
|
||||
RequisitarDados = true,
|
||||
// 71 ~ 74
|
||||
// 71 ~ 73
|
||||
BicosPulverizadores = new List<AtuadorBicoModel>(),
|
||||
// 51 ~ 51
|
||||
BombasPressurizadoras = new List<AtuadorBombaModel>()
|
||||
|
|
@ -304,10 +319,22 @@ namespace AgroBase.Models.Modules
|
|||
indice = 0,
|
||||
},
|
||||
new SensorValoresLeituraModel()
|
||||
{
|
||||
funcao = FuncoesPinout.QtdPulsos,
|
||||
posicao = CanMessagePosicaoDados.Dados1,
|
||||
indice = 0,
|
||||
},
|
||||
new SensorValoresLeituraModel()
|
||||
{
|
||||
funcao = FuncoesPinout.Periodo,
|
||||
posicao = CanMessagePosicaoDados.Dados1,
|
||||
indice = 1,
|
||||
},
|
||||
new SensorValoresLeituraModel()
|
||||
{
|
||||
funcao = FuncoesPinout.Fluxo,
|
||||
posicao = CanMessagePosicaoDados.Dados1,
|
||||
indice = 0,
|
||||
indice = 2,
|
||||
analise_health = true,
|
||||
maximo = 20,
|
||||
minimo = 0,
|
||||
|
|
@ -350,9 +377,15 @@ namespace AgroBase.Models.Modules
|
|||
},
|
||||
new SensorValoresLeituraModel()
|
||||
{
|
||||
funcao = FuncoesPinout.Massa,
|
||||
funcao = FuncoesPinout.LeituraBruta,
|
||||
posicao = CanMessagePosicaoDados.Dados1,
|
||||
indice = 0,
|
||||
},
|
||||
new SensorValoresLeituraModel()
|
||||
{
|
||||
funcao = FuncoesPinout.Massa,
|
||||
posicao = CanMessagePosicaoDados.Dados1,
|
||||
indice = 1,
|
||||
analise_health = true,
|
||||
maximo = 35,
|
||||
minimo = 0,
|
||||
|
|
@ -410,9 +443,15 @@ namespace AgroBase.Models.Modules
|
|||
},
|
||||
new SensorValoresLeituraModel()
|
||||
{
|
||||
funcao = FuncoesPinout.Pressao,
|
||||
funcao = FuncoesPinout.LeituraBruta,
|
||||
posicao = CanMessagePosicaoDados.Dados1,
|
||||
indice = 0,
|
||||
},
|
||||
new SensorValoresLeituraModel()
|
||||
{
|
||||
funcao = FuncoesPinout.Pressao,
|
||||
posicao = CanMessagePosicaoDados.Dados1,
|
||||
indice = 1,
|
||||
analise_health = true,
|
||||
maximo = 120,
|
||||
minimo = 0,
|
||||
|
|
@ -587,6 +626,103 @@ namespace AgroBase.Models.Modules
|
|||
}
|
||||
},
|
||||
},
|
||||
// 91 ~ 93
|
||||
Servos = new List<SensorServoModel>()
|
||||
{
|
||||
new SensorServoModel()
|
||||
{
|
||||
ID = "SRVB1",
|
||||
ID_Num = 91,
|
||||
Descricao = "Articulaccao Bico 01",
|
||||
Componente = S_Code.sSRV,
|
||||
Controlar = true,
|
||||
Mandatorio = false,
|
||||
Funcoes = new List<FuncoesPinout>()
|
||||
{
|
||||
FuncoesPinout.Servo,
|
||||
},
|
||||
_AnguloControle = 90,
|
||||
Incremental = true,
|
||||
ValoresLeituras = new List<SensorValoresLeituraModel>()
|
||||
{
|
||||
new SensorValoresLeituraModel()
|
||||
{
|
||||
funcao = FuncoesPinout.Iniciado,
|
||||
posicao = CanMessagePosicaoDados.Status,
|
||||
indice = 0,
|
||||
},
|
||||
new SensorValoresLeituraModel()
|
||||
{
|
||||
funcao = FuncoesPinout.ServoAnguloLeitura,
|
||||
posicao = CanMessagePosicaoDados.Dados1,
|
||||
indice = 0,
|
||||
analise_health = true
|
||||
},
|
||||
}
|
||||
},
|
||||
new SensorServoModel()
|
||||
{
|
||||
ID = "SRVB2",
|
||||
ID_Num = 92,
|
||||
Descricao = "Articulaccao Bico 02",
|
||||
Componente = S_Code.sSRV,
|
||||
Controlar = true,
|
||||
Mandatorio = false,
|
||||
Funcoes = new List<FuncoesPinout>()
|
||||
{
|
||||
FuncoesPinout.Servo,
|
||||
},
|
||||
_AnguloControle = 90,
|
||||
Incremental = true,
|
||||
ValoresLeituras = new List<SensorValoresLeituraModel>()
|
||||
{
|
||||
new SensorValoresLeituraModel()
|
||||
{
|
||||
funcao = FuncoesPinout.Iniciado,
|
||||
posicao = CanMessagePosicaoDados.Status,
|
||||
indice = 0,
|
||||
},
|
||||
new SensorValoresLeituraModel()
|
||||
{
|
||||
funcao = FuncoesPinout.ServoAnguloLeitura,
|
||||
posicao = CanMessagePosicaoDados.Dados1,
|
||||
indice = 0,
|
||||
analise_health = true
|
||||
},
|
||||
}
|
||||
},
|
||||
new SensorServoModel()
|
||||
{
|
||||
ID = "SRVB3",
|
||||
ID_Num = 93,
|
||||
Descricao = "Articulaccao Bico 03",
|
||||
Componente = S_Code.sSRV,
|
||||
Controlar = true,
|
||||
Mandatorio = false,
|
||||
Funcoes = new List<FuncoesPinout>()
|
||||
{
|
||||
FuncoesPinout.Servo,
|
||||
},
|
||||
_AnguloControle = 90,
|
||||
Incremental = true,
|
||||
ValoresLeituras = new List<SensorValoresLeituraModel>()
|
||||
{
|
||||
new SensorValoresLeituraModel()
|
||||
{
|
||||
funcao = FuncoesPinout.Iniciado,
|
||||
posicao = CanMessagePosicaoDados.Status,
|
||||
indice = 0,
|
||||
},
|
||||
new SensorValoresLeituraModel()
|
||||
{
|
||||
funcao = FuncoesPinout.ServoAnguloLeitura,
|
||||
posicao = CanMessagePosicaoDados.Dados1,
|
||||
indice = 0,
|
||||
analise_health = true
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
for (int i = 0; i < Variaveis.OperacaoEmAndamento.Parametros.QtdBicos; i++)
|
||||
{
|
||||
|
|
@ -595,6 +731,7 @@ namespace AgroBase.Models.Modules
|
|||
{
|
||||
ID = "B" + posicao.ToString("00"),
|
||||
ID_Num = 70 + posicao,
|
||||
Servo_ID_Num = 90 + posicao,
|
||||
Componente = S_Code.sBIC,
|
||||
Posicao = posicao,
|
||||
Atuacoes = 0,
|
||||
|
|
@ -624,6 +761,12 @@ namespace AgroBase.Models.Modules
|
|||
funcao = FuncoesPinout.EstadoLeitura,
|
||||
posicao = CanMessagePosicaoDados.Dados1,
|
||||
indice = 0,
|
||||
},
|
||||
new SensorValoresLeituraModel()
|
||||
{
|
||||
funcao = FuncoesPinout.ServoAnguloLeitura,
|
||||
posicao = CanMessagePosicaoDados.Dados1,
|
||||
indice = 1,
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -746,6 +889,10 @@ namespace AgroBase.Models.Modules
|
|||
var sensoresConfig = SensoresConfig(Conectar, configurarTodos);
|
||||
config.AddRange(sensoresConfig);
|
||||
|
||||
// Adicionar configurações dos Servos
|
||||
var servosConfig = ServosConfig(Conectar, configurarTodos);
|
||||
config.AddRange(servosConfig);
|
||||
|
||||
// Adicionar configurações dos Bicos
|
||||
var bicosConfig = BicosConfig(Conectar, configurarTodos);
|
||||
config.AddRange(bicosConfig);
|
||||
|
|
@ -834,6 +981,27 @@ namespace AgroBase.Models.Modules
|
|||
return config;
|
||||
}
|
||||
|
||||
private List<(int, CanMessagePosicaoDados, byte[])> ServosConfig(bool Conectar, bool ConfigurarTodos)
|
||||
{
|
||||
var config = new List<(int, CanMessagePosicaoDados, byte[])>();
|
||||
|
||||
foreach (var servo in Servos.Where(x => (x.Controlar && (ConfigurarTodos ? true : x.Inicializado != Conectar)) || (!x.Controlar && x.Inicializado)))
|
||||
{
|
||||
if (!servo.Controlar && servo.Inicializado)
|
||||
{
|
||||
Conectar = false;
|
||||
}
|
||||
(CanMessagePosicaoDados posicao, var payload) = servo.ProtocoloConfiguracao(Pinout, Conectar);
|
||||
if (payload != null)
|
||||
{
|
||||
config.Add((servo.ID_Num, posicao, payload));
|
||||
}
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
public void IniciarRegistrador()
|
||||
{
|
||||
if (!(tmrRegistrador?.IsRunning ?? false))
|
||||
|
|
@ -885,53 +1053,13 @@ namespace AgroBase.Models.Modules
|
|||
AtualizaComponentesIniciados();
|
||||
}
|
||||
|
||||
public (bool, List<string>) StatusModulosATU()
|
||||
{
|
||||
var Bicos = BicosPulverizadores.Where(x => x.Comandar).ToList();
|
||||
var BicosComFalha = Bicos.Where(x => !x.Liberado).ToList();
|
||||
bool _bicosOperantes = !BicosComFalha.Any();
|
||||
|
||||
var _bomba = BombasPressurizadoras.FirstOrDefault();
|
||||
var _sensorFluxo = Sensores.FirstOrDefault(x => x.Componente == S_Code.sFLX);
|
||||
bool _sensorFluxoOperante = !_sensorFluxo?.Liberado ?? false;
|
||||
var _sensorMassa = Sensores.FirstOrDefault(x => x.Componente == S_Code.sMAS);
|
||||
bool _sensorMassaOperante = !_sensorMassa?.Liberado ?? false;
|
||||
var _sensorPressao = Sensores.FirstOrDefault(x => x.Componente == S_Code.sPRS);
|
||||
bool _sensorPressaoOperante = !_sensorPressao?.Liberado ?? false;
|
||||
|
||||
List<string> ModsComFalha = BicosComFalha.Select(x => x.ID).ToList();
|
||||
|
||||
bool _bombaOperante = _bomba?.Liberado ?? false;
|
||||
|
||||
if (!_bombaOperante)
|
||||
{
|
||||
ModsComFalha.Add(_bomba?.ID);
|
||||
}
|
||||
if (!_sensorFluxoOperante)
|
||||
{
|
||||
ModsComFalha.Add(_sensorFluxo.ID);
|
||||
}
|
||||
if (!_sensorMassaOperante)
|
||||
{
|
||||
ModsComFalha.Add(_sensorMassa.ID);
|
||||
}
|
||||
if (!_sensorPressaoOperante)
|
||||
{
|
||||
ModsComFalha.Add(_sensorPressao.ID);
|
||||
}
|
||||
|
||||
bool _atuadorOperante = _bombaOperante && _bicosOperantes && _sensorPressaoOperante && _sensorMassaOperante && _sensorFluxoOperante;
|
||||
|
||||
return (_atuadorOperante, ModsComFalha);
|
||||
}
|
||||
|
||||
private void VerificaControleLeitura()
|
||||
{
|
||||
if (true) // !frmDiagnosticos.Diagnosticando
|
||||
{
|
||||
foreach (var bico in BicosPulverizadores.Where(x => x.Comandar && x.Inicializado))
|
||||
{
|
||||
Estado leituraEstado = (Estado?)(bico.ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.EstadoLeitura)?.atual?.valor) ?? Estado.Desligado;
|
||||
Estado leituraEstado = bico._EstadoLeitura;
|
||||
Estado comandoEstado = bico.ComandoAtuar ? Estado.Ligado : Estado.Desligado;
|
||||
if (leituraEstado != comandoEstado)
|
||||
{
|
||||
|
|
@ -942,7 +1070,7 @@ namespace AgroBase.Models.Modules
|
|||
var bomba = BombasPressurizadoras.FirstOrDefault(x => x.Comandar && x.Inicializado);
|
||||
if (bomba != null)
|
||||
{
|
||||
bool leituraEstado = (bomba.ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.Potencia)?.atual?.valor ?? 0) > 0;
|
||||
bool leituraEstado = bomba._Potencia > 0;
|
||||
|
||||
// Desliga a bomba caso esteja ligada e o nivel de herbicida caiu
|
||||
if (ContadorCarga.PercentualAtual < VariaveisEquipamento.PercentualReservatorioMin && leituraEstado == true)
|
||||
|
|
@ -960,6 +1088,14 @@ namespace AgroBase.Models.Modules
|
|||
GeneralJoystick.EnviarComandoAtuador(bomba.Componente, bomba.ID, Status: bomba.ComandoAtuar);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var servo in Servos.Where(x => x.Controlar && x.Inicializado))
|
||||
{
|
||||
if (servo._AnguloLeiutra != servo._AnguloControle)
|
||||
{
|
||||
GeneralJoystick.EnviarComandoSensoriamento(S_Code.sFRO, servo.ID, servo._AnguloControle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -983,6 +1119,10 @@ namespace AgroBase.Models.Modules
|
|||
{
|
||||
sensor.Inicializado = false;
|
||||
}
|
||||
foreach (var servo in Servos.Where(x => x.Inicializado && x.UltimaLeitura.AddMilliseconds(TempoLimiteConexao) < Agora))
|
||||
{
|
||||
servo.Inicializado = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1126,6 +1266,7 @@ namespace AgroBase.Models.Modules
|
|||
public int Posicao { get; set; }
|
||||
public S_Code Componente { get; set; } = S_Code.sBIC;
|
||||
public bool AtuacaoNivelAlto { get; set; }
|
||||
public int Servo_ID_Num { get; set; }
|
||||
public double AnguloControle { get; set; }
|
||||
public double AnguloAbertura { get; set; }
|
||||
private bool _atuado;
|
||||
|
|
@ -1162,7 +1303,7 @@ namespace AgroBase.Models.Modules
|
|||
}
|
||||
}
|
||||
public List<SensorValoresLeituraModel> ValoresLeituras { get; set; }
|
||||
|
||||
public Estado _EstadoLeitura => ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.EstadoLeitura)?.atual?.valor ?? Estado.Desligado;
|
||||
|
||||
|
||||
public (CanMessagePosicaoDados, byte[]) ProtocoloConfiguracao(PinoutDataModel pinout, bool conectar)
|
||||
|
|
@ -1174,6 +1315,7 @@ namespace AgroBase.Models.Modules
|
|||
(byte)Componente,
|
||||
(byte)(conectar ? 1 : 0),
|
||||
(byte)(AtuacaoNivelAlto ? 1 : 0),
|
||||
(byte)Servo_ID_Num,
|
||||
(byte)(pino?.Barramento ?? TiposBarramentos.CONTROLADOR),
|
||||
(byte)(pino?.Pino ?? PinoutUtils.PINO_INVALIDO)
|
||||
};
|
||||
|
|
@ -1188,7 +1330,8 @@ namespace AgroBase.Models.Modules
|
|||
CanMessagePosicaoDados.Command1,
|
||||
new byte[]
|
||||
{
|
||||
(byte)(ComandoAtuar ? Estado.Ligado : Estado.Desligado)
|
||||
(byte)(ComandoAtuar ? Estado.Ligado : Estado.Desligado),
|
||||
(byte)AnguloControle
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
@ -1259,6 +1402,7 @@ namespace AgroBase.Models.Modules
|
|||
public int ID_Num { get; set; }
|
||||
public bool ComandoAtuar { get; set; }
|
||||
public S_Code Componente { get; set; } = S_Code.sBMB;
|
||||
public int Sensor_ID_Num { get; set; }
|
||||
public bool Comandar { get; set; }
|
||||
public bool Mandatorio { get; set; }
|
||||
public bool Liberado
|
||||
|
|
@ -1278,6 +1422,9 @@ namespace AgroBase.Models.Modules
|
|||
}
|
||||
}
|
||||
public List<SensorValoresLeituraModel> ValoresLeituras { get; set; }
|
||||
public Estado _EstadoLeitura => ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.EstadoLeitura)?.atual?.valor ?? Estado.Desligado;
|
||||
public double _Potencia => ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.Potencia)?.atual?.valor ?? 0;
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1289,6 +1436,7 @@ namespace AgroBase.Models.Modules
|
|||
(byte)Componente,
|
||||
(byte)(conectar ? 1 : 0),
|
||||
(byte)Variaveis.OperacaoEmAndamento.Parametros.Controle.AtuPressaoLinha,
|
||||
(byte)Sensor_ID_Num,
|
||||
(byte)(pinout.Pinos.FirstOrDefault(x => x.ComponenteID == ID && x.Funcao == FuncoesPinout.ENA)?.Pino ?? PinoutUtils.PINO_INVALIDO),
|
||||
(byte)(pinout.Pinos.FirstOrDefault(x => x.Funcao == FuncoesPinout.CS)?.Pino ?? PinoutUtils.PINO_INVALIDO),
|
||||
};
|
||||
|
|
@ -1503,21 +1651,6 @@ namespace AgroBase.Models.Modules
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public class FirmwareBombaPressurizadora : IFirmwareSensorBase
|
||||
{
|
||||
public DateTime Momento { get; set; }
|
||||
public string ID { get; set; }
|
||||
public int ID_Num { get; set; }
|
||||
public bool Iniciado { get; set; }
|
||||
public CanCommandFreqModel<Estado> Estado { get; set; } = new CanCommandFreqModel<Estado>();
|
||||
public CanCommandFreqModel<double> Potencia { get; set; } = new CanCommandFreqModel<double>();
|
||||
public CanCommandFreqModel<double> PressaoSP { get; set; } = new CanCommandFreqModel<double>();
|
||||
public CanCommandFreqModel<double> Pressao { get; set; } = new CanCommandFreqModel<double>();
|
||||
}
|
||||
|
||||
public class AtuadorMensagemJsonModel
|
||||
{
|
||||
public DateTime Momento { get; set; }
|
||||
|
|
@ -1527,9 +1660,10 @@ namespace AgroBase.Models.Modules
|
|||
public string Mod_ID { get; set; }
|
||||
public int QualidadeWifi { get; set; }
|
||||
public int LatenciaLoop { get; set; }
|
||||
public List<AtuadorBicoModel> BicosPulverizadores { get; set; } = new List<AtuadorBicoModel>();
|
||||
public List<AtuadorBombaModel> BombasPressurizadoras { get; set; } = new List<AtuadorBombaModel>();
|
||||
public List<SensorModel> Sensores { get; set; } = new List<SensorModel>();
|
||||
public List<AtuadorBicoModel> BicosPulverizadores { get; set; }
|
||||
public List<AtuadorBombaModel> BombasPressurizadoras { get; set; }
|
||||
public List<SensorModel> Sensores { get; set; }
|
||||
public List<SensorServoModel> Servos { get; set; }
|
||||
public DateTime UltimoComandoRespondido { get; set; }
|
||||
}
|
||||
|
||||
|
|
@ -1566,8 +1700,9 @@ namespace AgroBase.Models.Modules
|
|||
var sensor = Disp.Sensores.FirstOrDefault(x => x.ID_Num == ID_Num);
|
||||
var bico = Disp.BicosPulverizadores.FirstOrDefault(x => x.ID_Num == ID_Num);
|
||||
var bomba = Disp.BombasPressurizadoras.FirstOrDefault(x => x.ID_Num == ID_Num);
|
||||
var servo = Disp.Servos.FirstOrDefault(x => x.ID_Num == ID_Num);
|
||||
|
||||
return sensor?.Componente ?? bico?.Componente ?? bomba?.Componente ?? S_Code.sVZO;
|
||||
return sensor?.Componente ?? bico?.Componente ?? bomba?.Componente ?? servo?.Componente ?? S_Code.sVZO;
|
||||
}
|
||||
|
||||
private void AtualizarDados(int CompID_Num, CanMessagePosicaoDados Posicao, S_Code componente, List<dynamic> Parametros)
|
||||
|
|
@ -1577,12 +1712,14 @@ namespace AgroBase.Models.Modules
|
|||
var sensor = Dados.Sensores.FirstOrDefault(x => x.ID_Num == CompID_Num);
|
||||
var bomba = Dados.BombasPressurizadoras.FirstOrDefault(x => x.ID_Num == CompID_Num);
|
||||
var bico = Dados.BicosPulverizadores.FirstOrDefault(x => x.ID_Num == CompID_Num);
|
||||
var servo = Dados.Servos.FirstOrDefault(x => x.ID_Num == CompID_Num);
|
||||
|
||||
List<SensorValoresLeituraModel> valoresLeituras = new List<SensorValoresLeituraModel>();
|
||||
|
||||
if (sensor != null) valoresLeituras = sensor.ValoresLeituras;
|
||||
else if (bomba != null) valoresLeituras = bomba.ValoresLeituras;
|
||||
else if (bico != null) valoresLeituras = bico.ValoresLeituras;
|
||||
else if (servo != null) valoresLeituras = servo.ValoresLeituras;
|
||||
|
||||
for (int i = 0; i < valoresLeituras.Where(x => x.posicao == Posicao).Count(); i++)
|
||||
{
|
||||
|
|
@ -1610,6 +1747,8 @@ namespace AgroBase.Models.Modules
|
|||
bomba.Inicializado = v;
|
||||
if (bico != null)
|
||||
bico.Inicializado = v;
|
||||
if (servo != null)
|
||||
servo.Inicializado = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1681,7 +1820,8 @@ namespace AgroBase.Models.Modules
|
|||
case CanMessagePosicaoDados.Dados1:
|
||||
{
|
||||
Estado estado = (Estado)data[2];
|
||||
AtualizarDados(ID_Num, posicao, componente, new List<dynamic>() { estado });
|
||||
int angulo = data[3];
|
||||
AtualizarDados(ID_Num, posicao, componente, new List<dynamic>() { estado, angulo });
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1699,8 +1839,10 @@ namespace AgroBase.Models.Modules
|
|||
}
|
||||
case CanMessagePosicaoDados.Dados1:
|
||||
{
|
||||
double vazao = ConverterByteParaDouble(data, 2);
|
||||
AtualizarDados(ID_Num, posicao, componente, new List<dynamic>() { vazao });
|
||||
int qtdPulsos = data[2];
|
||||
ushort periodo = Converter2BytesU16(data, 3);
|
||||
double vazao = ConverterByteParaDouble(data, 5);
|
||||
AtualizarDados(ID_Num, posicao, componente, new List<dynamic>() { qtdPulsos, periodo, vazao });
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1718,8 +1860,9 @@ namespace AgroBase.Models.Modules
|
|||
}
|
||||
case CanMessagePosicaoDados.Dados1:
|
||||
{
|
||||
double massa = ConverterByteParaDouble(data, 2);
|
||||
AtualizarDados(ID_Num, posicao, componente, new List<dynamic>() { massa });
|
||||
double raw = ConverterByteParaDouble(data, 2);
|
||||
double massa = ConverterByteParaDouble(data, 4);
|
||||
AtualizarDados(ID_Num, posicao, componente, new List<dynamic>() { raw, massa });
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1737,8 +1880,9 @@ namespace AgroBase.Models.Modules
|
|||
}
|
||||
case CanMessagePosicaoDados.Dados1:
|
||||
{
|
||||
double pressao = ConverterByteParaDouble(data, 2);
|
||||
AtualizarDados(ID_Num, posicao, componente, new List<dynamic>() { pressao });
|
||||
ushort raw = Converter2BytesU16(data, 2);
|
||||
double pressao = ConverterByteParaDouble(data, 4);
|
||||
AtualizarDados(ID_Num, posicao, componente, new List<dynamic>() { raw, pressao });
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1787,9 +1931,28 @@ namespace AgroBase.Models.Modules
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case S_Code.sSRV:
|
||||
{
|
||||
switch (posicao)
|
||||
{
|
||||
case CanMessagePosicaoDados.Status:
|
||||
{
|
||||
bool Iniciado = data[2] == 1;
|
||||
AtualizarDados(ID_Num, posicao, componente, new List<dynamic>() { Iniciado });
|
||||
break;
|
||||
}
|
||||
case CanMessagePosicaoDados.Dados1:
|
||||
{
|
||||
int angulo = data[2];
|
||||
AtualizarDados(ID_Num, posicao, componente, new List<dynamic>() { angulo });
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Dados.DadosLeitura.UltimoComandoRespondido = DateTime.Now;
|
||||
|
||||
Variaveis.OperacaoEmAndamento.DispAtu.Dados.AtualizarDadosSensoresExternos(componente, ID_Num);
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ namespace AgroBase.Models.Modules
|
|||
|
||||
public string IP_Mov { get; set; } = Variaveis.FaixaIPethernet + ".10";
|
||||
public string IP_Dir { get; set; } = Variaveis.FaixaIPethernet + ".11";
|
||||
public DateTime UltimoTickRegistrador = DateTime.MinValue;
|
||||
|
||||
public static int LogsManter { get; set; } = 60;
|
||||
public AsyncTaskTimerModel tmrRegistrador;
|
||||
|
|
@ -138,6 +139,7 @@ namespace AgroBase.Models.Modules
|
|||
Dados.DistanciaPercorridaOperacao = 0;
|
||||
Dados.VelocidadeMedia = 0;
|
||||
Dados.TempoEmAtividade = 0;
|
||||
Dados.UltimoTickRegistrador = DateTime.MinValue;
|
||||
Dados.Modulos.ForEach(x =>
|
||||
{
|
||||
x.MovMotor.AlarmeSensores = false;
|
||||
|
|
@ -220,7 +222,11 @@ namespace AgroBase.Models.Modules
|
|||
var UltimaDirecao = Variaveis.OperacaoEmAndamento.Controle.TiposControle.FirstOrDefault(x => x.Tipo == T_Code.Mov)?.UltimaDirecao ?? Direcao.Parado;
|
||||
if (UltimaDirecao != Direcao.Parado)
|
||||
{
|
||||
double tempo = _TaxaAmostragem / 1000.0;
|
||||
//double tempo = _TaxaAmostragem / 1000.0;
|
||||
DateTime agora = DateTime.Now;
|
||||
double tempo = UltimoTickRegistrador == DateTime.MinValue ? 0 : (agora - UltimoTickRegistrador).TotalSeconds;
|
||||
UltimoTickRegistrador = agora;
|
||||
|
||||
double distancia = tempo * VelocidadeMedia;
|
||||
DistanciaPercorridaTotal += distancia;
|
||||
DistanciaPercorridaParcial += ((UltimaDirecao == Direcao.Frente ? 1 : UltimaDirecao == Direcao.Tras ? -1 : 0) * distancia);
|
||||
|
|
|
|||
|
|
@ -405,7 +405,7 @@ namespace AgroBase.Models.Modules
|
|||
ModbusDI,
|
||||
ModbusRO,
|
||||
ModbusDE_RE,
|
||||
ServoFreio,
|
||||
Servo,
|
||||
Potenciometro,
|
||||
M0,
|
||||
M1,
|
||||
|
|
@ -432,7 +432,9 @@ namespace AgroBase.Models.Modules
|
|||
CodAlarme,
|
||||
LeituraBruta,
|
||||
LeituraAngulo,
|
||||
Cooler
|
||||
Cooler,
|
||||
QtdPulsos,
|
||||
Periodo
|
||||
}
|
||||
|
||||
public static class PinoutUtils
|
||||
|
|
|
|||
|
|
@ -1211,10 +1211,16 @@ namespace AgroBase.Models.Modules
|
|||
indice = 0,
|
||||
},
|
||||
new SensorValoresLeituraModel()
|
||||
{
|
||||
funcao = FuncoesPinout.LeituraBruta,
|
||||
posicao = CanMessagePosicaoDados.Dados1,
|
||||
indice = 0,
|
||||
},
|
||||
new SensorValoresLeituraModel()
|
||||
{
|
||||
funcao = FuncoesPinout.LuzUV,
|
||||
posicao = CanMessagePosicaoDados.Dados1,
|
||||
indice = 0,
|
||||
indice = 1,
|
||||
analise_health = true,
|
||||
maximo = 11.0,
|
||||
minimo = 0.0,
|
||||
|
|
@ -1263,10 +1269,16 @@ namespace AgroBase.Models.Modules
|
|||
indice = 0,
|
||||
},
|
||||
new SensorValoresLeituraModel()
|
||||
{
|
||||
funcao = FuncoesPinout.LeituraBruta,
|
||||
posicao = CanMessagePosicaoDados.Dados1,
|
||||
indice = 0,
|
||||
},
|
||||
new SensorValoresLeituraModel()
|
||||
{
|
||||
funcao = FuncoesPinout.Gas,
|
||||
posicao = CanMessagePosicaoDados.Dados1,
|
||||
indice = 0,
|
||||
indice = 1,
|
||||
analise_health = true,
|
||||
maximo = 600.0,
|
||||
minimo = 0.0,
|
||||
|
|
@ -1315,10 +1327,16 @@ namespace AgroBase.Models.Modules
|
|||
indice = 0,
|
||||
},
|
||||
new SensorValoresLeituraModel()
|
||||
{
|
||||
funcao = FuncoesPinout.LeituraBruta,
|
||||
posicao = CanMessagePosicaoDados.Dados1,
|
||||
indice = 0,
|
||||
},
|
||||
new SensorValoresLeituraModel()
|
||||
{
|
||||
funcao = FuncoesPinout.Gas,
|
||||
posicao = CanMessagePosicaoDados.Dados1,
|
||||
indice = 0,
|
||||
indice = 1,
|
||||
analise_health = true,
|
||||
maximo = 400.0,
|
||||
minimo = 0.0,
|
||||
|
|
@ -1510,10 +1528,16 @@ namespace AgroBase.Models.Modules
|
|||
indice = 0,
|
||||
},
|
||||
new SensorValoresLeituraModel()
|
||||
{
|
||||
funcao = FuncoesPinout.LeituraBruta,
|
||||
posicao = CanMessagePosicaoDados.Dados1,
|
||||
indice = 0,
|
||||
},
|
||||
new SensorValoresLeituraModel()
|
||||
{
|
||||
funcao = FuncoesPinout.Chuva,
|
||||
posicao = CanMessagePosicaoDados.Dados1,
|
||||
indice = 0,
|
||||
indice = 1,
|
||||
analise_health = true,
|
||||
maximo = 100.0,
|
||||
minimo = 0.0,
|
||||
|
|
@ -1753,12 +1777,12 @@ namespace AgroBase.Models.Modules
|
|||
ID = "FROET",
|
||||
ID_Num = 41,
|
||||
Descricao = "Freio Motor ET",
|
||||
Componente = S_Code.sFRO,
|
||||
Componente = S_Code.sSRV,
|
||||
Controlar = true,
|
||||
Mandatorio = false,
|
||||
Funcoes = new List<FuncoesPinout>()
|
||||
{
|
||||
FuncoesPinout.ServoFreio,
|
||||
FuncoesPinout.Servo,
|
||||
},
|
||||
_AnguloControle = 0,
|
||||
Incremental = true,
|
||||
|
|
@ -1784,12 +1808,12 @@ namespace AgroBase.Models.Modules
|
|||
ID = "FROEF",
|
||||
ID_Num = 42,
|
||||
Descricao = "Freio Motor EF",
|
||||
Componente = S_Code.sFRO,
|
||||
Componente = S_Code.sSRV,
|
||||
Controlar = false,
|
||||
Mandatorio = false,
|
||||
Funcoes = new List<FuncoesPinout>()
|
||||
{
|
||||
FuncoesPinout.ServoFreio,
|
||||
FuncoesPinout.Servo,
|
||||
},
|
||||
_AnguloControle = 0,
|
||||
Incremental = true,
|
||||
|
|
@ -1815,12 +1839,12 @@ namespace AgroBase.Models.Modules
|
|||
ID = "FRODT",
|
||||
ID_Num = 43,
|
||||
Descricao = "Freio Motor DT",
|
||||
Componente = S_Code.sFRO,
|
||||
Componente = S_Code.sSRV,
|
||||
Controlar = true,
|
||||
Mandatorio = false,
|
||||
Funcoes = new List<FuncoesPinout>()
|
||||
{
|
||||
FuncoesPinout.ServoFreio,
|
||||
FuncoesPinout.Servo,
|
||||
},
|
||||
_AnguloControle = 180,
|
||||
Incremental = false,
|
||||
|
|
@ -1846,12 +1870,12 @@ namespace AgroBase.Models.Modules
|
|||
ID = "FRODF",
|
||||
ID_Num = 44,
|
||||
Descricao = "Freio Motor DF",
|
||||
Componente = S_Code.sFRO,
|
||||
Componente = S_Code.sSRV,
|
||||
Controlar = false,
|
||||
Mandatorio = false,
|
||||
Funcoes = new List<FuncoesPinout>()
|
||||
{
|
||||
FuncoesPinout.ServoFreio,
|
||||
FuncoesPinout.Servo,
|
||||
},
|
||||
_AnguloControle = 180,
|
||||
Incremental = false,
|
||||
|
|
@ -2263,35 +2287,6 @@ namespace AgroBase.Models.Modules
|
|||
AtualizaComponentesIniciados();
|
||||
}
|
||||
|
||||
public (bool, List<string>) StatusModulosSEN()
|
||||
{
|
||||
var _Sensores = Sensores?.Where(x => x.Aferir).ToList();
|
||||
var _SensoresComFalha = _Sensores?.Where(x => !x.Liberado).ToList();
|
||||
bool _sensoresOperantes = (_SensoresComFalha?.Count() ?? 0) < (_Sensores?.Count() ?? 0);
|
||||
|
||||
var _Sinaleiros = Sinaleiros?.ToList();
|
||||
var _SinaleirosComFalha = _Sinaleiros?.Where(x => !x.Inicializado).ToList();
|
||||
bool _sinaleirosOperantes = !(_SinaleirosComFalha?.Any() ?? false);
|
||||
|
||||
var _Reles = Reles?.Where(x => x.Controlar).ToList();
|
||||
var _RelesComFalha = _Reles?.Where(x => !x.Liberado).ToList();
|
||||
bool _relesOperantes = !(_RelesComFalha?.Any() ?? false);
|
||||
|
||||
var _Servos = Servos?.Where(x => x.Controlar).ToList();
|
||||
var _ServosComFalha = _Servos?.Where(x => !x.Liberado).ToList();
|
||||
bool _servosOperantes = !(_ServosComFalha?.Any() ?? false);
|
||||
|
||||
bool _sensoriamentoOperante = _sinaleirosOperantes && _sensoresOperantes && _relesOperantes && _servosOperantes;
|
||||
List<string> ModsComFalha =
|
||||
(_SensoresComFalha?.Select(x => x.ID) ?? new List<string>())
|
||||
.Union(_SinaleirosComFalha?.Select(x => x.ID) ?? new List<string>())
|
||||
.Union(_RelesComFalha?.Select(x => x.ID) ?? new List<string>())
|
||||
.Union(_ServosComFalha?.Select(x => x.ID) ?? new List<string>())
|
||||
.ToList();
|
||||
|
||||
return (_sensoriamentoOperante, ModsComFalha);
|
||||
}
|
||||
|
||||
private void VerificaControleLeitura()
|
||||
{
|
||||
if (true) // !frmDiagnosticos.Diagnosticando
|
||||
|
|
@ -2334,8 +2329,7 @@ namespace AgroBase.Models.Modules
|
|||
|
||||
foreach (var servo in Servos.Where(x => x.Controlar && x.Inicializado))
|
||||
{
|
||||
int leituraAngulo = (int?)(servo.ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.ServoAnguloLeitura)?.atual?.valor) ?? 0;
|
||||
if (leituraAngulo != servo._AnguloControle)
|
||||
if (servo._AnguloLeiutra != servo._AnguloControle)
|
||||
{
|
||||
GeneralJoystick.EnviarComandoSensoriamento(S_Code.sFRO, servo.ID, servo._AnguloControle);
|
||||
}
|
||||
|
|
@ -2369,73 +2363,6 @@ namespace AgroBase.Models.Modules
|
|||
}
|
||||
}
|
||||
|
||||
public void AtualizarStatusComponentes()
|
||||
{
|
||||
var StatusSaudaveis = new List<StatusModulo>() { StatusModulo.Desconectado, StatusModulo.Falha };
|
||||
|
||||
var saudeSen = RedisService.GetField<ManagerWorkerMessageResponseModulosPendentesSaudeModel>(RedisService.ModKey(T_Code.Sen), "saude");
|
||||
DadosLeitura.Conectado = !StatusSaudaveis.Contains(saudeSen?.status ?? StatusModulo.Desconectado);
|
||||
|
||||
if (DadosLeitura.Conectado)
|
||||
{
|
||||
var objetos =
|
||||
Sensores
|
||||
.Select(x => new
|
||||
{
|
||||
Chave = "sensores",
|
||||
Componente = x.Componente,
|
||||
ID_Num = x.ID_Num
|
||||
})
|
||||
.Union(Servos
|
||||
.Select(x => new
|
||||
{
|
||||
Chave = "servos",
|
||||
Componente = x.Componente,
|
||||
ID_Num = x.ID_Num
|
||||
}))
|
||||
.ToList();
|
||||
|
||||
foreach (var sensor in objetos)
|
||||
{
|
||||
string chave = sensor.Chave;
|
||||
int tipo = (int)sensor.Componente;
|
||||
int id = sensor.ID_Num;
|
||||
string basePath = $"{chave}.{tipo}.{id}";
|
||||
|
||||
var saude = RedisService.GetField<ManagerWorkerMessageResponseModulosPendentesSaudeModel>(RedisService.ModKey(T_Code.Sen), $"{basePath}.saude");
|
||||
bool inicializado = !StatusSaudaveis.Contains(saude?.status ?? StatusModulo.Desconectado);
|
||||
switch (chave)
|
||||
{
|
||||
case "sensores":
|
||||
Sensores.FirstOrDefault(x => x.ID_Num == sensor.ID_Num).Inicializado = inicializado;
|
||||
break;
|
||||
case "servos":
|
||||
Servos.FirstOrDefault(x => x.ID_Num == sensor.ID_Num).Inicializado = inicializado;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var led in Sinaleiros.Where(x => x.Inicializado))
|
||||
{
|
||||
led.Inicializado = false;
|
||||
}
|
||||
foreach (var rele in Reles.Where(x => x.Inicializado))
|
||||
{
|
||||
rele.Inicializado = false;
|
||||
}
|
||||
foreach (var servo in Servos.Where(x => x.Inicializado))
|
||||
{
|
||||
servo.Inicializado = false;
|
||||
}
|
||||
foreach (var sensor in Sensores.Where(x => x.Inicializado))
|
||||
{
|
||||
sensor.Inicializado = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class SensorModel
|
||||
|
|
@ -2562,7 +2489,6 @@ namespace AgroBase.Models.Modules
|
|||
}
|
||||
public bool AtuacaoNivelAlto { get; set; }
|
||||
public Estado StatusControle { get; set; }
|
||||
public Estado StatusLeitura => ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.EstadoLeitura)?.atual?.valor ?? Estado.Desligado;
|
||||
public bool Inicializado { get; set; }
|
||||
public DateTime UltimaLeitura
|
||||
{
|
||||
|
|
@ -2572,6 +2498,8 @@ namespace AgroBase.Models.Modules
|
|||
}
|
||||
}
|
||||
public List<SensorValoresLeituraModel> ValoresLeituras { get; set; }
|
||||
public Estado _EstadoLeitura => ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.EstadoLeitura)?.atual?.valor ?? Estado.Desligado;
|
||||
|
||||
|
||||
public (CanMessagePosicaoDados, byte[]) ProtocoloConfiguracao(PinoutDataModel pinout, bool conectar)
|
||||
{
|
||||
|
|
@ -2718,19 +2646,6 @@ namespace AgroBase.Models.Modules
|
|||
}
|
||||
}
|
||||
|
||||
public class SenSensorimanetoGrafico
|
||||
{
|
||||
public DateTime Momento { get; set; }
|
||||
public string ComponenteID { get; set; }
|
||||
public S_Code Componente { get; set; }
|
||||
public double Leitura1 { get; set; }
|
||||
public double Leitura2 { get; set; }
|
||||
public double Leitura3 { get; set; }
|
||||
public double Leitura4 { get; set; }
|
||||
public bool AlarmeMaxima { get; set; }
|
||||
public bool AlarmeMinima { get; set; }
|
||||
}
|
||||
|
||||
public class SensorParametroModel
|
||||
{
|
||||
public string Descricao { get; set; }
|
||||
|
|
@ -2779,247 +2694,6 @@ namespace AgroBase.Models.Modules
|
|||
public string unidade_medida { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class FirmwareSensorTemperaturaNTC : IFirmwareSensorBase
|
||||
{
|
||||
public DateTime Momento { get; set; }
|
||||
public string ID { get; set; }
|
||||
public int ID_Num { get; set; }
|
||||
public bool Iniciado { get; set; }
|
||||
public CanCommandFreqModel<double> Temperatura { get; set; } = new CanCommandFreqModel<double>();
|
||||
}
|
||||
|
||||
public class FirmwareSensorCorrente : IFirmwareSensorBase
|
||||
{
|
||||
public DateTime Momento { get; set; }
|
||||
public string ID { get; set; }
|
||||
public int ID_Num { get; set; }
|
||||
public bool Iniciado { get; set; }
|
||||
public CanCommandFreqModel<double> BusVoltage { get; set; } = new CanCommandFreqModel<double>();
|
||||
public CanCommandFreqModel<double> ShuntVoltage { get; set; } = new CanCommandFreqModel<double>();
|
||||
public CanCommandFreqModel<double> Current { get; set; } = new CanCommandFreqModel<double>();
|
||||
public CanCommandFreqModel<double> Power { get; set; } = new CanCommandFreqModel<double>();
|
||||
public CanCommandFreqModel<double> Energy { get; set; } = new CanCommandFreqModel<double>();
|
||||
public CanCommandFreqModel<double> Temperature { get; set; } = new CanCommandFreqModel<double>();
|
||||
}
|
||||
|
||||
public class FirmwareSinaleiro : IFirmwareSensorBase
|
||||
{
|
||||
public DateTime Momento { get; set; }
|
||||
public string ID { get; set; }
|
||||
public int ID_Num { get; set; }
|
||||
public bool Iniciado { get; set; }
|
||||
public CanCommandFreqModel<StatusLED> Leitura { get; set; } = new CanCommandFreqModel<StatusLED>();
|
||||
public CanCommandFreqModel<StatusLED> Comando { get; set; } = new CanCommandFreqModel<StatusLED>();
|
||||
}
|
||||
|
||||
public class FirmwareRele : IFirmwareSensorBase
|
||||
{
|
||||
public DateTime Momento { get; set; }
|
||||
public string ID { get; set; }
|
||||
public int ID_Num { get; set; }
|
||||
public bool Iniciado { get; set; }
|
||||
public CanCommandFreqModel<Estado> Leitura { get; set; } = new CanCommandFreqModel<Estado>();
|
||||
}
|
||||
|
||||
public class FirmwareServoFreio : IFirmwareSensorBase
|
||||
{
|
||||
public DateTime Momento { get; set; }
|
||||
public string ID { get; set; }
|
||||
public int ID_Num { get; set; }
|
||||
public bool Iniciado { get; set; }
|
||||
public CanCommandFreqModel<double> Angulo { get; set; } = new CanCommandFreqModel<double>();
|
||||
}
|
||||
|
||||
public class FirmwareSensorFluxo : IFirmwareSensorBase
|
||||
{
|
||||
public DateTime Momento { get; set; }
|
||||
public string ID { get; set; }
|
||||
public int ID_Num { get; set; }
|
||||
public bool Iniciado { get; set; }
|
||||
public CanCommandFreqModel<double> Vazao { get; set; } = new CanCommandFreqModel<double>();
|
||||
}
|
||||
|
||||
public class FirmwareSensorMassa : IFirmwareSensorBase
|
||||
{
|
||||
public DateTime Momento { get; set; }
|
||||
public string ID { get; set; }
|
||||
public int ID_Num { get; set; }
|
||||
public bool Iniciado { get; set; }
|
||||
public CanCommandFreqModel<double> Massa { get; set; } = new CanCommandFreqModel<double>();
|
||||
}
|
||||
|
||||
public class FirmwareSensorPressao : IFirmwareSensorBase
|
||||
{
|
||||
public DateTime Momento { get; set; }
|
||||
public string ID { get; set; }
|
||||
public int ID_Num { get; set; }
|
||||
public bool Iniciado { get; set; }
|
||||
public CanCommandFreqModel<double> Pressao { get; set; } = new CanCommandFreqModel<double>();
|
||||
}
|
||||
|
||||
public class FirmwareSensorIMU : IFirmwareSensorBase
|
||||
{
|
||||
public DateTime Momento { get; set; }
|
||||
public string ID { get; set; }
|
||||
public int ID_Num { get; set; }
|
||||
public bool Iniciado { get; set; }
|
||||
public double AccX { get; set; }
|
||||
public double AccY { get; set; }
|
||||
public double AccZ { get; set; }
|
||||
public double GyrX { get; set; }
|
||||
public double GyrY { get; set; }
|
||||
public double GyrZ { get; set; }
|
||||
public double MagX { get; set; }
|
||||
public double MagY { get; set; }
|
||||
public double MagZ { get; set; }
|
||||
public double Temperatura { get; set; }
|
||||
public double Pressao { get; set; }
|
||||
public double Altitude { get; set; }
|
||||
public double Roll { get; set; }
|
||||
public double Pitch { get; set; }
|
||||
public double Yaw { get; set; }
|
||||
public double YawFixed
|
||||
{
|
||||
get
|
||||
{
|
||||
double angulo = Yaw;
|
||||
|
||||
// ✅ Aplica o offset armazenado
|
||||
return GPSUtils.NormalizarAngulo(GPSUtils.NormalizarAngulo(angulo) + Offset);
|
||||
}
|
||||
}
|
||||
|
||||
public double Offset { get; set; } = 0.0;
|
||||
private DateTime ultimaAtualizacaoOffset = DateTime.MinValue;
|
||||
public void AtualizarOffset(GPSModel UltimaLeitura)
|
||||
{
|
||||
// Verifica se a qualidade do GPS é boa
|
||||
if (UltimaLeitura.QualidadeFix == TiposCorrecaoGPS.RTKFixo || UltimaLeitura.QualidadeFix == TiposCorrecaoGPS.RTKFlutuante)
|
||||
{
|
||||
// Só atualiza o offset se a última atualização foi há pelo menos 2 segundos (evita variações rápidas)
|
||||
if ((DateTime.Now - ultimaAtualizacaoOffset).TotalSeconds > 2)
|
||||
{
|
||||
// Suaviza a mudança do offset para evitar grandes variações
|
||||
double novoOffset = UltimaLeitura.OrientacaoReal - YawFixed;
|
||||
Offset = (Offset * 0.8) + (novoOffset * 0.2); // Filtro exponencial
|
||||
|
||||
// Atualiza o tempo da última atualização
|
||||
ultimaAtualizacaoOffset = DateTime.Now;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public FirmwareSensorIMU Clone()
|
||||
{
|
||||
return new FirmwareSensorIMU()
|
||||
{
|
||||
ID_Num = ID_Num,
|
||||
Iniciado = Iniciado,
|
||||
Pitch = Pitch,
|
||||
Roll = Roll,
|
||||
Yaw = Yaw,
|
||||
Temperatura = Temperatura,
|
||||
Altitude = Altitude,
|
||||
Pressao = Pressao,
|
||||
AccX = AccX,
|
||||
AccY = AccY,
|
||||
AccZ = AccZ,
|
||||
MagX = MagX,
|
||||
MagY = MagY,
|
||||
MagZ = MagZ,
|
||||
GyrX = GyrX,
|
||||
GyrY = GyrY,
|
||||
GyrZ = GyrZ,
|
||||
Offset = Offset,
|
||||
};
|
||||
}
|
||||
|
||||
public string DadosToString()
|
||||
{
|
||||
return
|
||||
$"[IMU] " +
|
||||
$"Iniciado: {Iniciado}, " +
|
||||
$"AccX: {AccX}, " +
|
||||
$"AccY: {AccY}, " +
|
||||
$"AccZ: {AccZ}, " +
|
||||
$"GyrX: {GyrX}, " +
|
||||
$"GyrY: {GyrY}, " +
|
||||
$"GyrZ: {GyrZ}, " +
|
||||
$"MagX: {MagX}, " +
|
||||
$"MagY: {MagY}, " +
|
||||
$"MagZ: {MagZ}, " +
|
||||
$"Temperatura: {Temperatura}, " +
|
||||
$"Pressao: {Pressao}, " +
|
||||
$"Altitude: {Altitude}, " +
|
||||
$"Roll: {Roll}, " +
|
||||
$"Pitch: {Pitch}, " +
|
||||
$"Yaw: {Yaw}, " +
|
||||
$"Yaw Corrigido: {YawFixed}";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class FirmwareSensorGas : IFirmwareSensorBase
|
||||
{
|
||||
public DateTime Momento { get; set; }
|
||||
public string ID { get; set; }
|
||||
public int ID_Num { get; set; }
|
||||
public bool Iniciado { get; set; }
|
||||
public CanCommandFreqModel<double> PPM { get; set; } = new CanCommandFreqModel<double>();
|
||||
}
|
||||
|
||||
public class FirmwareSensorTemperaturaSHT : IFirmwareSensorBase
|
||||
{
|
||||
public DateTime Momento { get; set; }
|
||||
public string ID { get; set; }
|
||||
public int ID_Num { get; set; }
|
||||
public bool Iniciado { get; set; }
|
||||
public CanCommandFreqModel<double> Temperatura { get; set; } = new CanCommandFreqModel<double>();
|
||||
public CanCommandFreqModel<double> Umidade { get; set; } = new CanCommandFreqModel<double>();
|
||||
}
|
||||
|
||||
public class FirmwareSensorLuminosidade : IFirmwareSensorBase
|
||||
{
|
||||
public DateTime Momento { get; set; }
|
||||
public string ID { get; set; }
|
||||
public int ID_Num { get; set; }
|
||||
public bool Iniciado { get; set; }
|
||||
public CanCommandFreqModel<double> Lux { get; set; } = new CanCommandFreqModel<double>();
|
||||
}
|
||||
|
||||
public class FirmwareSensorLuzUV : IFirmwareSensorBase
|
||||
{
|
||||
public DateTime Momento { get; set; }
|
||||
public string ID { get; set; }
|
||||
public int ID_Num { get; set; }
|
||||
public bool Iniciado { get; set; }
|
||||
public CanCommandFreqModel<double> IndiceUV { get; set; } = new CanCommandFreqModel<double>();
|
||||
}
|
||||
|
||||
public class FirmwareSensorQualidadeAr : IFirmwareSensorBase
|
||||
{
|
||||
public DateTime Momento { get; set; }
|
||||
public string ID { get; set; }
|
||||
public int ID_Num { get; set; }
|
||||
public bool Iniciado { get; set; }
|
||||
public CanCommandFreqModel<double> TVOC { get; set; } = new CanCommandFreqModel<double>();
|
||||
public CanCommandFreqModel<double> ECO2 { get; set; } = new CanCommandFreqModel<double>();
|
||||
public CanCommandFreqModel<double> AQI { get; set; } = new CanCommandFreqModel<double>();
|
||||
public CanCommandFreqModel<double> Temperatura { get; set; } = new CanCommandFreqModel<double>();
|
||||
public CanCommandFreqModel<double> Umidade { get; set; } = new CanCommandFreqModel<double>();
|
||||
}
|
||||
|
||||
public class FirmwareSensorChuva : IFirmwareSensorBase
|
||||
{
|
||||
public DateTime Momento { get; set; }
|
||||
public string ID { get; set; }
|
||||
public int ID_Num { get; set; }
|
||||
public bool Iniciado { get; set; }
|
||||
public CanCommandFreqModel<double> Percentual { get; set; } = new CanCommandFreqModel<double>();
|
||||
}
|
||||
|
||||
|
||||
public class SensoriamentoMensagemJsonModel
|
||||
{
|
||||
public DateTime Momento { get; set; }
|
||||
|
|
@ -3334,8 +3008,9 @@ namespace AgroBase.Models.Modules
|
|||
}
|
||||
case CanMessagePosicaoDados.Dados1:
|
||||
{
|
||||
double temperatura = ConverterByteParaDouble(data, 2);
|
||||
AtualizarDados(ID_Num, posicao, componente, new List<dynamic>() { temperatura });
|
||||
ushort raw = Converter2BytesU16(data, 2);
|
||||
double temperatura = ConverterByteParaDouble(data, 4);
|
||||
AtualizarDados(ID_Num, posicao, componente, new List<dynamic>() { raw, temperatura });
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -3410,7 +3085,7 @@ namespace AgroBase.Models.Modules
|
|||
}
|
||||
break;
|
||||
}
|
||||
case S_Code.sFRO:
|
||||
case S_Code.sSRV:
|
||||
{
|
||||
switch (posicao)
|
||||
{
|
||||
|
|
@ -3494,8 +3169,9 @@ namespace AgroBase.Models.Modules
|
|||
}
|
||||
case CanMessagePosicaoDados.Dados1:
|
||||
{
|
||||
double ppm = ConverterBytesParaDouble32(data, 2);
|
||||
AtualizarDados(ID_Num, posicao, componente, new List<dynamic>() { ppm });
|
||||
ushort raw = Converter2BytesU16(data, 2);
|
||||
double ppm = ConverterBytesParaDouble32(data, 4);
|
||||
AtualizarDados(ID_Num, posicao, componente, new List<dynamic>() { raw, ppm });
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -3552,8 +3228,9 @@ namespace AgroBase.Models.Modules
|
|||
}
|
||||
case CanMessagePosicaoDados.Dados1:
|
||||
{
|
||||
double iuv = ConverterByteParaDouble(data, 2);
|
||||
AtualizarDados(ID_Num, posicao, componente, new List<dynamic>() { iuv });
|
||||
ushort raw = Converter2BytesU16(data, 2);
|
||||
double iuv = ConverterByteParaDouble(data, 4);
|
||||
AtualizarDados(ID_Num, posicao, componente, new List<dynamic>() { raw, iuv });
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -3599,8 +3276,9 @@ namespace AgroBase.Models.Modules
|
|||
}
|
||||
case CanMessagePosicaoDados.Dados1:
|
||||
{
|
||||
double percentual = ConverterByteParaDouble(data, 2);
|
||||
AtualizarDados(ID_Num, posicao, componente, new List<dynamic>() { percentual });
|
||||
ushort raw = Converter2BytesU16(data, 2);
|
||||
double percentual = ConverterByteParaDouble(data, 4);
|
||||
AtualizarDados(ID_Num, posicao, componente, new List<dynamic>() { raw, percentual });
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1461,7 +1461,7 @@ namespace AgroBase.Models
|
|||
{
|
||||
foreach (var Bomba in Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombasPressurizadoras)
|
||||
{
|
||||
bool Ligado = Bomba.ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.Potencia)?.atual?.valor > 0;
|
||||
bool Ligado = Bomba._Potencia > 0;
|
||||
if (!Ligado)
|
||||
{
|
||||
Variaveis.OperacaoEmAndamento.Controle.BombaAtuada = true;
|
||||
|
|
@ -1694,6 +1694,7 @@ namespace AgroBase.Models
|
|||
if (controleBase.Controle.PercentualVelocidadeSP != null) _Controle.PercentualVelocidadeSP = (double)controleBase.Controle.PercentualVelocidadeSP;
|
||||
if (controleBase.Controle.AnguloSP != null) _Controle.Angulo = (double)controleBase.Controle.AnguloSP;
|
||||
if (controleBase.Controle.TipoMovimentoDirecional != null) _Controle.TipoMovimento = (TipoMovimentoDirecional)controleBase.Controle.TipoMovimentoDirecional;
|
||||
if (controleBase.Controle.EmFreio != null) _Controle.EmFreio = (bool)controleBase.Controle.EmFreio;
|
||||
|
||||
Keys tecla = GeneralJoystick.DeParaComandos.FirstOrDefault(x => x.botaoJoy == controleBase.Tecla)?.key ?? Keys.Escape;
|
||||
GeneralJoystick.EnviaComandoMotor(tecla, controleBase.Dispositivo, ForcarComando: true, ID: controleBase._comp_id);
|
||||
|
|
@ -1821,7 +1822,7 @@ namespace AgroBase.Models
|
|||
VolumeReservatorio = Variaveis.OperacaoEmAndamento.DispAtu.Dados.ContadorCarga.VolumeAtual_L,
|
||||
PressaoLinha_SP = Variaveis.OperacaoEmAndamento.Parametros.Controle.AtuPressaoLinha,
|
||||
PressaoLinha = Variaveis.OperacaoEmAndamento.DispAtu.Dados.PressaoLinha,
|
||||
PotenciaBomba = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombasPressurizadoras.FirstOrDefault()?.ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.Potencia)?.atual?.valor ?? 0,
|
||||
PotenciaBomba = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombasPressurizadoras.FirstOrDefault()?._Potencia ?? 0,
|
||||
BombaLigada = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombasPressurizadoras.FirstOrDefault().ComandoAtuar,
|
||||
VazaoFluxoMLpSInstantanea = Variaveis.OperacaoEmAndamento.DispAtu.Dados.VazaoFluxoMLpSInstantanea,
|
||||
VazaoFluxoMLpSMedia = Variaveis.OperacaoEmAndamento.DispAtu.Dados.VazaoFluxoMLpSMedia,
|
||||
|
|
@ -1836,7 +1837,7 @@ namespace AgroBase.Models
|
|||
Atuado = Bico.ComandoAtuar,
|
||||
MediaNivelFluxo = Bico.MediaNivelFluxo,
|
||||
Posicao = Bico.Posicao,
|
||||
StatusBico = Bico.ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.EstadoLeitura)?.atual?.valor == Estado.Ligado,
|
||||
StatusBico = Bico._EstadoLeitura == Estado.Ligado,
|
||||
Atuacoes = Bico.Atuacoes,
|
||||
TempoAtuado = Bico.TempoAtuado,
|
||||
}).ToList(),
|
||||
|
|
@ -2245,6 +2246,7 @@ namespace AgroBase.Models
|
|||
public double? PercentualVelocidadeSP { get; set; }
|
||||
public double? AnguloSP { get; set; }
|
||||
public TipoMovimentoDirecional? TipoMovimentoDirecional { get; set; }
|
||||
public bool? EmFreio { get; set; }
|
||||
public bool? Estado { get; set; }
|
||||
public double? Altura { get; set; }
|
||||
}
|
||||
|
|
@ -2376,13 +2378,14 @@ namespace AgroBase.Models
|
|||
PercentualErvasNoRadar = WeedWorkerService.DadosLeitura?.Analise?.estatisticas?.erva?.ema_global ?? 0,
|
||||
PercentualReservatorio = _Reservatorio.PercentualAtual,
|
||||
VolumeReservatorio = _Reservatorio.VolumeAtual_L,
|
||||
MassaReservatorio = _Reservatorio.MassaAtual_Kg,
|
||||
PressaoLinha = _DispAtu.Dados.PressaoLinha,
|
||||
VazaoInstantanea = _DispAtu.Dados.VazaoFluxoMLpSInstantanea,
|
||||
VazaoMedia = _DispAtu.Dados.VazaoFluxoMLpSMedia,
|
||||
TempoBombaAtuada = _DispAtu.Dados.TempoAtuado,
|
||||
ComandoBomba = _DispAtu.Dados.BombasPressurizadoras.FirstOrDefault()?.ComandoAtuar ?? false,
|
||||
LeituraComandoBomba = (_DispAtu.Dados.BombasPressurizadoras.FirstOrDefault().ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.EstadoLeitura)?.atual?.valor ?? Estado.Desligado) == Estado.Ligado,
|
||||
LeituraPotenciaBomba = FuncoesMatematicas.Clamp(_DispAtu.Dados.BombasPressurizadoras.FirstOrDefault().ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.Potencia)?.atual?.valor ?? 0, 0, 100),
|
||||
ComandoBomba = _DispAtu.Dados.BombasPressurizadoras.FirstOrDefault().ComandoAtuar,
|
||||
LeituraComandoBomba = _DispAtu.Dados.BombasPressurizadoras.FirstOrDefault()._EstadoLeitura == Estado.Ligado,
|
||||
LeituraPotenciaBomba = FuncoesMatematicas.Clamp(_DispAtu.Dados.BombasPressurizadoras.FirstOrDefault()._Potencia, 0, 100),
|
||||
VolumeVazaoMl = _DispAtu.Dados.VolumeVazaoML,
|
||||
Iniciados = _DispAtu.Dados.Sensores.Select(s => new { s.ID, s.Inicializado }).Union(_DispAtu.Dados.BicosPulverizadores.Select(b => new { b.ID, b.Inicializado })).Union(_DispAtu.Dados.BombasPressurizadoras.Select(b => new { b.ID, b.Inicializado })).ToDictionary(x => x.ID, x => x.Inicializado),
|
||||
AnguloBarraEsquerda = _DispAtu.Dados.AnguloBarraEsquerda,
|
||||
|
|
@ -2401,7 +2404,7 @@ namespace AgroBase.Models
|
|||
Atuado = Bico.ComandoAtuar,
|
||||
MediaNivelFluxo = Bico.MediaNivelFluxo,
|
||||
Posicao = Bico.Posicao,
|
||||
StatusBico = Bico.ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.EstadoLeitura)?.atual?.valor == Estado.Ligado,
|
||||
StatusBico = Bico._EstadoLeitura == Estado.Ligado,
|
||||
Atuacoes = Bico.Atuacoes,
|
||||
TempoAtuado = Bico.TempoAtuado,
|
||||
AnguloAbertura = Bico.AnguloAbertura,
|
||||
|
|
@ -2577,7 +2580,7 @@ namespace AgroBase.Models
|
|||
DispositivosMapeados = new List<DispositivoDetalhesModel>(SerialService.DispositivosMapeados),
|
||||
ModsCalibragem = new Dictionary<T_Code, Dictionary<string, bool>>(Variaveis.OperacaoEmAndamento.ModsCalibragem),
|
||||
Temperaturas = _DispSen?.Dados?.Sensores?.Where(x => x.Componente == S_Code.sNTC)?.ToDictionary(x => x.ID, y => (double?)(y.ValoresLeituras?.FirstOrDefault(v => v.funcao == FuncoesPinout.Temperatura)?.atual?.valor) ?? -1),
|
||||
Reles = _DispSen?.Dados?.Reles?.ToDictionary(x => x.ID, y => (y.StatusControle == Estado.Ligado, y.StatusLeitura == Estado.Ligado)),
|
||||
Reles = _DispSen?.Dados?.Reles?.ToDictionary(x => x.ID, y => (y.StatusControle == Estado.Ligado, y._EstadoLeitura == Estado.Ligado)),
|
||||
Servos = _DispSen?.Dados?.Servos?.ToDictionary(x => x.ID, y => (y._AnguloControle, y._AnguloLeiutra, y.Incremental)),
|
||||
Iniciados = _DispSen?.Dados?.Servos?.Select(s => new { s.ID, s.Inicializado }).Union(_DispSen?.Dados?.Reles?.Select(r => new { r.ID, r.Inicializado })).Union(_DispSen?.Dados?.Sinaleiros?.Select(s => new { s.ID, s.Inicializado })).Union(_DispSen?.Dados?.Sensores?.Select(s => new { s.ID, s.Inicializado })).ToDictionary(s => s.ID, s => s.Inicializado),
|
||||
Logs = new List<OperacaoSensoriamentoLogErrosModel>(Logs ?? new List<OperacaoSensoriamentoLogErrosModel>()),
|
||||
|
|
@ -2680,6 +2683,7 @@ namespace AgroBase.Models
|
|||
public bool ErvasNoRadar { get; set; }
|
||||
public double PercentualErvasNoRadar { get; set; }
|
||||
public double PercentualReservatorio { get; set; }
|
||||
public double MassaReservatorio { get; set; }
|
||||
public double VolumeReservatorio { get; set; }
|
||||
public double PressaoLinha { get; set; }
|
||||
public double VazaoInstantanea { get; set; }
|
||||
|
|
@ -2713,6 +2717,7 @@ namespace AgroBase.Models
|
|||
PercentualErvasTerreno = PercentualErvasTerreno,
|
||||
PercentualReservatorio = PercentualReservatorio,
|
||||
VolumeReservatorio = VolumeReservatorio,
|
||||
MassaReservatorio = MassaReservatorio,
|
||||
PressaoLinha = PressaoLinha,
|
||||
VazaoInstantanea = VazaoInstantanea,
|
||||
VazaoMedia = VazaoMedia,
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ namespace AgroBase.Models
|
|||
public static double PercentualReservatorioMin { get; set; } = 8.0;
|
||||
public static double PercentualToleranciaPressaoLinha { get; set; } = 0.15;
|
||||
public static int QuantidadeCamerasSolo { get; set; } = 1;
|
||||
public static int QuantidadeBicosPulverizadores { get; set; } = 4;
|
||||
public static int QuantidadeBicosPulverizadores { get; set; } = 3;
|
||||
public static double AlturaBarraPulverizadoraCm { get; set; } = 80;
|
||||
public static double ComprimentoBarraPulverizadoraCm { get; set; } = 103.7;
|
||||
public static double DistanciaEntreBicosCm { get; set; } = 50;
|
||||
|
|
|
|||
|
|
@ -157,9 +157,9 @@ namespace AgroBase.Services
|
|||
|
||||
private void EnviarComando()
|
||||
{
|
||||
if (ReleCoolerEntrada != null && (ReleCoolerEntrada?.StatusLeitura ?? Estado.Desligado) != CoolerEntradaEstado)
|
||||
if (ReleCoolerEntrada != null && ReleCoolerEntrada._EstadoLeitura != CoolerEntradaEstado)
|
||||
GeneralJoystick.EnviarComandoSensoriamento(ReleCoolerEntrada.Componente, ReleCoolerEntrada.ID, CoolerEntradaEstado);
|
||||
if (ReleCoolerSaida != null && (ReleCoolerSaida?.StatusLeitura ?? Estado.Desligado) != CoolerSaidaEstado)
|
||||
if (ReleCoolerSaida != null && ReleCoolerSaida._EstadoLeitura != CoolerSaidaEstado)
|
||||
GeneralJoystick.EnviarComandoSensoriamento(ReleCoolerSaida.Componente, ReleCoolerSaida.ID, CoolerSaidaEstado);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ namespace AgroBase.Services
|
|||
/// Massa atual lida no reservatório (Kg).
|
||||
/// </summary>
|
||||
public double MassaAtual_Kg { get; private set; }
|
||||
public double MassaAtual_Kg_Calc { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Volume atual estimado no reservatório (L).
|
||||
|
|
@ -163,8 +164,9 @@ namespace AgroBase.Services
|
|||
if (!Iniciado)
|
||||
return;
|
||||
|
||||
bool pulverizando = Variaveis.OperacaoEmAndamento.DispAtu?.Dados?.BicosPulverizadores?.Any(x => x.Inicializado && (x.ValoresLeituras?.Any(y => y.funcao == FuncoesPinout.EstadoLeitura && y.atual?.valor == Estado.Ligado) ?? false)) ?? false;
|
||||
bool pulverizando = Variaveis.OperacaoEmAndamento.DispAtu?.Dados?.BicosPulverizadores?.Any(x => x.Inicializado && x._EstadoLeitura == Estado.Ligado) ?? false;
|
||||
double massaLida_Kg = Sensor?.ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.Massa)?.atual?.valor ?? 0;
|
||||
double massaLida_Kg_bruto = Sensor?.ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.LeituraBruta)?.atual?.valor ?? 0;
|
||||
double volumeMedido_L = massaLida_Kg / DensidadeProduto;
|
||||
int qtd_atuacoes = Variaveis.OperacaoEmAndamento.Controle?.BicosAtuados?.Sum(x => x.Atuacoes) ?? 0;
|
||||
|
||||
|
|
@ -181,11 +183,13 @@ namespace AgroBase.Services
|
|||
_tempoTotalAnterior_s = tempoTotalSegundosAtual;
|
||||
|
||||
MassaAtual_Kg = massaLida_Kg;
|
||||
MassaAtual_Kg_Calc = massaLida_Kg_bruto;
|
||||
VolumeAtual_L = volumeMedido_L;
|
||||
return;
|
||||
}
|
||||
|
||||
MassaAtual_Kg = massaLida_Kg;
|
||||
MassaAtual_Kg_Calc = massaLida_Kg_bruto;
|
||||
VolumeAtual_L = volumeMedido_L;
|
||||
|
||||
// --- Cálculo de deltas básicos ---
|
||||
|
|
|
|||
|
|
@ -1075,7 +1075,7 @@ namespace OperationControl.Windows
|
|||
|
||||
var bico = rover?.Controle?.BicosAtuados?.FirstOrDefault(x => x.ID == label);
|
||||
bool comando = bico?.ComandoAtuar ?? false;
|
||||
var leitura = bico?.ValoresLeituras?.FirstOrDefault(x => x.funcao == AgroBase.Models.Modules.FuncoesPinout.EstadoLeitura)?.atual?.valor;
|
||||
var leitura = bico?._EstadoLeitura;
|
||||
txtBico_Titulo.Text = $"Bico {label} - Testes";
|
||||
txtBico_Comando.Text = comando ? "Ligado" : "Desligado";
|
||||
txtBico_StatusReal.Text = leitura != null && (AgroBase.Models.Enums.Estado)Enum.Parse(typeof(AgroBase.Models.Enums.Estado), leitura.ToString(), true) == AgroBase.Models.Enums.Estado.Ligado ? "Ligado" : "Desligado";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,355 @@
|
|||
// Dispositivo: Atuador
|
||||
// Versão Firmware: 12
|
||||
// Ultima atualização: 16/12/2025
|
||||
// Atualização: Adicionado controle dos bicos pulverizadores
|
||||
|
||||
#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\BicoPulverizadorModel.h"
|
||||
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\BombaPressurizadoraModel.h"
|
||||
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SensorFluxoModel.h"
|
||||
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SensorMassaModel.h"
|
||||
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SensorPressaoModel.h"
|
||||
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SensorMagneticoModel.h"
|
||||
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\ServoAgroModel.h"
|
||||
|
||||
|
||||
// Configurações do CAN
|
||||
uint8_t CanID = 0x12;
|
||||
CanService canService = CanService(CanID);
|
||||
|
||||
#define D_Code Atu
|
||||
int VERSION = 12;
|
||||
const String Mod_ID = "Atu";
|
||||
|
||||
#define _pinoLED RGB_BUILTIN
|
||||
|
||||
bool Conectado = false;
|
||||
bool Conectar = false;
|
||||
|
||||
int _TaxaAmostragem = 1000;
|
||||
volatile bool RequisitarDados = false;
|
||||
int latenciaLoop = 0;
|
||||
int qtdEnviosStatus = 0;
|
||||
int maxEnviosStatus = 5;
|
||||
|
||||
std::vector<Bico*> listaBicos;
|
||||
std::vector<BombaPressurizadora*> listaBombas;
|
||||
std::vector<SensorFluxo*> listaSensoresFluxo;
|
||||
std::vector<SensorMassa*> listaSensoresMassa;
|
||||
std::vector<SensorPressao*> listaSensoresPressao;
|
||||
std::vector<SensorMagnetico*> listaSensoresMagneticos;
|
||||
std::vector<ServoAgro*> listaServos;
|
||||
|
||||
void MostrarLog(String mensagem) {
|
||||
bool _debugMode = false;
|
||||
if (_debugMode) {
|
||||
PrintTela(String("[ATU] ") + mensagem);
|
||||
}
|
||||
}
|
||||
|
||||
void inicializarDependenciasI2C() {
|
||||
I2CService::IniciarI2C();
|
||||
I2CService::IniciarMUX();
|
||||
}
|
||||
|
||||
void setup() {
|
||||
delay(5000);
|
||||
|
||||
inicializarDependenciasI2C();
|
||||
|
||||
// Registrar callback para processar mensagens CAN recebidas
|
||||
canService.setReceiveCallback([](int packetSize, int senderId, CanMessagePosicaoDados posicao, byte* data, int dataLength) {
|
||||
std::vector<uint8_t> fullData;
|
||||
fullData.push_back(static_cast<uint8_t>(posicao)); // Primeiro byte é sempre a posicao
|
||||
for (int i = 0; i < dataLength; i++) {
|
||||
fullData.push_back(data[i]);
|
||||
}
|
||||
|
||||
ProcessarFrameCAN(posicao, fullData);
|
||||
});
|
||||
|
||||
canService.begin();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (!RequisitarDados) {
|
||||
enviarLogsPeriodicamente();
|
||||
}
|
||||
|
||||
for (auto* bomba : listaBombas) {
|
||||
bomba->Loop();
|
||||
}
|
||||
for (auto* sensor : listaSensoresFluxo) {
|
||||
sensor->Loop();
|
||||
}
|
||||
|
||||
delay(1);
|
||||
}
|
||||
|
||||
// Função para enviar logs do sensor periodicamente
|
||||
unsigned long ultimoEnvioLogs = 0;
|
||||
const unsigned long intervaloEnvioLogs = 1000; // 1 segundo
|
||||
void enviarLogsPeriodicamente() {
|
||||
unsigned long tempoAtual = millis();
|
||||
// Verifica se o intervalo de 5 segundos já passou
|
||||
if (tempoAtual - ultimoEnvioLogs >= intervaloEnvioLogs) {
|
||||
ultimoEnvioLogs = tempoAtual; // Atualiza o tempo do último envio
|
||||
|
||||
enviarDadosSensores(canService.ID_Num_sTOD, CanMessagePosicaoDados::DadosAll);
|
||||
}
|
||||
}
|
||||
|
||||
void enviarDadosSensores(uint8_t id_num, CanMessagePosicaoDados posicao) {
|
||||
if (Conectado || posicao == CanMessagePosicaoDados::Status) {
|
||||
unsigned long startLoop = millis();
|
||||
|
||||
bool enviarStatus = qtdEnviosStatus >= maxEnviosStatus && posicao != CanMessagePosicaoDados::Status;
|
||||
bool todosDados = posicao == CanMessagePosicaoDados::DadosAll;
|
||||
bool todosIDs = id_num == canService.ID_Num_sTOD;
|
||||
|
||||
if (id_num == canService.ID_Num_sMOD) {
|
||||
EnviarDadosCAN(canService.MontarFrameReqStatusMod(D_Code, Conectado, VERSION));
|
||||
return;
|
||||
}
|
||||
|
||||
MostrarLog("Atualizando dados dos sensores...");
|
||||
|
||||
if (todosIDs && enviarStatus) {
|
||||
EnviarDadosCAN(canService.MontarFrameReqStatusMod(D_Code, Conectado, VERSION));
|
||||
}
|
||||
|
||||
ComponenteCAN::ProcessarComponentesCAN(listaBombas, {CanMessagePosicaoDados::Dados1}, todosIDs, id_num, enviarStatus, todosDados, posicao, EnviarDadosCAN);
|
||||
ComponenteCAN::ProcessarComponentesCAN(listaBicos, {CanMessagePosicaoDados::Dados1}, todosIDs, id_num, enviarStatus, todosDados, posicao, EnviarDadosCAN);
|
||||
ComponenteCAN::ProcessarComponentesCAN(listaSensoresFluxo, {CanMessagePosicaoDados::Dados1}, todosIDs, id_num, enviarStatus, todosDados, posicao, EnviarDadosCAN);
|
||||
ComponenteCAN::ProcessarComponentesCAN(listaSensoresMassa, {CanMessagePosicaoDados::Dados1}, todosIDs, id_num, enviarStatus, todosDados, posicao, EnviarDadosCAN);
|
||||
ComponenteCAN::ProcessarComponentesCAN(listaSensoresPressao, {CanMessagePosicaoDados::Dados1}, todosIDs, id_num, enviarStatus, todosDados, posicao, EnviarDadosCAN);
|
||||
ComponenteCAN::ProcessarComponentesCAN(listaSensoresMagneticos, {CanMessagePosicaoDados::Dados1}, todosIDs, id_num, enviarStatus, todosDados, posicao, EnviarDadosCAN);
|
||||
ComponenteCAN::ProcessarComponentesCAN(listaServos, {CanMessagePosicaoDados::Dados1}, todosIDs, id_num, enviarStatus, todosDados, posicao, EnviarDadosCAN);
|
||||
|
||||
if (enviarStatus) {
|
||||
qtdEnviosStatus = 0;
|
||||
}
|
||||
else {
|
||||
qtdEnviosStatus++;
|
||||
}
|
||||
|
||||
latenciaLoop = millis() - startLoop;
|
||||
|
||||
if (posicao == CanMessagePosicaoDados::DadosAll) {
|
||||
EnviarDadosCAN(canService.MontarFrameReqDadosFim(latenciaLoop));
|
||||
}
|
||||
|
||||
MostrarLog("Ciclo concluido, latencia de loop: " + String(latenciaLoop));
|
||||
}
|
||||
}
|
||||
|
||||
void EnviarDadosCAN(std::vector<uint8_t> data) {
|
||||
if (data.size() > 2) {
|
||||
canService.adicionarMensagemFila(data);
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessarFrameCAN(CanMessagePosicaoDados posicao, std::vector<uint8_t> data) {
|
||||
if (data.size() < 1) return;
|
||||
|
||||
F_Code funcao = canService.FuncaoPorPosicao(posicao);
|
||||
|
||||
switch (funcao) {
|
||||
case F_Code::ReqTx: ProcessarReq(data); break;
|
||||
case F_Code::CmdTx: ProcessarCmd(data); break;
|
||||
case F_Code::CfgTx: ProcessarCfg(data); break;
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessarReq(std::vector<uint8_t> data) {
|
||||
if (data.size() < 2) return;
|
||||
CanMessagePosicaoDados posicao = (CanMessagePosicaoDados)data[0];
|
||||
uint8_t id = data[1];
|
||||
enviarDadosSensores(id, posicao);
|
||||
}
|
||||
|
||||
void ProcessarCfg(std::vector<uint8_t> data) {
|
||||
if (data.size() < 4) return;
|
||||
std::vector<uint8_t> _chkRx;
|
||||
CanMessagePosicaoDados posicao = (CanMessagePosicaoDados)data[0];
|
||||
uint8_t id = data[1];
|
||||
S_Code componente = DetectarComponente(id);
|
||||
if (componente == S_Code::sMOD) {
|
||||
switch (posicao) {
|
||||
case CanMessagePosicaoDados::Config1: {
|
||||
if (data.size() < 7) return;
|
||||
bool conectar = data[2] == 1;
|
||||
int taxa = data[3] * 10;
|
||||
bool requisitar = data[4] == 1;
|
||||
int pinoSDA = data[5];
|
||||
int pinoSCL = data[6];
|
||||
|
||||
_TaxaAmostragem = taxa;
|
||||
RequisitarDados = requisitar;
|
||||
|
||||
LimparListasComponentes();
|
||||
|
||||
if (pinoSDA != PINO_INVALIDO && pinoSCL != PINO_INVALIDO) {
|
||||
if (I2CService::DefinirPinos(pinoSDA, pinoSCL) || !I2CService::I2CIniciado) {
|
||||
//inicializarDependenciasI2C();
|
||||
}
|
||||
}
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
|
||||
Conectado = conectar;
|
||||
_chkRx = canService.MontarFrameReqStatusMod(D_Code, Conectado, VERSION);
|
||||
|
||||
MostrarLog("Configuracao do modulo concluida");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
componente = (S_Code)data[2];
|
||||
switch (componente) {
|
||||
case sBIC: {
|
||||
_chkRx = Bico::ConfigurarBico(listaBicos, data, Mod_ID, listaServos);
|
||||
break;
|
||||
}
|
||||
case sFLX: {
|
||||
_chkRx = SensorFluxo::ConfigurarSensor(listaSensoresFluxo, data, Mod_ID);
|
||||
break;
|
||||
}
|
||||
case sPRS: {
|
||||
_chkRx = SensorPressao::ConfigurarSensor(listaSensoresPressao, data, Mod_ID);
|
||||
break;
|
||||
}
|
||||
case sMAS: {
|
||||
_chkRx = SensorMassa::ConfigurarSensor(listaSensoresMassa, data, Mod_ID);
|
||||
break;
|
||||
}
|
||||
case sBMB: {
|
||||
_chkRx = BombaPressurizadora::ConfigurarBomba(listaBombas, data, Mod_ID, listaSensoresPressao);
|
||||
break;
|
||||
}
|
||||
case sMAG: {
|
||||
_chkRx = SensorMagnetico::ConfigurarSensor(listaSensoresMagneticos, data, Mod_ID);
|
||||
break;
|
||||
}
|
||||
case sSRV: {
|
||||
_chkRx = ServoAgro::ConfigurarServo(listaServos, data, Mod_ID);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EnviarDadosCAN(_chkRx);
|
||||
}
|
||||
|
||||
void ProcessarCmd(std::vector<uint8_t> data) {
|
||||
if (data.size() < 2) return;
|
||||
CanMessagePosicaoDados posicao = (CanMessagePosicaoDados)data[0];
|
||||
uint8_t id = data[1];
|
||||
S_Code componente = DetectarComponente(id);
|
||||
switch (componente) {
|
||||
case sBIC: {
|
||||
Bico::ComandarBico(listaBicos, data);
|
||||
ComponenteCAN::ProcessarComponentesCAN(listaBicos, {}, false, id, false, false, CanMessagePosicaoDados::Dados1, EnviarDadosCAN);
|
||||
break;
|
||||
}
|
||||
case sBMB: {
|
||||
BombaPressurizadora::ComandarBomba(listaBombas, data);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void LimparListasComponentes() {
|
||||
for (auto* bico : listaBicos) {
|
||||
if (bico) {
|
||||
bico->Desligar();
|
||||
MostrarLog("Bico " + bico->_ID + " desligado.");
|
||||
delete bico;
|
||||
}
|
||||
}
|
||||
listaBicos.clear();
|
||||
|
||||
for (auto* bomba : listaBombas) {
|
||||
if (bomba) {
|
||||
bomba->Desligar();
|
||||
MostrarLog("Bomba Pressurizadora " + bomba->_ID + " desligada.");
|
||||
delete bomba;
|
||||
}
|
||||
}
|
||||
listaBombas.clear();
|
||||
|
||||
for (auto* sensor : listaSensoresFluxo) {
|
||||
if (sensor) {
|
||||
sensor->Desligar();
|
||||
MostrarLog("Sensor de Fluxo " + sensor->_ID + " desligado.");
|
||||
delete sensor;
|
||||
}
|
||||
}
|
||||
listaSensoresFluxo.clear();
|
||||
|
||||
for (auto* sensor : listaSensoresMassa) {
|
||||
if (sensor) {
|
||||
sensor->Desligar();
|
||||
MostrarLog("Sensor de Massa " + sensor->_ID + " desligado.");
|
||||
delete sensor;
|
||||
}
|
||||
}
|
||||
listaSensoresMassa.clear();
|
||||
|
||||
for (auto* sensor : listaSensoresPressao) {
|
||||
if (sensor) {
|
||||
sensor->Desligar();
|
||||
MostrarLog("Sensor de Pressao " + sensor->_ID + " desligado.");
|
||||
delete sensor;
|
||||
}
|
||||
}
|
||||
listaSensoresPressao.clear();
|
||||
|
||||
for (auto* sensor : listaSensoresMagneticos) {
|
||||
sensor->Desligar();
|
||||
MostrarLog("Sensor magnetico " + sensor->_ID + " desligado.");
|
||||
delete sensor;
|
||||
}
|
||||
listaSensoresMagneticos.clear();
|
||||
|
||||
for (auto* servo : listaServos) {
|
||||
servo->Desligar();
|
||||
MostrarLog("Servo " + servo->_ID + " desligado.");
|
||||
delete servo;
|
||||
}
|
||||
listaServos.clear();
|
||||
}
|
||||
|
||||
S_Code DetectarComponente(uint8_t idNum) {
|
||||
if (idNum == canService.ID_Num_sMOD) return S_Code::sMOD;
|
||||
for (auto* s : listaBicos) {
|
||||
if (s->ID_Num == idNum) return S_Code::sBIC;
|
||||
}
|
||||
for (auto* s : listaBombas) {
|
||||
if (s->ID_Num == idNum) return S_Code::sBMB;
|
||||
}
|
||||
for (auto* s : listaSensoresFluxo) {
|
||||
if (s->ID_Num == idNum) return S_Code::sFLX;
|
||||
}
|
||||
for (auto* s : listaSensoresMassa) {
|
||||
if (s->ID_Num == idNum) return S_Code::sMAS;
|
||||
}
|
||||
for (auto* s : listaSensoresPressao) {
|
||||
if (s->ID_Num == idNum) return S_Code::sPRS;
|
||||
}
|
||||
for (auto* s : listaSensoresMagneticos) {
|
||||
if (s->ID_Num == idNum) return S_Code::sMAG;
|
||||
}
|
||||
for (auto* s : listaServos) {
|
||||
if (s->ID_Num == idNum) return S_Code::sSRV;
|
||||
}
|
||||
return S_Code::sVZO;
|
||||
}
|
||||
|
|
@ -0,0 +1,216 @@
|
|||
#include "SerialService.h"
|
||||
#include "Pinout.h"
|
||||
#include "Utils.h"
|
||||
#include "IComponenteCAN.h"
|
||||
#include "ServoAgroModel.h"
|
||||
|
||||
#ifndef BicoModel
|
||||
#define BicoModel
|
||||
|
||||
class Bico : public ComponenteCAN {
|
||||
public:
|
||||
|
||||
Bico(String _modID, String _id) {
|
||||
Mod_ID = _modID;
|
||||
_ID = _id;
|
||||
}
|
||||
|
||||
String Mod_ID;
|
||||
String _ID;
|
||||
int ID_Num;
|
||||
PinoModel _pino;
|
||||
bool Iniciado = false;
|
||||
|
||||
bool AtuacaoNivelAlto = true;
|
||||
|
||||
Estado _Status = Desligado;
|
||||
|
||||
ServoAgro* servoMov = nullptr;
|
||||
|
||||
void Inicializar() {
|
||||
if (Iniciado) {
|
||||
MostrarLog("Bico ja inicializado");
|
||||
return;
|
||||
}
|
||||
|
||||
if (servoMov == nullptr) {
|
||||
PrintTela("Servo nao definido, bico nao tera controle de movimento");
|
||||
//Iniciado = false;
|
||||
//return;
|
||||
}
|
||||
|
||||
_pino.Conectar(!AtuacaoNivelAlto);
|
||||
|
||||
Iniciado = _pino.Definido();
|
||||
|
||||
if (Iniciado) {
|
||||
MostrarLog("Bico iniciado");
|
||||
}
|
||||
else
|
||||
{
|
||||
MostrarLog("Bico nao iniciado");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Desligar() {
|
||||
if (!Iniciado) {
|
||||
MostrarLog("Bico nao esta inicializado");
|
||||
return;
|
||||
}
|
||||
|
||||
servoMov = nullptr;
|
||||
|
||||
// Redefinir as configurações para os valores iniciais
|
||||
_pino.Desconectar();
|
||||
|
||||
MostrarLog("Bico Desligado");
|
||||
|
||||
Iniciado = false;
|
||||
}
|
||||
|
||||
void AtualizarStatus(Estado novoEstado, int novoAngulo) {
|
||||
if (Iniciado) {
|
||||
bool status = novoEstado == Ligado;
|
||||
if (!AtuacaoNivelAlto) {
|
||||
status = !status;
|
||||
}
|
||||
|
||||
MostrarLog("Atualizando status do bico de " + String(_Status) + " para " + String(novoEstado));
|
||||
|
||||
_pino.set(status);
|
||||
_Status = (Estado)_pino.get();
|
||||
|
||||
if (servoMov != nullptr) {
|
||||
servoMov->AtualizarAngulo(novoAngulo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AtualizarLeitura() {
|
||||
if (Iniciado) {
|
||||
_Status = (Estado)_pino.get();
|
||||
}
|
||||
}
|
||||
|
||||
void RequisitarDados() {
|
||||
AtualizarLeitura();
|
||||
}
|
||||
|
||||
std::vector<uint8_t> MontarMensagemCAN(CanMessagePosicaoDados posicao) {
|
||||
std::vector<uint8_t> data;
|
||||
data.push_back(static_cast<uint8_t>(posicao));
|
||||
data.push_back(ID_Num);
|
||||
switch (posicao) {
|
||||
case CanMessagePosicaoDados::Status: {
|
||||
data.push_back(Iniciado ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
case CanMessagePosicaoDados::Dados1: {
|
||||
data.push_back(static_cast<uint8_t>(_Status));
|
||||
data.push_back(servoMov->_Angulo);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
static std::vector<uint8_t> ConfigurarBico(std::vector<Bico*>& lista, std::vector<uint8_t>& data, const String& Mod_ID, std::vector<ServoAgro*>& servos) {
|
||||
std::vector<uint8_t> status;
|
||||
if (data.size() < 2) return status;
|
||||
CanMessagePosicaoDados posicao = (CanMessagePosicaoDados)data[0];
|
||||
uint8_t idNum = data[1];
|
||||
auto it = std::find_if(lista.begin(), lista.end(), [idNum](Bico* s) { return s->ID_Num == idNum; });
|
||||
bool jaExiste = it != lista.end();
|
||||
Bico* bico;
|
||||
switch (posicao) {
|
||||
case CanMessagePosicaoDados::Config1: {
|
||||
if (data.size() < 8) return status;
|
||||
bool conectar = data[3] == 1;
|
||||
bool atuacaoNivelAlto = data[4] == 1;
|
||||
int servo_id = (data[5] == 0xFF) ? -1 : (int)data[5];
|
||||
TiposBarramentos tipoBarramento = (TiposBarramentos)data[6];
|
||||
int pino = data[7];
|
||||
if (conectar) {
|
||||
if (!jaExiste) {
|
||||
bico = new Bico(Mod_ID, "sBIC_" + String(idNum));
|
||||
}
|
||||
else {
|
||||
bico = *it;
|
||||
}
|
||||
if (!bico->Iniciado) {
|
||||
bool com_movimento = servo_id >= 0;
|
||||
if (com_movimento) {
|
||||
if (servos.size() > 0) {
|
||||
auto srv = std::find_if(servos.begin(), servos.end(), [servo_id](ServoAgro* s) { return s->ID_Num == servo_id; });
|
||||
bool servo_encontrado = srv != servos.end();
|
||||
if (servo_encontrado && (*srv)->Iniciado) {
|
||||
bico->servoMov = *srv;
|
||||
}
|
||||
}
|
||||
if (bico->servoMov == nullptr) {
|
||||
PrintTela("O servo " + String(servo_id) + " nao foi encontrado para ser associado ao bico.");
|
||||
delete bico;
|
||||
return status;
|
||||
}
|
||||
}
|
||||
bico->ID_Num = idNum;
|
||||
bico->_pino = PinoModel(pino, tipoBarramento, _OUTPUT);
|
||||
bico->AtuacaoNivelAlto = atuacaoNivelAlto;
|
||||
bico->Inicializar();
|
||||
if (!jaExiste) {
|
||||
lista.push_back(bico);
|
||||
bico->MostrarLog("Bico adicionado via CAN: sBIC_" + String(idNum));
|
||||
}
|
||||
}
|
||||
status = bico->MontarMensagemCAN(CanMessagePosicaoDados::Status);
|
||||
} else {
|
||||
if (jaExiste) {
|
||||
bico = *it;
|
||||
bico->Desligar();
|
||||
status = bico->MontarMensagemCAN(CanMessagePosicaoDados::Status);
|
||||
bico->MostrarLog("Bico removido via CAN: sBIC_" + String(idNum));
|
||||
delete bico;
|
||||
lista.erase(it);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static void ComandarBico(std::vector<Bico*>& lista, std::vector<uint8_t>& data) {
|
||||
if (data.size() < 4) return;
|
||||
CanMessagePosicaoDados posicao = (CanMessagePosicaoDados)data[0];
|
||||
uint8_t idNum = data[1];
|
||||
for (auto* _bico : lista) {
|
||||
if (_bico->ID_Num == idNum) {
|
||||
switch (posicao) {
|
||||
case CanMessagePosicaoDados::Command1: {
|
||||
Estado novoEstado = (Estado)data[2];
|
||||
int novoAngulo = data[3];
|
||||
_bico->AtualizarStatus(novoEstado, novoAngulo);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
bool DebugMode = false;
|
||||
|
||||
void MostrarLog(String mensagem) {
|
||||
if (DebugMode) {
|
||||
PrintTela("[BIC " + _ID + "] " + mensagem);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -33,7 +33,7 @@ class BombaPressurizadora : public ComponenteCAN {
|
|||
bool bombaDesligadaPorPressao = false;
|
||||
//PID* _PID = nullptr;
|
||||
|
||||
SensorPressao* sensorPressao;
|
||||
SensorPressao* sensorPressao = nullptr;
|
||||
|
||||
int ZeroRampa = 0;
|
||||
int RampaMax = 1023;
|
||||
|
|
@ -184,11 +184,12 @@ class BombaPressurizadora : public ComponenteCAN {
|
|||
BombaPressurizadora* bomba;
|
||||
switch (posicao) {
|
||||
case CanMessagePosicaoDados::Config1: {
|
||||
if (data.size() < 7) return status;
|
||||
if (data.size() < 8) return status;
|
||||
bool conectar = data[3] == 1;
|
||||
int pressaoSp = (int)data[4];
|
||||
int pinoEn = data[5];
|
||||
int pinoCs = data[6];
|
||||
int sensor_id = (data[5] == 0xFF) ? -1 : (int)data[5];
|
||||
int pinoEn = data[6];
|
||||
int pinoCs = data[7];
|
||||
if (conectar) {
|
||||
if (!jaExiste) {
|
||||
bomba = new BombaPressurizadora(Mod_ID, "sBMB_" + String(idNum));
|
||||
|
|
@ -197,15 +198,20 @@ class BombaPressurizadora : public ComponenteCAN {
|
|||
bomba = *it;
|
||||
}
|
||||
if (!bomba->Iniciado) {
|
||||
if (sensoresPressao.size() > 0) {
|
||||
if (sensoresPressao[0]->Iniciado) {
|
||||
bomba->sensorPressao = sensoresPressao[0];
|
||||
bool malha_fechada = sensor_id >= 0;
|
||||
if (malha_fechada) {
|
||||
auto prs = std::find_if(sensoresPressao.begin(), sensoresPressao.end(), [sensor_id](SensorPressao* s) { return s->ID_Num == sensor_id; });
|
||||
bool sensor_encontrado = prs != sensoresPressao.end();
|
||||
if (sensoresPressao.size() > 0) {
|
||||
if (sensor_encontrado && (*prs)->Iniciado) {
|
||||
bomba->sensorPressao = *prs;
|
||||
}
|
||||
}
|
||||
if (bomba->sensorPressao == nullptr) {
|
||||
PrintTela("Sensor de pressao " + String(sensor_id) + " nao encontrado para associar à bomba.");
|
||||
delete bomba;
|
||||
return status;
|
||||
}
|
||||
}
|
||||
if (bomba->sensorPressao == nullptr) {
|
||||
PrintTela("Nenhum sensor de pressão disponível para associar à bomba.");
|
||||
delete bomba;
|
||||
return status;
|
||||
}
|
||||
bomba->ID_Num = idNum;
|
||||
bomba->_pinoEN = PinoModel(pinoEn, CONTROLADOR, _OUTPUT);
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ enum S_Code {
|
|||
sIUV = 31,
|
||||
sQAR = 32,
|
||||
sCHV = 33,
|
||||
sSRV = 34,
|
||||
};
|
||||
|
||||
enum Estado {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ class SensorChuva : public ComponenteCAN {
|
|||
int ID_Num;
|
||||
PinoModel _pino;
|
||||
|
||||
int leitura = 0;
|
||||
double tensao = 0;
|
||||
double percentual = -1;
|
||||
|
||||
|
|
@ -65,8 +66,8 @@ class SensorChuva : public ComponenteCAN {
|
|||
}
|
||||
case CanMessagePosicaoDados::Dados1: {
|
||||
int16_t pInt = static_cast<int16_t>(round(percentual * 100.0f));
|
||||
data.push_back((uint8_t)(pInt >> 8));
|
||||
data.push_back((uint8_t)(pInt & 0xFF));
|
||||
data.push_back((uint8_t)(leitura >> 8)); data.push_back((uint8_t)(leitura & 0xFF));
|
||||
data.push_back((uint8_t)(pInt >> 8)); data.push_back((uint8_t)(pInt & 0xFF));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -141,7 +142,7 @@ class SensorChuva : public ComponenteCAN {
|
|||
void AferirChuva() {
|
||||
if (!Iniciado) return;
|
||||
|
||||
int leitura = _pino.get();
|
||||
leitura = _pino.get();
|
||||
tensao = (float)leitura / 4095.0f * Vs;
|
||||
tensao = tensao * divisor * vOffset;
|
||||
|
||||
|
|
|
|||
|
|
@ -101,8 +101,9 @@ class SensorFluxo : public ComponenteCAN {
|
|||
}
|
||||
case CanMessagePosicaoDados::Dados1: {
|
||||
uint16_t vazaoEscalada = (uint16_t)(_Vazao * 100);
|
||||
data.push_back(vazaoEscalada >> 8);
|
||||
data.push_back(vazaoEscalada & 0xFF);
|
||||
data.push_back(_PulsosLeitura);
|
||||
data.push_back((uint8_t)(_PeriodoTotalLeitura >> 8)); data.push_back((uint8_t)(_PeriodoTotalLeitura & 0xFF));
|
||||
data.push_back(vazaoEscalada >> 8); data.push_back(vazaoEscalada & 0xFF);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -183,16 +184,25 @@ class SensorFluxo : public ComponenteCAN {
|
|||
}
|
||||
|
||||
float CalcularVazao(uint16_t pulsos, unsigned long periodoMs) {
|
||||
if (periodoMs == 0) return 0;
|
||||
if (periodoMs == 0) return 0.0f; // evita divisão por zero
|
||||
|
||||
float frequencia = (float)pulsos / (float)periodoMs * 1000.0; // Hz
|
||||
const float Rh = 0.0047; // raio interno do tubo
|
||||
const float Rt = 0.0037; // raio interno do rotor
|
||||
// F = pulsos / (periodoMs/1000) => Hz
|
||||
float F = ((float)pulsos) * 1000.0f / (float)periodoMs;
|
||||
|
||||
float vazao_m3s = frequencia * 2.0 * PI * Rh * PI * (Rt * Rt); // m³/s
|
||||
float vazao_ml_s = vazao_m3s * 1e6; // ml/s
|
||||
// Equação do anúncio: F = 8.1*q - 3 (q em L/min)
|
||||
float q_L_min = (F + 3.0f) / 8.1f;
|
||||
|
||||
return vazao_ml_s;
|
||||
// evita valores negativos perto do zero (offset -3)
|
||||
if (q_L_min < 0.0f) q_L_min = 0.0f;
|
||||
|
||||
// limites do sensor informados: 0.3–10 L/min (opcional "clamp")
|
||||
// se você quiser respeitar mínimo físico, pode usar 0.3f ao invés de 0.0f
|
||||
if (q_L_min > 10.0f) q_L_min = 10.0f;
|
||||
|
||||
// L/min -> mL/s (1 L = 1000 mL; 1 min = 60 s)
|
||||
float q_mL_s = q_L_min * (1000.0f / 60.0f);
|
||||
|
||||
return q_mL_s;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ class SensorGas : public ComponenteCAN {
|
|||
|
||||
float ppm = -1;
|
||||
float tensao = -1;
|
||||
int leitura = 0;
|
||||
|
||||
bool Iniciado = false;
|
||||
bool Checando = false;
|
||||
|
|
@ -71,11 +72,9 @@ class SensorGas : public ComponenteCAN {
|
|||
break;
|
||||
}
|
||||
case CanMessagePosicaoDados::Dados1: {
|
||||
int32_t leituraInt = static_cast<int32_t>(round(ppm * 100.0f));
|
||||
data.push_back((uint8_t)(leituraInt >> 24));
|
||||
data.push_back((uint8_t)(leituraInt >> 16));
|
||||
data.push_back((uint8_t)(leituraInt >> 8));
|
||||
data.push_back((uint8_t)(leituraInt & 0xFF));
|
||||
int32_t ppmInt = static_cast<int32_t>(round(ppm * 100.0f));
|
||||
data.push_back((uint8_t)(leitura >> 8)); data.push_back((uint8_t)(leitura & 0xFF));
|
||||
data.push_back((uint8_t)(ppmInt >> 24)); data.push_back((uint8_t)(ppmInt >> 16)); data.push_back((uint8_t)(ppmInt >> 8)); data.push_back((uint8_t)(ppmInt & 0xFF));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -143,7 +142,7 @@ class SensorGas : public ComponenteCAN {
|
|||
|
||||
void AferirGas() {
|
||||
if (!Iniciado) return;
|
||||
float leitura = _pino.get();
|
||||
leitura = _pino.get();
|
||||
ppm = CalcularPPM(leitura);
|
||||
MostrarLog("Leitura Gas: " + String(leitura) + ", Tensao: " + String(tensao) + ", PPM estimado: " + String(ppm));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ class SensorLuzUV : public ComponenteCAN {
|
|||
|
||||
double tensao = 0;
|
||||
double uv_index = -1;
|
||||
int leitura = 0;
|
||||
|
||||
bool Iniciado = false;
|
||||
bool Checando = false;
|
||||
|
|
@ -65,8 +66,8 @@ class SensorLuzUV : public ComponenteCAN {
|
|||
}
|
||||
case CanMessagePosicaoDados::Dados1: {
|
||||
int16_t uvInt = static_cast<int16_t>(round(uv_index * 100.0f));
|
||||
data.push_back((uint8_t)(uvInt >> 8));
|
||||
data.push_back((uint8_t)(uvInt & 0xFF));
|
||||
data.push_back((uint8_t)(leitura >> 8)); data.push_back((uint8_t)(leitura & 0xFF));
|
||||
data.push_back((uint8_t)(uvInt >> 8)); data.push_back((uint8_t)(uvInt & 0xFF));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -137,7 +138,7 @@ class SensorLuzUV : public ComponenteCAN {
|
|||
|
||||
void AferirUV() {
|
||||
if (!Iniciado) return;
|
||||
int leitura = _pino.get();
|
||||
leitura = _pino.get();
|
||||
float Vadc = (float)leitura / 4095.0f * Vs;
|
||||
Vadc = Vadc * divisor * vOffset;
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ class SensorMassa : public ComponenteCAN {
|
|||
SimpleKalmanFilter filtro = SimpleKalmanFilter(0.05, 0.05, 0.25);
|
||||
|
||||
float Massa = 0;
|
||||
float leitura = 0;
|
||||
|
||||
bool Iniciado = false;
|
||||
|
||||
|
|
@ -85,8 +86,8 @@ class SensorMassa : public ComponenteCAN {
|
|||
}
|
||||
case CanMessagePosicaoDados::Dados1: {
|
||||
uint16_t massaEscalada = (uint16_t)(Massa * 100);
|
||||
data.push_back(massaEscalada >> 8);
|
||||
data.push_back(massaEscalada & 0xFF);
|
||||
data.push_back(leitura >> 8); data.push_back(leitura & 0xFF);
|
||||
data.push_back(massaEscalada >> 8); data.push_back(massaEscalada & 0xFF);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -147,9 +148,10 @@ class SensorMassa : public ComponenteCAN {
|
|||
private:
|
||||
void AferirMassa() {
|
||||
if (Iniciado) {
|
||||
float leitura = -balanca.get_units(5);
|
||||
leitura += _OffsetMassa;
|
||||
Massa = filtro.updateEstimate(leitura);
|
||||
leitura = balanca.get_units(5);
|
||||
float _leitura = -leitura;
|
||||
_leitura += _OffsetMassa;
|
||||
Massa = filtro.updateEstimate(_leitura);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class SensorPressao : public ComponenteCAN {
|
|||
double _Vmax = 4.5;
|
||||
double _Pmax = 174.045;
|
||||
|
||||
double leitura = 0;
|
||||
int leitura = 0;
|
||||
double Pressao = 0;
|
||||
|
||||
SimpleKalmanFilter filtro = SimpleKalmanFilter(2, 2, 0.01);
|
||||
|
|
@ -80,8 +80,8 @@ class SensorPressao : public ComponenteCAN {
|
|||
}
|
||||
case CanMessagePosicaoDados::Dados1: {
|
||||
uint16_t pressaoEscalada = (uint16_t)(Pressao * 100);
|
||||
data.push_back(pressaoEscalada >> 8);
|
||||
data.push_back(pressaoEscalada & 0xFF);
|
||||
data.push_back((uint8_t)(leitura >> 8)); data.push_back((uint8_t)(leitura & 0xFF));
|
||||
data.push_back(pressaoEscalada >> 8); data.push_back(pressaoEscalada & 0xFF);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ class SensorTemperatura : public ComponenteCAN {
|
|||
int ID_Num;
|
||||
PinoModel _pino;
|
||||
|
||||
double leitura = 0;
|
||||
int leitura = 0;
|
||||
double temperatura = -1;
|
||||
double tensao = 0;
|
||||
|
||||
|
|
@ -73,8 +73,8 @@ class SensorTemperatura : public ComponenteCAN {
|
|||
}
|
||||
case CanMessagePosicaoDados::Dados1: {
|
||||
int16_t leituraInt = static_cast<int16_t>(round(temperatura * 100.0f));
|
||||
data.push_back((uint8_t)(leituraInt >> 8));
|
||||
data.push_back((uint8_t)(leituraInt & 0xFF));
|
||||
data.push_back((uint8_t)(leitura >> 8)); data.push_back((uint8_t)(leitura & 0xFF));
|
||||
data.push_back((uint8_t)(leituraInt >> 8)); data.push_back((uint8_t)(leituraInt & 0xFF));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,181 @@
|
|||
#include "SerialService.h"
|
||||
#include "Pinout.h"
|
||||
#include "Utils.h"
|
||||
#include "IComponenteCAN.h"
|
||||
#include <ESP32Servo.h>
|
||||
|
||||
#ifndef ServoAgroModel
|
||||
#define ServoAgroModel
|
||||
|
||||
class ServoAgro : public ComponenteCAN {
|
||||
public:
|
||||
|
||||
ServoAgro(String _modID, String _id) {
|
||||
Mod_ID = _modID;
|
||||
_ID = _id;
|
||||
}
|
||||
|
||||
String Mod_ID;
|
||||
String _ID;
|
||||
int ID_Num;
|
||||
PinoModel _pino;
|
||||
|
||||
bool Incremental = true;
|
||||
|
||||
bool Iniciado = false;
|
||||
|
||||
int _Angulo = 0;
|
||||
|
||||
Servo _Servo;
|
||||
|
||||
void Inicializar() {
|
||||
if (Iniciado) {
|
||||
MostrarLog("Servo ja inicializado");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_pino.Definido()) {
|
||||
_Servo.attach(_pino.num);
|
||||
AtualizarAngulo(Incremental ? 0 : 180);
|
||||
|
||||
Iniciado = true;
|
||||
|
||||
MostrarLog("Servo iniciado");
|
||||
}
|
||||
else {
|
||||
MostrarLog("Servo nao iniciado");
|
||||
}
|
||||
}
|
||||
|
||||
void Desligar() {
|
||||
if (!Iniciado) {
|
||||
MostrarLog("Servo nao esta inicializado");
|
||||
return;
|
||||
}
|
||||
|
||||
// Redefinir as configurações para os valores iniciais
|
||||
if (_pino.Definido()) {
|
||||
_Servo.detach();
|
||||
}
|
||||
|
||||
MostrarLog("Servo Desligado");
|
||||
|
||||
Iniciado = false;
|
||||
}
|
||||
|
||||
void AtualizarAngulo(int novoAngulo) {
|
||||
if (Iniciado) {
|
||||
MostrarLog("Angulo atualizado de " + String(_Angulo) + " para " + String(novoAngulo));
|
||||
|
||||
_Angulo = novoAngulo;
|
||||
|
||||
_Servo.write(_Angulo);
|
||||
}
|
||||
}
|
||||
|
||||
void RequisitarDados() {
|
||||
|
||||
}
|
||||
|
||||
std::vector<uint8_t> MontarMensagemCAN(CanMessagePosicaoDados posicao) {
|
||||
std::vector<uint8_t> data;
|
||||
data.push_back(static_cast<uint8_t>(posicao));
|
||||
data.push_back(ID_Num);
|
||||
switch (posicao) {
|
||||
case CanMessagePosicaoDados::Status: {
|
||||
data.push_back(Iniciado ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
case CanMessagePosicaoDados::Dados1: {
|
||||
data.push_back(_Angulo); // 0 a 180
|
||||
break;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
static std::vector<uint8_t> ConfigurarServo(std::vector<ServoAgro*>& lista, std::vector<uint8_t>& data, const String& Mod_ID) {
|
||||
std::vector<uint8_t> status;
|
||||
if (data.size() < 2) return status;
|
||||
CanMessagePosicaoDados posicao = (CanMessagePosicaoDados)data[0];
|
||||
uint8_t idNum = data[1];
|
||||
auto it = std::find_if(lista.begin(), lista.end(), [idNum](ServoAgro* s) { return s->ID_Num == idNum; });
|
||||
bool jaExiste = it != lista.end();
|
||||
ServoAgro* sensor;
|
||||
switch (posicao) {
|
||||
case CanMessagePosicaoDados::Config1: {
|
||||
if (data.size() < 7) return status;
|
||||
bool conectar = data[3] == 1;
|
||||
bool incremental = data[4] == 1;
|
||||
TiposBarramentos tipoBarramento = (TiposBarramentos)data[5];
|
||||
int pino = data[6];
|
||||
if (conectar) {
|
||||
if (!jaExiste) {
|
||||
sensor = new ServoAgro(Mod_ID, "sSRV_" + String(idNum));
|
||||
}
|
||||
else {
|
||||
sensor = *it;
|
||||
}
|
||||
if (!sensor->Iniciado) {
|
||||
sensor->ID_Num = idNum;
|
||||
sensor->Incremental = incremental;
|
||||
sensor->_pino = PinoModel(pino, tipoBarramento, _OUTPUT);
|
||||
sensor->Inicializar();
|
||||
if (!jaExiste) {
|
||||
lista.push_back(sensor);
|
||||
sensor->MostrarLog("Servo adicionado via CAN: sSRV_" + String(idNum));
|
||||
}
|
||||
}
|
||||
status = sensor->MontarMensagemCAN(CanMessagePosicaoDados::Status);
|
||||
} else {
|
||||
if (jaExiste) {
|
||||
sensor = *it;
|
||||
sensor->Desligar();
|
||||
status = sensor->MontarMensagemCAN(CanMessagePosicaoDados::Status);
|
||||
sensor->MostrarLog("Servo removido via CAN: sSRV_" + String(idNum));
|
||||
delete sensor;
|
||||
lista.erase(it);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static void ComandarServo(std::vector<ServoAgro*>& lista, std::vector<uint8_t>& data) {
|
||||
if (data.size() < 3) return;
|
||||
CanMessagePosicaoDados posicao = (CanMessagePosicaoDados)data[0];
|
||||
uint8_t idNum = data[1];
|
||||
for (auto* _servo : lista) {
|
||||
if (_servo->ID_Num == idNum) {
|
||||
switch (posicao) {
|
||||
case CanMessagePosicaoDados::Command1: {
|
||||
int novoAngulo = (int)data[2];
|
||||
_servo->AtualizarAngulo(novoAngulo);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
bool DebugMode = false;
|
||||
|
||||
void MostrarLog(String mensagem) {
|
||||
if (DebugMode) {
|
||||
PrintTela("[SRV " + _ID + "] " + mensagem);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,464 @@
|
|||
// Dispositivo: Sensoriamento
|
||||
// Versão Firmware: 21
|
||||
// Ultima atualização: 16/12/2025
|
||||
// Atualização: Padronizado uso do componente ServoAgro
|
||||
|
||||
#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\LoRaService.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\SensorTemperaturaModel.h"
|
||||
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SensorCorrenteModel.h"
|
||||
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SensorIMUModel.h"
|
||||
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SinaleiroModel.h"
|
||||
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\ReleModel.h"
|
||||
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\ServoAgroModel.h"
|
||||
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SensorGasModel.h"
|
||||
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SensorTemperaturaSHTModel.h"
|
||||
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SensorLuminosidadeModel.h"
|
||||
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SensorLuzUVModel.h"
|
||||
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SensorQualidadeArModel.h"
|
||||
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SensorChuvaModel.h"
|
||||
#include "C:\ZendionInc\agrobot_base\Firmware\Modulos\SensorMagneticoModel.h"
|
||||
|
||||
|
||||
// Configurações do CAN
|
||||
uint8_t CanID = 0x11;
|
||||
CanService canService(CanID);
|
||||
|
||||
LoRaService loraService(&canService);
|
||||
|
||||
#define D_Code Sen
|
||||
int VERSION = 21;
|
||||
String Mod_ID = "Sen";
|
||||
|
||||
#define _pinoLED RGB_BUILTIN
|
||||
|
||||
bool Conectado = false;
|
||||
bool Conectar = false;
|
||||
|
||||
int _TaxaAmostragem = 1000;
|
||||
volatile bool RequisitarDados = false;
|
||||
int latenciaLoop = 0;
|
||||
int qtdEnviosStatus = 0;
|
||||
int maxEnviosStatus = 5;
|
||||
|
||||
std::vector<SensorTemperatura*> listaSensoresTemperaturaNTC;
|
||||
std::vector<SensorCorrente*> listaSensoresCorrente;
|
||||
std::vector<Sinaleiro*> listaSinaleiros;
|
||||
std::vector<Rele*> listaReles;
|
||||
std::vector<ServoAgro*> listaServos;
|
||||
std::vector<SensorIMU*> listaSensoresIMU;
|
||||
std::vector<SensorGas*> listaSensoresGas;
|
||||
std::vector<SensorTemperaturaSHT*> listaSensoresTemperaturaSHT;
|
||||
std::vector<SensorLuminosidade*> listaSensoresLuminosidade;
|
||||
std::vector<SensorLuzUV*> listaSensoresLuzUV;
|
||||
std::vector<SensorQualidadeAr*> listaSensoresQualidadeAr;
|
||||
std::vector<SensorChuva*> listaSensoresChuva;
|
||||
std::vector<SensorMagnetico*> listaSensoresMagneticos;
|
||||
|
||||
void MostrarLog(String mensagem) {
|
||||
bool _debugMode = false;
|
||||
if (_debugMode) {
|
||||
PrintTela(String("[SEN] ") + mensagem);
|
||||
}
|
||||
}
|
||||
|
||||
void inicializarDependenciasI2C() {
|
||||
I2CService::IniciarI2C();
|
||||
I2CService::IniciarMUX();
|
||||
I2CService::IniciarMCP();
|
||||
}
|
||||
|
||||
void setup() {
|
||||
delay(2000);
|
||||
|
||||
inicializarDependenciasI2C();
|
||||
|
||||
// Registrar callback para processar mensagens CAN recebidas
|
||||
canService.setReceiveCallback([](int packetSize, int senderId, CanMessagePosicaoDados posicao, byte* data, int dataLength) {
|
||||
std::vector<uint8_t> fullData;
|
||||
fullData.push_back(static_cast<uint8_t>(posicao)); // Primeiro byte é sempre a posicao
|
||||
for (int i = 0; i < dataLength; i++) {
|
||||
fullData.push_back(data[i]);
|
||||
}
|
||||
|
||||
ProcessarFrameCAN(posicao, fullData);
|
||||
});
|
||||
|
||||
canService.begin();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (!RequisitarDados) {
|
||||
enviarLogsPeriodicamente();
|
||||
}
|
||||
|
||||
delay(1);
|
||||
}
|
||||
|
||||
// Função para enviar logs do sensor periodicamente
|
||||
unsigned long ultimoEnvioLogs = 0;
|
||||
const unsigned long intervaloEnvioLogs = 1000; // 1 segundo
|
||||
void enviarLogsPeriodicamente() {
|
||||
unsigned long tempoAtual = millis();
|
||||
// Verifica se o intervalo de 5 segundos já passou
|
||||
if (tempoAtual - ultimoEnvioLogs >= intervaloEnvioLogs) {
|
||||
ultimoEnvioLogs = tempoAtual; // Atualiza o tempo do último envio
|
||||
|
||||
enviarDadosSensores(canService.ID_Num_sTOD, CanMessagePosicaoDados::DadosAll);
|
||||
}
|
||||
}
|
||||
|
||||
void enviarDadosSensores(uint8_t id_num, CanMessagePosicaoDados posicao) {
|
||||
if (Conectado || posicao == CanMessagePosicaoDados::Status) {
|
||||
unsigned long startLoop = millis();
|
||||
|
||||
bool enviarStatus = qtdEnviosStatus >= maxEnviosStatus && posicao != CanMessagePosicaoDados::Status;
|
||||
bool todosDados = posicao == CanMessagePosicaoDados::DadosAll;
|
||||
bool todosIDs = id_num == canService.ID_Num_sTOD;
|
||||
|
||||
if (id_num == canService.ID_Num_sMOD) {
|
||||
EnviarDadosCAN(canService.MontarFrameReqStatusMod(D_Code, Conectado, VERSION));
|
||||
return;
|
||||
}
|
||||
|
||||
if (id_num == canService.ID_Num_sLRA) {
|
||||
EnviarDadosCAN(loraService.MontarMensagemCAN(posicao));
|
||||
return;
|
||||
}
|
||||
|
||||
MostrarLog("Atualizando dados dos sensores...");
|
||||
|
||||
if (todosIDs && enviarStatus) {
|
||||
EnviarDadosCAN(canService.MontarFrameReqStatusMod(D_Code, Conectado, VERSION));
|
||||
EnviarDadosCAN(loraService.MontarMensagemCAN(CanMessagePosicaoDados::Status));
|
||||
}
|
||||
|
||||
ComponenteCAN::ProcessarComponentesCAN(listaSensoresTemperaturaNTC, {CanMessagePosicaoDados::Dados1}, todosIDs, id_num, enviarStatus, todosDados, posicao, EnviarDadosCAN);
|
||||
ComponenteCAN::ProcessarComponentesCAN(listaSensoresCorrente, {CanMessagePosicaoDados::Dados1, CanMessagePosicaoDados::Dados2}, todosIDs, id_num, enviarStatus, todosDados, posicao, EnviarDadosCAN);
|
||||
ComponenteCAN::ProcessarComponentesCAN(listaSinaleiros, {CanMessagePosicaoDados::Dados1}, todosIDs, id_num, enviarStatus, todosDados, posicao, EnviarDadosCAN);
|
||||
ComponenteCAN::ProcessarComponentesCAN(listaReles, {CanMessagePosicaoDados::Dados1}, todosIDs, id_num, enviarStatus, todosDados, posicao, EnviarDadosCAN);
|
||||
ComponenteCAN::ProcessarComponentesCAN(listaServos, {CanMessagePosicaoDados::Dados1}, todosIDs, id_num, enviarStatus, todosDados, posicao, EnviarDadosCAN);
|
||||
ComponenteCAN::ProcessarComponentesCAN(listaSensoresGas, {CanMessagePosicaoDados::Dados1}, todosIDs, id_num, enviarStatus, todosDados, posicao, EnviarDadosCAN);
|
||||
ComponenteCAN::ProcessarComponentesCAN(listaSensoresTemperaturaSHT, {CanMessagePosicaoDados::Dados1}, todosIDs, id_num, enviarStatus, todosDados, posicao, EnviarDadosCAN);
|
||||
ComponenteCAN::ProcessarComponentesCAN(listaSensoresLuminosidade, {CanMessagePosicaoDados::Dados1}, todosIDs, id_num, enviarStatus, todosDados, posicao, EnviarDadosCAN);
|
||||
ComponenteCAN::ProcessarComponentesCAN(listaSensoresLuzUV, {CanMessagePosicaoDados::Dados1}, todosIDs, id_num, enviarStatus, todosDados, posicao, EnviarDadosCAN);
|
||||
ComponenteCAN::ProcessarComponentesCAN(listaSensoresQualidadeAr, {CanMessagePosicaoDados::Dados1, CanMessagePosicaoDados::Dados2}, todosIDs, id_num, enviarStatus, todosDados, posicao, EnviarDadosCAN);
|
||||
ComponenteCAN::ProcessarComponentesCAN(listaSensoresChuva, {CanMessagePosicaoDados::Dados1}, todosIDs, id_num, enviarStatus, todosDados, posicao, EnviarDadosCAN);
|
||||
ComponenteCAN::ProcessarComponentesCAN(listaSensoresIMU, {CanMessagePosicaoDados::Dados1, CanMessagePosicaoDados::Dados2}, todosIDs, id_num, enviarStatus, todosDados, posicao, EnviarDadosCAN);
|
||||
ComponenteCAN::ProcessarComponentesCAN(listaSensoresMagneticos, {CanMessagePosicaoDados::Dados1}, todosIDs, id_num, enviarStatus, todosDados, posicao, EnviarDadosCAN);
|
||||
|
||||
if (enviarStatus) {
|
||||
qtdEnviosStatus = 0;
|
||||
}
|
||||
else {
|
||||
qtdEnviosStatus++;
|
||||
}
|
||||
|
||||
latenciaLoop = millis() - startLoop;
|
||||
|
||||
if (posicao == CanMessagePosicaoDados::DadosAll) {
|
||||
EnviarDadosCAN(canService.MontarFrameReqDadosFim(latenciaLoop));
|
||||
}
|
||||
|
||||
MostrarLog("Ciclo concluido, latencia de loop: " + String(latenciaLoop));
|
||||
}
|
||||
}
|
||||
|
||||
void EnviarDadosCAN(std::vector<uint8_t> data) {
|
||||
if (data.size() > 2) {
|
||||
canService.adicionarMensagemFila(data);
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessarFrameCAN(CanMessagePosicaoDados posicao, std::vector<uint8_t> data) {
|
||||
if (data.size() < 1) return;
|
||||
|
||||
F_Code funcao = canService.FuncaoPorPosicao(posicao);
|
||||
|
||||
switch (funcao) {
|
||||
case F_Code::ReqTx: ProcessarReq(data); break;
|
||||
case F_Code::CmdTx: ProcessarCmd(data); break;
|
||||
case F_Code::CfgTx: ProcessarCfg(data); break;
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessarReq(std::vector<uint8_t> data) {
|
||||
if (data.size() < 2) return;
|
||||
CanMessagePosicaoDados posicao = (CanMessagePosicaoDados)data[0];
|
||||
uint8_t id = data[1];
|
||||
enviarDadosSensores(id, posicao);
|
||||
}
|
||||
|
||||
void ProcessarCfg(std::vector<uint8_t> data) {
|
||||
if (data.size() < 4) return;
|
||||
std::vector<uint8_t> _chkRx;
|
||||
CanMessagePosicaoDados posicao = (CanMessagePosicaoDados)data[0];
|
||||
uint8_t id = data[1];
|
||||
S_Code componente = DetectarComponente(id);
|
||||
if (componente == S_Code::sMOD) {
|
||||
switch (posicao) {
|
||||
case CanMessagePosicaoDados::Config1: {
|
||||
if (data.size() < 8) return;
|
||||
bool conectar = data[2] == 1;
|
||||
int taxa = data[3] * 10;
|
||||
bool requisitar = data[4] == 1;
|
||||
loraService.AddressBase = data[5];
|
||||
int pinoSDA = data[6];
|
||||
int pinoSCL = data[7];
|
||||
|
||||
_TaxaAmostragem = taxa;
|
||||
RequisitarDados = requisitar;
|
||||
|
||||
LimparListasComponentes();
|
||||
|
||||
if (pinoSDA != PINO_INVALIDO && pinoSCL != PINO_INVALIDO) {
|
||||
if (I2CService::DefinirPinos(pinoSDA, pinoSCL) || !I2CService::I2CIniciado) {
|
||||
inicializarDependenciasI2C();
|
||||
}
|
||||
}
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
|
||||
Conectado = conectar;
|
||||
_chkRx = canService.MontarFrameReqStatusMod(D_Code, Conectado, VERSION);
|
||||
|
||||
MostrarLog("Configuracao do modulo concluida");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (componente == S_Code::sLRA) {
|
||||
_chkRx = loraService.ConfigurarModulo(data);
|
||||
}
|
||||
else {
|
||||
componente = (S_Code)data[2];
|
||||
switch (componente) {
|
||||
case sNTC: {
|
||||
_chkRx = SensorTemperatura::ConfigurarSensor(listaSensoresTemperaturaNTC, data, Mod_ID);
|
||||
break;
|
||||
}
|
||||
case sCOR: {
|
||||
_chkRx = SensorCorrente::ConfigurarSensor(listaSensoresCorrente, data, Mod_ID);
|
||||
break;
|
||||
}
|
||||
case sLED: {
|
||||
_chkRx = Sinaleiro::ConfigurarSinaleiro(listaSinaleiros, data, Mod_ID);
|
||||
break;
|
||||
}
|
||||
case sRLE: {
|
||||
_chkRx = Rele::ConfigurarRele(listaReles, data, Mod_ID);
|
||||
break;
|
||||
}
|
||||
case sSRV: {
|
||||
_chkRx = ServoAgro::ConfigurarServo(listaServos, data, Mod_ID);
|
||||
break;
|
||||
}
|
||||
case sIMU: {
|
||||
_chkRx = SensorIMU::ConfigurarSensor(listaSensoresIMU, data, Mod_ID);
|
||||
break;
|
||||
}
|
||||
case sGAS: {
|
||||
_chkRx = SensorGas::ConfigurarSensor(listaSensoresGas, data, Mod_ID);
|
||||
break;
|
||||
}
|
||||
case sSHT: {
|
||||
_chkRx = SensorTemperaturaSHT::ConfigurarSensor(listaSensoresTemperaturaSHT, data, Mod_ID);
|
||||
break;
|
||||
}
|
||||
case sLUZ: {
|
||||
_chkRx = SensorLuminosidade::ConfigurarSensor(listaSensoresLuminosidade, data, Mod_ID);
|
||||
break;
|
||||
}
|
||||
case sIUV: {
|
||||
_chkRx = SensorLuzUV::ConfigurarSensor(listaSensoresLuzUV, data, Mod_ID);
|
||||
break;
|
||||
}
|
||||
case sQAR: {
|
||||
_chkRx = SensorQualidadeAr::ConfigurarSensor(listaSensoresQualidadeAr, data, Mod_ID);
|
||||
break;
|
||||
}
|
||||
case sCHV: {
|
||||
_chkRx = SensorChuva::ConfigurarSensor(listaSensoresChuva, data, Mod_ID);
|
||||
break;
|
||||
}
|
||||
case sMAG: {
|
||||
_chkRx = SensorMagnetico::ConfigurarSensor(listaSensoresMagneticos, data, Mod_ID);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EnviarDadosCAN(_chkRx);
|
||||
}
|
||||
|
||||
void ProcessarCmd(std::vector<uint8_t> data) {
|
||||
if (data.size() < 2) return;
|
||||
CanMessagePosicaoDados posicao = (CanMessagePosicaoDados)data[0];
|
||||
uint8_t id = data[1];
|
||||
S_Code componente = DetectarComponente(id);
|
||||
switch (componente) {
|
||||
case sLED: {
|
||||
Sinaleiro::ComandarSinaleiro(listaSinaleiros, data);
|
||||
break;
|
||||
}
|
||||
case sRLE: {
|
||||
Rele::ComandarRele(listaReles, data);
|
||||
break;
|
||||
}
|
||||
case sSRV: {
|
||||
ServoAgro::ComandarServo(listaServos, data);
|
||||
break;
|
||||
}
|
||||
case sLRA: {
|
||||
loraService.EnviarComando(data);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void LimparListasComponentes() {
|
||||
for (auto* rele : listaReles) {
|
||||
rele->Desligar();
|
||||
MostrarLog("Rele " + rele->_ID + " desligado.");
|
||||
delete rele;
|
||||
}
|
||||
listaReles.clear();
|
||||
|
||||
for (auto* sinaleiro : listaSinaleiros) {
|
||||
sinaleiro->Desligar();
|
||||
MostrarLog("Sinaleiro " + sinaleiro->_ID + " desligado.");
|
||||
delete sinaleiro;
|
||||
}
|
||||
listaSinaleiros.clear();
|
||||
|
||||
for (auto* servo : listaServos) {
|
||||
servo->Desligar();
|
||||
MostrarLog("Servo " + servo->_ID + " desligado.");
|
||||
delete servo;
|
||||
}
|
||||
listaServos.clear();
|
||||
|
||||
for (auto* sensor : listaSensoresCorrente) {
|
||||
sensor->Desligar();
|
||||
MostrarLog("Sensor de Corrente " + sensor->_ID + " desligado.");
|
||||
delete sensor;
|
||||
}
|
||||
listaSensoresCorrente.clear();
|
||||
|
||||
for (auto* sensor : listaSensoresTemperaturaNTC) {
|
||||
sensor->Desligar();
|
||||
MostrarLog("Sensor de Temperatura " + sensor->_ID + " desligado.");
|
||||
delete sensor;
|
||||
}
|
||||
listaSensoresTemperaturaNTC.clear();
|
||||
|
||||
for (auto* sensor : listaSensoresIMU) {
|
||||
sensor->Desligar();
|
||||
MostrarLog("Sensor IMU " + sensor->_ID + " desligado.");
|
||||
delete sensor;
|
||||
}
|
||||
listaSensoresIMU.clear();
|
||||
|
||||
for (auto* sensor : listaSensoresGas) {
|
||||
sensor->Desligar();
|
||||
MostrarLog("Sensor de gas " + sensor->_ID + " desligado.");
|
||||
delete sensor;
|
||||
}
|
||||
listaSensoresGas.clear();
|
||||
|
||||
for (auto* sensor : listaSensoresTemperaturaSHT) {
|
||||
sensor->Desligar();
|
||||
MostrarLog("Sensor de temperatura e umidade " + sensor->_ID + " desligado.");
|
||||
delete sensor;
|
||||
}
|
||||
listaSensoresTemperaturaSHT.clear();
|
||||
|
||||
for (auto* sensor : listaSensoresLuminosidade) {
|
||||
sensor->Desligar();
|
||||
MostrarLog("Sensor de luminosidade " + sensor->_ID + " desligado.");
|
||||
delete sensor;
|
||||
}
|
||||
listaSensoresLuminosidade.clear();
|
||||
|
||||
for (auto* sensor : listaSensoresLuzUV) {
|
||||
sensor->Desligar();
|
||||
MostrarLog("Sensor de luz UV " + sensor->_ID + " desligado.");
|
||||
delete sensor;
|
||||
}
|
||||
listaSensoresLuzUV.clear();
|
||||
|
||||
for (auto* sensor : listaSensoresQualidadeAr) {
|
||||
sensor->Desligar();
|
||||
MostrarLog("Sensor de qualidade do ar " + sensor->_ID + " desligado.");
|
||||
delete sensor;
|
||||
}
|
||||
listaSensoresQualidadeAr.clear();
|
||||
|
||||
for (auto* sensor : listaSensoresChuva) {
|
||||
sensor->Desligar();
|
||||
MostrarLog("Sensor de chuva " + sensor->_ID + " desligado.");
|
||||
delete sensor;
|
||||
}
|
||||
listaSensoresChuva.clear();
|
||||
|
||||
for (auto* sensor : listaSensoresMagneticos) {
|
||||
sensor->Desligar();
|
||||
MostrarLog("Sensor magnetico " + sensor->_ID + " desligado.");
|
||||
delete sensor;
|
||||
}
|
||||
listaSensoresMagneticos.clear();
|
||||
|
||||
}
|
||||
|
||||
S_Code DetectarComponente(uint8_t idNum) {
|
||||
if (idNum == canService.ID_Num_sMOD) return S_Code::sMOD;
|
||||
if (idNum == canService.ID_Num_sTOD) return S_Code::sTOD;
|
||||
if (idNum == canService.ID_Num_sLRA) return S_Code::sLRA;
|
||||
for (auto* s : listaSensoresTemperaturaNTC) {
|
||||
if (s->ID_Num == idNum) return S_Code::sNTC;
|
||||
}
|
||||
for (auto* s : listaSensoresCorrente) {
|
||||
if (s->ID_Num == idNum) return S_Code::sCOR;
|
||||
}
|
||||
for (auto* s : listaSinaleiros) {
|
||||
if (s->ID_Num == idNum) return S_Code::sLED;
|
||||
}
|
||||
for (auto* s : listaReles) {
|
||||
if (s->ID_Num == idNum) return S_Code::sRLE;
|
||||
}
|
||||
for (auto* s : listaServos) {
|
||||
if (s->ID_Num == idNum) return S_Code::sSRV;
|
||||
}
|
||||
for (auto* s : listaSensoresIMU) {
|
||||
if (s->ID_Num == idNum) return S_Code::sIMU;
|
||||
}
|
||||
for (auto* s : listaSensoresGas) {
|
||||
if (s->ID_Num == idNum) return S_Code::sGAS;
|
||||
}
|
||||
for (auto* s : listaSensoresTemperaturaSHT) {
|
||||
if (s->ID_Num == idNum) return S_Code::sSHT;
|
||||
}
|
||||
for (auto* s : listaSensoresLuminosidade) {
|
||||
if (s->ID_Num == idNum) return S_Code::sLUZ;
|
||||
}
|
||||
for (auto* s : listaSensoresLuzUV) {
|
||||
if (s->ID_Num == idNum) return S_Code::sIUV;
|
||||
}
|
||||
for (auto* s : listaSensoresQualidadeAr) {
|
||||
if (s->ID_Num == idNum) return S_Code::sQAR;
|
||||
}
|
||||
for (auto* s : listaSensoresChuva) {
|
||||
if (s->ID_Num == idNum) return S_Code::sCHV;
|
||||
}
|
||||
for (auto* s : listaSensoresMagneticos) {
|
||||
if (s->ID_Num == idNum) return S_Code::sMAG;
|
||||
}
|
||||
return S_Code::sVZO;
|
||||
}
|
||||
Loading…
Reference in New Issue