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

Revision:
0:59f7c34059ec
diff -r 000000000000 -r 59f7c34059ec main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Sep 23 11:21:28 2013 +0000
@@ -0,0 +1,236 @@
+/* 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);
+}
\ No newline at end of file