File CayenneTypes.hpp
File List > src > CayenneTypes.hpp
Go to the documentation of this file
/*
* Copyright 2024 (C) CayenneLPP library
*
* Licensed under the GPL License, Version 3.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://fsf.org/
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Authors: Adrian Sanchez del C. <asanchezdelc>
* Jarno <JarnoW999>
* Majid <majidsabbagh>
* Victor Hogeweij <Hoog-V>
*/
#ifndef CayenneTypes_HPP
#define CayenneTypes_HPP
namespace CayenneLPP
{
#define CAYENNE_MAX_UNION_SIZE (sizeof(GPSCoord_t))
#define UINT24_MAX ((((2 ^ 24) - 1)))
#define TEMP_MAX_RANGE (UINT16_MAX / 10)
#define LUM_MAX_RANGE (UINT16_MAX / 100)
#define PRESENCE_MIN_RANGE (0)
#define DIG_GPIO_MIN_RANGE (0)
#define RH_MAX_RANGE (UINT16_MAX / 2)
#define ANALOG_VOLT_MAX_RANGE (UINT16_MAX / 100)
#define BAROMETRIC_PRESS_MAX_RANGE (UINT16_MAX / 10)
#define MAX_GPS_LAT_RANGE (UINT24_MAX / 10000)
#define MAX_GPS_LONG_RANGE (UINT24_MAX / 10000)
#define MAX_GPS_ALT_RANGE (UINT24_MAX / 100)
typedef uint8_t RawByteVal_t;
typedef uint8_t RawBitVal_t;
// Represents a 16-bit word, commonly used for medium-range integer values.
typedef uint16_t Word16Val_t;
/***
* Represents a 32-bit word, used for larger integer values or raw data.
*/
typedef uint32_t Word32Val_t;
/***
* Represents a 32-bit floating-point number, used for precise numerical values.
*/
typedef float Float32Val_t;
/***
* Represents a digital GPIO (General Purpose Input/Output) value, for digital pin states.
*/
typedef uint8_t DigitalGPIOVal_t;
/***
* Represents a presence detection value, typically indicating detection (1) or absence (0).
*/
typedef uint8_t PresenceVal_t;
/***
* Represents a luminosity value, used for light intensity measurements.
*/
typedef uint16_t LuminosityVal_t;
/***
* Represents an analog GPIO value, for analog pin readings.
*/
typedef uint16_t AnalogGPIOVal_t;
/***
* Represents a temperature measurement, typically in a scaled format for precision.
*/
typedef uint16_t TemperatureVal_t;
/***
* Represents relative humidity as a percentage, in a scaled format for precision.
*/
typedef uint16_t RelativeHumidity_t;
/***
* Represents barometric pressure, typically in a scaled format to represent hPa values.
*/
typedef uint16_t BarometricPressure_t;
#pragma pack(push, 1)
typedef struct
{
uint16_t x;
uint16_t y;
uint16_t z;
} GyroVal_t;
#pragma pack(pop)
/***
* Represents 3-axis acceleration values, for motion or orientation detection.
*/
#pragma pack(push, 1)
typedef struct
{
uint16_t x;
uint16_t y;
uint16_t z;
} AcceleroVal_t;
#pragma pack(pop)
/***
* Represents GPS coordinates (latitude, longitude) and altitude, with compact bit field packing.
*/
#pragma pack(push, 1)
typedef struct
{
uint32_t latitude : 24; /* Latitude, scaled to store fractional degrees */
uint32_t longitude : 24; /* Longitude, scaled to store fractional degrees */
uint32_t altitude : 24; /* Altitude, scaled to store values with precision */
} GPSCoord_t;
#pragma pack(pop)
/***
* Represents a union of all possible measurement values, allowing for diverse data types.
*/
typedef union
{
RawBitVal_t RawBit;
RawByteVal_t RawByte;
DigitalGPIOVal_t DigitalGPIO;
PresenceVal_t Presence;
Word16Val_t Word16;
LuminosityVal_t Luminosity;
AnalogGPIOVal_t AnalogGPIO;
TemperatureVal_t Temperature;
RelativeHumidity_t RelativeHumidity;
BarometricPressure_t BarometricPressure;
Word32Val_t Word32;
Float32Val_t Float32;
GPSCoord_t GPS;
AcceleroVal_t Acceleration;
GyroVal_t Gyro;
uint8_t RawBytes[CAYENNE_MAX_UNION_SIZE];
} MeasurementData_t;
// Defines the measurement types, corresponding to specific data representations.
typedef enum
{
MEASUREMENT_TYPE_INVALID = 255,
MEASUREMENT_TYPE_DIGITAL_OUTPUT = 1,
MEASUREMENT_TYPE_DIGITAL_INPUT = 0,
MEASUREMENT_TYPE_RAWBIT_1 = 116,
MEASUREMENT_TYPE_RAWBIT_2 = 117,
MEASUREMENT_TYPE_RAWBIT_3 = 118,
MEASUREMENT_TYPE_RAWBIT_4 = 119,
MEASUREMENT_TYPE_RAWBIT_5 = 120,
MEASUREMENT_TYPE_RAWBIT_6 = 121,
MEASUREMENT_TYPE_RAWBIT_7 = 122,
MEASUREMENT_TYPE_RAWBIT_8 = 123,
MEASUREMENT_TYPE_RAWBYTE = 5,
MEASUREMENT_TYPE_RAWWORD16 = 6,
MEASUREMENT_TYPE_RAWWORD32 = 7,
MEASUREMENT_TYPE_RAWFLOAT32 = 8,
MEASUREMENT_TYPE_PRESENCE = 102,
MEASUREMENT_TYPE_LUMINOSITY = 101,
MEASUREMENT_TYPE_ANALOG_OUTPUT = 3,
MEASUREMENT_TYPE_ANALOG_INPUT = 2,
MEASUREMENT_TYPE_TEMPERATURE = 103,
MEASUREMENT_TYPE_RELATIVE_HUMIDITY = 104,
MEASUREMENT_TYPE_BAROMETRIC_PRESSURE = 115,
MEASUREMENT_TYPE_ACCELERATION = 113,
MEASUREMENT_TYPE_GYRO = 134,
MEASUREMENT_TYPE_GPS = 136,
} CayenneMeasurementType_t;
// Represents a general-purpose measurement structure, including type and value.
typedef struct
{
CayenneMeasurementType_t type;
MeasurementData_t val;
} Measurement_t;
static inline Measurement_t ResetMeasurement()
{
MeasurementData_t Data = {.RawByte = 0};
return {MEASUREMENT_TYPE_INVALID, Data};
}
static inline Measurement_t SetDigitalOutput(const uint8_t digital_output_val)
{
MeasurementData_t Data = {.DigitalGPIO = (digital_output_val > DIG_GPIO_MIN_RANGE)};
return {MEASUREMENT_TYPE_DIGITAL_OUTPUT, Data};
}
static inline Measurement_t SetDigitalInput(const uint8_t digital_input_val)
{
MeasurementData_t Data = {.DigitalGPIO = (digital_input_val > DIG_GPIO_MIN_RANGE)};
return {MEASUREMENT_TYPE_DIGITAL_INPUT, Data};
}
static inline Measurement_t SetPresence(const uint8_t presence_val)
{
MeasurementData_t Data = {.Presence = (presence_val > PRESENCE_MIN_RANGE)};
return {MEASUREMENT_TYPE_PRESENCE, Data};
}
static inline Measurement_t SetLuminosity(const float luminosity_val)
{
const float val = (luminosity_val <= LUM_MAX_RANGE) ? luminosity_val : LUM_MAX_RANGE;
MeasurementData_t Data = {.Luminosity = uint16_t(val * 100)};
return {MEASUREMENT_TYPE_LUMINOSITY, Data};
}
static inline Measurement_t SetAnalogOutput(const float analog_output_val)
{
const float val = (analog_output_val <= ANALOG_VOLT_MAX_RANGE) ? analog_output_val : ANALOG_VOLT_MAX_RANGE;
MeasurementData_t Data = {.AnalogGPIO = uint16_t((val * 100))};
return {MEASUREMENT_TYPE_ANALOG_OUTPUT, Data};
}
static inline Measurement_t SetAnalogInput(const float analog_input_val)
{
const float val = (analog_input_val <= ANALOG_VOLT_MAX_RANGE) ? analog_input_val : ANALOG_VOLT_MAX_RANGE;
MeasurementData_t Data = {.AnalogGPIO = uint16_t((val * 100))};
return {MEASUREMENT_TYPE_ANALOG_INPUT, Data};
}
static inline Measurement_t SetTemperature(const float temperature_val)
{
const float val = (temperature_val <= TEMP_MAX_RANGE) ? temperature_val : TEMP_MAX_RANGE;
MeasurementData_t Data = {.Temperature = uint16_t(val * 10)};
return {MEASUREMENT_TYPE_TEMPERATURE, Data};
}
static inline Measurement_t SetRelativeHumidity(const float humidity_val)
{
const float val = (humidity_val <= RH_MAX_RANGE) ? humidity_val : RH_MAX_RANGE;
MeasurementData_t Data = {.RelativeHumidity = uint16_t(val * 2)};
return {MEASUREMENT_TYPE_RELATIVE_HUMIDITY, Data};
}
static inline Measurement_t SetBarometricPressure(const float barometric_pressure_val)
{
const float val = (barometric_pressure_val <= BAROMETRIC_PRESS_MAX_RANGE) ? barometric_pressure_val : BAROMETRIC_PRESS_MAX_RANGE;
MeasurementData_t Data = {.BarometricPressure = uint16_t(val * 10)};
return {MEASUREMENT_TYPE_BAROMETRIC_PRESSURE, Data};
}
static inline Measurement_t SetAcceleration(const float x, const float y, const float z)
{
const AcceleroVal_t accelero_val = {.x = uint16_t(x * 1000), .y = uint16_t(y * 1000), .z = uint16_t(z * 1000)};
const MeasurementData_t Data = {.Acceleration = accelero_val};
return {MEASUREMENT_TYPE_ACCELERATION, Data};
}
static inline Measurement_t SetGyro(const float x, const float y, const float z)
{
const GyroVal_t gyro_val = {.x = uint16_t(x * 100), .y = uint16_t(y * 100), .z = uint16_t(z * 100)};
const MeasurementData_t Data = {.Gyro = gyro_val};
return {MEASUREMENT_TYPE_GYRO, Data};
}
static inline Measurement_t SetGPS(const float latitude, const float longitude, const float altitude)
{
const float lat_val = latitude <= MAX_GPS_LAT_RANGE ? latitude : MAX_GPS_LAT_RANGE;
const float long_val = longitude <= MAX_GPS_LONG_RANGE ? longitude : MAX_GPS_LONG_RANGE;
const float alt_val = altitude <= MAX_GPS_ALT_RANGE ? altitude : MAX_GPS_ALT_RANGE;
const GPSCoord_t gps_val = {.latitude = uint32_t(alt_val * 10000), .longitude = uint32_t(long_val * 10000), .altitude = uint32_t(alt_val * 100)};
const MeasurementData_t Data = {.GPS = gps_val};
return {MEASUREMENT_TYPE_GPS, Data};
}
static inline void SetRawBit(const uint8_t raw_bit_val, Measurement_t *prevMeasurement)
{
const uint8_t prevMeasurementWasBit = (prevMeasurement->type >= MEASUREMENT_TYPE_RAWBIT_1 && prevMeasurement->type < MEASUREMENT_TYPE_RAWBIT_8);
uint8_t bitpos = prevMeasurementWasBit ? ((prevMeasurement->type - MEASUREMENT_TYPE_RAWBIT_1) + 1) : 0;
if (prevMeasurementWasBit)
{
prevMeasurement->val.RawBit |= (raw_bit_val << bitpos);
bitpos++;
prevMeasurement->type = static_cast<CayenneMeasurementType_t>((MEASUREMENT_TYPE_RAWBIT_1 + bitpos) - 1);
}
else
{
prevMeasurement->val.RawBit = (raw_bit_val << bitpos);
prevMeasurement->type = MEASUREMENT_TYPE_RAWBIT_1;
}
}
static inline Measurement_t SetRawByte(const uint8_t raw_byte_val)
{
const RawByteVal_t raw_byte = raw_byte_val;
const MeasurementData_t Data = {.RawByte = raw_byte};
return {MEASUREMENT_TYPE_RAWBYTE, Data};
}
static inline Measurement_t SetWord16(const uint16_t word16_val)
{
const Word16Val_t word16 = word16_val;
const MeasurementData_t Data = {.Word16 = word16};
return {MEASUREMENT_TYPE_RAWWORD16, Data};
}
static inline Measurement_t SetWord32(const uint32_t word32_val)
{
const Word32Val_t word32 = word32_val;
const MeasurementData_t Data = {.Word32 = word32};
return {MEASUREMENT_TYPE_RAWWORD32, Data};
}
static inline Measurement_t SetFloat32(const float float32_val)
{
const Float32Val_t float32 = float32_val;
const MeasurementData_t Data = {.Float32 = float32};
return {MEASUREMENT_TYPE_RAWFLOAT32, Data};
}
}
#endif