From 3d7bb3d6ea8ff309e4744189be9560c39fc1f4de Mon Sep 17 00:00:00 2001 From: Unknown Date: Mon, 30 Jul 2018 14:40:44 +0200 Subject: [PATCH] Prvni odevzdani kostry --- API.md | 84 ++++++++++++++++ ETCPLPP.cpp | 240 +++++++++++++++++++++++++++++++++++++++++++++ ETCPLPP.h | 73 ++++++++++++++ keywords.txt | 37 +++++++ library.properties | 10 ++ 5 files changed, 444 insertions(+) create mode 100644 API.md create mode 100644 ETCPLPP.cpp create mode 100644 ETCPLPP.h create mode 100644 keywords.txt create mode 100644 library.properties diff --git a/API.md b/API.md new file mode 100644 index 0000000..665ff08 --- /dev/null +++ b/API.md @@ -0,0 +1,84 @@ +# API Reference + +The `ETCPLPP` class enables Arduino devices to encode data with the EasyTherm Connect + Low Power Protocol (LPP). + +## Class: `ETCPPP` + +Include and instantiate the ETCPLPP class. The constructor takes the size of the allocated buffer. Depending on the LoRa frequency plan and data rate used, the maximum payload varies. It's safe to send up to 51 bytes of payload. + +```c +#include + +ETCPLPP lpp(uint8_t size); +``` + +- `uint8_t size`: The maximum payload size to send, e.g. `51`. + +## Example + +```c +TheThingsNetwork ttn(loraSerial, debugSerial, freqPlan); +ETCPLPP lpp(51); + +lpp.reset(); +lpp.addTemperature(1, 22.5); +lpp.addBarometricPressure(2, 1073.21); +lpp.addGPS(3, 52.37365, 4.88650, 2); + +ttn.sendBytes(lpp.getBuffer(), lpp.getSize()); +``` + +See the [CayenneLPP](https://github.com/TheThingsNetwork/arduino-device-lib/blob/master/examples/CayenneLPP/CayenneLPP.ino) example. + +## Method: `reset` + +Resets the buffer. + +```c +void reset(void); +``` + +## Method: `getSize` + +Returns the size of the buffer. + +```c +uint8_t getSize(void); +``` + +## Method: `getBuffer` + +Returns a pointer to the buffer. + +```c +uint8_t *getBuffer(void); +``` + +## Method: `copy` + +Copies the internal buffer to a specified buffer and returns the copied size. + +```c +uint8_t copy(uint8_t *buffer); +``` + +## Methods: `add...` + +Add data to the buffer. The `channel` parameter acts as a key for the data field. The data fields you send are dynamic; you can selectively send data as long as the channel matches. + +```c +uint8_t addDigitalInput(uint8_t channel, uint8_t value); +uint8_t addDigitalOutput(uint8_t channel, uint8_t value); + +uint8_t addAnalogInput(uint8_t channel, float value); +uint8_t addAnalogOutput(uint8_t channel, float value); + +uint8_t addLuminosity(uint8_t channel, uint16_t lux); +uint8_t addPresence(uint8_t channel, uint8_t value); +uint8_t addTemperature(uint8_t channel, float celsius); +uint8_t addRelativeHumidity(uint8_t channel, float rh); +uint8_t addAccelerometer(uint8_t channel, float x, float y, float z); +uint8_t addBarometricPressure(uint8_t channel, float hpa); +uint8_t addGyrometer(uint8_t channel, float x, float y, float z); +uint8_t addGPS(uint8_t channel, float latitude, float longitude, float meters); +``` diff --git a/ETCPLPP.cpp b/ETCPLPP.cpp new file mode 100644 index 0000000..8b3229d --- /dev/null +++ b/ETCPLPP.cpp @@ -0,0 +1,240 @@ +// Adapted from https://developer.mbed.org/teams/myDevicesIoT/code/Cayenne-LPP/ + +// Copyright © 2017 The Things Network +// Use of this source code is governed by the MIT license that can be found in the LICENSE file. + +#include "ETCPLPP.h" + +ETCPLPP::ETCPLPP(uint8_t size) : maxsize(size) +{ + + buffer = (uint8_t *)malloc(size); + cursor = 0; +} + +ETCPLPP::~ETCPLPP(void) +{ + + if (buffer) + free(buffer); +} + +void ETCPLPP::reset(void) +{ + cursor = 0; +} + +uint8_t ETCPLPP::getSize(void) +{ + return cursor; +} + +uint8_t *ETCPLPP::getBuffer(void) +{ + + return buffer; +} + +uint8_t ETCPLPP::copy(uint8_t *dst) +{ + memcpy(dst, buffer, cursor); + return cursor; +} + +uint8_t ETCPLPP::addDigitalInput(uint8_t channel, uint8_t value) +{ + if ((cursor + LPP_DIGITAL_INPUT_SIZE) > maxsize) + { + return 0; + } + buffer[cursor++] = channel; + buffer[cursor++] = LPP_DIGITAL_INPUT; + buffer[cursor++] = value; + + return cursor; +} + +uint8_t ETCPLPP::addDigitalOutput(uint8_t channel, uint8_t value) +{ + if ((cursor + LPP_DIGITAL_OUTPUT_SIZE) > maxsize) + { + return 0; + } + buffer[cursor++] = channel; + buffer[cursor++] = LPP_DIGITAL_OUTPUT; + buffer[cursor++] = value; + + return cursor; +} + +uint8_t ETCPLPP::addAnalogInput(uint8_t channel, float value) +{ + if ((cursor + LPP_ANALOG_INPUT_SIZE) > maxsize) + { + return 0; + } + + int16_t val = value * 100; + buffer[cursor++] = channel; + buffer[cursor++] = LPP_ANALOG_INPUT; + buffer[cursor++] = val >> 8; + buffer[cursor++] = val; + + return cursor; +} + +uint8_t ETCPLPP::addAnalogOutput(uint8_t channel, float value) +{ + if ((cursor + LPP_ANALOG_OUTPUT_SIZE) > maxsize) + { + return 0; + } + int16_t val = value * 100; + buffer[cursor++] = channel; + buffer[cursor++] = LPP_ANALOG_OUTPUT; + buffer[cursor++] = val >> 8; + buffer[cursor++] = val; + + return cursor; +} + +uint8_t ETCPLPP::addLuminosity(uint8_t channel, uint16_t lux) +{ + if ((cursor + LPP_LUMINOSITY_SIZE) > maxsize) + { + return 0; + } + buffer[cursor++] = channel; + buffer[cursor++] = LPP_LUMINOSITY; + buffer[cursor++] = lux >> 8; + buffer[cursor++] = lux; + + return cursor; +} + +uint8_t CayenneLPP::addPresence(uint8_t channel, uint8_t value) +{ + if ((cursor + LPP_PRESENCE_SIZE) > maxsize) + { + return 0; + } + buffer[cursor++] = channel; + buffer[cursor++] = LPP_PRESENCE; + buffer[cursor++] = value; + + return cursor; +} + +uint8_t CayenneLPP::addTemperature(uint8_t channel, float celsius) +{ + if ((cursor + LPP_TEMPERATURE_SIZE) > maxsize) + { + return 0; + } + int16_t val = celsius * 10; + buffer[cursor++] = channel; + buffer[cursor++] = LPP_TEMPERATURE; + buffer[cursor++] = val >> 8; + buffer[cursor++] = val; + + return cursor; +} + +uint8_t CayenneLPP::addRelativeHumidity(uint8_t channel, float rh) +{ + if ((cursor + LPP_RELATIVE_HUMIDITY_SIZE) > maxsize) + { + return 0; + } + buffer[cursor++] = channel; + buffer[cursor++] = LPP_RELATIVE_HUMIDITY; + buffer[cursor++] = rh * 2; + + return cursor; +} + +uint8_t CayenneLPP::addAccelerometer(uint8_t channel, float x, float y, float z) +{ + if ((cursor + LPP_ACCELEROMETER_SIZE) > maxsize) + { + return 0; + } + int16_t vx = x * 1000; + int16_t vy = y * 1000; + int16_t vz = z * 1000; + + buffer[cursor++] = channel; + buffer[cursor++] = LPP_ACCELEROMETER; + buffer[cursor++] = vx >> 8; + buffer[cursor++] = vx; + buffer[cursor++] = vy >> 8; + buffer[cursor++] = vy; + buffer[cursor++] = vz >> 8; + buffer[cursor++] = vz; + + return cursor; +} + +uint8_t CayenneLPP::addBarometricPressure(uint8_t channel, float hpa) +{ + if ((cursor + LPP_BAROMETRIC_PRESSURE_SIZE) > maxsize) + { + return 0; + } + int16_t val = hpa * 10; + + buffer[cursor++] = channel; + buffer[cursor++] = LPP_BAROMETRIC_PRESSURE; + buffer[cursor++] = val >> 8; + buffer[cursor++] = val; + + return cursor; +} + +uint8_t CayenneLPP::addGyrometer(uint8_t channel, float x, float y, float z) +{ + if ((cursor + LPP_GYROMETER_SIZE) > maxsize) + { + return 0; + } + int16_t vx = x * 100; + int16_t vy = y * 100; + int16_t vz = z * 100; + + buffer[cursor++] = channel; + buffer[cursor++] = LPP_GYROMETER; + buffer[cursor++] = vx >> 8; + buffer[cursor++] = vx; + buffer[cursor++] = vy >> 8; + buffer[cursor++] = vy; + buffer[cursor++] = vz >> 8; + buffer[cursor++] = vz; + + return cursor; +} + +uint8_t CayenneLPP::addGPS(uint8_t channel, float latitude, float longitude, float meters) +{ + if ((cursor + LPP_GPS_SIZE) > maxsize) + { + return 0; + } + int32_t lat = latitude * 10000; + int32_t lon = longitude * 10000; + int32_t alt = meters * 100; + + buffer[cursor++] = channel; + buffer[cursor++] = LPP_GPS; + + buffer[cursor++] = lat >> 16; + buffer[cursor++] = lat >> 8; + buffer[cursor++] = lat; + buffer[cursor++] = lon >> 16; + buffer[cursor++] = lon >> 8; + buffer[cursor++] = lon; + buffer[cursor++] = alt >> 16; + buffer[cursor++] = alt >> 8; + buffer[cursor++] = alt; + + return cursor; +} diff --git a/ETCPLPP.h b/ETCPLPP.h new file mode 100644 index 0000000..0bd1646 --- /dev/null +++ b/ETCPLPP.h @@ -0,0 +1,73 @@ +// Adapted from https://developer.mbed.org/teams/myDevicesIoT/code/Cayenne-LPP/ + +// Copyright © 2017 The Things Network +// Use of this source code is governed by the MIT license that can be found in the LICENSE file. + +#ifndef _CAYENNE_LPP_H_ +#define _CAYENNE_LPP_H_ + +#include + +//LPP_BATTERY = // TODO Unsupported in IPSO Smart Object +//LPP_PROXIMITY = // TODO Unsupported in IPSO Smart Object + +#define LPP_DIGITAL_INPUT 0 // 1 byte +#define LPP_DIGITAL_OUTPUT 1 // 1 byte +#define LPP_ANALOG_INPUT 2 // 2 bytes, 0.01 signed +#define LPP_ANALOG_OUTPUT 3 // 2 bytes, 0.01 signed +#define LPP_LUMINOSITY 101 // 2 bytes, 1 lux unsigned +#define LPP_PRESENCE 102 // 1 byte, 1 +#define LPP_TEMPERATURE 103 // 2 bytes, 0.1°C signed +#define LPP_RELATIVE_HUMIDITY 104 // 1 byte, 0.5% unsigned +#define LPP_ACCELEROMETER 113 // 2 bytes per axis, 0.001G +#define LPP_BAROMETRIC_PRESSURE 115 // 2 bytes 0.1 hPa Unsigned +#define LPP_GYROMETER 134 // 2 bytes per axis, 0.01 °/s +#define LPP_GPS 136 // 3 byte lon/lat 0.0001 °, 3 bytes alt 0.01 meter + +// Data ID + Data Type + Data Size +#define LPP_DIGITAL_INPUT_SIZE 3 // 1 byte +#define LPP_DIGITAL_OUTPUT_SIZE 3 // 1 byte +#define LPP_ANALOG_INPUT_SIZE 4 // 2 bytes, 0.01 signed +#define LPP_ANALOG_OUTPUT_SIZE 4 // 2 bytes, 0.01 signed +#define LPP_LUMINOSITY_SIZE 4 // 2 bytes, 1 lux unsigned +#define LPP_PRESENCE_SIZE 3 // 1 byte, 1 +#define LPP_TEMPERATURE_SIZE 4 // 2 bytes, 0.1°C signed +#define LPP_RELATIVE_HUMIDITY_SIZE 3 // 1 byte, 0.5% unsigned +#define LPP_ACCELEROMETER_SIZE 8 // 2 bytes per axis, 0.001G +#define LPP_BAROMETRIC_PRESSURE_SIZE 4 // 2 bytes 0.1 hPa Unsigned +#define LPP_GYROMETER_SIZE 8 // 2 bytes per axis, 0.01 °/s +#define LPP_GPS_SIZE 11 // 3 byte lon/lat 0.0001 °, 3 bytes alt 0.01 meter + +class CayenneLPP +{ +public: + CayenneLPP(uint8_t size); + ~CayenneLPP(); + + void reset(void); + uint8_t getSize(void); + uint8_t *getBuffer(void); + uint8_t copy(uint8_t *buffer); + + uint8_t addDigitalInput(uint8_t channel, uint8_t value); + uint8_t addDigitalOutput(uint8_t channel, uint8_t value); + + uint8_t addAnalogInput(uint8_t channel, float value); + uint8_t addAnalogOutput(uint8_t channel, float value); + + uint8_t addLuminosity(uint8_t channel, uint16_t lux); + uint8_t addPresence(uint8_t channel, uint8_t value); + uint8_t addTemperature(uint8_t channel, float celsius); + uint8_t addRelativeHumidity(uint8_t channel, float rh); + uint8_t addAccelerometer(uint8_t channel, float x, float y, float z); + uint8_t addBarometricPressure(uint8_t channel, float hpa); + uint8_t addGyrometer(uint8_t channel, float x, float y, float z); + uint8_t addGPS(uint8_t channel, float latitude, float longitude, float meters); + +private: + uint8_t *buffer; + uint8_t maxsize; + uint8_t cursor; +}; + +#endif diff --git a/keywords.txt b/keywords.txt new file mode 100644 index 0000000..2736837 --- /dev/null +++ b/keywords.txt @@ -0,0 +1,37 @@ +####################################### +# Syntax Coloring Map For CayenneLPP +####################################### + +####################################### +# Class (KEYWORD1) +####################################### + +CayenneLPP KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +reset KEYWORD2 +getSize KEYWORD2 +*getBuffer KEYWORD2 +copy KEYWORD2 + +addDigitalInput KEYWORD2 +addDigitalOutput KEYWORD2 + +addAnalogInput KEYWORD2 +addAnalogOutput KEYWORD2 + +addLuminosity KEYWORD2 +addPresence KEYWORD2 +addTemperature KEYWORD2 +addRelativeHumidity KEYWORD2 +addAccelerometer KEYWORD2 +addBarometricPressure KEYWORD2 +addGyrometer KEYWORD2 +addGPS KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### diff --git a/library.properties b/library.properties new file mode 100644 index 0000000..136cd48 --- /dev/null +++ b/library.properties @@ -0,0 +1,10 @@ +name=CayenneLPP +version=1.0.0 +author=The Things Network +maintainer=Andres Sabas +sentence=CayenneLPP Arduino Library. +paragraph=Compatible with Cayenne Low Power Payload. +category=Communication +url=https://github.com/sabas1080/CayenneLPP +architectures=* +includes=CayenneLPP.h