制造商零件编号 U001-C
ENV III UNIT WITH TEMPERATURE HU
M5Stack Technology Co., Ltd.
License: General Public License Arduino
* Thanks for the source code and project information provided by @KeHoSoftware(Achim Kern)
Things used in this project
Hardware components
M5Stack Atom DTU LoRaWAN Kit 868MHz (ASR6501)×1
M5Stack PIR Sensor Human Body Infrared PIR Motion Sensor (AS312)×1
Software apps and online services
Introduction
M5STACK recently released the ATOM DTU LoRaWAN868.The M5STACK ATOM can be programmed using Arduino IDE (2.0.4).
This tutorial shows you how to connect UNIT ENVIII, UNIT PIR to this system and how we transmit all that data to The Things Network V3. Your LCARS SmartHome SensorNode will be able to measure your environment data (temperature, humidity and pressure) and intruder motions. The LED in front of the ATOM will always inform you about the system status. Every 10 minutes we will send automatically sensor data to TTN - if you press the button - you can send messages manually. The PIR Unit will count motions between your sending periods.
LED WHITE - system is booting and joining TTN
LED BLUE - system has joined TTN and sending data
LED RED - intruder alert
LED GREEN - system actual in stand-by modeThe Arduino Code is well documented and compiled with the new IDE 2.0.4. Also, you will see very detailed DEBUG messages about every single step. We will and can easily expand the Code with more sensors like
CO2, PM10, Digital Light etc.
M5STACK ATOM DTU LoRaWAN868
ATOM DTU LoRaWAN868 is a LoRaWAN Programmable Data Transmission Unit (DTU) suitable for 868MHz frequency. The module adopts the ASR6501 scheme, which supports long-distance communication and has both ultra-low power consumption and high sensitivity. The module integrates the LoRaWAN protocol stack and adopts a serial communication interface (using AT command set for control). When used, it can be used as a collection node to access a large number of gateways for data collection and management. Integrate SMA external antenna interface to improve the communication quality and signal stability of the device. Unlike the DTU which generally only has the function of data transparent transmission, the ATOM DTU series adopts a more open architecture design. The controller ATOM LITE can modify the program at will according to the actual business. The whole machine reserves a variety of interfaces (RS485, I2C, custom interface) for user expansion, which is convenient for the rapid access of sensors and actuators. With its own guide rail clamping structure, it is perfectly embedded in various industrial control sites. A cost-effective solution for small data collection nodes.
Product Features
Sensors we will connect to the ATOM DTU LoRaWAN868
We will start to connect at first the sensors Unit ENVIII and PIR. You can later easily expand the code and include more sensors like CO2, PM10, Digital Light etc.
Unit ENVIII
ENV III is an environmental sensor that integrates SHT30 and QMP6988 internally to detect temperature, humidity, and atmospheric pressure data. SHT30 is a high-precision and low-power digital temperature and humidity sensor, and supports I2C interface (SHT30:0x44, QMP6988:0x70).QMP6988 is an absolute air pressure sensor specially designed for mobile applications, with high accuracy and stability, suitable for environmental data collection and detection types of projects.
This Unit communicates with ATOM Lite GROVE(I2C I/0 UART).
Product Features
Unit PIR
PIR is a human body infrared unit. It belongs to the "passive pyroelectric infrared detector". It detects the infrared radiation emitted and reflected by the human body or object. When infrared is detected, the output level is high, and it takes a while. Delay (high during the period and allow repeated triggers) until the trigger signal disappears (restores low).
This Unit communicates with ATOM DTU LoRaWAN868 GROVE PORT A.
Product Features
Build Instructions
Our ATOM DTU LoRaWAN SensorNode is very easy to set up. The PIR sensor connects to the top PORT A and the ENVIII sensor to the bottom I2C I/O UART PORT of the Atom Lite.
If you like - you can build a nice construction with some LEGO parts as we do.
Compiling the Arduino Source Code
The Source Code of our ATOM DTU LoRaWAN TTN SensorNode is coded with the new Arduino 2.0 IDE - well documented - and shows DEBUG info for every step we take. You only have to edit your DEV EUI, APP EUI and APP KEY.
https://docs.arduino.cc/software/ide-v2/tutorials/getting-started-ide-v2
Please use Board "M5Stack-ATOM"
If you need to install M5Stack boards include
https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/arduino/package_m5stack_index.json
in the Arduino preferences alternative board extensions. We need some external libraries - all info inside Source Code.
https://github.com/m5stack/M5Atom#include "M5Atom.h"
https://github.com/m5stack/M5-LoRaWAN#include "M5_LoRaWAN.h"
https://github.com/m5stack/M5Unit-ENV#include "M5_ENV.h"
Configuration of TTN V3
Follow the device registration tutorial from the TTN's website https://docs.m5stack.com/en/quick_start/lorawan/ttn create an account and register an app as well the device.
In your application check Integrations and please add Data Storage and MQTT. Next you should edit the Payload Format Uplink (decoder).
// we can change each end devive via port number
function Decoder(bytes, port)
{
var decoded = {};
if (port === 2)
{
if (bytes.length==6)
{
var tmp = (bytes[0]<<8 | bytes[1]);
var hum = (bytes[4]);
var pre = (bytes[2]<<8 | bytes[3]);
var motion = (bytes[5]);
decoded.env3_temperature = (tmp-5000)/100;
decoded.env3_pressure = pre/10;
decoded.env3_humidity = hum/2;
decoded.pir_motion = motion;
return decoded;
}
else
{
decoded.Status="JOIN - ATOM DTU LoRaWAN is online";
return decoded;
}
}
}
Application is booting
Application is booting
16:56:02.776 -> M5Atom initializing...OK
16:56:07.789 ->
16:56:07.789 ->
16:56:07.789 -> Starting...
16:56:07.789 -> M5ATOM_DTU_LoRaWan_OTAA_Node_01 Version 1.04
16:56:07.789 -> connected via LoRaWAN to TTN V3
16:56:07.789 ->
16:56:07.789 -> [x] Initializing M5Stack Atom_DTU_LoRaWAN868
16:56:07.789 -> [x] Initializing ENVIII Unit (SHT30 and QMP6988)
16:56:07.891 -> [x] Initializing PIR Unit
you should see then some more messages how we init the LoRaWAN system.
Finally you should see this in your serial monitor:
16:56:25.610 -> [?] CJOIN:OK
16:56:25.610 -> [x] LoRaWAN TTN V3 JOIN-OK
16:56:33.126 -> [x] sending first sensor data to TTN V3 ...
16:56:33.126 ->
16:56:33.126 ->
16:56:33.126 -> M5ATOM_DTU_LoRaWan_OTAA_Node_01 Version 1.04
16:56:33.126 ->
16:56:33.126 -> [x] ENVIII Pressure: 990.03
16:56:33.363 -> [x] ENVIII Temperature: 20.75
16:56:33.363 -> [x] ENVIII Humidity: 55.56
16:56:33.394 ->
16:56:33.394 -> [x] PIR Motion: 0
16:56:33.394 -> [x] actual TTN payload --> 1BA326AC6F00
16:56:33.394 -> [x] sending data to TTN V3 ...
16:56:33.497 -> [?]
16:56:38.491 -> [?] OK SENT:01
16:56:43.496 -> [?]
M5STACK ATOM DTU LoRaWAN868 connected to TTN standby mode
We hope all runs fine if you rebuild this nice LCARS SmartHome TTN Node. Next step you can do - include more sensors - grab MQTT sensor data with a Node-Red system - post data into an InfluxDB, visualize all with Grafana.
Schematics
Wiring Unit ENVIII and Unit PIR with M5STACK ATOM DTU LoRaWAN868
/****************************************************************************
** **
** Name: M5ATOM_DTU_LoRaWan_TTN_OTAA_Node_01 **
** Author: Achim Kern **
** Interpreter: Arduino IDE 2.0.4 on MacBookPro **
** Licence: Freeware **
** Function: Main Program **
** **
** Notes: based on idea from TTN, M5STACK and LCARS SmartHome **
** send sensor node data via LoRaWan to TTN V3 **
** **
** History: **
** **
** 1.00 - 01.02.2023 - initial release **
** 1.01 - 01.01.2023 - new code from M5_LoRaWan not DTU ! **
** 1.02 - 03.01.2023 - send and receive changes **
** - work on payload **
** 1.03 - 04.01.2023 - PIR sensor included **
** 1.04 - 06.01.2023 - hackster.io version **
** **
****************************************************************************/
/*
* Application and Version
*/
const char* application = "M5ATOM_DTU_LoRaWan_OTAA_Node_01";
const char* aktu_version = "1.04";
/*
* Introduction
*
* M5STACK recently released the ATOM DTU LoRaWAN868.
* This Source Code connects UNIT ENVIII, UNIT PIR to this system and
* transmits all sensor data to The Things Network V3.
*
* Your LCARS SmartHome SensorNode will be able to measure your environment data
* (temperature, humidity and pressure) and intruder motions.
* The LED in front of the ATOM will always inform you about the system status.
*
* LED WHITE - system is booting and joining TTN
* LED BLUE - system has joined TTN and sending data
* LED RED - intruder alert
* LED GREEN - system actual in stand-by mode
*
* The Arduino Source Code is well documented and compiled with the new IDE 2.0.4.
* https://docs.arduino.cc/software/ide-v2/tutorials/getting-started-ide-v2
* Also you will see very detailed DEBUG messages about every single step.
* We will and can easy include more sensors like CO2, PM10, Digital Light etc.
*
* Please fill / edit your TTN device and application data in modul ACTOR_ATOM_DTU_LoRaWAN868 !
/*
* actual TTN payload decoder
*
* // we can change each end devive via port number
*
* function Decoder(bytes, port)
* {
* var decoded = {};
*
* if (port === 2)
* {
* if (bytes.length==6)
* {
* var tmp = (bytes[0]<<8 | bytes[1]);
* var hum = (bytes[4]);
* var pre = (bytes[2]<<8 | bytes[3]);
* var motion = (bytes[5]);
* decoded.env3_temperature = (tmp-5000)/100;
* decoded.env3_pressure = pre/10;
* decoded.env3_humidity = hum/2;
* decoded.pir_motion = motion;
*
* return decoded;
* }
* else
* {
* decoded.Status="JOIN - ATOM DTU LoRaWAN is online";
* return decoded;
* }
* }
* }
*
*/
/*
* DEBUG_MODE:
* if defined serial messages will be displayed
*/
// Enable/disable DEBUG
#define DEBUG_MODE
/*
* M5 ATOM lib
*/
// https://github.com/m5stack/M5Atom
#include "M5Atom.h"
/*
* connected actors
*/
/*
* M5STACK ATOM DTU LoRaWAN868 - data transmission actor
*
* Description:
* ATOM DTU LoRaWAN868 is a LoRaWAN Programmable Data Transmission Unit (DTU) suitable for 868MHz frequency.
* The module adopts the ASR6501 scheme, which supports long-distance communication and has both ultra-low power consumption and high sensitivity.
* The module integrates the LoRaWAN protocol stack and adopts a serial communication interface (using AT command set for control).
* When used, it can be used as a collection node to access a large number of gateways for data collection and management.
* Integrate SMA external antenna interface to improve the communication quality and signal stability of the device.
* Unlike the DTU which generally only has the function of data transparent transmission, the ATOM DTU series adopts a more open architecture design.
* The controller ATOM LITE can modify the program at will according to the actual business.
* The whole machine reserves a variety of interfaces (RS485, I2C, custom interface) for user expansion,
* which is convenient for the rapid access of sensors and actuators.
* With its own guide rail clamping structure, it is perfectly embedded in various industrial control sites.
* A cost-effective solution for small data collection nodes.
*
* Wiki:
* https://docs.m5stack.com/en/atom/atom_dtu_lorawan868
*
* Product Features:
* ASR6501
* Operating frequency: 868MHz
* Serial communication: UART 115200bps (AT command)
* With super anti-interference ability, able to work normally in complex interference environment
* RS485 communication interface (with 12V input interface, internal integrated DCDC step-down 5V)
* Modbus Master/slave
* Strong signal access capability
* External antenna: SMA antenna interface
* Grove expansion interface: -I2C x1 -Custom x1
* Self-contained rail clamping
*
*/
// Enable/disable actors if you want to
#define ENABLE_ACTOR_ATOM_DTU_LoRaWAN868
// Actors enabled, but not found in the hardware will be ignored
#ifdef ENABLE_ACTOR_ATOM_DTU_LoRaWAN868
// https://github.com/m5stack/M5-LoRaWAN
#include "M5_LoRaWAN.h"
M5_LoRaWAN LoRaWAN;
String response;
typedef enum { kError = 0, kConnecting, kConnected, kSending } DTUState_t;
DTUState_t State = kConnecting;
// Your TTN OTAA Mode access data
// fill in here your TTN device and application data !!!
// we get the DEV EUI from the TTN console - and we have to set on our chip
// TTN CONSOLE V3 DEV EUI
char* DevEui="0000000000000000";
// we get the APP EUI from the TTN console - and we have to set on our chip
// TTN CONSOLE V3 APP EUI
char* AppEui="0000000000000000";
// we get the APP KEY from the TTN console - and we have to set on our chip
// TTN CONSOLE V3 APP KEY
char* AppKey="00000000000000000000000000000000";
#endif
/*
* connected sensors
*/
/*
* M5STACK UNIT ENVIII - environment sensor
*
* Description:
* ENV III is an environmental sensor that integrates SHT30 and QMP6988 internally
* to detect temperature, humidity, and atmospheric pressure data.
* SHT30 is a high-precision and low-power digital temperature and humidity sensor,
* and supports I2C interface (SHT30:0x44 , QMP6988:0x70).
* QMP6988 is an absolute air pressure sensor specially designed for mobile applications,
* with high accuracy and stability, suitable for environmental data collection and detection types of projects.
* This Unit communicates with the ATOM Lite via the GROVE(I2C I/0 UART).
*
* Wiki:
* https://docs.m5stack.com/en/unit/envIII
*
* Product Features:
* Simple and easy to use
* High accuracy
* I2C communication interface
* HY2.0-4P interface, support platform UIFlow , Arduino
* 2x LEGO compatible holes
*
*/
// Enable/disable sensor measurements if you want to
#define ENABLE_SENSOR_ENVIII
// Sensors enabled, but not found in the hardware will be ignored
#ifdef ENABLE_SENSOR_ENVIII
// https://github.com/m5stack/M5Unit-ENV
#include "M5_ENV.h"
SHT3X sht30;
QMP6988 qmp6988;
float env3_tmp = 0.0;
float env3_hum = 0.0;
float env3_pres = 0.0;
#endif
/*
* M5STACK UNIT PIR - motion sensor
*
* Description:
* PIR is a human body infrared unit. It belongs to the "passive pyroelectric infrared detector".
* It detects the infrared radiation emitted and reflected by the human body or object.
* When infrared is detected, the output level is high and it takes a while.
* Delay (high during the period and allow repeated triggers) until the trigger signal disappears (restores low).
* This Unit communicates with the ATOM DTU LoRaWAN868 via the GROVE PORT A.
*
* Wiki:
* https://docs.m5stack.com/en/unit/pir
*
* Product Features:
* Detects the distance: 500cm
* latency time: 2s
* Sensing range: < 100
* Quiescent current: < 60uA
* Operating temperature: -20 - 80 C
* GROVE interface, support UIFlow and Arduino
* Two Lego installation holes
*
*/
// Enable/disable sensor measurements if you want to
#define ENABLE_SENSOR_PIR_MOTION
// Sensors enabled, but not found in the hardware will be ignored
#ifdef ENABLE_SENSOR_PIR_MOTION
#define PIR_MOTION_SENSOR 21
bool MOTION = false;
int motion_counter = 0;
#endif
/*
* Generally, you should use "unsigned long" for variables that hold time
* The value will quickly become too large for an int to store
*/
// this timer is used to update data send frequence
unsigned long previousMillis = 0;
// every 10 minutes
unsigned long interval = 600000;
// every 5 minutes
// unsigned long interval = 300000;
// every 3 minutes
// unsigned long interval = 180000;
// every 1 minute
// unsigned long interval = 60000;
// every 30 seconds
// unsigned long interval = 30000;
/*-------------------------------------------------------------------------------*/
/* Function String waitRevice() */
/* */
/* TASK : wait until we got a response */
/* UPDATE : 02.01.2023 */
/*-------------------------------------------------------------------------------*/
String waitRevice()
{
String recvStr;
do
{
recvStr = Serial2.readStringUntil('\n');
}
while (recvStr.length() == 0);
DebugPrint("[?] ");
DebugPrintln(recvStr);
return recvStr;
}
/*-------------------------------------------------------------------------------*/
/* Function void array_to_string(byte array[], unsigned int len, char buffer[]) */
/* */
/* TASK : build string out of payload data */
/* UPDATE : 24.01.2021 */
/*-------------------------------------------------------------------------------*/
void array_to_string(byte array[], unsigned int len, char buffer[])
{
for (unsigned int i = 0; i < len; i )
{
byte nib1 = (array[i] >> 4) & 0x0F;
byte nib2 = (array[i] >> 0) & 0x0F;
buffer[i*2 0] = nib1 < 0xA ? '0' nib1 : 'A' nib1 - 0xA;
buffer[i*2 1] = nib2 < 0xA ? '0' nib2 : 'A' nib2 - 0xA;
}
buffer[len*2] = '\0';
}
/*-------------------------------------------------------------------------------*/
/* Function void DebugPrint(String) */
/* */
/* TASK : print debug infos on serial monitor */
/* UPDATE : 05.01.2023 */
/*-------------------------------------------------------------------------------*/
void DebugPrint(String msg)
{
#ifdef DEBUG_MODE
Serial.print(msg);
#endif
}
/*-------------------------------------------------------------------------------*/
/* Function void DebugPrintln(String) */
/* */
/* TASK : print debug infos on serial monitor */
/* UPDATE : 05.01.2023 */
/*-------------------------------------------------------------------------------*/
void DebugPrintln(String msg)
{
#ifdef DEBUG_MODE
Serial.println(msg);
#endif
}
/*-------------------------------------------------------------------------------*/
/* Function void send_data(void) */
/* */
/* TASK : send data to via LoRaWAN to TTN V3 */
/* UPDATE : 02.01.2023 */
/*-------------------------------------------------------------------------------*/
void send_data(void)
{
// LED color RED
M5.dis.fillpix(0xff0000);
// we show always who am i
DebugPrintln(F("\n\r"));
DebugPrint(F(application));
DebugPrint(F(" Version "));
DebugPrintln(F(aktu_version));
DebugPrintln(F(""));
#ifdef ENABLE_SENSOR_ENVIII
// obtain the data of qmp6988
env3_pres = qmp6988.calcPressure();
DebugPrint("[x] ENVIII Pressure: ");
DebugPrintln(String(env3_pres/100));
// obtain the data of shT30
if (sht30.get() == 0)
{
// store the temperature obtained from shT30.
env3_tmp = sht30.cTemp;
// store the humidity obtained from the SHT30.
env3_hum = sht30.humidity;
DebugPrint("[x] ENVIII Temperature: ");
DebugPrintln(String(env3_tmp));
DebugPrint("[x] ENVIII Humidity: ");
DebugPrintln(String(env3_hum));
DebugPrintln(F(""));
}
else
{
env3_tmp = 0, env3_hum = 0;
}
#endif
#ifdef ENABLE_SENSOR_PIR_MOTION
DebugPrint("[x] PIR Motion: ");
DebugPrintln(String(motion_counter));
#endif
// new payload - smaller - and better data */
int tmp = ((int)(env3_tmp * 100)) 5000;
int pre = (int)(env3_pres / 100 * 10);
byte hum = (int)(env3_hum * 2);
byte motion = (int)(motion_counter);
byte payload[6];
payload[0] = tmp >> 8;
payload[1] = tmp;
payload[2] = pre >> 8;
payload[3] = pre;
payload[4] = hum;
payload[5] = motion;
char str[32] = "";
array_to_string(payload, 6, str);
DebugPrint(F("[x] actual TTN payload --> "));
DebugPrintln(str);
DebugPrintln(F("[x] sending data to TTN V3 ..."));
String AT_command = "AT DTRX=1,20,6,";
AT_command = AT_command str;
AT_command = AT_command ("\r\n");
State = kSending;
LoRaWAN.writeCMD(AT_command);
// LED color BLUE
M5.dis.fillpix(0x0000FF);
// check if all runbs fine
String recvStr = waitRevice();
delay(5000);
recvStr = waitRevice();
delay(5000);
recvStr = waitRevice();
delay(5000);
// LED color GREEN
M5.dis.fillpix(0x00FF00);
State = kConnected;
// motion counter reset
motion_counter = 0;
}
/*-------------------------------------------------------------------------------*/
/* Function void setup() */
/* */
/* TASK : setup all needed requirements */
/* UPDATE : 01.01.2023 */
/*-------------------------------------------------------------------------------*/
void setup()
{
M5.begin(true, false, true);
// LED color WHITE
M5.dis.fillpix(0xFFFFFF);
// do we debug ?
#ifdef DEBUG_MODE
Serial.begin(115200);
delay(5000);
#endif
// boot application
DebugPrintln(F(" "));
DebugPrintln(F(" "));
DebugPrintln(F("Starting..."));
DebugPrint(F(application)); Serial.print(F(" Version ")); Serial.println(F(aktu_version));
DebugPrintln(F("connected via LoRaWAN to TTN V3"));
DebugPrintln(F(" "));
DebugPrintln("[x] Initializing M5Stack Atom_DTU_LoRaWAN868");
// wire init, adding the I2C bus.
Wire.begin(26,32);
#ifdef ENABLE_SENSOR_ENVIII
// init Unit ENVIII
DebugPrintln(F("[x] Initializing ENVIII Unit (SHT30 and QMP6988)"));
qmp6988.init();
#endif
#ifdef ENABLE_SENSOR_PIR_MOTION
// init Unit PIR
pinMode(PIR_MOTION_SENSOR, INPUT);
DebugPrintln(F("[x] Initializing PIR Unit"));
#endif
// init LoRaWAN Unit
LoRaWAN.Init(&Serial2, 19, 22);
delay(100);
while (!LoRaWAN.checkDeviceConnect())
LoRaWAN.writeCMD("AT?\r\n");
delay(100);
Serial2.flush();
// disable Log Information
DebugPrintln(F(" "));
DebugPrintln("[x] LoRaWAN Module - disable log informations ...");
LoRaWAN.writeCMD("AT ILOGLVL=0\r\n");
response = LoRaWAN.waitMsg(1000);
DebugPrint("[>] ");
DebugPrint(response);
// enable Log Information
DebugPrintln("[x] LoRaWAN Module - enable log informations ...");
LoRaWAN.writeCMD("AT CSAVE\r\n");
response = LoRaWAN.waitMsg(1000);
DebugPrint("[>] ");
DebugPrint(response);
// reboot
DebugPrintln("[x] LoRaWAN Module - rebooting ...");
LoRaWAN.writeCMD("AT IREBOOT=0\r\n");
response = LoRaWAN.waitMsg(1000);
DebugPrint("[>] ");
DebugPrint(response);
// Set Join Mode OTAA.
DebugPrintln("[x] LoRaWAN Module - set mode OTAA with DEV EUI, APP EUI and APP KEY ...");
LoRaWAN.configOTTA(DevEui, // DEV EUI
AppEui, // APP EUI
AppKey, // APP KEY
"2" // Upload Download Mode
);
response = LoRaWAN.waitMsg(1000);
DebugPrint("[>] ");
DebugPrint(response);
// Set ClassC mode
DebugPrintln("[x] LoRaWAN Module - set ClassC mode ...");
LoRaWAN.setClass("2");
response = LoRaWAN.waitMsg(1000);
DebugPrint("[>] ");
DebugPrint(response);
// set Work Mode
DebugPrintln("[x] LoRaWAN Module - set Work mode ...");
LoRaWAN.writeCMD("AT CWORKMODE=2\r\n");
response = LoRaWAN.waitMsg(1000);
DebugPrint("[>] ");
DebugPrint(response);
// LoRaWAN868
// TX Freq
// 868.1 - SF7BW125 to SF12BW125
// 868.3 - SF7BW125 to SF12BW125 and SF7BW250
// 868.5 - SF7BW125 to SF12BW125
// 867.1 - SF7BW125 to SF12BW125
// 867.3 - SF7BW125 to SF12BW125
// 867.5 - SF7BW125 to SF12BW125
// 867.7 - SF7BW125 to SF12BW125
// 867.9 - SF7BW125 to SF12BW125
// 868.8 - FSK
DebugPrintln("[x] LoRaWAN Module - set FreqMask ...");
LoRaWAN.setFreqMask("0001");
response = LoRaWAN.waitMsg(1000);
DebugPrint("[>] ");
DebugPrint(response);
// 869.525 - SF9BW125 (RX2) | 869525000
// set RXWindow
DebugPrintln("[x] LoRaWAN Module - set RXWindow ...");
LoRaWAN.setRxWindow("869525000");
response = LoRaWAN.waitMsg(1000);
DebugPrint("[>] ");
DebugPrint(response);
// change default port 10 to 2 (1-233 possible)
DebugPrintln("[x] LoRaWAN Module - change port ...");
LoRaWAN.writeCMD("AT CAPPPORT=2\r\n");
response = LoRaWAN.waitMsg(1000);
DebugPrint("[>] ");
DebugPrint(response);
DebugPrintln("[x] LoRaWAN TTN V3 try to JOIN ...");
LoRaWAN.startJoin();
response = LoRaWAN.waitMsg(1000);
DebugPrint("[>] ");
DebugPrint(response);
delay(5000);
// have we joined ?
String recvStr = waitRevice();
if (recvStr.indexOf(" CJOIN:") != -1)
{
if (recvStr.indexOf("OK") != -1)
{
// all runs fine
DebugPrintln("[x] LoRaWAN TTN V3 JOIN-OK");
State = kConnected;
// 3x LED blinking BLUE
M5.dis.fillpix(0x000000);
delay(500);
M5.dis.fillpix(0x0000FF);
delay(500);
M5.dis.fillpix(0x000000);
delay(500);
M5.dis.fillpix(0x0000FF);
delay(500);
M5.dis.fillpix(0x000000);
delay(500);
M5.dis.fillpix(0x0000FF);
}
else
{
// something went wrong
DebugPrintln("[!] LoRaWAN TTN V3 JOIN-FAIL");
State = kError;
// 3x LED blinking RED
M5.dis.fillpix(0x000000);
delay(500);
M5.dis.fillpix(0xFF0000);
delay(500);
M5.dis.fillpix(0x000000);
delay(500);
M5.dis.fillpix(0xFF0000);
delay(500);
M5.dis.fillpix(0x000000);
delay(500);
M5.dis.fillpix(0xFF0000);
}
}
delay(5000);
if (State == kConnected)
{
DebugPrintln("[x] sending first sensor data to TTN V3 ...");
send_data();
}
}
/*-------------------------------------------------------------------------------*/
/* Function void loop() */
/* */
/* TASK : this runs forever */
/* UPDATE : 01.01.2023 */
/*-------------------------------------------------------------------------------*/
void loop()
{
if (M5.Btn.wasPressed())
{
if (State == kConnected)
{
send_data();
}
}
/*
* If we have an enabled PIR Motion Sensor we will send immediately
* a message to the LoRaWan Gateway if we have detected an intruder
*/
#ifdef ENABLE_SENSOR_PIR_MOTION
int sensorValue = digitalRead(PIR_MOTION_SENSOR);
// if the sensor value is HIGH we have an intruder ?
if(sensorValue == HIGH)
{
if (MOTION == false)
{
MOTION=true;
DebugPrintln("[x] PIR MOTION detected ...");
// 3x LED blinking RED
M5.dis.fillpix(0x000000);
delay(300);
M5.dis.fillpix(0xFF0000);
delay(300);
M5.dis.fillpix(0x000000);
delay(300);
M5.dis.fillpix(0xFF0000);
delay(300);
M5.dis.fillpix(0x000000);
delay(300);
M5.dis.fillpix(0xFF0000);
motion_counter ;
}
}
// if the sensor value is HIGH we have an intruder ?
if(sensorValue == LOW)
{
MOTION=false;
M5.dis.fillpix(0x00FF00);
}
#endif
/*
* It is checked whether the time for the transmission interval has already expired
* If the time difference between the last save and the current time is greater
* as the interval, the following function is executed.
*/
if (millis() - previousMillis > interval)
{
// correct timer
previousMillis = millis();
// send data to TTN V3
if (State == kConnected)
{
send_data();
}
}
delay(50);
M5.update();
}