Using qsort to average readings

If it can help, here is one I recently made, and I’d like to integrate a “median filter” in the analyze() function:

(My previous choice of water temperature sensor was one with PWM output, needing one I/O pin per sensor. Below is a sketch I made to read temperatures of 16 of these sensors with one Particle. I will adapt it to use the DS18B20 sensors.)


/**************************************************************
 * Duty Cycle analyzer FUNCTION for PWM temperature sensors
 Any pin can be sensor input pin: Specify in function call in the loop()
 For debugging, the serial monitor shows all temperatures on one line
 **************************************************************/

float T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, Tav, temperature; // Only variables needed in the loop() function.
int nrPins;
char resultstr[64]; // To send results to Google as string

void setup()
{
 Serial.begin(9600);
 Particle.variable("result", resultstr, STRING);
}

void loop()
{
// 1) Data collection (All 16 Photon pins!)

 nrPins=0; // Reset every time

 analyze(D0);
 T1=temperature;
 if (temperature!=0)
 {
  nrPins++;
  Serial.print("=D0 ");
 }
 analyze(D1);
 T2=temperature;
 if (temperature!=0)
 {
  nrPins++;
  Serial.print("=D1 ");
 }
 analyze(D2);
 T3=temperature;
 if (temperature!=0)
 {
  nrPins++;
  Serial.print("=D2 ");
 }
 analyze(D3);
 T4=temperature;
 if (temperature!=0)
 {
  nrPins++;
  Serial.print("=D3 ");
 }
 analyze(D4);
 T5=temperature;
 if (temperature!=0)
 {
  nrPins++;
  Serial.print("=D4 ");
 }
 analyze(D5);
 T6=temperature;
 if (temperature!=0)
 {
  nrPins++;
  Serial.print("=D5 ");
 }
 analyze(D6);
 T7=temperature;
 if (temperature!=0)
 {
  nrPins++;
  Serial.print("=D6 ");
 }
 analyze(D7);
 T8=temperature;
 if (temperature!=0)
 {
  nrPins++;
  Serial.print("=D7 ");
 }
 analyze(A0);
 T9=temperature;
 if (temperature!=0)
 {
  nrPins++;
  Serial.print("=A0 ");
 }
 analyze(A1);
 T10=temperature;
 if (temperature!=0)
 {
  nrPins++;
  Serial.print("=A1 ");
 }
 analyze(A2);
 T11=temperature;
 if (temperature!=0)
 {
  nrPins++;
  Serial.print("=A2 ");
 }
 analyze(A3);
 T12=temperature;
 if (temperature!=0)
 {
  nrPins++;
  Serial.print("=A3 ");
 }
 analyze(A4);
 T13=temperature;
 if (temperature!=0)
 {
  nrPins++;
  Serial.print("=A4 ");
 }
 analyze(A5);
 T14=temperature;
 if (temperature!=0)
 {
  nrPins++;
  Serial.print("=A5 ");
 }
 analyze(A6);
 T15=temperature;
 if (temperature!=0)
 {
  nrPins++;
  Serial.print("=A6 ");
 }
 analyze(A7);
 T16=temperature;
 if (temperature!=0)
 {
  nrPins++;
  Serial.print("=A7 ");
 }

// 2) Data processing

 // Calculate average, buffer energy etc...
 if (nrPins!=0)
 {
  Tav=(T1+T2+T3+T4+T5+T6+T7+T8+T9+T10+T11+T12+T13+T14+T15+T16)/nrPins;
  Serial.print(" T-av = ");
  Serial.println(Tav,1);
 }

 // 3) Data broadcasting to Google
 sprintf(resultstr, "{\"T1\":%lg,\"T2\":%lg,\"T3\":%lg,\"T4\":%lg,\"T5\":%lg,\"T6\":%lg,\"T7\":%lg,\"T8\":%lg}", T1, T2, T3, T4, T5, T6, T7, T8);

 // 4) Test conditions and send status & alert messages, take actions: Pumps, valves...
 if (T1 > 30) // Example...
 {
  Serial.println("T1 > 30 deg");
  Particle.publish("Status","T1 > 30 deg",60,PRIVATE);
  RGB.control(true); // start control RGB LED
  RGB.color(255, 255, 255);// RGB LED White
  delay(1000);
  RGB.control(false); // stop control RGB LED
 }
 delay(500); // Slow down!
}

// In this function I'd like to integrate a "median filter":

void analyze(pin_t pulsePin)
{
  RGB.control(true); // control RGB LED
  RGB.color(255, 0, 0);// RGB LED Red

  unsigned long startTime, endTime; // Variable to record the start & end time
  int nrPulses = 160;  // Even number: Number of HI+LOW pulses (Number of spaces in array)
  int periods = nrPulses/2;  // For this sensor, use a multiple of 8! (See datasheet)
  int dataCounter;
  byte storedData[nrPulses]; // Array to store the data
  // Use floating variables for calculations
  float transmissionDuration, transmissionDurationSec, totalCount, totalLowCount, totalHighCount, dutycycle, frequency;
  temperature=0;// Reset each time
  frequency=0;

  pinMode(pulsePin, INPUT_PULLUP);// Make the pin HIGH without signal

  startTime=micros(); //Start time to measure wait time
  while(digitalRead(pulsePin) == HIGH)  //Detect NO CONNECTION; Wait for LOW signal:
  {
    if ((micros()-startTime) > 10000) // If it takes longer than 10ms, quit function!
    {
     return;// Exit the function!
    }
  }
  RGB.color(0, 0, 255);// RGB LED Blue

  while(digitalRead(pulsePin) == LOW)  //Wait here until a HIGH signal is received:
  {
   startTime=micros(); //Reset start time with every recording
  }

  for(int i=0; i<nrPulses; i=i+2) // Record pulse train!
  {
   dataCounter=0; //reset the counter
   while(digitalRead(pulsePin) == HIGH)
   {
    dataCounter++;
    storedData[i]=dataCounter;
   }

   dataCounter=0; //reset the counter
   while(digitalRead(pulsePin) == LOW)
   {
    dataCounter++;
    storedData[i+1]=dataCounter;
   }
  }
  endTime=micros(); //End time of the pulse train reading

  transmissionDuration=endTime-startTime;
  transmissionDurationSec = transmissionDuration/1000000;
  frequency = periods/transmissionDurationSec;
  //Serial.print("Freq = ");
  //Serial.println(frequency,0);

  totalLowCount=0; //reset accumulator
  totalHighCount=0; //reset accumulator

  for(int i=0; i<nrPulses; i=i+2)
  {
   totalHighCount=totalHighCount+storedData[i]; // Total all HIGH pulses
   totalLowCount=totalLowCount+storedData[i+1]; // Total all LOW pulses
   //Serial.print(storedData[i]);
   //Serial.print(",");
   //Serial.println(storedData[i+1]);
  }

  totalCount=totalHighCount+totalLowCount;
  dutycycle=totalHighCount/totalCount;
  temperature = (212.77*dutycycle)-68.085;
  if (temperature!=0)
  {
    Serial.print(temperature,1);
  }
  RGB.control(false); // end RGB LED control
}