How to Make a Touch Capacitive Piano Using Arduino

Publisher:温暖的拥抱Latest update time:2023-06-06 Source: elecfansKeywords:Arduino Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

#include

#include "piano_tones.h"

#define common_pin 2 // Common "send" pin for all keys

#define Buzzer A4 // Output pin of piezoelectric buzzer

#define recordbtn 12 // Recording button

#define CPin(pin) CapacitiveSensor (common_pin, pin)


At the beginning of the “piano_pcb.ino” file, we have the “CapacitiveSensor.h” and “piano_tones.h” header files. I then defined three macros for the respective GPIO pins. “common_pin” is used to set “digital pin 2” to the “Send Pin”, “buzzer” is used to define analog pin 4 (A4), and “recordbtn” is used to slide the “button” into “digital pin 12”. I then created the “CPin (pin)” macro so that we don’t need to pass the send pin (which is common_pin) and the receive pin (which is the pin of the individual resistors) multiple times in the CapacitiveSensor(common_pin,pin).



Integer comment[]={NOTE_C7, NOTE_D7, NOTE_E7, NOTE_F7, NOTE_G7, NOTE_A7, NOTE_B7, NOTE_C8};

//Startup sound

int soundOnStartUp[] = {

Attention_E7, Attention_E7, 0, Attention_E7,

0, Attention_C7, Attention_E7, 0,

NOTE_G7, 0, 0, 0,

NOTE_G6, 0, 0, 0 };

capacitivesensorkeys[] = {CPin(3), CPin(4), CPin(5), CPin(6), CPin(7), CPin(8), CPin(9), CPin(10)};


After calling the library and defining some macros, we need to create 3 arrays as mentioned above. These are notes[], soundOnStartUp[] and keys[]. The "notes[]" array stores the notes that correspond to the piano in a certain scale (e.g. NOTE_C7, NOTE_D7, etc.). You can change the scale by uncommenting the other "notes[]" that I have provided in the code. The soundOnStartUp[] array is used to store some tunes that I use during the startup of the piano. This array has been called in the setup() function. The capacitive sensor keys[] array is used to store the corresponding receiving pins, using the CPin() function that we defined earlier.



void recordButton(){

// Set the sensor's sensitivity.

long touch1 = keys[0].capacitiveSensor(sensitivity);

long touch2 = keys[1].capacitiveSensor(sensitivity);

long touch3 = keys[2].capacitiveSensor(sensitivity);

long touch4 = keys[3].capacitiveSensor(sensitivity);

long touch5 = keys[4].capacitiveSensor(sensitivity);

long touch6 = keys[5].capacitiveSensor(sensitivity);

long touch7 = keys[6].capacitiveSensor(sensitivity);

long touch8 = keys[7].capacitiveSensor(sensitivity);

pev_button = button;

// When we touch the sensor, the button will record the corresponding number.

if (touch1 > sensitivity)

button = 1;

if (touch2 > sensitivity)

button = 2;

if (touch3 > sensitivity)

button = 3;

if (touch4 > sensitivity)

button = 4;

if (touch5 > sensitivity)

button = 5;

if (touch6 > sensitivity)

button = 6;

if (touch7 > sensitivity)

button = 7;

if (touch8 > sensitivity)

button = 8;

// When we don't touch it, no tone is produced.

if (touch1<=sensitivity& touch2<=sensitivity& touch3<=sensitivity& touch4<=sensitivity& touch5<=sensitivity& touch6<=sensitivity& touch7<=sensitivity& touch8<=sensitivity)

button = 0;

/****Record the pressed buttons in an array***/

if (button != pev_button && pev_button != 0)

{

record button[button_index] = pev_button;

buttonIndex++;

recordButton[buttonIndex] = 0;

buttonIndex++;

}

/**Recording process ends**/

}


We read the capacitance value of each key using the "keys[0].capacitiveSensor(sensitivity)" function and compare it to some specified value to determine which key was pressed in the recordButtons() function above. We also keep track of the order in which the buttons were pressed in this function. The recorded values ​​are saved in the recorded buttons[] array. We first check to see if a new key was pressed, and if so, we check again that it is not button 0. But no button was pressed, so button 0 has nothing. We save the value at the index specified by the variable button_index inside the if loop, and then we increment that index value to avoid overwriting the same location.



void playTone() {

/****Time delay between each button press in the Rcord array***/

if (button != pev_button)

{

note_time = (millis() - start_time) / 10;

if (note time != 0) {

note_time[time_index] = note_time;

time_index++;

startTime = milliseconds();

}

Serial.println(time_index);

}

/**Recording process ends**/

if (button == 0)

{

noTone(buzzer);

}

if (button == 1)

{

tone(buzzer, notes[0]);

}

if (button == 2)

{

tone(buzzer, note[1]);

}

if (button == 3)

{

tone(buzzer, note[2]);

}

if (button == 4)

{

tone(buzzer, note[3]);

}

if (button == 5)

{

tone(buzzer, note[4]);

}

if (button == 6)

{

tone(buzzer, note[5]);

}

if (button == 7)

{

tone(buzzer, note[6]);

}

if (button == 8)

{

tone(buzzer, note[7]);

}

}


Using various if conditions, we will play the appropriate tone for the key presses in the playTone() function. The full code for this function is shown above. We will also use an array called recorded time[] to hold the length of time the buttons were pressed. The process is similar to recording a sequence of buttons in that we use the millis() function to calculate how long each button was pressed and then divide that value by 10 to reduce the size of the variable. We do not play any tone during the same time period for button 0, which indicates that the user did not press anything.



void setup() {

SerialNumber.Start(9600);

// Turn off autocalibration for all channels:

for(int i=0; i<8; ++i) {

Key[i].set_CS_AutocaL_Millis(0xFFFFFFFF);

}

// Set the buzzer as an output:

pinMode(buzzer, OUTPUT);

pinMode(recordbtn,input);

noTone(buzzer);

delay(10);

int sizeed = sizeof(soundOnStartUp) / sizeof(int);

for (int thisNote = sizeed; thisNote > 0 ; thisNote--) {

sound(buzzer, soundOnStartUp[thisNote]);

delay(100);

}

noTone(buzzer);

delay(10);

}


There are two for loops in the setup() function. In the first loop, I set the keys using "keys[i].set_CS_AutocaL_Millis(0xFFFFFFFF)". The second for loop is used to play the soundOnStartUp[] note by using tone(buzzer, soundOnStartUp[thisNote]).



void loop(){

Serial.println(digitalRead(recordbtn));

while (digitalRead(recordbtn) == 1) //If the toggle switch is set to recording mode

{

recordButton();

playSound();

}

while (digitalRead(recordbtn) == 0) //If the toggle switch is set to play mode

{

for (int i = 0; i < sizeof(recorded_button) / 2; i++)

{

delay((recordtime[i])*10); //wait for next song to be paid

if (recorded_button[i] == 0)

noTone(buzzer); //user did not touch any button

Other

sound(buzzer, note[(recorded_button[i] - 1)]); //play the sound corresponding to the button touched by the user

}

}

}


Then, to play the recorded tone, the user must push the slide switch to the other direction after recording. Once this is done, the program exits the previous while loop and enters the second while loop where we play the notes of the previously recorded length in the order in which the keys were hit. The code to accomplish this is provided above. You can watch the video attached below for more explanation.


Code


#include


#include "piano_tones.h"


#define common_pin 2 // Common "send" pin for all resistors


#define buzzer A4 // Output pin of piezoelectric buzzer


#define recordbtn 12 // Recording button


// This macro creates a capacitive sensor object for each resistor pin


#define CPin(pin) CapacitiveSensor(common_pin, pin)


char button = 0;


integer analog value;


char REC = 0;


int record button[200];


int pev_button;


int sensitivity = 2000;


int record time [200];


Character time index;


characterButtonIndex = 0;


unsigned long startTime;


int note_time;


// Each key corresponds to a note, defined here. Uncomment the scale you want to use:


//int notes[]={NOTE_C4, NOTE_D4, NOTE_E4, NOTE_F4, NOTE_G4, NOTE_A4, NOTE_B4, NOTE_C5}; // C major scale


//int notes[]={NOTE_A4,NOTE_B4,NOTE_C5,NOTE_D5,NOTE_E5,NOTE_F5,NOTE_G5,NOTE_A5}; // A-minor scale


//int notes[]={NOTE_C4, NOTE_D4, NOTE_E4, NOTE_F4, NOTE_G4, NOTE_A4, NOTE_C5, NOTE_D5}; // C blues scale


//int notes[] = {1300, 1500, 1700, 1900, 2000, 2300, 2600, 2700};


Integer comment[]={NOTE_C7, NOTE_D7, NOTE_E7, NOTE_F7, NOTE_G7, NOTE_A7, NOTE_B7, NOTE_C8};


//int notes[] = {1915, 1700, 1519, 1432, 1275, 1136, 1014, 956};


// Start the sound


int soundOnStartUp[] = {


NOTE_E7, NOTE_E7, 0, NOTE_E7,


0, NOTE_C7, NOTE_E7, 0,


Note_G7, 0, 0, 0,


Note_G6, 0, 0, 0


};


// Define the pins to which the registers are connected:


CapacitiveSensor keys[] = {CPin(3), CPin(4), CPin(5), CPin(6), CPin(7), CPin(8), CPin(9), CPin(10)};


void setup() {


Serial.begin(9600);


// Turn off autocalibration for all channels:


for (int i = 0; i < 8; ++i) {


keys[i].set_CS_AutocaL_Millis(0xFFFFFFFF);


}


// Set the buzzer as output:


pinMode(buzzer, OUTPUT);


pinMode(recordbtn,input);


noTone(buzzer);


delay(10);


int sizeed = sizeof(soundOnStartUp)/sizeof(int);


for (int thisNote = sizeed; thisNote 〉 0 ; thisNote--) {


tone(buzzer, soundOnStartUp[thisNote]);


delay(100);


}


noTone(buzzer);


delay(10);


}


void loop() {


Serial.println(digitalRead(recordbtn));


while (digitalRead(recordbtn) == 1) //If the toggle switch is set to recording mode


{


recordButtons();


playSound();


}


while (digitalRead(recordbtn) == 0) //If the toggle switch is set to play mode


{


for (int i = 0; i < sizeof(recorded_button) / 2; i++)

[1] [2] [3]
Keywords:Arduino Reference address:How to Make a Touch Capacitive Piano Using Arduino

Previous article:How to Build a Gesture-Controlled Raspberry Pi Media Player
Next article:How to Build a Portable Humidifier Using Arduino

Latest Embedded Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号