Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Problem: ADC with microphone input (PIC18F4550)

Status
Not open for further replies.

DrStu

New Member
uC - PIC18F4550 (Compiler: MPLAB MC18)

I'm trying to build a simple circuit using the built in ADC of the PIC to convert the analog values from an electret microphone.

Objective:
- Light up an LED if the sound amplitude is above a certain level

Brief Block Diagram:
Mic -----> Amplifier -----> PIC

Problem:
So far i've not been able to make the PIC work with the mic. Unsure whether the problem is in the amplifier stage or the coding of the ADC. Btw, i've tested the ADC using DC voltage and it works fine. (LED lights when ADC connected to +5V DC and vice versa). It just wouldn't work with the mic.

Circuit Used:
Mini Amplifier with LM386. The LM386 is a low voltage audio power amplifier, simple and easy to build a mini amplifier with only a few components. (7/3/2006)
(Using the general purpose amplifier from this site)

Code:
#include <p18cxxx.h>
#include <adc.h>

//Global Variables
int ADC_Output=0;

#pragma config FOSC = HS
#pragma config WDT = OFF /* Turn the watchdog timer off */
#pragma config LVP = OFF /* Turns Low Voltage Programming off */
#pragma config MCLRE = ON /* To enable MCLR - To enable PIC reset */

void main()
{

    TRISA = 0xFF;

    TRISC = 0x00; /*Configure Port C as All Output*/
    LATC = 0x00;

    // configure A/D convertor
    OpenADC( ADC_FOSC_16     &
         ADC_RIGHT_JUST &
         ADC_12_TAD,
         ADC_CH0     &
         ADC_INT_OFF ,
         ADC_VREFPLUS_VDD);

    while (1)
    {
        ConvertADC(); // Start conversion
        while( BusyADC() ); // Wait for completion
        ADC_Output = ReadADC(); // Read result
        if (ADC_Output>512){
            LATC=0b11111111;
        }
        else {
            LATC=0b00000000;
        }
    }
}

Any help would be much appreciated. I'm not very familiar with audio signals (as in mic and the amplifier stage). Thx! ....Very Very Much!
 
Hey thx nigel :) I've actually refered to ur tutorial for LED Matrix multiplexing and i must say it was truly very helpful :) (though i'm not coding mine in assembly language)

BTW, I've tried putting a diode at the output, but theres no difference with the original output, which is fixed output (at about 2 to 2.5V DC).

ALso, there's this dat i i'm quite confused about...is the output an oscillating wave or a constant DC voltage? coz if it is oscillating then the value read by the ADC will juz keep varying isnt it ?

Also, wad does it mean by
the output is automatically
biased to one half the supply voltage.
....got it from the datasheet of LM386 ...
 
Look at the application notes for the LM3915/LM3914.

yea...did came across this searching the net while troubleshooting for this prob... but actually this is juz part of a larger project i'm trying to do using the PIC ...i'm not merely trying to juz light the led and so using the ADC directly would reduce the chip count

anyway do appreciate ur reply :)
 
Hey thx nigel :) I've actually refered to ur tutorial for LED Matrix multiplexing and i must say it was truly very helpful :) (though i'm not coding mine in assembly language)

BTW, I've tried putting a diode at the output, but theres no difference with the original output, which is fixed output (at about 2 to 2.5V DC).

ALso, there's this dat i i'm quite confused about...is the output an oscillating wave or a constant DC voltage? coz if it is oscillating then the value read by the ADC will juz keep varying isnt it ?

You need to rectify and smooth it, paying attention to the attack and decay times. As suggested, checking circuits using the LM3915 will provide various examples - you can't just stick a diode on the output of the opamp.
 
DrStu
There are several ways to do this. I have done (but do not recommend) AC couple the audio amplifier to the PIC analog pin. Use two resistors to get the DC to 2.5 volts. (1/2 supply) Read the ADC as fast as possible (50,000/second). Treat the numbers as + and – values. In software full wage rectify. Find absolute value. Filter in software. This is low parts count but difficult in software.
--OR--
Use the op-amp circuit commonly used with the LM3814. It full wave rectifies the audio, filters in a response that is much like that speed of a mechanical movement meter. Now the analog is ‘slow’ and the software is much simpler. You could sample at only 200 times a second and get good results.
 
many thanks nigel and ronsimpson :) many many thx :) my prob initially was down to one basic point....i tot that the input signal is constant. (hehe :p ...i know i know its such a easy thing to get wrong :p ....even my lecturer was like...shocked...hahaha)..and well i guess i juz haven worked with mic bfore hehe


Anyways...today i went to sch so that i could use an oscilloscope look at the output of the amp ....eth looks fine as in its a random signal which rises in amplitude when i make some noise.....

btw ronsimpson, the DC of the signal is already at 2.5V (a function of the LM386) .... now i'll try the software and hardware rectifying.....

I'll get back here after i've done them. Thx guys!
 
hi guys, still trying to get it to work but am wondering bout this:

since i'm not actually trying to reproduce the audio signal, juz trying to light LEDs according to the amplitude of the audio wave (somewhat the same as wad LM3915 does but using a PIC instead) ....so is it necessary to sample at that high rate? (40k sps? ...as in twice the highest audio frequency?) ...im thinking that since our human eye cant response to that high a frequency...eventhough the LEDs lights at that fast a rate we cant see the fast changes? ...or am i missing out something? :confused:
 
hi guys, still trying to get it to work but am wondering bout this:

since i'm not actually trying to reproduce the audio signal, juz trying to light LEDs according to the amplitude of the audio wave (somewhat the same as wad LM3915 does but using a PIC instead) ....so is it necessary to sample at that high rate? (40k sps? ...as in twice the highest audio frequency?) ...im thinking that since our human eye cant response to that high a frequency...eventhough the LEDs lights at that fast a rate we cant see the fast changes? ...or am i missing out something? :confused:

LIke I said above, rectify the audio, and smooth it (paying attention to attack and decay times), then just sample it everytime you wish to update the display.
 
Bro,i think i dping a same title with u,but i'm using music as my input(you's mic), initially,i low pass my music to 4Khz,and now i dono what microcontroller can A/D my signal.......i use music to control somethings oso......any1 please help
 
Hello, i am facing problems with pic18f4550 can u help me with it.
i want to read portB thats it.
i have set the TRISB=1;
ADCON=0x0F;
but dont get anything.
what should i do. i am asking u because u r using adc therefore u must have done this.
thanks.
 
yes nigel im trying to rectify it in the software... but can still not progress and this is starting to get real frustrating...hehe :)

anyway...
i've tried rectifying the signal inside the software (inverting any signal below 2.5V with respect to 2.5V) ...
and yet when i test it with the ADC, it is reading a constant 5V from the amplifier output...

(Tested the amplifier outwith wih a scope.....it shows 2.5V DC but when i swicth it to AC mode,
it shows it oscilaating at -2.5V to 2.5V .....is this possible?)
 
Hi,
If you're checking the audio magnitude continuously, at one time you may have sampled the lowest point of the signal, and the next sampling cycle (or few cycles later) you may have sampled the peak of the signal. Possible the LED is blinking and you don't realize?
 
yes nigel im trying to rectify it in the software... but can still not progress and this is starting to get real frustrating...hehe :)

Far easier to rectify it externally, making the software extremely simple.

Try posting the circuit you're using, I suspect you may be doing things wrongly.
 
Last edited:
The circuit you posted is missing very important parts that stop the LM386 amplifier from oscillating:
1) A supply bypass capacitor.
2) A 10 ohm resistor in series with a 0.047uF ceramic disc capacitor at the output to ground.

Look at the datasheet of the LM386 to see them.
 
Hi,
If you're checking the audio magnitude continuously, at one time you may have sampled the lowest point of the signal, and the next sampling cycle (or few cycles later) you may have sampled the peak of the signal. Possible the LED is blinking and you don't realize?

i did tot of this too bananasiong ...but i dun think this is the reason... bcoz i tested it in a quiet place and the output is ocillating at <1V .(observed through oscilloscope)...
 
Last edited:
Far easier to rectify it externally, making the software extremely simple.



tried external rectifying...did check out the rectifier circuits with the LM3915, prob is by using LM386 the output is automatically biased to 2.5V ....so the rectifier circuits of the LM3915 won't work (i guess....)

Try posting the circuit you're using, I suspect you may be doing things wrongly.

still using the same amplifier circuit
(Mini Amplifier with LM386. The LM386 is a low voltage audio power amplifier, simple and easy to build a mini amplifier with only a few components. (7/3/2006))

this is the code im using to do the rectifying + averaging
Code:
OpenADC( ADC_FOSC_2 	& 
		 ADC_RIGHT_JUST &
		 ADC_8_TAD,
		 ADC_CH0 		& 
		 ADC_INT_OFF ,
		 ADC_VREFPLUS_VDD);

while (1)
{
	int i;
	Sum=0;

	LATC=0b00000000;

	for (i=0; i<10; i++){ 
		Delay10TCYx( 5 ); // Delay for 50TCY
		ConvertADC(); // Start conversion
		while( BusyADC() ); // Wait for completion
		ADC_Output = ReadADC(); // Read result

		if (ADC_Output>512+100){
			ADC_Output=ADC_Output-512-100;
			//LATCbits.LATC0 = 1;
		}
		else if (ADC_Output<512-100){
			ADC_Output=512-ADC_Output-100;
			//LATCbits.LATC1 = 1;
		}
		else{
			ADC_Output=0;
			//LATCbits.LATC1 = 1;
		}

		Sum=Sum+ADC_Output;

		Delay1KTCYx( 5 ); // Delay for 1ms
	}
	
	Sum=Sum/10;

		if (Sum<100){
			LATCbits.LATC0 = 1;
			Delay10KTCYx( 500 );
		}
		else if (Sum <250) {
			LATCbits.LATC1 = 1;
			Delay10KTCYx( 500 );
		}
		else{
			LATCbits.LATC2 =1;
			Delay10KTCYx( 500 );
		}
	}

juz realised sth REALLY wrong with this coding....even if i connect the ADC to 5V DC, C1 is lighted instead of C2
 
Last edited:
The circuit you posted is missing very important parts that stop the LM386 amplifier from oscillating:
1) A supply bypass capacitor.
2) A 10 ohm resistor in series with a 0.047uF ceramic disc capacitor at the output to ground.

Look at the datasheet of the LM386 to see them.

Thx :)

but i've added those into the circuit and yet problem not solved
 
Thx :)

but i've added those into the circuit and yet problem not solved
An LM386 power amplifier circuit works perfectly when it is built with all the important parts on a pcb. It might oscillate if it is built all spread out or built on a breadboard.
 
Status
Not open for further replies.

Latest threads

Back
Top