Skip to content

Instantly share code, notes, and snippets.

@jancumps
Created December 21, 2023 11:50
Show Gist options
  • Save jancumps/36a1d41e2ff566f07332c7db5757a6b6 to your computer and use it in GitHub Desktop.
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
#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;
}
@jancumps
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment