LED Instrument
BY: Diamondique, Mohammed and Dziedzom
Materials:
LED strips(dotstar)
Wires
Breadboard
Arduino
Hot glue gun
Description: 4 strips of LED’s are hot glued onto a box that has a hole in the middle. The strips are all connected to an arduino and breadboard using wires. The positive and negative wire of each strip and the one connected to the arduino are soldered onto the breadboard. The pins of the clock and data are plugged into different pin areas of the arduino. Plug the cable into your computer, upload the code and the lights should work. An led strip will light up if you play a note in it’s frequency, whereas the other lights will be off.
Code:
#include <Adafruit_DotStar.h>
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
*/
#define NUMPIXELS 8 // Number of LEDs in your strip
// Here’s how to control the LEDs from any two pins:
//#define DATAPIN 1,2,3,4
//#define CLOCKPIN 8,9,10,11
//fill_solid(leds, NUM_LEDS, CRBG(Red, green, blue));
//Adafruit_DotStar strip = Adafruit_DotStar(NUMPIXELS, DATAPIN, CLOCKPIN, DOTSTAR_BGR);
Adafruit_DotStar strip_a = Adafruit_DotStar(8, 1, 8, DOTSTAR_BRG);
Adafruit_DotStar strip_b = Adafruit_DotStar(8, 2, 9, DOTSTAR_BRG);
Adafruit_DotStar strip_c = Adafruit_DotStar(8, 3, 10, DOTSTAR_BRG);
Adafruit_DotStar strip_d = Adafruit_DotStar(8, 4, 11, DOTSTAR_BRG);
// The last parameter is optional — this is the color data order of the
// DotStar strip, which has changed over time in different production runs.
// Your code just uses R,G,B colors, the library then reassigns as needed.
// Default is DOTSTAR_BRG, so change this if you have an earlier strip.
// Hardware SPI is a little faster, but must be wired to specific pins
// (Arduino Uno = pin 11 for data, 13 for clock, other boards are different).
//Adafruit_DotStar strip = Adafruit_DotStar(NUMPIXELS, DOTSTAR_BRG);
//clipping indicator variables
boolean clipping = 0;
//data storage variables
byte newData = 0;
byte prevData = 0;
unsigned int time = 0;//keeps time and sends vales to store in timer[] occasionally
int timer[10];//sstorage for timing of events
int slope[10];//storage for slope of events
unsigned int totalTimer;//used to calculate period
unsigned int period;//storage for period of wave
byte index = 0;//current storage index
float frequency;//storage for frequency calculations
int maxSlope = 0;//used to calculate max slope as trigger point
int newSlope;//storage for incoming slope data
//variables for decided whether you have a match
byte noMatch = 0;//counts how many non-matches you’ve received to reset variables if it’s been too long
byte slopeTol = 3;//slope tolerance- adjust this if you need
int timerTol = 10;//timer tolerance- adjust this if you need
//variables for amp detection
unsigned int ampTimer = 0;
byte maxAmp = 0;
byte checkMaxAmp;
byte ampThreshold = 30;//raise if you have a very noisy signal
//variables for tuning
int detectedfrequency;//frequency for note being played
// Because conditional #includes don’t work w/Arduino sketches…
#include <SPI.h> // COMMENT OUT THIS LINE FOR GEMMA OR TRINKET
//#include <avr/power.h> // ENABLE THIS LINE FOR GEMMA OR TRINKET
void setup(){
Serial.begin(9600);
//pinMode(13,OUTPUT);//led indicator pin
// pinMode(12,OUTPUT);//output pin
strip_a.begin();
strip_b.begin();
strip_c.begin();
strip_d.begin();
strip_a.show(); // Initialize all pixels to ‘off’
strip_b.show();// Initialize all pixels to ‘off’
strip_c.show();
strip_d.show();
cli();//diable interrupts
//set up continuous sampling of analog pin 0 at 38.5kHz
//clear ADCSRA and ADCSRB registers
ADCSRA = 0;
ADCSRB = 0;
ADMUX |= (1 << REFS0); //set reference voltage
ADMUX |= (1 << ADLAR); //left align the ADC value- so we can read highest 8 bits from ADCH register only
ADCSRA |= (1 << ADPS2) | (1 << ADPS0); //set ADC clock with 32 prescaler- 16mHz/32=500kHz
ADCSRA |= (1 << ADATE); //enabble auto trigger
ADCSRA |= (1 << ADIE); //enable interrupts when measurement complete
ADCSRA |= (1 << ADEN); //enable ADC
ADCSRA |= (1 << ADSC); //start ADC measurements
sei();//enable interrupts
}
ISR(ADC_vect) {//when new ADC value ready
PORTB &= B11101111;//set pin 12 low
prevData = newData;//store previous value
newData = ADCH;//get value from A0
if (prevData < 127 && newData >=127){//if increasing and crossing midpoint
newSlope = newData – prevData;//calculate slope
if (abs(newSlope-maxSlope)<slopeTol){//if slopes are ==
//record new data and reset time
slope[index] = newSlope;
timer[index] = time;
time = 0;
if (index == 0){//new max slope just reset
PORTB |= B00010000;//set pin 12 high
noMatch = 0;
index++;//increment index
}
else if (abs(timer[0]-timer[index])<timerTol && abs(slope[0]-newSlope)<slopeTol){//if timer duration and slopes match
//sum timer values
totalTimer = 0;
for (byte i=0;i<index;i++){
totalTimer+=timer[i];
}
period = totalTimer;//set period
//reset new zero index values to compare with
timer[0] = timer[index];
slope[0] = slope[index];
index = 1;//set index to 1
PORTB |= B00010000;//set pin 12 high
noMatch = 0;
}
else{//crossing midpoint but not match
index++;//increment index
if (index > 9){
reset();
}
}
}
else if (newSlope>maxSlope){//if new slope is much larger than max slope
maxSlope = newSlope;
time = 0;//reset clock
noMatch = 0;
index = 0;//reset index
}
else{//slope not steep enough
noMatch++;//increment no match counter
if (noMatch>9){
reset();
}
}
}
if (newData == 0 || newData == 1023){//if clipping
PORTB |= B00100000;//set pin 13 high- turn on clipping indicator led
clipping = 1;//currently clipping
}
time++;//increment timer at rate of 38.5kHz
ampTimer++;//increment amplitude timer
if (abs(127-ADCH)>maxAmp){
maxAmp = abs(127-ADCH);
}
if (ampTimer==1000){
ampTimer = 0;
checkMaxAmp = maxAmp;
maxAmp = 0;
}
}
void reset(){//clea out some variables
index = 0;//reset index
noMatch = 0;//reset match couner
maxSlope = 0;//reset slope
}
void checkClipping(){//manage clipping indicator LED
if (clipping){//if currently clipping
PORTB &= B11011111;//turn off clipping indicator led
clipping = 0;
}
}
void freqDetect(){
if (frequency > 200 & frequency < 100 ) {
//Adjust frequency based on instrument
//strip_a.setPixelColor(0, 226, 15, 15);
strip_a.setPixelColor(1, 226, 15, 15);
strip_a.setPixelColor(2, 226, 15, 15);
strip_a.setPixelColor(3, 226, 15, 15);
strip_a.setPixelColor(4, 226, 15, 15);
strip_a.setPixelColor(5, 226, 15, 15);
strip_a.setPixelColor(6, 226, 15, 15);
strip_a.setPixelColor(7, 226, 15, 15);
strip_a.setPixelColor(8, 226, 15, 15);
for (int x = 0; x<=9; x++) {
strip_b.setPixelColor(x, 0,0,0);
strip_c.setPixelColor(x, 0,0,0);
strip_d.setPixelColor(x, 0,0,0);
}
//fill_solid(strip_a, 8, (0, 0, 0));
//strip_b.setPixelColor(0, 0, 0, 0);
//strip_c.setPixelColor(0, 0, 0, 0);
//strip_d.setPixelColor(0, 0, 0, 0);
//strip_a.setPixelColor(7, 0, 0, 0);
}
if (frequency > 300.0 and frequency < 500) {
// Adjust frequency based on instrument
//strip_b.setPixelColor(0, 219, 79, 24);
strip_b.setPixelColor(1, 219, 79, 24);
strip_b.setPixelColor(2, 219, 79, 24);
strip_b.setPixelColor(3, 219, 79, 24);
strip_b.setPixelColor(4, 219, 79, 24);
strip_b.setPixelColor(5, 219, 79, 24);
strip_b.setPixelColor(6, 219, 79, 24);
strip_b.setPixelColor(7, 219, 79, 24);
strip_b.setPixelColor(8, 219, 79, 24);
for (int x = 0; x<=9; x++) {
strip_a.setPixelColor(x, 0,0,0);
strip_c.setPixelColor(x, 0,0,0);
strip_d.setPixelColor(x, 0,0,0);
}
//strip_a.setPixelColor(0, 0, 0, 0);
//strip_c.setPixelColor(0, 0, 0, 0);
//strip_d.setPixelColor(0, 0, 0, 0);
//strip_b.setPixelColor(7, 0, 0, 0);
}
if (frequency > 600.0 and frequency < 1500.0) {
// Adjust frequency based on instrument
//strip_c.setPixelColor(0, 226, 120, 34);
strip_c.setPixelColor(1, 226, 120, 34);
strip_c.setPixelColor(2, 226, 120, 34);
strip_c.setPixelColor(3, 226, 120, 34);
strip_c.setPixelColor(4, 226, 120, 34);
strip_c.setPixelColor(5, 226, 120, 34);
strip_c.setPixelColor(6, 226, 120, 34);
strip_c.setPixelColor(7, 226, 120, 34);
strip_c.setPixelColor(8, 226, 120, 34);
for (int x = 0; x<=9; x++) {
strip_a.setPixelColor(x, 0,0,0);
strip_b.setPixelColor(x, 0,0,0);
strip_d.setPixelColor(x, 0,0,0);
}
//strip_a.setPixelColor(0, 0, 0, 0);
//strip_b.setPixelColor(0, 0, 0, 0);
//strip_d.setPixelColor(0, 0, 0, 0);
//strip_c.setPixelColor(7, 0, 0, 0);
}
if (frequency > 2000.0 and frequency < 2500.0) {
// Adjust frequency based on instrument
//strip_d.setPixelColor(0, 247, 209, 94);
strip_d.setPixelColor(1, 247, 209, 94);
strip_d.setPixelColor(2, 247, 209, 94);
strip_d.setPixelColor(3, 247, 209, 94);
strip_d.setPixelColor(4, 247, 209, 94);
strip_d.setPixelColor(5, 247, 209, 94);
strip_d.setPixelColor(6, 247, 209, 94);
strip_d.setPixelColor(7, 247, 209, 94);
strip_d.setPixelColor(8, 247, 209, 94);
for (int x = 0; x<=9; x++) {
strip_a.setPixelColor(x, 0,0,0);
strip_b.setPixelColor(x, 0,0,0);
strip_c.setPixelColor(x, 0,0,0);
}
strip_a.show();
strip_b.show();
strip_c.show();
strip_d.show();
}
void loop() {
checkClipping();
if (checkMaxAmp>ampThreshold){
frequency = 38462/float(period);//calculate frequency timer rate/period
//print results
Serial.print(frequency);
Serial.println(” hz”);
}
freqDetect();
delay(80);
}
End Product: