Program to convert audio signals in RGB LED animations. Requests hardware peripherals (DiscoTech PCB). EESTEC Workshop September 2013 LC Hamburg.

Dependencies:   PwmDAC ShiftReg Terminal adc mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* This program executes an audio to rgb light conversion.
00002  * It is made for an international EESTEC Workshop by LC Hamburg.
00003  * This works on mbed LPC1768 with hardware peripherals on pcb.
00004  * It converts a stereo (to chan. mixed to mono) signal to light animation
00005  * Using digital filters or any alogrithm you prefer to convert music into ligth
00006  * It controlls 3 RGB LED stripes powerlines with 74HC595 shift
00007  * register.
00008  * 
00009  * Project:         DiscoTech
00010  * HDK/ SDK Eng:    Tobias Wulf
00011  * Date:            21.09.2013
00012  *
00013  */
00014  
00015 #include "mbed.h"
00016 #include "Terminal.h"
00017 
00018 #include "adc.h"
00019 #include "PwmDAC.h"
00020 #include "ShiftReg.h"
00021 
00022 #include "stdlib.h"
00023 
00024 #define SAMPLE_RATE 48000 //Hz
00025 #define ADC_BIAS 1.65 //Volts
00026 #define ULSB 3.3 / 4095
00027 #define RESOLUTION 256
00028 
00029 #define MASK 0x07 // for shift register
00030 
00031 /* declair your functions
00032  * isr routine doesn't have to be declaired
00033  */
00034 void mainInit();
00035 
00036 
00037 PwmDAC rgb;
00038 ADC adc(SAMPLE_RATE, 1);
00039 //AnalogOut dac(p18);
00040 ShiftReg LEDstripes(p30, p29, p28);
00041 
00042 /* Serial communication via usb uplink to pc
00043  * to display what ever you want in the terminal
00044  * or to send what ever you want from the terminal
00045  */
00046 Terminal usbPC(USBTX, USBRX);
00047 
00048 /* array for updating the PwmDAC object
00049  * and pointers for easy work
00050  * we use steps 1 3 5 ...point'em
00051  */
00052 double channels[6];
00053 
00054 /*
00055 uint32_t *redChan;
00056 uint32_t *greenChan;
00057 uint32_t *blueChan;
00058 */
00059 
00060 /* global variables to work in the adc interrupt
00061  * service routine to get the data from interrupt
00062  */
00063 
00064 unsigned int pattern = 0;
00065 double newSample;
00066 
00067 bool adcActive = true;
00068 
00069 
00070 
00071 int main() {
00072     
00073     // LP for output pwm channel 1
00074     double b1[3] = {0.207481, 0.414962, 0.207481}; 
00075     double a1[2] = {-0.170076, 0.542269}; 
00076     double w1[3] = {0.0, 0.0, 0.0};
00077     double y1 = 0.0;
00078 
00079     // HP for output pwm channel 3
00080     double b3[3] = {0.365315, 0.730629, 0.365315}; 
00081     double a3[2] = {-0.417651, 0.043608}; 
00082     double w3[3] = {0.0, 0.0, 0.0};
00083     double y3 = 0.0;
00084 
00085     //BP - HP for output to LP
00086     double b5i[3] = { 1.0, -1.9884555305478397,  1.0000000000000022}; 
00087     double a5i[2] = {-1.9906581470004894,   0.99457555239826922}; 
00088     double w5i[3] = {0.0, 0.0, 0.0};
00089     double y5i = 0.0;
00090 
00091     // BP - LP for output pwm channel 5
00092     double b5j[3] = {1.0, -1.9988801446006126, 1.0}; 
00093     double a5j[2] = {-1.991742261264652, 0.99502978931485908}; 
00094     double w5j[3] = {0.0, 0.0, 0.0};
00095     double y5j = 0.0;
00096     
00097     //int counter = 0;
00098     
00099     usbPC.printf("...start program\n");
00100     wait(0.2);
00101 
00102     mainInit();
00103     usbPC.printf("...init completed\n");
00104     wait(0.2);
00105     
00106     //srand(7);
00107     
00108     adcActive = false;
00109         
00110     while(1) {
00111         if(adcActive) {
00112             adcActive = false;
00113             
00114             // first LP, chan 1 (red)
00115             w1[0] = newSample + (a1[0] * w1[1]) + (a1[1] * w1[2]);
00116             y1 = (b1[0] * w1[0]) +(b1[1] * w1[1]) + (b1[2] * w1[2]);
00117             w1[2] = w1[1]; 
00118             w1[1] = w1[0];
00119             channels[1] = (double) ((y1 + ADC_BIAS) * 100 / 3.3);
00120             
00121             // first HP, chan 3 (green)
00122             w3[0] = newSample + (a3[0] * w3[1]) + (a3[1] * w3[2]);
00123             y3 = (b3[0] * w3[0]) +(b3[1] * w3[1]) + (b3[2] * w3[2]);
00124             w3[2] = w3[1]; 
00125             w3[1] = w3[0];
00126             channels[3] = (double) ((y3 + ADC_BIAS) * 100 / 3.3);
00127             
00128             // first BP - HP, target BP - LP
00129             w5i[0] = 0.0099616678552018837 * newSample + (a5i[0] * w5i[1]) + (a5i[1] * w5i[2]);
00130             y5i = (b5i[0] * w5i[0]) +(b5i[1] * w5i[1]) + (b5i[2] * w5i[2]);
00131             w5i[2] = w5i[1]; 
00132             w5i[1] = w5i[0];
00133             
00134             // first BP LP, chan 5 (blue)
00135             w5j[0] = y5i + (a5j[0] * w5j[1]) + (a5j[1] * w5j[2]);
00136             y5j = (b5j[0] * w5j[0]) +(b5j[1] * w5j[1]) + (b5j[2] * w5j[2]);
00137             w5j[2] = w5j[1]; 
00138             w5j[1] = w5j[0];
00139             channels[5] = (double) ((y5j + ADC_BIAS) * 100 / 3.3);
00140                       
00141             rgb.updateDuty(channels);    
00142         }
00143 
00144         usbPC.printf("Sample = %f\n", newSample);
00145         usbPC.printf("Chan1 = %f\n", channels[1]);
00146         usbPC.printf("Chan3 = %f\n", channels[3]);
00147         usbPC.printf("Chan5 = %f\n", channels[5]);
00148 
00149         LEDstripes.ShiftByte(pattern, ShiftReg::MSBFirst);
00150         LEDstripes.Latch();
00151         LEDstripes.ShiftByte((unsigned int) MASK, ShiftReg::MSBFirst);
00152         LEDstripes.Latch();     
00153         
00154         
00155     }
00156 }/* end main */
00157 
00158 
00159 
00160 
00161 
00162 
00163 
00164 
00165 
00166 /* interrupt service routine from adc object
00167  * here should be done the data processing
00168  * variable and output updates
00169  */
00170 void getADC(int chan, uint32_t value) {
00171     adcActive = true;
00172     newSample = (double) adc.read(p15);
00173     newSample = newSample * ULSB - ADC_BIAS;
00174     
00175     // maybe do something other, but do it fast!
00176 }        
00177 
00178 /* function to initialize the main program, objects and 
00179  * implement all variables
00180  */
00181 void mainInit() {
00182        
00183     for(int i=0; i<6; i++) {
00184         channels[i] = 0;
00185     }
00186         
00187 
00188     usbPC.printf("...variables implemented\n");
00189     wait(0.2);
00190     
00191     /* setup shift register (stripe power)
00192      */
00193      LEDstripes.ShiftByte((unsigned int) MASK, ShiftReg::MSBFirst);
00194      LEDstripes.Latch();
00195      wait(0.2);
00196     
00197     usbPC.printf("...shift register initialized\n");
00198     wait(0.2);
00199     
00200     /* setup adc input
00201      */
00202     adc.append(getADC);
00203     
00204     adc.startmode(0,0);
00205     adc.burst(1);
00206    
00207     adc.setup(p15,1);
00208     adc.setup(p16,0);
00209     adc.setup(p17,0);
00210     adc.setup(p18,0);
00211     adc.setup(p19,0);
00212     adc.setup(p20,0);
00213    
00214     adc.interrupt_state(p15,1);
00215     
00216     
00217     usbPC.printf("%u, %u, %u, %u\n", adc.setup(p15), 
00218                                      adc.burst(),
00219                                      adc.interrupt_state(p15), 
00220                                      adc.actual_sample_rate());   
00221     
00222     usbPC.printf("...ADC initialized\n");
00223     wait(0.2);
00224     
00225     /* setup pwm output
00226      */
00227     rgb.init();
00228     rgb.deactivate(0);
00229     rgb.deactivate(2);
00230     rgb.deactivate(4);
00231     rgb.setResolution(RESOLUTION);
00232     rgb.start();
00233     
00234     usbPC.printf("...PWM output initialized\n");
00235     wait(0.2);
00236 }