Índice:
- Suprimentos
- Etapa 1: Biblioteca
- Etapa 2: Pinagem
- Etapa 3: Pin AUX
- Etapa 4: Esquema totalmente conectado Esp8266
- Etapa 5: Esquema Arduino totalmente conectado
- Etapa 6: Biblioteca: Construtor
- Etapa 7: começar
- Etapa 8: Configuração e Método de Informação
- Etapa 9: recipiente de resposta
- Etapa 10: opção de configuração básica
- Etapa 11: enviar receber mensagem
- Etapa 12: Modo de transmissão normal
- Etapa 13: Gerenciar Estrutura
- Etapa 14: modo fixo em vez do modo normal
- Etapa 15: Obrigado
Vídeo: Comunicação sem fio LoRa de 3 km a 8 km com dispositivo E32 (sx1278 / sx1276) de baixo custo para Arduino, Esp8266 ou Esp32: 15 etapas
2024 Autor: John Day | [email protected]. Última modificação: 2024-01-30 11:35
Eu crio uma biblioteca para gerenciar EBYTE E32 baseada na série Semtech de dispositivo LoRa, dispositivo muito poderoso, simples e barato.
Você pode encontrar a versão de 3Km aqui, a versão de 8Km aqui
Eles podem trabalhar a uma distância de 3.000m a 8.000m e têm muitos recursos e parâmetros. Então, eu crio esta biblioteca para simplificar o uso.
É uma solução para recuperar dados de sensores metropolitanos ou para controlar drones.
Suprimentos
Arduino UNO
Wemos D1 mini
LoRa E32 TTL 100 versão de 3 km
Versão LoRa E32 TTL 1W 8Km
Etapa 1: Biblioteca
Você pode encontrar minha biblioteca aqui.
Baixar.
Clique no botão DOWNLOADS no canto superior direito, renomeie a pasta descompactada LoRa_E32.
Verifique se a pasta LoRa_E32 contém LoRa_E32.cpp e LoRa_E32.h.
Coloque a pasta de biblioteca LoRa_E32 em sua pasta / libraries /. Você pode precisar criar a subpasta de bibliotecas se for sua primeira biblioteca.
Reinicie o IDE.
Etapa 2: Pinagem
Como você pode ver, você pode definir vários modos por meio dos pinos M0 e M1.
Existem alguns pinos que podem ser usados de forma estática, mas se você conectá-lo ao microcontrolador e configurá-los na biblioteca você ganha em desempenho e pode controlar todos os modos via software, mas explicaremos melhor a seguir.
Etapa 3: Pin AUX
Como eu já disse, não é importante conectar todos os pinos na saída do microcontrolador, você pode colocar os pinos M0 e M1 em HIGH ou LOW para obter a configuração desejada, e se você não conectar AUX a biblioteca definir um atraso razoável para ter certeza que a operação foi concluída.
Pino AUX
Ao transmitir dados, pode ser usado para despertar o MCU externo e retornar ALTO no término da transferência de dados.
Ao receber AUX indo para BAIXO e retornando ALTO quando o buffer está vazio.
Também é usado para autoverificação para restaurar a operação normal (na inicialização e modo de suspensão / programa).
Etapa 4: Esquema totalmente conectado Esp8266
O esquema de conexão esp8266 é mais simples porque funciona na mesma voltagem das comunicações lógicas (3.3v).
É importante adicionar um resistor pull-up (4, 7Kohm) para obter uma boa estabilidade.
Etapa 5: Esquema Arduino totalmente conectado
A tensão de trabalho do Arduino é 5v, então precisamos adicionar um divisor de tensão no pino RX M0 e M1 do módulo LoRa para evitar danos, você pode obter mais informações aqui Divisor de tensão: calculadora e aplicativo.
Você pode usar um resistor de 2Kohm para GND e 1Kohm de sinal do que colocar juntos em RX.
Etapa 6: Biblioteca: Construtor
Fiz um conjunto de construtores bastante numerosos, porque podemos ter mais opções e situações para gerir.
LoRa_E32 (byte rxPin, byte txPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
LoRa_E32 (byte rxPin, byte txPin, byte auxPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600); LoRa_E32 (byte rxPin, byte txPin, byte auxPin, byte m0Pin, byte m1Pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
O primeiro conjunto de construtores é criado para delegar o gerenciamento de pinos seriais e outros à biblioteca.
rxPin e txPin é o pino para conectar ao UART e eles são obrigatórios.
auxPin é um pino que verifica o estado de operação, transmissão e recebimento (explicaremos melhor a seguir), esse pino não é obrigatório, se você não configurá-lo, aplico um retardo para permitir que a operação se complete (com latência).
m0pin e m1Pin são os pinos para mudar o MODO de operação (veja a tabela acima), eu acho que esses pinos em “produção” vão se conectar diretamente ALTO ou BAIXO, mas para teste eles são úteis para serem gerenciados pela biblioteca.
bpsRate é a taxa de transmissão de SoftwareSerial normalmente é 9600 (a única taxa de transmissão no modo programmin / sleep)
Um exemplo simples é
#include "LoRa_E32.h" LoRa_E32 e32ttl100 (2, 3); // RX, TX // LoRa_E32 e32ttl100 (2, 3, 5, 6, 7); // RX, TX
Podemos usar diretamente um SoftwareSerial com outro construtor
LoRa_E32 (HardwareSerial * serial, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
LoRa_E32 (HardwareSerial * serial, byte auxPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
LoRa_E32 (HardwareSerial * serial, byte auxPin, byte m0Pin, byte m1Pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
O exemplo superior com este construtor pode ser feito assim.
#include #include "LoRa_E32.h"
SoftwareSerial mySerial (2, 3); // RX, TX
LoRa_E32 e32ttl100 (& mySerial);
// LoRa_E32 e32ttl100 (& mySerial, 5, 7, 6);
O último conjunto de construtor é permitir o uso de HardwareSerial em vez de SoftwareSerial.
LoRa_E32 (SoftwareSerial * serial, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
LoRa_E32 (SoftwareSerial * serial, byte auxPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
LoRa_E32 (SoftwareSerial * serial, byte auxPin, byte m0Pin, byte m1Pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
Etapa 7: começar
O comando begin é usado para inicializar serial e pinos no modo de entrada e saída.
void begin ();
em execução está
// Iniciar todos os pinos e UART
e32ttl100.begin ();
Etapa 8: Configuração e Método de Informação
Existe um conjunto de métodos para gerenciar a configuração e obter informações do dispositivo.
ResponseStructContainer getConfiguration ();
ResponseStatus setConfiguration (configuração de configuração, PROGRAM_COMMAND saveType = WRITE_CFG_PWR_DWN_LOSE);
ResponseStructContainer getModuleInformation ();
void printParameters (configuração da configuração da estrutura);
ResponseStatus resetModule ();
Etapa 9: recipiente de resposta
Para simplificar o gerenciamento de resposta eu crio um conjunto de container, para mim muito útil para gerenciar erros e retornar dados genéricos.
ResponseStatus
Este é um contêiner de status e tem 2 pontos de entrada simples, com isso você pode obter o código de status e a descrição do código de status
Serial.println (c.getResponseDescription ()); // Descrição do código
Serial.println (c.code); // 1 se tiver sucesso
O código é
SUCESSO = 1, ERR_UNKNOWN, ERR_NOT_SUPPORT, ERR_NOT_IMPLEMENT, ERR_NOT_INITIAL, ERR_INVALID_PARAM, ERR_DATA_SIZE_NOT_MATCH, ERR_BUF_TOO_SMALL, ERR_TIMEOUT, ERR_HARDWARE, ERR_HEAD_NOT_RECOGNIZED
ResponseContainer
Este contêiner é criado para gerenciar a resposta da String e tem 2 pontos de entrada.
dados com a string retornada da mensagem e status uma instância de RepsonseStatus.
ResponseContainer rs = e32ttl.receiveMessage ();
String message = rs.data;
Serial.println (rs.status.getResponseDescription ());
Serial.println (mensagem);
ResponseStructContainer
Este é o contêiner mais “complexo”, eu o uso para gerenciar a estrutura. Ele tem o mesmo ponto de entrada do ResponseContainer, mas os dados são um ponteiro vazio para gerenciar a estrutura complexa.
ResponseStructContainer c;
c = e32ttl100.getConfiguration (); // É importante obter o ponteiro de configuração antes de todas as outras operações
Configuração de configuração = * (Configuração *) c.data;
Serial.println (c.status.getResponseDescription ());
Serial.println (c.status.code);
getConfiguration e setConfiguration
O primeiro método é getConfiguration, você pode usá-lo para recuperar todos os dados armazenados no dispositivo.
ResponseStructContainer getConfiguration ();
Aqui está um exemplo de uso.
ResponseStructContainer c;
c = e32ttl100.getConfiguration (); // É importante obter o ponteiro de configuração antes de todas as outras operações
Configuração de configuração = * (Configuração *) c.data;
Serial.println (c.status.getResponseDescription ());
Serial.println (c.status.code);
Serial.println (configuration. SPED.getUARTBaudRate ());
Estrutura de configuração tem todos os dados de configurações, e eu adiciono uma série de funções para obter todas as descrições de dados individuais.
configuração. ADDL = 0x0; // Primeira parte de addressconfiguration. ADDH = 0x1; // Segunda parte da configuração do endereço. CHAN = 0x19; // Configuração do canal. OPTION.fec = FEC_0_OFF; // Configuração da chave de correção de erro de encaminhamento. OPTION.fixedTransmission = FT_TRANSPARENT_TRANSMISSION; // Configuração do modo de transmissão. OPTION.ioDriveMode = IO_D_MODE_PUSH_PULLS_PULL_UPS; // Configuração de gerenciamento de pull-up. OPTION.transmissionPower = POWER_17; // configuração da potência de transmissão dBm. OPTION.wirelessWakeupTime = WAKE_UP_1250; // Tempo de espera para configuração de ativação. SPED.airDataRate = AIR_DATA_RATE_011_48; // Air data rate configuration. SPED.uartBaudRate = UART_BPS_115200; // Configuração da taxa de transmissão de comunicação. SPED.uartParity = MODE_00_8N1; // bit de paridade
Você tem a função equivalente para todos os atributos para obter todas as descrições:
Serial.print (F ("Chan:")); Serial.print (configuração. CHAN, DEC); Serial.print ("->"); Serial.println (configuration.getChannelDescription ()); Serial.println (F ("")); Serial.print (F ("SpeedParityBit:")); Serial.print (configuração. SPED.uartParity, BIN); Serial.print ("->"); Serial.println (configuration. SPED.getUARTParityDescription ()); Serial.print (F ("SpeedUARTDatte:")); Serial.print (configuração. SPED.uartBaudRate, BIN); Serial.print ("->"); Serial.println (configuration. SPED.getUARTBaudRate ()); Serial.print (F ("SpeedAirDataRate:")); Serial.print (configuração. SPED.airDataRate, BIN); Serial.print ("->"); Serial.println (configuration. SPED.getAirDataRate ()); Serial.print (F ("OptionTrans:")); Serial.print (configuração. OPÇÃO.fixedTransmission, BIN); Serial.print ("->"); Serial.println (configuration. OPTION.getFixedTransmissionDescription ()); Serial.print (F ("OptionPullup:")); Serial.print (configuração. OPÇÃO.ioDriveMode, BIN); Serial.print ("->"); Serial.println (configuration. OPTION.getIODroveModeDescription ()); Serial.print (F ("OptionWakeup:")); Serial.print (configuração. OPÇÃO.wirelessWakeupTime, BIN); Serial.print ("->"); Serial.println (configuration. OPTION.getWirelessWakeUPTimeDescription ()); Serial.print (F ("OptionFEC:")); Serial.print (configuração. OPÇÃO.fec, BIN); Serial.print ("->"); Serial.println (configuration. OPTION.getFECDescription ()); Serial.print (F ("OptionPower:")); Serial.print (configuração. OPÇÃO.transmissionPower, BIN); Serial.print ("->"); Serial.println (configuration. OPTION.getTransmissionPowerDescription ());
Da mesma forma, setConfiguration deseja uma estrutura de configuração, então acho que a melhor maneira de gerenciar a configuração é recuperar a atual, aplicar a única alteração necessária e defini-la novamente.
ResponseStatus setConfiguration (configuração de configuração, PROGRAM_COMMAND saveType = WRITE_CFG_PWR_DWN_LOSE);
configuração é a estrutura anterior mostrada, saveType permite que você escolha se a mudança se torna permanente apenas para a sessão atual.
ResponseStructContainer c; c = e32ttl100.getConfiguration (); // É importante obter o ponteiro de configuração antes de todas as outras operações Configuration configuration = * (Configuration *) c.data; Serial.println (c.status.getResponseDescription ()); Serial.println (c.status.code); printParameters (configuração); configuração. ADDL = 0x0; configuração. ADDH = 0x1; configuração. CHAN = 0x19; configuração. OPÇÃO.fec = FEC_0_OFF; configuration. OPTION.fixedTransmission = FT_TRANSPARENT_TRANSMISSION; configuration. OPTION.ioDriveMode = IO_D_MODE_PUSH_PULLS_PULL_UPS; configuration. OPTION.transmissionPower = POWER_17; configuration. OPTION.wirelessWakeupTime = WAKE_UP_1250; configuration. SPED.airDataRate = AIR_DATA_RATE_011_48; configuração. SPED.uartBaudRate = UART_BPS_115200; configuração. SPED.uartParity = MODE_00_8N1; // Definir configuração alterada e definir para não manter a configuração ResponseStatus rs = e32ttl100.setConfiguration (configuração, WRITE_CFG_PWR_DWN_LOSE); Serial.println (rs.getResponseDescription ()); Serial.println (rs.code); printParameters (configuração);
Os parâmetros são todos gerenciados como constantes:
Etapa 10: opção de configuração básica
Etapa 11: enviar receber mensagem
Primeiro, devemos apresentar um método simples, mas útil para verificar se algo está no buffer de recebimento
disponível int ();
É simplesmente retornar quantos bytes você tem no stream atual.
Etapa 12: Modo de transmissão normal
O modo de transmissão normal / transparente é usado para enviar mensagens a todos os dispositivos com o mesmo endereço e canal.
Existem vários métodos para enviar / receber mensagens, vamos explicar em detalhes:
ResponseStatus sendMessage (const String mensagem);
ResponseContainer receiveMessage ();
O primeiro método é sendMessage e é usado para enviar uma String a um dispositivo no modo normal.
ResponseStatus rs = e32ttl.sendMessage ("Prova"); Serial.println (rs.getResponseDescription ());
O outro dispositivo simplesmente faz no loop
if (e32ttl.available ()> 1) {ResponseContainer rs = e32ttl.receiveMessage (); String message = rs.data; // Obtenha primeiro os dados Serial.println (rs.status.getResponseDescription ()); Serial.println (mensagem); }
Etapa 13: Gerenciar Estrutura
Se você quiser enviar uma estrutura complexa, você pode usar este método
ResponseStatus sendMessage (const void * message, const uint8_t size); ResponseStructContainer receiveMessage (const uint8_t size);
É usado para enviar estrutura, por exemplo:
struct Messagione {tipo de caractere [5]; mensagem char [8]; bool mitico; }; struct Messaggione messaggione = {"TEMP", "Peple", true}; ResponseStatus rs = e32ttl.sendMessage (& messaggione, sizeof (Messaggione)); Serial.println (rs.getResponseDescription ());
e do outro lado você pode receber a mensagem para
ResponseStructContainer rsc = e32ttl.receiveMessage (sizeof (Messaggione)); struct Messaggione messaggione = * (Messaggione *) rsc.data; Serial.println (messaggione.message); Serial.println (messaggione.mitico);
Leia a estrutura parcial
Se você quiser ler a primeira parte da mensagem para gerenciar mais tipos de estrutura, pode usar este método.
ResponseContainer receiveInitialMessage (const uint8_t size);
Eu crio para receber um string com tipo ou outro para identificar a estrutura a carregar.
struct Messaggione {// estrutura parcial sem mensagem de tipo de letra [8]; bool mitico; }; tipo char [5]; // primeira parte da estrutura ResponseContainer rs = e32ttl.receiveInitialMessage (sizeof (type)); // Coloca string em um array de char (não necessário) memcpy (type, rs.data.c_str (), sizeof (type)); Serial.println ("TIPO DE LEITURA:"); Serial.println (rs.status.getResponseDescription ()); Serial.println (tipo); // Lê o resto da estrutura ResponseStructContainer rsc = e32ttl.receiveMessage (sizeof (Messaggione)); struct Messaggione messaggione = * (Messaggione *) rsc.data;
Etapa 14: modo fixo em vez do modo normal
Da mesma maneira, crio um conjunto de métodos para usar com transmissão fixa
Transmissão fixa
Você precisa alterar apenas o método de envio, pois o dispositivo de destino não recebe o preâmbulo com Endereço e Canal quando define o modo fixo.
Então, para mensagem String você tem
ResponseStatus sendFixedMessage (byte ADDL, byte ADDH, byte CHAN, const String mensagem); ResponseStatus sendBroadcastFixedMessage (byte CHAN, const String mensagem);
e para estrutura você tem
ResponseStatus sendFixedMessage (byte ADDL, byte ADDH, byte CHAN, const void * mensagem, const uint8_t size); ResponseStatus sendBroadcastFixedMessage (byte CHAN, const void * mensagem, const uint8_t tamanho);
Aqui está um exemplo simples
ResponseStatus rs = e32ttl.sendFixedMessage (0, 0, 0x17, & messaggione, sizeof (Messaggione)); // ResponseStatus rs = e32ttl.sendFixedMessage (0, 0, 0x17, "Ciao");
A transmissão fixa tem mais cenários
Se você enviar para um dispositivo específico (segundos cenários de transmissão fixa), você deve adicionar ADDL, ADDH e CHAN para identificá-lo diretamente.
ResponseStatus rs = e32ttl.sendFixedMessage (2, 2, 0x17, "Mensagem para um dispositivo");
Se você quiser enviar uma mensagem para todos os dispositivos em um canal especificado, você pode usar este método.
ResponseStatus rs = e32ttl.sendBroadcastFixedMessage (0x17, "Mensagem para dispositivos de um canal");
Se você deseja receber todas as mensagens de transmissão na rede, você deve definir seu ADDH e ADDL com BROADCAST_ADDRESS.
ResponseStructContainer c; c = e32ttl100.getConfiguration (); // É importante obter o ponteiro de configuração antes de todas as outras operações Configuration configuration = * (Configuration *) c.data; Serial.println (c.status.getResponseDescription ()); Serial.println (c.status.code); printParameters (configuração); configuração. ADDL = BROADCAST_ADDRESS; configuração. ADDH = BROADCAST_ADDRESS; // Definir configuração alterada e definir para não manter a configuração ResponseStatus rs = e32ttl100.setConfiguration (configuração, WRITE_CFG_PWR_DWN_LOSE); Serial.println (rs.getResponseDescription ()); Serial.println (rs.code); printParameters (configuração);
Etapa 15: Obrigado
Agora você tem todas as informações para fazer seu trabalho, mas acho importante mostrar alguns exemplos realistas para entender e melhor todas as possibilidades.
- Dispositivo LoRa E32 para Arduino, esp32 ou esp8266: configurações e uso básico
- Dispositivo LoRa E32 para Arduino, esp32 ou esp8266: biblioteca
- Dispositivo LoRa E32 para Arduino, esp32 ou esp8266: configuração
- Dispositivo LoRa E32 para Arduino, esp32 ou esp8266: transmissão fixa
- Dispositivo LoRa E32 para Arduino, esp32 ou esp8266: economia de energia e envio de dados estruturados
Recomendado:
Holofote UV de baixo custo DIY para colagem sem adesivo de chips microfluídicos de PMMA: 11 etapas
Holofote UV de baixo custo DIY para colagem sem adesivo de chips microfluídicos de PMMA: Dispositivos microfluídicos fabricados em termoplásticos estão cada vez mais sendo usados devido à rigidez, transparência, permeabilidade de gás reduzida, biocompatibilidade e tradução mais fácil para métodos de produção em massa, como moldagem por injeção. Métodos de colagem para
Rede de sensores sem fio de baixo custo na banda de 433 MHz: 5 etapas (com imagens)
Rede de sensores sem fio de baixo custo na banda de 433 MHz: Muito obrigado a Teresa Rajba por gentilmente me dar sua aceitação em usar os dados de suas publicações neste artigo. * Na imagem acima - as cinco unidades de sensor remetente que usei para testar o que são sensores sem fio redes? Uma definição simples seria
Como medir corretamente o consumo de energia dos módulos de comunicação sem fio na era do baixo consumo de energia ?: 6 etapas
Como medir corretamente o consumo de energia dos módulos de comunicação sem fio na era do baixo consumo de energia ?: O baixo consumo de energia é um conceito extremamente importante na Internet das coisas. A maioria dos nós de IoT precisa ser alimentada por baterias. Somente medindo corretamente o consumo de energia do módulo sem fio podemos estimar com precisão a quantidade de bateria i
Faça você mesmo de microfone sem fio para sistema de guitarra sem fio: 4 etapas
Faça você mesmo de microfone sem fio para sistema de guitarra sem fio: Tenho assistido a alguns vídeos e bandas e quase todas usam um sistema sem fio na guitarra. Enlouquecer, mover-se, caminhar e fazer o que quiserem sem o cabo, então sonho em ter um .. Mas .. para mim agora é muito caro então eu vim para isso
Resfriador / suporte de laptop de custo zero (sem cola, sem perfuração, sem porcas e parafusos, sem parafusos): 3 etapas
Resfriador / suporte para laptop de custo zero (sem cola, sem furação, sem porcas e parafusos, sem parafusos): ATUALIZAÇÃO: ATUALIZAÇÃO ESPECIALMENTE VOTE MEU INSTRUTÁVEL, OBRIGADO ^ _ ^ VOCÊ TAMBÉM PODE GOSTAR DE VOTO EM MEU OUTRO CONCURSO INSCREVA-SE EM www.instructables.com/id/Zero-Cost-Aluminum-Furnace-No-Propane-No-Glue-/ OU TALVEZ VOTE NO MEU MELHOR AMIGO