shabaz designed a Data Acquisition Board for Pi Pico . In the first post, I used it in continuous sample mode. I took 1 second worth of samples, in 860 samples per second mode.
In this post, I use C++ STL constructs to find the minimum and maximum value. I'm using all the code from the 1st post, to collect 860 samples in a buffer.

Actions to do on that buffer:
- swap the bytes. The ADS1115 delivers them in the wrong order for Pico math (done in Average bulk samples from Data Acquisition Board for Pi Pico with C++ STL )
- use std::minmax_element() to fetch both in a std::pair.
In the original program, the buffer is a plain C array, not an STL container. I don't change that. I use STL iterators that can work on such a continuous buffer.
Find the min and max value with an STL algorithm
STL has an algorithm that finds both values in a single call: std::minmax_element(). It returns a pair of values, where first represents the min value, and second the max.
auto minmax = std::minmax_element(std::begin(buf), std::end(buf));
printf("MIN = %.7f V\n", to_volts(BOARD0, 0, *minmax.first));
printf("MAX = %.7f V\n", to_volts(BOARD0, 0, *minmax.second));
Full source of the main function. There are more functions that can be STL'd (the to_volts() conversion, printing the results, ...). For this post, I wanted to focus on the two calls related to averaging.
// ************ main function *******************
int main(void) {
stdio_init_all();
board_init();
build_data_rate(BOARD0, DR_860);
build_gain(BOARD0, AIN1, GAIN_2_048); // +- 2.048V
#define SAMPLES 860
// #define SAMPLES 10
uint16_t buf[SAMPLES];
build_cont_conversion(0);
adc_set_mux(BOARD0,0,false);
adc_enable_rdy(0);
uint8_t* buf8_ptr = (uint8_t*)buf;
*buf8_ptr = ADS1115_REG_CONVERSION;
i2c_write_blocking(i2c_port, adc_addr[BOARD0], buf8_ptr, 1, false);
uint8_t* buf8_end_ptr = ((uint8_t*)buf) + (sizeof buf);
rdy = false;
while (buf8_ptr < buf8_end_ptr) {
if (rdy) {
rdy = false;
i2c_read_blocking(i2c_port, adc_addr[BOARD0], buf8_ptr, 2, false);
buf8_ptr += 2;
}
}
// 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
// prereq: bytes are already swapped
uint16_t statistic;
// average
statistic = std::accumulate(std::begin(buf), std::end(buf), 0.0) / std::size(buf);
// std::cout << "AVG = " << to_volts(BOARD0, 0, statistic) <<" V" << std::endl;
printf("AING = %.7f V\n", to_volts(BOARD0, 0, statistic));
// min and max
auto minmax = std::minmax_element(std::begin(buf), std::end(buf));
printf("MIN = %.7f V\n", to_volts(BOARD0, 0, *minmax.first));
printf("MAX = %.7f V\n", to_volts(BOARD0, 0, *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 to_volts(BOARD0, 0, u); });
std::for_each(std::begin(volts), std::end(volts), [](double& d){
printf("AIN1 = %.7f V\n", d);
});
while (FOREVER) {}
}
Check the first post for the source of the functions called in this example.
The use of the iterators, minmax_elements() and other STL functions did not add noticeable resource use.
Enjoy.