[LORA] Add water counter sensor with example (#1941)
* Add water counter example
This commit is contained in:
1 parent
b5e0223602
commit
bae4364e41
5 files changed
+427
-2
No files matched your search
@@ -0,0 +1,184 @@
|
|||||||
|
#include <LoRa.h>
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#include <Wire.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <Adafruit_Sensor.h>
|
||||||
|
#include <DHT.h>
|
||||||
|
#include <DHT_U.h>
|
||||||
|
|
||||||
|
#include "SSD1306.h"
|
||||||
|
|
||||||
|
//LoRa pins
|
||||||
|
#define SCK 5 // GPIO5 -- SX1278's SCK
|
||||||
|
#define MISO 19 // GPIO19 -- SX1278's MISnO
|
||||||
|
#define MOSI 27 // GPIO27 -- SX1278's MOSI
|
||||||
|
#define SS 18 // GPIO18 -- SX1278's CS
|
||||||
|
#define RST 23 // GPIO14 -- SX1278's RESET
|
||||||
|
#define DI0 26 // GPIO26 -- SX1278's IRQ(Interrupt Request)
|
||||||
|
#define BAND 433E6
|
||||||
|
|
||||||
|
//OLED pins
|
||||||
|
#define OLED_SDA 21
|
||||||
|
#define OLED_SCL 22
|
||||||
|
//#define OLED_RST 16
|
||||||
|
|
||||||
|
#define LED 25
|
||||||
|
|
||||||
|
#define DHT_PIN 14
|
||||||
|
#define DHT_TYPE DHT22
|
||||||
|
|
||||||
|
#define CNT_PIN 34
|
||||||
|
|
||||||
|
#define BAT_PIN 35
|
||||||
|
|
||||||
|
const int MAX_ANALOG_VAL = 4095;
|
||||||
|
const float MAX_BATTERY_VOLTAGE = 4.2;
|
||||||
|
|
||||||
|
int cntpkt = 0;
|
||||||
|
unsigned long counter = 0;
|
||||||
|
unsigned long last_interrupt_time = 0;
|
||||||
|
int pulse_seen = 0; // pulse detected by interrupt function
|
||||||
|
int bounce_delay_ms = 100;
|
||||||
|
|
||||||
|
SSD1306 display(0x3c, OLED_SDA, OLED_SCL);
|
||||||
|
String rssi = "RSSI --";
|
||||||
|
String packSize = "--";
|
||||||
|
String packet;
|
||||||
|
|
||||||
|
DHT_Unified dht(DHT_PIN, DHT_TYPE); //Inizializza oggetto chiamato "dht", parametri: pin a cui è connesso il sensore, tipo di dht 11/22
|
||||||
|
|
||||||
|
void ICACHE_RAM_ATTR bounceCheck ();
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
pinMode(LED, OUTPUT);
|
||||||
|
|
||||||
|
//pinMode(OLED_RST, OUTPUT);
|
||||||
|
//digitalWrite(OLED_RST, LOW); // set GPIO16 low to reset OLED
|
||||||
|
//delay(50);
|
||||||
|
//digitalWrite(OLED_RST, HIGH); // while OLED is running, must set GPIO16 in high
|
||||||
|
|
||||||
|
Serial.begin(115200);
|
||||||
|
while (!Serial);
|
||||||
|
Serial.println();
|
||||||
|
Serial.println("LoRa Sender Test");
|
||||||
|
|
||||||
|
SPI.begin(SCK, MISO, MOSI, SS);
|
||||||
|
LoRa.setPins(SS, RST, DI0);
|
||||||
|
if (!LoRa.begin(BAND)) {
|
||||||
|
Serial.println("Starting LoRa failed!");
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println("init ok");
|
||||||
|
display.init();
|
||||||
|
display.flipScreenVertically();
|
||||||
|
display.setFont(ArialMT_Plain_10);
|
||||||
|
|
||||||
|
pinMode(BAT_PIN, INPUT);
|
||||||
|
pinMode(CNT_PIN, INPUT_PULLUP);
|
||||||
|
|
||||||
|
attachInterrupt (CNT_PIN, bounceCheck, RISING);
|
||||||
|
|
||||||
|
dht.begin();
|
||||||
|
sensor_t sensor;
|
||||||
|
dht.temperature().getSensor(&sensor);
|
||||||
|
Serial.println(F("------------------------------------"));
|
||||||
|
Serial.println(F("Temperature Sensor"));
|
||||||
|
Serial.print (F("Sensor Type: ")); Serial.println(sensor.name);
|
||||||
|
Serial.print (F("Driver Ver: ")); Serial.println(sensor.version);
|
||||||
|
Serial.print (F("Unique ID: ")); Serial.println(sensor.sensor_id);
|
||||||
|
Serial.print (F("Max Value: ")); Serial.print(sensor.max_value); Serial.println(F("°C"));
|
||||||
|
Serial.print (F("Min Value: ")); Serial.print(sensor.min_value); Serial.println(F("°C"));
|
||||||
|
Serial.print (F("Resolution: ")); Serial.print(sensor.resolution); Serial.println(F("°C"));
|
||||||
|
Serial.println(F("------------------------------------"));
|
||||||
|
// Print humidity sensor details.
|
||||||
|
dht.humidity().getSensor(&sensor);
|
||||||
|
Serial.println(F("Humidity Sensor"));
|
||||||
|
Serial.print (F("Sensor Type: ")); Serial.println(sensor.name);
|
||||||
|
Serial.print (F("Driver Ver: ")); Serial.println(sensor.version);
|
||||||
|
Serial.print (F("Unique ID: ")); Serial.println(sensor.sensor_id);
|
||||||
|
Serial.print (F("Max Value: ")); Serial.print(sensor.max_value); Serial.println(F("%"));
|
||||||
|
Serial.print (F("Min Value: ")); Serial.print(sensor.min_value); Serial.println(F("%"));
|
||||||
|
Serial.print (F("Resolution: ")); Serial.print(sensor.resolution); Serial.println(F("%"));
|
||||||
|
Serial.println(F("------------------------------------"));
|
||||||
|
|
||||||
|
delay(1500);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
sensors_event_t event1, event2;
|
||||||
|
|
||||||
|
display.clear();
|
||||||
|
display.setTextAlignment(TEXT_ALIGN_LEFT);
|
||||||
|
display.setFont(ArialMT_Plain_10);
|
||||||
|
|
||||||
|
display.drawString(0, 0, "Sending packet: ");
|
||||||
|
display.drawString(90, 0, String(cntpkt));
|
||||||
|
|
||||||
|
String NodeId = WiFi.macAddress();
|
||||||
|
// float temp = dht.readTemperature();
|
||||||
|
// float hum = dht.readHumidity();
|
||||||
|
float battery = getBattery();
|
||||||
|
|
||||||
|
dht.temperature().getEvent(&event1);
|
||||||
|
if (isnan(event1.temperature)) {
|
||||||
|
Serial.println(F("Error reading temperature!"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Serial.print(F("Temperature: "));
|
||||||
|
Serial.print(event1.temperature);
|
||||||
|
Serial.println(F("°C"));
|
||||||
|
}
|
||||||
|
// Get humidity event and print its value.
|
||||||
|
dht.humidity().getEvent(&event2);
|
||||||
|
if (isnan(event2.relative_humidity)) {
|
||||||
|
Serial.println(F("Error reading humidity!"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Serial.print(F("Humidity: "));
|
||||||
|
Serial.print(event2.relative_humidity);
|
||||||
|
Serial.println(F("%"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// send packet
|
||||||
|
LoRa.beginPacket();
|
||||||
|
|
||||||
|
String msg = "{\"model\":\"ESP32CNT\",\"id\":\"" + NodeId + "\",\"count\":\"" + String(counter) + "\",\"tempc\":\"" + String(event1.temperature) + "\",\"hum\":\"" + String(event2.relative_humidity) + "\",\"batt\":\"" + String(battery) + "\"}";
|
||||||
|
// Send json string
|
||||||
|
LoRa.print(msg);
|
||||||
|
LoRa.endPacket();
|
||||||
|
|
||||||
|
Serial.println(msg);
|
||||||
|
|
||||||
|
display.drawString(0, 15, String(NodeId));
|
||||||
|
display.drawString(0, 30, "count: " + String(counter));
|
||||||
|
display.drawString(0, 45, "battery: " + String(battery)+ " %");
|
||||||
|
display.display();
|
||||||
|
|
||||||
|
delay(5000);
|
||||||
|
|
||||||
|
cntpkt++;
|
||||||
|
|
||||||
|
digitalWrite(LED, HIGH); // turn the LED on (HIGH is the voltage level)
|
||||||
|
delay(1000); // wait for a second
|
||||||
|
digitalWrite(LED, LOW); // turn the LED off by making the voltage LOW
|
||||||
|
//delay(60000); // wait for 60 seconds
|
||||||
|
delay(6000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ICACHE_RAM_ATTR bounceCheck (){
|
||||||
|
unsigned long interrupt_time = millis();
|
||||||
|
if (interrupt_time - last_interrupt_time > bounce_delay_ms) counter++; // void loop() then notes pulse == 1 and takes action
|
||||||
|
last_interrupt_time = interrupt_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
float getBattery(void) {
|
||||||
|
int rawValue = analogRead(BAT_PIN);
|
||||||
|
|
||||||
|
float voltageLevel = (rawValue / 4095.0) * 2 * 1.1 * 3.3; // calculate voltage level
|
||||||
|
float perc = voltageLevel / MAX_BATTERY_VOLTAGE * 100;
|
||||||
|
|
||||||
|
return(perc);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
# OpenMQTTGateway LoRa Node Example
|
||||||
|
This repository contains an example of a LoRa node program designed for the ESP32 platform.
|
||||||
|
The program reads the DHT22 temperature and humidity, the battery level and water consumption via reed switch, packages the data into a JSON format, and sends it over LoRa.
|
||||||
|
|
||||||
|
## Features:
|
||||||
|
* Uses an SX12XX LoRa module.
|
||||||
|
* Displays packet sending status, counter and battery level data on an SSD1306 OLED display.
|
||||||
|
* Sends the ESP32's MAC address as the node ID.
|
||||||
|
* Sends temperature data in Celsius.
|
||||||
|
|
||||||
|
## Hardware Requirements:
|
||||||
|
* ESP32 development board.
|
||||||
|
* SX12XX LoRa module.
|
||||||
|
* SSD1306 OLED display.
|
||||||
|
|
||||||
|
## Pin Configuration: (Lilygo LoRa32 V2.1_1.6)
|
||||||
|
* SCK - GPIO5
|
||||||
|
* MISO - GPIO19
|
||||||
|
* MOSI - GPIO27
|
||||||
|
* SS - GPIO18
|
||||||
|
* RST - GPIO23
|
||||||
|
* DI0 - GPIO26
|
||||||
|
|
||||||
|
## Setup:
|
||||||
|
### Hardware Setup:
|
||||||
|
|
||||||
|
Connect the SX1278 LoRa module and the SSD1306 OLED display to the ESP32 according to the pin configuration.
|
||||||
|
Ensure that the OLED display is powered correctly.
|
||||||
|
|
||||||
|
### Software Setup:
|
||||||
|
|
||||||
|
* Clone this repository.
|
||||||
|
* Open the provided node program with PlatformIO
|
||||||
|
* Upload the program to your ESP32.
|
||||||
|
|
||||||
|
## Usage:
|
||||||
|
Power on the ESP32.
|
||||||
|
The OLED display will show the status of the packet being sent and the current temperature reading.
|
||||||
|
The built-in LED on the ESP32 will blink once every time a packet is sent.
|
||||||
|
Monitor the serial output (at 115200 baud rate) to see the JSON formatted data being sent.
|
||||||
|
|
||||||
|
If you use arduino load ino file.
|
||||||
|
|
||||||
|
## Data Format:
|
||||||
|
The data is sent in the following JSON format:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"model": "ESP32CNT",
|
||||||
|
"id": "ESP32_MAC_ADDRESS",
|
||||||
|
"count": "COUNTER_IN_LITER",
|
||||||
|
"tempc": "TEMPERATURE_IN_CELSIUS",
|
||||||
|
"hum": "HUMIDITY_IN_PERCENTAGE",
|
||||||
|
"batt": "BATTERY_IN_PERCENTAGE"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting:
|
||||||
|
LoRa Initialization Failed: Ensure that the SX1278 LoRa module is connected correctly and powered on.
|
||||||
|
OLED Display Not Working: Check the connections and ensure that the display is powered correctly.
|
||||||
|
No Temperature Data: Ensure that the ESP32's internal temperature sensor is functional.
|
||||||
|
Contributing:
|
||||||
|
Feel free to contribute to this example by opening issues or submitting pull requests. Any feedback or improvements are welcome!
|
||||||
|
|
||||||
|
I hope this README helps users understand and use your program! Adjustments can be made as necessary to fit any additional details or changes.
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
; PlatformIO Project Configuration File
|
||||||
|
;
|
||||||
|
; Build options: build flags, source filter
|
||||||
|
; Upload options: custom upload port, speed and extra flags
|
||||||
|
; Library options: dependencies, extra library storages
|
||||||
|
; Advanced options: extra scripting
|
||||||
|
;
|
||||||
|
; Please visit documentation for the other options and examples
|
||||||
|
; https://docs.platformio.org/page/projectconf.html
|
||||||
|
|
||||||
|
[env:ttgo-lora32-v1]
|
||||||
|
platform = espressif32
|
||||||
|
board = ttgo-lora32-v1
|
||||||
|
framework = arduino
|
||||||
|
lib_deps =
|
||||||
|
https://github.com/sandeepmistry/arduino-LoRa.git#f4a1d27
|
||||||
|
https://github.com/ThingPulse/esp8266-oled-ssd1306.git#f96fd6a
|
||||||
|
monitor_speed = 115200
|
||||||
|
|
||||||
|
[env:ttgo-lora32-v21]
|
||||||
|
platform = espressif32
|
||||||
|
board = ttgo-lora32-v21
|
||||||
|
framework = arduino
|
||||||
|
lib_deps =
|
||||||
|
https://github.com/sandeepmistry/arduino-LoRa.git#f4a1d27
|
||||||
|
https://github.com/ThingPulse/esp8266-oled-ssd1306.git#f96fd6a
|
||||||
|
monitor_speed = 115200
|
||||||
|
|
||||||
|
[env:heltec-wifi-lora-32] ; Heltec ESP32 Board with SSD1306 display
|
||||||
|
platform = espressif32
|
||||||
|
board = heltec_wifi_lora_32
|
||||||
|
framework = arduino
|
||||||
|
lib_deps =
|
||||||
|
https://github.com/sandeepmistry/arduino-LoRa.git#f4a1d27
|
||||||
|
https://github.com/ThingPulse/esp8266-oled-ssd1306.git#f96fd6a
|
||||||
|
monitor_speed = 115200
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
#include <LoRa.h>
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#include <Wire.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "SSD1306.h"
|
||||||
|
#include "rom/ets_sys.h"
|
||||||
|
#include "soc/rtc_cntl_reg.h"
|
||||||
|
#include "soc/sens_reg.h"
|
||||||
|
|
||||||
|
#define SCK 5 // GPIO5 -- SX1278's SCK
|
||||||
|
#define MISO 19 // GPIO19 -- SX1278's MISnO
|
||||||
|
#define MOSI 27 // GPIO27 -- SX1278's MOSI
|
||||||
|
#define SS 18 // GPIO18 -- SX1278's CS
|
||||||
|
#define RST 23 // GPIO23 -- SX1278's RESET
|
||||||
|
#define DI0 26 // GPIO26 -- SX1278's IRQ(Interrupt Request)
|
||||||
|
#define BAND 433E6
|
||||||
|
|
||||||
|
//OLED pins
|
||||||
|
#define OLED_SDA 21
|
||||||
|
#define OLED_SCL 22
|
||||||
|
//#define OLED_RST 16
|
||||||
|
|
||||||
|
#define LED 25
|
||||||
|
|
||||||
|
#define DHT_PIN 12
|
||||||
|
#define DHT_TYPE DHT22
|
||||||
|
|
||||||
|
#define CNT_PIN 34
|
||||||
|
|
||||||
|
#define BAT_PIN 35
|
||||||
|
|
||||||
|
const int MAX_ANALOG_VAL = 4095;
|
||||||
|
const float MAX_BATTERY_VOLTAGE = 4.2;
|
||||||
|
|
||||||
|
int cntpkt = 0;
|
||||||
|
unsigned long counter = 0;
|
||||||
|
unsigned long last_interrupt_time = 0;
|
||||||
|
int pulse_seen = 0; // pulse detected by interrupt function
|
||||||
|
int bounce_delay_ms = 100;
|
||||||
|
|
||||||
|
SSD1306 display(0x3c, OLED_SDA, OLED_SCL);
|
||||||
|
String rssi = "RSSI --";
|
||||||
|
String packSize = "--";
|
||||||
|
String packet;
|
||||||
|
|
||||||
|
DHT dht(DHT_PIN, DHT_TYPE); //Inizializza oggetto chiamato "dht", parametri: pin a cui è connesso il sensore, tipo di dht 11/22
|
||||||
|
|
||||||
|
void ICACHE_RAM_ATTR bounceCheck ();
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
pinMode(LED, OUTPUT);
|
||||||
|
|
||||||
|
//pinMode(OLED_RST, OUTPUT);
|
||||||
|
//digitalWrite(OLED_RST, LOW); // set GPIO16 low to reset OLED
|
||||||
|
//delay(50);
|
||||||
|
//digitalWrite(OLED_RST, HIGH); // while OLED is running, must set GPIO16 in high
|
||||||
|
|
||||||
|
Serial.begin(115200);
|
||||||
|
while (!Serial);
|
||||||
|
Serial.println();
|
||||||
|
Serial.println("LoRa Sender Test");
|
||||||
|
|
||||||
|
SPI.begin(SCK, MISO, MOSI, SS);
|
||||||
|
LoRa.setPins(SS, RST, DI0);
|
||||||
|
if (!LoRa.begin(BAND)) {
|
||||||
|
Serial.println("Starting LoRa failed!");
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println("init ok");
|
||||||
|
display.init();
|
||||||
|
display.flipScreenVertically();
|
||||||
|
display.setFont(ArialMT_Plain_10);
|
||||||
|
|
||||||
|
pinMode(BAT_PIN, INPUT);
|
||||||
|
pinMode(CNT_PIN, INPUT_PULLUP);
|
||||||
|
|
||||||
|
attachInterrupt (CNT_PIN, bounceCheck, RISING);
|
||||||
|
|
||||||
|
delay(1500);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
display.clear();
|
||||||
|
display.setTextAlignment(TEXT_ALIGN_LEFT);
|
||||||
|
display.setFont(ArialMT_Plain_10);
|
||||||
|
|
||||||
|
display.drawString(0, 0, "Sending packet: ");
|
||||||
|
display.drawString(90, 0, String(cntpkt));
|
||||||
|
|
||||||
|
String NodeId = WiFi.macAddress();
|
||||||
|
float temp = dht.readTemperature();
|
||||||
|
float hum = dht.readHumidity();
|
||||||
|
float battery = getBattery();
|
||||||
|
// send packet
|
||||||
|
LoRa.beginPacket();
|
||||||
|
// Build json string to send
|
||||||
|
//per test rimuovere
|
||||||
|
|
||||||
|
String msg = "{\"model\":\"ESP32CNT\",\"id\":\"" + NodeId + "\",\"count\":\"" + String(counter) + "\",\"tempc\":\"" + String(temp) + "\",\"hum\":\"" + String(hum) + "\",\"batt\":\"" + String(battery) + "\"}";
|
||||||
|
// Send json string
|
||||||
|
LoRa.print(msg);
|
||||||
|
LoRa.endPacket();
|
||||||
|
|
||||||
|
Serial.println(msg);
|
||||||
|
|
||||||
|
display.drawString(0, 15, String(NodeId));
|
||||||
|
display.drawString(0, 30, "count: " + String(counter));
|
||||||
|
display.drawString(0, 45, "battery: " + String(battery)+ " %");
|
||||||
|
display.display();
|
||||||
|
|
||||||
|
delay(5000);
|
||||||
|
|
||||||
|
cntpkt++;
|
||||||
|
|
||||||
|
digitalWrite(LED, HIGH); // turn the LED on (HIGH is the voltage level)
|
||||||
|
delay(1000); // wait for a second
|
||||||
|
digitalWrite(LED, LOW); // turn the LED off by making the voltage LOW
|
||||||
|
delay(60000); // wait for 60 seconds
|
||||||
|
}
|
||||||
|
|
||||||
|
void ICACHE_RAM_ATTR bounceCheck (){
|
||||||
|
unsigned long interrupt_time = millis();
|
||||||
|
if (interrupt_time - last_interrupt_time > bounce_delay_ms) counter++; // void loop() then notes pulse == 1 and takes action
|
||||||
|
last_interrupt_time = interrupt_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
float getBattery(void) {
|
||||||
|
int rawValue = analogRead(BAT_PIN);
|
||||||
|
|
||||||
|
float voltageLevel = (rawValue / 4095.0) * 2 * 1.1 * 3.3; // calculate voltage level
|
||||||
|
float perc = voltageLevel / MAX_BATTERY_VOLTAGE * 100;
|
||||||
|
|
||||||
|
return(perc);
|
||||||
|
}
|
||||||
|
|
||||||
+4
-2
@@ -125,11 +125,13 @@ struct LORAdevice {
|
|||||||
bool isDisc;
|
bool isDisc;
|
||||||
};
|
};
|
||||||
|
|
||||||
const char LORAparameters[3][4][12] = {
|
const char LORAparameters[5][4][12] = {
|
||||||
// LORA key, name, unit, device_class
|
// LORA key, name, unit, device_class
|
||||||
{"tempc", "temperature", "°C", "temperature"},
|
{"tempc", "temperature", "°C", "temperature"},
|
||||||
{"hum", "humidity", "%", "humidity"},
|
{"hum", "humidity", "%", "humidity"},
|
||||||
{"moi", "moisture", "%", "humidity"}};
|
{"moi", "moisture", "%", "humidity"},
|
||||||
|
{"batt", "battery", "%", "battery"},
|
||||||
|
{"count", "counter", "L", "water"}};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user