• Arduino Powered Player Pianos and Player Xylophones

QC

Arduino Powered Player Pianos and Player Xylophones

Code your favorite music and play it on a Casio keyboard or one of the two xylophones described in the project.

Devices and components

Arduino Mega 2560 Rev3

Materials and tools

Soldering iron (generic)

Project description

Casio Player piano and xylophones powered by Arduino

Introduction

The projects

Why build these projects?

Abilities

Overview of Xylophone projects

Xylophones

Choosing a xylophone

Build the Cool Xylo

Mounting the solenoids

Mounting the solenoid bars

The Jig

Wiring the control box

The design of the universal shield

Build a Universal Shield on a Prototype Board

Soldering Tips

Installing Components

List of components and where to buy them

Component Wiring

Various circuit diagrams

The control panel and its circuits

Building the 51-key Casio Player piano

Mounting the solenoids

Selection of solenoids

JF-0730 solenoid noise problem

Noise reduction techniques

A template for slicing polystyrene pads

The solenoid foot

Measuring the Noise from the Solenoid Driven Keys

Various circuits

Control panel circuits.

Player Piano Circuits

Sheet music and musical symbols

Background

Sheet music and musical symbols

Measures

Ledger lines

Cleffs

The rhythm, tempo or rhythm of music

3/4 Time

Notes and silences

The accidentals

Notes with a period

Notes transmitted

Links and insults

Song dynamics

Chords

Metronome mark

Hold symbol

Other symbols

Arduino IDE and music sketches

The Arduino family of computers

Arduino Computers

Arduino Shields

The Mega 2560

The Arduino IDE

//The sketch Blink

void setup() // the setup function runs once

{

pinMode(13, OUTPUT); //initialize digital pin 13 as an output

}

void loop() // the loop function runs over and over again

{

digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)

delay(1000); // wait for a second

digitalWrite(13, LOW); // turn the LED off by making the voltage LOW

delay(1000); // wait for a second

}

// Scales and “Twinkle, Twinkle, Little Star”

#define SOLPIN_1 27 // “G”. Output port 27 will activate key G

#define SOLPIN_2 28 // “A”

#define SOLPIN_3 29 // “B”

#define SOLPIN_4 30 // “C” Output port 30 will activate Middle C

#define SOLPIN_5 31 // “D”

#define SOLPIN_6 32 // “E”

#define SOLPIN_7 33 // “F”

#define SOLPIN_8 34 // “G”

#define SOLPIN_9 35 // “A”

#define SOLPIN_1036 // “B”

#define SOLPIN_1137 // “C”

#define SOLPIN_1238 // “D”

#define SOLPIN_1339 // “E”

#define SOLPIN_1440 // “F”

#define SOLPIN_1541 // “G”

#define SOLPIN_1642 // “A”

#define SOLPIN_1743 // “B”

#define SOLPIN_1844 // “C”. Output port 44 will activate key C

#defineSOLTIME_DURATION_A 15 //solenoid pulse duration

#defineSOLTIME_DURATION_B 500 //quarter note duration

#defineSOLTIME_DURATION_C 1000 //half note duration

#defineSOLTIME_DURATION_D 2000 // full note duration

#defineSOLTIME_DURATION_S 500 // quarter note duration (scales}

void setup() // The setup function runs once when

{ // press reset or power the board,

pinMode(SOLPIN_1, OUTPUT); // initializes the output ports

pinMode(SOLPIN_2, OUTPUT);

pinMode(SOLPIN_3, OUTPUT);

pinMode(SOLPIN_4, OUTPUT);

pinMode(SOLPIN_5, OUTPUT);

pinMode(SOLPIN_6, OUTPUT);

pinMode(SOLPIN_7, OUTPUT);

pinMode(SOLPIN_8, OUTPUT);

pinMode(SOLPIN_9, OUTPUT);

pinMode(SOLPIN_10, OUTPUT);

pinMode(SOLPIN_11, OUTPUT);

pinMode(SOLPIN_12, OUTPUT);

pinMode(SOLPIN_13, OUTPUT);

pinMode(SOLPIN_14, OUTPUT);

pinMode(SOLPIN_15, OUTPUT);

pinMode(SOLPIN_16, OUTPUT);

pinMode(SOLPIN_17, OUTPUT);

pinMode(SOLPIN_18, OUTPUT);

}

void loop()

{ //the loop function runs over and over

// plays the 18 notescales

digitalWrite(SOLPIN_1, HIGH); //turn solenoid 27 on ("G")

delay(SOLTIME_DURATION_A); //wait for the delay period A

digitalWrite(SOLPIN_1, LOW); //turn the solenoid off

delay(SOLTIME_DURATION_S); //wait for the delay period S

digitalWrite(SOLPIN_2, HIGH); //Activate the next solenoid

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_2, LOW);

delay(SOLTIME_DURATION_S);

digitalWrite(SOLPIN_3, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_3, LOW);

delay(SOLTIME_DURATION_S);

digitalWrite(SOLPIN_4, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_4, LOW);

delay(SOLTIME_DURATION_S);

digitalWrite(SOLPIN_5, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_5, LOW);

delay(SOLTIME_DURATION_S);

digitalWrite(SOLPIN_6, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_6, LOW);

delay(SOLTIME_DURATION_S);

digitalWrite(SOLPIN_7, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_7, LOW);

delay(SOLTIME_DURATION_S);

digitalWrite(SOLPIN_8, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_8, LOW);

delay(SOLTIME_DURATION_S);

digitalWrite(SOLPIN_9, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_9, LOW);

delay(SOLTIME_DURATION_S);

digitalWrite(SOLPIN_10, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_10, LOW);

delay(SOLTIME_DURATION_S);

digitalWrite(SOLPIN_11, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_11, LOW);

delay(SOLTIME_DURATION_S);

digitalWrite(SOLPIN_12, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_12, LOW);

delay(SOLTIME_DURATION_S);

digitalWrite(SOLPIN_13, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_13, LOW);

delay(SOLTIME_DURATION_S);

digitalWrite(SOLPIN_14, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_14, LOW);

delay(SOLTIME_DURATION_S);

digitalWrite(SOLPIN_15, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_15, LOW);

delay(SOLTIME_DURATION_S);

digitalWrite(SOLPIN_16, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_16, LOW);

delay(SOLTIME_DURATION_S);

digitalWrite(SOLPIN_17, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_17, LOW);

delay(SOLTIME_DURATION_S);

digitalWrite(SOLPIN_18, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_18, LOW);

delay(SOLTIME_DURATION_S); //end of playing the 18 note Scales

delay (2000);

//Start coding "Twinkle Twinkle Little Star'

digitalWrite(SOLPIN_4, HIGH); //turn on solenoid 4

delay(SOLTIME_DURATION_A); //wait for delay period A

digitalWrite(SOLPIN_4, LOW); //turn off solenoid 4

delay(SOLTIME_DURATION_B); //wait for delay period B

digitalWrite(SOLPIN_4, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_4, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_8, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_8, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_8, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_8, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_9, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_9, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_9, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_9, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_8, HIGH); //turn the solenoid on

delay(SOLTIME_DURATION_A); //wait for the delay period

digitalWrite(SOLPIN_8, LOW); //turn the solenoid off

delay(SOLTIME_DURATION_C); //wait for the delay period

digitalWrite(SOLPIN_7, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_7, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_7, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_7, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_6, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_6, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_6, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_6, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_5, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_5, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_5, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_5, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_4, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_4, LOW);

delay(SOLTIME_DURATION_C);

digitalWrite(SOLPIN_8, HIGH); //turn the solenoid on

delay(SOLTIME_DURATION_A); //wait for the delay period

digitalWrite(SOLPIN_8, LOW); //turn the solenoid off

delay(SOLTIME_DURATION_B); //wait for the delay period

digitalWrite(SOLPIN_8, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_8, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_7, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_7, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_7, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_7, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_6, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_6, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_6, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_6, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_5, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_5, LOW);

delay(SOLTIME_DURATION_C);

digitalWrite(SOLPIN_8, HIGH); //turn the solenoid on

delay(SOLTIME_DURATION_A); //wait for the delay period

digitalWrite(SOLPIN_8, LOW); //turn the solenoid off

delay(SOLTIME_DURATION_B); //wait for the delay period

digitalWrite(SOLPIN_8, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_8, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_7, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_7, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_7, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_7, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_6, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_6, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_6, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_6, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_5, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_5, LOW);

delay(SOLTIME_DURATION_C);

digitalWrite(SOLPIN_4, HIGH); //turn the solenoid on

delay(SOLTIME_DURATION_A); //wait for the delay period

digitalWrite(SOLPIN_4, LOW); //turn the solenoid off

delay(SOLTIME_DURATION_B); //wait for the delay period

digitalWrite(SOLPIN_4, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_4, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_8, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_8, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_8, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_8, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_9, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_9, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_9, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_9, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_8, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_8, LOW);

delay(SOLTIME_DURATION_C);

digitalWrite(SOLPIN_7, HIGH); //turn the solenoid on

delay(SOLTIME_DURATION_A); //wait for the delay period

digitalWrite(SOLPIN_7, LOW); //turn the solenoid off

delay(SOLTIME_DURATION_B); //wait for the delay period

digitalWrite(SOLPIN_7, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_7, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_6, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_6, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_6, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_6, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_5, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_5, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_5, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_5, LOW);

delay(SOLTIME_DURATION_B);

digitalWrite(SOLPIN_4, HIGH);

delay(SOLTIME_DURATION_A);

digitalWrite(SOLPIN_4, LOW);

delay(SOLTIME_DURATION_C);

delay (2000);

}

The scales and “Twinkle, Twinkle Little Star”

We only code the 18 “white” keys. If accidentals were to be played, we would expand the "#define" list and assign port numbers to them.

The #defines for SOLPIN 1 through 18 display the port number and key name (G through C). Note that the middle C is port 30 for the xylophones.

We only\t“#define” a single delay for the strike time (SOLTIME_DURATION_A 15). We could have “#define” other delays say, 10ms or 20ms to make the key sound softer or louder.

Only three of the delays that determine the duration of the note are “#define”. The other two eighth notes and sixteenth notes would be defined if they were to be played in the song. Download the code above into your Mega xylophone control box and the music will be played on either xylophone.

Chords

Robo-C Sketch Intro Code

Song Beat

#define BEAT_60 999 //Number of ms for various beats

#define BEAT_70 857 // according to the metronome's "beats per minute”

#define BEAT_80 750

#define BEAT_90 666

#define BEAT_100 600

#define BEAT_110 550

#define BEAT_120 500

#define BEAT_130 467

#define BEAT_140 433

#define BEAT_150 400

#define BEAT_160 375

#define BEAT_170 352

#define BEAT_180 333

#define BEAT_300 200 //Used for very short “Blip” notes

Note duration

#define DURATION_FULL 1 //Defines the multiplier needed

#define DURATION_HALF 2 // to determine the length of the note

#define DURATION_QUARTER 3

#define DURATION_EIGHTH 4

#define DURATION_SIXTEENTH 5

Solenoid Activation

#define SOLTIME_A 4 //Solenoid is energized for 100% of the note's duration

#define SOLTIME_B 3 //Solenoid is energized for 75% of the note's duration

#define SOLTIME_C 2 //Solenoid is energized for 50% of the note's duration

#define SOLTIME_D 1 //Solenoid is energized for 25% of the note's duration

Enabling Sustain and Low Volume features

#define SUSTAIN_ON 1

#define SUSTAIN_OFF 2

#define VOLUME_LOW 1

#define VOLUME_FULL 2

Activating Chord Software

#define CHORD_START1

#define

#define CHORD_END 3

Define keys and ports

#define WHITE_KEY 0

#define BLACK_KEY 1

#define

#define

#define

#define

#define SONG_END255

static int beatMult[] = {0, 16, 8, 4, 2, 1}

Structuring the note

struct myNote

{

byte Port;

byte blackStateP5: 1;

byte blackStateP6: 1;

byte blackStateP7: 1;

byte blackStateP8: 1;

byte blackStateP9: 1;

int Beat;

byte Sustain : 2;

byte Volume : 2;

byte Duration: 4;

byte Soltime: 4;

byte Chord : 4;

byte BlackKey : 4;

} Note;

struct myNoteElise[] = {

“Elise Fur” coding

CHORD_START is abbreviated as: C_S

CHORD_CONTINUE is abbreviated as: C_C

CHORD_END is abbreviated as: C_E

The two lines of code for measure 1 look like this.

//Measure 1

{45, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

{15, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

//Measure 2

{45, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

{15, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

{45, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

{42, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

{44, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

{43, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

//Measure 3

{41, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_A, C_S, WHITE_KEY },

{27, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_A, C_E, WHITE_KEY },

{41, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, C_S, WHITE_KEY },

{31, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, C_E, WHITE_KEY },

{34, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

{36, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

{38, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

{41, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

//Measure 4

{42, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_A, C_S, WHITE_KEY },

{24, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_A, C_E, WHITE_KEY },

{42, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, C_S WHITE_KEY },

{31, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, C_E, WHITE_KEY },

{7, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

{38, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

{12, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

{42, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

//Measure 5

{43, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_A, C_S, WHITE_KEY },

{27, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_A, C_E, WHITE_KEY },

{43, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, C_S, WHITE_KEY },

{31, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, C_E, WHITE_KEY },

{34, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

{38, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

{45, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

{15, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, BLACK_KEY },

//Measure 6

{45, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

{15, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

{45, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

{42, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

{44, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

{43, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

//Measure 7

{41, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_A, C_S, WHITE_KEY },

{27, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_A, C_E, WHITE_KEY },

{41, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, C_S WHITE_KEY },

{31, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, C_E, WHITE_KEY },

{34, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

{36, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

{38, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

{41, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

//Measure 9

{41, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_A, C_S, WHITE_KEY },

{27, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_A, C_E, WHITE_KEY },

{41, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_A, C_S, WHITE_KEY },

{31, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_A, C_E, WHITE_KEY },

{41, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_A, C_S, WHITE_KEY },

{34, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_A, C_E, WHITE_KEY },

{41, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

{45, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

{15, 0, 0, 0, 0, 0, BEAT_110, 0, 0, DURATION_EIGHTH, SOLTIME_B, 0, WHITE_KEY },

The Robo-C code

{SONG_END, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, WHITE_KEY},

};

struct myNote * pSong = Elise;

voidsetup() //the setup routine runs once when Reset,

//the digital pins are initialized as outputs

{

pSong= Elise;

inti = START_BLACK_KEY; //Reset ports 0 to 19

while(i<= END_BLACK_KEY) {

pinMode(i, OUTPUT);

digitalWrite(i, LOW);

i++;

}

i= START_WHITE_KEY; //Reset ports 22 to 53

while(i<= END_WHITE_KEY) {

pinMode(i, OUTPUT);

digitalWrite(i, LOW);

i++;

}

{

pinMode(20, OUTPUT); //Set up the ports to activate

pinMode(21, OUTPUT); // the sustain and volume relays

}

}

voidplayTune(struct myNote * pTune) {

bytePort1 = pTune->Port; // Select a Port

intSoltime= pTune->Soltime; // Select one of 4 setting for the solenoids

if(Port1== SONG_END) { // End the song when Port 255 is detected

pSong= pTune;

return;

}

if(pTune->Sustain== 1) { // Turns on the sustain feature on Port 20

digitalWrite(20, HIGH);

}

if(pTune->Sustain== 0) { //Turns off the sustain feature on Port 20

digitalWrite(20, LOW);

}

if(pTune->Volume== 1) { // Turns the volume feature to low on Port 21

digitalWrite(21, HIGH);

}

if(pTune->Volume== 0) { //Turns the volume feature to full on Port 21

digitalWrite(21, LOW);

}

intbeat = pTune->Beat ; // Establishes the beat time of the song

beat= beat * beatMult[pTune->Duration]/4; // Establishes the duration

// of the 5 notes from full to

// one sixteenth based on the beat

intdurMS = beat * Soltime/4 ; // Establishes the duration that

// the solenoids are energized:

//.25,.50,.75, 1.0 of beat time

if(pTune->BlackKey== HIGH) {

digitalWrite(5, pTune->blackStateP5);

digitalWrite(6, pTune->blackStateP6);

digitalWrite(7, pTune->blackStateP7);

digitalWrite(8, pTune->blackStateP8);

digitalWrite(9, pTune->blackStateP9);

}else {

if(Port1){

digitalWrite(Port1, HIGH); // Execute command HIGH for the designated note

} // Energize the solenoids for time duration durMs

structmyNote * pChordTune = pTune;

if((pChordTune->Chord== CHORD_START) || (pChordTune->Chord == CHORD_CONTINUE)) {

pChordTune++; // Combine individual notes into chords

playTune(pChordTune);

}

if((pTune->Chord== CHORD_END) || (pTune->Chord == 0)) {

delay(durMS); //Determines the length of time that the

} //solenoid is energized. One delay per chord

if(pTune->BlackKey== HIGH) { //Turn off the black keys (ports 0 to 19)

inti = START_BLACK_KEY; //after the end of the durMS delay

while(i<= END_BLACK_KEY) {

pinMode(i, OUTPUT);

digitalWrite(i, LOW);

i++;

}

}else{

inti = START_BLACK_KEY;

while(i<= END_BLACK_KEY) {

pinMode(i, OUTPUT);

digitalWrite(i, LOW);

i++;

}

i= START_WHITE_KEY; //Turn off the white keys (ports 22 to 53)

while(i<= END_WHITE_KEY) { // after the end of the durMS delay

pinMode(i, OUTPUT);

digitalWrite(i, LOW);

i++;

}

}

//Now wait out the beat time (Duration of the note)

if((pTune->Chord == CHORD_END) || (pTune->Chord == 0)) {

pTune++;

pSong= pTune;

delay(beat-durMS); //After the completion of the note or chord,

//select the next note

//Serial.begin(9600); //Activate the Serial Monitor (commented out)

//intn = (beat-durMS);

//Serial.println(n) ;

}

}

voidloop() // the loop routine runs over and over

{

\tif(pSong->Port== SONG_END) {

\t\tpSong= Elise;

\t\tdelay(2000);

\t}

playTune(pSong);

}

Robo-C

This is the code that controls the player piano

1{SONG_END, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, WHITE_KEY},
2 };
3 //This the end of the coding of the scales and of the song. We will now generate the first note as explained in the comments.
4
5 struct myNote * pSong = Elise;
6 void setup() //the setup routine runs once when the reset switch is pressed
7 // the digital pins are initialized as outputs
8 {
9 pSong = Elise;
10
11 int i = START_BLACK_KEY; //Reset ports 0 to 19
12 while(i <= END_BLACK_KEY) {
13 pinMode(i, OUTPUT);
14 digitalWrite(i, LOW);
15 i++;
16 }
17 i = START_WHITE_KEY; //Reset ports 22 to 53
18 while(i <= END_WHITE_KEY) {
19 pinMode(i, OUTPUT);
20 digitalWrite(i, LOW);
21 i++;
22 }
23 {
24 pinMode(20, OUTPUT); //Set up the ports to activate the sustain and volume relays
25 pinMode(21, OUTPUT);
26 }
27 }
28 void playTune(struct myNote * pTune) {
29 byte Port1 = pTune->Port; // Select a Port
30 int Soltime= pTune->Soltime; // Select one of 4 setting for the solenoids
31 if(Port1 == SONG_END) { // End the song when Port 255 is detected
32 pSong = pTune;
33 return;
34 }
35 if(pTune->Sustain == 1) { // Turns on the sustain feature on Port 20
36 digitalWrite(20, HIGH);
37 }
38 if(pTune->Sustain == 0) { //Turns off the sustain feature on Port 20
39 digitalWrite(20, LOW);
40 }
41 if(pTune->Volume == 1) { // Turns the volume feature to low on Port 21
42 digitalWrite(21, HIGH);
43 }
44 if(pTune->Volume == 0) { //Turns the volume feature to full on Port 21
45 digitalWrite(21, LOW);
46 }
47 int beat = pTune->Beat ; // Establishes the beat time of the song (millisecs)
48 beat = beat * beatMult[pTune->Duration]/4; // Establishes the duration of the 5 notes
49 // from Full to one Sixteenth based on the beat (millisecs)
50 int durMS = beat * Soltime/4 ; // Establishes the amount of time that the solenoids
51 // are energized .25,.50,.75 or 1.0 of the beat time (millisecs)
52 if(pTune->BlackKey == HIGH) { // the black keys are driven directly from a Mega port in this version
53 digitalWrite(5, pTune->blackStateP5); // of Robo-C. These 7 lines of code are not used.
54 digitalWrite(6, pTune->blackStateP6);
55 digitalWrite(7, pTune->blackStateP7);
56 digitalWrite(8, pTune->blackStateP8);
57 digitalWrite(9, pTune->blackStateP9);
58 } else {
59 if(Port1) {
60 digitalWrite(Port1, HIGH); // Execute command HIGH for the designated white or black note
61 } // Energize the solenoids for time duration durMs
62 }
63 struct myNote * pChordTune = pTune;
64
65 if((pChordTune->Chord == CHORD_START) || (pChordTune->Chord == CHORD_CONTINUE)) {
66 pChordTune++; // Combine individual notes into chords
67 playTune(pChordTune);
68 }
69 if((pTune->Chord == CHORD_END) || (pTune->Chord == 0)) {
70 delay (durMS); // Determines the length of time that the
71 } // Solenoid is energized. One delay per chord
72
73 if(pTune->BlackKey == HIGH) { //Turn off the black keys (ports 0 to 19) after the end of the durMS delay
74 int i = START_BLACK_KEY;
75 while(i <= END_BLACK_KEY) {
76 pinMode(i, OUTPUT);
77 digitalWrite(i, LOW);
78 i++;
79 }
80 }else {
81 int i = START_BLACK_KEY;
82 while(i <= END_BLACK_KEY) {
83 pinMode(i, OUTPUT);
84 digitalWrite(i, LOW);
85 i++;
86 }
87 i = START_WHITE_KEY; //Turn off the white keys (ports 22 to 53) after the end of the durMS delay
88 while(i <= END_WHITE_KEY) {
89 pinMode(i, OUTPUT);
90 digitalWrite(i, LOW);
91 i++;
92 }
93 }
94 // Now wait out the beat time (the duration of the note)
95 if((pTune->Chord == CHORD_END) || (pTune->Chord == 0)) {
96 pTune++;
97 pSong = pTune;
98 delay (beat-durMS); //After the completion of the note or chord, select the next note
99
100 //Serial.begin(9600); // Activate the Serial Monitor (commented out unless needed)
101 //int n = (beat-durMS);
102 //Serial.println (n) ;
103 }
104 }
105 void loop() // the loop routine runs over and over
106 {
107 if(pSong->Port == SONG_END) {
108 pSong = Elise;
109 delay(2000);
110 }
111 playTune(pSong);
112 }
113

Downloadable files

Control panel diagrams

Overview

Control panel diagrams

Universal Shield Wiring Diagram

Arduino Shield Point-to-Point Wiring Overview

Universal Shield Wiring Diagram

Circuit diagram

Overview of the control panel and its circuits

Circuit diagram

Control panel diagrams

Overview

Control panel diagrams

Universal Shield Wiring Diagram

Arduino Shield Point-to-Point Wiring Overview

Universal Shield Wiring Diagram

Circuit diagram

Overview of the control panel and its circuits

Circuit diagram




Note: Content and images are from: https://projecthub.arduino.cc/, with some modifications.
If you want it removed due to copyright reasons, please leave a comment. Thank you.
I want to share this article more widely so that everyone knows about Arduino and your project.

SendData

Điều khiển trạng thái qua Firebase Trạng thái hiện tại: Đang tải... ĐỔI TRẠNG THÁI