Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
- Committer:
- eencae
- Date:
- 2014-07-22
- Revision:
- 1:7c6c1f98b8f5
- Parent:
- 0:a497562bb2f9
- Child:
- 2:8da22b498051
File content as of revision 1:7c6c1f98b8f5:
#include "mbed.h" #include "N5110.h" extern "C" void fftR4(short *y, short *x, int N); float magnitude(short y1, short y2); void updateSamples(); void doFFT(); void printSpectrum(); void printSamples(); void ledBarGraph(); void lcdEqualiser(); int calcPeakFrequency(); AnalogIn audio(p17); // ADC pin must be biased at Vcc/2 using coupling capacitor and potential divider BusOut leds(LED1,LED2,LED3,LED4); LocalFileSystem local("local"); // Create the local filesystem under the name "local" Serial serial(USBTX,USBRX); // VCC,SCE,RST,D/C,MOSI,SCLK,LED N5110 lcd(p7,p8,p9,p10,p11,p13,p21); #define BUF_LEN 1024 #define SAMP_FREQ 10000 short samples[BUF_LEN]; // store the values read from ADC short mx[BUF_LEN*2]; // input data 16 bit, 4 byte aligned x0r,x0i,x1r,x1i,.... short my[BUF_LEN*2]; // output data 16 bit,4 byte aligned y0r,y0i,y1r,y1i,.... float spectrum[BUF_LEN/2]; // frequency spectrum char buffer[14]; // screen buffer int main() { // initialise LCD and display welcomes message lcd.init(); lcd.printString("Audio FFT",14,0); lcd.printString("Analyser",20,1); lcd.printString("Craig A. Evans",0,4); serial.baud(115200); leds = 15; wait(2.0); // short pause to allow coupling capacitor to charge leds = 0; lcd.clear(); while(1) { updateSamples(); // read in new analog values ledBarGraph(); // display amplitude bar graph on LEDs from sample values doFFT(); // calc FFT lcdEqualiser(); // plot spectrum on LCD //printSpectrum(); //printSamples(); //int tone = calcPeakFrequency(); // calculate peak frequcny and send over serial for debug //serial.printf("f = %u\n",tone); wait_ms(100); // update display 100 ms } } void ledBarGraph() { float rms = 0.0; // initialse array for (int i = 0; i < BUF_LEN; i++) { rms+= samples[i]*samples[i]; } // calc the sum of the squares rms/=BUF_LEN; // get the mean rms = sqrt(rms); // and root to get the RMS rms/= 16384.0; // scale according to 16-bit signed maximum value // check value and update LEDs to show amplitude if (rms > 0.8) { leds = 15; } else if (rms > 0.6) { leds = 7; } else if (rms > 0.4) { leds = 3; } else if (rms > 0.2) { leds = 1; } else { leds = 0; } //serial.printf("RMS = %f\n",rms); } float magnitude(short y1, short y2) { return sqrt(float(y1*y1+y2*y2)); // pythagoras } void updateSamples() { for (int i = 0; i < BUF_LEN; i++) { samples[i] = (short) (audio.read_u16() - 0x8000); // read unsigned 16-bit and convert to signed 16-bit (subtract 32768) wait_us(1e6/SAMP_FREQ); // wait for sampling frequency, should really implement with tickers } } void doFFT() { // clear buffers for (int i=0; i<2*BUF_LEN; i++) { my[i] = 0; mx[i] = 0; } for (int i=0; i<BUF_LEN; i++) { // load samples in array (skip imaginary input values) mx[i*2]=samples[i]; } fftR4(my, mx, BUF_LEN); // call FFT routine int j = 0; for (int i = 0; i < BUF_LEN; i+=2) { spectrum[j] = magnitude(my[i],my[i+1]); // get magnitude of FFT output to get spectrum data j++; } } void printSpectrum() { FILE *fp = fopen("/local/fft.csv","w"); //now write a CSV file to filesytem of frequency vs amplitude int j = 0; for (int i = 0; i < BUF_LEN; i+=2) { int frequency = int(SAMP_FREQ/BUF_LEN/2*i); // calculate value of frequency bin fprintf(fp, "%d,%f\n", frequency, spectrum[j]); j++; } fclose(fp); } void printSamples() { FILE *fp = fopen("/local/samples.csv","w"); //now write a CSV file to filesytem of frequency vs amplitude for (int i = 0; i < BUF_LEN; i++) { fprintf(fp, "%d\n", samples[i]); } fclose(fp); } int calcPeakFrequency() { float max = 0.0; int frequency = 0; int j = 0; for (int i=0; i<BUF_LEN; i+=2) { // loop through spectrum and look for maximum value if (spectrum[j] > max) { max = spectrum[j]; frequency = int(SAMP_FREQ/BUF_LEN/2*i); } j++; } //serial.printf("Max = %f\n",max); return frequency; } void lcdEqualiser() { // spectrum has BUF_LEN/2 values = 512 // screen has 84 pixel, giving 6 spectrum points per pixel float max = 0.0; // used for normalisation later float pixelValue[84]; for (int i=0; i<84; i++) { // loop through array pixelValue[i] = 0.0; for (int y=0; y<6; y++) { pixelValue[i] += spectrum[i*6+y]; // sum the 6 values in the spectrum } pixelValue[i]/=6; // calc. average for that pixel if (pixelValue[i] > max) // check for biggest value max = pixelValue[i]; } for (int i=0; i<84; i++) { // loop through array pixelValue[i]/=max; // normalise to 1.0 } lcd.clear(); for (int i=0; i<84; i++) { // loop through array for (int j=0; j<= 47 - int(pixelValue[i]*47.0); j++) { // loop through array lcd.setPixel(i,j); // draw bar graphs for spectrum bins } } lcd.refresh(); }