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
12 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
ExcluirConsigo compilar o MASTER, mas na compilação do Slave aparece um erro "Adafruit_SPIDevice.cpp: In member function 'bool Adafruit_SPIDevice::write(const uint8_t*, size_t, const uint8_t*, size_t)':"
ResponderExcluirAcredito que deva ser algo que mudou na atualização de alguma library, tentei compilar em versões anteriores mas também não funcionou...
Agora funcionou, vi que teve uma atualização na biblioteca Adafruit_BusIO, acredito que foi isso!
Excluir