phydat.h¶
Generic data container for physical data interface.
-
PHYDAT_DIM
¶ The fixed number of dimensions we work with.
1
(3U)
We use a fixed number of 3 dimensions, as many physical values we encounter can be expressed this way. In practice we have e.g. readings from accelerometers, gyros, color sensors, or set data for RGB LEDs.
When expressing 1-dimensional data we just ignore the 2 higher dimension. This leads to a slight overhead of some byte of memory - but we benefit from a unified data structure for passing around physical data.
-
PHYDAT_SCALE_STR_MAXLEN
¶ The maximum length of a scaling string.
1
(sizeof("*E-128\0"))
-
PHYDAT_MIN
¶ Minimum value for
phydat.h::phydat_t::val
.1
(INT16_MIN)
-
PHYDAT_MAX
¶ Maximum value for
phydat.h::phydat_t::val
.1
(INT16_MAX)
-
enum
@200
¶ - UNIT_UNDEF
- unit undefined
- UNIT_NONE
- data has no physical unit
- UNIT_TEMP_C
- degree Celsius
- UNIT_TEMP_F
- degree Fahrenheit
- UNIT_TEMP_K
- Kelvin.
- UNIT_LUX
- Lux (lx)
- UNIT_M
- meters
- UNIT_M2
- square meters
- UNIT_M3
- cubic meters
- UNIT_G
- gravitational force
- UNIT_DPS
- degree per second
- UNIT_GR
- grams - not using the SI unit (kg) here to make scale handling simpler
- UNIT_A
- Ampere.
- UNIT_V
- Volts.
- UNIT_GS
- gauss
- UNIT_DBM
- decibel-milliwatts
- UNIT_BAR
- Beer?
- UNIT_PA
- Pascal.
- UNIT_CD
- Candela.
- UNIT_BOOL
- boolean value [0|1]
- UNIT_CTS
- counts
- UNIT_PERCENT
- out of 100
- UNIT_PERMILL
- out of 1000
- UNIT_PPM
- part per million
- UNIT_PPB
- part per billion
- UNIT_TIME
- the three dimensions contain sec, min, and hours
- UNIT_DATE
- the 3 dimensions contain days, months and years
-
void
phydat_dump
(phydat_t * data, uint8_t dim)¶ Dump the given data container to STDIO.
Parameters
data: data container to dump dim: number of dimension of data
to dump
-
const char *
phydat_unit_to_str
(uint8_t unit)¶ Convert the given unit to a string.
Parameters
unit: unit to convert Return values
- string representation of given unit (e.g. V or m)
- NULL if unit was not recognized
-
char
phydat_prefix_from_scale
(int8_t scale)¶ Convert the given scale factor to an SI prefix.
The given scaling factor is returned as a SI unit prefix (e.g. M for Mega, u for micro, etc), or
\0
otherwise.Parameters
scale: scale factor to convert Return values
- SI prefix if applicable
\0
if no SI prefix was found
-
void
phydat_fit
(phydat_t * dat, const int32_t * values, unsigned int dim)¶ Scale integer value(s) to fit into a phydat_t.
Inserts the
values
in the givendat
so that alldim
values invalues
fit inside the limits of the data type, [phydat.h::PHYDAT_MIN
,phydat.h::PHYDAT_MAX
], and updates the stored scale factor. The value is rounded to the nearest integer if possible, otherwise away from zero. E.g.0.5
and0.6
are rounded to1
,0.4
and-0.4
are rounded to0
,-0.5
and-0.6
are rounded to-1
.1 2 3
int32_t values[] = { 100000, 2000000, 30000000 }; phydat_t dat = { .scale = 0 }; phydat_fit(&dat, values, 3);
Note
Unless compiled with
-DPHYDAT_FIT_TRADE_PRECISION_FOR_ROM=0
, this function will scale the value-32768
, even though it would fit into a phydat_t. Statistically, this precision loss happens in 0.00153% of the calls. This optimization saves a bit more than 20 bytes.Parameters
dat: the value will be written into this data array values: value(s) to rescale dim: Number of elements in values
-
struct
phydat_t
¶ Generic data structure for expressing physical values.
Physical data is expressed in a 3-dimensional touple of values. In addition to the data fields, this struct contains further the (physical) unit and the scale factor of the data. The unit is expressed as constant. The scale factor is expressed as power of 10 (10^factor).
The combination of signed 16-bit numbers with and the scale factor gives us a very high dynamic range (from -32*10^-131 to 32*10^130). In a wider sense we are saving the values as fixed floating points…
The scale factor is identical for all 3 values.
In a traditional (scientific) computational system the obvious choice for the used data type would be to use floats. We are however on heavily resource constrained (even 8-bit) embedded systems, so we use int16_t here. As most sensor are in some way ADC based, they normally do not use a higher accuracy than 12-14bit, so using 16-bit integers to represent this data is good enough in most cases.
-
int16_t
val
()¶ the 3 generic dimensions of data
-
uint8_t
unit
¶ the (physical) unit of the data
-
int8_t
scale
¶ the scale factor, 10^*scale*
-
int16_t