filter implement on DiscoTech device
Dependencies: PwmDAC ShiftReg Terminal adc mbed
main.cpp@0:b2736cb133e0, 2013-09-25 (annotated)
- Committer:
- XIZ
- Date:
- Wed Sep 25 14:03:21 2013 +0000
- Revision:
- 0:b2736cb133e0
Filter implement on DiscoTech device
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
XIZ | 0:b2736cb133e0 | 1 | /* This program executes an audio to rgb light conversion. |
XIZ | 0:b2736cb133e0 | 2 | * It is made for an international EESTEC Workshop by LC Hamburg. |
XIZ | 0:b2736cb133e0 | 3 | * This works on mbed LPC1768 with hardware peripherals on pcb. |
XIZ | 0:b2736cb133e0 | 4 | * It converts a stereo (to chan. mixed to mono) signal to light animation |
XIZ | 0:b2736cb133e0 | 5 | * Using digital filters or any alogrithm you prefer to convert music into ligth |
XIZ | 0:b2736cb133e0 | 6 | * It controlls 3 RGB LED stripes powerlines with 74HC595 shift |
XIZ | 0:b2736cb133e0 | 7 | * register. |
XIZ | 0:b2736cb133e0 | 8 | * |
XIZ | 0:b2736cb133e0 | 9 | * Project: DiscoTech |
XIZ | 0:b2736cb133e0 | 10 | * HDK/ SDK Eng: Tobias Wulf |
XIZ | 0:b2736cb133e0 | 11 | * Date: 21.09.2013 |
XIZ | 0:b2736cb133e0 | 12 | * |
XIZ | 0:b2736cb133e0 | 13 | */ |
XIZ | 0:b2736cb133e0 | 14 | |
XIZ | 0:b2736cb133e0 | 15 | #include "mbed.h" |
XIZ | 0:b2736cb133e0 | 16 | #include "Terminal.h" |
XIZ | 0:b2736cb133e0 | 17 | |
XIZ | 0:b2736cb133e0 | 18 | |
XIZ | 0:b2736cb133e0 | 19 | #include "adc.h" |
XIZ | 0:b2736cb133e0 | 20 | #include "PwmDAC.h" |
XIZ | 0:b2736cb133e0 | 21 | #include "ShiftReg.h" |
XIZ | 0:b2736cb133e0 | 22 | |
XIZ | 0:b2736cb133e0 | 23 | |
XIZ | 0:b2736cb133e0 | 24 | #define SAMPLE_RATE 48000 //Hz |
XIZ | 0:b2736cb133e0 | 25 | #define ADC_BIAS 1.65 //Volts |
XIZ | 0:b2736cb133e0 | 26 | #define ULSB 3.3 / 4095 |
XIZ | 0:b2736cb133e0 | 27 | #define RESOLUTION 256 |
XIZ | 0:b2736cb133e0 | 28 | |
XIZ | 0:b2736cb133e0 | 29 | #define MASK 0x07 // for shift register |
XIZ | 0:b2736cb133e0 | 30 | |
XIZ | 0:b2736cb133e0 | 31 | |
XIZ | 0:b2736cb133e0 | 32 | #define NUMBER_OF_SAMPLES 1024 |
XIZ | 0:b2736cb133e0 | 33 | |
XIZ | 0:b2736cb133e0 | 34 | /* declair your functions |
XIZ | 0:b2736cb133e0 | 35 | * isr routine doesn't have to be declaired |
XIZ | 0:b2736cb133e0 | 36 | */ |
XIZ | 0:b2736cb133e0 | 37 | void mainInit(); |
XIZ | 0:b2736cb133e0 | 38 | |
XIZ | 0:b2736cb133e0 | 39 | |
XIZ | 0:b2736cb133e0 | 40 | PwmDAC rgb; |
XIZ | 0:b2736cb133e0 | 41 | ADC adc(SAMPLE_RATE, 1); |
XIZ | 0:b2736cb133e0 | 42 | //AnalogOut dac(p18); |
XIZ | 0:b2736cb133e0 | 43 | ShiftReg LEDstripes(p30, p29, p28); |
XIZ | 0:b2736cb133e0 | 44 | |
XIZ | 0:b2736cb133e0 | 45 | /* Serial communication via usb uplink to pc |
XIZ | 0:b2736cb133e0 | 46 | * to display what ever you want in the terminal |
XIZ | 0:b2736cb133e0 | 47 | * or to send what ever you want from the terminal |
XIZ | 0:b2736cb133e0 | 48 | */ |
XIZ | 0:b2736cb133e0 | 49 | Terminal usbPC(USBTX, USBRX); |
XIZ | 0:b2736cb133e0 | 50 | |
XIZ | 0:b2736cb133e0 | 51 | /* array for updating the PwmDAC object |
XIZ | 0:b2736cb133e0 | 52 | * and pointers for easy work |
XIZ | 0:b2736cb133e0 | 53 | * we use steps 1 3 5 ...point'em |
XIZ | 0:b2736cb133e0 | 54 | */ |
XIZ | 0:b2736cb133e0 | 55 | uint32_t channels[6]; |
XIZ | 0:b2736cb133e0 | 56 | |
XIZ | 0:b2736cb133e0 | 57 | |
XIZ | 0:b2736cb133e0 | 58 | |
XIZ | 0:b2736cb133e0 | 59 | /* global variables to work in the adc interrupt |
XIZ | 0:b2736cb133e0 | 60 | * service routine to get the data from interrupt |
XIZ | 0:b2736cb133e0 | 61 | */ |
XIZ | 0:b2736cb133e0 | 62 | |
XIZ | 0:b2736cb133e0 | 63 | unsigned int pattern; |
XIZ | 0:b2736cb133e0 | 64 | double newSample; |
XIZ | 0:b2736cb133e0 | 65 | |
XIZ | 0:b2736cb133e0 | 66 | |
XIZ | 0:b2736cb133e0 | 67 | bool save; |
XIZ | 0:b2736cb133e0 | 68 | |
XIZ | 0:b2736cb133e0 | 69 | double adcSavings[NUMBER_OF_SAMPLES]; |
XIZ | 0:b2736cb133e0 | 70 | double adcSamples[NUMBER_OF_SAMPLES]; |
XIZ | 0:b2736cb133e0 | 71 | |
XIZ | 0:b2736cb133e0 | 72 | |
XIZ | 0:b2736cb133e0 | 73 | |
XIZ | 0:b2736cb133e0 | 74 | double adcSample; |
XIZ | 0:b2736cb133e0 | 75 | // LP for output pwm channel 1 |
XIZ | 0:b2736cb133e0 | 76 | const double b1[3] = {0.034566506326168603, 0.069133012652337206, 0.034566506326168603}; |
XIZ | 0:b2736cb133e0 | 77 | const double a1[2] = { -1.5156844350566925, 0.65395046036136695}; |
XIZ | 0:b2736cb133e0 | 78 | double w1[3]; |
XIZ | 0:b2736cb133e0 | 79 | double y1; |
XIZ | 0:b2736cb133e0 | 80 | |
XIZ | 0:b2736cb133e0 | 81 | |
XIZ | 0:b2736cb133e0 | 82 | int main() { |
XIZ | 0:b2736cb133e0 | 83 | |
XIZ | 0:b2736cb133e0 | 84 | |
XIZ | 0:b2736cb133e0 | 85 | // init for saving samples and filter results |
XIZ | 0:b2736cb133e0 | 86 | for (int i = 0; i < NUMBER_OF_SAMPLES; i++){ |
XIZ | 0:b2736cb133e0 | 87 | adcSavings[i] = 0.0f; |
XIZ | 0:b2736cb133e0 | 88 | adcSamples[i] = 0.0f; |
XIZ | 0:b2736cb133e0 | 89 | } |
XIZ | 0:b2736cb133e0 | 90 | |
XIZ | 0:b2736cb133e0 | 91 | |
XIZ | 0:b2736cb133e0 | 92 | // LP for output pwm channel 1 |
XIZ | 0:b2736cb133e0 | 93 | for(int i= 0; i<3;i++) |
XIZ | 0:b2736cb133e0 | 94 | w1[i] = 0.0f; |
XIZ | 0:b2736cb133e0 | 95 | y1 = 0.0f; |
XIZ | 0:b2736cb133e0 | 96 | |
XIZ | 0:b2736cb133e0 | 97 | |
XIZ | 0:b2736cb133e0 | 98 | |
XIZ | 0:b2736cb133e0 | 99 | |
XIZ | 0:b2736cb133e0 | 100 | usbPC.printf("...start program\n"); |
XIZ | 0:b2736cb133e0 | 101 | wait(0.2); |
XIZ | 0:b2736cb133e0 | 102 | |
XIZ | 0:b2736cb133e0 | 103 | mainInit(); |
XIZ | 0:b2736cb133e0 | 104 | usbPC.printf("...init completed\n"); |
XIZ | 0:b2736cb133e0 | 105 | wait(0.2); |
XIZ | 0:b2736cb133e0 | 106 | |
XIZ | 0:b2736cb133e0 | 107 | |
XIZ | 0:b2736cb133e0 | 108 | while(1) { |
XIZ | 0:b2736cb133e0 | 109 | |
XIZ | 0:b2736cb133e0 | 110 | if(save == false) { |
XIZ | 0:b2736cb133e0 | 111 | |
XIZ | 0:b2736cb133e0 | 112 | usbPC.locate(0,0); |
XIZ | 0:b2736cb133e0 | 113 | usbPC.cls(); |
XIZ | 0:b2736cb133e0 | 114 | |
XIZ | 0:b2736cb133e0 | 115 | |
XIZ | 0:b2736cb133e0 | 116 | for(int i=0; i<NUMBER_OF_SAMPLES; i++) |
XIZ | 0:b2736cb133e0 | 117 | usbPC.printf("%1.4f %1.4f\n",adcSavings[i],adcSamples[i]); |
XIZ | 0:b2736cb133e0 | 118 | } |
XIZ | 0:b2736cb133e0 | 119 | |
XIZ | 0:b2736cb133e0 | 120 | if(save == false) break; |
XIZ | 0:b2736cb133e0 | 121 | |
XIZ | 0:b2736cb133e0 | 122 | } |
XIZ | 0:b2736cb133e0 | 123 | |
XIZ | 0:b2736cb133e0 | 124 | }/* end main */ |
XIZ | 0:b2736cb133e0 | 125 | |
XIZ | 0:b2736cb133e0 | 126 | |
XIZ | 0:b2736cb133e0 | 127 | |
XIZ | 0:b2736cb133e0 | 128 | |
XIZ | 0:b2736cb133e0 | 129 | |
XIZ | 0:b2736cb133e0 | 130 | |
XIZ | 0:b2736cb133e0 | 131 | |
XIZ | 0:b2736cb133e0 | 132 | |
XIZ | 0:b2736cb133e0 | 133 | /* interrupt service routine from adc object |
XIZ | 0:b2736cb133e0 | 134 | * here should be done the data processing |
XIZ | 0:b2736cb133e0 | 135 | * variable and output updates |
XIZ | 0:b2736cb133e0 | 136 | */ |
XIZ | 0:b2736cb133e0 | 137 | void getADC(int chan, uint32_t value) { |
XIZ | 0:b2736cb133e0 | 138 | static int cycleCounter = 0; |
XIZ | 0:b2736cb133e0 | 139 | |
XIZ | 0:b2736cb133e0 | 140 | adcSample = (double) adc.read(p15); |
XIZ | 0:b2736cb133e0 | 141 | adcSample = adcSample * ULSB; |
XIZ | 0:b2736cb133e0 | 142 | // first LP, chan 1 (red) |
XIZ | 0:b2736cb133e0 | 143 | w1[0] = adcSample - (a1[0] * w1[1]) - (a1[1] * w1[2]); |
XIZ | 0:b2736cb133e0 | 144 | y1 = 0.89125093813374 * ((b1[0] * w1[0]) +(b1[1] * w1[1]) + (b1[2] * w1[2])); |
XIZ | 0:b2736cb133e0 | 145 | w1[2] = w1[1]; |
XIZ | 0:b2736cb133e0 | 146 | w1[1] = w1[0]; |
XIZ | 0:b2736cb133e0 | 147 | |
XIZ | 0:b2736cb133e0 | 148 | if(cycleCounter < NUMBER_OF_SAMPLES) { |
XIZ | 0:b2736cb133e0 | 149 | adcSavings[cycleCounter] = y1; |
XIZ | 0:b2736cb133e0 | 150 | adcSamples[cycleCounter] = adcSample; |
XIZ | 0:b2736cb133e0 | 151 | cycleCounter++; |
XIZ | 0:b2736cb133e0 | 152 | if((cycleCounter == NUMBER_OF_SAMPLES-1) && save) { |
XIZ | 0:b2736cb133e0 | 153 | save = false; |
XIZ | 0:b2736cb133e0 | 154 | cycleCounter = 0; |
XIZ | 0:b2736cb133e0 | 155 | } |
XIZ | 0:b2736cb133e0 | 156 | } |
XIZ | 0:b2736cb133e0 | 157 | |
XIZ | 0:b2736cb133e0 | 158 | } |
XIZ | 0:b2736cb133e0 | 159 | |
XIZ | 0:b2736cb133e0 | 160 | /* function to initialize the main program, objects and |
XIZ | 0:b2736cb133e0 | 161 | * implement all variables |
XIZ | 0:b2736cb133e0 | 162 | */ |
XIZ | 0:b2736cb133e0 | 163 | void mainInit() { |
XIZ | 0:b2736cb133e0 | 164 | |
XIZ | 0:b2736cb133e0 | 165 | |
XIZ | 0:b2736cb133e0 | 166 | |
XIZ | 0:b2736cb133e0 | 167 | for(int i=0; i<6; i++) { |
XIZ | 0:b2736cb133e0 | 168 | channels[i] = 0; |
XIZ | 0:b2736cb133e0 | 169 | } |
XIZ | 0:b2736cb133e0 | 170 | |
XIZ | 0:b2736cb133e0 | 171 | |
XIZ | 0:b2736cb133e0 | 172 | usbPC.printf("...variables implemented\n"); |
XIZ | 0:b2736cb133e0 | 173 | wait(0.2); |
XIZ | 0:b2736cb133e0 | 174 | |
XIZ | 0:b2736cb133e0 | 175 | /* setup shift register (stripe power) |
XIZ | 0:b2736cb133e0 | 176 | */ |
XIZ | 0:b2736cb133e0 | 177 | LEDstripes.ShiftByte((unsigned int) MASK, ShiftReg::MSBFirst); |
XIZ | 0:b2736cb133e0 | 178 | LEDstripes.Latch(); |
XIZ | 0:b2736cb133e0 | 179 | wait(0.2); |
XIZ | 0:b2736cb133e0 | 180 | |
XIZ | 0:b2736cb133e0 | 181 | usbPC.printf("...shift register initialized\n"); |
XIZ | 0:b2736cb133e0 | 182 | wait(0.2); |
XIZ | 0:b2736cb133e0 | 183 | |
XIZ | 0:b2736cb133e0 | 184 | /* setup adc input |
XIZ | 0:b2736cb133e0 | 185 | */ |
XIZ | 0:b2736cb133e0 | 186 | adc.append(getADC); |
XIZ | 0:b2736cb133e0 | 187 | |
XIZ | 0:b2736cb133e0 | 188 | adc.startmode(0,0); |
XIZ | 0:b2736cb133e0 | 189 | adc.burst(1); |
XIZ | 0:b2736cb133e0 | 190 | |
XIZ | 0:b2736cb133e0 | 191 | adc.setup(p15,1); |
XIZ | 0:b2736cb133e0 | 192 | adc.setup(p16,0); |
XIZ | 0:b2736cb133e0 | 193 | adc.setup(p17,0); |
XIZ | 0:b2736cb133e0 | 194 | adc.setup(p18,0); |
XIZ | 0:b2736cb133e0 | 195 | adc.setup(p19,0); |
XIZ | 0:b2736cb133e0 | 196 | adc.setup(p20,0); |
XIZ | 0:b2736cb133e0 | 197 | |
XIZ | 0:b2736cb133e0 | 198 | wait(0.2); |
XIZ | 0:b2736cb133e0 | 199 | adc.interrupt_state(p15,1); |
XIZ | 0:b2736cb133e0 | 200 | |
XIZ | 0:b2736cb133e0 | 201 | |
XIZ | 0:b2736cb133e0 | 202 | |
XIZ | 0:b2736cb133e0 | 203 | |
XIZ | 0:b2736cb133e0 | 204 | usbPC.printf("%u, %u, %u, %u\n", adc.setup(p15), |
XIZ | 0:b2736cb133e0 | 205 | adc.burst(), |
XIZ | 0:b2736cb133e0 | 206 | adc.interrupt_state(p15), |
XIZ | 0:b2736cb133e0 | 207 | adc.actual_sample_rate()); |
XIZ | 0:b2736cb133e0 | 208 | |
XIZ | 0:b2736cb133e0 | 209 | usbPC.printf("...ADC initialized\n"); |
XIZ | 0:b2736cb133e0 | 210 | wait(0.2); |
XIZ | 0:b2736cb133e0 | 211 | |
XIZ | 0:b2736cb133e0 | 212 | /* setup pwm output |
XIZ | 0:b2736cb133e0 | 213 | */ |
XIZ | 0:b2736cb133e0 | 214 | rgb.init(); |
XIZ | 0:b2736cb133e0 | 215 | rgb.deactivate(0); |
XIZ | 0:b2736cb133e0 | 216 | rgb.deactivate(2); |
XIZ | 0:b2736cb133e0 | 217 | rgb.deactivate(4); |
XIZ | 0:b2736cb133e0 | 218 | rgb.setResolution(RESOLUTION); |
XIZ | 0:b2736cb133e0 | 219 | rgb.start(); |
XIZ | 0:b2736cb133e0 | 220 | |
XIZ | 0:b2736cb133e0 | 221 | usbPC.printf("...PWM output initialized\n"); |
XIZ | 0:b2736cb133e0 | 222 | wait(0.2); |
XIZ | 0:b2736cb133e0 | 223 | } |