Embedded System Design 2 - Project
lpp.c
Go to the documentation of this file.
1 /***************************************************************************//**
2  * @file lpp.c
3  * @brief Basic Low Power Payload (LPP) functionality.
4  * @version 2.3
5  * @author
6  * Geoffrey Ottoy@n
7  * Modified by Brecht Van Eeckhoudt
8  *
9  * ******************************************************************************
10  *
11  * @section Versions
12  *
13  * @li v1.0: DRAMCO GitHub version (https://github.com/DRAMCO/EFM32-RN2483-LoRa-Node).
14  * @li v1.1: Added custom methods to add specific data to the LPP packet.
15  * @li v1.2: Merged methods to use less bytes when sending the data.
16  * @li v1.3: Updated documentation.
17  * @li v2.0: Updated version number.
18  * @li v2.1: Added extra dbprint debugging statements.
19  * @li v2.2: Fixed suboptimal buffer logic causing lockups after some runtime.
20  * @li v2.3: Chanced logic to clear the buffer before going to sleep.
21  *
22  ******************************************************************************/
23 
24 /* ____ ____ _ __ __ ____ ___
25  * | _ \| _ \ / \ | \/ |/ ___/ _ \
26  * | | | | |_) | / _ \ | |\/| | | | | | |
27  * | |_| | _ < / ___ \| | | | |__| |_| |
28  * |____/|_| \_\/_/ \_\_| |_|\____\___/
29  * research group
30  * dramco.be/
31  *
32  * KU Leuven - Technology Campus Gent,
33  * Gebroeders De Smetstraat 1,
34  * B-9000 Gent, Belgium
35  *
36  * File: lpp.c
37  * Created: 2018-03-23
38  * Author: Geoffrey Ottoy - Modified by Brecht Van Eeckhoudt
39  *
40  * Description: Basic Low Power Payload (LPP) functionality.
41  */
42 
43 #include <em_device.h> /* Math functionality */
44 #include <stdlib.h> /* Memory functionality */
45 #include <stdint.h> /* (u)intXX_t */
46 #include <stdbool.h> /* "bool", "true", "false" */
47 
48 #include "lpp.h" /* Corresponding header file */
49 #include "datatypes.h" /* Definitions of the custom data-types */
50 #include "debug_dbprint.h" /* Enable or disable printing to UART for debugging */
51 
52 /* LPP types */
53 #define LPP_DIGITAL_INPUT 0x00
54 #define LPP_ANALOG_INPUT 0x02
55 #define LPP_TEMPERATURE 0x67
56 #define LPP_HUMIDITY 0x68
57 #define LPP_ACCELEROMETER 0x71
58 #define LPP_PRESSURE 0x73
59 
60 /* LPP data sizes */
61 #define LPP_DIGITAL_INPUT_SIZE 0x03
62 #define LPP_ANALOG_INPUT_SIZE 0x04
63 #define LPP_TEMPERATURE_SIZE 0x04
64 #define LPP_HUMIDITY_SIZE 0x03
65 #define LPP_ACCELEROMETER_SIZE 0x08
66 #define LPP_PRESSURE_SIZE 0x04
67 
68 /* LPP channel ID's */
69 #define LPP_DIGITAL_INPUT_CHANNEL 0x01
70 #define LPP_ANALOG_INPUT_CHANNEL 0x02
71 #define LPP_TEMPERATURE_CHANNEL 0x03
72 #define LPP_HUMIDITY_CHANNEL 0x04
73 #define LPP_ACCELEROMETER_CHANNEL 0x05
74 #define LPP_PRESSURE_CHANNEL 0x06
75 
76 /* Custom channel ID's */
77 #define LPP_VBAT_CHANNEL 0x10 /* 16 */
78 #define LPP_TEMPERATURE_CHANNEL_INT 0x11 /* 17 */
79 #define LPP_TEMPERATURE_CHANNEL_EXT 0x12 /* 18 */
80 #define LPP_STORM_CHANNEL 0x13 /* 19 */
81 #define LPP_CABLE_BROKEN_CHANNEL 0x14 /* 20 */
82 #define LPP_STATUS_CHANNEL 0x15 /* 21 */
83 
84 bool LPP_InitBuffer(LPP_Buffer_t *b, uint8_t size)
85 {
86 
87 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
88  dbinfo("Started initializing LPP buffer...");
89 #endif /* DEBUG_DBPRINT */
90 
91  // LPP_FreeBuffer(b); // Before: LPP_ClearBuffer(b);
92 
93  b->buffer = (uint8_t *) malloc(sizeof(uint8_t) * size);
94 
95 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
96  dbinfo("> Memory allocated.");
97 #endif /* DEBUG_DBPRINT */
98 
99  if(b->buffer != NULL)
100  {
101  b->fill = 0;
102  b->length = size;
103 
104 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
105  dbinfo("LPP Buffer initialized (returned true).");
106 #endif /* DEBUG_DBPRINT */
107 
108  return (true);
109  }
110 
111 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
112  dbwarn("LPP Buffer initialized (returned false).");
113 #endif /* DEBUG_DBPRINT */
114 
115  return (false);
116 }
117 
119 {
120  memset(b->buffer, 0, b->length);
121  b->fill = 0;
122 
123 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
124  dbinfo("> LPP buffer cleared.");
125 #endif /* DEBUG_DBPRINT */
126 
127 }
128 
130 {
131  if (b->buffer != NULL) free(b->buffer); /* This logic was previously in `LPP_ClearBuffer` */
132 
133 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
134  dbinfo("> LPP buffer freed.");
135 #endif /* DEBUG_DBPRINT */
136 
137 }
138 
139 /**************************************************************************//**
140  * @brief
141  * Add measurement data to the LPP packet following the *custom message
142  * convention* to save bytes to send.
143  *
144  * @details
145  * This is what each added byte represents, **in the case of `2` measurements**:
146  * - **byte 0:** Amount of measurements
147  * - **byte 1:** Battery voltage channel (`LPP_VBAT_CHANNEL = 0x10`)
148  * - **byte 2:** LPP analog input type (`LPP_ANALOG_INPUT = 0x02`)
149  * - **byte 3-4:** A battery voltage measurement
150  * - **byte 5-6:** Another battery voltage measurement (in the case of `2` measurements)
151  * - ...
152  * - **byte 7:** Internal temperature channel (`LPP_TEMPERATURE_CHANNEL_INT = 0x11`)
153  * - **byte 8:** LPP temperature type (`LPP_TEMPERATURE = 0x67`)
154  * - **byte 9-10:** An internal temperature measurement
155  * - **byte 11-12:** Another internal temperature measurement (in the case of `2` measurements)
156  * - ...
157  * - **byte 13:** External temperature channel (`LPP_TEMPERATURE_CHANNEL_EXT = 0x12`)
158  * - **byte 14:** LPP temperature type (`LPP_TEMPERATURE = 0x67`)
159  * - **byte 15-16:** An external temperature measurement
160  * - **byte 17-18:** Another external temperature measurement (in the case of `2` measurements)
161  * - ...
162  *
163  * If we have **6 measurements** we need **43 bytes**:
164  * - `1 byte` to hold the amount of measurements
165  * - `2 bytes` to hold the battery voltage channel and LPP analog input type
166  * - `6*2bytes` to hold the battery voltage measurements
167  * - `2 bytes` to hold the internal temperature channel and LPP temperature type
168  * - `6*2bytes` to hold the internal temperature measurements
169  * - `2 bytes` to hold the external temperature channel and LPP temperature type
170  * - `6*2bytes` to hold the external temperature measurements
171  *
172  * @param[in] b
173  * The pointer to the LPP pointer.
174  *
175  * @param[in] data
176  * The struct which contains the measurements to send using LoRaWAN.
177  *
178  * @return
179  * @li `true` - Successfully added the data to the LoRaWAN packet.
180  * @li `false` - Couldn't add the data to the LoRaWAN packet.
181  *****************************************************************************/
183 {
184 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
185  dbinfo("Started adding measurements...");
186 #endif /* DEBUG_DBPRINT */
187 
188  /* Calculate free space in the buffer */
189  uint8_t space = b->length - b->fill;
190 
191  /* Calculate necessary space, first byte holds the amount of measurements */
192  uint8_t necessarySpace = 1;
193 
194  /* Add space necessary for the battery voltage and internal and external temperature measurements.
195  * (1 byte for the channel ID, 1 byte for the data type, 2 bytes for each measurement) */
196  necessarySpace += 3*(2+(2*(data.index)));
197 
198  /* Return `false` if we don't have the necessary space available */
199  if (space < necessarySpace) return (false);
200 
201  /* Fill the first byte with the amount of measurements */
202  b->buffer[b->fill++] = data.index;
203 
204  /* Fill the next bytes with battery voltage measurements */
205  b->buffer[b->fill++] = LPP_VBAT_CHANNEL;
206  b->buffer[b->fill++] = LPP_ANALOG_INPUT;
207 
208  for (uint8_t i = 0; i < data.index; i++)
209  {
210  /* Convert battery voltage value (should represent 0.01 signed ) */
211  int16_t batteryLPP = (int16_t)(round((float)data.voltage[i]/10));
212 
213  b->buffer[b->fill++] = (uint8_t)((0xFF00 & batteryLPP) >> 8);
214  b->buffer[b->fill++] = (uint8_t)(0x00FF & batteryLPP);
215  }
216 
217  /* Fill the next bytes with internal temperature measurements */
219  b->buffer[b->fill++] = LPP_TEMPERATURE;
220 
221  for (uint8_t i = 0; i < data.index; i++)
222  {
223  /* Convert temperature sensor value (should represent 0.1 °C Signed MSB) */
224  int16_t intTempLPP = (int16_t)(round((float)data.intTemp[i]/100));
225 
226  b->buffer[b->fill++] = (uint8_t)((0xFF00 & intTempLPP) >> 8);
227  b->buffer[b->fill++] = (uint8_t)(0x00FF & intTempLPP);
228  }
229 
230  /* Fill the next bytes with external temperature measurements */
232  b->buffer[b->fill++] = LPP_TEMPERATURE;
233 
234  for (uint8_t i = 0; i < data.index; i++)
235  {
236  /* Convert temperature sensor value (should represent 0.1 °C Signed MSB) */
237  int16_t extTempLPP = (int16_t)(round((float)data.extTemp[i]/100));
238 
239  b->buffer[b->fill++] = (uint8_t)((0xFF00 & extTempLPP) >> 8);
240  b->buffer[b->fill++] = (uint8_t)(0x00FF & extTempLPP);
241  }
242 
243 #if DEBUG_DBPRINT == 1 /* DEBUG_DBPRINT */
244  dbinfo("Measurements successfully added.");
245 #endif /* DEBUG_DBPRINT */
246 
247  return (true);
248 }
249 
250 /**************************************************************************//**
251  * @brief
252  * Add a value to indicate that a storm has been detected to the LPP packet
253  * following the *custom message convention*.
254  *
255  * @details
256  * This is what each added byte represents:
257  * - **byte 0:** Amount of measurements (in this case always one)
258  * - **byte 1:** *Storm detected* channel (`LPP_STORM_CHANNEL = 0x13`)
259  * - **byte 2:** LPP digital input type (`LPP_DIGITAL_INPUT = 0x00`)
260  * - **byte 3:** The `stormDetected` value
261  *
262  * **We always need 4 bytes.**
263  *
264  * @param[in] b
265  * The pointer to the LPP pointer.
266  *
267  * @param[in] stormDetected
268  * If a storm is detected using the accelerometer or not.
269  *
270  * @return
271  * @li `true` - Successfully added the data to the LoRaWAN packet.
272  * @li `false` - Couldn't add the data to the LoRaWAN packet.
273  *****************************************************************************/
274 bool LPP_AddStormDetected (LPP_Buffer_t *b, uint8_t stormDetected)
275 {
276  /* Calculate free space in the buffer */
277  uint8_t space = b->length - b->fill;
278 
279  /* Return `false` if we don't have the necessary space available */
280  if (space < LPP_DIGITAL_INPUT_SIZE + 1) return (false); /* "+1": One extra byte for the amount of measurements */
281 
282  /* Fill the first byte with the amount of measurements (in this case always one) */
283  b->buffer[b->fill++] = 0x01;
284 
285  /* Fill the next bytes following the default LPP packet convention */
286  b->buffer[b->fill++] = LPP_STORM_CHANNEL;
287  b->buffer[b->fill++] = LPP_DIGITAL_INPUT;
288  b->buffer[b->fill++] = stormDetected;
289 
290  return (true);
291 }
292 
293 /**************************************************************************//**
294  * @brief
295  * Add a value to indicate that the cable has been broken to the LPP packet
296  * following the *custom message convention*.
297  *
298  * @details
299  * This is what each added byte represents:
300  * - **byte 0:** Amount of measurements (in this case always one)
301  * - **byte 1:** *Cable broken* channel (`LPP_CABLE_BROKEN_CHANNEL = 0x14`)
302  * - **byte 2:** LPP digital input type (`LPP_DIGITAL_INPUT = 0x00`)
303  * - **byte 3:** The `cableBroken` value
304  *
305  * **We always need 4 bytes.**
306  *
307  * @param[in] b
308  * The pointer to the LPP pointer.
309  *
310  * @param[in] cableBroken
311  * The *cable break* value.
312  *
313  * @return
314  * @li `true` - Successfully added the data to the LoRaWAN packet.
315  * @li `false` - Couldn't add the data to the LoRaWAN packet.
316  *****************************************************************************/
317 bool LPP_AddCableBroken (LPP_Buffer_t *b, uint8_t cableBroken)
318 {
319  /* Calculate free space in the buffer */
320  uint8_t space = b->length - b->fill;
321 
322  /* Return `false` if we don't have the necessary space available */
323  if (space < LPP_DIGITAL_INPUT_SIZE + 1) return (false); /* "+1": One extra byte for the amount of measurements */
324 
325  /* Fill the first byte with the amount of measurements (in this case always one) */
326  b->buffer[b->fill++] = 0x01;
327 
328  /* Fill the next bytes following the default LPP packet convention */
330  b->buffer[b->fill++] = LPP_DIGITAL_INPUT;
331  b->buffer[b->fill++] = cableBroken;
332 
333  return (true);
334 }
335 
336 /**************************************************************************//**
337  * @brief
338  * Add a value to indicate a program status to the LPP packet following the
339  * *custom message convention*.
340  *
341  * @details
342  * This is what each added byte represents:
343  * - **byte 0:** Amount of measurements (in this case always one)
344  * - **byte 1:** *Status* channel (`LPP_STATUS_CHANNEL = 0x15`)
345  * - **byte 2:** LPP digital input type (`LPP_DIGITAL_INPUT = 0x00`)
346  * - **byte 3:** The `status` value
347  *
348  * **We always need 4 bytes.**
349  *
350  * @param[in] b
351  * The pointer to the LPP pointer.
352  *
353  * @param[in] status
354  * The *status* value.
355  *
356  * @return
357  * @li `true` - Successfully added the data to the LoRaWAN packet.
358  * @li `false` - Couldn't add the data to the LoRaWAN packet.
359  *****************************************************************************/
360 bool LPP_AddStatus (LPP_Buffer_t *b, uint8_t status)
361 {
362  /* Calculate free space in the buffer */
363  uint8_t space = b->length - b->fill;
364 
365  /* Return `false` if we don't have the necessary space available */
366  if (space < LPP_DIGITAL_INPUT_SIZE + 1) return (false); /* "+1": One extra byte for the amount of measurements */
367 
368  /* Fill the first byte with the amount of measurements (in this case always one) */
369  b->buffer[b->fill++] = 0x01;
370 
371  /* Fill the next bytes following the default LPP packet convention */
372  b->buffer[b->fill++] = LPP_STATUS_CHANNEL;
373  b->buffer[b->fill++] = LPP_DIGITAL_INPUT;
374  b->buffer[b->fill++] = status;
375 
376  return (true);
377 }
378 
379 /**************************************************************************//**
380  * @brief
381  * Add a battery voltage measurement to the LPP packet, disguised as an
382  * *Analog Input* packet (2 bytes). The channel is defined by `LPP_VBAT_CHANNEL`
383  * and is `0x10`.
384  *
385  * @deprecated
386  * This is a deprecated method following the standard LPP format to add data
387  * to the LPP packet. In practice it uses too much bytes to send a lot of
388  * measurements at once. The method is kept here just in case.
389  *
390  * @param[in] b
391  * The pointer to the LPP pointer.
392  *
393  * @param[in] vbat
394  * The measured battery voltage.
395  *
396  * @return
397  * @li `true` - Successfully added the data to the LoRaWAN packet.
398  * @li `false` - Couldn't add the data to the LoRaWAN packet.
399  *****************************************************************************/
400 bool LPP_deprecated_AddVBAT (LPP_Buffer_t *b, int16_t vbat)
401 {
402  uint8_t space = b->length - b->fill;
403  if (space < LPP_ANALOG_INPUT_SIZE) return (false);
404 
405  b->buffer[b->fill++] = LPP_VBAT_CHANNEL;
406  b->buffer[b->fill++] = LPP_ANALOG_INPUT;
407  b->buffer[b->fill++] = (uint8_t)((0xFF00 & vbat) >> 8);
408  b->buffer[b->fill++] = (uint8_t)(0x00FF & vbat);
409 
410  return (true);
411 }
412 
413 /**************************************************************************//**
414  * @brief
415  * Add an internal temperature measurement (2 bytes) to the LPP packet.
416  * The channel is defined by `LPP_TEMPERATURE_CHANNEL_INT` and is `0x11`.
417  *
418  * @deprecated
419  * This is a deprecated method following the standard LPP format to add data
420  * to the LPP packet. In practice it uses too much bytes to send a lot of
421  * measurements at once. The method is kept here just in case.
422  *
423  * @param[in] b
424  * The pointer to the LPP pointer.
425  *
426  * @param[in] intTemp
427  * The measured internal temperature.
428  *
429  * @return
430  * @li `true` - Successfully added the data to the LoRaWAN packet.
431  * @li `false` - Couldn't add the data to the LoRaWAN packet.
432  *****************************************************************************/
433 bool LPP_deprecated_AddIntTemp (LPP_Buffer_t *b, int16_t intTemp)
434 {
435  uint8_t space = b->length - b->fill;
436  if (space < LPP_TEMPERATURE_SIZE) return (false);
437 
439  b->buffer[b->fill++] = LPP_TEMPERATURE;
440  b->buffer[b->fill++] = (uint8_t)((0xFF00 & intTemp) >> 8);
441  b->buffer[b->fill++] = (uint8_t)(0x00FF & intTemp);
442 
443  return (true);
444 }
445 
446 /**************************************************************************//**
447  * @brief
448  * Add an external temperature measurement (2 bytes) to the LPP packet.
449  * The channel is defined by `LPP_TEMPERATURE_CHANNEL_EXT` and is `0x12`.
450  *
451  * @deprecated
452  * This is a deprecated method following the standard LPP format to add data
453  * to the LPP packet. In practice it uses too much bytes to send a lot of
454  * measurements at once. The method is kept here just in case.
455  *
456  * @param[in] b
457  * The pointer to the LPP pointer.
458  *
459  * @param[in] extTemp
460  * The measured external temperature.
461  *
462  * @return
463  * @li `true` - Successfully added the data to the LoRaWAN packet.
464  * @li `false` - Couldn't add the data to the LoRaWAN packet.
465  *****************************************************************************/
466 bool LPP_deprecated_AddExtTemp (LPP_Buffer_t *b, int16_t extTemp)
467 {
468  uint8_t space = b->length - b->fill;
469  if (space < LPP_TEMPERATURE_SIZE) return (false);
470 
472  b->buffer[b->fill++] = LPP_TEMPERATURE;
473  b->buffer[b->fill++] = (uint8_t)((0xFF00 & extTemp) >> 8);
474  b->buffer[b->fill++] = (uint8_t)(0x00FF & extTemp);
475 
476  return (true);
477 }
478 
479 /**************************************************************************//**
480  * @brief
481  * Add a *storm* value to the LPP packet, disguised as a *Digital Input*
482  * packet (1 byte). The channel is defined by `LPP_STORM_CHANNEL` and is `0x13`.
483  *
484  * @deprecated
485  * This is a deprecated method following the standard LPP format to add data
486  * to the LPP packet. The method is kept here just in case.
487  *
488  * @param[in] b
489  * The pointer to the LPP pointer.
490  *
491  * @param[in] stormDetected
492  * If a storm is detected using the accelerometer or not.
493  *
494  * @return
495  * @li `true` - Successfully added the data to the LoRaWAN packet.
496  * @li `false` - Couldn't add the data to the LoRaWAN packet.
497  *****************************************************************************/
498 bool LPP_deprecated_AddStormDetected (LPP_Buffer_t *b, uint8_t stormDetected)
499 {
500  uint8_t space = b->length - b->fill;
501  if (space < LPP_DIGITAL_INPUT_SIZE) return (false);
502 
503  b->buffer[b->fill++] = LPP_STORM_CHANNEL;
504  b->buffer[b->fill++] = LPP_DIGITAL_INPUT;
505  b->buffer[b->fill++] = stormDetected;
506 
507  return (true);
508 }
509 
510 /**************************************************************************//**
511  * @brief
512  * Add a *cable break* value to the LPP packet, disguised as a *Digital Input*
513  * packet (1 byte). The channel is defined by `LPP_CABLE_BROKEN_CHANNEL` and is `0x14`.
514  *
515  * @deprecated
516  * This is a deprecated method following the standard LPP format to add data
517  * to the LPP packet. The method is kept here just in case.
518  *
519  * @param[in] b
520  * The pointer to the LPP pointer.
521  *
522  * @param[in] cableBroken
523  * The *cable break* value.
524  *
525  * @return
526  * @li `true` - Successfully added the data to the LoRaWAN packet.
527  * @li `false` - Couldn't add the data to the LoRaWAN packet.
528  *****************************************************************************/
529 bool LPP_deprecated_AddCableBroken (LPP_Buffer_t *b, uint8_t cableBroken)
530 {
531  uint8_t space = b->length - b->fill;
532  if (space < LPP_DIGITAL_INPUT_SIZE) return (false);
533 
535  b->buffer[b->fill++] = LPP_DIGITAL_INPUT;
536  b->buffer[b->fill++] = cableBroken;
537 
538  return (true);
539 }
540 
541 /**************************************************************************//**
542  * @brief
543  * Add a *status* value to the LPP packet, disguised as a *Digital Input*
544  * packet (1 byte). The channel is defined by `LPP_STATUS_CHANNEL` and is `0x15`.
545  *
546  * @deprecated
547  * This is a deprecated method following the standard LPP format to add data
548  * to the LPP packet. The method is kept here just in case.
549  *
550  * @param[in] b
551  * The pointer to the LPP pointer.
552  *
553  * @param[in] status
554  * The *status* value.
555  *
556  * @return
557  * @li `true` - Successfully added the data to the LoRaWAN packet.
558  * @li `false` - Couldn't add the data to the LoRaWAN packet.
559  *****************************************************************************/
560 bool LPP_deprecated_AddStatus (LPP_Buffer_t *b, uint8_t status)
561 {
562  uint8_t space = b->length - b->fill;
563  if (space < LPP_DIGITAL_INPUT_SIZE) return (false);
564 
565  b->buffer[b->fill++] = LPP_STATUS_CHANNEL;
566  b->buffer[b->fill++] = LPP_DIGITAL_INPUT;
567  b->buffer[b->fill++] = status;
568 
569  return (true);
570 }
571 
573 {
574  uint8_t space = b->length - b->fill;
575  if(space < LPP_DIGITAL_INPUT_SIZE){
576  return (false);
577  }
578 
580  b->buffer[b->fill++] = LPP_DIGITAL_INPUT;
581  b->buffer[b->fill++] = data;
582 
583  return (true);
584 }
585 
586 bool LPP_AddAnalog(LPP_Buffer_t *b, int16_t data)
587 {
588  uint8_t space = b->length - b->fill;
589  if(space < LPP_ANALOG_INPUT_SIZE){
590  return (false);
591  }
592 
594  b->buffer[b->fill++] = LPP_ANALOG_INPUT;
595  b->buffer[b->fill++] = (uint8_t)((0xFF00 & data) >> 8);
596  b->buffer[b->fill++] = (uint8_t)(0x00FF & data);
597 
598  return (true);
599 }
600 
602 {
603  uint8_t space = b->length - b->fill;
604  if(space < LPP_TEMPERATURE_SIZE){
605  return (false);
606  }
607 
609  b->buffer[b->fill++] = LPP_TEMPERATURE;
610  b->buffer[b->fill++] = (uint8_t)((0xFF00 & data) >> 8);
611  b->buffer[b->fill++] = (uint8_t)(0x00FF & data);
612 
613  return (true);
614 }
615 
617 {
618  uint8_t space = b->length - b->fill;
619  if(space < LPP_HUMIDITY_SIZE){
620  return (false);
621  }
622 
623  b->buffer[b->fill++] = LPP_HUMIDITY_CHANNEL;
624  b->buffer[b->fill++] = LPP_HUMIDITY;
625  b->buffer[b->fill++] = data;
626 
627  return (true);
628 }
629 
630 bool LPP_AddAccelerometer(LPP_Buffer_t *b, int16_t x, int16_t y, int16_t z)
631 {
632  uint8_t space = b->length - b->fill;
633  if(space < LPP_ACCELEROMETER_SIZE){
634  return (false);
635  }
636 
638  b->buffer[b->fill++] = LPP_ACCELEROMETER;
639  b->buffer[b->fill++] = (uint8_t)((0xFF00 & x) >> 8);
640  b->buffer[b->fill++] = (uint8_t)(0x00FF & x);
641  b->buffer[b->fill++] = (uint8_t)((0xFF00 & y) >> 8);
642  b->buffer[b->fill++] = (uint8_t)(0x00FF & y);
643  b->buffer[b->fill++] = (uint8_t)((0xFF00 & z) >> 8);
644  b->buffer[b->fill++] = (uint8_t)(0x00FF & z);
645 
646  return (true);
647 }
648 
650 {
651  uint8_t space = b->length - b->fill;
652  if(space < LPP_PRESSURE_SIZE){
653  return (false);
654  }
655 
656  b->buffer[b->fill++] = LPP_PRESSURE_CHANNEL;
657  b->buffer[b->fill++] = LPP_PRESSURE;
658  b->buffer[b->fill++] = (uint8_t)((0xFF00 & data) >> 8);
659  b->buffer[b->fill++] = (uint8_t)(0x00FF & data);
660 
661  return (true);
662 }
#define LPP_STATUS_CHANNEL
Definition: lpp.c:82
bool LPP_AddDigital(LPP_Buffer_t *b, uint8_t data)
Definition: lpp.c:572
#define LPP_HUMIDITY
Definition: lpp.c:56
#define LPP_ACCELEROMETER_CHANNEL
Definition: lpp.c:73
uint8_t fill
Definition: lpp.h:41
bool LPP_InitBuffer(LPP_Buffer_t *b, uint8_t size)
Definition: lpp.c:84
bool LPP_AddStormDetected(LPP_Buffer_t *b, uint8_t stormDetected)
Add a value to indicate that a storm has been detected to the LPP packet following the custom message...
Definition: lpp.c:274
#define LPP_DIGITAL_INPUT_SIZE
Definition: lpp.c:61
#define LPP_PRESSURE_CHANNEL
Definition: lpp.c:74
Basic Low Power Payload (LPP) functionality.
bool LPP_AddPressure(LPP_Buffer_t *b, uint16_t data)
Definition: lpp.c:649
#define LPP_TEMPERATURE
Definition: lpp.c:55
Definitions of the custom data-types used.
MeasurementData_t data
Definition: main.c:189
bool LPP_AddHumidity(LPP_Buffer_t *b, uint8_t data)
Definition: lpp.c:616
void dbwarn(char *message)
Print a warning string (char array) in yellow to USARTx and go to the next line.
Definition: dbprint.c:521
Definition: lpp.h:38
bool LPP_AddTemperature(LPP_Buffer_t *b, int16_t data)
Definition: lpp.c:601
void dbinfo(char *message)
Print an info string (char array) to USARTx and go to the next line.
Definition: dbprint.c:503
#define LPP_PRESSURE
Definition: lpp.c:58
bool LPP_deprecated_AddCableBroken(LPP_Buffer_t *b, uint8_t cableBroken)
Add a cable break value to the LPP packet, disguised as a Digital Input packet (1 byte)...
Definition: lpp.c:529
bool LPP_deprecated_AddStatus(LPP_Buffer_t *b, uint8_t status)
Add a status value to the LPP packet, disguised as a Digital Input packet (1 byte). The channel is defined by LPP_STATUS_CHANNEL and is 0x15.
Definition: lpp.c:560
int32_t intTemp[6]
Definition: datatypes.h:73
#define LPP_ANALOG_INPUT_CHANNEL
Definition: lpp.c:70
#define LPP_CABLE_BROKEN_CHANNEL
Definition: lpp.c:81
#define LPP_HUMIDITY_CHANNEL
Definition: lpp.c:72
uint8_t * buffer
Definition: lpp.h:40
#define LPP_TEMPERATURE_CHANNEL
Definition: lpp.c:71
void LPP_ClearBuffer(LPP_Buffer_t *b)
Definition: lpp.c:118
#define LPP_DIGITAL_INPUT
Definition: lpp.c:53
#define LPP_STORM_CHANNEL
Definition: lpp.c:80
bool LPP_AddCableBroken(LPP_Buffer_t *b, uint8_t cableBroken)
Add a value to indicate that the cable has been broken to the LPP packet following the custom message...
Definition: lpp.c:317
#define LPP_VBAT_CHANNEL
Definition: lpp.c:77
void LPP_FreeBuffer(LPP_Buffer_t *b)
Definition: lpp.c:129
Enable or disable printing to UART with dbprint.
int32_t extTemp[6]
Definition: datatypes.h:74
bool LPP_deprecated_AddVBAT(LPP_Buffer_t *b, int16_t vbat)
Add a battery voltage measurement to the LPP packet, disguised as an Analog Input packet (2 bytes)...
Definition: lpp.c:400
#define LPP_HUMIDITY_SIZE
Definition: lpp.c:64
bool LPP_AddAccelerometer(LPP_Buffer_t *b, int16_t x, int16_t y, int16_t z)
Definition: lpp.c:630
bool LPP_AddMeasurements(LPP_Buffer_t *b, MeasurementData_t data)
Add measurement data to the LPP packet following the custom message convention to save bytes to send...
Definition: lpp.c:182
bool LPP_deprecated_AddIntTemp(LPP_Buffer_t *b, int16_t intTemp)
Add an internal temperature measurement (2 bytes) to the LPP packet. The channel is defined by LPP_TE...
Definition: lpp.c:433
#define LPP_DIGITAL_INPUT_CHANNEL
Definition: lpp.c:69
#define LPP_ACCELEROMETER
Definition: lpp.c:57
bool LPP_AddStatus(LPP_Buffer_t *b, uint8_t status)
Add a value to indicate a program status to the LPP packet following the custom message convention...
Definition: lpp.c:360
#define LPP_ANALOG_INPUT_SIZE
Definition: lpp.c:62
#define LPP_TEMPERATURE_CHANNEL_INT
Definition: lpp.c:78
bool LPP_AddAnalog(LPP_Buffer_t *b, int16_t data)
Definition: lpp.c:586
uint8_t length
Definition: lpp.h:42
int32_t voltage[6]
Definition: datatypes.h:72
#define LPP_TEMPERATURE_SIZE
Definition: lpp.c:63
#define LPP_PRESSURE_SIZE
Definition: lpp.c:66
bool LPP_deprecated_AddStormDetected(LPP_Buffer_t *b, uint8_t stormDetected)
Add a storm value to the LPP packet, disguised as a Digital Input packet (1 byte). The channel is defined by LPP_STORM_CHANNEL and is 0x13.
Definition: lpp.c:498
#define LPP_ANALOG_INPUT
Definition: lpp.c:54
#define LPP_TEMPERATURE_CHANNEL_EXT
Definition: lpp.c:79
bool LPP_deprecated_AddExtTemp(LPP_Buffer_t *b, int16_t extTemp)
Add an external temperature measurement (2 bytes) to the LPP packet. The channel is defined by LPP_TE...
Definition: lpp.c:466
#define LPP_ACCELEROMETER_SIZE
Definition: lpp.c:65