Tomas UrbanavičiusVilma Vanagiene
Published © GPL3+

Smart Energy Efficiency and Air Quality Monitoring System

Smart Energy Efficiency and Air Quality Monitoring System

IntermediateProtip4 hours4
Smart Energy Efficiency and Air Quality Monitoring System

Things used in this project

Hardware components

WisGate Edge Lite 2
Arduino WisGate Edge Lite 2
×1
Board RAK19001 Dual I/O
×1
Core RAK4631 Nordic nRF52840
×1
WisBlock Environmental Sensor RAK1906
RAKwireless WisBlock Environmental Sensor RAK1906
×1
Sensor RAK12004 MQ2
×1
LoRa Antenna 863-870MHz
×1

Software apps and online services

Arduino IDE
Arduino IDE
The Things Stack
The Things Industries The Things Stack

Hand tools and fabrication machines

Multitool, Screwdriver
Multitool, Screwdriver

Story

Read more

Code

Gas detector

C/C++
// 1. LOARAWAN IR BAZINĖS BIBLIOTEKOS
#include <WisBlock-API-V2.h>
#include <CayenneLPP.h>
#include <LoRaWan-Arduino.h>
#include <Wire.h>
// PRIVALOMA: Rankiniu būdu apibrėžiame TIK tas konstantes, kurios vis dar nerandamos
#define LMH_SUCCESS 0
#define LMH_APL_SET 1 // Prisijungimo sėkmė
// Minimali lmh_evt_t struktūra (paliekama, nes naudojama callback'uose)
typedef struct {
uint8_t type;
struct {
uint8_t join_result;
struct {
int16_t rssi;
int8_t snr;
} send_confirm;
} params;
} lmh_evt_t;
// Event konstantos
#define LMH_EVT_JOINED 0
#define LMH_EVT_SEND_CONFIRMED 1
#define LMH_EVT_SEND_UNCONFIRMED 2
// 2. JUTIKLIŲ BIBLIOTEKOS
#include <Adafruit_BME680.h>
#include <bsec.h>
// ---------------------- LOARAWAN NUSTATYMAI ----------------------
#define LORAWAN_APP_PORT 2
#define LORAWAN_SEND_CYCLE 300000
time_t next_send_time = 0;
bool is_joined = false;
// RAK LoRaWAN raktų konfigūracija
uint8_t nodeDeviceEUI[8] = {0xAC, 0x1F, 0x09, 0xFF, 0xFE, 0x05, 0x8C, 0x66};
uint8_t nodeAppEUI[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t nodeAppKey[16] = {0x33, 0xCC, 0x98, 0x22, 0xCD, 0xAB, 0x67, 0x00, 0x68, 0x27, 0x8F, 0xC3, 0x01, 0x33, 0x24, 0xEE};
// ---------------------- JUTIKLIŲ OBJEKTAI IR KINTAMIEJI ----------------------
Adafruit_BME680 bme680;
Bsec iaqSensor;
#define MQ2_I2C_ADDR 0x04
float mq2_raw_value = 0.0;
float temperature = 0.0;
float humidity = 0.0;
float pressure = 0.0;
float iaq = 0.0;
// ---------------------- TRŪKSTAMOS API FUNKCIJOS DEKLARAVIMAS ----------------------
void setup_app(void);
bool init_app(void); // PATAISYTA: pakeista iš 'void' į 'bool'
void app_event_handler(void);
void lora_data_handler(void);
// Kintamasis, kurio reikalauja BLE modulis (net jei nenaudojamas)
char g_ble_dev_name[10] = "IEEOKS_GW";
// ---------------------- SENOSIOS FUNKCIJOS DEKLARAVIMAS ----------------------
void getBME680Data(void);
void getMQ2Data(void);
void send_lora_data(void);
void user_init_lora(void);
void callback_lora_event(lmh_evt_t *evt);
// CALLBACK FUNKCIJŲ DEKLARAVIMAS
uint8_t join_callback(void);
void send_done_callback(uint8_t *evt);
uint32_t receive_data_callback(void);
void confirm_callback(lmh_app_data_t *app_data);
void tx_needed_callback(void);
// ---------------------- WISBLOCK API IMPLEMENTACIJA ----------------------
// 1. Kviečiama RAK setup() metu
void setup_app(void) {
// Čia atliekame Serijinės jungties ir I2C inicializavimą
Serial.begin(115200);
delay(1000);
Serial.println("IEEOKS sistema inicijuojama (setup_app).");
Wire.begin();
}
// 2. Kviečiama RAK setup() metu (tęsia inicijavimą)
bool init_app(void) { // PATAISYTA: pakeista iš 'void' į 'bool'
// Perkeliame jutiklių ir LoRaWAN inicializavimą
// BME680 / BSEC Inicializavimas
if (!bme680.begin(0x76, true)) {
Serial.println("BME680 nepavyko rasti!");
return false; // Grąžiname FALSE, jei jutiklis nerastas
}
iaqSensor.begin(0x76, Wire);
// LoRaWAN Inicializavimas
user_init_lora();
return true; // Grąžiname TRUE, jei pavyko
}
// 3. Kviečiama RAK loop() metu (tvarko ciklinį siuntimą)
void lora_data_handler(void) {
if (is_joined && millis() >= next_send_time) {
send_lora_data();
next_send_time = millis() + LORAWAN_SEND_CYCLE;
}
}
// 4. Kviečiama RAK loop() metu (tvarko įvykius)
void app_event_handler(void) {
// Galima palikti tuščią, jei viskas tvarkoma callback'uose
}
// ---------------------- SENOSIOS FUNKCIJOS KŪNAS ----------------------
// ... (Likęs kodas nesikeičia)
void getBME680Data(void) {
if (iaqSensor.run()) {
temperature = iaqSensor.temperature;
humidity = iaqSensor.humidity;
pressure = iaqSensor.pressure / 100.0;
iaq = iaqSensor.iaq;
}
}
void getMQ2Data(void) {
uint16_t raw_data;
Wire.beginTransmission(MQ2_I2C_ADDR);
Wire.write(0x00);
Wire.endTransmission(false);
if (Wire.requestFrom(MQ2_I2C_ADDR, 2) == 2) {
raw_data = Wire.read() << 8 | Wire.read();
mq2_raw_value = (float)raw_data;
} else {
mq2_raw_value = 0;
}
}
void send_lora_data() {
getBME680Data();
getMQ2Data();
CayenneLPP lpp(50);
lpp.addAnalogInput(0, iaq);
lpp.addTemperature(1, temperature);
lpp.addRelativeHumidity(2, humidity);
lpp.addBarometricPressure(3, pressure);
lpp.addAnalogInput(4, mq2_raw_value);
lmh_app_data_t app_data;
app_data.buffer = lpp.getBuffer();
app_data.buffsize = lpp.getSize();
app_data.port = LORAWAN_APP_PORT;
if (lmh_send(&app_data, LMH_UNCONFIRMED_MSG) == LMH_SUCCESS) {
Serial.printf("LoRaWAN paketas siunčiamas. Dydis: %d baitai.\n", app_data.buffsize);
} else {
Serial.println("Nepavyko išsiųsti paketo.");
}
}
void callback_lora_event(lmh_evt_t *evt) {
// ...
}
// Callback funkcijų realizacijos, atitinkančios naują API parašą
uint8_t join_callback(void) {
Serial.println("Prisijungimo kvietimas inicijuotas. API tvarko bandymą.");
return 0;
}
void send_done_callback(uint8_t *evt) {
Serial.println("Paketas išsiųstas (send_done_callback).");
}
uint32_t receive_data_callback(void) {
Serial.println("Gauti duomenys (receive_data_callback).");
return 0;
}
void confirm_callback(lmh_app_data_t *app_data) {
Serial.printf("Patvirtinimas gautas (Port: %d, confirm_callback).\n", app_data->port);
is_joined = true;
next_send_time = millis() + LORAWAN_SEND_CYCLE;
}
void tx_needed_callback(void) {
Serial.println("TX reikalingas (tx_needed_callback).");
}
// Globalus kintamasis, užpildytas su poziciniu inicializavimu
lmh_callback_t lora_callbacks = {
(uint8_t (*)())join_callback,          // 1: uint8_t (*)(void)
(void (*)(uint8_t*))send_done_callback,    // 2: void (*)(uint8_t*)
(uint32_t (*)())receive_data_callback,    // 3: uint32_t (*)(void)
(void (*)(lmh_app_data_t*))confirm_callback, // 4: void (*)(lmh_app_data_t*)
tx_needed_callback                         // 5: void (*)(void)
};
void user_init_lora(void) {
// LoRaWAN Inicializavimas
lmh_param_t lora_config;
lora_config.adr_enable = true;
lora_config.tx_power = 14;
if (lmh_init(&lora_callbacks, lora_config, true, CLASS_A, LORAMAC_REGION_EU868, false) != LMH_SUCCESS) {
Serial.println("LMH inicializavimo klaida!");
return;
}
Serial.println("Pradedamas OTAA prisijungimas prie LoRaWAN...");
lmh_join();
}

Credits

Tomas Urbanavičius
7 projects • 7 followers
Teacher at Kaunas Education Center of Technologies (Kautech) & Erasmus+ project member: "DSIoT" (2022-1-PT01-KA220-VET-000090202)
Vilma Vanagiene
1 project • 7 followers

Comments