Some general comments:
Code:
READ:
currentState = digitalRead(BUTTON_PIN);
if(lastState == HIGH && currentState == LOW)
Serial.println();
else if(lastState == LOW && currentState == HIGH)
Serial.println();
// save the the last state
lastState = currentState;
if(currentState == LOW)
goto READKEYS;
else if (currentState == HIGH)
goto READ;
READKEYS:
// ...
Don't use goto, use human-readable control structures like if, while, do-while, for, function calls, etc. instead:
Code:
do {
currentState = digitalRead(BUTTON_PIN);
if(lastState == HIGH && currentState == LOW)
Serial.println();
else if(lastState == LOW && currentState == HIGH)
Serial.println();
// save the the last state
lastState = currentState;
} while (currentState == HIGH);
// ...
Using this while loop (or goto) here might not be a great idea, it blocks the entire system while waiting for a button press. It might be better to just poll the button input once on every iteration of the loop function. Or better yet, use a library that abstracts all the state change detection and debouncing away from the user.
Unless you're doing exercises for an algorithms course or unless you have really specific requirements, don't write your own sorting algorithms (especially not bubble sort). Use the standard library function `std::sort`. Don't use `qsort` unless you're limited to C.
Code:
#include <algorithm>
std::sort(std::begin(analogValues), std::end(analogValues));
// the analogValues array is now sorted, from beginning to end
In fact, you don't even need to sort the array at all, to calculate the median, you just need the element in the middle, sorting the rest is unnecessary work. Use the `std::nth_element` function:
Code:
#include <algorithm>
const int numReadings = 9;
int analogValues[numReadings] = {9, 4, 1, 5, 7, 6, 3, 2, 8};
auto median = std::begin(analogValues) + numReadings / 2;
std::nth_element(std::begin(analogValues), median, std::end(analogValues));
Serial.print("The median is ");
Serial.println(*median); // 5
Going even further, a median filter is usually overkill for filtering an analog input. Averaging (possibly with hysteresis) is usually sufficient.
int readingNumber; // counter for the sample array
This should be a local variable inside your loops, don't make it global. Idem for your other loop indices and temporary variables: make them as local as possible.
Code:
for (int readingNumber = 0; readingNumber < numReadings; readingNumber++)
int numReadings = 9; // number of samples to take
int analogValues[9];
Don't leave room for these to get out of sync if you change one:
Code:
const int numReadings = 9;
int analogValues[numReadings];
Code:
// average the values in the array:
int averageArray() {
int total = 0;
int average = 0;
for (i = 0; i< numReadings; i++) {
total = total + analogValues[i];
}
average = total/(numReadings + 1);
return average;
}
This can be a one-liner:
Code:
#include <numeric>
// add up all elements in the array and divide by the number of elements
return std::accumulate(std::begin(analogValues), std::end(analogValues), 0) / numReadings;
In fact, if you remove the median filter, you can remove the analogValues array entirely and just keep a running sum while you're doing the measurements.