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.