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
main.cpp
- Committer:
- flash_ahaa
- Date:
- 2013-09-23
- Revision:
- 0:59f7c34059ec
File content as of revision 0:59f7c34059ec:
/* This program executes an audio to rgb light conversion. * It is made for an international EESTEC Workshop by LC Hamburg. * This works on mbed LPC1768 with hardware peripherals on pcb. * It converts a stereo (to chan. mixed to mono) signal to light animation * Using digital filters or any alogrithm you prefer to convert music into ligth * It controlls 3 RGB LED stripes powerlines with 74HC595 shift * register. * * Project: DiscoTech * HDK/ SDK Eng: Tobias Wulf * Date: 21.09.2013 * */ #include "mbed.h" #include "Terminal.h" #include "adc.h" #include "PwmDAC.h" #include "ShiftReg.h" #include "stdlib.h" #define SAMPLE_RATE 48000 //Hz #define ADC_BIAS 1.65 //Volts #define ULSB 3.3 / 4095 #define RESOLUTION 256 #define MASK 0x07 // for shift register /* declair your functions * isr routine doesn't have to be declaired */ void mainInit(); PwmDAC rgb; ADC adc(SAMPLE_RATE, 1); //AnalogOut dac(p18); ShiftReg LEDstripes(p30, p29, p28); /* Serial communication via usb uplink to pc * to display what ever you want in the terminal * or to send what ever you want from the terminal */ Terminal usbPC(USBTX, USBRX); /* array for updating the PwmDAC object * and pointers for easy work * we use steps 1 3 5 ...point'em */ double channels[6]; /* uint32_t *redChan; uint32_t *greenChan; uint32_t *blueChan; */ /* global variables to work in the adc interrupt * service routine to get the data from interrupt */ unsigned int pattern = 0; double newSample; bool adcActive = true; int main() { // LP for output pwm channel 1 double b1[3] = {0.207481, 0.414962, 0.207481}; double a1[2] = {-0.170076, 0.542269}; double w1[3] = {0.0, 0.0, 0.0}; double y1 = 0.0; // HP for output pwm channel 3 double b3[3] = {0.365315, 0.730629, 0.365315}; double a3[2] = {-0.417651, 0.043608}; double w3[3] = {0.0, 0.0, 0.0}; double y3 = 0.0; //BP - HP for output to LP double b5i[3] = { 1.0, -1.9884555305478397, 1.0000000000000022}; double a5i[2] = {-1.9906581470004894, 0.99457555239826922}; double w5i[3] = {0.0, 0.0, 0.0}; double y5i = 0.0; // BP - LP for output pwm channel 5 double b5j[3] = {1.0, -1.9988801446006126, 1.0}; double a5j[2] = {-1.991742261264652, 0.99502978931485908}; double w5j[3] = {0.0, 0.0, 0.0}; double y5j = 0.0; //int counter = 0; usbPC.printf("...start program\n"); wait(0.2); mainInit(); usbPC.printf("...init completed\n"); wait(0.2); //srand(7); adcActive = false; while(1) { if(adcActive) { adcActive = false; // first LP, chan 1 (red) w1[0] = newSample + (a1[0] * w1[1]) + (a1[1] * w1[2]); y1 = (b1[0] * w1[0]) +(b1[1] * w1[1]) + (b1[2] * w1[2]); w1[2] = w1[1]; w1[1] = w1[0]; channels[1] = (double) ((y1 + ADC_BIAS) * 100 / 3.3); // first HP, chan 3 (green) w3[0] = newSample + (a3[0] * w3[1]) + (a3[1] * w3[2]); y3 = (b3[0] * w3[0]) +(b3[1] * w3[1]) + (b3[2] * w3[2]); w3[2] = w3[1]; w3[1] = w3[0]; channels[3] = (double) ((y3 + ADC_BIAS) * 100 / 3.3); // first BP - HP, target BP - LP w5i[0] = 0.0099616678552018837 * newSample + (a5i[0] * w5i[1]) + (a5i[1] * w5i[2]); y5i = (b5i[0] * w5i[0]) +(b5i[1] * w5i[1]) + (b5i[2] * w5i[2]); w5i[2] = w5i[1]; w5i[1] = w5i[0]; // first BP LP, chan 5 (blue) w5j[0] = y5i + (a5j[0] * w5j[1]) + (a5j[1] * w5j[2]); y5j = (b5j[0] * w5j[0]) +(b5j[1] * w5j[1]) + (b5j[2] * w5j[2]); w5j[2] = w5j[1]; w5j[1] = w5j[0]; channels[5] = (double) ((y5j + ADC_BIAS) * 100 / 3.3); rgb.updateDuty(channels); } usbPC.printf("Sample = %f\n", newSample); usbPC.printf("Chan1 = %f\n", channels[1]); usbPC.printf("Chan3 = %f\n", channels[3]); usbPC.printf("Chan5 = %f\n", channels[5]); LEDstripes.ShiftByte(pattern, ShiftReg::MSBFirst); LEDstripes.Latch(); LEDstripes.ShiftByte((unsigned int) MASK, ShiftReg::MSBFirst); LEDstripes.Latch(); } }/* end main */ /* interrupt service routine from adc object * here should be done the data processing * variable and output updates */ void getADC(int chan, uint32_t value) { adcActive = true; newSample = (double) adc.read(p15); newSample = newSample * ULSB - ADC_BIAS; // maybe do something other, but do it fast! } /* function to initialize the main program, objects and * implement all variables */ void mainInit() { for(int i=0; i<6; i++) { channels[i] = 0; } usbPC.printf("...variables implemented\n"); wait(0.2); /* setup shift register (stripe power) */ LEDstripes.ShiftByte((unsigned int) MASK, ShiftReg::MSBFirst); LEDstripes.Latch(); wait(0.2); usbPC.printf("...shift register initialized\n"); wait(0.2); /* setup adc input */ adc.append(getADC); adc.startmode(0,0); adc.burst(1); adc.setup(p15,1); adc.setup(p16,0); adc.setup(p17,0); adc.setup(p18,0); adc.setup(p19,0); adc.setup(p20,0); adc.interrupt_state(p15,1); usbPC.printf("%u, %u, %u, %u\n", adc.setup(p15), adc.burst(), adc.interrupt_state(p15), adc.actual_sample_rate()); usbPC.printf("...ADC initialized\n"); wait(0.2); /* setup pwm output */ rgb.init(); rgb.deactivate(0); rgb.deactivate(2); rgb.deactivate(4); rgb.setResolution(RESOLUTION); rgb.start(); usbPC.printf("...PWM output initialized\n"); wait(0.2); }