0

Goodafternoon,

I want to read values form a microphone (Adafruit MAX9814) connected to the Analog port A0 from Arduino and store the values that are incoming inside an array.

After the values are stored in the array, I want to read out the values and store the number that is repeated most time in a variable. Is this possible and how to achieve this?

I came up with the following:

const int micPin = A0;
int soundArray[10];

void setup() {

  Serial.begin(9600);
  pinMode(micPin, INPUT);

}

void loop() {

  int micValue = analogRead(micPin);
  Serial.println(micValue, DEC);
  //delay(400);

  for (int i = 0; i > 10; i++) {
    soundArray[i] = micValue;
    Serial.println(soundArray[i]);
  }
  delay(1000);
  Serial.println("End of for loop");


}

The problem now is that a value of the microphone will be repeated 10 times. So I will receive 10 times the number 234 for example. See image.

This is not what I want. I want to get different numbers in the array of that moment. enter image description here

Hope someone can help me out. Thanks in advance.

  • I have a library that does what you want: github.com/MajenkoLibraries/Average – Majenko Jun 24 '15 at 11:50
  • 2
    Since you do not change micValue, soundArray[i] = micValue is always storing the same number. You probably mean soundArray[i] = analogRead(micPin). – Edgar Bonet Jun 24 '15 at 12:11
  • 1
    I'm guessing that the code you posted is not copied from your sketch as the for loop will do nothing. You initialise i to zero then only run the loop whilst i is greater than 10, which it will never be... – Mick Waites Jun 24 '15 at 12:13
1

The error message is correct. You did not define the size of the array. You have 3 choices:

  1. Declare it with a constant length

    int foo[10];

  2. Declare it and initalize it

    int foo[] = {0,1,2,3,4,5,6,7,8,9};

  3. Declare it dynamic as pointer and alloc or realloc the mem by yourself (this is not recommended (realloc) because of possible heap memory fragmentation)

    int foo; int size = 10; foo = (int)malloc(size * sizeof(int)); free(foo);

As reference: http://www.arduino.cc/en/pmwiki.php?n=Reference/Array

  • Ah oke, I understand it. And the third point is to calculate the average? – Caspert Jun 24 '15 at 11:48
  • Add the values together, then divide by the number of values. Simple junior school math. – Majenko Jun 24 '15 at 11:49
  • Maybe I am not asked it right. The values from the analog port will be stored in the array. Then I want to get the number that is repeated most time.. So when I get an array with: (1,2,1,4,5,2,1,3) the number 1 is repeated most type and that one I will store in another variable for example valMost. – Caspert Jun 24 '15 at 11:52
  • Ah, the operation then is called "mode". My Average library (pointed to above) will do mode() for you. – Majenko Jun 24 '15 at 12:00
  • I will check your code @Majenko. Check also my updated answer so there will be no mistakes! – Caspert Jun 24 '15 at 12:01
1

There are three main sorts of "average" used normally in Maths:

  • Mean: This is the most common meaning of Average. It is the mathematical average of all the values in the set - the sum of all the values divided by the number of values.
  • Mode: This is the "most common" value in a set of values. For the set {1, 2, 3, 4, 3, 5, 3, 1, 7, 3} the "mode" would be 3 since there are more 3's than any other number.
  • Median: This is the middle value of a set of values. If there are 5 values and they are sorted into ascending order the "median" would be the third (middle) value.

By your comments it sounds like "mode" is what you are after - the most common number in your set of values.

It's quite easy to work out which is the most common number in a set if you are willing to loop through that set enough times.

I have an Average library that can do it for you. The main part of the mode() function of that library looks like this:

most = _store[0];
mostcount = 1;
for(pos = 0; pos < _count; pos++) {
    current = _store[pos];
    currentcount = 0;
    for(inner = pos + 1; inner < _count; inner++) {
        if(_store[inner] == current) {
            currentcount++;
        }
    }
    if(currentcount > mostcount) {
        most = current;
        mostcount = currentcount;
    }
    // If we have less array slices left than the current
    // maximum count, then there is no room left to find
    // a bigger count.  We have finished early and we can
    // go home.
    if(_count - pos < mostcount) {
        break;
    }
}
return most;

Basically two loops, one inside the other. The outer one steps through each number, and the inner one counts the number of times than number appears in the set (actually just from the current outer loop position to the end of the set - no point in counting numbers we've already looked at). If the count is greater than the current "mode" count then store that as the "mode" count and also store the value as the "mode" value. Move on to the next number.

To use the Average library it's quite simple:

const int micPin = A0;

// We want to be able to store 10 int values here.
Average <int>sounds(10);

void setup() {
  Serial.begin(9600);
}

void loop() {
    // Push 10 values into the Average buffer.  Any old values will drop
    // off the bottom.
    for (int i = 0; i < 10; i++) {
        sounds.push(analogRead(micPin));
    }
    Serial.print("Mode value is: ");
    Serial.println(sounds.mode());
    delay(1000);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.