Concept:
For this assignment, my partner Fasya and I designed a musical instrument that merges digital and analog elements to create an interactive, light-based piano. Our idea centers around a glowing wand that functions as a control interface. When moved over the keys, the wand activates notes from the C major scale (C, D, E, F, and G) like magic, and the brightness of its glow determines the octave. We integrated a potentiometer to adjust brightness, allowing users to easily shift the octave up or down. Additionally, we added a switch to toggle the instrument off, which prevents accidental note activation—particularly useful to avoid unintended sounds from ambient light sources like flashlights.
Highlight:
To bring our vision to life, we used five photoresistors to detect light from the wand and mapped each sensor’s range to specific notes (C, D, E, F, and G) and their octave scales. By setting sensor thresholds from a default minimum to a maximum value that a flashlight might produce, we could dynamically adjust the octave based on the brightness the photoresistor detects. Essentially, the brighter the wand, the higher the octave, allowing for an expressive range in tone.
For the wand itself, we created a purple glow using a tricolored LED, giving the instrument an ethereal fairy-like visual quality. A potentiometer is attached to the LED to control brightness, making it easy for users to adjust octaves on the fly. The setup includes separate circuits for the keyboard and wand, creating flexibility for future enhancements, such as adding multiple wands for collaborative play.
Keyboard Code:
#include "pitches.h"
bool buttonState = false;
// Define the piezo buzzer pin
const int buzzerPin = 8;
// Define frequencies for each note across multiple octaves
const int fNotes[] = {NOTE_F4, NOTE_F5, NOTE_F6, NOTE_F7}; // Octaves of A
const int gNotes[] = {NOTE_G4, NOTE_G5, NOTE_G6, NOTE_G7}; // Octaves of B
const int cNotes[] = {NOTE_C4, NOTE_C5, NOTE_C6, NOTE_C7}; // Octaves of C
const int dNotes[] = {NOTE_D4, NOTE_D5, NOTE_D6, NOTE_D7}; // Octaves of D
const int eNotes[] = {NOTE_E4, NOTE_E5, NOTE_E6, NOTE_E7}; // Octaves of E
void setup() {
// Initialize serial communication at 9600 bps for debugging
Serial.begin(9600);
pinMode(7,INPUT);
}
void loop() {
// Array to store sensor values
int sensorValues[5];
int switchValue = digitalRead(7);
if (switchValue == HIGH){
buttonState = true;
}
// Read each sensor value and store in the array
sensorValues[0] = analogRead(A3); // f note
sensorValues[1] = analogRead(A4); // g note
sensorValues[2] = analogRead(A0); // C note
sensorValues[3] = analogRead(A1); // D note
sensorValues[4] = analogRead(A2); // E note
// Play a note based on each sensor value
for (int i = 0; i < 5; i++) {
int note;
if (sensorValues[i] < 850 || !buttonState) {
// Stop any sound if the sensor value is below 900
noTone(buzzerPin);
continue;
} else {
// Map the sensor value (900 to 1100) to an index (0 to 3) for each note array
int noteIndex = map(sensorValues[i], 850, 1100, 0, 3);
// Assign the note based on the sensor index
switch(i) {
case 0: note = fNotes[noteIndex]; break;
case 1: note = gNotes[noteIndex]; break;
case 2: note = cNotes[noteIndex]; break;
case 3: note = dNotes[noteIndex]; break;
case 4: note = eNotes[noteIndex]; break;
}
// Play the mapped frequency on the piezo buzzer
tone(buzzerPin, note);
}
// Delay to control the speed of tone change
delay(100);
}
}
Wand Code:
// *Interfacing RGB LED with Arduino
// * Author: Osama Ahmed
//Defining variable and the GPIO pin on Arduino
int redPin= 9;
int greenPin = 10;
int bluePin = 11;
int potPin = A2;
int sensorVal = 0;
double brightness = 0;
void setup() {
Serial.begin(9600);
//Defining the pins as OUTPUT
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
}
void loop() {
sensorVal = analogRead(potPin);
brightness = (double)sensorVal / 1023;
Serial.println(brightness);
setColor(170, 0, 255, brightness); // Purple Color
// delay(1000);
}
void setColor(int redValue, int greenValue, int blueValue, double brightValue) {
analogWrite(redPin, (double) redValue * brightValue);
analogWrite(greenPin, (double) greenValue * brightValue);
analogWrite(bluePin, (double) blueValue * brightValue);
}
Demonstration:

