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