Spectrum Shield Hookup Guide
This Tutorial is Retired!
This tutorial covers concepts or technologies that are no longer current. It's still here for you to read and enjoy, but may not be as useful as our newest tutorials.
View the updated tutorial: Spectrum Shield Hookup Guide (v2)
Arduino Code
Basic Arduino Example
Now that you have your hardware all hooked up, it's time to get things blinking!
If you're unsure how to program your Arduino/RedBoard, please check our tutorial here.
We are going to walk through the SparkFun Spectrum Demo sketch. Download that file below, and upload it to your Arduino.
The first thing we must do in our code is set up the RedBoard pins to function properly. The Spectrum Shield pin connections to the RedBoard must be defined, and any pins that will be driving LEDs must also be declared.
language:c
//Declare Spectrum Shield pin connections
#define STROBE 4
#define RESET 5
#define DC_One A0
#define DC_Two A1
//Define LED connections on the Arduino/Shield
int LED[] = {7, 8, 9, 10, 11, 12, 13};
//Define spectrum variables
int freq_amp;
int Frequencies_One[7];
int Frequencies_Two[7];
int i;
Note that we declare the LED pins in an array. This enables us to step through the LED pins using a for
loop, which we will discuss later. We also declare two arrays Frequencies_One
and Frequencies_Two
. These will be used to store the frequencies output by the MSGEQ7 ICs.
In the setup loop, set each LED pin as an output (notice that for
loop used to step through each LED pin connection!), and set the initial state of the LEDs to off. The shield pins must also be declared as outputs for the STROBE
and RESET
pins so we can control the shield using the RedBoard. The DC output pins are each declared as an INPUT
in the code, because the RedBoard will be reading data in from these pins. Once the pins are declared, the ICs are initialized by cycling the STROBE and RESET pins as described earlier in the Control Pins section.
language:c
/********************Setup Loop*************************/
void setup() {
//Set LED pin configurations
for(i=0; i<7; i++)
{
pinMode(LED[i], OUTPUT);
digitalWrite(LED[i], LOW);
}
//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);
//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);
}
For the main section of the sketch, we loop through two user-defined functions. Read_Frequenices()
and Graph_Frequencies()
tell the RedBoard to read the frequencies coming off the Spectrum Shield, and light up the connected LEDs, respectively.
language:c
/****************Main Function Loop***************************/
void loop() {
Read_Frequencies();
Graph_Frequencies();
delay(50);
}
The Read_Frequencies()
function is defined next in the code. This steps through each frequency band on the Spectrum Shield, reading the DC values output, and storing these values into the predefined frequency arrays.
language:c
/*************Pull frquencies from Spectrum Shield****************/
void Read_Frequencies(){
//Read frequencies for each band
for (freq_amp = 0; freq_amp<7; freq_amp++)
{
digitalWrite(STROBE, HIGH);
delayMicroseconds(50);
digitalWrite(STROBE, LOW);
delayMicroseconds(50);
Frequencies_One[freq_amp] = analogRead(DC_One);
Frequencies_Two[freq_amp] = analogRead(DC_Two);
}
}
The function where the real fun happens is the Graph_Frequencies()
function. With this function, the RedBoard drives the LEDs based on the frequencies being read by the Spectrum Shield.
We have included two different example sketches in the repository, to show different methods of lighting the LEDs. Each will create a different effect, so you can choose which works better for your particular project. In this first example, we compare the two frequencies to see which is larger. We then use the higher DC output as the delay time for turning the LED on. This cycles through each LED, turning them on or off based on the frequency output. This creates a bit of a "Jacob's Ladder" effect with the lights.
language:c
/***********Light LEDs based on frequencies***********************/
void Graph_Frequencies(){
for( i= 0; i<7; i++)
{
if(Frequencies_Two[i] > Frequencies_One[i]){
digitalWrite(LED[i], HIGH);
delay(Frequencies_Two[i]);
digitalWrite(LED[i], LOW);
}
else{
digitalWrite(LED[i], HIGH);
delay(Frequencies_One[i]);
digitalWrite(LED[i], LOW);
}
}
}
If instead you would prefer to have all the LEDs on at the same time and have the lights brighten or dim based on the frequency outputs, use the SparkFun PWM Demo instead.
In this sketch, the LEDs are all turned on, but as the RedBoard cycles through each frequency channel, the RedBoard uses PWM to control the brightness of each LED. The frequency values are mapped from the 0-1023 analog readings to the 0-255 range that Arduinos can use for the analogWrite
function. This creates a pulsing light effect on all of the LEDs.
language:c
/***************Light LEDs based on frequencies******************/
void Graph_Frequencies(){
for( i= 0; i<7; i++)
{
if(Frequencies_Two[i] > Frequencies_One[i]){
analogWrite(LED[i], Frequencies_Two[i]/4);
}
else{
analogWrite(LED[i], Frequencies_One[i]/4);
}
}
}
Keep in mind to use this example, you must have your LEDs hooked up to pins that are capable of PWM. You can find more information about which pins have this functionality on the Arduino boards here.
Additional Examples
There are plenty of projects out there using the Spectrum Shield, so do a bit of searching if you need some more inspiration! Bliptronics, the collaborator on the Spectrum Shield wrote a great Arduino example that works with the Spectrum Shield and an LED matrix. The sketch is included here for reference, but you can also find it in the GitHub repository.
language:c
#include <LEDPixels.h>
//Example to control RGB LED Modules with Spectrum Analyzer
//Bliptronics.com
//Ben Moyes 2010
//Use this as you wish, but please give credit, or at least buy some of my LEDs!
//
LEDPixels LP; //Our LEDPixels library - see http://www.bliptronics.com/ArduinoCode/LEDPixels.zip
//For spectrum analyzer shield, these three pins are used.
//You can move pinds 4 and 5, but you must cut the trace on the shield and re-route from the 2 jumpers.
int spectrumReset=5;
int spectrumStrobe=4;
int spectrumAnalog=0; //0 for left channel, 1 for right.
//This holds the 15 bit RGB values for each LED.
//You'll need one for each LED, we're using 25 LEDs here.
//Note you've only got limited memory, so you can only control
//Several hundred LEDs on a normal arduino. Double that on a Duemilanove.
int MyDisplay[25];
// Spectrum analyzer read values will be kept here.
int Spectrum[7];
void setup() {
byte Counter;
//Initialize the LEDPixels library.
// refresh delay, address of data, number of LEDs, clock pin, data pin.
LP.initialize(25, &MyDisplay[0],25, 12, 11 );
//Setup pins to drive the spectrum analyzer.
pinMode(spectrumReset, OUTPUT);
pinMode(spectrumStrobe, OUTPUT);
//Init spectrum analyzer
digitalWrite(spectrumStrobe,LOW);
delay(1);
digitalWrite(spectrumReset,HIGH);
delay(1);
digitalWrite(spectrumStrobe,HIGH);
delay(1);
digitalWrite(spectrumStrobe,LOW);
delay(1);
digitalWrite(spectrumReset,LOW);
delay(5);
// Reading the analyzer now will read the lowest frequency.
// Turn all LEDs off.
LP.setRange(0,24,LP.color(0,0,0));
LP.show(); //Write out display to LEDs
}
void loop() {
int Counter, Counter2, Counter3;
showSpectrum();
delay(15); //We wait here for a little while until all the values to the LEDs are written out.
//This is being done in the background by an interrupt.
}
// Read 7 band equalizer.
void readSpectrum()
{
// Band 0 = Lowest Frequencies.
byte Band;
for(Band=0;Band <7; Band++)
{
Spectrum[Band] = (analogRead(spectrumAnalog) + analogRead(spectrumAnalog) ) >>1; //Read twice and take the average by dividing by 2
digitalWrite(spectrumStrobe,HIGH);
delayMicroseconds(50);
digitalWrite(spectrumStrobe,LOW);
delayMicroseconds(50);
}
}
void showSpectrum()
{
//Not I don;t use any floating point numbers - all integers to keep it zippy.
readSpectrum();
byte Band, BarSize, MaxLevel;
static unsigned int Divisor = 80, ChangeTimer=0; //, ReminderDivisor,
unsigned int works, Remainder;
MaxLevel = 0;
for(Band=0;Band<5;Band++)//We only graph the lowest 5 bands here, there is 2 more unused!
{
//If value is 0, we don;t show anything on graph
works = Spectrum[Band]/Divisor; //Bands are read in as 10 bit values. Scale them down to be 0 - 5
if(works > MaxLevel) //Check if this value is the largest so far.
MaxLevel = works;
for(BarSize=1;BarSize <=5; BarSize++)
{
if( works > BarSize) LP.setLEDFast( LP.Translate(Band,BarSize-1),BarSize*6,31-(BarSize*5),0);
else if ( works == BarSize) LP.setLEDFast( LP.Translate(Band,BarSize-1),BarSize*6,31-(BarSize*5),0); //Was remainder
else LP.setLEDFast( LP.Translate(Band,BarSize-1),5,0,5);
}
}
LP.show();
// Adjust the Divisor if levels are too high/low.
// If below 4 happens 20 times, then very slowly turn up.
if (MaxLevel >= 5)
{
Divisor=Divisor+1;
ChangeTimer=0;
}
else
if(MaxLevel < 4)
{
if(Divisor > 65)
if(ChangeTimer++ > 20)
{
Divisor--;
ChangeTimer=0;
}
}
else
{
ChangeTimer=0;
}
}
You will need to install the LEDPixels library in order to use the original designer example. The most up-to-date library is available here, or you can download the zip here.
If you need a reminder as to how to install an Arduino library, please check out our tutorial here.