@@ -233,11 +233,12 @@ void HCSR04SensorManager::collectSensorResults() {
233233 dist = static_cast <uint16_t >(duration / MICRO_SEC_TO_CM_DIVIDER);
234234 }
235235 sensor->rawDistance = dist;
236- sensorValues[idx] = correctSensorOffset (dist, sensor->offset );
236+ sensorValues[idx] = correctSensorOffset (medianMeasure (sensor, dist) , sensor->offset );
237237
238238#ifdef DEVELOP
239- Serial.printf (" Raw sensor[%d] distance read %03u / %03u -> *%03ucm*, duration: %zu us - echo pin state: %d\n " ,
240- idx, sensor->rawDistance , dist, sensorValues[idx], duration, digitalRead (sensor->echoPin ));
239+ Serial.printf (" Raw sensor[%d] distance read %03u / %03u (%03u, %03u, %03u) -> *%03ucm*, duration: %zu us - echo pin state: %d\n " ,
240+ idx, sensor->rawDistance , dist, sensor->distances [0 ], sensor->distances [1 ],
241+ sensor->distances [2 ], sensorValues[idx], duration, digitalRead (sensor->echoPin ));
241242#endif
242243
243244 if (sensorValues[idx] > 0 && sensorValues[idx] < sensor->minDistance )
@@ -331,6 +332,31 @@ uint32_t HCSR04SensorManager::microsSince(uint32_t a) {
331332 return microsBetween (micros (), a);
332333}
333334
335+ uint16_t HCSR04SensorManager::medianMeasure (HCSR04SensorInfo *const sensor, uint16_t value) {
336+ sensor->distances [sensor->nextMedianDistance ++] = value;
337+ if (sensor->nextMedianDistance >= MEDIAN_DISTANCE_MEASURES) {
338+ sensor->nextMedianDistance = 0 ;
339+ }
340+ return median (sensor->distances [0 ], sensor->distances [1 ], sensor->distances [2 ]);
341+ }
342+
343+ uint16_t HCSR04SensorManager::median (uint16_t a, uint16_t b, uint16_t c) {
344+ if (a < b) {
345+ if (a >= c) {
346+ return a;
347+ } else if (b < c) {
348+ return b;
349+ }
350+ } else {
351+ if (a < c) {
352+ return a;
353+ } else if (b >= c) {
354+ return b;
355+ }
356+ }
357+ return c;
358+ }
359+
334360void IRAM_ATTR HCSR04SensorManager::isr (int idx) {
335361 // since the measurement of start and stop use the same interrupt
336362 // mechanism we should see a similar delay.
0 commit comments