1

I am new to Arduino.

My project is an electronic piano that has 8 tactile switch keys that can play 8 octaves. I want to record a song that a user plays on the keys into EEPROM. I have implemented it. However, the playback is bad. You can't hear different note frequencies but you can hear soft buzzing when a note is supposed to be played.

Here is my code. Could you please help me find the problem? Thank you in advance.

#include <EEPROM.h> 
#include "pitches.h"
#define speaker A5
#define record_button 3
#define play_button 5
#define record_led 2
#define play_led 4

int eeAddress = 0;
int eeAddressplay = 0;
const int inPot = A1; // potentiometer to change octaves (8 octaves total)
byte octave; 
byte tone_out; 
int tone_key; // frequency of key
boolean silence; 
int maxNumber = 500;
byte time = 20; 
byte check = 0;
byte buttons[] = {6,7,8,9,10,11,12,13};
int saveSounds[500];
int saveNumber = 0;

byte melody1[8] = { 
  NOTE_C1 , NOTE_D1, NOTE_E1, NOTE_F1, NOTE_G1, NOTE_A1, NOTE_B1, NOTE_C2};
byte melody2[8] = { 
  NOTE_C2 , NOTE_D2, NOTE_E2, NOTE_F2, NOTE_G2, NOTE_A2, NOTE_B2, NOTE_C3};
int melody3[8] = { 
  NOTE_C3 , NOTE_D3, NOTE_E3, NOTE_F3, NOTE_G3, NOTE_A3, NOTE_B3, NOTE_C4};
int melody4[8] = { 
  NOTE_C4 , NOTE_D4, NOTE_E4, NOTE_F4, NOTE_G4, NOTE_A4, NOTE_B4, NOTE_C5};
int melody5[8] = { 
  NOTE_C5 , NOTE_D5, NOTE_E5, NOTE_F5, NOTE_G5, NOTE_A5, NOTE_B5, NOTE_C6};
int melody6[8] = { 
  NOTE_C6 , NOTE_D6, NOTE_E6, NOTE_F6, NOTE_G6, NOTE_A6, NOTE_B6, NOTE_C7};
int melody7[8] = { 
  NOTE_C7 , NOTE_D7, NOTE_E7, NOTE_F7, NOTE_G7, NOTE_A7, NOTE_B7, NOTE_C8};

//PIANO FUNCTION
void freePlay()
{
  octave = map(analogRead(inPot),0,1023,1,7);                        
  if (digitalRead(buttons[0]) == HIGH) {      
    tone_out = 0;                            
    silence = false;                        
  } 
  else if (digitalRead(buttons[1]) == HIGH) {
    tone_out = 1;  
    silence = false;
  } 
  else if (digitalRead(buttons[2]) == HIGH) {
    tone_out = 2; 
    silence = false;
  } 
  else if (digitalRead(buttons[3]) == HIGH) {
    tone_out = 3;  
    silence = false;
  } 
  else if (digitalRead(buttons[4]) == HIGH) {
    tone_out = 4;  
    silence = false;
  } 
  else if (digitalRead(buttons[5]) == HIGH) {
    tone_out = 5; 
    silence = false;
  } 
  else if (digitalRead(buttons[6]) == HIGH) {
    tone_out = 6; 
    silence = false;
  } 
  else if (digitalRead(buttons[7]) == HIGH) {
    tone_out = 7;
    silence = false;
  } 
  else {
    silence = true;         
  }

  if (silence == false)
  {
    switch(octave) 
    {
    case 1: 
      tone_key = melody1[tone_out]; break;
    case 2: 
      tone_key = melody2[tone_out]; break;
    case 3: 
      tone_key = melody3[tone_out]; break;
    case 4: 
      tone_key = melody4[tone_out]; break;
    case 5: 
      tone_key = melody5[tone_out]; break;
    case 6: 
      tone_key = melody6[tone_out]; break;
    case 7: 
      tone_key = melody7[tone_out]; break;
    }
    tone(speaker,tone_key);  
  }                         
  else {
   noTone(speaker); 
   delay (5); } 
}

//SETUP FUNCTION
void setup() 
{ 
 for(int i = 0; i < 8; i++)
 {
  pinMode(buttons[i], INPUT); 
 } 
 pinMode(speaker, OUTPUT); 
 pinMode(melody_button, INPUT);
 pinMode(record_led, OUTPUT);
 pinMode(play_led, OUTPUT);
 pinMode(inPot, INPUT);
}

//MAIN CODE
void loop() {
freePlay(); 
if (digitalRead(record_button) == HIGH) {
  digitalWrite(record_led, HIGH);
    for(int i = 0; i < maxNumber ; i++) {
      octave = map(analogRead(inPot),0,1023,1,7);                                           
        if (digitalRead(buttons[0]) == HIGH) {      
        tone_out = 0;                             
        silence = false;                          
        } 
        else if (digitalRead(buttons[1]) == HIGH) {
        one_out = 1;  
        silence = false;
        } 
        else if (digitalRead(buttons[2]) == HIGH) {
        tone_out = 2; 
        silence = false;
        } 
        else if (digitalRead(buttons[3]) == HIGH) {
        tone_out = 3;  
        silence = false;
        } 
        else if (digitalRead(buttons[4]) == HIGH) {
        tone_out = 4;  
        silence = false;
        } 
        else if (digitalRead(buttons[5]) == HIGH) {
        tone_out = 5; 
        silence = false;
        } 
        else if (digitalRead(buttons[6]) == HIGH) {
        tone_out = 6; 
        silence = false;
        } 
        else if (digitalRead(buttons[7]) == HIGH) {
        tone_out = 7;
        silence = false;
        } 
        else {
        silence = true;
        tone_key = 0;
        }

        if (silence == false) {
        switch(octave) { 
        case 1: tone_key = melody1[tone_out]; break;
        case 2: tone_key = melody2[tone_out]; break;
        case 3: tone_key = melody3[tone_out]; break;
        case 4: tone_key = melody4[tone_out]; break;
        case 5: tone_key = melody5[tone_out]; break;
        case 6: tone_key = melody6[tone_out]; break;
        case 7: tone_key = melody7[tone_out]; break;
        }
        tone(speaker,tone_key); 
        delay(time);
        }                         
        else {
        noTone(speaker);
        tone_key = 0; 
        delay (time);
        } 

    saveSounds[saveNumber] = tone_key;
    saveNumber++;
    if (digitalRead(play_button) == HIGH){
    break;}
    }

digitalWrite(record_led, LOW);
tone(speaker, 700);
delay(200);
noTone(speaker);
check++;
}

for (int i = 0; i<500; i++) {
  EEPROM.put(eeAddress,saveSounds[i]);
  eeAddress = eeAddress + 2;
}

if(check >= 1) {
  while (0 == 0){
    freePlay();
    if(digitalRead(play_button) == HIGH) {
      digitalWrite(play_led, HIGH);
        for(int i = 0; i < maxNumber; i++) {
        if(saveSounds[i] != 0) {
          tone(speaker,EEPROM.get(eeAddressplay,saveSounds[i]));
          eeAddressplay = eeAddressplay + 2;
          delay(25);
        }
        else {
          noTone(speaker);
          delay(time);
        }
        }
      noTone(speaker);
      digitalWrite(play_led,LOW);
    }
    freePlay();
  }
}
}
4
  • I don't have an answer on your question, sorry for that. However, some general comments: in freePlay you can make a loop instead of the first 8 if statements, even for the second 8, if you make from melody an array (so melody[melody_nr][...] In loop, you can also make a for loop of the 8 if statements, and second again using the same melody[melody_nr][...] variable. This will greatly reduce your code size (and maintainable etc). May 8 '17 at 10:15
  • Thank you for your message. I'm new to Arduino and C programming. I don't really understand what you mean. Could you please give an example?
    – mirandamg
    May 8 '17 at 11:07
  • I am not being sarcastic, but have you checked the volume control? It could be you need more power to the speaker. Another possibility is you are outputting to the 'LINE' rather than the 'SPEAKER'. It could be something to do with the resistance of your speaker not matching your circuit. May 8 '17 at 11:46
  • The whole thing was working prior to me saving the data into EEPROM.
    – mirandamg
    May 9 '17 at 0:11
1

NOTE: this is not an answer, but a response not able to put in a comment as request from the submittor mirandamg.

For the first example

Instead of

if (digitalRead(buttons[0]) == HIGH) {      
  tone_out = 0;                            
  silence = false;                        
} 
else if (digitalRead(buttons[1]) == HIGH) {
  tone_out = 1;  
  silence = false;
} 
...

Use

for (int buttonIndex = 0; buttonIndex < 8; buttonIndex++)
{
    if (digitalRead(buttons[butonIndex] == HIGH)
    {
       tone_out = buttonIndex;
       silence = false;
    }
}

This method does not work directly for variables melody1, 2, 3... Therefore, make an array, instead of:

byte melody1[8] = { 
...

use

byte melodies[8][8] = {
...

The first 8 is for the number of melodies, the second is for the number of notes.

You can improve it even further by making 2 constants:

const byte NR_OF_MELODIES = 8; // Number of melodies
const byte NR_OF_NOTES = 8;    // Number of notes per melody

And the array can be created s

byte melodies[NR_OF_MELODIES][NR_OF_NOTES] = {

If you make a const for the number of buttons:

const byte NR_OF_BUTTONS = 8; // Number of physical buttons

Then also the first line in the loop in my example can be changed as:

for (int buttonIndex = 0; buttonIndex < NR_OF_BUTTONS; buttonIndex++)

If you later need to change the number of notes, melodies or buttons, you don't need to iterate over your application to find all values. Especially since they are all 8.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.