Components and supplies
Espressif ESP32 Development Board - Developer Edition
Buzzer
DHT22 Temperature Sensor
Monochrome 0.91”128x32 I2C OLED Display with Chip Pad
Arduino Pro Mini 328 - 5V/16MHz
Pushbutton Switch, Momentary
RFM95W Module
Tools and machines
Soldering iron (generic)
Solder Wire, Lead Free
Apps and platforms
Arduino IoT Cloud
Arduino IDE
Project description
Code
messages.h
arduino
Pre-Defined messages inlude file.
1#define NUMBER_OF_STRING 4 2#define MAX_STRING_SIZE 40 3 4char arr[NUMBER_OF_STRING][MAX_STRING_SIZE] = 5{ "Get on the phone!", 6 "The music is too loud", 7 "I'm ready to move", 8 "See you at 10:00 AM" 9}; 10
LoRa_ESP32_Cloud.ino
arduino
ESP32 LoRa Arduino IOT Cloud gateway
1/* 2 LoRa Cloud Arduino IOT Gateway with ESP32 3 4 Created by Carlo Stramaglia 26 07 2022 5 6*/ 7 8#include "thingProperties.h" 9#include <SPI.h> // include libraries 10#include <LoRa.h> 11 12const int csPin = 5; // LoRa radio chip select 13const int resetPin = 14; // LoRa radio reset 14const int irqPin = 2; // change for your board; must be a hardware interrupt pin 15 16byte msgCount = 0; // count of outgoing messages 17byte localAddress = 0x01; // address of this device 18byte destination = 0xFF; // destination to send to 19long lastSendTime = 0; // last send time 20int interval = 2000; // interval between sends 21 22String incoming; 23String outgoing; // outgoing message 24 25void setup() { 26 // Initialize serial and wait for port to open: 27 Serial.begin(9600); 28 // This delay gives the chance to wait for a Serial Monitor without blocking if none is found 29 delay(1500); 30 31 // override the default CS, reset, and IRQ pins (optional) 32 LoRa.setPins(csPin, resetPin, irqPin);// set CS, reset, IRQ pin 33 34 if (!LoRa.begin(868E6)) { // initialize ratio at 915 MHz 35 Serial.println("LoRa init failed. Check your connections."); 36 while (true); // if failed, do nothing 37 } 38 39 Serial.println("LoRa init succeeded."); 40 41 delay(1500); 42 43 // Defined in thingProperties.h 44 initProperties(); 45 46 // Connect to Arduino IoT Cloud 47 ArduinoCloud.begin(ArduinoIoTPreferredConnection); 48 49 /* 50 The following function allows you to obtain more information 51 related to the state of network and IoT Cloud connection and errors 52 the higher number the more granular information you’ll get. 53 The default is 0 (only errors). 54 Maximum is 4 55 */ 56 setDebugMessageLevel(2); 57 ArduinoCloud.printDebugInfo(); 58} 59 60void loop() { 61 ArduinoCloud.update(); 62 // Your code here 63 // parse for a packet, and call onReceive with the result: 64 onReceive(LoRa.parsePacket()); 65 //ciaoString = incoming; 66 67 68} 69 70 71 72/* 73 Since CiaoString is READ_WRITE variable, onCiaoStringChange() is 74 executed every time a new value is received from IoT Cloud. 75*/ 76void onCiaoStringChange() { 77 // Add your code here to act upon CiaoString change 78 sendMessage(ciaoString); 79} 80 81void sendMessage(String outgoing) { 82 LoRa.beginPacket(); // start packet 83 LoRa.write(destination); // add destination address 84 LoRa.write(localAddress); // add sender address 85 LoRa.write(msgCount); // add message ID 86 LoRa.write(outgoing.length()); // add payload length 87 LoRa.print(outgoing); // add payload 88 LoRa.endPacket(); // finish packet and send it 89 msgCount++; // increment message ID 90} 91 92void onReceive(int packetSize) { 93 if (packetSize == 0) return; // if there's no packet, return 94 95 // read packet header bytes: 96 int recipient = LoRa.read(); // recipient address 97 byte sender = LoRa.read(); // sender address 98 byte incomingMsgId = LoRa.read(); // incoming msg ID 99 byte incomingLength = LoRa.read(); // incoming msg length 100 101 Serial.println("Received from: 0x" + String(sender, HEX)); 102 Serial.println("Sent to: 0x" + String(recipient, HEX)); 103 Serial.println("Message ID: " + String(incomingMsgId)); 104 Serial.println("Message length: " + String(incomingLength)); 105 Serial.println(); 106 107 incoming = ""; 108 byte incomingData[20]; 109 int i=0; 110 111 if (sender != 0x2) { 112 while (LoRa.available()) { 113 incoming += (char)LoRa.read(); 114 } 115/* if (incomingLength != incoming.length()) { // check length for error 116 Serial.println("error: message length does not match length"); 117 return; // skip rest of function 118 } */ 119 } 120 else { 121 Serial.println("We are in the case of data rceiving"); 122 while (LoRa.available()) { 123 incomingData[i] = LoRa.read(); 124 i++; 125 } 126 } 127 128 129 130 // if the recipient isn't this device or broadcast, 131 if (recipient != localAddress && recipient != 0xFF) { 132 Serial.println("This message is not for me."); 133 return; // skip rest of function 134 } 135 136 if (sender != 0x2) { 137 // if message is for this device, or broadcast, print details: 138 Serial.println("Received from: 0x" + String(sender, HEX)); 139 Serial.println("Sent to: 0x" + String(recipient, HEX)); 140 Serial.println("Message ID: " + String(incomingMsgId)); 141 Serial.println("Message length: " + String(incomingLength)); 142 Serial.println("Message: " + incoming); 143 Serial.println("RSSI: " + String(LoRa.packetRssi())); 144 Serial.println("Snr: " + String(LoRa.packetSnr())); 145 Serial.println(); 146 ciaoString = "Device " + String (sender,DEC) + ": " + incoming; 147 } 148 else { 149 humidity = ((incomingData[2] << 8) | incomingData[3]); 150 humidity = humidity/10; 151 temperature = ((incomingData[0] << 8) | incomingData[1]); 152 temperature = temperature/10; 153 rzero = ((incomingData[4] << 16) | incomingData[5] << 8 | incomingData[6]); 154 rzero = rzero/100; 155 crzero = ((incomingData[7] << 16) | incomingData[8] << 8 | incomingData[9]); 156 crzero = crzero/100; 157 resistance = ((incomingData[10] << 16) | incomingData[11] << 8 | incomingData[12]); 158 resistance = resistance/100; 159 ppm = ((incomingData[13] << 16) | incomingData[14] << 8 | incomingData[15]); 160 ppm = ppm/100; 161 cppm = ((incomingData[16] << 16) | incomingData[17] << 8 | incomingData[18]); 162 cppm = cppm/100; 163 Serial.println("Final Temperature: " + String (temperature)); 164 Serial.println("Final Humidity: " + String (humidity)); 165 Serial.println("Final rzero: " + String (rzero)); 166 Serial.println("Final crzero: " + String (crzero)); 167 Serial.println("Final resistance: " + String (resistance)); 168 Serial.println("Final ppm: " + String (ppm)); 169 Serial.println("Final cppm: " + String (cppm)); 170 } 171}
LoRaWK_Carlo.ino
arduino
This is the LoRa Node with Display, Buzzer and Push Button
1/* 2 LoRa Messaging with ESP32 3 4 This code send messages between Devices. 5 6 created 19 06 2022 7 by Carlo Stramaglia 8*/ 9 10#include <SPI.h> // include libraries 11#include <LoRa.h> 12#include <U8g2lib.h> 13#include "OneButton.h" 14#include "messages.h" 15 16#ifdef U8X8_HAVE_HW_SPI 17#include <SPI.h> 18#endif 19#ifdef U8X8_HAVE_HW_I2C 20#include <Wire.h> 21#endif 22 23U8G2_SSD1306_128X32_UNIVISION_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); 24 25#define PIN_INPUT 15 // PIN for push button 26#define PIN_BUZ 4 // PIN for buzzer 27// current Buzzer state, staring with LOW (0) 28int buzState = LOW; 29OneButton button(PIN_INPUT, true); 30 31int exitFlag = 0; 32int stringNumber = -1; 33 34const int csPin = 5; // LoRa radio chip select 35const int resetPin = 14; // LoRa radio reset 36const int irqPin = 2; // change for your board; must be a hardware interrupt pin 37 38String outgoing; // outgoing message 39 40byte msgCount = 0; // count of outgoing messages 41byte localAddress = 0xBA; // address of this device 42byte destination = 0xFF; // destination to send to 43long lastSendTime = 0; // last send time 44int interval = 2000; // interval between sends 45 46 47 48void setup() { 49 Serial.begin(9600); // initialize serial 50 u8g2.begin(); 51 52 // enable the buzzer 53 pinMode(PIN_BUZ, OUTPUT); // sets the digital pin as output 54 digitalWrite(PIN_BUZ, buzState); // sets the buzzer in mute 55 56 // link the doubleclick function to be called on a doubleclick event. 57 button.attachClick(Click); 58 button.attachLongPressStart(longPressStart); 59 60 // override the default CS, reset, and IRQ pins (optional) 61 LoRa.setPins(csPin, resetPin, irqPin);// set CS, reset, IRQ pin 62 63 if (!LoRa.begin(868E6)) { // initialize ratio at 868 MHz 64 Serial.println("LoRa init failed. Check your connections."); 65 while (true); // if failed, do nothing 66 } 67 68 Serial.println("LoRa init succeeded."); 69} 70 71void loop() { 72 73 delay(10); 74 button.tick(); 75 // parse for a packet, and call onReceive with the result: 76 onReceive(LoRa.parsePacket()); 77} 78 79void sendMessage(String outgoing) { 80 LoRa.beginPacket(); // start packet 81 LoRa.write(destination); // add destination address 82 LoRa.write(localAddress); // add sender address 83 LoRa.write(msgCount); // add message ID 84 LoRa.write(outgoing.length()); // add payload length 85 LoRa.print(outgoing); // add payload 86 LoRa.endPacket(); // finish packet and send it 87 msgCount++; // increment message ID 88} 89 90void onReceive(int packetSize) { 91 if (packetSize == 0) return; // if there's no packet, return 92 93 // read packet header bytes: 94 int recipient = LoRa.read(); // recipient address 95 byte sender = LoRa.read(); // sender address 96 byte incomingMsgId = LoRa.read(); // incoming msg ID 97 byte incomingLength = LoRa.read(); // incoming msg length 98 99 String incoming = ""; 100 101 while (LoRa.available()) { 102 incoming += (char)LoRa.read(); 103 } 104 105 if (incomingLength != incoming.length()) { // check length for error 106 Serial.println("error: message length does not match length"); 107 return; // skip rest of function 108 } 109 110 111 112 // if the recipient isn't this device or broadcast, 113 if (recipient != localAddress && recipient != 0xFF) { 114 Serial.println("This message is not for me."); 115 return; // skip rest of function 116 } 117 118 // if message is for this device, or broadcast, print details: 119 Serial.println("Received from: 0x" + String(sender, HEX)); 120 Serial.println("Sent to: 0x" + String(recipient, HEX)); 121 Serial.println("Message ID: " + String(incomingMsgId)); 122 Serial.println("Message length: " + String(incomingLength)); 123 Serial.println("Message: " + incoming); 124 Serial.println("RSSI: " + String(LoRa.packetRssi())); 125 Serial.println("Snr: " + String(LoRa.packetSnr())); 126 Serial.println(); 127 digitalWrite(PIN_BUZ, !buzState); 128 Serial.println("Buzzer ON"); 129 delay (100); 130 digitalWrite(PIN_BUZ, buzState); 131 Serial.println("Buzzer OFF"); 132 sendDisplay(sender, incoming); 133} 134 135void sendDisplay(unsigned int nodeID, String messageLoRa) { 136 char messageLocal[MAX_STRING_SIZE]; 137 u8g2.clearBuffer(); 138 u8g2.setFont(u8g2_font_ncenB08_tr); 139 if (nodeID == 1) 140 sprintf (messageLocal, "Message From: Cloud"); 141 else 142 sprintf (messageLocal, "Message From: %d", nodeID); 143 u8g2.drawStr(0,10, messageLocal); 144 messageLoRa.toCharArray(messageLocal, MAX_STRING_SIZE); 145 u8g2.drawStr(0,30, messageLocal); 146 u8g2.sendBuffer(); 147 delay(1000); 148} 149 150 151void Click() 152{ 153 Serial.println("x1"); 154 stringNumber++; 155 if (stringNumber > (NUMBER_OF_STRING-1)) 156 stringNumber = 0; 157 displayString (stringNumber+1, arr[stringNumber]); 158 159 exitFlag = 0; 160 161} // Click 162 163void longPressStart() 164{ 165 Serial.println("Long"); 166 displaySend (stringNumber+1, arr[stringNumber]); 167 // Send data to the node 168 //LoRaNow.clear(); 169 sendMessage(arr[stringNumber]); 170 exitFlag = 1; 171 172} // LongPressStart 173 174 175void displayString (unsigned int stringNo, char* stringToDisplay) { 176 char messageLocal[MAX_STRING_SIZE]; 177 u8g2.clearBuffer(); 178 u8g2.setFont(u8g2_font_ncenB08_tr); 179 sprintf (messageLocal, "Destination: %d", destination); 180 u8g2.drawStr(0,10, messageLocal); 181 sprintf (messageLocal, "Text selection: %d of %d", stringNo, NUMBER_OF_STRING); 182 u8g2.drawStr(0,20, messageLocal); 183 u8g2.drawStr(0,30, stringToDisplay); 184 u8g2.sendBuffer(); 185 delay(100); 186} 187 188void displaySend (unsigned int stringNo, char* stringToDisplay) { 189 char messageLocal[MAX_STRING_SIZE]; 190 u8g2.clearBuffer(); 191 u8g2.setFont(u8g2_font_ncenB08_tr); 192 sprintf (messageLocal, "Destination: %d", destination); 193 u8g2.drawStr(0,10, messageLocal); 194 sprintf (messageLocal, "Sending Message: %d of %d", stringNo, NUMBER_OF_STRING); 195 u8g2.drawStr(0,20, messageLocal); 196 u8g2.drawStr(0,30, stringToDisplay); 197 u8g2.sendBuffer(); 198 delay(100); 199} 200
thingProperties.h
arduino
1// Code generated by Arduino IoT Cloud, DO NOT EDIT. 2 3#include <ArduinoIoTCloud.h> 4#include <Arduino_ConnectionHandler.h> 5 6const char DEVICE_LOGIN_NAME[] = "TO BE REPLACED WITH YOUR DATA"; 7 8const char SSID[] = "TO BE REPLACED WITH YOUR DATA"; // Network SSID (name) 9const char PASS[] = "TO BE REPLACED WITH YOUR DATA"; // Network password (use for WPA, or use as key for WEP) 10const char DEVICE_KEY[] = "TO BE REPLACED WITH YOUR DATA"; // Secret device password 11 12void onCiaoStringChange(); 13 14String ciaoString; 15float cppm; 16float crzero; 17float ppm; 18float resistance; 19float rzero; 20CloudTemperatureSensor temperature; 21CloudRelativeHumidity humidity; 22 23void initProperties(){ 24 25 ArduinoCloud.setBoardId(DEVICE_LOGIN_NAME); 26 ArduinoCloud.setSecretDeviceKey(DEVICE_KEY); 27 ArduinoCloud.addProperty(ciaoString, READWRITE, ON_CHANGE, onCiaoStringChange); 28 ArduinoCloud.addProperty(cppm, READ, ON_CHANGE, NULL); 29 ArduinoCloud.addProperty(crzero, READ, ON_CHANGE, NULL); 30 ArduinoCloud.addProperty(ppm, READ, ON_CHANGE, NULL); 31 ArduinoCloud.addProperty(resistance, READ, ON_CHANGE, NULL); 32 ArduinoCloud.addProperty(rzero, READ, ON_CHANGE, NULL); 33 ArduinoCloud.addProperty(temperature, READ, ON_CHANGE, NULL); 34 ArduinoCloud.addProperty(humidity, READ, ON_CHANGE, NULL); 35 36} 37 38WiFiConnectionHandler ArduinoIoTPreferredConnection(SSID, PASS);
LoRa_ESP32_Cloud.ino
arduino
ESP32 LoRa Arduino IOT Cloud gateway
1/* 2 LoRa Cloud Arduino IOT Gateway with ESP32 3 4 Created by 5 Carlo Stramaglia 26 07 2022 6 7*/ 8 9#include "thingProperties.h" 10#include 11 <SPI.h> // include libraries 12#include <LoRa.h> 13 14const int 15 csPin = 5; // LoRa radio chip select 16const int resetPin = 14; // 17 LoRa radio reset 18const int irqPin = 2; // change for your board; must 19 be a hardware interrupt pin 20 21byte msgCount = 0; // count of outgoing 22 messages 23byte localAddress = 0x01; // address of this device 24byte destination 25 = 0xFF; // destination to send to 26long lastSendTime = 0; // last 27 send time 28int interval = 2000; // interval between sends 29 30String 31 incoming; 32String outgoing; // outgoing message 33 34void setup() 35 { 36 // Initialize serial and wait for port to open: 37 Serial.begin(9600); 38 39 // This delay gives the chance to wait for a Serial Monitor without blocking if 40 none is found 41 delay(1500); 42 43 // override the default CS, reset, and 44 IRQ pins (optional) 45 LoRa.setPins(csPin, resetPin, irqPin);// set CS, reset, 46 IRQ pin 47 48 if (!LoRa.begin(868E6)) { // initialize ratio at 915 49 MHz 50 Serial.println("LoRa init failed. Check your connections."); 51 while 52 (true); // if failed, do nothing 53 } 54 55 Serial.println("LoRa 56 init succeeded."); 57 58 delay(1500); 59 60 // Defined in thingProperties.h 61 62 initProperties(); 63 64 // Connect to Arduino IoT Cloud 65 ArduinoCloud.begin(ArduinoIoTPreferredConnection); 66 67 68 /* 69 The following function allows you to obtain more information 70 71 related to the state of network and IoT Cloud connection and errors 72 the 73 higher number the more granular information you’ll get. 74 The default is 0 75 (only errors). 76 Maximum is 4 77 */ 78 setDebugMessageLevel(2); 79 ArduinoCloud.printDebugInfo(); 80} 81 82void 83 loop() { 84 ArduinoCloud.update(); 85 // Your code here 86 // parse for a 87 packet, and call onReceive with the result: 88 onReceive(LoRa.parsePacket()); 89 90 //ciaoString = incoming; 91 92 93} 94 95 96 97/* 98 Since CiaoString 99 is READ_WRITE variable, onCiaoStringChange() is 100 executed every time a new value 101 is received from IoT Cloud. 102*/ 103void onCiaoStringChange() { 104 // Add your 105 code here to act upon CiaoString change 106 sendMessage(ciaoString); 107} 108 109void 110 sendMessage(String outgoing) { 111 LoRa.beginPacket(); // start 112 packet 113 LoRa.write(destination); // add destination address 114 115 LoRa.write(localAddress); // add sender address 116 LoRa.write(msgCount); 117 // add message ID 118 LoRa.write(outgoing.length()); // 119 add payload length 120 LoRa.print(outgoing); // add payload 121 122 LoRa.endPacket(); // finish packet and send it 123 msgCount++; 124 // increment message ID 125} 126 127void onReceive(int 128 packetSize) { 129 if (packetSize == 0) return; // if there's no packet, 130 return 131 132 // read packet header bytes: 133 int recipient = LoRa.read(); // 134 recipient address 135 byte sender = LoRa.read(); // sender address 136 137 byte incomingMsgId = LoRa.read(); // incoming msg ID 138 byte incomingLength 139 = LoRa.read(); // incoming msg length 140 141 Serial.println("Received from: 142 0x" + String(sender, HEX)); 143 Serial.println("Sent to: 0x" + String(recipient, 144 HEX)); 145 Serial.println("Message ID: " + String(incomingMsgId)); 146 Serial.println("Message 147 length: " + String(incomingLength)); 148 Serial.println(); 149 150 incoming = 151 ""; 152 byte incomingData[20]; 153 int i=0; 154 155 if (sender != 0x2) { 156 157 while (LoRa.available()) { 158 incoming += (char)LoRa.read(); 159 } 160/* 161 if (incomingLength != incoming.length()) { // check length for error 162 Serial.println("error: 163 message length does not match length"); 164 return; // 165 skip rest of function 166 } */ 167 } 168 else { 169 Serial.println("We 170 are in the case of data rceiving"); 171 while (LoRa.available()) { 172 incomingData[i] 173 = LoRa.read(); 174 i++; 175 } 176 } 177 178 179 180 // if the recipient 181 isn't this device or broadcast, 182 if (recipient != localAddress && recipient 183 != 0xFF) { 184 Serial.println("This message is not for me."); 185 return; 186 // skip rest of function 187 } 188 189 if (sender 190 != 0x2) { 191 // if message is for this device, or broadcast, print details: 192 193 Serial.println("Received from: 0x" + String(sender, HEX)); 194 Serial.println("Sent 195 to: 0x" + String(recipient, HEX)); 196 Serial.println("Message ID: " + String(incomingMsgId)); 197 198 Serial.println("Message length: " + String(incomingLength)); 199 Serial.println("Message: 200 " + incoming); 201 Serial.println("RSSI: " + String(LoRa.packetRssi())); 202 203 Serial.println("Snr: " + String(LoRa.packetSnr())); 204 Serial.println(); 205 206 ciaoString = "Device " + String (sender,DEC) + ": " + incoming; 207 208 } 209 else { 210 humidity = ((incomingData[2] << 8) | incomingData[3]); 211 212 humidity = humidity/10; 213 temperature = ((incomingData[0] << 8) | incomingData[1]); 214 215 temperature = temperature/10; 216 rzero = ((incomingData[4] << 16) | incomingData[5] 217 << 8 | incomingData[6]); 218 rzero = rzero/100; 219 crzero = ((incomingData[7] 220 << 16) | incomingData[8] << 8 | incomingData[9]); 221 crzero = crzero/100; 222 223 resistance = ((incomingData[10] << 16) | incomingData[11] << 8 | incomingData[12]); 224 225 resistance = resistance/100; 226 ppm = ((incomingData[13] << 16) | incomingData[14] 227 << 8 | incomingData[15]); 228 ppm = ppm/100; 229 cppm = ((incomingData[16] 230 << 16) | incomingData[17] << 8 | incomingData[18]); 231 cppm = cppm/100; 232 233 Serial.println("Final Temperature: " + String (temperature)); 234 Serial.println("Final 235 Humidity: " + String (humidity)); 236 Serial.println("Final rzero: " + String 237 (rzero)); 238 Serial.println("Final crzero: " + String (crzero)); 239 Serial.println("Final 240 resistance: " + String (resistance)); 241 Serial.println("Final ppm: " + String 242 (ppm)); 243 Serial.println("Final cppm: " + String (cppm)); 244 } 245}
LoRaWK_Carlo.ino
arduino
This is the LoRa Node with Display, Buzzer and Push Button
1/* 2 LoRa Messaging with ESP32 3 4 This code send messages between 5 Devices. 6 7 created 19 06 2022 8 by Carlo Stramaglia 9*/ 10 11#include 12 <SPI.h> // include libraries 13#include <LoRa.h> 14#include <U8g2lib.h> 15#include 16 "OneButton.h" 17#include "messages.h" 18 19#ifdef U8X8_HAVE_HW_SPI 20#include 21 <SPI.h> 22#endif 23#ifdef U8X8_HAVE_HW_I2C 24#include <Wire.h> 25#endif 26 27U8G2_SSD1306_128X32_UNIVISION_F_SW_I2C 28 u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); 29 30#define 31 PIN_INPUT 15 // PIN for push button 32#define PIN_BUZ 4 // PIN for buzzer 33// 34 current Buzzer state, staring with LOW (0) 35int buzState = LOW; 36OneButton button(PIN_INPUT, 37 true); 38 39int exitFlag = 0; 40int stringNumber = -1; 41 42const int csPin 43 = 5; // LoRa radio chip select 44const int resetPin = 14; // LoRa 45 radio reset 46const int irqPin = 2; // change for your board; must be a 47 hardware interrupt pin 48 49String outgoing; // outgoing message 50 51byte 52 msgCount = 0; // count of outgoing messages 53byte localAddress = 0xBA; 54 // address of this device 55byte destination = 0xFF; // destination to 56 send to 57long lastSendTime = 0; // last send time 58int interval = 2000; 59 // interval between sends 60 61 62 63void setup() { 64 Serial.begin(9600); 65 // initialize serial 66 u8g2.begin(); 67 68 // enable the 69 buzzer 70 pinMode(PIN_BUZ, OUTPUT); // sets the digital pin as output 71 digitalWrite(PIN_BUZ, 72 buzState); // sets the buzzer in mute 73 74 // link the doubleclick function 75 to be called on a doubleclick event. 76 button.attachClick(Click); 77 button.attachLongPressStart(longPressStart); 78 79 80 // override the default CS, reset, and IRQ pins (optional) 81 LoRa.setPins(csPin, 82 resetPin, irqPin);// set CS, reset, IRQ pin 83 84 if (!LoRa.begin(868E6)) { // 85 initialize ratio at 868 MHz 86 Serial.println("LoRa init failed. Check your 87 connections."); 88 while (true); // if failed, do nothing 89 90 } 91 92 Serial.println("LoRa init succeeded."); 93} 94 95void loop() { 96 97 98 delay(10); 99 button.tick(); 100 // parse for a packet, and call onReceive 101 with the result: 102 onReceive(LoRa.parsePacket()); 103} 104 105void sendMessage(String 106 outgoing) { 107 LoRa.beginPacket(); // start packet 108 LoRa.write(destination); 109 // add destination address 110 LoRa.write(localAddress); // 111 add sender address 112 LoRa.write(msgCount); // add message ID 113 114 LoRa.write(outgoing.length()); // add payload length 115 LoRa.print(outgoing); 116 // add payload 117 LoRa.endPacket(); // finish 118 packet and send it 119 msgCount++; // increment message 120 ID 121} 122 123void onReceive(int packetSize) { 124 if (packetSize == 0) return; 125 // if there's no packet, return 126 127 // read packet header bytes: 128 129 int recipient = LoRa.read(); // recipient address 130 byte sender = 131 LoRa.read(); // sender address 132 byte incomingMsgId = LoRa.read(); 133 // incoming msg ID 134 byte incomingLength = LoRa.read(); // incoming msg 135 length 136 137 String incoming = ""; 138 139 while (LoRa.available()) { 140 141 incoming += (char)LoRa.read(); 142 } 143 144 if (incomingLength != incoming.length()) 145 { // check length for error 146 Serial.println("error: message length does 147 not match length"); 148 return; // skip rest of 149 function 150 } 151 152 153 154 // if the recipient isn't this device or broadcast, 155 156 if (recipient != localAddress && recipient != 0xFF) { 157 Serial.println("This 158 message is not for me."); 159 return; // skip rest 160 of function 161 } 162 163 // if message is for this device, or broadcast, print 164 details: 165 Serial.println("Received from: 0x" + String(sender, HEX)); 166 Serial.println("Sent 167 to: 0x" + String(recipient, HEX)); 168 Serial.println("Message ID: " + String(incomingMsgId)); 169 170 Serial.println("Message length: " + String(incomingLength)); 171 Serial.println("Message: 172 " + incoming); 173 Serial.println("RSSI: " + String(LoRa.packetRssi())); 174 175 Serial.println("Snr: " + String(LoRa.packetSnr())); 176 Serial.println(); 177 178 digitalWrite(PIN_BUZ, !buzState); 179 Serial.println("Buzzer ON"); 180 delay 181 (100); 182 digitalWrite(PIN_BUZ, buzState); 183 Serial.println("Buzzer OFF"); 184 185 sendDisplay(sender, incoming); 186} 187 188void sendDisplay(unsigned int nodeID, 189 String messageLoRa) { 190 char messageLocal[MAX_STRING_SIZE]; 191 u8g2.clearBuffer(); 192 193 u8g2.setFont(u8g2_font_ncenB08_tr); 194 if (nodeID == 1) 195 sprintf 196 (messageLocal, "Message From: Cloud"); 197 else 198 sprintf (messageLocal, 199 "Message From: %d", nodeID); 200 u8g2.drawStr(0,10, messageLocal); 201 messageLoRa.toCharArray(messageLocal, 202 MAX_STRING_SIZE); 203 u8g2.drawStr(0,30, messageLocal); 204 u8g2.sendBuffer(); 205 206 delay(1000); 207} 208 209 210void Click() 211{ 212 Serial.println("x1"); 213 214 stringNumber++; 215 if (stringNumber > (NUMBER_OF_STRING-1)) 216 stringNumber 217 = 0; 218 displayString (stringNumber+1, arr[stringNumber]); 219 220 exitFlag 221 = 0; 222 223} // Click 224 225void longPressStart() 226{ 227 Serial.println("Long"); 228 229 displaySend (stringNumber+1, arr[stringNumber]); 230 // Send data to the node 231 232 //LoRaNow.clear(); 233 sendMessage(arr[stringNumber]); 234 exitFlag = 1; 235 236 237} // LongPressStart 238 239 240void displayString (unsigned int stringNo, char* 241 stringToDisplay) { 242 char messageLocal[MAX_STRING_SIZE]; 243 u8g2.clearBuffer(); 244 245 u8g2.setFont(u8g2_font_ncenB08_tr); 246 sprintf (messageLocal, 247 "Destination: %d", destination); 248 u8g2.drawStr(0,10, messageLocal); 249 250 sprintf (messageLocal, "Text selection: %d of %d", stringNo, NUMBER_OF_STRING); 251 252 u8g2.drawStr(0,20, messageLocal); 253 u8g2.drawStr(0,30, stringToDisplay); 254 255 u8g2.sendBuffer(); 256 delay(100); 257} 258 259void displaySend 260 (unsigned int stringNo, char* stringToDisplay) { 261 char messageLocal[MAX_STRING_SIZE]; 262 263 u8g2.clearBuffer(); 264 u8g2.setFont(u8g2_font_ncenB08_tr); 265 sprintf 266 (messageLocal, "Destination: %d", destination); 267 u8g2.drawStr(0,10, messageLocal); 268 269 sprintf (messageLocal, "Sending Message: %d of %d", stringNo, NUMBER_OF_STRING); 270 271 u8g2.drawStr(0,20, messageLocal); 272 u8g2.drawStr(0,30, stringToDisplay); 273 274 u8g2.sendBuffer(); 275 delay(100); 276} 277
LoRa_Temperature_and_Air_Node.ino
arduino
1/* 2 LoRa Temperature and Air Node. 3 4 This code send Temperature and MQ135 data to a Gateway for Arduino IOT data collection. 5 6 created 25 07 2022 7 by Carlo Stramaglia 8*/ 9 10#include <SPI.h> // include libraries 11#include <LoRa.h> 12#include <MQ135.h> 13#include <DHT.h> 14 15const int csPin = 10; // LoRa radio chip select 16const int resetPin = 7; // LoRa radio reset 17const int irqPin = 4; // change for your board; must be a hardware interrupt pin 18 19String outgoing; // outgoing message 20 21byte msgCount = 0; // count of outgoing messages 22byte localAddress = 0x02; // address of this device 23byte destination = 0x01; // destination to send to 24 25int Temperature = 0; // Temperature Integer 26int Humidity = 0; // Humidity Integer 27int Rzero = 0; 28int cRzero = 0; 29int Resistance = 0; 30int Ppm = 0; 31int Cppm = 0; 32 33int payloadLenght = 19; 34byte Data[19]; 35 36#define PIN_MQ135 A0 // MQ135 Analog Input Pin 37#define DHTPIN 3 // DHT Digital Input Pin 38#define DHTTYPE DHT22 // DHT11 or DHT22, depends on your sensor 39 40MQ135 mq135_sensor(PIN_MQ135); 41DHT dht(DHTPIN, DHTTYPE); 42 43float temperature, humidity; // Temp and Humid floats, will be measured by the DHT 44 45void setup() { 46 Serial.begin(9600); // initialize serial 47 dht.begin(); 48 delay (1000); 49 50 // override the default CS, reset, and IRQ pins (optional) 51 LoRa.setPins(csPin, resetPin, irqPin);// set CS, reset, IRQ pin 52 53 if (!LoRa.begin(868E6)) { // initialize ratio at 868 MHz 54 Serial.println("LoRa init failed. Check your connections."); 55 while (true); // if failed, do nothing 56 } 57 58 Serial.println("LoRa init succeeded."); 59} 60 61void loop() { 62 63 delay(4000); 64 65 humidity = dht.readHumidity(); 66 temperature = dht.readTemperature(); 67 68 // Check if any reads failed and exit early (to try again). 69 if (isnan(humidity) || isnan(temperature)) { 70 Serial.println(F("Failed to read from DHT sensor!")); 71 return; 72 } 73 74 float rzero = mq135_sensor.getRZero(); 75 float correctedRZero = mq135_sensor.getCorrectedRZero(temperature, humidity); 76 float resistance = mq135_sensor.getResistance(); 77 float ppm = mq135_sensor.getPPM(); 78 float correctedPPM = mq135_sensor.getCorrectedPPM(temperature, humidity); 79 80 Serial.print("MQ135 RZero: "); 81 Serial.print(rzero); 82 Serial.print("\ Corrected RZero: "); 83 Serial.print(correctedRZero); 84 Serial.print("\ Resistance: "); 85 Serial.print(resistance); 86 Serial.print("\ PPM: "); 87 Serial.print(ppm); 88 Serial.print("ppm"); 89 Serial.print("\ Corrected PPM: "); 90 Serial.print(correctedPPM); 91 Serial.println("ppm"); 92 Serial.println("Temperature and Humidity before the calculation"); 93 Serial.print(temperature); 94 Serial.print(" "); 95 Serial.println(humidity); 96 97 Temperature = int (temperature*10); 98 Humidity = int (humidity*10); 99 Rzero = int (rzero*100); 100 cRzero = int (correctedRZero*100); 101 Resistance = int (resistance*100); 102 Ppm = int(ppm*100); 103 Cppm = int (correctedPPM*100); 104 // prepare and schedule data for transmission 105 Data[0] = Temperature >> 8; 106 Data[1] = Temperature; 107 Data[2] = Humidity >> 8; 108 Data[3] = Humidity; 109 Data[4] = Rzero >> 16; 110 Data[5] = Rzero >> 8; 111 Data[6] = Rzero; 112 Data[7] = cRzero >> 16; 113 Data[8] = cRzero >> 8; 114 Data[9] = cRzero; 115 Data[10] = Resistance >> 16; 116 Data[11] = Resistance >> 8; 117 Data[12] = Resistance; 118 Data[13] = Ppm >> 16; 119 Data[14] = Ppm >> 8; 120 Data[15] = Ppm; 121 Data[16] = Cppm >> 16; 122 Data[17] = Cppm >> 8; 123 Data[18] = Cppm; 124 //Data[0] = 0xa; 125 //Data[1] = 0xb; 126 //Data[2] = 0xc; 127 //Data[3] = 0xd; 128 Serial.println("Data of Temp and Hum after manipulation"); 129 Serial.println(Temperature); 130 Serial.println(Humidity); 131 //Serial.println(Data[2],DEC); 132 //Serial.println(Data[3],DEC); 133 134 sendMessage(Data); 135} 136 137void sendMessage(byte* outgoing) { 138 LoRa.beginPacket(); // start packet 139 LoRa.write(destination); // add destination address 140 LoRa.write(localAddress); // add sender address 141 LoRa.write(msgCount); // add message ID 142 //LoRa.write(outgoing.length()); // add payload length 143 LoRa.write(payloadLenght); // add payload length 144 LoRa.write(outgoing, payloadLenght); // add payload 145 LoRa.endPacket(); // finish packet and send it 146 msgCount++; // increment message ID 147} 148
messages.h
arduino
Pre-Defined messages inlude file.
1#define NUMBER_OF_STRING 4 2#define MAX_STRING_SIZE 40 3 4char arr[NUMBER_OF_STRING][MAX_STRING_SIZE] = 5{ "Get on the phone!", 6 "The music is too loud", 7 "I'm ready to move", 8 "See you at 10:00 AM" 9}; 10
thingProperties.h
arduino
1// Code generated by Arduino IoT Cloud, DO NOT EDIT. 2 3#include <ArduinoIoTCloud.h> 4#include 5 <Arduino_ConnectionHandler.h> 6 7const char DEVICE_LOGIN_NAME[] = "TO BE REPLACED 8 WITH YOUR DATA"; 9 10const char SSID[] = "TO BE REPLACED WITH 11 YOUR DATA"; // Network SSID (name) 12const char PASS[] = "TO 13 BE REPLACED WITH YOUR DATA"; // Network password (use for WPA, or use as key 14 for WEP) 15const char DEVICE_KEY[] = "TO BE REPLACED WITH YOUR DATA"; // 16 Secret device password 17 18void onCiaoStringChange(); 19 20String ciaoString; 21float 22 cppm; 23float crzero; 24float ppm; 25float resistance; 26float rzero; 27CloudTemperatureSensor 28 temperature; 29CloudRelativeHumidity humidity; 30 31void initProperties(){ 32 33 34 ArduinoCloud.setBoardId(DEVICE_LOGIN_NAME); 35 ArduinoCloud.setSecretDeviceKey(DEVICE_KEY); 36 37 ArduinoCloud.addProperty(ciaoString, READWRITE, ON_CHANGE, onCiaoStringChange); 38 39 ArduinoCloud.addProperty(cppm, READ, ON_CHANGE, NULL); 40 ArduinoCloud.addProperty(crzero, 41 READ, ON_CHANGE, NULL); 42 ArduinoCloud.addProperty(ppm, READ, ON_CHANGE, NULL); 43 44 ArduinoCloud.addProperty(resistance, READ, ON_CHANGE, NULL); 45 ArduinoCloud.addProperty(rzero, 46 READ, ON_CHANGE, NULL); 47 ArduinoCloud.addProperty(temperature, READ, ON_CHANGE, 48 NULL); 49 ArduinoCloud.addProperty(humidity, READ, ON_CHANGE, NULL); 50 51} 52 53WiFiConnectionHandler 54 ArduinoIoTPreferredConnection(SSID, PASS);
Downloadable files
Arduino Mini Pro loRa node
Arduino Mini Pro loRa node
ESP32 LoRa Node with Display, Buzzer and push button
ESP32 LoRa Node with Display, Buzzer and push button
ESP32 LoRa Arduino IOT Gateway
ESP32 LoRa Arduino IOT Gateway
ESP32 LoRa Arduino IOT Gateway
ESP32 LoRa Arduino IOT Gateway
Arduino Mini Pro loRa node
Arduino Mini Pro loRa node
ESP32 LoRa Node with Display, Buzzer and push button
ESP32 LoRa Node with Display, Buzzer and push button
Comments
Only logged in users can leave comments
essarts-le-roi
10 months ago
Hi. Very Nice project. May I have few questions ? 1) do you configure the Lora nodes on the Arduino IoT Cloud portal ? If yes, the boards are déclaré as Lora nodes or as ESP board (so Wi-Fi ?) 2) do you use the Arduino IDE soft or Arduino IoT Cloud to compile and download the sketches ? 3) do you think that I could use the TTGO ESP32 Lora with boards for the remote and the gateway ? 4) do you know how many "remote" ESP32 boards can Be connectés on the sale ESP32 gateway ? Thanks and vert Best Regards.