LED Piano: Code

We used the function “tone” to output the sound on the speaker.

To control the LED outputs, we had to make function called “OutputRegister.” This function enables output registers to load bits that we want in register. Once loaded in, they latch to the outputs. The first number you input to the function accepts how many LEDs you want to turn on. The second number is how many spaces you want between the LEDs.

To have capacitive touch interact with the LEDs and music, we wrote a function called “PianoPlay.” This is basically a “free play function.” Once we put in our main loop it allows the user to play anything on the instrument freely. The function consists of a combination of “if” and “else” statements. A threshold is set for the capacitive touch pins and once a pin exceeds the threshold (you touch the wire with your finger), it produces a tone.

We combined “tone” “OutputRegister” and “PianoPlay” to complete the code for our project.

 

Two ways to play a pre-programmed song:

Button:

The button we have uses an interrupt. The button is hooked to the interrupt pin on the Arduino through a pull up resister. When the button is pressed, the pin receives a low signal which activates interrupt. This makes it go to the button function in the code, which then toggles the state variable to high. Once state is high, a pre-programmed song is played.

Pulse Width Modulation:

PWM is our interface with the A3BU. We’re using A3BU to transmit a PWM signal. If we type a certain word in TeraTerm, a PWM signal is inputted into one Arduino pin. Once the Arduino senses it, it will play a pre-programmed song.

Here is the code for the Arduino part of the project.


#include <SPI.h>
#include <CapacitiveSensor.h>
#include "pitches.h"

//Pin Color Code
//White = Clock and Latch
//Blue = Serial
//Yellow = Output
//Red = Power
//Black/Green = GND

//LED Setup
int serialIn = 8; //inputs serial to the shift register
int latchIn = 9; //latches the serial data in the register to the parallel outputs
int clockIn = 10; //allows the shift register to function. Action occurs when clock is low
boolean registers[32];

//BUTTON Setup
int buttonIn = 1; //Pin 3
volatile int state = LOW;

//PWM Setup
byte PWM_PIN = 5;
int pwm_value;

//MUSIC Setup
#define COMMON_PIN 2 // The common 'send' pin for all keys
#define BUZZER_PIN A4 // The output pin for the piezo buzzer
#define NUM_OF_SAMPLES 10 // Higher number whens more delay but more consistent readings
#define CAP_THRESHOLD 150 // Capactive reading that triggers a note (adjust to fit your needs)
#define NUM_OF_KEYS 8 // Number of keys that are on the keyboard
#define CS(Y) CapacitiveSensor(2, Y)
int notes[] = {NOTE_C4, NOTE_D4, NOTE_E4, NOTE_F4, NOTE_G4, NOTE_A4, NOTE_B4, NOTE_C5}; // C-Major scale
int total[NUM_OF_KEYS];
CapacitiveSensor keys[] = {CS(A0), CS(4), CS(A1), CS(6), CS(7), CS(11), CS(12), CS(13)};

/******SETUP BEGIN*******/
void setup() {
Serial.begin(9600);

//LED Matrix Setup
pinMode(serialIn, OUTPUT);
pinMode(latchIn, OUTPUT);
pinMode(clockIn, OUTPUT);

//Button Setup
attachInterrupt(buttonIn, buttonControl, LOW);

//PWM Setup
pinMode(PWM_PIN, INPUT);

//MUSIC Setup
for (int i = 0; i < 8; ++i) {
keys[i].set_CS_AutocaL_Millis(0xFFFFFFFF);
}
pinMode(BUZZER_PIN, OUTPUT);
}
/*****SETUP END******/

/******FUNCTIONS BEGINS******/

/*****CLEAR FUNCTION******/
void clearAll() {
//SETUP
digitalWrite(latchIn, LOW);
digitalWrite(clockIn, HIGH);

//WRITE LOW's
digitalWrite(serialIn, LOW);
for (int i = 0; i < 32; i++) {
digitalWrite(clockIn, LOW);
digitalWrite(clockIn, HIGH);
}

//LATCH
digitalWrite(latchIn, HIGH);
}
/*****PIANO FUNCTION*****/
void pianoPlay() {
if (total[0] > CAP_THRESHOLD)
{
tone(BUZZER_PIN, notes[0]);
clearAll();
outputRegister(4, 0);
} else if (total[1] > CAP_THRESHOLD)
{
tone(BUZZER_PIN, notes[1]);
clearAll();
outputRegister(4, 4);
} else if (total[2] > CAP_THRESHOLD)
{
tone(BUZZER_PIN, notes[2]);
clearAll();
outputRegister(4, 8);
} else if (total[3] > CAP_THRESHOLD)
{
tone(BUZZER_PIN, notes[3]);
clearAll();
outputRegister(4, 12);
} else if (total[4] > CAP_THRESHOLD)
{
tone(BUZZER_PIN, notes[4]);
clearAll();
outputRegister(4, 16);
} else if (total[5] > CAP_THRESHOLD)
{
tone(BUZZER_PIN, notes[5]);
clearAll();
outputRegister(4, 20);
} else if (total[6] > CAP_THRESHOLD)
{
tone(BUZZER_PIN, notes[6]);
clearAll();
outputRegister(4, 24);
} else if (total[7] > CAP_THRESHOLD)
{
tone(BUZZER_PIN, notes[7]);
clearAll();
outputRegister(4, 28);
} else
{
noTone(BUZZER_PIN);
clearAll();
}
}
/*****LED OUTPUT FUNCTION*****/
void outputRegister(int leds, int spaces) {

//SETUP
digitalWrite(latchIn, LOW);
digitalWrite(clockIn, HIGH);

//WRITE HIGH's
digitalWrite(serialIn, HIGH);
for (int i = 0; i < leds; i++) {
digitalWrite(clockIn, LOW);
digitalWrite(clockIn, HIGH);
}

//WRITE LOW's
digitalWrite(serialIn, LOW);
for (int i = 0; i < spaces; i++) {
digitalWrite(clockIn, LOW);
digitalWrite(clockIn, HIGH);
}

//LATCH
digitalWrite(latchIn, HIGH);

}
/****BUTTON CONTROL FUNCTION****/
void buttonControl() {
for (int j = 0; j < 50; j++)
{
delayMicroseconds(1000);
}
state = !state;
Serial.println("Goodbye");
}

/*******FUNCTIONS END********/

/*********MAIN LOOP BEGIN**********/
void loop() {

//ENABLE TOUCH
total[0] = keys[0].capacitiveSensor(30);
total[1] = keys[1].capacitiveSensor(30);
total[2] = keys[2].capacitiveSensor(30);
total[3] = keys[3].capacitiveSensor(30);
total[4] = keys[4].capacitiveSensor(30);
total[5] = keys[5].capacitiveSensor(30);
total[6] = keys[6].capacitiveSensor(30);
total[7] = keys[7].capacitiveSensor(30);

//TOUCH SENSOR PRINT
Serial.println(total[0]);
Serial.println(total[1]);
Serial.println(total[2]);
Serial.println(total[3]);
Serial.println(total[4]);
Serial.println(total[5]);
Serial.println(total[6]);
Serial.println(total[7]);
//FREE PLAY
pianoPlay();

//BUTTON SONG
//if(state == HIGH)
//{
//}
//PWM SONG
// pwm_value = pulseIn(PWM_PIN, HIGH);
// Serial.println(pwm_value);
//if(pwm_value<400 && pwm_value>370)
//{
//}

}
/**********MAIN LOOP END**********/