Bastante útil por depurar e
testar o seu programa, em função do display que já o acompanha, hoje vamos
tratar novamente do ESP32 LoRa, desta vez em um projeto utilizando o sensor BME280.
Vocês já sabem que gosto muito deste chip, inclusive pela possibilidade de seu
uso em campo. Vamos, então, enviar solicitações utilizando LoRa, executar a
leitura da temperatura, pressão e umidade utilizando o sensor BME280, além de
enviar resposta à solicitação com os dados lidos.
No nosso projeto, o Master envia uma solicitação ao Slave. O Slave utilza o sensor BME280 para fazer a leitura dos dados, sendo que este mesmo Slave envia para o Master os dados lidos. O Master, então, calcula o tempo da operação e mostra os dados. Tudo isso, faço usando o radio LoRa, que vai longe, como
comprovado em um teste que fizemos que chegamos ao alcance de 6,5 km.
Comunicação
1 - O Master envia um pacote indicando que deseja receber os dados do Slave
2 - O Slave recebe e verifica
este pacote
3 - O Slave envia de volta um
pacote com os dados lidos do sensor BME280
4 - O Master recebe, verifica
o pacote e exibe os dados
Heltec WiFi LoRa 32 Pinout
BME280
Sensor de temperatura, pressão
e umidade.
Montagem
Biblioteca BME280
Na IDE do Arduino vá em
Sketch->Incluir Biblioteca->Gerenciar Bibliotecas...
Procure por BME280 e instale
Adafruit BME280 Library
Biblioteca Adafruit Unified Sensor
Na IDE do Arduino vá em
Sketch->Incluir Biblioteca->Gerenciar Bibliotecas...
Procure por adafruit sensor
based libraries e instale Adafruit Unified Sensor
Modificar pinagem I2C do WiFi LoRa 32
Preciso contar para vocês que,
na primeira vez que compilei o BME280 no ESP32, não deu certo. Então, veja só
essa dica: você tem que modificar um .h de dentro do compilador do arduino.
Essa é uma questão que não se descobre rapidamente, então quero te explicar
aqui o que você deve fazer.
Em
C:\Users\<SEU_USUARIO>\Documents\Arduino\hardware\heltec\esp32\variants\wifi_lora_32\pins_arduino.h a Heltec colocou o SAD
e o SCL, no pinos 21 e 22, respectivamente. Porém, a lib da Adafruit não aceita
esses pinos. Qual a biblioteca aceita: o 4 e o 15. Essa alteração, portanto, é
muito importante.
Portanto:
Abra o arquivo:
C:\Users\<SEU_USUARIO>\Documents\Arduino\hardware\heltec\esp32\variants\wifi_lora_32\pins_arduino.h
Código fonte
Esse código fonte é o mesmo
que utilizei no vídeo: ESP32 LoRa comArduino IDE Send e Receive TX RX. Eu apenas o modifiquei para o BME280.
LoRaSendReceiveBME280.ino
De início, vamos incluir as
bibliotecas e definir os destinos dos GPIOs, além da frequência do rádio.
Ainda, vamos criar constantes para informar ao Slave sobre os trabalhos com os
dados, bem como o retorno destes para o Master. Estruturamos ainda os dados do
sensor e apontamos a variável para controlar o display.
#include <SPI.h> #include <LoRa.h> #include <Wire.h> #include <SSD1306.h> //Deixe esta linha descomentada para compilar o Master //Comente ou remova para compilar o Slave #define MASTER #define RST 14 // GPIO14 RESET #define DI00 26 // GPIO26 IRQ(Interrupt Request) #define BAND 433E6 //Frequência do radio - exemplo : 433E6, 868E6, 915E6 //Constante para informar ao Slave que queremos os dados const String GETDATA = "getdata"; //Constante que o Slave retorna junto com os dados para o Master const String SETDATA = "setdata="; //Estrutura com os dados do sensor typedef struct { double temperature; double pressure; double humidity; }Data; //Variável para controlar o display SSD1306 display(0x3c, SDA, SCL);
LoRaSendReceiveBME280.ino – setupDisplay
Neste primeiro Setup, vamos
atuar na configuração do display.
void setupDisplay(){ //O estado do GPIO16 é utilizado para controlar o display OLED pinMode(16, OUTPUT); //Reseta as configurações do display OLED digitalWrite(16, LOW); //Para o OLED permanecer ligado, o GPIO16 deve permanecer HIGH //Deve estar em HIGH antes de chamar o display.init() e fazer as demais configurações, //não inverta a ordem digitalWrite(16, HIGH); //Configurações do display display.init(); display.flipScreenVertically(); display.setFont(ArialMT_Plain_16); display.setTextAlignment(TEXT_ALIGN_LEFT); }
LoRaSendReceiveBME280.ino – setupLoRa
Aqui, vamos tratar das
configurações iniciais do LoRa.
//Configurações iniciais do LoRa void setupLoRa(){ //Inicializa a comunicação SPI.begin(SCK, MISO, MOSI, SS); LoRa.setPins(SS, RST, DI00); //Inicializa o LoRa if (!LoRa.begin(BAND, true)){ //Se não conseguiu inicializar, mostra uma mensagem no display display.clear(); display.drawString(0, 0, "Erro ao inicializar o LoRa!"); display.display(); while (1); } //Ativa o crc LoRa.enableCrc(); //Ativa o recebimento de pacotes LoRa.receive(); }
Master.ino – setup
Fazemos nesta parte as
configurações que envolvem o Master, estas sobre a compilação, o intervalo
entre envios, bem como o tempo do último envio. Ainda, chamamos as configurações
iniciais do display e do LoRa.
//Compila apenas se MASTER estiver definido no arquivo principal #ifdef MASTER //Intervalo entre os envios #define INTERVAL 500 //Tempo do último envio long lastSendTime = 0; void setup(){ Serial.begin(115200); //Chama a configuração inicial do display setupDisplay(); //Chama a configuração inicial do LoRa setupLoRa(); display.clear(); display.drawString(0, 0, "Master"); display.display(); }
Master.ino – loop
Neste Loop, definimos o envio
do pacote para informar ao Slave o desejo de receber dados e ainda verificamos
se existem pacotes a serem recebidos.
void loop(){ //Se passou o tempo definido em INTERVAL desde o último envio if (millis() - lastSendTime > INTERVAL){ //Marcamos o tempo que ocorreu o último envio lastSendTime = millis(); //Envia o pacote para informar ao Slave que queremos receber os dados send(); } //Verificamos se há pacotes para recebermos receive(); }
Master.ino – send
Inicializamos o pacote e
enviamos o que está contido em “GETDATA”, para posteriormente finalizar e
enviar o pacote.
void send(){ //Inicializa o pacote LoRa.beginPacket(); //Envia o que está contido em "GETDATA" LoRa.print(GETDATA); //Finaliza e envia o pacote LoRa.endPacket(); }
Master.ino – receive
Nesta etapa, verificamos se o
pacote tem o tamanho mínimo de caracteres que esperamos e armazenamos uma
string. Ainda analisamos se o cabeçalho é o que esperamos, partimos para a
leitura dos dados e os exibimos no display.
void receive(){ //Tentamos ler o pacote int packetSize = LoRa.parsePacket(); //Verificamos se o pacote tem o tamanho mínimo de caracteres que esperamos if (packetSize > SETDATA.length()){ String received = ""; //Armazena os dados do pacote em uma string for(int i=0; i<SETDATA.length(); i++){ received += (char) LoRa.read(); } //Se o cabeçalho é o que esperamos if(received.equals(SETDATA)){ //Fazemos a leitura dos dados Data data; LoRa.readBytes((uint8_t*)&data, sizeof(data)); //Mostramos os dados no display showData(data); } } }
Master.ino – showData
Por fim, mostramos o tempo que
o Master levou para criar o pacote, enviar, o Slave receber, fazer a leitura,
criar um novo pacote e enviá-lo ao Master, que o recebe e faz a leitura. Este é
impresso no display.
void showData(Data data){ //Tempo que demorou para o Master criar o pacote, enviar o pacote, //o Slave receber, fazer a leitura, criar um novo pacote, enviá-lo //e o Master receber e ler String waiting = String(millis() - lastSendTime); //Mostra no display os dados e o tempo que a operação demorou display.clear(); display.drawString(0, 0, String(data.temperature) + " C"); display.drawString(0, 16, String(data.pressure) + " Pa"); display.drawString(0, 32, String(data.humidity) + "%"); display.drawString(0, 48, waiting + " ms"); display.display(); } #endif
Slave.ino
Iniciando o código do Slave,
compilamos apenas se o Master não estiver definido no arquivo principal. Incluímos as bibliotecas e apontamos a
responsável pela leitura da temperatura, pressão e umidade.
//Compila apenas se MASTER não estiver definido no arquivo principal #ifndef MASTER #include <adafruit_sensor.h> #include <adafruit_bme280.h> //Responsável pela leitura da temperatura, pressão e umidade Adafruit_BME280 bme;
Slave.ino – Setup
No Setup do Slave, chamamos as
configurações iniciais do display e do LoRa.
void setup(){ Serial.begin(115200); //Chama a configuração inicial do display setupDisplay(); //Chama a configuração inicial do LoRa setupLoRa(); //0x76 se pino SDO do sensor estiver no GND //0x77 se pino SDO do sensor estiver no 3.3v if (!bme.begin(0x76)) { display.clear(); display.drawString(0, 0, "Sensor não encontrado"); display.display(); while(1); } display.clear(); display.drawString(0, 0, "Slave esperando..."); display.display(); }
Slave.ino - Loop
Assim como no Master, nesta
parte do Loop do Slave, verificamos se o mesmo tem a quantidade de caracteres
esperada e armazenamos os dados em uma String. Ainda, simulamos a leitura dos
dados. Criamos o pacote, finalizamos e enviamos. Por fim, exibimos as
informações no display.
void loop(){ //Tenta ler o pacote int packetSize = LoRa.parsePacket(); //Verifica se o pacote possui a quantidade de caracteres que esperamos if (packetSize == GETDATA.length()) { String received = ""; //Armazena os dados do pacote em uma string while(LoRa.available()) { received += (char) LoRa.read(); } if(received.equals(GETDATA)) { //Faz a leitura dos dados Data data = readData(); Serial.println("Criando pacote para envio"); //Cria o pacote para envio LoRa.beginPacket(); LoRa.print(SETDATA); LoRa.write((uint8_t*)&data, sizeof(data)); //Finaliza e envia o pacote LoRa.endPacket(); showSentData(data); } } }
Slave.ino – readData
Nesta parte tratamos da função
onde se faz a leitura dos dados.
//Função onde se faz a leitura dos dados Data readData() { Data data; data.temperature = bme.readTemperature(); data.pressure = bme.readPressure(); data.humidity = bme.readHumidity(); return data; }
Slave.ino – showSentData
Enfim, exibidos os dados no
display.
void showSentData(Data data) { //Mostra no display display.clear(); display.drawString(0, 0, "Enviou:"); display.drawString(0, 16, String(data.temperature) + " C"); display.drawString(0, 32, String(data.pressure) + " Pa"); display.drawString(0, 48, String(data.humidity) + "%"); display.display(); } #endif
Onde encontrar este ESP32 LoRa: https://bit.ly/2JpAi7u
10 Comentários
Olá Fernando, estou seguindo esta aula, porem está dando este erro ao compilar:
ResponderExcluirLoRaSendReceiveBME280:54: error: no matching function for call to 'LoRaClass::begin(double, bool)'
In file included from C:\Users\Rafael\Google Drive\Indus4\Projetos\Estação Met\Programa ESP\LoRaSendReceiveBME280\LoRaSendReceiveBME280\LoRaSendReceiveBME280.ino:2:0:
C:\Users\Rafael\Documents\Arduino\libraries\LoRa\src/LoRa.h:31:7: note: candidate: int LoRaClass::begin(long int)
int begin(long frequency);
^
C:\Users\Rafael\Documents\Arduino\libraries\LoRa\src/LoRa.h:31:7: note: candidate expects 1 argument, 2 provided
exit status 1
no matching function for call to 'LoRaClass::begin(double, bool)'
Olá, boa tarde. Estou com o mesmo problema. Ao compilar apresenta o mesmo erro :
Excluirexit status 1
no matching function for call to 'LoRaClass::begin(double, bool)'
Conseguiu resolver? Pode me ajudar com alguma dica? Obrigado
Só tirar o true que ta resolvido
ExcluirBoa noite… Eu gostaria de fazer um projeto onde usaria um display OLED grande e nele constariam 4 leituras de sensores ultrasonicos diferentes… Você poderia me ajudar?
ResponderExcluirBom dia Fernando
ResponderExcluirMuito obrigado por vossos videos que sigo desde Paris. Apprendi bastente com a qualidade das informaçoes. Este video mostra uma imagem do Heltec Wifi Lora 32 que parece que foi feita com Fritzing. Nao consigo encontrar o modelo, seria possivel voce por a disposiçao en descarga no materail para download?
Obrigado
Daniel
Olá,
ResponderExcluirEstou tentando utilizar o EPS32 LORA WIFI da HELTEC junto do GPS-NEO6M e não estou conseguindo fazer leitura do GPS. Alguém poderia me ajudar? Já tentei usar Software e HardwareSerial ambas sem sucesso (talvez por falta de conhecimento de como utilizá-las corretamente)...
Olá boa tarde a todos. Estou tentando reproduzir esse projeto, porém ao compilar apresenta o mesmo erro informado pelo colega acima. Alguma dica? Desde já agradeço.
ResponderExcluirexit status 1
no matching function for call to 'LoRaClass::begin(double, bool)'
Miguel.
Tira o ,bool que vai funcionar porém ... né
Excluirna linha 54 ---> if (!LoRa.begin(BAND, true)){
ResponderExcluirretirar o true
desta forma funciona ---> if (!LoRa.begin(BAND)){
Compilo, mais aparece no display MASTER e no outro esp32 aparece slave esperando mais nada
Excluir