+//#define USE_MEDIAN_FILTER
+// Read the filtered value ( burst mode ) on a given pin
+unsigned int Adc::read(Pin *pin)
+{
+ PinName p = this->_pin_to_pinname(pin);
+ int channel = adc->_pin_to_channel(p);
+
+ uint16_t median_buffer[num_samples];
+ // needs atomic access TODO maybe be able to use std::atomic here or some lockless mutex
+ __disable_irq();
+ memcpy(median_buffer, sample_buffers[channel], sizeof(median_buffer));
+ __enable_irq();
+
+#ifdef USE_MEDIAN_FILTER
+ // returns the median value of the last 8 samples
+ return median_buffer[quick_median(median_buffer, num_samples)];
+
+#elif defined(OVERSAMPLE)
+ // Oversample to get 2 extra bits of resolution
+ // weed out top and bottom worst values then oversample the rest
+ // put into a 4 element moving average and return the average of the last 4 oversampled readings
+ static uint16_t ave_buf[num_channels][4] = { {0} };
+ std::sort(median_buffer, median_buffer + num_samples);
+ uint32_t sum = 0;
+ for (int i = num_samples / 4; i < (num_samples - (num_samples / 4)); ++i) {
+ sum += median_buffer[i];
+ }
+ // this slows down the rate of change a little bit
+ ave_buf[channel][3]= ave_buf[channel][2];
+ ave_buf[channel][2]= ave_buf[channel][1];
+ ave_buf[channel][1]= ave_buf[channel][0];
+ ave_buf[channel][0]= sum >> OVERSAMPLE;
+ return roundf((ave_buf[channel][0]+ave_buf[channel][1]+ave_buf[channel][2]+ave_buf[channel][3])/4.0F);
+
+#else
+ // sort the 8 readings and return the average of the middle 4
+ std::sort(median_buffer, median_buffer + num_samples);
+ int sum = 0;
+ for (int i = num_samples / 4; i < (num_samples - (num_samples / 4)); ++i) {
+ sum += median_buffer[i];
+ }
+ return sum / (num_samples / 2);
+
+#endif