LoRaMESH + ESP8266 + Conversor RS232-TTL (max3232)

Olá a todos!

  • Tenho dois equipamentos se comunicando via RS232 (não sei o que cada um está escrevendo).

  • O projeto consiste em utilizar 1 ESP8266 + 1 módulo Loramesh + Conversor RS232 em cada equipamento.

  • Ou seja, a ideia é fazer com que ambos equipamentos troquem os pacotes via rádio e escrevam na sua respectiva serial, mantendo o funcionamento como se estivessem ligados pelo cabo serial, só que o módulo LoraMesh fazendo essa ponte.

Dados seriais: tamanho pacote: 32 bytes, Baudrate: 9600bps, Data bits: 8, Stop bits: 1, Paridade: nenhum.

Perguntas: Como posso tratar esses dados lidos para enviar pelo loramesh, sendo que não sei o que estou lendo?

Obs. Estou usando o código do fabiorausis como referência. Mas notei que lá é mostrado como enviar uma String fixa “Radioenge_payload+_LoRaMESH”. Acredito que preciso formar minha própria string lendo a serial antes de enviar pro lora, mas não estou sabendo onde e como fazer isso, se é no LerSerial( ), TrataRX() ou CMD_aplicacao().

Cheguei até esse código abaixo, por enquanto:

#include <Ticker.h>
#include<SoftwareSerial.h>
SoftwareSerial SWSerial(4, 5); //D2, D1 : Será usada a serial por software para deixar livre a serial do monitor serial

int count = 0;
char inData[255]; // Buffer com tamanho suficiente para receber qualquer mensagem
char inChar=-1; // char para receber um caractere lido
byte indice = 0; // índice para percorrer o vetor de char = Buffer
int listaEndDevices[1] = {1}; //pretendo incluir mais
//int polingID=0;//usado para escolher qual ID do vetor acima será usado.
char flag= false;
//char comandos = 0;//usado para escolher qual comando enviar.
//==============================================================
void ICACHE_RAM_ATTR onTimerISR(){
digitalWrite(LED_BUILTIN,!(digitalRead(LED_BUILTIN))); //Toggle LED Pin
timer1_write(600000);//12us
count++;
}
//==============================================================

// ===================== protótipos das funções ======================
char lerSerial();
char TrataRX(byte indice);
uint16_t CalculaCRC(char* data_in, uint32_t length);
char CMD_aplicacao(int id, char cmd, String mensagem);
//==============================================================

void setup() {
Serial.begin(9600);
SWSerial.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
//Initialize Ticker every 0.5s
timer1_attachInterrupt(onTimerISR);
timer1_enable(TIM_DIV16, TIM_EDGE, TIM_SINGLE);
timer1_write(600000); //120 ms altera o tempo do timer para 120ms
}

void loop() {
if(count % 50 == 0)// = 6seg
{
count++;
String s_msg=“Radioenge_payload+_LoRaMESH”;
char c_cmd_app = 0x10; // qualquer valor de comando acima de 0x0B e menor que 0x7F (12 a 127 decimal)

CMD_aplicacao(listaEndDevices[polingID%1], c_cmd_app, s_msg);

}
flag = LerSerial();
if (flag)
{
TrataRX(indice);
}
}

//====================== Verifica Serial D1(tx) e D2(rx) ===================
char LerSerial( )
{
indice=0;
while (SWSerial.available() > 0)
{
if(indice < 254)
{
inChar = SWSerial.read(); // leio um caracter
inData[indice] = inChar; // armazeno ele
delay (2);
indice++; // incremento prox. indice para receber o novo caracter a ser armazenado no inData.
inData[indice] = ‘\0’; // encerra a sequencia de chars, formando uma string armazenada no inData.
}
}
if(indice>0)
{
return(1);
}
else
{
return (0);
}
}
//================== tratamento do que recebeu na serial============

char TrataRX(byte indice)
{
Serial.println(inData);
if(indice>5) //verifica se recebeu uma reposta de comando maior que 5 bytes para não ler dados inválidos
{
int id=inData[0]+inData[1]*256;

    if(inData[2] == 0xC2 )//resposta de comando na GPIO
    {
      if(inData[4] == 0x00 && inData[3] == 0x00) 

.
??
. .
}
}
}

//===================cálculo do CRC16==================
#define CRC_POLY (0xA001)
uint16_t CalculaCRC(char* data_in, uint32_t length)
{
uint32_t i;
uint8_t bitbang, j;
uint16_t crc_calc;
crc_calc = 0xC181;
for(i=0; i<length; i++)
{
crc_calc ^= ((uint16_t)data_in[i]) & 0x00FF;
for(j=0; j<8; j++)
{
bitbang = crc_calc;
crc_calc >>= 1;
if(bitbang & 1)
{
crc_calc ^= CRC_POLY;
}
}
}
return crc_calc;
}
//====================================================================

//====================== Comando de Aplicação = Envio de string =============
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);
SWSerial.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);
}

De antemão, agradeço a todos!

Acredito que o conversor USART-RS232 deva ser conectado na serial nativa do ESP8266 (a mesma que é usada no console GPIO03 e GPIO01) e… teria que fazer uma nova função para receber da serial console (LerSerial para a serial console). No final dessa nova função chamar CMD_aplicacao… encaminhando o que recebeu na serial nativa para a serialSW que estaria conectada no módulo LoRa.
obs.: Não será possível usar o console porque a serial já vai estar conectada no seu conversor RS232.
obs.2: O módulo opera com transmissões de pacotes (mensagens com intervalos entre novas mensagens). Não é viável para sistemas IOT o envio contínuo de dados.