Envio de String entre módulos Lora Mesh

Olá! Estou tentando realizar uma transmissão de strings entre dois módulos.
Porém não estou conseguindo enviar a string completa:

int listaEndDevices[5] = {0, 00, 0, 0, 0};

String Data = “011001ST012350022350032350042400052400062550072600082350092245102500112600122700132350142475152500FF”;

CMD_aplicacao((listaEndDevices[polingID % 5]),0x10,Data);

char CMD_aplicacao(int id, char cmd, String mensagem)
{
char id_lsb = id & 0xFF; //separando o ind em dois bytes para enviar no pacote; &0xFF pega somente os 8 bits menos significativos
char id_msb = (id >> 8) & 0xFF; //bitwise desloca os 8 bits mais signficativos e pega somente a parte msb do int
char comando = cmd; // comando referente a GPIO
int tamanho = mensagem.length() + 1; //inclui o fim de string 0x00
char payload[tamanho];
mensagem.toCharArray(payload, tamanho);
char pacote[tamanho + 5]; // 03 bytes do cabeçalho (id_lsb, id_msb e comando) e 2 bytes do crc
pacote[0] = id_lsb;
pacote[1] = id_msb;
pacote[2] = cmd;
int count = 0;
for (count = 3; count < (tamanho + 3); count++)
{
pacote[count] = payload[count - 3];
}
int crc = CalculaCRC(pacote, tamanho + 3);
pacote[tamanho + 3] = crc & 0xFF;
pacote[tamanho + 4] = ((crc >> 8) & 0xFF);
radio_master_serial_cmd.write(pacote, tamanho + 5);
Serial.print(“Envio string para o ID: “);//somente para aparecer no monitor serial do Arduino
Serial.print(id);
Serial.println(” — — —”);
return (1);
}

Na parte do receptor/mestre, não chega nem a receber o payload

A configuração de BW (largura de banda ocupada) , o fator de espalhamento SF e a relação bytes corretor de erros /bytes transmitidos C/R influenciam no tamanho máximo do payload. Então … faça alguns testes: Aumente a BW e diminua o SF … depois tente transmitir novamente.

Importante: Quanto maior o SF maior o tempo que o pacote leva para ser transmitido … maior será o tempo que se deve aguardar para fazer uma nova transmissão. Existem algumas ferramentas online para cálculo do airtime.

Quanto menor o SF e maior a BW … menor será o alcance. Então, para se ter o maior alcance pode ser necessário comprimir o payload (para poder usar o maior SF e menor BW) usando, por exemplo máscara de bits. Ser for um json… transmitir apenas os valores separados por vírgula …

Eu fiz isso mas ainda continua o mesmo problema.
Até diminuir o tamanho dos dados que quero enviar:
“011001ST012350022350032350042400052400”;

O mestre recebe apenas:
011001ST0123⸮

No tratamento tenho feito essas etapas:

char LerSerial()
{
indice = 0;
while (Serial2.available() > 0) // Don’t read unless// there you know there is data
{
if (indice < 254) // One less than the size of the array
{

   inChar = Serial2.read(); // Read a character
   inData[indice] = inChar; // Store it
   delay (10);
   indice++; // Increment where to write next
   inData[indice] = '\0'; // Null terminate the string
  // resp_LMH = "";
}

}

if (indice > 0)
{
return (1); //retorno da função avisando que recebeu dados na serial
}
else
{
return (0);
}

}

char TrataRX(byte indice) //IMPORATANTE: O terceiro byte [2] é sempre o comando… sabendo o comando sabemos como tratar o restante do pacote
{
//String pay = String(inData);
//Serial.println(inData);

for (int i = 4; i<=50;i++)
{
resp_LMH +=inData[i];
//Serial.print(inData[i]);
}
resp_LMH = resp_LMH.substring(1,255); //define o tamanho dos dados
Serial.println(resp_LMH); //mostra no console serial
}

sugestões:

Verifique se o int tamanho = mensagem.length() + 1; //inclui o fim de string 0x00 pegou o valor correto;

se o valor do char payload[tamanho]; / tamanho + 5 é menor que 255 (valor máximo para a variável do tipo byte);

faça um print do char pacote[]… para ver se o conteúdo está correto.

Exemplo de um pacote maior para enviar:
FE 00 10 30 31 31 30 30 31 53 54 30 31 32 33 35 30 30 32 32 33 35 30 30 33 32 33 35 30 30 34 32 34 30 30 30 35 32 34 30 30 30 36 32 35 35 30 30 37 32 36 30 30 30 38 32 33 35 30 30 39 32 32 34 35 31 30 52 07

http://download.radioenge.com.br/iot/SW_LoRaMESH_6R12.zip
com este sw é possível gerar os comandos para envio de string até 64 bytes.

Qual microcontrolador você está utilizando na IDE do arduino? Pode ser que seu buffer serial seja muito pequeno para a mensagem.

Estou usando um bluepill com um rádio 0 e um arduino nano com um rádio 3.
Ambos estão com buffer serial de 9600.
Até um payload de tamanho 33 eu consigo enviar. Depois disso não consigo mais captar um sinal.
Fiz as configurações que @fabio tinha recomendado mas nenhuma resposta clara até então.
Estou usando as interfaces transparentes em ambos os lados. Pela informação da documentação, era pra ter tido a captura total sem problemas

Sobre o buffer… que o martin230896 citou… é o inData[indice]… Qual o tamanho dele?

Para testar o rádio em si ( e eliminar um problema no HW) … pode usar esse código para ArduinoUno… que conecta a serial do módulo MESH com a serial de console… Aí pode-se conectar o sw de configuração do rádio mesh na serial de console do Arduino e fazer configurações e testes.
Código para Arduino ponte entre seriais Console e Serial rádio mesh:
http://download.radioenge.com.br/iot/SW_LoRaMESH_latest.zip
SW de configuração do rádio mesh:
http://download.radioenge.com.br/iot/SW_LoRaMESH_6R12.zip

O tamanho do inData[indice] não consigo capturar quando tento o payload completo.
É como se ambos os rádios estivessem em loop de enviar e receber.
Tentei utilizar o programa mas ocorre a mesma coisa, o que é estranho.
Existe algum código pré-pronto para arduino de envio de payloads entre rádios conectados com arduino ou outro controlador?

Existe algum código em arduino ou esp32/8266 funcional com envio de string entre os rádios com controlador?

Hoje eu fiz umas configurações nos dois rádios, ficou desta forma:
6ad7cd2c-4afb-4a8f-9381-95f763c62325

E usando o SW, fiz um teste de envio de mensagem.
Eu sei que o slave (DISP 3) está enviando este pacote toda vez que o mestre (DISP 0) manda qualquer string no comando 0x10:
01100173740123500223500323500424000524000625500726000823500922451025001126001227001323501424751525006666
Porém, no SW estou recebendo isso:

003 000 004 213 179 231 142 156 012 238 012 134 140 231 140 140 140 012 140 012 204 028 132 227 076 140 012 012 197 227 012 140 138 227 158 092 138 132 030 172

E no controlador " "

Consegui fazer o envio, e a solução foi a seguinte:
Mudei o BW para 125Khz ,SF=7 e CR =4/8;

Baudrate em ambos os rádios configurados em 9600, em Classe C com tempo de 5s.

Como que enviar o payload completo não estava sendo possível devido a perda da integridade dos dados (o dado que era enviado não era o mesmo recebido com caracteres misturados e posições diferentes), a solução foi dividir em pacotes de 40 e 60 bytes.

O comando de envio aplicado foi o 0x10.
Porém, ainda não entendi com clareza da diferença indicado no datasheet onde indica que é possível enviar um payload de 232 bytes. E o payload de 104 bytes só foi possível ser enviado em dois pacotes.
Qual foi a configuração que serviu de base para que seja possível testar a informação de capacidade de envio de 232 bytes no payload?

SF = SF7 e BW=500KHz

Estou aplicando essa configuração mas mesmo assim não consegui enviar o payload acima de 200 bytes usando o comando 0x10

O módulo configurado com SF7 e 500KHz de BW permite o envio de até 232 bytes em um único pacote e com os bytes sendo entregues espaçados com menos de 20ms.

Veja se consegue transmitir o pacote todo de uma única vez e não byte a byte.
exemplo:
-> char pacote[]={id_lsb, id_msb, comando,0x00, 0x00, 0x00, 0x00,0x00};
-> SWSerial.write(pacote,8);

Também considere compactar a mensagem porque a técnica LoRa tem melhor desempenho com pacotes menores (pode-se usar um SF maior e uma BW menor … que permitirá um maior alcance). Quanto menor a mensagem; Menor será o tempo “Air time”. Assim, será possível enviar mais mensagens e ter mais rádios na mesma rede.

Eu tenho feito isso, utilizando essa função.

char CMD_aplicacao(int id, char cmd, String mensagem)
{
  char id_lsb = id & 0xFF; //separando o ind em dois bytes para enviar no pacote; &0xFF pega somente os 8 bits menos significativos
  char id_msb = (id >> 8) & 0xFF; //bitwise desloca os 8 bits mais signficativos e pega somente a parte msb do int
  char comando = cmd; // comando referente a GPIO
  int tamanho = mensagem.length() + 1; //inclui o fim de string 0x00
  Serial.println(tamanho);
  char payload[tamanho];
  mensagem.toCharArray(payload, tamanho);
  char pacote[tamanho + 5]; // 03 bytes do cabeçalho (id_lsb, id_msb e comando) e 2 bytes do crc
  pacote[0] = id_lsb;
  pacote[1] = id_msb;
  pacote[2] = cmd;
  int count = 0;
  for (count = 3; count < (tamanho + 3); count++)
  {
    pacote[count] = payload[count - 3];
  }
  int crc = CalculaCRC(pacote, tamanho + 3);
  pacote[tamanho + 3] = crc & 0xFF;
  pacote[tamanho + 4] = ((crc >> 8) & 0xFF);
  Serial.println(mensagem);
  for(int i =0; i<=tamanho+5;i++)
  {
    Serial.print(pacote[i]);
  }
  Serial.println();
  //Serial.println();
  Serial2.write(pacote, tamanho + 5);
  Serial.print("Envio string para o ID: ");//somente para aparecer no monitor serial do Arduino
  Serial.print(id);
  Serial.println(" — — —");
  return (1);
}

Esse função está presente em um exemplo de aplicação com loramesh tendo o esp32.
Estou usando as configurações SF7, 500KHz de BW, CR = 4.
Mas mesmo assim não tenho recebido todo o pacote.

O slave envia isso:
0173740126000226000326000426000526000626000726000825500925501025501125501225501325501425501525001625501725501825501925002025009999

Mas o mestre recebe isso apenas, e com os primeiros dados embaralhados:
01737036075015 01225501325501425501525001625501725501825501925002025009999

A função que o slave manda é a mesma do mestre, sem mudar nada, nem o comando e com as mesmas configurações do rádio

Uma questão, você está inicializando o array pacote com uma variável (tamanho). Não pode ser esse o problema.
Porque em C esse tipo de definição não é possível.

Problema solucionado, obrigado mesmo pelo apoio e suporte!

char LerSerial()
{
  indice = 0;
  while (Serial2.available()>0)
  {
    
    if (indice < 254) // One less than the size of the array
    {
        inChar = Serial2.read(); // Read a character
        inData[indice] = inChar; // Store it
        delay (2); <- Altere o tempo de delay aqui
        indice++; // Increment where to write next
        inData[indice] = '\0'; // Null terminate the strin
        Serial.print(inChar);
    }
     
   }

Quando não for usar interrupção, é diminuir o valor do delay entre a recepção via serial. Dependendo da situação, precisa passar por um ajuste fino.