Go Down

Topic: problem: inconsistent microphone reading. (Read 2334 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
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy