![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Blinks LED cube along with music
Dependencies: mbed mbed-rtos MCP23S17
main.cpp@0:b6451e68016a, 2011-02-28 (annotated)
- Committer:
- gth646f
- Date:
- Mon Feb 28 03:26:53 2011 +0000
- Revision:
- 0:b6451e68016a
- Child:
- 1:ef3ad9c720c9
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
gth646f | 0:b6451e68016a | 1 | |
gth646f | 0:b6451e68016a | 2 | |
gth646f | 0:b6451e68016a | 3 | |
gth646f | 0:b6451e68016a | 4 | |
gth646f | 0:b6451e68016a | 5 | #include "mbed.h" |
gth646f | 0:b6451e68016a | 6 | #include "adc.h" |
gth646f | 0:b6451e68016a | 7 | #include "NokiaLCD.h" |
gth646f | 0:b6451e68016a | 8 | |
gth646f | 0:b6451e68016a | 9 | #define MN 256 /*Number of points*/ |
gth646f | 0:b6451e68016a | 10 | #define SAMPLE_RATE 48000 |
gth646f | 0:b6451e68016a | 11 | NokiaLCD lcd(p5, p7, p8, p9, NokiaLCD::LCD6610); // mosi, sclk, cs, rst, type |
gth646f | 0:b6451e68016a | 12 | |
gth646f | 0:b6451e68016a | 13 | |
gth646f | 0:b6451e68016a | 14 | //Going to use the Mellen FFT rather than STM, as the STM (port by Igor) won't compile |
gth646f | 0:b6451e68016a | 15 | //extern "C" void cr4_fft_256_stm32(void *pssOUT, void *pssIN, uint16_t Nbin); |
gth646f | 0:b6451e68016a | 16 | extern "C" void fftR4(short *y, short *x, int N); |
gth646f | 0:b6451e68016a | 17 | |
gth646f | 0:b6451e68016a | 18 | //use the LED as a bargraph |
gth646f | 0:b6451e68016a | 19 | DigitalOut l1(LED1); |
gth646f | 0:b6451e68016a | 20 | DigitalOut l2(LED2); |
gth646f | 0:b6451e68016a | 21 | DigitalOut l3(LED3); |
gth646f | 0:b6451e68016a | 22 | DigitalOut l4(LED4); |
gth646f | 0:b6451e68016a | 23 | |
gth646f | 0:b6451e68016a | 24 | //set up a timer for timing FFT's |
gth646f | 0:b6451e68016a | 25 | Timer timer; |
gth646f | 0:b6451e68016a | 26 | Ticker ticker; |
gth646f | 0:b6451e68016a | 27 | |
gth646f | 0:b6451e68016a | 28 | //Set up filesystem so we can write some useful files |
gth646f | 0:b6451e68016a | 29 | LocalFileSystem local("local"); |
gth646f | 0:b6451e68016a | 30 | FILE *fp; |
gth646f | 0:b6451e68016a | 31 | |
gth646f | 0:b6451e68016a | 32 | |
gth646f | 0:b6451e68016a | 33 | //Set up a global buffer for audio data so interrupt can access it |
gth646f | 0:b6451e68016a | 34 | int Counter = 0; |
gth646f | 0:b6451e68016a | 35 | int16_t Buffer[5000]; |
gth646f | 0:b6451e68016a | 36 | |
gth646f | 0:b6451e68016a | 37 | |
gth646f | 0:b6451e68016a | 38 | //Initialise ADC to maximum SAMPLE_RATE and cclk divide set to 1 |
gth646f | 0:b6451e68016a | 39 | ADC adc(SAMPLE_RATE, 1); |
gth646f | 0:b6451e68016a | 40 | |
gth646f | 0:b6451e68016a | 41 | //Functions to write 16 bit audio data and 32 bit headers to files in au format (cf sndRecorder Cookbook) |
gth646f | 0:b6451e68016a | 42 | void fwrite16(uint16_t v) { |
gth646f | 0:b6451e68016a | 43 | uint8_t *b = (uint8_t *)&v; |
gth646f | 0:b6451e68016a | 44 | |
gth646f | 0:b6451e68016a | 45 | fprintf(fp,"%c%c", b[1], b[0]); |
gth646f | 0:b6451e68016a | 46 | } |
gth646f | 0:b6451e68016a | 47 | void fwrite32(uint32_t v) { |
gth646f | 0:b6451e68016a | 48 | uint8_t *b = (uint8_t *)&v; |
gth646f | 0:b6451e68016a | 49 | |
gth646f | 0:b6451e68016a | 50 | fprintf(fp,"%c%c%c%c", b[3], b[2], b[1], b[0]); |
gth646f | 0:b6451e68016a | 51 | } |
gth646f | 0:b6451e68016a | 52 | |
gth646f | 0:b6451e68016a | 53 | |
gth646f | 0:b6451e68016a | 54 | |
gth646f | 0:b6451e68016a | 55 | //Our interrupt handler for audio sampling |
gth646f | 0:b6451e68016a | 56 | void sample_ADC(int chan, uint32_t value) { |
gth646f | 0:b6451e68016a | 57 | |
gth646f | 0:b6451e68016a | 58 | float s; |
gth646f | 0:b6451e68016a | 59 | s = adc.read(p20); |
gth646f | 0:b6451e68016a | 60 | int16_t b = (s -2048)*16; |
gth646f | 0:b6451e68016a | 61 | Buffer[Counter] = b; |
gth646f | 0:b6451e68016a | 62 | Counter += 1; |
gth646f | 0:b6451e68016a | 63 | /* bar graph */ |
gth646f | 0:b6451e68016a | 64 | int g = abs(s-2048); |
gth646f | 0:b6451e68016a | 65 | l1 = g > 0.1f*2048; |
gth646f | 0:b6451e68016a | 66 | l2 = g > 0.3f*2048; |
gth646f | 0:b6451e68016a | 67 | l3 = g > 0.6f*2048; |
gth646f | 0:b6451e68016a | 68 | l4 = g > 0.8f*2048; |
gth646f | 0:b6451e68016a | 69 | } |
gth646f | 0:b6451e68016a | 70 | |
gth646f | 0:b6451e68016a | 71 | int main() { |
gth646f | 0:b6451e68016a | 72 | |
gth646f | 0:b6451e68016a | 73 | while (1) { |
gth646f | 0:b6451e68016a | 74 | //Prepare for burst mode on all ADC pins and set up interrupt handler (using ADC library from Simon Blandford |
gth646f | 0:b6451e68016a | 75 | adc.append(sample_ADC); |
gth646f | 0:b6451e68016a | 76 | adc.startmode(0,0); |
gth646f | 0:b6451e68016a | 77 | adc.burst(1); |
gth646f | 0:b6451e68016a | 78 | adc.setup(p20,1); |
gth646f | 0:b6451e68016a | 79 | //introduce a delay as initial waveform has bias whilst decoupling cap charges |
gth646f | 0:b6451e68016a | 80 | wait(.4); |
gth646f | 0:b6451e68016a | 81 | //start the interrupt and wait for about 4096 samples |
gth646f | 0:b6451e68016a | 82 | adc.interrupt_state(p20,1); |
gth646f | 0:b6451e68016a | 83 | wait(0.1); |
gth646f | 0:b6451e68016a | 84 | //Finsh up - Unset pin 20 |
gth646f | 0:b6451e68016a | 85 | adc.interrupt_state(p20,0); |
gth646f | 0:b6451e68016a | 86 | adc.setup(p20,0); |
gth646f | 0:b6451e68016a | 87 | int actual_rate = adc.actual_sample_rate(); |
gth646f | 0:b6451e68016a | 88 | |
gth646f | 0:b6451e68016a | 89 | //now lets try mellen fft |
gth646f | 0:b6451e68016a | 90 | lcd.background(0x0000FF); |
gth646f | 0:b6451e68016a | 91 | |
gth646f | 0:b6451e68016a | 92 | short mx[MN*2]; // input data 16 bit, 4 byte aligned x0r,x0i,x1r,x1i,.... |
gth646f | 0:b6451e68016a | 93 | short my[MN*2]; // output data 16 bit,4 byte aligned y0r,y0i,y1r,y1i,.... |
gth646f | 0:b6451e68016a | 94 | float data2[512]; |
gth646f | 0:b6451e68016a | 95 | for (int i=0;i<MN*2;i++) mx[i]=0; |
gth646f | 0:b6451e68016a | 96 | |
gth646f | 0:b6451e68016a | 97 | for (int i=0;i<MN;i=i+1) { |
gth646f | 0:b6451e68016a | 98 | mx[i*2]=Buffer[i]; |
gth646f | 0:b6451e68016a | 99 | } |
gth646f | 0:b6451e68016a | 100 | //FILE* mlog = fopen("/local/mellen.csv","w"); |
gth646f | 0:b6451e68016a | 101 | //call functions; |
gth646f | 0:b6451e68016a | 102 | fftR4(my, mx, MN); |
gth646f | 0:b6451e68016a | 103 | for (int i=0; i<MN; i=i+2) { |
gth646f | 0:b6451e68016a | 104 | data2[i]= sqrt(float( (my[i]*my[i]) +(my[i+1]*my[i+1]))); |
gth646f | 0:b6451e68016a | 105 | //fprintf(mlog, "%d,%f\n", int(actual_rate/MN/2*i),sqrt(float( (my[i]*my[i]) +(my[i+1]*my[i+1])) ) ); |
gth646f | 0:b6451e68016a | 106 | } |
gth646f | 0:b6451e68016a | 107 | //fclose(mlog); |
gth646f | 0:b6451e68016a | 108 | |
gth646f | 0:b6451e68016a | 109 | |
gth646f | 0:b6451e68016a | 110 | //Display amplitude on Nokia LCD |
gth646f | 0:b6451e68016a | 111 | lcd.cls(); |
gth646f | 0:b6451e68016a | 112 | for (int i=0; i<128; i++) { |
gth646f | 0:b6451e68016a | 113 | data2[i+1] = 20*log10(data2[i+1]); |
gth646f | 0:b6451e68016a | 114 | lcd.fill(i, 0, 2, data2[i+1], 0x00FF00); |
gth646f | 0:b6451e68016a | 115 | } |
gth646f | 0:b6451e68016a | 116 | Counter = 0; |
gth646f | 0:b6451e68016a | 117 | } |
gth646f | 0:b6451e68016a | 118 | } |
gth646f | 0:b6451e68016a | 119 | |
gth646f | 0:b6451e68016a | 120 | |
gth646f | 0:b6451e68016a | 121 | |
gth646f | 0:b6451e68016a | 122 | |
gth646f | 0:b6451e68016a | 123 |