Project tutorial
Arduino Piano w/ Preset Songs

Arduino Piano w/ Preset Songs © GPL3+

Arduino Piano using an Arduino Mega2560. 13 keys, 20x4 LCD display, and 2 buttons to reset or change songs.

  • 23 views
  • 0 comments
  • 0 respects

Components and supplies

About this project

I'm an Electrical Engineering student and in one of my classes we had a semester long project. The project was open-ended and it to incorporate something in the electronics field of study. I decided to make a piano using Arduino since I had knowledge from the previous year of coding. I never quite understood coding as well as I do now. Doing a project by yourself is challenging but very rewarding. Troubleshooting is the best way to learn sometimes!

***Feel free to change components or pins as needed, this is just what I did for my project.***

************************************************************************************************************************************************************

I coded the songs using arrays and a for loop to step through the arrays. The songs were consisted of 2 arrays, one for the notes and the other array for the tempo. Making an array for the tones was easy, it was the tempo that was a bit interesting to make. There are two ways to do the tempo array, here's one way to do the ratio, since all tempo is a ratio based on BPM and 60, 000 ms (1 minute in milliseconds). I took the BPM of the songs I used and did some math. For example, Flamingo is a 178 bpm.

60, 000 / 179 = 337.08 ms.

Round to closest number and I get 337 ms for a quarter note. Using ratios and number manipulation I can get an half note, eighth note, sixteenth note, etc.

337 / 2 = 168.5 == 169 ms. Which is an eighth note.

169 / 2 = 84 ms. Sixteenth note.

The other way I did the ratio in the for loop was like this:

(60, 000 / BPM) / (32 / songtempo[thisNote])

Which is just dividing the 60, 000 ms by the BPM and the note duration in the array. I had help from this website http://www.sengpielaudio.com/calculator-bpmtempotime.htm

******************************************************************************

******************************************************************************

The code was relatively straightforward. Define variables. Void setup my buttons as INPUT_PULLUP to use the Arduino Mega internal resistors. Makes the circuit naturally ON or HIGH. Use 2 interrupts. Code main loop. Code my piano keys with while loops. The only trouble was figuring out the interrupts and the for loop. But after some troubleshooting and some help, I managed to code my for loops and my interrupts correctly. I used a bool to latch on my code, and to latch out when I needed to with the interrupts.

I noticed that sometimes changing songs, there is sometimes issues changing songs. I think maybe it's due to the interruption of the for loop and the Arduino has trouble changing into the next song. And/or also the buzzer tone will distort slightly as it changes songs. Dependent on whether you use an active or passive buzzer, there will be differences in sound quality, etc.

How the code works:

Main Loop:

  • 4 If statements. One for each song. Change which for loop is being used, clear and change the display to show the song title.
  • notes() this is the piano keys, just put into a different void for less clutter in the main loop

Void Notes:

  • Use while statements for each key
  • Display the Note & frequency
  • Tone note to buzzer
  • Code noTone(buzzer) in this loop, so that a note isn't left playing when I let go or change notes
  • Clear the LCD display if no note is being held down

For Loops:

  • Step through the note array for a song, and use the tempo array in tandem to create a song
  • Latch a bool in there so I can use my reset or count button to interrupt the for loop at anytime (thisNote < size && !halt);
  • int noteDuration is the length of the note & using the tempo array for the song
  • tone (buzzer, note, duration) this is the standard format of the tone function. I used ratios and variables for less "hard" coding
  • int pauseBetweenNotes is to distinguish each note. noteDuration * 1 ---- I can change the 1 into 1.5 to make each note longer. Or cut it short from 1 into.5 which is shorter note tempos/durations. It's a multiplier
  • Bool is set to FALSE outside the For Loop, so I can interrupt the loop with my interrupt function

Songs coded:

  • Flamingo - Kero Kero Bonito
  • Hall of Fame - The Script
  • Prelude - Final Fantasy 7
  • Best Love Song - T-Pain

Make sure to make a header file/include a Pitches.h file. And download the LCD I2C Arduino Library. Include that into the library folder so the display can work properly.

LCD I2C library-> https://www.arduinolibraries.info/libraries/liquid-crystal-i2-c

Code

Arduino PIanoC/C++
Defines + Setup + Interrupts + Main Loop + Voids + For Loops
#include "pitches.h"
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#define buttonC  22
#define buttonCS 24
#define buttonD  26
#define buttonDS 28
#define buttonE  30
#define buttonF  32
#define buttonFS 34
#define buttonG  36
#define buttonGS 38
#define buttonA  40
#define buttonAS 42
#define buttonB  44
#define buttonC2 46

bool screen = true;
bool halt = false;
bool pressed = false;
const int resetbutton = 2;
const int countbutton = 3;

const int buzzer = 11;
volatile int count = 0;

int fameBPM = 168;
int preludeBPM = 150;
int loveBPM = 160;

LiquidCrystal_I2C lcd(0x27, 20, 4);

int flamingo[] =
{
  //1ST loop
  NOTE_GS4, NOTE_AS4, NOTE_C5, NOTE_DS5,
  NOTE_F5,  NOTE_F5,  NOTE_G5, NOTE_F5,
  NOTE_DS5, NOTE_C5,  NOTE_F5, NOTE_DS5,

  NOTE_G4,
  NOTE_GS4, NOTE_AS4, NOTE_C5, NOTE_DS5,
  NOTE_F5,  NOTE_F5,  NOTE_G5, NOTE_F5,
  NOTE_DS5, NOTE_D5,  NOTE_AS4,

  NOTE_G4,  NOTE_C5,  NOTE_G4,  NOTE_C5, NOTE_AS4,

  NOTE_G4,  NOTE_FS4,
  NOTE_F4,  NOTE_GS4, NOTE_DS5,
  NOTE_F4,  NOTE_GS4, NOTE_DS5,
  NOTE_F4,  NOTE_DS5, NOTE_DS5,
  NOTE_F4,  NOTE_DS5, NOTE_F4,
  NOTE_G4,  NOTE_DS5, NOTE_G4, NOTE_AS4,

  //2ND LOOP
  NOTE_GS4, NOTE_AS4, NOTE_C5, NOTE_DS5,
  NOTE_F5,  NOTE_F5,  NOTE_G5, NOTE_F5,
  NOTE_DS5, NOTE_C5,  NOTE_F5, NOTE_DS5,

  NOTE_G4,
  NOTE_GS4, NOTE_AS4, NOTE_C5, NOTE_DS5,
  NOTE_F5,  NOTE_F5,  NOTE_G5, NOTE_F5,
  NOTE_DS5, NOTE_D5,  NOTE_AS4,

  NOTE_G4,  NOTE_C5,  NOTE_G4,  NOTE_C5, NOTE_AS4,

  NOTE_G4,  NOTE_FS4,
  NOTE_F4,  NOTE_GS4, NOTE_DS5,
  NOTE_F4,
  NOTE_C5,  NOTE_D5,  NOTE_DS5,
  0, 0
};

//notes in milliseconds
int tempo[]
{
  //1st measure
  169, 169, 169, 337,
  337, 84, 84,

  //2nd
  337, 337, 337, 337,

  //3rd
  505, 169, 169, 169, 169, 337,
  //4
  337, 84, 84, 337, 337,
  //5
  674, 505, 337,

  169, 169, 169, 505, 84, 84,

  169, 169, 169, 169, 169, 169, 169, 169,
  169, 169, 169, 169, 169, 169, 169, 169,

  //2nd loop 9th measure
  169, 169, 169, 337,
  337, 84, 84,

  337, 337, 337, 337,

  505, 169, 169, 169, 169, 337,

  337, 84, 84, 337, 337,

  647, 505, 337,

  169, 169, 169, 505, 84, 84,

  169, 169, 169, 169, 337, 337,

  674, 337, 337
};

int fame[]
{
  NOTE_AS4, NOTE_A4, NOTE_AS4, NOTE_G4,
  NOTE_AS4, NOTE_D4, NOTE_AS4, NOTE_G4,
  NOTE_AS4, NOTE_DS4, NOTE_DS5, NOTE_G4,
  NOTE_AS4, NOTE_DS4, NOTE_DS5, NOTE_AS4,

  NOTE_D5, NOTE_AS4, NOTE_DS5, NOTE_AS4,
  NOTE_F5, NOTE_AS4, NOTE_B4, NOTE_A4,
  NOTE_B4, NOTE_F4, NOTE_F5, NOTE_F4,
  NOTE_C5, NOTE_F4, NOTE_F5, NOTE_A4,

  NOTE_AS4, NOTE_A4, NOTE_AS4, NOTE_G4,
  NOTE_AS4, NOTE_D4, NOTE_AS4, NOTE_G4,
  NOTE_AS4, NOTE_DS4, NOTE_DS5, NOTE_G4,
  NOTE_AS4, NOTE_DS4, NOTE_DS5, NOTE_AS4,

  NOTE_D5, NOTE_AS4, NOTE_DS5, NOTE_AS4,
  NOTE_F5, NOTE_AS4, NOTE_C5, NOTE_A4,
  NOTE_C5, NOTE_F4, NOTE_F5, NOTE_F4,
  NOTE_C5, NOTE_F4, NOTE_F5, NOTE_A4
};

int fametempo[]
{
  16, 16, 16, 16,
  16, 16, 16, 16,
  16, 16, 16, 16,
  16, 16, 16, 16,

  16, 16, 16, 16,
  16, 16, 16, 16,
  16, 16, 16, 16,
  16, 16, 16, 16,

  16, 16, 16, 16,
  16, 16, 16, 16,
  16, 16, 16, 16,
  16, 16, 16, 16,

  16, 16, 16, 16,
  16, 16, 16, 16,
  16, 16, 16, 16,
  16, 16, 16, 16
};

int prelude[]
{
  NOTE_C3, NOTE_D3, NOTE_E3, NOTE_G3,
  NOTE_C4, NOTE_D4, NOTE_E4, NOTE_G4,
  NOTE_C5, NOTE_D5, NOTE_E5, NOTE_G5,
  NOTE_C6, NOTE_D6, NOTE_E6, NOTE_G6,
  NOTE_C7, 

  NOTE_G6, NOTE_E6, NOTE_D6, NOTE_C6,
  NOTE_G5, NOTE_E5, NOTE_D5, NOTE_C5,
  NOTE_G4, NOTE_E4, NOTE_D4, NOTE_C4,
  NOTE_G3, NOTE_E3, NOTE_D3, 

  NOTE_A2, NOTE_B2, NOTE_C2, NOTE_E2,
  NOTE_A3, NOTE_B3, NOTE_C3, NOTE_E3,
  NOTE_A4, NOTE_B4, NOTE_C4, NOTE_E4,
  NOTE_A5, NOTE_B5, NOTE_C5, NOTE_E5,
  NOTE_A6,

  NOTE_E5, NOTE_C5, NOTE_B5, NOTE_A5,
  NOTE_E4, NOTE_C4, NOTE_B4, NOTE_A4,
  NOTE_E3, NOTE_C3, NOTE_B3, NOTE_A3,
  NOTE_E2, NOTE_C2, NOTE_B2,
//2ND LOOP
  NOTE_C3, NOTE_D3, NOTE_E3, NOTE_G3,
  NOTE_C4, NOTE_D4, NOTE_E4, NOTE_G4,
  NOTE_C5, NOTE_D5, NOTE_E5, NOTE_G5,
  NOTE_C6, NOTE_D6, NOTE_E6, NOTE_G6,
  NOTE_C7, 

  NOTE_G6, NOTE_E6, NOTE_D6, NOTE_C6,
  NOTE_G5, NOTE_E5, NOTE_D5, NOTE_C5,
  NOTE_G4, NOTE_E4, NOTE_D4, NOTE_C4,
  NOTE_G3, NOTE_E3, NOTE_D3, 

  NOTE_A2, NOTE_B2, NOTE_C2, NOTE_E2,
  NOTE_A3, NOTE_B3, NOTE_C3, NOTE_E3,
  NOTE_A4, NOTE_B4, NOTE_C4, NOTE_E4,
  NOTE_A5, NOTE_B5, NOTE_C5, NOTE_E5,
  NOTE_A6,

  NOTE_E6, NOTE_C6, NOTE_B6, NOTE_A6,
  NOTE_E5, NOTE_C5, NOTE_B5, NOTE_A5,
  NOTE_E4, NOTE_C4, NOTE_B4, NOTE_A4,
  NOTE_E3, NOTE_C3, NOTE_B2, NOTE_A2,
//3rd - new section
  NOTE_C3, NOTE_F3, NOTE_G3, NOTE_A3,
  NOTE_C4, NOTE_F4, NOTE_G4, NOTE_A4,
  NOTE_C5, NOTE_F5, NOTE_G5, NOTE_A5,
  NOTE_C6, NOTE_F6, NOTE_G6, NOTE_A6,

  NOTE_G6, NOTE_F6, NOTE_C6, NOTE_A5,
  NOTE_G5, NOTE_F5, NOTE_C5, NOTE_A4,
  NOTE_G4, NOTE_F4, NOTE_C4, NOTE_A3,
  NOTE_G3, NOTE_F3, NOTE_C3, NOTE_B2,

  NOTE_D3, NOTE_G3, NOTE_A3, NOTE_B3,
  NOTE_D4, NOTE_G4, NOTE_A4, NOTE_B4,
  NOTE_D5, NOTE_G5, NOTE_A5, NOTE_B5,
  NOTE_D6, NOTE_G6, NOTE_A6, NOTE_B6,

  NOTE_A6, NOTE_G6, NOTE_D6, NOTE_B5,
  NOTE_A5, NOTE_G5, NOTE_D5, NOTE_B4,
  NOTE_A4, NOTE_G4, NOTE_D4, NOTE_B3,
  NOTE_A3, NOTE_G3, NOTE_D3, 
//13
  NOTE_GS2, NOTE_C3, NOTE_DS3, NOTE_G3,
  NOTE_GS3, NOTE_C4, NOTE_DS4, NOTE_G4,
  NOTE_GS4, NOTE_C5, NOTE_DS5, NOTE_G5,
  NOTE_GS5, NOTE_C6, NOTE_DS6, NOTE_G6,

  NOTE_DS6, NOTE_C6, NOTE_GS5, NOTE_G5,
  NOTE_DS5, NOTE_C5, NOTE_GS4, NOTE_G4,
  NOTE_DS4, NOTE_C4, NOTE_GS3, NOTE_G3,
  NOTE_DS3, NOTE_C3, NOTE_GS2,

  NOTE_D3, NOTE_F3, NOTE_A3, NOTE_AS3,
  NOTE_D4, NOTE_F4, NOTE_A4, NOTE_AS4,
  NOTE_D5, NOTE_F5, NOTE_A5, NOTE_AS5,
  NOTE_D6, NOTE_F6, NOTE_A6, NOTE_AS6,
   
  NOTE_A6, NOTE_F6, NOTE_D6, NOTE_AS5,
  NOTE_A5, NOTE_F5, NOTE_D5, NOTE_AS4,
  NOTE_A4, NOTE_F4, NOTE_D4, NOTE_AS3,
  NOTE_A3, NOTE_F3, NOTE_D3, NOTE_AS2
};

int preludetempo[]
{
  16,16,16,16,
  16,16,16,16,
  16,16,16,16,
  16,16,16,16,

  16,16,16,16,
  16,16,16,16,
  16,16,16,16,
  16,16,16,16,

  16,16,16,16,
  16,16,16,16,
  16,16,16,16,
  16,16,16,16,

  16,16,16,16,
  16,16,16,16,
  16,16,16,16,
  16,16,16,16,

  16,16,16,16,
  16,16,16,16,
  16,16,16,16,
  16,16,16,16,

  16,16,16,16,
  16,16,16,16,
  16,16,16,16,
  16,16,16,16,

  16,16,16,16,
  16,16,16,16,
  16,16,16,16,
  16,16,16,16,

  16,16,16,16,
  16,16,16,16,
  16,16,16,16,
  16,16,16,16,

  16,16,16,16,
  16,16,16,16,
  16,16,16,16,
  16,16,16,16,

  16,16,16,16,
  16,16,16,16,
  16,16,16,16,
  16,16,16,16,

  16,16,16,16,
  16,16,16,16,
  16,16,16,16,
  16,16,16,16,

  16,16,16,16,
  16,16,16,16,
  16,16,16,16,
  16,16,16,16,

  16,16,16,16,
  16,16,16,16,
  16,16,16,16,
  16,16,16,16,

  16,16,16,16,
  16,16,16,16,
  16,16,16,16,
  16,16,16,16,

  16,16,16,16,
  16,16,16,16,
  16,16,16,16,
  16,16,16,16,

  16,16,16,16,
  16,16,16,16,
  16,16,16,16,
  16,16,16
};

int love[]
{
  NOTE_G5, NOTE_FS5, NOTE_E5, NOTE_C5,
  NOTE_G5, NOTE_FS5, NOTE_E5, NOTE_C5,
  NOTE_G5, NOTE_FS5, NOTE_D5, NOTE_B4,
  NOTE_G5, NOTE_FS5, NOTE_D5, NOTE_B4,

  NOTE_G5,  NOTE_A5, NOTE_G5,  NOTE_A5,
  NOTE_FS5, NOTE_A5, NOTE_G5,  NOTE_A5,
  NOTE_FS5, NOTE_A5, NOTE_FS5, NOTE_C6, 
  NOTE_C6,  NOTE_C6, NOTE_B5,  NOTE_B5
};

int lovetempo []
{
  16,16,16,16,
  16,16,16,16,
  16,16,16,16,
  16,16,16,16,

  16,16,16,16,
  16,16,16,16,
  16,16,16,16,
  16,16,16,16,
};

void setup()
{
  Serial.begin(9600);
  Serial.print("count = ");
  Serial.println(count);
  pinMode(buttonC  , INPUT_PULLUP);
  pinMode(buttonCS , INPUT_PULLUP);
  pinMode(buttonD  , INPUT_PULLUP);
  pinMode(buttonDS , INPUT_PULLUP);
  pinMode(buttonE  , INPUT_PULLUP);
  pinMode(buttonF  , INPUT_PULLUP);
  pinMode(buttonFS , INPUT_PULLUP);
  pinMode(buttonG  , INPUT_PULLUP);
  pinMode(buttonGS , INPUT_PULLUP);
  pinMode(buttonA  , INPUT_PULLUP);
  pinMode(buttonAS , INPUT_PULLUP);
  pinMode(buttonB  , INPUT_PULLUP);
  pinMode(buttonC2 , INPUT_PULLUP);
  pinMode(resetbutton , INPUT_PULLUP);
  pinMode(countbutton , INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(3), plus, LOW);
  attachInterrupt(digitalPinToInterrupt(2), reset, LOW);
  lcd.init();
  lcd.backlight();
  lcd.begin(20,4);
  lcd.clear();
  lcd.setCursor(0,0);
}

void loop()
{
  if (count == 1)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Flamingo");
    lcd.setCursor(0, 1);
    lcd.print("By: Kero Kero Bonito");
    flamingosong();
  }

  if (count == 2)
  {   
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Hall of Fame");
    lcd.setCursor(0, 1);
    lcd.print("By: The Script");
    famesong();
  }

  if (count == 3)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Prelude");
    lcd.setCursor(0, 1);
    lcd.print("From: FF7");
    preludesong();
  }

  if (count == 4)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Best Love Song");
    lcd.setCursor(0, 1);
    lcd.print("By: T-Pain");
    lovesong();
  }
  notes(); 
}

void plus()
{
  int reading = digitalRead(countbutton);

  if (reading == LOW && !pressed) // if button is pressed and was not pressed before
  {
    Serial.println(reading);
    count++;
    halt = true;
    Serial.print("count = ");
    Serial.println(count);

    pressed = true;
  }
  else if (reading == HIGH) {
    pressed = false;
  }
}

void reset()
{
  count = 0;
  halt = true;
  Serial.print("count = ");
  Serial.println(count);
}

void notes()
{
  while (digitalRead(buttonC) == LOW)
  {
    tone(buzzer, NOTE_C4);
    lcd.setCursor ( 0, 0 ); 
    lcd.print("C - 262 Hz");
  }
  while (digitalRead(buttonCS) == LOW)
  {
    tone(buzzer, NOTE_CS4);
    lcd.setCursor ( 0, 0 ); 
    lcd.print("C# - 277 Hz");
  }
  while (digitalRead(buttonD) == LOW)
  {
    tone(buzzer, NOTE_D4);
    lcd.setCursor ( 0, 0 ); 
    lcd.print("D - 294 Hz");
  }
  while (digitalRead(buttonDS) == LOW)
  {
    tone(buzzer, NOTE_DS4);
    lcd.setCursor ( 0, 0 ); 
    lcd.print("D# - 311 Hz");
  }
  while (digitalRead(buttonE) == LOW)
  {
    tone(buzzer, NOTE_E4);
    lcd.setCursor ( 0, 0 );
    lcd.print("E - 330 Hz");
  }
  while (digitalRead(buttonF) == LOW)
  {
    tone(buzzer, NOTE_F4);
    lcd.setCursor ( 0, 0 ); 
    lcd.print("F - 349 Hz");
  }
  while (digitalRead(buttonFS) == LOW)
  {
    tone(buzzer, NOTE_FS4);
    lcd.setCursor ( 0, 0 ); 
    lcd.print("F# - 370 Hz");
  }
  while (digitalRead(buttonG) == LOW)
  {
    tone(buzzer, NOTE_G4);
    lcd.setCursor ( 0, 0 ); 
    lcd.print("G - 392 Hz");
  }
  while (digitalRead(buttonGS) == LOW)
  {
    tone(buzzer, NOTE_GS4);
    lcd.setCursor ( 0, 0 ); 
    lcd.print("G# - 415 Hz");
  }
  while (digitalRead(buttonA) == LOW)
  {
    tone(buzzer, NOTE_A4);
    lcd.setCursor ( 0, 0 ); 
    lcd.print("A - 440 Hz");
  }
  while (digitalRead(buttonAS) == LOW)
  {
    tone(buzzer, NOTE_AS4);
    lcd.setCursor ( 0, 0 ); 
    lcd.print("A# - 466 Hz");
  }
  while (digitalRead(buttonB) == LOW)
  {
    tone(buzzer, NOTE_B4);
    lcd.setCursor ( 0, 0 ); 
    lcd.print("B - 494 Hz");
  }
  while (digitalRead(buttonC2) == LOW)
  {
    tone(buzzer, NOTE_C5);
    lcd.setCursor ( 0, 0 ); 
    lcd.print("C - 523 Hz");
  } 
  lcd.clear();
  noTone(buzzer);
}

void flamingosong()
{
  int size = sizeof(flamingo) / sizeof(int);
  for (int thisNote = 0; (thisNote < size && !halt); thisNote++)
  {
    int noteDuration = tempo[thisNote];

    tone(buzzer, flamingo[thisNote], noteDuration);

    int pauseBetweenNotes = noteDuration * 1;
    delay(pauseBetweenNotes);
  }
  halt = false;
}

void famesong()
{
  int size = sizeof(fame) / sizeof(int);
  for (int thisNote = 0; (thisNote < size && !halt); thisNote++)
  {
    int noteDuration = (60000 / fameBPM) / (32 / fametempo[thisNote]);

    tone(buzzer, fame[thisNote], noteDuration);

    int pauseBetweenNotes = noteDuration * 1;
    delay(pauseBetweenNotes);
  }
  halt = false;
}

void preludesong()
{
  int size = sizeof(prelude) / sizeof(int);
  for (int thisNote = 0; (thisNote < size && !halt); thisNote++)
  {
    int noteDuration = (60000 / preludeBPM) / (32 / preludetempo[thisNote]);

    tone(buzzer, prelude[thisNote], noteDuration);

    int pauseBetweenNotes = noteDuration * 1;
    delay(pauseBetweenNotes);
  }
  halt = false;
}

void lovesong()
{
  int size = sizeof(love) / sizeof(int);
  for (int thisNote = 0; (thisNote < size && !halt); thisNote++)
  {
    int noteDuration = (60000 / loveBPM) / (32 / lovetempo[thisNote]);

    tone(buzzer, love[thisNote], noteDuration);

    int pauseBetweenNotes = noteDuration * 1;
    delay(pauseBetweenNotes);
  }
  halt = false;
}

Schematics

Arduino Piano
Use whatever buzzer. My 20x4 LCD display has a adapter on the back. So plug in the 5V, ground, SDA, SCL from LCD to Arduino. Make sure to plug the SDA and SCL into the correct pins on the Arduino.
Arduino pic tnxturtose

Comments

Similar projects you might like

Electronic Piano Keyboard With Preset Songs

Project tutorial by Lindsay Fox

  • 90,738 views
  • 68 comments
  • 181 respects

Unravel Preset Piano Easy Arduino (Even a Ghoul Can Make It)

Project in progress by ExeCuteLi

  • 14,794 views
  • 12 comments
  • 32 respects

PIANO

Project tutorial by يمنى السيد ندا

  • 3,844 views
  • 0 comments
  • 1 respect

Arduino Tutorial : Mini Piano

Project tutorial by the lonely programmer

  • 19,380 views
  • 3 comments
  • 30 respects

Arduino + LEDs + MIDI Keyboard + MuseScore = Piano Tutor

Project tutorial by tcucinotta

  • 11,110 views
  • 3 comments
  • 21 respects

Piano Stairs

Project tutorial by Bonnie Eisenman

  • 8,894 views
  • 2 comments
  • 38 respects
Add projectSign up / Login