Created
December 21, 2023 11:50
-
-
Save jancumps/36a1d41e2ff566f07332c7db5757a6b6 to your computer and use it in GitHub Desktop.
mock example for a sensor that works with stl containers and traditional C arrays as buffer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <algorithm> | |
#include <span> | |
#include <iterator> | |
#include <numeric> | |
#include <stdint.h> | |
#include <stdio.h> | |
#define SAMPLES (10) | |
#define BT_C_ARRAY | |
// #define BT_STD_VECTOR | |
// #define BT_STD_ARRAY | |
// #define BT_STD_LIST | |
#ifdef BT_C_ARRAY | |
// no include | |
uint16_t buf[SAMPLES]; | |
#endif | |
#ifdef BT_STD_VECTOR | |
#include <vector> | |
std::vector<uint16_t> buf = std::vector<uint16_t>(SAMPLES); | |
#endif | |
#ifdef BT_STD_ARRAY | |
#include <array> | |
std::array<uint16_t, SAMPLES> buf = std::array<uint16_t, SAMPLES>(); | |
#endif | |
#ifdef BT_STD_LIST | |
#include <list> | |
std::list<uint16_t> buf = std::list<uint16_t>(SAMPLES); | |
#endif | |
class sensor { | |
public: | |
// constructor | |
sensor() : voltconversionfactor(1.1) {} // mock conversion factor | |
// mock get bulk data by passing iterators to buffer | |
template<typename Iterator> | |
void fill(Iterator begin, Iterator end) { | |
// capture "this" between the [], allows to call this object's methods | |
// not used in this example, but used in real code to check data readiness status | |
std::for_each(begin, end, [this](uint16_t& u){ | |
u = 0b0000000100000000; // in reality, a sensor would get i2c/spi, ... data here | |
// I used 256, because after byte swapping later, it 'll become 1 | |
// obviously, just mocking sensor data here | |
}); | |
} | |
// get bulk data by passing a container (can be a C array) | |
void fill(std::span<uint16_t> buf) { | |
fill(buf.begin(), buf.end()); | |
} | |
// mock convert the raw value to volts present at the ADC input | |
// obviously, just mocking conversion here | |
inline double to_volts(uint16_t raw) { | |
return (double)(raw * voltconversionfactor); | |
} | |
private: | |
double voltconversionfactor; // mock conversion factor | |
}; | |
sensor s = sensor(); | |
int main() { | |
setbuf(stdout, NULL); // print output while debugging | |
// select the option to get the data: via iterators or by passing the buffer | |
// uncomment the one you want to use, comment the other | |
// s.fill(std::begin(buf), std::end(buf)); // option 1: with iterators | |
s.fill(buf); // option 2: with span view | |
// buffer bytes will now get swapped, | |
// and that's needed for the next actions | |
// use stl iterator and lambda function | |
std::for_each(std::begin(buf), std::end(buf), [](uint16_t& u){ u = u >> 8 | u << 8; }); // swap bytes | |
// statistics. Prereq: bytes are already swapped | |
// average | |
uint16_t average = std::accumulate(std::begin(buf), std::end(buf), 0.0) / std::size(buf); | |
printf("AVG = %.7f V\n", s.to_volts(average)); | |
// min and max | |
auto minmax = std::minmax_element(std::begin(buf), std::end(buf)); | |
printf("MIN = %.7f V\n", s.to_volts(*minmax.first)); | |
printf("MAX = %.7f V\n", s.to_volts(*minmax.second)); | |
// convert every value to voltage | |
double volts[SAMPLES]; | |
std::transform(std::begin(buf), std::end(buf), std::begin(volts), | |
[](uint16_t u){ return s.to_volts(u); }); | |
// print voltage | |
std::for_each(std::begin(volts), std::end(volts), [](double& d) { | |
printf("SMP = %.7f V\n", d); | |
}); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
for this blog: OO example for the Data Acquisition Board for Pi Pico: deep dive into the sample data buffer