Calculating a Median of Several Readings

What is the easiest way to calculate a Median from 7 to 10 Ultra Sonic Sensor Readings? I am kind of new to Arduino code but here is what I have so far (below). I am getting a few readings out of 30 that are clearly outliers. Seems that some of my HC-SR04 sensors are worse than others too.

// define variables:
#include <EEPROM.h>  // Initializes EEPROM; pulls in code from Ardiuno library.
int trigPin = 5; // trigger pin on the Ultrasonic Sensor HC-SR04 module is connected to Arduino Nano's pin 5
int echoPin=4;  // echo pin on the Ultrasonic Sensor HC-SR04 module is connected to Arduino Nano's pin 4
float distance; // variable to store 'distance' reading 
long duration; // variable to store duration time reading (from ultra sonic sound travel out and back from the arrow)
int led = 13
; // LED pin variable, the pin that the 'sight LED' is connected to (D13 with board LED)
int calPin = 6;  // the input pin for the calibration push button for initial calibration after installation on bow riser - different for each bow set up. Done only once per bow.
//int arrow = 60; //sets maximum distance of arrow from sensor in millimeters changes depending on the distance is from the arrow to the HC-SR04 Ultrasonic Sensor (now stored in EEPROM)
int val = 0;  // variable used to determin if calPin is high or low based on pushbutton (it is LOW if button is depressed, otherwise HIGH)
float arrow = EEPROM.read(0); // assigns the 'arrow' spec as the last distance stored in EEPROM (from HC-SR04 pushbutton calibration)

void setup() {
Serial.begin(9600); // USUALLY USED FOR SET UP REASONS FOR SPEED REASONS -Opens the serial port to communicate at 9600 bits per second on the Monitor
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
pinMode(led,OUTPUT);     // Sets led pin as Output from above
pinMode(calPin, INPUT);  // Sets pushbutton as Input
}

void loop() {
digitalWrite(trigPin, LOW); // Clears the trigPin (low state is 0)
delayMicroseconds(5);
digitalWrite(trigPin, HIGH); // Sets the trigPin to the HIGH state ('1') for 10 micro seconds
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH); // Reads the echoPin, returns the sound wave travel time in microseconds

distance= duration*0.34/2; // Calculating the distance in mm (a fine resolution compared to inches or cm without decimals)

Serial.print("Distance: "); // USUALLY USED FOR SET UP REASONS AND NOT FOR FUNCTION IN THE FIELD FOR SPEED REASONS - Prints the Distance heading on the Serial Monitor
Serial.println(distance);  // USUALLY USED FOR SET UP REASONS AND NOT FOR FUNCTION IN THE FIELD FOR SPEED REASONS - Prints the distance on the Serial Monitor
Serial.print("Arrow spec: ");
Serial.println(arrow);

// Arrow In Place
if (distance <= arrow && distance >= 0){  // IF distance is less than or equal to 'arrow' AND greater than or equal to zero (positive), then arrow is 'knocked & in place' (no LED light)
digitalWrite(led,LOW);
delay(1000);  // delays about 1.0 seconds after arrow is released so light doesn't bother archer during release follow through.
}
else {
//No Arrow
digitalWrite(led,HIGH); // blink LED ON
delay(300); // LED on time delay
digitalWrite(led,LOW); // blink LED OFF
delay(300);
}
// Store to 'arrow' calibration distance to EEPROM
val = digitalRead(calPin);  // read state of the calPin normally HIGH '1', else '0' if button is depressed
  if (val == HIGH){        // check if the calPin input is HIGH (button released); if HIGH no calibration action is required. If low calibrate per 'Else' below
   Serial.println(val);   //  USUALLY USED FOR SET UP REASONS AND NOT FOR FUNCTION IN THE FIELD FOR SPEED REASONS - Prints val to the Serial Monitor
  }
  else {
    distance = distance + 30; // adds 30 mm to reading to assure no blinking LED if arrow is loaded but arrow rest has not been raised yet.
    EEPROM.write(0,distance); // zero is the location in the EEPROM and 'distance' is the value stored there.
    arrow = EEPROM.read(0); // re-establishes distance specification in variable 'arrow' to determine if an arrow is in place.
    digitalWrite(calPin, LOW);}  // when calPin is LOW ('0' state)  
    
}

You could use something like this: Arduino Filters: MedianFilter.ino

Pieter

Please edit your post to add code tags, as described in "How to use this forum".

Thanks PieterP, is there an explanation available that explains what is going on in the code so I know how to tie it into my working code? I am using it to sense the presence of an object closer than X and then blink an LED if the object is missing. There is also a cal button used to set the max distance away from where the object is expected to be.

jremington, I will read up on that in "How to use this forum" and then fix it. This is my first post so I am just getting my feet wet.

The easiest way is to use the NewPing library's median method.

MillerInsMark:
Thanks PieterP, is there an explanation available that explains what is going on in the code so I know how to tie it into my working code?

You can click on "MedianFilter" in the example, and it'll take you to the detailed documentation.

https://tttapa.github.io/Arduino-Filters/Doxygen/d6/d25/classMedianFilter.html

First thing to do is break up the various parts of your code into well-named separate functions - sticking all
the code as a big slab inside the loop() function is not sustainable.

There should be at least one function for taking a reading, one to print it out if required,
one or more to manage eeprom, and probably one that handles the business logic
concerning "arrow", whatever that is.

Once you've got a separate function to take a reading, it can call a new function that stores it in an array.

Then you can have a function that computes the median of the current array at any time.

Everything is in its own place inside a function whose name is explanatory.

Google "separation of concerns" or "modularity".

Modular programs are easy to understand, improve, adapt, and will have fewer bugs that are easier to
test for and correct.