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);
}