L14-Click 1.0
STM32WLE5CC LoRaWAN Sensor Platform
Loading...
Searching...
No Matches
mysensors_base.h
Go to the documentation of this file.
1/*
2 * mysensors_base.h
3 *
4 * The base definition/declaration for sensors, global control variables and sensor availability
5 *
6 * Created on: 29. 1. 2026
7 * Author: Milan
8 */
9
10#ifndef INC_MYSENSORS_BASE_H_
11#define INC_MYSENSORS_BASE_H_
12
13#include "mysensors_def.h"
14
15#include "tmphm_sht45.h"
16#include "amb_tsl2591.h"
17#include "bar_ils22qs.h"
18#include "bar_bmp585.h"
19#include "scd41.h"
20#include "sps30.h"
21
22#include <stdint.h>
23
24#pragma pack(1)
25/** @brief 4-byte ASCII signature stored at offset 0 of systemParams_t to validate data integrity. */
26#define SYSTEMPARAMS_SIGN "MTTV"
27
28/** @brief Total size in bytes of the systemParams_t structure stored on the NFC tag and send via LoRa - the size is used for check of struct systemParams_t
29 * and it doens't match, the Error_Handler() is called
30 */
31#define SZ_SYSTEMPARAMS 90
32
33/** @brief Version of the systemParams_t layout; increment when fields are added or reordered. */
34#define SYSTEMPARAMS_STRUCTVER 1
35
36/** @brief Application firmware minor version number (plain integer). */
37#define SYSTEMPARAMS_APPVER00 0x01
38
39/** @brief Application firmware major version number (plain integer) - check of validity struct together with SYSTEMPARAMS_SIGN. */
40#define SYSTEMPARAMS_APPVER01 0x01
41
42/** @brief The default sensor altitue */
43#define SYSTEMPARAMS_DEFAULTALTITUDE 300
44
45/** @brief Minimum allowed sensor measurement interval in milliseconds (30 seconds). */
46#define SYSTEMPARAMS_MINSENSORTIME 30000
47
48/** @brief Default sensor measurement interval in milliseconds (10 minutes). */
49#define SYSTEMPARAMS_DEFAULTSENSORTIME 60*1000*10
50
51/** @brief Maximum allowed sensor measurement interval in milliseconds (18 hour). */
52#define SYSTEMPARAMS_MAXSENSORTIME 60*1000*60*18
53
54/**
55 * @brief Minimum idle time in milliseconds before the device enters OFF (standby) mode.
56 * Values below ~10 s are too short because the LoRaWAN stack may still be
57 * finishing a transmission when the timer fires.
58 */
59#define SYSTEMPARAMS_MINTIME2OFF 10000
60
61
62/** @brief Minimum valid LoRaWAN application port number (port 0 is reserved by the stack). */
63#define SYSTEMPARAMS_MINLORAWANPORT 1
64
65/** @brief Default LoRaWAN application port used for sensor uplinks. */
66#define SYSTEMPARAMS_DEFAULTLORAWANPORT 2
67
68/** @brief Maximum valid LoRaWAN application port number (ports 224–255 are reserved). */
69#define SYSTEMPARAMS_MAXLORAWANPORT 223
70
71
72/** @brief Default LoRaWAN JoinEUI / AppEUI (8 bytes, all zeros – overridden via NFC). */
73#define SYSTEM_APP_EUI 00,00,00,00,00,00,00,00
74
75/** @brief Default LoRaWAN AppKey (16 bytes – overridden via NFC before deployment). */
76#define SYSTEM_APP_KEY AB,CD,EF,01,02,03,10,11,12,05,06,07,EF,EF,EF,EF
77
78/** @brief First byte of the 3-byte OUI prefix used in the auto-generated DevEUI. */
79#define SYSTEM_APP_DevEUI0 0x45
80/** @brief Second byte of the 3-byte OUI prefix used in the auto-generated DevEUI. */
81#define SYSTEM_APP_DevEUI1 0x87
82/** @brief Third byte of the 3-byte OUI prefix used in the auto-generated DevEUI. */
83#define SYSTEM_APP_DevEUI2 0xF2
84
85/*
86 * The DevEUI is defined as fixed 3 bytes and CRC to identify of Amica RAK devices
87 * [ 45 87 F2 ] [ uid_4bytes ] [ crc8 ]
88 * 0 1 2 3 4 5 6 7
89 *
90 *
91 * The first 3 bytes of a DevEUI in LoRaWAN are typically an IEEE OUI (Organizationally Unique Identifier).
92 * Using a random value like 4587F2 risks colliding with a registered vendor. For example, 45:87:F2 may already belong to someone.
93 *
94 * Options:
95 * Register your own OUI with IEEE (~$730 USD, gives you a block of 4096+ EUIs) — overkill for most projects.
96 * Use the locally-administered bit — set bit 1 of byte 0 (0x02 mask), which signals "this is locally assigned, not globally unique."
97 * Example: 46 87 F2 (note 46 has bit 1 set). This is the standard way to signal a private/local identifier.
98 * Keep 4587F2 if this is purely internal/private LoRaWAN (no public network, no TTN/Helium), since collisions don't matter in a closed network.
99 *
100 * if (DevEUI[0] == 0x45 && DevEUI[1] == 0x87 && DevEUI[2] == F2 && systemParams_CalculateCrc(DevEUI, 7) == DevEUI[7])
101 * {
102 * }
103 */
104
105/**
106 * @brief Bitmask of sensor modules that are enabled / available for data collection.
107 * Used in systemParams_t.AvailableSensors; individual bits can be ORed together.
108 */
109typedef enum
110{
111 SYSPARAM_TEMP_HUM = 0x01, /**< Temperature and humidity sensor (SHT45) */
112 SYSPARAM_BAR = 0x02, /**< Barometric pressure sensor (ILPS22QS or BMP585) */
113 SYSPARAM_AMBIENT = 0x04, /**< Ambient light sensor (TSL2591) */
114 SYSPARAM_CO2 = 0x08, /**< CO2 / temperature / humidity sensor (SCD41) */
115 SYSPARAM_PARTICULAR = 0x10 /**< Particular matter sensor (SPS30) */
117
118/**
119 * @brief System configuration parameters – persisted in NFC EEPROM at address 0.
120 * The structure contains all modifiable variables/settings of system, can be read/writa via NFC tool or LoRa special read/write process
121 * The structure is 90 bytes (SZ_SYSTEMPARAMS) with a CRC8 byte at the end.
122 * Fields marked RO are written by the firmware; fields marked RW can be updated by a phone app via the NFC EEPROM or via LoRa special process
123 *
124 * The following code is used for checking the structure validity:
125 * @code
126 * if (strcmp(_systemParams.Sign, SYSTEMPARAMS_SIGN) != 0 || _systemParams.AppVersion[1] != SYSTEMPARAMS_APPVER01)
127 * {
128 * .... the structure is not valid
129 * }
130 *
131 * // crc checking
132 * if (!systemParams_CheckCRC(&_systemParams))
133 * {
134 * .... the structure is not valid
135 * }
136 *
137 * @endcode
138 *
139 * @note Do not reorder fields – the phone app and MQTT server rely fixed offsets.
140 */
141typedef struct
142{
143 /**< header - identification of structure, sign & version */
144 char Sign[5]; /**< RO Magic signature "MTTV" – used to detect uninitialized memory */
145 uint8_t AppVersion[2]; /**< RO Firmware version bytes [major, minor] (see SYSTEMPARAMS_APPVER00/01) */
146 /**< ---------------------------------------------------- */
147
148 /**< sensor settings */
149 uint32_t SensTimeoutMeasure; /**< RW Sensor measurement interval in ms (min 30 s, default 10 min, max 18 h) */
150 uint16_t SensAltitude; /**< RW Elevation above sea level in metres used for sea-level pressure correction */
151 uint8_t SensSendInOnePacket; /**< RW 1 – pack all sensor values into one uplink; 0 – send separately (default 0) */
152 uint8_t SensAvailableSensors; /**< RW Bitmask of sensors to poll (see systemParams_Sensors_t); default 0x1F (all) */
153 /**< ---------------------------------------------------- */
154
155 /**< memory settings */
156 uint8_t MemsStoreSensorData; /**< RW 1 – store readings in external flash; 0 – transmit only (default 1) */
157 uint16_t MemsMaxSensorData; /**< RO Maximum number of sensor records the flash circular queue can hold */
158 uint16_t MemsCurrentCountSensorData; /**< RO Number of sensor records currently stored in the queue */
159 /**< ---------------------------------------------------- */
160
161 /**< LoRaWan settings */
162 uint8_t LoRaPort; /**< RW LoRaWAN uplink port (min 1, default 2, max 223; ports ≥224 are reserved) */
163 uint8_t LoRaRepeatTryConnect; /**< RW Number of join retries after duty-cycle back-off (default 10, max 20) */
164 uint8_t LoRaAdaptiveDataRate; /**< RW 1 – enable ADR (DataRate field is then ignored); 0 – fixed DR (default 1) */
165 uint8_t LoRaDataRate; /**< RW Fixed data rate when ADR is disabled (0=DR_0 slowest … 5=DR_5 fastest) */
166 uint8_t LoRaTxPower; /**< RW TX power index (0=max power … 7=min power, default 0) */
167 uint8_t LoRaClass; /**< RW LoRaWAN device class: 0=Class A (default), 1=Class B, 2=Class C */
168 uint8_t LoRaRegion; /**< RW LoRaWAN region index (default 5 = EU868; range 0–9) */
169 /**< ---------------------------------------------------- */
170
171 /**< hardware settings */
172 uint8_t HWBatteryLevelStatus; /**< RO Battery charge level on a 1–254 scale (1 = very low, 254 = full) */
173 uint16_t HWBatteryMV; /**< RO Battery voltage in millivolts */
174 uint8_t HWDevEUI[8]; /**< RO DevEUI derived from chip UID (format: [45 87 F2][4-byte UID][crc8]) */
175 uint8_t HWAppEUI[8]; /**< RW LoRaWAN JoinEUI / AppEUI (default: all zeros) */
176 uint8_t HWAppKEY[16]; /**< RW LoRaWAN AppKey used for OTAA join (change before deployment) */
177 uint32_t HWDevADDR; /**< RO LoRaWAN DevAddr assigned after a successful OTAA join */
178 /**< ---------------------------------------------------- */
179
180 /**< device settings */
181 uint8_t DevRestart; /**< RW Write 1 from phone app to trigger a software restart on next poll */
182 uint8_t DevReset; /**< RW Write 1 from phone app to reset to factory defaults on next poll */
183 uint8_t DevOnOff; /**< RW 0 – device wakes periodically by RTC timer; 1 – stay on (default 0) */
184 /**< ---------------------------------------------------- */
185
186 /**< dummy */
187 uint8_t Dummy[20]; /**< RW Reserved for future use; initialised to 0 */
188 /* ------ CRC covers all fields above; Crc itself is excluded from the calculation */
189 uint8_t Crc; /**< CRC8 of bytes 0..(SZ_SYSTEMPARAMS-2); must be the last field */
191#pragma pack()
192
193extern int8_t _tryInit; /**< Flag used by xxx_Is() calls; when set to 1, the Is function attempts to (re-)initialise the sensor */
194extern systemParams_t _systemParams; /**< Global system parameters read from / written to the NFC tag EEPROM */
195
196
197/**
198 * @brief Return a pointer to the DevEUI stored in _systemParams.
199 * The DevEUI is auto-generated from the chip UID during initialisation
200 * and is read-only from the phone app's perspective.
201 * @return Pointer to the 8-byte DevEUI array inside _systemParams.
202 */
204
205/**
206 * @brief Return a pointer to the AppEUI (JoinEUI) stored in _systemParams.
207 * Used by the LoRaWAN stack during the OTAA join procedure.
208 * @return Pointer to the 8-byte AppEUI array inside _systemParams.
209 */
210uint8_t* systemParams_getAppEUI();
211
212/**
213 * @brief Return a pointer to the AppKey stored in _systemParams.
214 * Used by the LoRaWAN stack to derive session keys during OTAA join.
215 * @return Pointer to the 16-byte AppKey array inside _systemParams.
216 */
217uint8_t* systemParams_getAppKey();
218
219
220/**
221 * @brief Calculate a CRC-8 checksum (Sensirion polynomial) over a byte buffer.
222 * Used to validate sensor I2C response packets as well as the CRC field
223 * of systemParams_t.
224 * @param data Pointer to the data buffer.
225 * @param len Number of bytes to include in the calculation.
226 * @return Computed CRC-8 byte.
227 */
228uint8_t systemParams_CalculateCrc(uint8_t* data, uint8_t len);
229
230/**
231 * @brief Verify the CRC field of a systemParams_t structure.
232 * @param par Pointer to the systemParams_t to check.
233 * @retval 1 – CRC is valid (structure is intact).
234 * @retval 0 – CRC mismatch (structure is corrupt or uninitialised).
235 */
236uint8_t systemParams_CheckCRC(const systemParams_t* par);
237
238/**
239 * @brief Recalculate and store the CRC in _systemParams.Crc.
240 * Call this after modifying any field of _systemParams before writing
241 * the structure to the NFC EEPROM.
242 */
244
245/**
246 * @brief Clamp all RW fields of _systemParams to their valid ranges.
247 * Called after loading parameters from NFC to ensure no out-of-range
248 * values are used (e.g. port numbers, timeouts, data rates).
249 */
251
252/**
253 * @brief Check whether a particular sensor is enabled in _systemParams.AvailableSensors.
254 * @param sensorType One of the systemParams_Sensors_t bitmask values.
255 * @retval 1 – sensor is marked as available and should be polled.
256 * @retval 0 – sensor is disabled in the configuration.
257 */
259
260
261
262#ifdef WRITELOG
263/**
264 * @brief Log the current _systemParams fields to the UART debug output.
265 * @param info Optional prefix string printed before the dump (e.g. "LOAD" or "SAVE").
266 */
267void systemParams_Log(const char* info);
268#else
269#define systemParams_Log(...)
270#endif
271
272
273/**
274 * @defgroup SensorSizes Per-sensor payload size helpers
275 * @{
276 * Each macro evaluates to sizeof(sensor_data_struct) when the corresponding
277 * sensor is enabled, or 0 when it is disabled. Used to compute SENSORS_DATASIZE.
278 */
279#ifdef SENSOR_SHT45
280 /** @brief Byte size of tmphm_sht45_t in the packed sensor record. */
281 #define SIZE_SHT45 sizeof(tmphm_sht45_t)
282#else
283 #define SIZE_SHT45 0
284#endif
285
286#ifdef SENSOR_AMB_TSL2591
287 /** @brief Byte size of amb_tsl2591_t in the packed sensor record. */
288 #define SIZE_TSL2591 sizeof(amb_tsl2591_t)
289#else
290 #define SIZE_TSL2591 0
291#endif
292
293#ifdef SENSOR_BAR_ILS22QS
294 /** @brief Byte size of bar_ils22qs_t in the packed sensor record. */
295 #define SIZE_ILS22QS sizeof(bar_ils22qs_t)
296#else
297 #define SIZE_ILS22QS 0
298#endif
299
300#ifdef SENSOR_BAR_BMP585
301 /** @brief Byte size of bar_bmp585_t in the packed sensor record. */
302 #define SIZE_BMP585 sizeof(bar_bmp585_t)
303#else
304 #define SIZE_BMP585 0
305#endif
306
307#ifdef SENSOR_SCD41
308 /** @brief Byte size of scd41_t in the packed sensor record. */
309 #define SIZE_SCD41 sizeof(scd41_t)
310#else
311 #define SIZE_SCD41 0
312#endif
313
314#ifdef SENSOR_SPS30
315 /** @brief Byte size of sps30_t in the packed sensor record. */
316 #define SIZE_SPS30 sizeof(sps30_t)
317#else
318 #define SIZE_SPS30 0
319#endif
320/** @} */
321
322/**
323 * @brief Total size in bytes of one packed sensor data record.
324 * Computed as the sum of all enabled sensor struct sizes.
325 * Stored as Data_ItemSize in mems_MainBlock_t; changing the set of
326 * active sensors changes this value and requires a memory reset.
327 * The struct size contains 2bytes - represent the timeout of sensor measuring, in 0.1minutes (10min -> value 100, 0.5min value 50)
328 */
329#define SENSORS_DATASIZE (\
330 sizeof(uint16_t) \
331 + SIZE_SHT45 \
332 + SIZE_TSL2591 \
333 + SIZE_ILS22QS \
334 + SIZE_BMP585 \
335 + SIZE_SCD41 \
336 + SIZE_SPS30 \
337 )
338
339
340
341/**
342 * @brief Initialization of base sensor data structure
343 */
344void sensorsBase_Init();
345
346/**
347 * @brief start timer to off
348 * the function is called from PWR_EnterStopMode - timer is started
349 */
351
352/**
353 * @brief stop timer to off
354 * the function is called from PWR_ExitStopMode - the timer value is checked and the PWR_ExitStopMode was invoked from this times, system goes to OFF mode setModeDevice(MODEDEVICE_OFF)
355 */
357
358#endif /* INC_MYSENSORS_BASE_H_ */
void sensorsBase_StartTimerToOff()
start timer to off the function is called from PWR_EnterStopMode - timer is started
systemParams_t _systemParams
uint8_t * systemParams_getAppKey()
Return a pointer to the AppKey stored in _systemParams. Used by the LoRaWAN stack to derive session k...
void systemParams_SetCRCSystemParams()
Recalculate and store the CRC in _systemParams.Crc. Call this after modifying any field of _systemPar...
systemParams_Sensors_t
Bitmask of sensor modules that are enabled / available for data collection. Used in systemParams_t....
@ SYSPARAM_CO2
@ SYSPARAM_BAR
@ SYSPARAM_PARTICULAR
@ SYSPARAM_AMBIENT
@ SYSPARAM_TEMP_HUM
uint8_t systemParams_CalculateCrc(uint8_t *data, uint8_t len)
Calculate a CRC-8 checksum (Sensirion polynomial) over a byte buffer. Used to validate sensor I2C res...
uint8_t * systemParams_getAppEUI()
Return a pointer to the AppEUI (JoinEUI) stored in _systemParams. Used by the LoRaWAN stack during th...
uint8_t * systemParams_getAppDevEUI()
Return a pointer to the DevEUI stored in _systemParams. The DevEUI is auto-generated from the chip UI...
void sensorsBase_StopTimerToOff()
stop timer to off the function is called from PWR_ExitStopMode - the timer value is checked and the P...
uint8_t systemParams_CheckCRC(const systemParams_t *par)
Verify the CRC field of a systemParams_t structure.
void systemParams_Log(const char *info)
Log the current _systemParams fields to the UART debug output.
int8_t _tryInit
void systemParams_Correction()
Clamp all RW fields of _systemParams to their valid ranges. Called after loading parameters from NFC ...
void sensorsBase_Init()
Initialization of base sensor data structure.
uint8_t systemParams_IsSensorAvaiable(systemParams_Sensors_t sensorType)
Check whether a particular sensor is enabled in _systemParams.AvailableSensors.
System configuration parameters – persisted in NFC EEPROM at address 0. The structure contains all mo...
uint8_t AppVersion[2]
uint8_t Dummy[20]
uint8_t SensAvailableSensors
uint8_t HWBatteryLevelStatus
uint8_t MemsStoreSensorData
uint8_t HWAppEUI[8]
uint8_t HWAppKEY[16]
uint16_t MemsCurrentCountSensorData
uint8_t SensSendInOnePacket
uint8_t HWDevEUI[8]
uint32_t SensTimeoutMeasure
uint8_t LoRaAdaptiveDataRate
uint16_t MemsMaxSensorData
uint8_t LoRaRepeatTryConnect
uint16_t SensAltitude