Codes reading from an electret mic failes after some time

Hi. I am making a clapper switch and the code I wrote works just fine except it completely stops working after some time. I tryed to test this again with this code (to see if it was the external hardware or the code itself that failed):

void setup() {
pinMode(13, OUTPUT);
}

void loop() {
int value = analogRead(A0);
if (value > 1000) {
digitalWrite(13, HIGH);
delay(1000);
digitalWrite(13, LOW);
}
}

After some minutes this failed aswell and the LED stopped lighting up when I clapped my hands. This does not happen with the blink example so it is indeed the arduino which stops caring about the data it gets from the external hardware. The circuit that is connected to the arduino is soldered to a prototyping board and looks like this:

Resistors, R1 =R2 = 4.7k, sets the reference at mid point between VCC = 3V and ground. Thus, this set the op amp for single supply use. The gain of this preamplifier, which is 34dB (50x), is set by resistors R3 = 10k and R4 = 500k. A 10 MHz gain bandwidth product for the LMV721 is more than enough for most audio application since the normal audio range is from 20 Hz to 20kHz. A resistor R5 =5k provides the bias voltage for the electret microphone. Capacitors C1 =C2 = 4.7µF at the input and output is provided to block out the DC voltage offset.

I also tried to print the analog information using Serial.println(value, DEC); to see what data it was getting when the program seemed to fail. It supprised me to see that it was still reading a value of around 600 (which is when there is no sound in the room) and connecting it to ground did indeed give a reading of 0.

So to sum it up. After a while it would seem like the electret mic is simply unplugged from the circuit and the only way to "plug" it back in is to reupload the code (reset or unplugging/plugging the power does not work). What is wrong here?

  int value = analogRead(A0);

A0 is an alias to be used when using analog pin 0 as a digital pin. Since that is not what you are doing, you are not using the correct pin number.

It should be:

  int value = analogRead(0);

Where do you have the analog pin connected? if it is to the point marked "Output" in the circuit diagram, then the problem is that the DC level of the analog input pin is undefined. Assuming Vcc in the diagram is the Arduino +5v connection, you should connect the analog pin direct to the op-amp output, not through a capacitor. Then change the constant that you compare 'value' with from 1000 to whatever gives you the required sensitivity. If R1 = R2 in your diagram, then a value close to 512 will give you a high sensitivity, and a value close to 1023 will give you a low sensitivity.

Thanks for the replys.

A0 is an alias to be used when using analog pin 0 as a digital pin. Since that is not what you are doing, you are not using the correct pin number.

I am very new to the arduino and programming in general, but I'm abit curious about this. The "AnalogReadSerial" example uses the code "int sensorValue = analogRead(A0);" and it is not using the analog input as a digital input. I've been typing "A0" every time I'm reading from the analog input and it has been working fine, why would it keep reading analog data when I ask it to read digital data?

Where do you have the analog pin connected? if it is to the point marked "Output" in the circuit diagram, then the problem is that the DC level of the analog input pin is undefined. Assuming Vcc in the diagram is the Arduino +5v connection, you should connect the analog pin direct to the op-amp output, not through a capacitor. Then change the constant that you compare 'value' with from 1000 to whatever gives you the required sensitivity. If R1 = R2 in your diagram, then a value close to 512 will give you a high sensitivity, and a value close to 1023 will give you a low sensitivity.

I've skipped the cap on the output now, just have to wait for a while to see if it stops working :wink:

It seems to be working :smiley: The code has been running for quite some time now without failing. But how can a cap like that make the whole thing fail after a random amount of time, and not only that, refuse to work again unless you reupload the code?

The "Ax" aliases are valid for both analogue and digital use.

Cap was cutting off DC offset voltage, in other words analog input received pure AC. And I think negative semi-wave injected enough current into analog port, so microprocessor stop working. Atmel doesn't tolerate negative voltage at the inputs, btw what is the OPA on the drawings?

Magician:
Cap was cutting off DC offset voltage, in other words analog input received pure AC. And I think negative semi-wave injected enough current into analog port, so microprocessor stop working. Atmel doesn't tolerate negative voltage at the inputs...

Maybe, but I think it's more likely that the DC level of an essentially floating pin was starting off at Vcc/2 when the board powered up and the capacitor was discharged, and gradually drifting towards ground over time due to input leakage current. The atmega chip is supposed to handle a couple of mA negative or positive current injected into the input pins when they are below ground or above Vcc, so I doubt that the microproessor stopped working.

more likely that the DC level of an essentially floating pin was starting off at Vcc/2 when the board powered up and the capacitor was discharged, and gradually drifting towards ground

Yes, till first clap.

The atmega chip is supposed to handle a couple of mA negative or positive current injected into

They say 1 or 5 mA at maximum, average OPA LM358 could drive 50 mA.

so microprocessor stop working.

It didn't stop working. If I disconnected the wire from the external hardware, the analog reading started floating and a value above 1000 activated the led.

The op-amp I'm using is a MC1458L

I wan't to be able to have my clapper switch as sensetive as possible (adjusting it with a pot of course). I'm using a 1M resistor as R4 and the way it is now, the value is jumping up and down from 500 to 800 regardless of the sound level, but having the threshold at 850 or 900 makes the clapper work fine. What is the cause of the jumping up and down from 500 to 800? Is R4 simply too large?

What is the value of R3?

As it stands, that circuit is sensitive to noise on the Vcc line. I suggest adding a capacitor in parallel with R2. I can't suggest a value without knowing the values of R1 and R2.

It would also be a good idea to filter the Vcc supply to R5 with an R-C network. The values I would suggest depend on the value of R5.

Resistors, R1 =R2 = 4.7k, sets the reference at mid point between VCC = 3V and ground. Thus, this set the op amp for single supply use. The gain of this preamplifier, which is 34dB (50x), is set by resistors R3 = 10k and R4 = 500k. A 10 MHz gain bandwidth product for the LMV721 is more than enough for most audio application since the normal audio range is from 20 Hz to 20kHz. A resistor R5 =5k provides the bias voltage for the electret microphone. Capacitors C1 =C2 = 4.7µF at the input and output is provided to block out the DC voltage offset.

I notised that I actually forgot R3 so I rebuilt it on a breadboard with a 10uf cap in parallel with R2. All values except R4 are as described above.

It would also be a good idea to filter the Vcc supply to R5 with an R-C network. The values I would suggest depend on the value of R5.

Could you describe this a little further? What kind of RC network are you thinking about?

Plecto:

It would also be a good idea to filter the Vcc supply to R5 with an R-C network. The values I would suggest depend on the value of R5.

Could you describe this a little further? What kind of RC network are you thinking about?

Something like a 1K resistor from Vcc to one end of R5, other end of R5 to the mic, and 100uF between the junction of the 2 resistors and ground. Alternatively, increase R5 to about 50K if the microphone is OK with that, then make the new resistor 10K and use 10uF to ground.

Try this, makes everything much easier. Less noise, compression. Free samples from factory!

Just soldered a new board with the adjustments you recommended and it now works like a charm :smiley: My final question is how high gain I can put on this thing? What would happen if I put a 10M resistor as R4? The mic I am using is one of these:
http://www.taydaelectronics.com/servlet/the-1886/Miniature-MINI-CONDENSER-MICROPHONE/Detail

Plecto:
Just soldered a new board with the adjustments you recommended and it now works like a charm :smiley: My final question is how high gain I can put on this thing? What would happen if I put a 10M resistor as R4? The mic I am using is one of these:
http://www.taydaelectronics.com/servlet/the-1886/Miniature-MINI-CONDENSER-MICROPHONE/Detail

The input bias current for that op-amp you are using is 500nA maximum and temperature-dependent. The input bias current flows through R4 and gives rise to a temperature-dependent offset voltage at the output. I think you should aim to keeop this offset voltage at 0.5v or less, which implies R4 no more than 1M.

If you want a larger gain, you need to switch to an op-amp with jfet or mosfet inputs to get a lower input bias current.