# Find the largest values of analog data

Hello,

In my current project I am trying to find the 10 largest values coming in from analog data (A0) between the 6th second and the 16th second of receiving data. My first thought was to put the analog data in an array, and then sort it, but I am having second thoughts on that.

I’ve taken out quite a bit of my code (all of the array nonsense). Anyway let me know your thoughts.

``````void setup() {
// initialize the serial communication:
pinMode(A0, INPUT_PULLUP);
Serial.begin(9600);

void loop() {
unsigned long timer = millis();
if (timer > 6000 && timer < 16000) {

}

}
``````

I've taken out quite a bit of my code

Yup.

In my current project I am trying to find the 10 largest values coming in from analog data (A0) between the 6th second and the 16th second of receiving data. My first thought was to put the analog data in an array, and then sort it, but I am having second thoughts on that.

I’d really like to see about how many analogRead(A0)data samples you are talking and how you take them (equal time between each sample or different timing between samples?.

My naive approach would be to create an array with 10 elements initializing each element with a value of zero. Then store the first analog value read in the first array position, read the next analog value, store it in the first element position if larger (and move the existing first element to the second position) or store in the second element position if smaller,… Repeat until the end of the timer by moving values around as larger values are read… And when the timer is up, you should have an array of the 10 largest elements ordered largest to smallest.

``````unsigned int starttime = 0;
unsigned int endtime = 0;
unsigned int myvalue = 0;
unsigned int myarray[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

void setup()
{
pinMode(A0, INPUT);
starttime = millis();
endtime = starttime;
}

void loop()
{
endtime = millis();
while((endtime - starttime) >= 6000 && (endtime - starttime) <= 16000) // stay in this while loop between 6 seconds and 16 seconds
{
if (myvalue > myarray[0])
{
myarray[9] = myarray[8];
myarray[8] = myarray[7];
myarray[7] = myarray[6];
myarray[6] = myarray[5];
myarray[5] = myarray[4];
myarray[4] = myarray[3];
myarray[3] = myarray[2];
myarray[2] = myarray[1];
myarray[1] = myarray[0];
myarray[0] = myvalue;
}
else if (myvalue > myarray[1])
{
myarray[9] = myarray[8];
myarray[8] = myarray[7];
myarray[7] = myarray[6];
myarray[6] = myarray[5];
myarray[5] = myarray[4];
myarray[4] = myarray[3];
myarray[3] = myarray[2];
myarray[2] = myarray[1];
myarray[1] = myvalue;
}
else if (myvalue > myarray[2])
{
myarray[9] = myarray[8];
myarray[8] = myarray[7];
myarray[7] = myarray[6];
myarray[6] = myarray[5];
myarray[5] = myarray[4];
myarray[4] = myarray[3];
myarray[3] = myarray[2];
myarray[2] = myvalue;
}
else if (myvalue > myarray[3])
{
myarray[9] = myarray[8];
myarray[8] = myarray[7];
myarray[7] = myarray[6];
myarray[6] = myarray[5];
myarray[5] = myarray[4];
myarray[4] = myarray[3];
myarray[3] = myvalue;
}
else if (myvalue > myarray[4])
{
myarray[9] = myarray[8];
myarray[8] = myarray[7];
myarray[7] = myarray[6];
myarray[6] = myarray[5];
myarray[5] = myarray[4];
myarray[4] = myvalue;
}
else if (myvalue > myarray[5])
{
myarray[9] = myarray[8];
myarray[8] = myarray[7];
myarray[7] = myarray[6];
myarray[6] = myarray[5];
myarray[5] = myvalue;
}
else if (myvalue > myarray[6])
{
myarray[9] = myarray[8];
myarray[8] = myarray[7];
myarray[7] = myarray[6];
myarray[6] = myvalue;
}
else if (myvalue > myarray[7])
{
myarray[9] = myarray[8];
myarray[8] = myarray[7];
myarray[7] = myvalue;
}
else if (myvalue > myarray[8])
{
myarray[9] = myarray[8];
myarray[8] = myvalue;
}
else if (myvalue > myarray[9])
{
myarray[9] = myvalue;
}
endtime = millis();
}

// do something
// like, show the values or something
}
``````

It seems wasteful to type so much over and over again, but it is simple and I think it is efficient in the grand scheme of things. The size of each if else condition gets smaller as you go down the line. I put the reading and ordering inside a while loop to speed up that part of the process during the critical 10 seconds so that whatever you do later with the data won’t bog down the read and sort process loop.

Regarding the question of sample frequency, it should make no difference in regards to sorting. It may affect whether your data is accurate or whether you miss a peak, but… whatever. Get a faster microcontroller if you need to read the data faster for accuracy reasons.

Are 5000 to 10000 analog samples per second enough to capture the data you need to capture?

My first thought was to put the analog data in an array, and then sort it, but I am having second thoughts on

Right on! It is a time honored algorithm, it actually has a fancy name I naturally forgotten. Bubble sort? Shove the values in an array and compare each pair and swap the higher value to "top" and count each swap. Start over until there are no swaps and your are done! Amazingly , I did not need ANY code to agree with you. Not even video! Jim

More like an insertion sort. Bubble sort allows big values to move up while small values move down. Insertion sort doesn’t move the big values while it’s pushing the small ones down.

Do you need any other values? If you only need the largest then just look at the value you have and the value just read from analogRead(). If the new value is larger, then save that, replacing the previous value.

How many readings are there in total? Just 10 ,or are you looking for the top-ten out of thousands?