Music Box

by OnlyDislike in Circuits > Arduino

19 Views, 0 Favorites, 0 Comments

Music Box

Screenshot 2026-06-22 at 9.53.14 AM.png

This is my music box, a final project for my computer engineering course. The project itself is incomplete and has a lot of room to improve, which I will explain in the later steps. The project itself is a simple Arduino project and will only require some additional resources to complete. The music box basically acts like one of those beat boxes you can see online, where you have a large array of keys and each key plays a note. While this loses some of the functionality of those ones, there is still a lot of fun to be had with my music box. I will not be explaining basic concepts like how to wire a button, only where to wire each pin of a component.

Supplies

Screenshot 2026-06-22 at 10.06.16 AM.png
Screenshot 2026-06-22 at 10.08.19 AM.png
61nX6gSVtVL._AC_SY300_SX300_QL70_ML2_.jpg
616dcMQXT3L._SX522_.jpg
31uSQTvsBML._SX342_SY445_QL70_ML2_.jpg
71cvvGHcMwL._SX522_.jpg
819NdywxXfL._SX522_.jpg
61c5dwBsi+L._SX522_.jpg
images.jpeg
  1. Keypad x1
  2. LCD 16x2 x1
  3. Rotary Encoder x1
  4. Rocker Switch x1
  5. Push Button x1
  6. Arduino x1
  7. Breadboard x1
  8. Speaker x1
  9. 4AA Battery Holder x1

*Note: You can buy a lot of these things in a kit style to save money; often kits include an LCD display, push button, Arduino, and breadboard, which you can find on Amazon for the price of 1.5 Arduinos. Additionally, while you can do this with just the Arduino and the breadboard, if you are using a box, it makes it easier to connect to the Arduino if you don't have long wires.

Shell

20260622_105647.jpg
20260622_105640.jpg
20260622_105650.jpg
20260622_105642.jpg

The first step is to take a box or any cardboard, for that matter, that you feel is the right size and isn't too big or too small to fit all the components onto. Feel free to move the components around in a way that feels right to you, but if you're following mine, cut out holes in the exact same locations, with the big rectangular hole on top of the box for the LCD display, the small slit below it is for the keypad, the hole to the left of the LCD is for the button, the hole on the back is for the rocker switch, the one on the right side is for the rotary encoder, and the red circle at the front is for the speaker to be attached on the inside. That red circle is just cut out of cardboard.

Testing

The second step, while not the most interesting, is important: ensure all of the components work correctly, whether it be testing the button to make sure it can output or if the speaker takes in input by playing a tone on it. Ensuring all your components work can prevent confusion later down the line, when the circuit stops working, for instance.

Adding Your Components

Whether you decide to wire it first or glue it in first is your choice. I personally glued it first and then wired it in second. I know it's strange; it's just a personal preference. You can either use superglue, tape, hot glue, or even screws where applicable to attach the components in the corresponding spots. The Arduino, breadboard, and battery holder need to be able to fit inside with one another without overlapping. The keypad needs to be outside as well as the LCD display, the rotary encoder, and the rocker switch; all need to be usable from outside the box. The speaker module needs to be placed inside the box facing out behind the red circle.

Wiring Your Components

Once you've finished securely attaching all your components to the appropriate locations, it's now time to start wiring them. Follow this list below if you want to make sure the code provided later still works. This is also where it's a good idea to attach ground and power from your Arduino to your breadboard.


LCD 16x2 Display:

Connect SDA to Analog Pin 4 (A4) and SCL to Analog Pin 5 (A5).

Connect VCC to Power (5V) and GND to Ground.


Keypad:

Connect the leftmost pin when the keypad is facing up to pin 11, then connect each subsequent pin to the Arduino going left from pin 11, so the next pin attaches to pin 10 on the Arduino and so on.


Push Button:

Connect the push button input to pin 12 of the Arduino. Then connect the other two appropriate pins to ground and power, respectively, ensuring power goes to the push button through a 10K resistor.


Speaker Module:

Connect the ground side (usually the black wire) to ground and the power side (usually the red or blue wire) to the A0 pin on the Arduino.


Rotary Encoder:

Connect VCC to power (5V), GND to ground, DC to pin 3 on the Arduino, and CLK to pin 2 on the Arduino.


Rocker Switch/4AA Battery Holder:

Connect the black wire of the 4AA battery holder to ground and the red wire to the side with an O symbol on the rocker switch. Once you've connected the rocker switch to power, connect the wire side with an I symbol to the VIN pin of the Arduino to supply the Arduino with power.

Code

If you've now ensured all the components are attached, working, and wired appropriately to the Arduino/breadboard, it's now time to code. I have attached a copy and pastable code below, which you can open via Arduino Cloud or IDE. Ensure you have downloaded the Keypad library by Mark Stanley and Alexander Brevig as well as the LiquidCrystal library for the LCD display by Hans-Christoph Steiner.


#include <Keypad.h>

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

//Keypad
const int ROW_NUM = 4; //four rows
const int COLUMN_NUM = 4; //four columns

char keys[ROW_NUM][COLUMN_NUM] = {
{ '1', '2', '3', 'A' },
{ '4', '5', '6', 'B' },
{ '7', '8', '9', 'C' },
{ '*', '0', '#', 'D' }
};

byte pin_rows[ROW_NUM] = { 11, 10, 9, 8 }; //connect to the row pinouts of the keypad
byte pin_column[COLUMN_NUM] = { 7, 6, 5, 4}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad(makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM);

//Speaker
const int speaker = A0;

//Rotary Encoder (COMMENTED OUT)
//const int DT = 3;
//const int CLK = 2;

//volatile int encoderCount = 0;
//int lastCount = 0;
//volatile byte lastClkState;

//Button
const int Button = 12;

int buttonState = 0;
int lastButtonState = HIGH;
int currentState = 1;

//LCD
LiquidCrystal_I2C lcd(0x27, 16, 2);

void setup() {
Serial.begin(9600);
pinMode(speaker, OUTPUT);

// Rotary Encoder Setup (COMMENTED OUT)
//pinMode(CLK, INPUT_PULLUP);
//pinMode(DT, INPUT_PULLUP);

//lastClkState = digitalRead(CLK);

//attachInterrupt(digitalPinToInterrupt(CLK), readEncoder, CHANGE);

pinMode(Button, INPUT_PULLUP);

Serial.print("Current Button State: ");
Serial.println(currentState);

lcd.init(); // initialize the lcd
lcd.backlight(); //Turn on backlight
}

void loop() {
int reading = digitalRead(Button);

// Check if button state change
if (reading != lastButtonState) {

delay(50);

// Read pin again to confirm stable state
int stableReading = digitalRead(Button);

if (stableReading == LOW && lastButtonState == HIGH) {

currentState++;

if (currentState > 5) {
currentState = 1;
}

Serial.print("Current State: ");
Serial.println(currentState);
}

// Save stable reading for next loop execution
lastButtonState = stableReading;
}

char key = keypad.getKey();

if (key) {
Serial.println(key);
}

// Rotary Encoder Display Logic (COMMENTED OUT)
//if ((encoderCount / 2) != lastCount) {
// lastCount = encoderCount / 2; // Save the actual physical step
// Serial.print("Position: ");
// Serial.println(lastCount);
//}


if (key == '1') {
tone(speaker, 800 / currentState / 16 * 1, 100);
}

if (key == '2') {
tone(speaker, 800 / currentState / 16 * 2, 100);
}

if (key == '3') {
tone(speaker, 800 / currentState / 16 * 3, 100);
}

if (key == 'A') {
tone(speaker, 800 / currentState / 16 * 4, 100);
}

if (key == '4') {
tone(speaker, 800 / currentState / 16 * 5, 100);
}

if (key == '5') {
tone(speaker, 800 / currentState / 16 * 6, 100);
}
if (key == '6') {
tone(speaker, 800 / currentState / 16 * 7, 100);
}

if (key == 'B') {
tone(speaker, 800 / currentState / 16 * 8, 100);
}

if (key == '7') {
tone(speaker, 800 / currentState / 16 * 9, 100);
}

if (key == '8') {
tone(speaker, 800 / currentState / 16 * 10, 100);
}

if (key == '9') {
tone(speaker, 800 / currentState / 16 * 11, 100);
}

if (key == 'C') {
tone(speaker, 800 / currentState / 16 * 12, 100);
}

if (key == '*') {
tone(speaker, 800 / currentState / 16 * 13, 100);
}

if (key == '0') {
tone(speaker, 800 / currentState / 16 * 14, 100);
}

if (key == '#') {
tone(speaker, 800 / currentState / 16 * 15, 100);
}

if (key == 'D') {
tone(speaker, 800 / currentState / 16 * 16, 100);
}

lcd.setCursor(0, 0); // Move cursor to top-left (Column 0, Row 0)
lcd.print("MusicBox By Khai");

lcd.setCursor(0, 1); // Move cursor to bottom-left (Column 0, Row 1)
lcd.print("Music State: ");
lcd.print(currentState);
}

// Rotary Encoder Interrupt Routine (COMMENTED OUT)
//void readEncoder() {
// byte currentClkState = digitalRead(CLK);
//
// // If the CLK state changed, a turn happened
// if (currentClkState != lastClkState) {
// // If CLK state is different from DT state, it is turning Clockwise
// if (digitalRead(DT) != currentClkState) {
// encoderCount++;
// } else { // Otherwise, it is turning Counter-Clockwise
// encoderCount--;
// }
// }
//
// // Save the current state for the next turn
// lastClkState = currentClkState;
//}

Next Steps

Once you've uploaded the code to an Arduino, test the machine to ensure it works. If power is not being delivered, you most likely did not wire the power supply to the rocker switch and to the Arduino correctly. If you want to do more, feel free to tinker with the rotary encoder, as the code is simply commented out. If yours works properly, you can use it as a volume adjuster or even a secondary control mechanism for something like a menu system. I was not able to use the rotary encoder because the component itself broke down on me.