ajustes no lora e mpc

This commit is contained in:
Diego Freitas 2025-09-08 17:03:27 -03:00
parent c510f8a9b6
commit 35202470c3
64 changed files with 373 additions and 212 deletions

Binary file not shown.

View File

@ -226,7 +226,7 @@ namespace AgroBase.Forms.IHM
var lora = Variaveis.LoraService;
lbl.ForeColor = modDesconectado || lora == null
? Color.Black
: lora.Conectado && !lora.Conectado
: lora.Conectado && !lora.Configurado
? Color.Gold
: lora.Configurado
? Color.DarkGreen
@ -367,7 +367,10 @@ namespace AgroBase.Forms.IHM
string modId = lbl.Name.Split('_').Length == 4 ? lbl.Name.Split('_')[3] : "";
if (Sensor == S_Code.sLRA)
{
//saudeIndividual = saudeGeral?.saude_individual.FirstOrDefault(x => x.id == )
saudeIndividual = new ManagerWorkerMessageResponseModulosPendentesSaudeModel()
{
status = Variaveis.LoraService.Configurado ? StatusModulo.Operante : Variaveis.LoraService.Conectado ? StatusModulo.Alerta : StatusModulo.Falha,
};
}
else if (Sensor == S_Code.sFRO)
{
@ -413,7 +416,7 @@ namespace AgroBase.Forms.IHM
{
status = saudeIndividual.status;
saude = saudeIndividual.saude;
erros = string.Join(Environment.NewLine, saudeIndividual.motivos);
erros = string.Join(Environment.NewLine, saudeIndividual.motivos ?? new List<string>());
}
string msg =

View File

@ -166,7 +166,7 @@ namespace AgroBase.Forms.Operacoes
lblRPM.Text = _Sensoriamento.Movimentacao.RPMMedio.ToString("0") + " rpm";
lblVelocidade.Text = (_Sensoriamento.Movimentacao.VelocidadeMedia * 3.6).ToString("0.00");
bool atuadorAtivado = Variaveis.OperacaoEmAndamento.DispAtu.Dados.ConexaoAtiva;
bool atuadorAtivado = Variaveis.OperacaoEmAndamento.DispAtu.Dados.Conectado;
chbPulverizador.Enabled = atuadorAtivado;
if (!atuadorAtivado)
{

View File

@ -1710,6 +1710,8 @@ namespace AgroBase.Models.Modules
loRaService.Conectado = false;
loRaService.Configurado = false;
loRaService.ParametrosGet.UltimaLeitura = DateTime.MinValue;
VisualWorkerService.DadosLeitura.CameraFrames = new Dictionary<CameraFrameType, OAKCameraFrameModel>();
WeedWorkerService.DadosLeitura.CameraFrames = new Dictionary<CameraFrameType, OAKCameraFrameModel>();
ReiniciarLeituras(Dados);
}
@ -1819,7 +1821,7 @@ namespace AgroBase.Models.Modules
config.AddRange(sensoresConfig);
// Adicionar configurações do LoRa
if (false && (!loRaService.Conectado || !loRaService.Configurado || configurarTodos))
if (!loRaService.Conectado || !loRaService.Configurado || configurarTodos)
{
var loraConfig = loRaService.ProtocoloConfiguracao(Pinout, Conectar);
config.AddRange(loraConfig);
@ -2886,7 +2888,7 @@ namespace AgroBase.Models.Modules
{
bool Conectado = data[2] == 1;
bool Configurado = data[3] == 1;
//Console.WriteLine($"[LRA] Resposta {ID_Num} recebida. Conectado={Conectado}, Configurado={Configurado}");
Console.WriteLine($"[LRA] Resposta {ID_Num} recebida. Conectado={Conectado}, Configurado={Configurado}");
loraService.Conectado = Conectado;
loraService.Configurado = Configurado;
break;
@ -2918,6 +2920,7 @@ namespace AgroBase.Models.Modules
default:
{
DadosLoRaParse tipoDado = (DadosLoRaParse)posicao;
Console.WriteLine($"[LRA] Dados recebidos ({tipoDado.ToString()}). " + string.Join(" ", data));
switch (tipoDado)
{
case DadosLoRaParse.ComandoControle:

View File

@ -977,6 +977,11 @@ namespace AgroBase.Models
_ControleAnterior.PercentualVelocidadeSP = _Controle.PercentualVelocidadeSP;
_ControleAnterior.Direcao = _Controle.Direcao;
RedisService.AtualizarCampos(
CtxKey.DadosControle,
("velocidade_sp_ant", _Controle.PercentualVelocidadeSP)
);
Protocolos = new List<string>()
{
_Controle.Direcao.ToString() + ";" + _Controle.RPM_SP.ToString()
@ -1013,6 +1018,12 @@ namespace AgroBase.Models
_ControleAnterior.Angulo = _Controle.Angulo;
_ControleAnterior.Direcao = _Controle.Direcao;
RedisService.AtualizarCampos(
CtxKey.DadosControle,
("angulo_sp_ant", _Controle.Angulo),
("tipo_movimento_direcional_ant", _Controle.TipoMovimento)
);
Protocolos = new List<string>()
{
_Controle.Direcao.ToString() + ";" + _Controle.Angulo.ToString()
@ -1262,7 +1273,7 @@ namespace AgroBase.Models
Variaveis.OperacaoEmAndamento.idxLog++;
if (Variaveis.OperacaoEmAndamento.idxLog % 5 == 0)
if (Variaveis.OperacaoEmAndamento.idxLog % 10 == 0)
{
Variaveis.LoraService.EnviarDadosParaBase();
}
@ -1753,7 +1764,7 @@ namespace AgroBase.Models
PercentualErvasTerreno = _DispAtu.Dados.PercentualErvasTerreno,
HerbicidaPorErva = HerbicidaPorErva,
ErvasNoRadar = WeedWorkerService.DadosLeitura?.Analise?.ervas_no_radar ?? false,
PercentualErvasNoRadar = WeedWorkerService.DadosLeitura?.Analise?.estatisticas?.erva?.frac_global ?? 0,
PercentualErvasNoRadar = WeedWorkerService.DadosLeitura?.Analise?.estatisticas?.erva?.ema_global ?? 0,
PercentualReservatorio = FuncoesMatematicas.Clamp(_DispAtu.Dados.PercentualReservatorio, 0, 100),
VolumeReservatorio = _DispAtu.Dados.VolumeReservatorio,
PressaoLinha = _DispAtu.Dados.PressaoLinha,

View File

@ -8,6 +8,7 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using static AgroBase.Models.Enums;
using static AgroBase.Services.LoRaEspService;
namespace AgroBase.Services
{
@ -320,6 +321,10 @@ namespace AgroBase.Services
{
Mensagens.Add(novaMensagem);
MostrarLog($"Mensagem adicionada na fila. ID: {novaMensagem.IdTx}, Data: {FuncoesGlobais.ConverterComandoBytesParaTexto(novaMensagem.DataTx)}", idTx);
//if (dados[1] == Variaveis.ID_Num_sLRA)
//{
// Console.WriteLine($"{DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss.fff")} - MENSAGEM LORA ADICIONADO NA FILA CAN, FUNC_CODE: {((CanMessagePosicaoDados)dados[0]).ToString()} ({((DadosLoRaParse)dados[0]).ToString()}) " + string.Join(" ", dados));
//}
}
else
{

View File

@ -228,6 +228,10 @@ namespace AgroBase.Services
{
MensagensPendentes.Add(novaMensagem);
MostrarLog($"Mensagem adicionada na fila. ID: {novaMensagem.IdTx}, Data: {FuncoesGlobais.ConverterComandoBytesParaTexto(novaMensagem.DataTx)}", idTx);
//if (payload[0] == Variaveis.ID_Num_sLRA)
//{
// Console.WriteLine($"{DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss.fff")} - MENSAGEM LORA ADICIONADO NA FILA CAN, FUNC_CODE: {((CanMessagePosicaoDados)payload[1]).ToString()} ({((DadosLoRaParse)payload[1]).ToString()})" + string.Join(" ", payload));
//}
}
else
{

View File

@ -49,7 +49,7 @@ namespace AgroBase.Services
ParametrosSet.tranModeAndWorCycle
};
//Console.WriteLine($"Parametros de configuracao LoRa: {FuncoesGlobais.ConverterComandoBytesParaTexto(config2.ToArray())}");
Console.WriteLine($"Parametros de configuracao LoRa: {FuncoesGlobais.ConverterComandoBytesParaTexto(config2.ToArray())}");
return new List<(int, CanMessagePosicaoDados, byte[])>()
{

View File

@ -260,7 +260,7 @@ namespace AgroBase.Services
_long.AddRange(CompactarCoordenada(Gps.Longitude)); // 6 bytes
List<byte> _gerais = new List<byte>();
_long.AddRange(CanPrefix(DadosLoRaParse.GpsGerais));
_gerais.AddRange(CanPrefix(DadosLoRaParse.GpsGerais));
_gerais.AddRange(CompactarDecimal(Gps.Altitude)); // 2 bytes
_gerais.AddRange(CompactarDecimal(Gps.Velocidade)); // 2 bytes
_gerais.AddRange(CompactarDecimal(Gps.OrientacaoReal)); // 2 bytes

View File

@ -27,7 +27,7 @@ namespace AgroBase.Services
{
get
{
return VersionamentoService.ArquivoScript(Enums.TipoArquivoVersionado.Script_GreenDetector).NomeArquivoLocal;
return VersionamentoService.ArquivoScript(Enums.TipoArquivoVersionado.Script_WeedDetector).NomeArquivoLocal;
}
}
public static string ScriptStreetDetector

View File

@ -1 +0,0 @@
1.1AB07E887ACCA305058EEAB9053C96DC531C2C5C067AB4F30AFA2B31F1EDD966

View File

@ -1,5 +0,0 @@
{
"description": "Microsoft CRLSet",
"name": "MicrosoftCRLSet",
"version": "6498.2024.12.2"
}

View File

@ -20,7 +20,14 @@
"padded_top_topics_start_index": 0,
"taxonomy_version": 0,
"top_topics_and_observing_domains": [ ]
}, {
"calculation_time": "13401820180888621",
"config_version": 0,
"model_version": "0",
"padded_top_topics_start_index": 0,
"taxonomy_version": 0,
"top_topics_and_observing_domains": [ ]
} ],
"hex_encoded_hmac_key": "40F346D3248C3AFDF2BEE1FE496DBD32F7CED6E5AE98B881ABC421AA7E7B5642",
"next_scheduled_calculation_time": "13401819543885718"
"next_scheduled_calculation_time": "13402424980889204"
}

View File

@ -1,3 +1,3 @@
2025/09/05-16:00:23.061 940 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001
2025/09/05-16:00:23.067 940 Recovering log #3
2025/09/05-16:00:23.070 940 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/000003.log
2025/09/08-16:31:17.388 11ec Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001
2025/09/08-16:31:17.394 11ec Recovering log #3
2025/09/08-16:31:17.398 11ec Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/000003.log

View File

@ -1,3 +1,3 @@
2025/09/05-15:33:19.570 47c8 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001
2025/09/05-15:33:19.578 47c8 Recovering log #3
2025/09/05-15:33:19.582 47c8 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/000003.log
2025/09/08-16:13:12.809 9cc Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001
2025/09/08-16:13:12.816 9cc Recovering log #3
2025/09/08-16:13:12.819 9cc Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/000003.log

View File

@ -1 +1 @@
{"net":{"http_server_properties":{"servers":[{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13401661076733928","port":443,"protocol_str":"quic"}],"anonymization":["DAAAAAcAAABmaWxlOi8vAA==",false,0],"network_stats":{"srtt":139822},"server":"https://tile.openstreetmap.org","supports_spdy":true}],"supports_quic":{"address":"2804:d78:6a8:5d00:ecfc:7de1:4083:8c14","used_quic":true},"version":5},"network_qualities":{"CAASABiAgICA+P////8B":"4G","CAESABiAgICA+P////8B":"4G","CAISABiAgICA+P////8B":"4G","CAYSABiAgICA+P////8B":"Offline"}}}
{"net":{"http_server_properties":{"servers":[{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13401919905758592","port":443,"protocol_str":"quic"}],"anonymization":["DAAAAAcAAABmaWxlOi8vAA==",false,0],"network_stats":{"srtt":12274},"server":"https://tile.openstreetmap.org","supports_spdy":true}],"supports_quic":{"address":"2804:d78:6a8:5d00:3:b137:22ef:9d9c","used_quic":true},"version":5},"network_qualities":{"CAASABiAgICA+P////8B":"4G","CAESABiAgICA+P////8B":"4G","CAISABiAgICA+P////8B":"4G","CAYSABiAgICA+P////8B":"Offline"}}}

View File

@ -1 +1 @@
{"sts":[{"expiry":1788608154.333512,"host":"bWGAftl61rqoc0YzqPncsLvQQh/iC2Bdp3ejUeGC83w=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1757072154.333517}],"version":2}
{"sts":[{"expiry":1788891588.105686,"host":"bWGAftl61rqoc0YzqPncsLvQQh/iC2Bdp3ejUeGC83w=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1757355588.105689}],"version":2}

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,3 @@
2025/09/05-16:50:13.785 940 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001
2025/09/05-16:50:13.786 940 Recovering log #3
2025/09/05-16:50:13.789 940 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/000003.log
2025/09/08-17:01:10.553 11ec Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001
2025/09/08-17:01:10.555 11ec Recovering log #3
2025/09/08-17:01:10.558 11ec Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/000003.log

View File

@ -1,3 +1,3 @@
2025/09/05-15:39:06.299 47c8 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001
2025/09/05-15:39:06.300 47c8 Recovering log #3
2025/09/05-15:39:06.304 47c8 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/000003.log
2025/09/08-16:14:02.023 9cc Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001
2025/09/08-16:14:02.024 9cc Recovering log #3
2025/09/08-16:14:02.026 9cc Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/000003.log

View File

@ -1,3 +1,3 @@
2025/09/05-16:00:22.989 1b60 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001
2025/09/05-16:00:22.991 1b60 Recovering log #7
2025/09/05-16:00:22.991 1b60 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/000007.log
2025/09/08-16:31:17.316 42c4 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001
2025/09/08-16:31:17.318 42c4 Recovering log #7
2025/09/08-16:31:17.318 42c4 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/000007.log

View File

@ -1,3 +1,3 @@
2025/09/05-15:33:19.486 5698 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001
2025/09/05-15:33:19.488 5698 Recovering log #7
2025/09/05-15:33:19.488 5698 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/000007.log
2025/09/08-16:13:12.733 2a9c Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001
2025/09/08-16:13:12.736 2a9c Recovering log #7
2025/09/08-16:13:12.736 2a9c Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/000007.log

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"hashes":{"00AF3F07B5ABB71F6D30337E1EEF62FA280F06EF19485C0CF6B72171F92CCC0A":{"appid":"kpfehajjjbbcifeehjgfgnabifknmdad","fp":"1.00AF3F07B5ABB71F6D30337E1EEF62FA280F06EF19485C0CF6B72171F92CCC0A"},"1AB07E887ACCA305058EEAB9053C96DC531C2C5C067AB4F30AFA2B31F1EDD966":{"appid":"oankkpibpaokgecfckkdkgaoafllipag","fp":"1.1AB07E887ACCA305058EEAB9053C96DC531C2C5C067AB4F30AFA2B31F1EDD966"},"452064dcff76e03e0e81b4bb3c48ab1c432e040094f7546c7261a90d4a1c1bbf":{"appid":"fgbafbciocncjfbbonhocjaohoknlaco","fp":""},"4B81B4DF3AD971287E1AE02C449344FCFA5D20431DE17B2BA8854CC9CDCE4089":{"appid":"ahmaebgpfccdhgidjaidaoojjcijckba","fp":"1.4B81B4DF3AD971287E1AE02C449344FCFA5D20431DE17B2BA8854CC9CDCE4089"},"89f43cb3df807293de2772d5f01ac2fc1482b38ccc8fdaee859b80642b7a0487":{"appid":"pghocgajpebopihickglahgebcmkcekh","fp":""},"95FD9D48E4FC245A3F3A99A3A16ECD1355050BA3F4AFC555F19A97C7F9B49677":{"appid":"ohckeflnhegojcjlcpbfpciadgikcohk","fp":"1.95FD9D48E4FC245A3F3A99A3A16ECD1355050BA3F4AFC555F19A97C7F9B49677"},"A81D1959892AE4180554347DF1B97834ABBA2E1A5E6B9AEBA000ECEA26EABECC":{"appid":"fppmbhmldokgmleojlplaaodlkibgikh","fp":"1.A81D1959892AE4180554347DF1B97834ABBA2E1A5E6B9AEBA000ECEA26EABECC"},"A99D66CFCE8CA170740CE0403956F4DFAF4683829A89F4B7AD9C95303871E284":{"appid":"eeobbhfgfagbclfofmgbdfoicabjdbkn","fp":"1.A99D66CFCE8CA170740CE0403956F4DFAF4683829A89F4B7AD9C95303871E284"},"b987bdc4f2ad2a409b964921d4a5db1cdbe07f9c98f868293b4cc32acdc42cec":{"appid":"alpjnmnfbgfkmmpcfpejmmoebdndedno","fp":""},"bcb93cba8636743d1fbd32be3bd8ce8ff602323895bf4d136c26b9bc64b0a6a4":{"appid":"ndikpojcjlepofdkaaldkinkjbeeebkl","fp":""}}}
{"hashes":{"00AF3F07B5ABB71F6D30337E1EEF62FA280F06EF19485C0CF6B72171F92CCC0A":{"appid":"kpfehajjjbbcifeehjgfgnabifknmdad","fp":"1.00AF3F07B5ABB71F6D30337E1EEF62FA280F06EF19485C0CF6B72171F92CCC0A"},"452064dcff76e03e0e81b4bb3c48ab1c432e040094f7546c7261a90d4a1c1bbf":{"appid":"fgbafbciocncjfbbonhocjaohoknlaco","fp":""},"4B81B4DF3AD971287E1AE02C449344FCFA5D20431DE17B2BA8854CC9CDCE4089":{"appid":"ahmaebgpfccdhgidjaidaoojjcijckba","fp":"1.4B81B4DF3AD971287E1AE02C449344FCFA5D20431DE17B2BA8854CC9CDCE4089"},"89f43cb3df807293de2772d5f01ac2fc1482b38ccc8fdaee859b80642b7a0487":{"appid":"pghocgajpebopihickglahgebcmkcekh","fp":""},"95FD9D48E4FC245A3F3A99A3A16ECD1355050BA3F4AFC555F19A97C7F9B49677":{"appid":"ohckeflnhegojcjlcpbfpciadgikcohk","fp":"1.95FD9D48E4FC245A3F3A99A3A16ECD1355050BA3F4AFC555F19A97C7F9B49677"},"A81D1959892AE4180554347DF1B97834ABBA2E1A5E6B9AEBA000ECEA26EABECC":{"appid":"fppmbhmldokgmleojlplaaodlkibgikh","fp":"1.A81D1959892AE4180554347DF1B97834ABBA2E1A5E6B9AEBA000ECEA26EABECC"},"A99D66CFCE8CA170740CE0403956F4DFAF4683829A89F4B7AD9C95303871E284":{"appid":"eeobbhfgfagbclfofmgbdfoicabjdbkn","fp":"1.A99D66CFCE8CA170740CE0403956F4DFAF4683829A89F4B7AD9C95303871E284"},"b987bdc4f2ad2a409b964921d4a5db1cdbe07f9c98f868293b4cc32acdc42cec":{"appid":"alpjnmnfbgfkmmpcfpejmmoebdndedno","fp":""},"bcb93cba8636743d1fbd32be3bd8ce8ff602323895bf4d136c26b9bc64b0a6a4":{"appid":"ndikpojcjlepofdkaaldkinkjbeeebkl","fp":""},"fa29a6d5775ff340900a65b39b02fc8b4b77d403c048d8debf22f2f5d09c61a0":{"appid":"oankkpibpaokgecfckkdkgaoafllipag","fp":""}}}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -17,7 +17,7 @@
<meta name="viewport" content="width=device-width,
initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<style>
#map_b4846582c871aaafb422e9fb94bff081 {
#map_28e5199720417a91208a7dff1794e441 {
position: relative;
width: 100.0%;
height: 100.0%;
@ -54,14 +54,14 @@
<body>
<div class="folium-map" id="map_b4846582c871aaafb422e9fb94bff081" ></div>
<div class="folium-map" id="map_28e5199720417a91208a7dff1794e441" ></div>
</body>
<script>
var map_b4846582c871aaafb422e9fb94bff081 = L.map(
"map_b4846582c871aaafb422e9fb94bff081",
var map_28e5199720417a91208a7dff1794e441 = L.map(
"map_28e5199720417a91208a7dff1794e441",
{
center: [0.0, 0.0],
crs: L.CRS.EPSG3857,
@ -96,7 +96,7 @@
}
trajeto_json_add({"features": []});
trajeto_json.addTo(map_b4846582c871aaafb422e9fb94bff081);
trajeto_json.addTo(map_28e5199720417a91208a7dff1794e441);
function adicionarGeometria(novaGeometria) {
trajeto_json.addData(novaGeometria);
@ -159,9 +159,9 @@
var marcadorEquipamento = L.marker([0, 0], {
icon: customIcon
}).addTo(map_b4846582c871aaafb422e9fb94bff081);
}).addTo(map_28e5199720417a91208a7dff1794e441);
var marcadorBase = L.marker([0, 0], {}).addTo(map_b4846582c871aaafb422e9fb94bff081);
var marcadorBase = L.marker([0, 0], {}).addTo(map_28e5199720417a91208a7dff1794e441);
var icon = L.AwesomeMarkers.icon(
{"extraClasses": "fa-rotate-0", "icon": "info-sign", "iconColor": "white", "markerColor": "red", "prefix": "glyphicon"}
);
@ -226,7 +226,7 @@
}
if (foco) {
map_b4846582c871aaafb422e9fb94bff081.setView(novaPosicao, map_b4846582c871aaafb422e9fb94bff081.getZoom());
map_28e5199720417a91208a7dff1794e441.setView(novaPosicao, map_28e5199720417a91208a7dff1794e441.getZoom());
}
}
@ -248,7 +248,7 @@
marcadorDinamico.setRotationAngle(angulo);
adicionarCoordenada("Tj", [novaLongitude, novaLatitude]);
map_b4846582c871aaafb422e9fb94bff081.setView(novaPosicao, map_b4846582c871aaafb422e9fb94bff081.getZoom());*/
map_28e5199720417a91208a7dff1794e441.setView(novaPosicao, map_28e5199720417a91208a7dff1794e441.getZoom());*/
});
function calcularOrientacao(P1latitude, P1longitude, P2latitude, P2longitude) {

File diff suppressed because one or more lines are too long

View File

@ -258,9 +258,9 @@ def _comando_mapa_gps_mpc(contexto):
_controle = ContextoGlobalRedis.get_controle()
comando_anterior = {
"angulo": _controle.get("angulo_sp", 0.0),
"tipo": _controle.get("tipo_movimento_direcional", TipoMovimentoDirecional.RodasDianteiras.value),
"velocidade": _controle.get("velocidade_sp", 0.0)
"angulo": _controle.get("angulo_sp_ant", 0.0),
"tipo": _controle.get("tipo_movimento_direcional_ant", TipoMovimentoDirecional.RodasDianteiras.value),
"velocidade": _controle.get("velocidade_sp_ant", 0.0)
}
# 🔸 Requisição ao controlador MPC

View File

@ -29,7 +29,7 @@ def definir_comando(parada_necessaria: bool, erro: bool, filtro_vel: FiltroVeloc
#percentual_ervas_no_radar = (_contexto.get("Gerais", {}).get("percentual_ervas_no_radar", 0)) * 100.0
_dados_ww = ContextoGlobalRedis.get(CtxKey.DadosWeedWorker, {}).get("analise", {})
ervas_no_radar = _dados_ww.get("ervas_no_radar", False)
percentual_ervas_no_radar = _dados_ww.get("estatisticas", {}).get("frac_global", 0.0)
percentual_ervas_no_radar = _dados_ww.get("estatisticas", {}).get("ema_global", 0.0)
vel_min = 15
ervas_min_percenet = 0.5

View File

@ -1,4 +1,3 @@
from copy import deepcopy
import heapq
import math
import time
@ -254,7 +253,7 @@ class ControladorMPC:
def _corrigir_pontos_visitados(self, x, y, pontos_visitados: np.ndarray, idx_atual: int = -1,
limite_max_avanco: float = 5.0, # em METROS
limite_max_pontos: int = 10):
limite_max_pontos: int = 10, velocidade: float = -1, dt: float = -1):
try:
p_xy, p_mg, p_s = self._p_xy, self._p_margem, self._p_s
N = p_xy.shape[0]
@ -263,7 +262,7 @@ class ControladorMPC:
# --- (1) Igual ao antigo: marcar EXCLUSIVO quando idx_atual vier do C# ---
if idx_atual > -1:
pontos_visitados[:idx_atual] = True # <<< EXCLUSIVO (antes era :idx_atual+1)
pontos_visitados[:idx_atual+1] = True # <<< EXCLUSIVO (antes era :idx_atual+1)
return idx_atual
if pontos_visitados.all():
@ -286,12 +285,18 @@ class ControladorMPC:
margem2 = p_mg[sl] * p_mg[sl]
# --- (2) Opcional para fidelidade ao antigo: usar '<' em vez de '<=' ---
hits = dist2 < margem2 # era <=
hits = dist2 <= margem2 # era <=
if np.any(hits):
off = int(np.argmax(hits))
idx = start_idx + off
pontos_visitados[:idx+1] = True
pontos_visitados[:idx] = True
if velocidade > -1:
s_hit = self._p_s[idx]
s_goal = s_hit + self.d_look_ahead_m(velocidade, dt)
idx_alvo = int(np.searchsorted(self._p_s, s_goal, side="left"))
idx_alvo = min(idx_alvo, len(self._p_s)-1)
return idx_alvo
return idx
# --- (3) Fallback robusto para “próximo não visitado” ---
@ -333,7 +338,7 @@ class ControladorMPC:
try:
peso_erro_pos = 1.2 # 0
peso_erro_ori = 1.0 # 1
peso_suavidade = 1.4 # 2
peso_suavidade = 1.5 # 2
peso_fator_re = 0.2 # 3
peso_ideal = 0.4 # 4
@ -380,7 +385,7 @@ class ControladorMPC:
Propaga (x,y,theta) por 'latency_s' usando 'nova_posicao_fn' que depende de self.dt.
Retorna (x, y, theta) estimados no presente.
"""
visitados_copy = deepcopy(visitados)
visitados_copy = visitados.copy()
latency_s = max(0.0, float(latency_s))
if latency_s == 0.0:
return x, y, theta, visitados_copy
@ -435,6 +440,63 @@ class ControladorMPC:
# theta = (theta + np.pi) % (2*np.pi) - np.pi
return x, y, theta, visitados_copy
def d_look_ahead_m(self, velocidade, dt: float = None):
"""
Retorna look-ahead em METROS.
- velocidade: pode vir em m/s ou normalizada (0-1). Detecto automaticamente.
- dt: passo real do MPC (s) para suavização adaptativa (opcional).
"""
# --- 1) Normalização de velocidade ---------------------------------------
# tente usar self.vel_max_m_s se já existir; senão, usa 6.8 km/h (~1.889 m/s)
vel_max_ms = getattr(self, "vel_max_m_s", 6.8/3.6)
v = float(velocidade)
if v <= 1.05: # heurística: trata <=1.0 como v_norm
v = max(0.0, min(1.0, v)) * vel_max_ms
else:
v = max(0.0, v) # já está em m/s
# --- 2) Base polinomial (suave e previsível) ------------------------------
# L_base = L0 + a*v + b*v^2 (clamp em [Lmin, Lmax])
Lmin, Lmax = 0.60, 2.80 # bom para teu range (1.36.8 km/h)
L0, a, b = 0.60, 0.70, 0.20
L = L0 + a*v + b*(v*v)
if L < Lmin: L = Lmin
if L > Lmax: L = Lmax
# --- 3) Redução por curvatura e erro de orientação ------------------------
# Se você já calcula curvatura/erro, exponha em self; senão, assumo 0.
kappa = abs(getattr(self, "curvatura_atual", 0.0)) # 1/m
err_yaw = abs(getattr(self, "erro_angular_atual", 0.0)) # rad
# Fatores <=1.0: reduzem o L em curva forte e/ou erro de yaw grande.
# Ajuste c_k, c_e conforme seu corredor (mais alto = reduz mais).
c_k, c_e = 3.0, 1.2
f_k = 1.0 / (1.0 + c_k * kappa)
f_e = 1.0 / (1.0 + c_e * err_yaw)
L *= min(f_k, f_e)
# --- 4) Compensação de latência de controle/planta ------------------------
# Se você tem latência medida, exponha em self.tau_ctrl (s). Senão: ~0.15 s.
tau = float(getattr(self, "tau_ctrl", 0.15))
L += v * tau # “empurra” o alvo à frente para cobrir atraso
# Clamp final para garantir limites mesmo após fatores
if L < Lmin: L = Lmin
if L > Lmax: L = Lmax
# --- 5) Suavização temporal (anti-chatter) --------------------------------
# EMA com constante de tempo ~0.4 s (ajuste T_ema). Usa dt se informado.
T_ema = 0.40
if dt is None:
dt = float(getattr(self, "dt", 0.15)) # teu MPC já guarda dt
alpha = max(0.0, min(1.0, 1.0 - pow(2.718281828, -dt / T_ema)))
L_suave = getattr(self, "_L_ema", L)
L_suave = (1.0 - alpha) * L_suave + alpha * L
self._L_ema = L_suave
return L_suave
def _wrap_pi(self, a):
try:
@ -649,7 +711,7 @@ class ControladorMPC:
if exp_budget <= 0 or ms_left() <= 0:
break
x_atual, y_atual, theta_atual = candidato["x"], candidato["y"], candidato["theta"]
visitados = deepcopy(candidato["visitados"])
visitados = candidato["visitados"].copy()
cmd_anterior = {
"tipo": candidato["comandos"][-1][0],
"angulo": candidato["comandos"][-1][1],
@ -878,7 +940,7 @@ class ControladorMPC:
)
}
cmd_seq = None
x, y, theta, pts_visitados = self.corrigir_pose_por_latencia(
x, y, theta, self.visitados_execucao = self.corrigir_pose_por_latencia(
x, y, theta, self.visitados_execucao,
latency_s=min(pos_latencia, LAT_MAX),
dt=self.dt,
@ -888,7 +950,7 @@ class ControladorMPC:
time_left_ms=lambda: (deadline - now()) * 1000.0,
calc_omega_fn=self.gps_handler.calcular_omega
)
idx_alvo_correcao = self._corrigir_pontos_visitados(x, y, pts_visitados, idx_proximo_ponto_real)
idx_alvo_correcao = self._corrigir_pontos_visitados(x, y, self.visitados_execucao, idx_proximo_ponto_real)
# -------------------- Planejamento: horizonte ESPACIAL fixo --------------------
S_ALVO = float(getattr(self, "horizonte", 2.5))
@ -941,7 +1003,7 @@ class ControladorMPC:
"custo": 0.0,
"comandos": [(tipo_anterior, angulo_anterior)],
"trajetoria": [],
"visitados": pts_visitados,
"visitados": self.visitados_execucao,
"inicial": True
}]
@ -957,14 +1019,14 @@ class ControladorMPC:
break
x_atual, y_atual, theta_atual = candidato["x"], candidato["y"], candidato["theta"]
visitados = deepcopy(candidato["visitados"])
visitados = candidato["visitados"].copy()
cmd_anterior_local = {
"tipo": candidato["comandos"][-1][0],
"angulo": candidato["comandos"][-1][1],
}
idx_alvo = self._corrigir_pontos_visitados(x_atual, y_atual, visitados)
if idx_alvo < len(self.pontos_info) - 1: idx_alvo += 1
idx_alvo = self._corrigir_pontos_visitados(x_atual, y_atual, visitados, velocidade=v_sim, dt=dt_pred)
#if idx_alvo < len(self.pontos_info) - 1: idx_alvo += 1
ponto_alvo = self.pontos_info[idx_alvo]
tipos, angs, custos_candidatos = self._gerar_angulos_candidatos_receding(
@ -1931,7 +1993,7 @@ class ControladorMPC:
simulacoes = []
prev_ang = float(comando_anterior.get("angulo", 0.0))
prev_tipo = comando_anterior.get("tipo", TipoMovimentoDirecional.RodasDianteiras.value)
pontos_visitados = deepcopy(visitados)
pontos_visitados = visitados.copy()
# Contexto usado no custo
angulo_caminho = np.radians(contexto.get("Carro", {}).get("AnguloCaminho", 0.0))
@ -1945,7 +2007,7 @@ class ControladorMPC:
passos_local = max(1, int(getattr(self, "passos_horizonte_local", 1)))
dt_total = float(dt_pred) * passos_local
SUB_MAX = float(getattr(self, "_dt_sub_max", 0.08)) # ~80 ms por subpasso
SUB_MAX = float(getattr(self, "_dt_sub_max", 0.15)) # ~80 ms por subpasso
n_sub = max(1, int(math.ceil(dt_total / SUB_MAX)))
sub_dt = dt_total / n_sub
dist_sub = v_planejado * sub_dt # usado para custo por metro
@ -1962,7 +2024,7 @@ class ControladorMPC:
simulacoes.append((x_sim, y_sim, theta_sim))
# alvo mais próximo após avançar
idx_alvo_sim = self._corrigir_pontos_visitados(x_sim, y_sim, pontos_visitados)
idx_alvo_sim = self._corrigir_pontos_visitados(x_sim, y_sim, pontos_visitados, velocidade=v_planejado, dt=sub_dt)
ponto_alvo_sim = self.pontos_info[idx_alvo_sim]["xy"]
# orientação do caminho + erro angular combinado

View File

@ -104,15 +104,15 @@ class CostmapFuser:
use_persistence=False,
velocidade_mps=None, # m/s; se None, decisão não usa distância de frenagem
a_max_freio=0.8, # m/s²
margem_parada=0.25, # m
margem_parada=0.5, # m
N_on=2, # frames p/ entrar
N_off=5, # frames p/ sair
N_off=3, # frames p/ sair
blackout_imediato=True,
det_score_f=None, # (H,W) 0..1
det_label_id=None, # (H,W) int, -1 = none
det_strength=None, # (H,W) 0..1 ~ conf*cov dominante
thr_det_consider=0.25
thr_det_consider=0.15
):
H, W = custo_f.shape
c0, c1 = central_cols

View File

@ -183,13 +183,16 @@ public:
// tenta enfileirar pro worker
if (callbacksQ && xQueueSend(callbacksQ, &message, 0) != pdTRUE) {
if (DebugMode) {
PrintTela("Erro ao adicionar mensagem recebida na fila: " + String(rx_drops));
}
rx_drops++;
// (opcional) política "drop oldest": remove 1 e tenta de novo
// twai_message_t dump;
// if (xQueueReceive(callbacksQ, &dump, 0) == pdTRUE) {
// xQueueSend(callbacksQ, &message, 0);
// }
twai_message_t dump;
if (xQueueReceive(callbacksQ, &dump, 0) == pdTRUE) {
xQueueSend(callbacksQ, &message, 0);
}
vTaskDelay(pdMS_TO_TICKS(1)); // dá uma respirada
}
@ -212,8 +215,7 @@ public:
if (xQueueReceive(callbacksQ, &msg, portMAX_DELAY) == pdTRUE) {
if (_callback && msg.data_length_code > 0) {
CanMessagePosicaoDados posicao = (CanMessagePosicaoDados)msg.data[0];
_callback(msg.data_length_code, msg.identifier, posicao,
&msg.data[1], msg.data_length_code - 1);
_callback(msg.data_length_code, msg.identifier, posicao, &msg.data[1], msg.data_length_code - 1);
}
}
@ -540,7 +542,7 @@ private:
uint32_t _baudRate = 250000;
uint8_t _nodeId = 0;
OnReceiveCallback _callback = nullptr;
bool DebugMode = true;
bool DebugMode = false;
};
#endif // CANSERVICE_H

View File

@ -57,7 +57,7 @@ public:
// Inicializa GPIOs
pinMode(_pinM0, OUTPUT);
pinMode(_pinM1, OUTPUT);
pinMode(_pinAUX, INPUT);
pinMode(_pinAUX, INPUT_PULLUP);
_serialLoRa = &Serial2;
if (Conectado) {
@ -194,14 +194,32 @@ public:
//EnviarDadosCAN(MontarMensagemCAN(CanMessagePosicaoDados::Status));
if (Conectado) {
if (requisitarParametrosLoRa()) {
//EnviarDadosCAN(MontarMensagemCAN(CanMessagePosicaoDados::Dados1));
// Log detalhado do que veio da EEPROM
MostrarLog("EEPROM -> "
"Addr=" + String(parametrosAtual.address, HEX) +
" BaudAir=" + String(parametrosAtual.baudAndAirRate, HEX) +
" PacketPower=" + String(parametrosAtual.packetSizeAndPower, HEX) +
" Channel=" + String(parametrosAtual.channel, HEX) +
" TranModeWor=" + String(parametrosAtual.tranModeAndWorCycle, HEX)
);
MostrarLog("Desejado -> "
"Addr=" + String(addr, HEX) +
" BaudAir=" + String(baud, HEX) +
" PacketPower=" + String(packet, HEX) +
" Channel=" + String(channel, HEX) +
" TranModeWor=" + String(worCycle, HEX)
);
Configurado =
(uint8_t)parametrosAtual.address == (uint8_t)addr &&
(uint8_t)parametrosAtual.baudAndAirRate == (uint8_t)baud &&
(uint8_t)parametrosAtual.packetSizeAndPower == (uint8_t)packet &&
(uint8_t)parametrosAtual.channel == (uint8_t)channel &&
(uint8_t)parametrosAtual.tranModeAndWorCycle == (uint8_t)worCycle;
MostrarLog("Modulo ja configurado: " + String(Configurado));
parametrosAtual.address == addr &&
parametrosAtual.baudAndAirRate == baud &&
parametrosAtual.packetSizeAndPower == packet &&
parametrosAtual.channel == channel &&
parametrosAtual.tranModeAndWorCycle== worCycle;
MostrarLog(String("Modulo ja configurado? ") + (Configurado ? "SIM" : "NAO"));
if (!Configurado) {
Configurado = configurarModuloLoRa(addr, baud, packet, channel, worCycle);
}
@ -252,7 +270,7 @@ private:
void LraTaskRx(void* pvParameters) {
LoRaService* service = static_cast<LoRaService*>(pvParameters);
while (true) {
if (!Conectado || !Configurado) {
if (!Conectado || !Configurado || PausarRX) {
vTaskDelay(1000);
continue;
}
@ -343,7 +361,7 @@ private:
LoRaService* service = static_cast<LoRaService*>(pvParameters);
std::vector<uint8_t> msg;
while (true) {
if (!Conectado || !Configurado) {
if (!Conectado || !Configurado || PausarTX) {
vTaskDelay(1000);
continue;
}
@ -386,49 +404,98 @@ private:
int _baudRate = 9600;
LoRaMode currentMode = NORMAL;
LoRaParametrosModel parametrosAtual;
int commandTimeout = 200;
int commandTimeout = 800;
bool PausarTX = false;
bool PausarRX = false;
// Métodos internos
void pauseLoRaTasks() {
// pare produtoras de TX e consumidoras de RX antes de mexer no modo
PausarTX = true; // sua flag para impedir enqueue/envio
PausarRX = true; // idem recepção
vTaskDelay(5);
}
void resumeLoRaTasks() {
PausarTX = false;
PausarRX = false;
}
bool waitAUXHigh(unsigned long toMs = 2000) {
unsigned long t0 = millis();
while (millis() - t0 < toMs) {
if (digitalRead(_pinAUX) == HIGH) return true;
vTaskDelay(1);
}
return false;
}
void drainUart() {
// garante que nada esteja “pendurado” no buffer
if (_serialLoRa) {
_serialLoRa->flush(); // espera TX terminar
while (_serialLoRa->available()) _serialLoRa->read(); // limpa RX
}
}
// Define o modo do LoRa
bool setLoRaMode(LoRaMode mode) {
if (mode == currentMode) return true;
// Ajusta os pinos M0 e M1 conforme o modo desejado
switch (mode) {
case NORMAL:
digitalWrite(_pinM0, LOW);
digitalWrite(_pinM1, LOW);
break;
case WAKE_UP:
digitalWrite(_pinM0, HIGH);
digitalWrite(_pinM1, LOW);
break;
case POWER_SAVING:
digitalWrite(_pinM0, LOW);
digitalWrite(_pinM1, HIGH);
break;
case CONFIG:
digitalWrite(_pinM0, HIGH);
digitalWrite(_pinM1, HIGH);
break;
}
// 0) Garante direção dos pinos e pull-up no AUX
pinMode(_pinM0, OUTPUT);
pinMode(_pinM1, OUTPUT);
pinMode(_pinAUX, INPUT_PULLUP); // evita flutuação
MostrarLog("Modo alterado de " + String(currentMode) + " para " + String(mode));
// 1) Pausa tarefas que podem forçar TX/RX enquanto troca
pauseLoRaTasks();
currentMode = mode;
vTaskDelay(100); // Aguarda sinalização inicial de troca
// ESPERA o AUX ir para HIGH, indicando que a troca completou
unsigned long timeout = millis() + commandTimeout;
while (digitalRead(_pinAUX) == LOW) {
if (millis() > timeout) {
MostrarLog("Erro: Timeout aguardando AUX após mudança de modo.");
// 2) Aguarda o rádio estar ocioso antes de mexer em M0/M1
if (!waitAUXHigh(2000)) {
MostrarLog("Erro: AUX não ficou HIGH antes da troca de modo.");
resumeLoRaTasks();
return false;
}
// 3) Para tráfego de UART e limpa buffers
drainUart();
// 4) Comuta M0/M1
switch (mode) {
case NORMAL: digitalWrite(_pinM0, LOW); digitalWrite(_pinM1, LOW); break;
case WAKE_UP: digitalWrite(_pinM0, HIGH); digitalWrite(_pinM1, LOW); break;
case POWER_SAVING: digitalWrite(_pinM0, LOW); digitalWrite(_pinM1, HIGH); break;
case CONFIG: digitalWrite(_pinM0, HIGH); digitalWrite(_pinM1, HIGH); break;
}
vTaskDelay(100); // Manual pede 2ms após AUX ficar HIGH
// 5) Esperas mínimas do datasheet
vTaskDelay(5); // >2ms após M0/M1
// 6) Espera o módulo sinalizar pronto no novo modo
if (!waitAUXHigh(2000)) {
MostrarLog("Erro: Timeout aguardando AUX após mudança de modo.");
resumeLoRaTasks();
return false;
}
// 7) Ajustes específicos por modo
if (mode == CONFIG) {
// A UART do módulo em CONFIG é 9600 8N1 SEMPRE.
if (_serialLoRa) _serialLoRa->begin(9600, SERIAL_8N1, _pinRXD, _pinTXD);
drainUart();
}
if (mode == NORMAL) {
// voltar à baud configurada do módulo (ex.: 9600/19200/etc)
if (_serialLoRa) _serialLoRa->begin(_baudRate, SERIAL_8N1, _pinRXD, _pinTXD);
drainUart();
}
currentMode = mode;
MostrarLog("Modo alterado OK: " + String(mode));
// 8) Retoma tarefas só quando NORMAL (evita competição em CONFIG)
if (mode == NORMAL) resumeLoRaTasks();
return true;
}
@ -547,66 +614,69 @@ private:
return sucesso;
}
bool receberParametrosModulo(uint8_t _startAddr, uint8_t _dataLen) {
unsigned long startTime = millis();
bool sucesso = false;
bool readByteWithTimeout(uint8_t &out, unsigned long toMs = 500) {
unsigned long t0 = millis();
while ((millis() - t0) < toMs) {
if (_serialLoRa && _serialLoRa->available()) {
int r = _serialLoRa->read();
if (r >= 0) {
out = (uint8_t)r;
return true;
}
}
// no ESP32 tem FreeRTOS; se preferir, use vTaskDelay(1);
vTaskDelay(1);
}
return false;
}
while (!sucesso && millis() - startTime < commandTimeout) {
if (_serialLoRa->available()) {
uint8_t cabecalho = _serialLoRa->read();
if (cabecalho == CodigosFuncoes::CfgRx) { // Cabeçalho de resposta correta
MostrarLog("Cabecalho recebido corretamente.");
uint8_t startAddr = _serialLoRa->read();
uint8_t dataLen = _serialLoRa->read();
bool receberParametrosModulo(uint8_t _startAddr, uint8_t _dataLen) {
unsigned long t0 = millis();
// janela total mais folgada p/ rádio
while ((millis() - t0) < 1500UL) {
uint8_t b = 0;
if (!readByteWithTimeout(b, 500)) {
// não chegou nada ainda, segue tentando até estourar 1.5s
continue;
}
if (b == CodigosFuncoes::CfgRx) {
uint8_t startAddr = 0, dataLen = 0;
if (!readByteWithTimeout(startAddr) || !readByteWithTimeout(dataLen)) {
return false;
}
if (startAddr == _startAddr && dataLen == _dataLen) {
MostrarLog("Parâmetros recebidos corretamente.");
// Agora ler os registros
uint8_t addh = _serialLoRa->read(); // byte 0
uint8_t addl = _serialLoRa->read(); // byte 1
parametrosAtual.address = addl; // usa só o ADDL (0~255)
parametrosAtual.baudAndAirRate = _serialLoRa->read(); // byte 2
parametrosAtual.packetSizeAndPower = _serialLoRa->read(); // byte 3
parametrosAtual.channel = _serialLoRa->read(); // byte 4
parametrosAtual.tranModeAndWorCycle = _serialLoRa->read(); // byte 5
if (DebugMode) {
String log =
"Recebido Parametros do Modulo: (" + String(dataLen) + " bytes): " +
"0x" + String(startAddr, HEX) + " " +
"0x" + String(dataLen, HEX) + " " +
"0x" + String(addh, HEX) + " " +
"0x" + String(addl, HEX) + " " +
"0x" + String(parametrosAtual.baudAndAirRate, HEX) + " " +
"0x" + String(parametrosAtual.packetSizeAndPower, HEX) + " " +
"0x" + String(parametrosAtual.channel, HEX) + " " +
"0x" + String(parametrosAtual.tranModeAndWorCycle, HEX);
MostrarLog(log);
uint8_t addh=0, addl=0, bAir=0, pwr=0, ch=0, wor=0;
if (!readByteWithTimeout(addh) || !readByteWithTimeout(addl) ||
!readByteWithTimeout(bAir) || !readByteWithTimeout(pwr) ||
!readByteWithTimeout(ch) || !readByteWithTimeout(wor)) {
return false;
}
sucesso = true;
}
else {
if (DebugMode) {
String log = "Dados Corrompidos: (" + String(dataLen) + " bytes): 0x" + String(startAddr, HEX) + " 0x" + String(dataLen, HEX) + " ";
for (size_t i = 0; i < dataLen; i++) {
uint8_t c = _serialLoRa->read();
log += "0x" + String(c, HEX) + " ";
}
MostrarLog(log);
parametrosAtual.address = addl; // assumindo ADDL como address
parametrosAtual.baudAndAirRate = bAir;
parametrosAtual.packetSizeAndPower = pwr;
parametrosAtual.channel = ch;
parametrosAtual.tranModeAndWorCycle = wor;
return true;
} else {
// endereçamento diferente: drena os bytes anunciados pra limpar o stream
for (int i = 0; i < dataLen; i++) {
uint8_t dump;
if (!readByteWithTimeout(dump)) break;
}
}
} else if (cabecalho == CodigosFuncoes::WrongMode) {
MostrarLog("Modo invalido!");
} else if (b == CodigosFuncoes::WrongMode) {
// opcional: logar que o módulo respondeu “modo errado”
// e talvez sair para re-tentar setLoRaMode(CONFIG)
}
}
vTaskDelay(10);
// senão, segue laçando e coletando até bater timeout total
}
limparBufferLoRa();
return sucesso;
limparBufferLoRa(); // garantir que não fique lixo
return false;
}
void enviarDadosSerial(const uint8_t* dados, int tamanho, const String& descricao = "") {

View File

@ -65,7 +65,7 @@ void inicializarDependenciasI2C() {
}
void setup() {
delay(5000);
delay(2000);
inicializarDependenciasI2C();