Go Down

Topic: problem: inconsistent microphone reading. (Read 2259 times) previous topic - next topic

makovanx

electret condenser mic to A0 of the analog input.

here is my code:
Code: [Select]
/*
this sketch will test if the electret mic will pick up
signal or input.

the output is generated in the serial monitor(ctrl+shift+m).

the output will show the range of frequencies that the mic
support.
*/

int senseMic = 0
; //analog pin of gizduino

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

void loop(){
Serial.println(analogRead(senseMic));
delay(500);
}


the schematic diagram:


the reading in serial monitor:
Code: [Select]
539
535
533
533
533
530
535
672  //i give a continuous input to the mic fro here to..
252
757
136
757
758 //..here
533
532
536
536
546
562
170  //aslo from here to..
487
758
310
758
758
707  //..here
547
548
542
545
546



what should i do or should i add/take to make the reading more consistent?

Grumpy_Mike

I would expect the readings you get. The signal from a microphone is an audio wave not a sound envelope. What are you expecting?
When you say constant input to the microphone what exactly do you mean?

makovanx

good day sir,
i am expecting that when i give an input to the mic,
the reading will give an above 550 value throughout the duration i am giving it an input.

is there something i can do to make it consistent? or its just natural for the mic to give
a low value time to time when i give an input to the mic?

retrolefty


good day sir,
i am expecting that when i give an input to the mic,
the reading will give an above 550 value throughout the duration i am giving it an input.

is there something i can do to make it consistent? or its just natural for the mic to give
a low value time to time when i give an input to the mic?


What is the specific form of the input you are giving the microphone? An audio signal is never a 'steady' value, if you ever could look at a audio signal on a oscilloscope it might be more clear to you what you are up against. Taking a single 'spot' reading with a analogRead() command tells one almost nothing about the audio signal. I think you need more understand about AC and DC voltages before proceeding too far in this project.

Lefty

makovanx

what i am trying to make sir is a blow sensor,
so, is it just natural for the reading to go down.?

ahm, i'm making this project at home so i don't have an oscilloscope sir,.
sorry,..

dhenry

What you saw makes sense: the output is a 1/2 Vcc dc + an audio signal. So when the mic isn't blown at, it is just the 1/2 Vcc -> 512 adc readings that you are getting.

When the audio signal comes in, the readings start to deviate from 512 -> which is what you observed.

Grumpy_Mike

You need a circuit called a peak detector to turn the signal from the microphone into the sort of signal you are expecting.
Try a seriese diode and a capacitor to ground before the analogue input, also put a resistor in parallel with the capacitor.

dhenry

With what you have, you can solve the problem easily in software:

Code: [Select]

#define THRESHOLD_BLOWN 100 //threshold when mic is blown
#define MEMORY_MIC 16 //moving average memory
#define COUNT_BLOWN 4 //number of consecutive material deviations

unsigned char isblown(unsigned char mic) {
  unsigned short tmp_adc; //temp variable for adc
  static unsigned short mav_mic=0; //moving average
  static unsigned short mdev_mic=0; //moving deviation
  static unsigned char count_mic=0; //consequetive reads when mic is outside of THRESHOLD_BLOWN
 
  tmp_adc = analogRead(mic); //read the mic
  mav_mic += (tmp_adc - mav_mic) / MEMORY_MIC; //calculat the moving average
  mdev_mic += ((tmp_adc > mav_mic)?(tmp_adc - mav_mic):(mav_mic-tmp_adc) - mdev_mic) / MEMORY_MIC; //calculate the moving average of deviations
  if (mdev_mic > THRESHOLD_BLOWN) count_mic+=1; //increment mic
  else count_mic = 0; //otherwise, reset
  return (count_mic>COUNT_BLOWN)?1:0;
}


It does three things:

1) it maintains a moving average of the adc results: essentially a capacitor to block the dc portion of the signal;
2) it detects the amplitude of the ac portion of the signal: so if the mic is blown at, this portion will go up;
3) it then counts the number of times the mic is outside of the levels determined by THRESHOLD_BLOWN and keeps track of it: when the mic returns a high deviation signal over a number of reads (defined by COUNT_BLOWN), the function returns a 1.

So your user code would be something like this:

Code: [Select]

  if (isblown(senseMic)) { //mic is being blown at
    do_something();
  } else {
    do_something_else();
  }



dhenry

Here is this piece in action:

Code: [Select]

#include <stdio.h>
#include <stdlib.h>

#define THRESHOLD_BLOWN 100 //threshold when mic is blown
#define MEMORY_MIC 4 //moving average memory
#define COUNT_BLOWN 4 //number of consecutive material deviations

#define DAT_COUNT 52
unsigned short analogRead(unsigned char adc_ch) {
    const unsigned short dat[DAT_COUNT]= {
        539,
        535,
        533,
        533,
        533,
        530,
        535,
        539,
        535,
        533,
        533,
        533,
        530,
        535,
        539,
        535,
        533,
        533,
        533,
        530,
        535,
        539,
        535,
        533,
        533,
        533,
        530,
        535,
        672,  //i give a continuous input to the mic fro here to..
        252,
        757,
        136,
        757,
        758, //..here
        533,
        532,
        536,
        536,
        546,
        562,
        170, //aslo from here to..
        487,
        758,
        310,
        758,
        758,
        707,  //..here
        547,
        548,
        542,
        545,
        546
    };
    static unsigned char index=0;

    index=(index==DAT_COUNT-1)? 0: (index+1);
    return dat[index];
}

unsigned char isblown(unsigned char mic) {
    unsigned short tmp_adc; //temp variable for adc
    static unsigned short mav_mic=0; //moving average
    static unsigned short mdev_mic=0; //moving deviation
    static unsigned char count_mic=0; //consequetive reads when mic is outside of THRESHOLD_BLOWN

    tmp_adc = analogRead(mic); //read the mic
    mav_mic += (tmp_adc - mav_mic) / MEMORY_MIC; //calculat the moving average
    mdev_mic += (((tmp_adc > mav_mic)?(tmp_adc - mav_mic):(mav_mic-tmp_adc)) - mdev_mic) / MEMORY_MIC; //calculate the moving average of deviations
    if (mdev_mic > THRESHOLD_BLOWN) count_mic+=1; //increment mic
    else count_mic = 0; //otherwise, reset

    printf("count_mic=%4d, tmp_adc = %5d, mav_mic=%5d, mdev_mic=%5d\n", count_mic, tmp_adc, mav_mic, mdev_mic);
    return (count_mic>COUNT_BLOWN)?1:0;
}

int main(void) {
    unsigned char i=0;

    printf("Hello world!\n");
    for (i=0; i<DAT_COUNT; i++) {
    //if (isblown(0)) printf("isblown() = 1\n");
    //else printf("isblown() = 0\n");
    isblown(0);
    }
    return 0;
}


It ran on Turbo C (my favorite tool to write code for mcus). I wrote the analogRead() piece to replicate the data you got from your microphone - you will need to eliminate it from your code.

Code: [Select]

count_mic=   0, tmp_adc =   535, mav_mic=  133, mdev_mic=  100
count_mic=   1, tmp_adc =   533, mav_mic=  233, mdev_mic=  150
count_mic=   2, tmp_adc =   533, mav_mic=  308, mdev_mic=  168
count_mic=   3, tmp_adc =   533, mav_mic=  364, mdev_mic=  168
count_mic=   4, tmp_adc =   530, mav_mic=  405, mdev_mic=  158
count_mic=   5, tmp_adc =   535, mav_mic=  437, mdev_mic=  143
count_mic=   6, tmp_adc =   539, mav_mic=  462, mdev_mic=  127
count_mic=   7, tmp_adc =   535, mav_mic=  480, mdev_mic=  109
count_mic=   0, tmp_adc =   533, mav_mic=  493, mdev_mic=   92
count_mic=   0, tmp_adc =   533, mav_mic=  503, mdev_mic=   77
count_mic=   0, tmp_adc =   533, mav_mic=  510, mdev_mic=   64
count_mic=   0, tmp_adc =   530, mav_mic=  515, mdev_mic=   52
count_mic=   0, tmp_adc =   535, mav_mic=  520, mdev_mic=   43
count_mic=   0, tmp_adc =   539, mav_mic=  524, mdev_mic=   36
count_mic=   0, tmp_adc =   535, mav_mic=  526, mdev_mic=   30
count_mic=   0, tmp_adc =   533, mav_mic=  527, mdev_mic=   24
count_mic=   0, tmp_adc =   533, mav_mic=  528, mdev_mic=   20
count_mic=   0, tmp_adc =   533, mav_mic=  529, mdev_mic=   16
count_mic=   0, tmp_adc =   530, mav_mic=  529, mdev_mic=   13
count_mic=   0, tmp_adc =   535, mav_mic=  530, mdev_mic=   11
count_mic=   0, tmp_adc =   539, mav_mic=  532, mdev_mic=   10
count_mic=   0, tmp_adc =   535, mav_mic=  532, mdev_mic=    9
count_mic=   0, tmp_adc =   533, mav_mic=  532, mdev_mic=    7
count_mic=   0, tmp_adc =   533, mav_mic=  532, mdev_mic=    6
count_mic=   0, tmp_adc =   533, mav_mic=  532, mdev_mic=    5
count_mic=   0, tmp_adc =   530, mav_mic=  532, mdev_mic=    5
count_mic=   0, tmp_adc =   535, mav_mic=  532, mdev_mic=    5
count_mic=   0, tmp_adc =   672, mav_mic=  567, mdev_mic=   30
count_mic=   0, tmp_adc =   252, mav_mic=  489, mdev_mic=   81
count_mic=   1, tmp_adc =   757, mav_mic=  556, mdev_mic=  111
count_mic=   2, tmp_adc =   136, mav_mic=  451, mdev_mic=  162
count_mic=   3, tmp_adc =   757, mav_mic=  527, mdev_mic=  179
count_mic=   4, tmp_adc =   758, mav_mic=  584, mdev_mic=  178
count_mic=   5, tmp_adc =   533, mav_mic=  572, mdev_mic=  144
count_mic=   6, tmp_adc =   532, mav_mic=  562, mdev_mic=  116
count_mic=   0, tmp_adc =   536, mav_mic=  556, mdev_mic=   92
count_mic=   0, tmp_adc =   536, mav_mic=  551, mdev_mic=   73
count_mic=   0, tmp_adc =   546, mav_mic=  550, mdev_mic=   56
count_mic=   0, tmp_adc =   562, mav_mic=  553, mdev_mic=   45
count_mic=   1, tmp_adc =   170, mav_mic=  458, mdev_mic=  105
count_mic=   0, tmp_adc =   487, mav_mic=  465, mdev_mic=   85
count_mic=   1, tmp_adc =   758, mav_mic=  538, mdev_mic=  118
count_mic=   2, tmp_adc =   310, mav_mic=  481, mdev_mic=  131
count_mic=   3, tmp_adc =   758, mav_mic=  550, mdev_mic=  150
count_mic=   4, tmp_adc =   758, mav_mic=  602, mdev_mic=  151
count_mic=   5, tmp_adc =   707, mav_mic=  628, mdev_mic=  133
count_mic=   6, tmp_adc =   547, mav_mic=  608, mdev_mic=  115
count_mic=   0, tmp_adc =   548, mav_mic=  593, mdev_mic=   98
count_mic=   0, tmp_adc =   542, mav_mic=  581, mdev_mic=   84
count_mic=   0, tmp_adc =   545, mav_mic=  572, mdev_mic=   70
count_mic=   0, tmp_adc =   546, mav_mic=  566, mdev_mic=   58
count_mic=   0, tmp_adc =   539, mav_mic=  560, mdev_mic=   49


The code falsely returned a "blown" signal initially, very similar to a capacitor that's being charged up. Once mav_mic has been correctly established, it triggered reliably, as you can see that the count_mic variable goes up / down with the ac portion of the signal.

The code is a copy-and-paste back to your arduino development, minus the printf() piece in isblown().

makovanx

thank you for the informative reply sir Grumpy_Mike and sir dhenry,..

i will study your suggested hardware & software solution to understand them better,
with this, i hope this project of mine will be up and running soon,..
again, thank you kind sirs,..

Go Up