Overview:
In this tutorial we will explore the benefits of LoRa and program one LoRa enabled dev-board to receive inputs and transmit those inputs to another LoRa enabled board which will coordinate a response. Specifically, we will build two circuits: one that senses when one of two push switches has been pressed and transmits a LoRa packet, and the second that receives the LoRa packet and turns a LED on or off based on the sent data. This tutorial could be applied to projects such as Smart-Home controllers such as garage door openers or light switches or home garden monitoring devices.
The major steps are:
- Solder pin headers
- Prepare your Arduino IDE to communicate with the Heltec WiFi LoRa 32 V2 dev-boards
- Wire the circuits
- Write code to control the transmitter and receiver boards
Why LoRa?
In short, LoRa (Long Range) is a type of wireless data communication that is used for projects that have long distance and lower power usage requirements. LoRa is great for projects that run on solar power or small batteries and need to be placed in areas that do not have WiFi connectivity. Further, LoRa can be used in a point to point (just two devices) or network (three or more devices). However, LoRa is not suitable for situations where data is communicated frequently and in large quantities.
For more information about LoRa please visit these resources:
This tutorial explains radio frequency allocation in the US and guides the user through calculating data loss
Parts needed:
- 2 Heltec WiFi LoRa 32 V2 Boards
- When purchasing LoRa devices, check that they support transmission at the proper frequency band for your region. For instance, these boards can transmit at 915MHz
- These boards come with a built-in OLED display and WiFi capabilities. These extra features are not necessary and there are less expensive boards that come without these features.
- The boards can also be purchased here
- (1) large breadboard (or two small breadboards)
- (2) push switches
- (1) LED
- (1) 220Ω resistor
- (7) M-M jumper wires
Step-by-Step:
Step 1: Solder the pin headers onto the Heltec WiFi LoRa 32 V2 dev-boards
The Heltec WiFi LoRa 32 V2 dev-boards do not come assembled and need to be soldered. When soldering, be careful not to burn the ribbon cable that connects the board to the OLED. Here is a helpful tutorial on how to solder header pins on printed circuit boards. Additionally, Adafruit has an awesome help-guide that covers soldering tools and techniques.
Step 2: Prepare your Arduino IDE to communicate with the Heltec WiFi LoRa 32 V2 dev-boards
Follow the Heltec official ESP32+LoRa Series Quick start guide. Ensure that you:
- Add the latest Heltec ESP32 board manager to the board manager URLs
- Install the Heltec ESP32 boards in the board manager
- Download the Heltec ESP32 library
Before you start wiring, test that your boards are working:
- Ensure that you have switched to the LoRa board by going to Tools > Board Manager > Heltec ESP32 Arduino > WiFi LoRa 32 (V2)
- Ensure that you are using the correct COM port for your LoRa board (for instance, on my machine, COM3 was reserved for my Arduino Uno and COM4 and COM5 were used for the LoRa boards)
- Load the transmitter example LoRa+OLED sketch from Heltec onto one of the boards: File > Examples > Heltec ESP32 Dev-Boards (under Examples from Custom Libraries) > LoRa > OLED_LoRa_Sender
- **Important note**: as noted above, ensure that you band value on line 23 to make sure you are transmitting on an appropriate frequency for your region
- Load the receiver example LoRa+OLED sketch from Heltec onto one of the boards: File > Examples > Heltec ESP32 Dev-Boards (under Examples from Custom Libraries) > LoRa > OLED_LoRa_Reciever
- **Important note**: as noted above, ensure that you band value on line 12 to make sure you are transmitting on an appropriate frequency for your region
When you power up the boards with these sketches, the Heltec logo should flash for 1.5 seconds, then it should its LoRa functionality has been initialized with: “Heltec.LoRa Initial success!”. Finally, on the receiver board you should start to see “hello “ with an incrementing digit for the number of packets that have been received.
Step 3: Wire the circuits
To a novice, the pinout diagram for the Heltec WiFi LoRa 32 V2 dev-board can be overwhelming. I have included a copy of the pinout diagram from the Heltec WiFi-Kit series Github page.
When identifying pins to use for your projects, first pay attention to the red arrows. These arrows indicate which pins are reserved for the OLED and LoRa capabilities of the board and should not be adjusted. GPIO (General Purpose Input/Output) pins such as 2, 12, 13, 17, 22, 23, and 34-39 are open pins.
Now that the pins have been selected, it is time to wire the transmitter and receiver circuits.
Transmitter circuit:
The transmitter circuit contains two push switches, button A and button B. These buttons are connected to digital pins 2 and 17, respectively, and grounded to one of the LoRa boards 2 ground pins. When a button is pressed, the digital signal at its corresponding pin will read LOW, whereas the default reading is HIGH. In the code, we can look for this change in signal and complete some actions based on the event occurring.
Receiver circuit:
The receiver circuit is a little simpler. It is just a standard LED connected to pin 17 on the receiver LoRa board with a 220Ω resistor. The code for the receiver circuit will control the LED by setting pin 17 to high for LED on, or low for LED off.
Step 4: Write code to control the transmitter and receiver boards
The code for this project is held in this Github repository. Additionally, I have included both sketches below. Everything is explained in the comments throughout.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
/* Control an LED Remotely via 2 Heltec LoRa boards: Transmitter Author Johnathan Clementi Date: 2022/03/30 This project builds on the example showing the Heltec.LoRa sended data in OLED from Aaron Lee at Heltec. This project uses 2 Heltec WiFi LoRa 32 V2 boards, one as a transmitter connected to two push buttons, and one as a receiver connected to an LED. When buttons A/B are pressed, the transmitter LoRa board will send a LoRa packet containing a string based on the button that has been pressed. When this packet is recieved by the receiver, it the packet will be parsed, compared to a predefined string, and the signal sent to an LED will be determined by this string comparison. A note from Aaron Lee about the functionality of the OLED display: The onboard OLED display is SSD1306 driver and I2C interface. In order to make the OLED correctly operation, you should output a high-low-high(1-0-1) signal by soft- ware to OLED's reset pin, the low-level signal at least 5ms. OLED pins to ESP32 GPIOs via this connecthin: OLED_SDA -- GPIO4 OLED_SCL -- GPIO15 OLED_RST -- GPIO16 by Aaron.Lee from HelTec AutoMation, ChengDu, China https://heltec.org this project also realess in GitHub: https://github.com/Heltec-Aaron-Lee/WiFi_Kit_series */ #include "heltec.h" #include "images.h" #define BAND 915E6 //Band 915E6 is for use in N. America, 868E6 is for Europe // LED handling // int buttonApin = 2; // We will read the input of Button A at pin 2 int buttonBpin = 17; // We will read the input of Button B at pin 17 unsigned int counter = 0; // The counter counts how many packets have been sent String rssi = "RSSI --"; // RSSI stands for Recieved Signal Strength Indication // and indicates the strength of the signal between the LoRa boards String packSize = "--"; String packet ; void logo() // This routine will display the Heltec logo on the OLED display // The hexidecimal values are held in the images.h file // These values could be edited to display other images { Heltec.display->clear(); // Clear the display Heltec.display->drawXbm(0,5,logo_width,logo_height,logo_bits); // interpret the hex values Heltec.display->display(); // show the image on the OLED display } void setup() { pinMode(buttonApin, INPUT_PULLUP); // Define ButtonA pin (2) as an Input Pullup for the button pinMode(buttonBpin, INPUT_PULLUP); // Define ButtonB pin (17) as an Input Pullup for the button //WIFI Kit series V1 not support Vext control Heltec.begin(true /*DisplayEnable Enable*/, true /*Heltec.Heltec.Heltec.LoRa Disable*/, true /*Serial Enable*/, true /*PABOOST Enable*/, BAND /*long BAND*/); Heltec.display->init(); // initialize the OLED display Heltec.display->flipScreenVertically(); // ensure the correct orientation of the OLED display Heltec.display->setFont(ArialMT_Plain_10); logo(); // Show the logo for 1.5 seconds delay(1500); Heltec.display->clear(); // remove the logo from the screen Heltec.display->drawString(0, 0, "Heltec.LoRa Initial success!"); // initialize LoRa Heltec.display->display(); delay(1000); } void loop() { Heltec.display->clear(); // clear setup text Heltec.display->setTextAlignment(TEXT_ALIGN_LEFT); // Left justify text Heltec.display->setFont(ArialMT_Plain_10); Heltec.display->drawString(0, 0, "Sending packet: "); // This indicates how many packets have been sent // aka the number of times a button has been pressed Heltec.display->drawString(90, 0, String(counter)); // show the text for packet incrementing the packet counter Heltec.display->display(); // display that text if (digitalRead(buttonApin) == LOW) // check if Button A has been pressed, do nothing if not (HIGH) { LoRa.beginPacket(); // initialize a packet LoRa.setTxPower(5,RF_PACONFIG_PASELECT_PABOOST); // set the signal strength to 5 decibles - useful for debugging // lower signal strength = shorter travel of signal LoRa.print("button A pressed"); // this is the text that will be included in the packet LoRa.endPacket(); // close the packet and send it out counter++; // increment the packet counter delay(500); // delay half a second before a button and packet can be sent so there is enough time to // finish sending a packet } if (digitalRead(buttonBpin) == LOW) { LoRa.beginPacket(); // initialize a packet LoRa.setTxPower(5,RF_PACONFIG_PASELECT_PABOOST); // set the signal strength to 5 decibles - useful for debugging // lower signal strength = shorter travel of signal LoRa.print("button B pressed"); // this is the text that will be included in the packet LoRa.endPacket(); counter++; delay(500); // delay half a second before a button and packet can be sent so there is enough time to // finish sending a packet } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
/* Control an LED Remotely via 2 Heltec LoRa boards: Reciever Author Johnathan Clementi Date: 2022/03/30 This project builds on the example showing the Heltec.LoRa sended data in OLED from Aaron Lee at Heltec. This project uses 2 Heltec WiFi LoRa 32 V2 boards, one as a transmitter connected to two push buttons, and one as a receiver connected to an LED. When buttons A/B are pressed, the transmitter LoRa board will send a LoRa packet containing a string based on the button that has been pressed. When this packet is recieved by the receiver, it the packet will be parsed, compared to a predefined string, and the signal sent to an LED will be determined by this string comparison. A note from Aaron Lee about the functionality of the OLED display: The onboard OLED display is SSD1306 driver and I2C interface. In order to make the OLED correctly operation, you should output a high-low-high(1-0-1) signal by soft- ware to OLED's reset pin, the low-level signal at least 5ms. OLED pins to ESP32 GPIOs via this connecthin: OLED_SDA -- GPIO4 OLED_SCL -- GPIO15 OLED_RST -- GPIO16 by Aaron.Lee from HelTec AutoMation, ChengDu, China https://heltec.org this project also realess in GitHub: https://github.com/Heltec-Aaron-Lee/WiFi_Kit_series */ #include "heltec.h" #include "images.h" // Output LED pin // help from https://docs.arduino.cc/tutorials/mkr-wan-1310/lora-button-press String buttonAPress = "button A pressed"; // When Button A is pressed on the transmitter circuit // This text will be included in the packet. String buttonBPress = "button B pressed"; // When Button B is pressed on the transmitter circuit // This text will be included in the packet. int ledPin = 17; // Pin 17 controls the signal sent to the LED #define BAND 915E6 //Band 915E6 is for use in N. America, 868E6 is for Europe String rssi = "RSSI --"; // RSSI stands for Recieved Signal Strength Indication // and indicates the strength of the signal between the LoRa boards String packSize = "--"; String packet ; void logo(){// This routine will display the Heltec logo on the OLED display // The hexidecimal values are held in the images.h file // These values could be edited to display other images Heltec.display->clear(); // Clear the display Heltec.display->drawXbm(0,5,logo_width,logo_height,logo_bits); // interpret the hex values Heltec.display->display(); // show the image on the OLED display } void LoRaData(){ Heltec.display->clear(); // Clear the display Heltec.display->setTextAlignment(TEXT_ALIGN_LEFT); // Left justify text Heltec.display->setFont(ArialMT_Plain_10); Heltec.display->drawString(0 , 15 , "Received "+ packSize + " bytes"); // Indicate how big the packet recieved is Heltec.display->drawStringMaxWidth(0 , 26 , 128, packet); // parse the packet size Heltec.display->drawString(0, 0, rssi); Heltec.display->display(); } void cbk(int packetSize) { // This routine will parse the packet and respond based on its contents packet =""; // Start with a blank string for the packet packSize = String(packetSize,DEC); // read packet for (int i = 0; i < packetSize; i++) { packet += (char) LoRa.read(); } // parse packet rssi = "RSSI " + String(LoRa.packetRssi(), DEC) ; // RSSI = Recieved Signal Strength Indication LoRaData(); // display the packet information on the OLED if(packet.equals(buttonAPress)){ // check if the packet contains Button A text digitalWrite(ledPin, HIGH); // if button A was pressed, turn the LED on } if(packet.equals(buttonBPress)){ // check if the packet contains Button A text digitalWrite(ledPin, LOW); // if button A was pressed, turn the LED on } } void setup() { pinMode(ledPin, OUTPUT); // initialize pin 17 as the pin output digitalWrite(ledPin, HIGH); // initialize LED in On state //WIFI Kit series V1 not support Vext control Heltec.begin(true /*DisplayEnable Enable*/, true /*Heltec.Heltec.Heltec.LoRa Disable*/, true /*Serial Enable*/, true /*PABOOST Enable*/, BAND /*long BAND*/); Heltec.display->init(); // initialze the display Heltec.display->flipScreenVertically(); // ensure the correct orientation of the OLED display Heltec.display->setFont(ArialMT_Plain_10); logo(); // Show the logo for 1.5 seconds delay(1500); Heltec.display->clear(); // remove the logo from the screen Heltec.display->drawString(0, 0, "Heltec.LoRa Initial success!"); // initialize LoRa Heltec.display->drawString(0, 10, "Wait for incoming data..."); // Indicate waiting for data Heltec.display->display(); delay(1000); //LoRa.onReceive(cbk); LoRa.receive(); } void loop() { // This routine will wait until a packet is recieved // once a packet is recieved, low-level parse then interpret it using cbk function created above int packetSize = LoRa.parsePacket(); if (packetSize) { cbk(packetSize); } delay(10); // wait 10 milliseconds after last packet is recieved to start listening again } |
One reply on “Using 2 Heltec WiFi-LoRa 32 V2 boards to transmit and respond to sensed data”
I know that this is for the v2.
Is there a way to compile it for v3?