Playing a melody with my Arduino UNO

Hi!

I've been trying to figure out how to make my Arduino UNO play a melody, but I want it to be programmable so that I can put in different notes for other melodies. There are a couple of variables that I would like to include in my code and these are tone length, tempo and of course the tone. Also, the button is there to start the melody, and I intend for the led to be blinking when the melody can be started by pressing the button, but I think I will be able to code these things later. Here is my code so far:

//Own Project 000 Melody player v.1

int button = 4;
int speaker = 5;
int led = 6;
int buttonState = 0;
// int tempo = 1;
int toneFrequency = 0;
int toneLength = 0;
int waitTime = 1000000 / (toneFrequency * 2);
int startMicros;
int currentMicros;
int period = 1000000;


int H () {
  toneLength = 1;
}
int I () {
  toneLength = 2;
}
int J () {
  toneLength = 3;
}
int K () {
  toneLength = 4;
}


int C () {
  toneFrequency = 261;
}
int D () {
  toneFrequency = 294;
}
int E () {
  toneFrequency = 329;
}
int F () {
  toneFrequency = 349;
}
int G () {
  toneFrequency = 392;
}
int A () {
  toneFrequency = 440;
}
int B () {
  toneFrequency = 493;
}
int C2 () {
  toneFrequency = 523;
}

int playNote () {
  currentMicros = micros();
  if ((currentMicros - startMicros) >= (period * toneLength)) {
    digitalWrite(speaker, HIGH);
    delayMicroseconds(waitTime);
    digitalWrite(speaker, LOW);
    delayMicroseconds(waitTime);
    startMicros = currentMicros;
  }
}


void setup() {
  pinMode(speaker, OUTPUT);
  pinMode(led, OUTPUT);
  pinMode(button, INPUT);
  startMicros = micros();
}

void loop() {
  H ();
  C ();
  playNote ();
  I ();
  F ();
  playNote ();
  I ();
  F ();
  playNote ();
  H ();
  G ();
  playNote ();
  H ();
  A ();
  playNote ();
  H ();
  B ();
  playNote ();
  H ();
  G ();
  playNote ();
  I ();
  A ();
  playNote ();
  H ();
  G ();
  playNote ();
  H ();
  A ();
  playNote ();
}

As you can see I haven't really figured out a way to work the tempo variable into my code (and thus it is behind // at the start of the code), but I did want to try it out to see if it would work for as far as I've gotten.

When I tried to compile the code, however, I got this error message:

Arduino: 1.8.5 (Mac OS X), Board: "Arduino/Genuino Uno"

In file included from /Users/Ruben/Library/Arduino15/packages/arduino/hardware/avr/1.6.21/cores/arduino/Arduino.h:231:0,
                 from sketch/Melody_player_v.1.ino.cpp:1:
/Users/Ruben/Library/Arduino15/packages/arduino/hardware/avr/1.6.21/cores/arduino/WString.h:38:28: error: expected unqualified-id before 'reinterpret_cast'
 #define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
                            ^
/Users/Ruben/Documents/Persoonlijke documenten/Arduino/Own Projects/Melody_player_v.1/Melody_player_v.1.ino:39:5: note: in expansion of macro 'F'
 int F () {
     ^
/Users/Ruben/Library/Arduino15/packages/arduino/hardware/avr/1.6.21/cores/arduino/WString.h:38:28: error: expected ')' before 'reinterpret_cast'
 #define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
                            ^
/Users/Ruben/Documents/Persoonlijke documenten/Arduino/Own Projects/Melody_player_v.1/Melody_player_v.1.ino:39:5: note: in expansion of macro 'F'
 int F () {
     ^
In file included from /Users/Ruben/Library/Arduino15/packages/arduino/hardware/avr/1.6.21/cores/arduino/Arduino.h:28:0,
                 from sketch/Melody_player_v.1.ino.cpp:1:
/Users/Ruben/Library/Arduino15/packages/arduino/hardware/avr/1.6.21/cores/arduino/WString.h:38:74: error: expected unqualified-id before ')' token
 #define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
                                                                          ^
/Users/Ruben/Documents/Persoonlijke documenten/Arduino/Own Projects/Melody_player_v.1/Melody_player_v.1.ino:39:5: note: in expansion of macro 'F'
 int F () {
     ^
/Users/Ruben/Documents/Persoonlijke documenten/Arduino/Own Projects/Melody_player_v.1/Melody_player_v.1.ino: In function 'void loop()':
/Users/Ruben/Library/Arduino15/packages/arduino/hardware/avr/1.6.21/cores/arduino/WString.h:38:74: error: expected primary-expression before ')' token
 #define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
                                                                          ^
/Users/Ruben/Documents/Persoonlijke documenten/Arduino/Own Projects/Melody_player_v.1/Melody_player_v.1.ino:80:3: note: in expansion of macro 'F'
   F ();
   ^
/Users/Ruben/Library/Arduino15/packages/arduino/hardware/avr/1.6.21/cores/arduino/WString.h:38:74: error: expected primary-expression before ')' token
 #define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
                                                                          ^
/Users/Ruben/Documents/Persoonlijke documenten/Arduino/Own Projects/Melody_player_v.1/Melody_player_v.1.ino:83:3: note: in expansion of macro 'F'
   F ();
   ^
exit status 1
Error compiling for board Arduino/Genuino Uno.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

So basically I have two questions:

  • What is wrong with the code for it to give this error message?
  • What would be the best way to implement the tempo function into my code?

I would appreciate any help!

Thanks!

P.S. I am aware that there are better and more compact ways of playing a melody using an Arduino, but I wanted to challenge myself and come up with a way to do this with the very limited knowledge I have of Arduino coding at the moment.

F() is a macro used to ensure constant strings stay in flash.

TolpuddleSartre:
F() is a macro used to ensure constant strings stay in flash.

Ok so basically I can't use F()?

Rublie14:
Ok so basically I can't use F()?

That is correct

int period = 1000000;

An int data type can hold -32768 to 32767. A long data type would be more appropriate.

Arduino data types.

And there are a lot of warnings because you specify a return type for functions but there is no return statement in the function.

int H () {
  toneLength = 1;
}

TolpuddleSartre:
That is correct

Could I maybe use a non-capitalised f then because f is the name for the tone after all...

groundFungus:

int period = 1000000;

An int data type can hold -32768 to 32767. A long data type would be more appropriate.

Arduino data types.

And there are a lot of warnings because you specify a return type for functions but there is no return statement in the function.

int H () {

toneLength = 1;
}

Thank you for answering!

So it would be better like this?:

long int period = 1000000;

And I'm not sure what you mean by a return statement.

int J () {
  toneLength = 3;
}

Here you made a promise to the compiler that the function J() would return an "int", but you don't return a value.
In fact, the return type of the function should be "void".

TolpuddleSartre:

int J () {

toneLength = 3;
}



Here you made a promise to the compiler that the function J() would return an "int", but you don't return a value.
In fact, the return type of the function should be "void".

Ok so like this?:

void h () {
  toneLength = 1;
}

Yes, just like that, except you misspelled J :wink:

long int period = 1000000;

Could just be

long period = 1000000;

but, since it is a variable that deals with time it may be better

unsigned long period = 1000000;

(because time, in my universe, never goes negative).

Right, I copied the wrong one over :grinning:

groundFungus:

unsigned long period = 1000000;

(because time, in my universe, never goes negative).

And from the link you posted earlier I get that too now, because unsigned means it only stores positive numbers.

Thank you!