This page is under construction.
The following is provided as a tutorial for music responsive lighting as requested. I didn't have a lot of time to put into this so I hope it helps. Feel free to contact me with any questions!
The following is provided as a tutorial for music responsive lighting as requested. I didn't have a lot of time to put into this so I hope it helps. Feel free to contact me with any questions!
Demonstration Videos:
Summary
See first: Sparkfun Spectrum Shield
This system was designed with the goal of having color-chasing LED effects that automatically sync with a hard music line. The color-chasing effects observed in the video are actually not synchronized to the music, but the changing of effects is. The system works well across many genres of music. This system is unique in that music volume does not matter. Many commercial implementations control lighting effects based off of overall volume intensity. This is problematic, as many people do not control final music volume with the source of the music (i.e. leaving your PC volume constant and controlling speaker volume instead.
An additional feature of this system is that it contains a wireless remote and the ability to control the lights independent of the music. This allows for rapid light patterns at parties, and soothing ambient lighting at all other times.
This system was designed with the goal of having color-chasing LED effects that automatically sync with a hard music line. The color-chasing effects observed in the video are actually not synchronized to the music, but the changing of effects is. The system works well across many genres of music. This system is unique in that music volume does not matter. Many commercial implementations control lighting effects based off of overall volume intensity. This is problematic, as many people do not control final music volume with the source of the music (i.e. leaving your PC volume constant and controlling speaker volume instead.
An additional feature of this system is that it contains a wireless remote and the ability to control the lights independent of the music. This allows for rapid light patterns at parties, and soothing ambient lighting at all other times.
Electrical System
The system is composed primarily of an Arduino, Sparkfun Spectrum Shield, and Super Bright LEDs Color Chasing RGB Controller. A music auxiliary input is fed into the Spectrum Shield, which splits the frequencies into 7 bands on a left and right channel. The Arduino analyzes the frequency signals, then uses a digital output to control the 'change effect' signal on the RGB Controller.
Code
The code is based on a simple algorithm.
The development of the threshold function took some experimentation on Excel. This was accomplished by running various songs through the system and using code from the internet to store the Arduino data in a text file. Then using Python code to error check and fix the file. Finally the data was input to Excel and graphed with several different threshold functions. The best threshold function and frequency for the project was chosen.
The threshold function is as follows:
threshold = (running average)*1.40
Whenever the intensity of the 63HZ band surpasses that threshold, the LED effect is changed and a delay time is entered to ensure that a single peak (i.e. a single drum beat) doesn't continuously set off the LED change.
This is the code. I wrote it during my lunch break and don't have a lot of time to work on this tutorial, so good luck working your way through it:)
Code:
/*
* Paul Schulman 2018
* Michigan State University
*/
//Declare Spectrum Shield pin connections
#define STROBE 4
#define RESET 5
#define DC_One A0
#define DC_Two A1
//Declare LED controller outputs
#define POWER 2 //this can be used to turn the LED controller on and off
#define MODEUP 3 //this can be used to change the LED effect
//many other buttons exist on the Superbright conroller that are not used here
//Define spectrum variables
int freq_amp;
//int Frequencies_One[7]; //left audio channel (not needed)
int Frequencies_Two[7]; //right audio channel
int i, j, k, rnd;
int history[] = {1000, 1000, 1000, 1000, 1000};
int sum;
double avg, threshold;
bool condition_met;
int hold_period = 10;
int rnd_max = 5;
double threshold_factor = 1.40;
int press_time = 50;
int n = 0; //n is used to select which of the 7 frequency bands to analyze, we analyze the 63HZ band (n=0)
/********************Setup Loop*************************/
void setup() {
//Set spectrum Shield pin configurations
pinMode(STROBE, OUTPUT);
pinMode(RESET, OUTPUT);
pinMode(DC_One, INPUT);
pinMode(DC_Two, INPUT);
digitalWrite(STROBE, HIGH);
digitalWrite(RESET, HIGH);
//Set LED controller configurations
pinMode(POWER, OUTPUT); //the power button is unused in my current setup, but can be used to turn the LEDs on/off
pinMode(MODEUP, OUTPUT);
//Initialize the LED controller buttons in their unpressed state
digitalWrite(POWER, HIGH);
digitalWrite(MODEUP, HIGH);
delay(3000);
//Turn on the LED controller
digitalWrite(POWER, LOW);
delay(press_time);
digitalWrite(POWER, HIGH);
//Initialize Spectrum Analyzers
digitalWrite(STROBE, LOW);
delay(1);
digitalWrite(RESET, HIGH);
delay(1);
digitalWrite(STROBE, HIGH);
delay(1);
digitalWrite(STROBE, LOW);
delay(1);
digitalWrite(RESET, LOW);
}
/****************Main Function Loop***************************/
void loop() {
Read_Frequencies(); //sample the music
condition_met = Analyse_Frequencies(); //check if threshold has been broken
if ((i==hold_period)&&(condition_met)){ //checks that this is a new intensity spike
Change_Effect(); //change the LED effect
i=0;
}
if (i<hold_period){ //ensures that a single intensity spike doesn't cause several LED changes
i += 1;
}
rnd += 1;
if(rnd == rnd_max){
rnd = 0;
}
delay(50); //this gives the Spectrum shield time to cycle between frequency bands
//it is not needed if you are only reading a single frequency band
}
/*************Pull frequencies from Spectrum Shield****************/
void Read_Frequencies(){
//Read frequencies for each band
for (freq_amp = 0; freq_amp<7; freq_amp++) //reads all frequency bands for the right audio signal
//this is unnecessary as we only use one of the frequency bands
{
Frequencies_Two[freq_amp] = analogRead(DC_Two); //see the Sparkfun Spectrum documentation to understand this proccess
digitalWrite(STROBE, HIGH);
digitalWrite(STROBE, LOW);
}
}
bool Analyse_Frequencies(){ //maintains a running average and adjusted threshold function
history[rnd] = Frequencies_Two[n]; //maintains a rnd-point running average, i.e. a 5-point running average for rnd=5
sum = 0;
for (k=0; k<rnd_max; k++){
sum += history[k];
}
avg = sum/rnd_max; //computes the running average
threshold = avg * threshold_factor; //adjusts the average to the threshold value
//this ensures that the LEDs are not continuously affected during random electrical noise when no music is playing
if ((Frequencies_Two[n] >= threshold)&&(Frequencies_Two[n]>100)){
return true; //threshold has been crossed, change effect
}
return false; //threshold has not been crossed, do not change effect
}
void Change_Effect(){ //simulate a button press on the Superbright LEDs Controller
digitalWrite(MODEUP, LOW);
delay(press_time); //this value is optimized for the Superbright RGB Color Chasing Controller
digitalWrite(MODEUP, HIGH);
}
- One frequency line on one channel is isolated from the Spectrum Shield.
- A running average function is maintained on the frequency input.
- The averaging function is shifted up to create a threshold for effect changing.
- Whenever the isolated frequency intensity rises above the threshold, the 'change effect' command is given.
- The Arduino sends a temporary digital low signal to the 'change effect' input line of the RGB controller. This is simulating a button press on the controller.
- A quick delay time is given to allow the frequency jump to subside.
The development of the threshold function took some experimentation on Excel. This was accomplished by running various songs through the system and using code from the internet to store the Arduino data in a text file. Then using Python code to error check and fix the file. Finally the data was input to Excel and graphed with several different threshold functions. The best threshold function and frequency for the project was chosen.
The threshold function is as follows:
threshold = (running average)*1.40
Whenever the intensity of the 63HZ band surpasses that threshold, the LED effect is changed and a delay time is entered to ensure that a single peak (i.e. a single drum beat) doesn't continuously set off the LED change.
This is the code. I wrote it during my lunch break and don't have a lot of time to work on this tutorial, so good luck working your way through it:)
Code:
/*
* Paul Schulman 2018
* Michigan State University
*/
//Declare Spectrum Shield pin connections
#define STROBE 4
#define RESET 5
#define DC_One A0
#define DC_Two A1
//Declare LED controller outputs
#define POWER 2 //this can be used to turn the LED controller on and off
#define MODEUP 3 //this can be used to change the LED effect
//many other buttons exist on the Superbright conroller that are not used here
//Define spectrum variables
int freq_amp;
//int Frequencies_One[7]; //left audio channel (not needed)
int Frequencies_Two[7]; //right audio channel
int i, j, k, rnd;
int history[] = {1000, 1000, 1000, 1000, 1000};
int sum;
double avg, threshold;
bool condition_met;
int hold_period = 10;
int rnd_max = 5;
double threshold_factor = 1.40;
int press_time = 50;
int n = 0; //n is used to select which of the 7 frequency bands to analyze, we analyze the 63HZ band (n=0)
/********************Setup Loop*************************/
void setup() {
//Set spectrum Shield pin configurations
pinMode(STROBE, OUTPUT);
pinMode(RESET, OUTPUT);
pinMode(DC_One, INPUT);
pinMode(DC_Two, INPUT);
digitalWrite(STROBE, HIGH);
digitalWrite(RESET, HIGH);
//Set LED controller configurations
pinMode(POWER, OUTPUT); //the power button is unused in my current setup, but can be used to turn the LEDs on/off
pinMode(MODEUP, OUTPUT);
//Initialize the LED controller buttons in their unpressed state
digitalWrite(POWER, HIGH);
digitalWrite(MODEUP, HIGH);
delay(3000);
//Turn on the LED controller
digitalWrite(POWER, LOW);
delay(press_time);
digitalWrite(POWER, HIGH);
//Initialize Spectrum Analyzers
digitalWrite(STROBE, LOW);
delay(1);
digitalWrite(RESET, HIGH);
delay(1);
digitalWrite(STROBE, HIGH);
delay(1);
digitalWrite(STROBE, LOW);
delay(1);
digitalWrite(RESET, LOW);
}
/****************Main Function Loop***************************/
void loop() {
Read_Frequencies(); //sample the music
condition_met = Analyse_Frequencies(); //check if threshold has been broken
if ((i==hold_period)&&(condition_met)){ //checks that this is a new intensity spike
Change_Effect(); //change the LED effect
i=0;
}
if (i<hold_period){ //ensures that a single intensity spike doesn't cause several LED changes
i += 1;
}
rnd += 1;
if(rnd == rnd_max){
rnd = 0;
}
delay(50); //this gives the Spectrum shield time to cycle between frequency bands
//it is not needed if you are only reading a single frequency band
}
/*************Pull frequencies from Spectrum Shield****************/
void Read_Frequencies(){
//Read frequencies for each band
for (freq_amp = 0; freq_amp<7; freq_amp++) //reads all frequency bands for the right audio signal
//this is unnecessary as we only use one of the frequency bands
{
Frequencies_Two[freq_amp] = analogRead(DC_Two); //see the Sparkfun Spectrum documentation to understand this proccess
digitalWrite(STROBE, HIGH);
digitalWrite(STROBE, LOW);
}
}
bool Analyse_Frequencies(){ //maintains a running average and adjusted threshold function
history[rnd] = Frequencies_Two[n]; //maintains a rnd-point running average, i.e. a 5-point running average for rnd=5
sum = 0;
for (k=0; k<rnd_max; k++){
sum += history[k];
}
avg = sum/rnd_max; //computes the running average
threshold = avg * threshold_factor; //adjusts the average to the threshold value
//this ensures that the LEDs are not continuously affected during random electrical noise when no music is playing
if ((Frequencies_Two[n] >= threshold)&&(Frequencies_Two[n]>100)){
return true; //threshold has been crossed, change effect
}
return false; //threshold has not been crossed, do not change effect
}
void Change_Effect(){ //simulate a button press on the Superbright LEDs Controller
digitalWrite(MODEUP, LOW);
delay(press_time); //this value is optimized for the Superbright RGB Color Chasing Controller
digitalWrite(MODEUP, HIGH);
}
Additional Considerations
Coming soon.