CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Getting analog input from a microphone and FFT transform.
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ranii



Joined: 11 Sep 2013
Posts: 16

View user's profile Send private message

Getting analog input from a microphone and FFT transform.
PostPosted: Tue Sep 24, 2013 1:00 pm     Reply with quote

Hi.
Using a pic, i need to get the signal from the analog input, that will be generated from a microphone in a small distance.

To get the signal i will set only a microphone pre-amp with one bjt transistor- that goes right into the ADC of the pic.

- is it enough good to pick the signal from close distance or i need more?

I need to identify the frequency of the signal, which i am going to use some algorithm that is not an FFT, since i know FFT is a little bit problem for the pic, so i was thinking using Goerzel-Algorithm to get the frequency of a certain f.

-is there a way to get a real fft with some dspic ? are there some library to make it easy ? using the simpe C algorithm with Goerzel is reasonable ?

Thanks a lot.
Pol.
ranii



Joined: 11 Sep 2013
Posts: 16

View user's profile Send private message

more data
PostPosted: Tue Sep 24, 2013 1:29 pm     Reply with quote

more data:

1. it should not be in real time, but even picking the data for 1 second, than perform the fft, is great.

2. the frequencies are 16-18khz (mic is good for that).

3. the fft resolution needs to be of about 100hz.

I don't need to draw a graph or something, just pick some signal for a second, and check his fft and a few more things.

How can you collect so many samples of 1 full second ? Do I need to calculate a window each time again and save only the results ?
temtronic



Joined: 01 Jul 2010
Posts: 9162
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Sep 24, 2013 3:03 pm     Reply with quote

first problem to solve..
'audio' is 'bipolar',swinging both positive and negative...and the PICs ADC is 'monoploar', only accepts zero to say +5 volts.

...so first thing to do is 'level shift' the analog to be 'zero' at 2.5Vdc. Simple opamp101 circuits will work.

test using say a 1KHz sinewave, and develop your code, with this known source..then...expand to other frequencies.

hth
jay
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Tue Sep 24, 2013 3:05 pm     Reply with quote

what PIC do you have in mind?

The adc in the pic is probably inadequate, but
ADC performance is not your biggest challenge:

the extensive TRIG and floating point calcs to
do anything with your samples is going to crush you,
especially given the upper end of your frequency
detection range .

and the slowest sampling rate required for a so-so detection
of 18khz will require about 80ksps (++) .......,

taken together, i would not attempt this with a pic:
the number gods are NOT lined up in favor Very Happy Very Happy
ranii



Joined: 11 Sep 2013
Posts: 16

View user's profile Send private message

the algorithm .
PostPosted: Wed Sep 25, 2013 2:16 am     Reply with quote

Thanks both .
I guess its little bit hard with a pic but i know of many examples on the net, of people that did that even with pic17f .

I guess that some simple algorithm such as goerzel is reasonable , i will put the algorithm here and tell me what you think :

This function gets all the samples (can i save them all?? )and check fft only in one given bin (frequency) .

Code:
float goertzel_mag(int16_t* data ,int SAMPLING_RATE ,double TARGET_FREQUENCY,int numSamples )
{
    int     k,i;
    float   floatnumSamples;
    float   omega,sine,cosine,coeff,q0,q1,q2,magnitude,real,imag;
    float   scalingFactor = numSamples / 2.0; // -2
   
    floatnumSamples = (float) numSamples;
    k = (int) (0.5 + ((floatnumSamples * TARGET_FREQUENCY) / SAMPLING_RATE));
    omega = (2.0 * M_PI * k) / floatnumSamples;
    sine = sin(omega);
    cosine = cos(omega);
    coeff = 2.0 * cosine;
    q0=0;
    q1=0;
    q2=0;
   
    for(i=0; i<numSamples; i++)
    {
        q0 = coeff * q1 - q2 + data[i];
        q2 = q1;
        q1 = q0;
    }
   
   
    real = (q1 - q2 * cosine) / scalingFactor;
    imag = (q2 * sine) / scalingFactor;
   
    //double theta = atan2 ( imag, real); //PHASE
    magnitude = sqrtf(real*real + imag*imag);
    return magnitude;
}


Can this be done on a pic ?
oxo



Joined: 13 Nov 2012
Posts: 219
Location: France

View user's profile Send private message

PostPosted: Wed Sep 25, 2013 2:57 am     Reply with quote

Doesn't look too bad, but as asmboy says, the difficult part will be sampling the signal.

Remember that the samples must be at precisely equal time periods.. jitter will spoil the results.

If your signal is periodic over the number of samples, then you don't need to window it. However, I suspect it won't be periodic, and you will have to have many more samples in your dataset to smooth the window edges.
temtronic



Joined: 01 Jul 2010
Posts: 9162
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Sep 25, 2013 7:18 am     Reply with quote

re:...
This function gets all the samples (can i save them all?? )and

...providing you have the correct PIC , yes,though maybe storing into FRAM would be a good idea.

You'll hve to 'do the math' to see how much memory you need.

re:...
Can this be done on a pic ?

...yes, again, you'll have to 'do the math' to decide which PIC has the speed and processing power for the task.There's way to many factors and variables for us to say which PIC. Frequency, analog 'front end', how precise a result you need( not want !),cost of project,one off ? or production run ??,etc.
You'll need to do some serious 'r&d' to decide which route to take, but bottom line is that yes, a PIC will do the job.


hth
jay
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Wed Sep 25, 2013 8:59 am     Reply with quote

lets say you DO have a way to store the samples, ( which i doubt)

if you can't sample and store at 80,000+ samples/sec
with a jitter of less than 3.5 usec then the results at your top frequency
of interest, aren't going to matter, because they will be woefully:
a) inaccurate
b) unstable

the code space for the trig functions/float point math
is going to be significant , as will be the execution cycles per data point
with your chosen algorithm.

and i don't see which pic can let you interleave data reading with calculation, given your top frequency you wish to discriminate.


good luck with the project.
Ttelmah



Joined: 11 Mar 2010
Posts: 19328

View user's profile Send private message

PostPosted: Wed Sep 25, 2013 9:25 am     Reply with quote

You need to quantify things quite a bit (lot) more.

However a few of the later PIC18's, and many (most) DsPIC'c, have a reasonable amount of RAM, and ADC's that are fast enough to (possibly) do this - depending on what you actually want to do...

You'd need to sample for (say) about 1/20th second, and sample synchronously to the CCP. Don't use an interrupt, but have the CCP start the ADC, wait for it to say 'conversion complete', immediately read it, and go back to waiting. Repeat for the sample time, then perform the FFT.
On the PIC 18, the RAM would limit you to perhaps 3000 readings, and sampling at 80KHz, you could read for 1/26th second. Only a chip like the 87K90 could manage this (it is one of the few that has an ADC fast enough). You'd then take more time to process the data, and could resolve plenty 'below the target frequency, but little above. However something like a simple 'signal present' detection could be done, and would lag by only perhaps 1/10th second.

You could 'improve' on this with some of the DsPIC's, using two buffers Some of the PIC33 chips have enough RAM to give more data and enough speed to perform the maths much quicker. However you are getting into really 'precision' programming, with a lot of careful work needed.

However I'd say the odds are better than 99%, that there would be a better (and simpler) way of doing what you want, if you told us what it is. There are for instance 'off the shelf' programmable filter chips.

So, more data needed....
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Wed Sep 25, 2013 2:12 pm     Reply with quote

if trying to use PIC SRAM its actually worse than Mr. T says.

8 bit resolution will not do a very good job of discriminating frequencies

the 12 bits a 18f46k80 offers are more like it,
but require 2 sram locations for storage of each reading

even with NO other VAR usage ( tall order !)
- you are down to only 1800 samples or less

still a hard pull IMB.

with fast enough sampling - even 8 bits might be enough if you don't use the FFT method however.
The key to an alternative method is sampling fast enough with low enough jitter. BUT it would only work well for sine or square wave input.
But for complex Waveforms FFT is it.
ranii



Joined: 11 Sep 2013
Posts: 16

View user's profile Send private message

THANKS!
PostPosted: Thu Sep 26, 2013 2:27 am     Reply with quote

Thanks to all of you for your answers, it helped me a lot .

As you said, i have to define to you more about what we do .
Well , we need to send a DTMF signals at the frequecies of 16-18khz.

At each moment, there will be only one pure sin wave of a certain f .
Noise probably , but not too much .
The delta between the f's is about 200hz, but if making it 500hz will be easier so we can do that . (sampling rate at 40khz is too high for ADC? )

Final goal is some kind of fsk (as a part of a bigger system) .

some idea :

Should we put instead, some kind of a serial band pass filters at a certain frequencies, going into the pic directly and do the "hard" job, so the pic will get high pin when a certain f is there ? is that a good/better idea ?
I think for that to work, we need some band pass filters at a very high resolution, and capacitors have drifts and i am not sure they can be at 200-500hz accuracy (when they small enough).
Ttelmah



Joined: 11 Mar 2010
Posts: 19328

View user's profile Send private message

PostPosted: Thu Sep 26, 2013 3:43 am     Reply with quote

I'd say this is a perfect case for a PLL. The output voltage of the PLL drive, will match the signal frequency shift. Much simpler, and potentially do-able in real time, rather than having to stop and process.
Effectively the circuit used in an FM decoder.

Remember that a signal shifting in frequency produces tonal values above the two fundamentals. So if you have a frequency going from 18KHz, up to 18500Hz, depending on the rate of change, the detector has to be able to handle frequencies well above 18500Hz. This is why we are all talking about much higher sampling frequencies than a simple Nyquist criterion on the fundamental signals....

Best Wishes
ranii



Joined: 11 Sep 2013
Posts: 16

View user's profile Send private message

thank
PostPosted: Thu Sep 26, 2013 4:25 am     Reply with quote

Thanks T.

Well pll is great idea but i have 2 problems with that :

1. our circuit has to be mass production , and a pll is expensive isn't it ?
(compare to a few transistors )

2. i couldn't understand what is the setup- i am amplify a microphone, than put that into a pll , that in turn gives me voltages/frequencies , and these voltages going to a pic ADC ??

Do you have in mind any nice cheap pll for that job ?

Thanks again ,you helped me a lot .
oxo



Joined: 13 Nov 2012
Posts: 219
Location: France

View user's profile Send private message

PostPosted: Thu Sep 26, 2013 6:25 am     Reply with quote

Quote:
At each moment, there will be only one pure sin wave of a certain f .


If that's true, then the simplest thing would be to square it up ( or use a zero-crossing detector) then measure the period with a timer input.
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Thu Sep 26, 2013 7:23 am     Reply with quote

you said:
Quote:

DTMF signals at the frequecies of 16-18khz.


then you said
Quote:

At each moment, there will be only one pure sin wave of a certain f .


ordinary DTMF is much lower in frequency unless this is not CCITT DTMF

http://www.dialabc.com/sound/dtmf.html

The combined cognitive dissonance of the statements
really has my head spinning.
BTW: cheap PLL 74hc4046
or advanced 74hct9046 ( real nice - real cheap)







Idea Question Question Question


Last edited by asmboy on Thu Sep 26, 2013 7:25 am; edited 1 time in total
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group