Functions with Arrays

Im trying to store melodies for a piezo as arrays in functions so that when PinA is high function A is run and melody A is played.

this is the code that im using (for single melodies)

int notes[13] = {1915, ((1000000 / 277) / 2), 1700, ((1000000 / 311) / 2), 1519, 1432, ((1000000 / 370) / 2), 1275, ((1000000 / 415) / 2), 1136, ((1000000 / 466) / 2), 1014, 956,};
   int c = notes[0];
   int csharp = notes[1];
   int d = notes[2];
   int dsharp = notes[3];
   int e = notes[4];
   int f = notes[5];
   int fsharp = notes[6];
   int g = notes[7];
   int gsharp = notes[8];
   int a = notes[9];
   int asharp = notes[10];
   int b = notes[11];
   int C = notes[12];
 const byte totalnotes = 15; 
 int tones[totalnotes] = {g, asharp, f, e, f, e, f, g, asharp, f, e, f, e, f, g}; 
 int beatnote[totalnotes] = {2, 2, 2, 2, 2, 1, 5, 2, 2, 2, 2, 2, 2, 5, 8};    

 
void setup() {
  pinMode(9, OUTPUT);
  pinMode(14, INPUT);
  pinMode(2, INPUT);
}
void loop() {int tempo = analogRead(14); tempo = map(tempo, 0, 1024, 1, 5);
 for(byte i = 0; i < totalnotes; i++) {int constantbeat = (100000 / (tones[i])) * (beatnote[i]) * tempo; for(int time = 0; time < constantbeat; time++) {digitalWrite(9, HIGH); delayMicroseconds(tones[i]); digitalWrite(9, LOW); delayMicroseconds(tones[i]);delay(1);}}}

pin 2 was an input either high or low for the if() condition .

The code is basically just the example player. the code plays just one melody in a loop. in order to store more than one melody, i first tried an if(condition) {funcA (i)}… i would include 3 functions per melody. 1 for the tones, 1 for the totalnotes, and 1 for the beatnote. these would take the value of byte i and would return the corresponding index for their array (just a value for totalnotes). Howver this didnt work. can anyone explain or give correct method? i did some research and i read that arrays cant be used in functions. is this true?

i did some research and i read that arrays cant be used in functions. is this true?

Not at all.

Im trying to store melodies for a piezo as arrays in functions

Looks to me like you are storing the data in global arrays.

void loop() {int tempo = analogRead(14); tempo = map(tempo, 0, 1024, 1, 5);
 for(byte i = 0; i < totalnotes; i++) {int constantbeat = (100000 / (tones[i])) * (beatnote[i]) * tempo; for(int time = 0; time < constantbeat; time++) {digitalWrite(9, HIGH); delayMicroseconds(tones[i]); digitalWrite(9, LOW); delayMicroseconds(tones[i]);delay(1);}}}

Man, oh man. Can I suggest you learn how to use the enter key? Putting the { and } on separate lines and proper indenting would make your code so much more readable.

void loop()
{
  int tempo = analogRead(14);
  tempo = map(tempo, 0, 1024, 1, 5);
  for(byte i = 0; i < totalnotes; i++)
  {
    int constantbeat = (100000 / tones[i]) * beatnote[i] * tempo;
    for(int time = 0; time < constantbeat; time++)
    {
      digitalWrite(9, HIGH);
      delayMicroseconds(tones[i]);
      digitalWrite(9, LOW);
      delayMicroseconds(tones[i]);
      delay(1);
    }
  }
}

in order to store more than one melody, i first tried an if(condition) {funcA (i)}… i would include 3 functions per melody. 1 for the tones, 1 for the totalnotes, and 1 for the beatnote. these would take the value of byte i and would return the corresponding index for their array (just a value for totalnotes). Howver this didnt work.

What did you try? How did it “not work”? What did it do that you didn’t want? What did it not do that you did want?

I don’t understand your code, but perhaps the Tone library might simplify things?

http://www.arduino.cc/en/Reference/Tone

Example:

#include <Tone.h>

Tone tone1;

tone1.begin(9);

 tone1.play(NOTE_C4, 100);
 delay (100);
 tone1.play(NOTE_D4, 100);
 delay (100);
 tone1.play(NOTE_E4, 100);
 delay (1000);

since your using int and not float or double your better off just doing the math real fast for these ((1000000 / 277) / 2) and putting 1805 instead of having the micro-controller do it and dropping off the decimals anyway.

Since you're using int and not float or double, you're better off just doing the math real fast for these ((1000000 / 277) / 2) and putting 1805, instead of having the micro-controller do it and dropping off the decimals anyway.

But microcontrollers (and more importantly, compilers) are good at doing arithmetic - why not let them do it?

my first attempt looked something like this

int notes[13] = {1915, ((1000000 / 277) / 2), 1700, ((1000000 / 311) / 2), 1519, 1432, ((1000000 / 370) / 2), 1275, ((1000000 / 415) / 2), 1136, ((1000000 / 466) / 2), 1014, 956,};
   int c = notes[0];
   int csharp = notes[1];
   int d = notes[2];
   int dsharp = notes[3];
   int e = notes[4];
   int f = notes[5];
   int fsharp = notes[6];
   int g = notes[7];
   int gsharp = notes[8];
   int a = notes[9];
   int asharp = notes[10];
   int b = notes[11];
   int C = notes[12];
   const byte totalnotes = 15; 
   int tones; 
   int beatnote;
   byte i;
   
 
 
void setup() {
  pinMode(9, OUTPUT);
  pinMode(14, INPUT);
  pinMode(2, INPUT);
}
void loop() {if(2 == HIGH) {totalnotes = 3; funcAbeats(i); funcAtones(i);}...int tempo = analogRead(14); tempo = map(tempo, 0, 1024, 1, 5);
 for(byte i = 0; i < totalnotes; i++) {int constantbeat = (100000 / (tones[i])) * (beatnote[i]) * tempo; for(int time = 0; time < constantbeat; time++) {digitalWrite(9, HIGH); delayMicroseconds(tones[i]); digitalWrite(9, LOW); delayMicroseconds(tones[i]);delay(1);}}}
 
 int funcAbeats(i){
   beats[3] = {a, a, a}
   return beats[i];
 }
 ...[code]
i declared i in global scope but the error for undeclared in this scope still appeared

[/code]

if(2 == HIGH)

Don't expect that to work. Check what HIGH is defined as.

What is wrong with your return key?

int funcAbeats(i)

i needs a type.

 beats[3] = {a, a, a}

Needs more semicolon. And a type for "beats"

What are you trying to do here?

...int tempo
int c = notes[0];
   int csharp = notes[1];

Why not just store (or simply define - try an enum) the indices - why copy the values?

totalnotes = 3

You've declared it as a constant so you can't change it.

beatnote[i]

"beatnote" isn't an array, so you can't subscript it. Neither is "tones".

Please - format your code before posting - try the IDE's auto-format (ctrl-T)

Code: beats[3] = {a, a, a}Needs more semicolon. And a type for "beats"

sorry when i wrote "beats" i meant "beatnote". so "i" and "beatnote" have to be redeclared within the functions?

i also tried moving the entire loop function into two other functions. the loop function would run and if(condition) function A would run else if(conditon) function B would run. So "beatnote" and "i" and "tones" would be defined within each separate function. i didnt get any errors but nothing happened when i uploaded it.

does anyone know of any codes for what i am trying to do?

What was wrong with my earlier suggestion of using the Tone library?

can it be used to store multiple melodies? i just assumed that the tone function was another [easier] way of creating the desired frequency.

Just let the library do the hard work. Then you need a structure with notes/durations. This works, for example:

// see: http://arduino.cc/en/Tutorial/Tone

#define NOTE_C4  262
#define NOTE_CS4 277
#define NOTE_D4  294
#define NOTE_DS4 311
#define NOTE_E4  330
#define NOTE_F4  349
#define NOTE_FS4 370
#define NOTE_G4  392
#define NOTE_GS4 415
#define NOTE_A4  440
#define NOTE_AS4 466
#define NOTE_B4  494

// pin the speaker is on
#define SPEAKER 9

void setup ()
{
}

// a tune consists of notes and durations
typedef struct t_tune {
  unsigned int note;
  float duration;
} ;


// first tune
t_tune tune1 [] = { 
  { NOTE_C4, 4 },
  { NOTE_D4, 8 },
  { NOTE_E4, 4 },
  { 0 },  // end of table marker
};


// second tune
t_tune tune2 [] = { 
  { NOTE_G4, 4 },
  { NOTE_AS4, 4 },
  { NOTE_F4, 4 },
  { NOTE_E4, 4 },
  { NOTE_F4, 4 },
  { NOTE_E4, 2 },
  { NOTE_G4, 1 },
  { NOTE_AS4, 4 },
  { NOTE_F4, 4 },
  { NOTE_E4, 4 },
  { NOTE_F4, 4 },
  { NOTE_E4, 4 },
  { NOTE_F4, 1 },
  { NOTE_G4, 0.5 },
  { 0 },  // end of table marker
};


// play any tune
void playtune (struct t_tune which [])
{
for (int i = 0; which [i].note; i++)
  {
    int noteDuration = 1000 / which [i].duration;
    tone (SPEAKER, which [i].note);
    delay(noteDuration);
    noTone(SPEAKER);
    delay (20);
  }

}

// play a couple of tunes
void loop ()
{
  
 playtune (tune1);
 delay (1000);
 playtune (tune2);
 delay (1000);

}

Thanks, I think this will work

Just figured it out

if(2 == HIGH)

Don’t expect that to work.

Turns out you were right. Here’s the working code

int button = 2;

int notes[13] = {
  1915, ((1000000 / 277) / 2), 1700, ((1000000 / 311) / 2), 1519, 1432, ((1000000 / 370) / 2), 1275, ((1000000 / 415) / 2), 1136, ((1000000 / 466) / 2), 1014, 956,};
int c = notes[0];
int csharp = notes[1];
int d = notes[2];
int dsharp = notes[3];
int e = notes[4];
int f = notes[5];
int fsharp = notes[6];
int g = notes[7];
int gsharp = notes[8];
int a = notes[9];
int asharp = notes[10];
int b = notes[11];
int C = notes[12];




void setup() {
  pinMode(9, OUTPUT);
  pinMode(2, INPUT);
}
void loop() {
  if(digitalRead(button) == HIGH) {
    play1 ();
  }
  else if(digitalRead(button) == LOW) {
    play2 ();
  }
}

void play1 () {

  byte totalnotes = 4;
  int tones[] = {
    c, d, e, f    };
  int beatnote[] = {
    1, 1, 1, 1    };  
  int tempo = analogRead(14); 
  tempo = map(tempo, 0, 1024, 1, 5);
  for(byte i = 0; i < totalnotes; i++) 
  {
    int constantbeat = (100000 / (tones[i])) * (beatnote[i]) * tempo;
    for(int time = 0; time < constantbeat; time++) 
    {
      digitalWrite(9, HIGH); 
      delayMicroseconds(tones[i]); 
      digitalWrite(9, LOW); 
      delayMicroseconds(tones[i]);
    }
  }
}

void play2 () {

  byte totalnotes = 4;
  int tones[] = {
    c, C, c, C    };
  int beatnote[] = {
    1, 1, 1, 1    };  
  int tempo = analogRead(14); 
  tempo = map(tempo, 0, 1024, 1, 5);
  for(byte i = 0; i < totalnotes; i++) 
  {
    int constantbeat = (100000 / (tones[i])) * (beatnote[i]) * tempo;
    for(int time = 0; time < constantbeat; time++) 
    {
      digitalWrite(9, HIGH); 
      delayMicroseconds(tones[i]); 
      digitalWrite(9, LOW); 
      delayMicroseconds(tones[i]);
    }
  }
}

Thanks to everyone for the help!