Last week I dumped a lot of time into finishing the majority of the project for last class as I knew this week (and next) I’d be swamped with work for other classes. So luckily, I didn’t have much work to do to finish up this week. All I really needed to do was some re-programming of the visualizer to mesh nicely with the infinity icosahedron shape. Since I now no longer have 9 pixel bands per edge and instead have a continuous loops in the top and bottom of the icosahedron, I could expand the amount of pixels per frequency channel up to 18 pixels. This gave me the resolution to do a cooler volume visualizer by expanding from either side of a center point instead of expanding left to right. Other major changes I made to the visualization was changing the color of all the pixels based on which frequency is currently the loudest, as well as scaling the brightness of each band depending on how loud its corresponding frequency is. Finally, I setup the infinity icosahedron so that no wires were showing and surrounded it with a white background to help amplify the effect the dancing lights have outside the icosahedron.
And in case you’re curious on the source code for this project:
#include <Arduino.h>
#include <FastLED.h>
#include <math.h>
#define LED_PIN 7
#define NUM_LEDS 117
#define SPECTRUM_LENGTH 6
int RED[3] = {255, 0, 0};
int GREEN[3] = {0, 255, 0};
int BLUE[3] = {0, 0, 255};
int ORANGE[3] = {255, 100, 0};
int PURPLE[3] = {100, 0, 255};
int YELLOW[3] = {255, 255, 0};
CRGB leds[NUM_LEDS];
byte first = 1;
int band[18];
int scale = 1;
int color[3] = {RED[0], RED[1], RED[2]};
int rnd[18] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
void set_band (int b0, int b1, int b2, int b3, int b4, int b5, int b6, int b7, int b8,
int b9, int b10, int b11, int b12, int b13, int b14, int b15, int b16, int b17) {
band[0] = b0;
band[1] = b1;
band[2] = b2;
band[3] = b3;
band[4] = b4;
band[5] = b5;
band[6] = b6;
band[7] = b7;
band[8] = b8;
band[9] = b9;
band[10] = b10;
band[11] = b11;
band[12] = b12;
band[13] = b13;
band[14] = b14;
band[15] = b15;
band[16] = b16;
band[17] = b17;
}
void setupSpectrum() {
//Setup pins to drive the spectrum analyzer. It needs RESET and STROBE pins.
pinMode(5, OUTPUT);
pinMode(4, OUTPUT);
//Init spectrum analyzer
digitalWrite(4,LOW); //pin 4 is strobe on shield
digitalWrite(5,HIGH); //pin 5 is RESET on the shield
digitalWrite(4,HIGH);
digitalWrite(4,LOW);
digitalWrite(5,LOW);
}
void setup() {
Serial.begin(9600);
Serial.println("Hello World!");
setupSpectrum();
FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
}
int getLoudest(int spectrum[SPECTRUM_LENGTH]) {
byte loudestBand = 0;
int loudestValue = -1;
for(byte band = 0; band < SPECTRUM_LENGTH; band++) {
if (spectrum[band] > loudestValue) {
loudestBand = band;
loudestValue = spectrum[band];
}
}
return loudestBand;
}
void assignColor(int c[3]) {
color[0] = c[0];
color[1] = c[1];
color[2] = c[2];
}
void visualizeLoudest(int loudest) {
FastLED.clear();
switch (loudest)
{
case 0:
assignColor(ORANGE);
break;
case 1:
assignColor(BLUE);
break;
case 2:
assignColor(RED);
break;
case 3:
assignColor(GREEN);
break;
case 4:
assignColor(PURPLE);
break;
case 5:
assignColor(YELLOW);
break;
case 6:
assignColor(YELLOW);
break;
}
}
int r() {
return ((int)random(0, 2)) * 2;
}
void visualizeBand(float value, float max_val, float min_val) {
int diff = round((value - min_val) / (max_val - min_val) * 10);
if (diff > 10) diff = 10;
scale = 13 - diff;
switch (diff)
{
case 0:
set_band(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
break;
case 1:
set_band(0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0);
break;
case 2:
set_band(0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0);
break;
case 3:
set_band(0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0);
break;
case 4:
set_band(0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0);
break;
case 5:
set_band(0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0);
break;
case 6:
set_band(0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0);
break;
case 7:
set_band(0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0);
break;
case 8:
set_band(0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0);
break;
case 9:
set_band(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
break;
case 10:
if(millis() % 3 == 0) {
rnd[0] = r(); rnd[1] = r(); rnd[2] = r(); rnd[3] = r(); rnd[4] = r(); rnd[5] = r(); rnd[6] = r(); rnd[7] = r(); rnd[8] = r(); rnd[9] = r(); rnd[10] = r(); rnd[11] = r(); rnd[12] = r(); rnd[13] = r(); rnd[14] = r(); rnd[15] = r(); rnd[16] = r(); rnd[17] = r();
}
set_band(rnd[0], rnd[1], rnd[2], rnd[3], rnd[4], rnd[5], rnd[6], rnd[7], rnd[8], rnd[9], rnd[10], rnd[11], rnd[12], rnd[13], rnd[14], rnd[15], rnd[16], rnd[17]);
break;
default:
set_band(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
break;
}
}
void lightLED(int pos, int mode) {
switch (mode)
{
case 0:
leds[pos] = CRGB(0, 0, 0);
break;
case 1:
leds[pos] = CRGB(color[0] / scale, color[1] / scale, color[2] / scale);
break;
case 2:
leds[pos] = CRGB(color[0], color[1], color[2]);
break;
default:
leds[pos] = CRGB(0, 0, 0);
break;
}
}
void visualizeSpectrum(int spectrum[SPECTRUM_LENGTH], int start) {
for (int i = 0; i < SPECTRUM_LENGTH; i++) {
visualizeBand((float)spectrum[i], (float)1000, (float)50);
for (int pos = 0; pos < 18; pos ++) {
lightLED(start + pos + i * 18, band[pos]);
}
}
}
void printSpectrum(int spectrum[SPECTRUM_LENGTH]) {
for (int i = 0; i < SPECTRUM_LENGTH; i++) {
Serial.print(spectrum[i]);
Serial.print("\t");
}
Serial.println("");
}
// Function to read 7 band equalizers
void dance() {
// Spectrum analyzer read values will be kept here.
int middle[7]; // Band 0 = Lowest Frequencies.
int right[7];
int left[7];
// Get the reading from each of 7 channels each (left and right)
byte Band;
for (Band=0;Band <7; Band++) {
// left
left[Band] = analogRead(0);
// right
right[Band] = analogRead(1);
// middle
middle[Band] = (left[Band] + right[Band]) / 2;
digitalWrite(4,HIGH); //Strobe pin on the shield
delay(2);
digitalWrite(4,LOW);
}
visualizeLoudest(getLoudest(middle));
visualizeSpectrum(middle, 0);
// printSpectrum(middle);
FastLED.show();
}
void loop() {
dance();
delay(25);
}