0

I am trying to store a set of functions with different parameter in an array. When the code enters the function songlearn with tune==1 I want the functions with set parameters to be stored in the array without executing. What am I doing wrong? Here's my code:

const int x=100;
int (*SongSeq[x])();
int note[x];
int playNote(int midi, int row, int col, int len, bool short_led = false);
void songlearn(int tune);
int tune;
void songlearn (int tune){
 if (tune==1){ 
 state=1;
 lcd.clear();
 lcd.setCursor(4,0); 
 lcd.print("Learning Song :");// Print a message to the LCD.
 lcd.setCursor(1, 1);
 lcd.print(menuP1);
// if (songpage==1){
// if (BackState==HIGH){//leaving song
// posP=0;
// Page=2; 
// Play(posP);
// }
// }
 //Plays Mary Had a Little Lamb on a loop at 145 BPM
//Bar 1
SongSeq[0]= playNote(0x40, 3, 1, 414); //Quarter note: E
note[0]=0x40;
SongSeq[1]=playNote(0x3e, 2, 4, 414); //Quarter note: D
note[1]=0x3e;
SongSeq[2]=playNote(0x3c, 2, 2, 414); //Quarter note: C
note[2]=0x3c;
SongSeq[3]=playNote(0x3e, 2, 4, 414); //Quarter note: D
note[3]=0x3e;
//Bar 2
SongSeq[4]=playNote(0x40, 3, 1, 414,1); //Quarter note: E
note[4]=0x40;
SongSeq[5]=playNote(0x40, 3, 1, 414,1); //Quarter note: E
note[5]=0x40;
SongSeq[6]=playNote(0x40, 3, 1, 828,1); //Half note: E
note[6]=0x40;
//Bar 3
SongSeq[7]=playNote(0x3e, 2, 4, 414,1); //Quarter note: D
note[7]=0x3e;
SongSeq[8]=playNote(0x3e, 2, 4, 414,1); //Quarter note: D 
note[8]=0x3e;
SongSeq[9]=playNote(0x3e, 2, 4, 828,1); //Half note: D
note[9]=0x3e;
//Bar 4
SongSeq[10]=playNote(0x40, 3, 1, 414); //Quarter note: E
note[10]=0x40;
SongSeq[11]=playNote(0x43, 3, 4, 414,1); //Quarter note: G
note[11]=0x43;
SongSeq[12]=playNote(0x43, 3, 4, 828,1); //Half note: G
note[12]=0x43;
//Bar 5
SongSeq[13]=playNote(0x40, 3, 1, 414); //Quarter note: E
note[13]=0x40;
SongSeq[14]=playNote(0x3e, 2, 4, 414); //Quarter note: D
note[14]=0x3e;
SongSeq[15]=playNote(0x3c, 2, 2, 414); //Quarter note: C
note[15]=0x3c;
SongSeq[16]=playNote(0x3e, 2, 4, 414); //Quarter note: D
note[16]=0x3e;
//Bar 6
SongSeq[17]=playNote(0x40, 3, 1, 414,1); //Quarter note: E
note[17]=0x40;
SongSeq[18]=playNote(0x40, 3, 1, 414,1); //Quarter note: E
note[18]=0x40;
SongSeq[19]=playNote(0x40, 3, 1, 414,1); //Quarter note: E
note[19]=0x40;
SongSeq[20]=playNote(0x40, 3, 1, 414,1); //Quarter note: E
note[20]=0x40;
//Bar 7
SongSeq[21]=playNote(0x3e, 2, 4, 414,1); //Quarter note: D
note[21]=0x3e;
SongSeq[22]=playNote(0x3e, 2, 4, 414,1); //Quarter note: D
note[22]=0x3e;
SongSeq[23]=playNote(0x40, 3, 1, 414); //Quarter note: E
note[23]=0x40;
SongSeq[24]=playNote(0x3e, 2, 4, 414); //Quarter note: D
note[24]=0x3e;
//Bar 8
SongSeq[25]=playNote(0x3c, 2, 2, 1656); //Whole note: C
note[25]=0x3c;
//End song
 }
 }
 int playNote(int midi, int row, int col, int len, bool short_led = false)
{
 int len1, len2;
 if (short_led) {
 len1 = len * 3 / 4;
 len2 = len * 1 / 4;
 } else {
 len1 = len;
 len2 = 0;
 }
 noteOn(0x90, midi, 100);
 digitalWrite(LedR[row], HIGH);
 digitalWrite(LedC[col], LOW);
 delay(len1);
 digitalWrite(LedR[row], LOW);
 digitalWrite(LedC[col], HIGH);
 delay(len2);
 noteOff(0x90, midi, 0);
}
Ghanima
4595 silver badges18 bronze badges
asked Apr 17, 2017 at 5:36
1
  • 1
    You probably want to explain in greater detail what you meant by "storing functions in an array". It may be well understood to you but certainly not to others. Commented Apr 17, 2017 at 10:56

2 Answers 2

2

What you have done will certainly call the function. Since it is always the same function, just store the arguments into an array. Something like this:

const int COUNT = 100;
struct 
 {
 int midi;
 int row;
 int col; int len;
 bool short_led;
 } notes [COUNT] = {
 { 0x40, 3, 1, 414 }, //Quarter note: E
 { 0x3e, 2, 4, 414 }, //Quarter note: D
 { 0x3c, 2, 2, 414 }, //Quarter note: C
 // and so on
 };
int playNote(int midi, int row, int col, int len, bool short_led = false);
void setup() 
 {
 // put your setup code here, to run once:
 }
void loop() 
 {
 for (int i = 0; i < COUNT; i++)
 {
 if (notes [i].midi)
 playNote (notes [i].midi, notes [i].row, notes [i].col, 
 notes [i].len, notes [i].short_led);
 }
 }
int playNote(int midi, int row, int col, int len, bool short_led)
{
 int len1, len2;
 if (short_led) {
 len1 = len * 3 / 4;
 len2 = len * 1 / 4;
 } else {
 len1 = len;
 len2 = 0;
 }
 noteOn(0x90, midi, 100);
 digitalWrite(LedR[row], HIGH);
 digitalWrite(LedC[col], LOW);
 delay(len1);
 digitalWrite(LedR[row], LOW);
 digitalWrite(LedC[col], HIGH);
 delay(len2);
 noteOff(0x90, midi, 0);
}

yeah but i want to be able to store the function in an array with the set parameters

Do you? I wonder why.

Anyway, you can do that by making an array of lambda functions like this:

const int COUNT = 100;
int playNote(int midi, int row, int col, int len, bool short_led = false);
void (*SongSeq[COUNT])() = 
 {
 [] { playNote(0x40, 3, 1, 414); } ,
 [] { playNote(0x3e, 2, 4, 414); } ,
 [] { playNote(0x3c, 2, 2, 414); } ,
 [] { playNote(0x3e, 2, 4, 414); } ,
 // ... and so on 
 };
void setup() 
 {
 Serial.begin (115200);
 }
void loop() 
 {
 for (int i = 0; i < COUNT; i++)
 {
 if (SongSeq [i])
 SongSeq [i] ();
 }
 }
int playNote(int midi, int row, int col, int len, bool short_led)
{
 Serial.print ("Playing note ");
 Serial.println (midi);
 delay (100);
}
answered Apr 17, 2017 at 5:59
5
  • yeah but i want to be able to store the function in an array with the set parameters Commented Apr 17, 2017 at 6:20
  • i am getting an error: exit status 1 conflicting declaration 'void (* SongSeq [100])()' Commented Apr 17, 2017 at 10:51
  • The second sketch I posted above compiles without errors for me under IDE 1.6.9. Have you tried that exact code? Commented Apr 17, 2017 at 11:41
  • i was able to get it to work i had an extra int (*SongSeq [100] ) in the code which i got rid of. thank you for your help and guidance Commented Apr 17, 2017 at 13:09
  • Leave it to you, @Gammon. Very clever use of code. Commented May 29, 2017 at 4:25
1

Calling or entering a function means executing it -- that is just how the language is defined. A 'function' is not a construct you can manage, i.e., store or otherwise mess-with (technical term!) in the ways you might do with other kinds of data. But:

You can store a function's address (i.e., a pointer to the function) and use the pointer to call the function, and you can store its parameters just as you would store any data. So, if I understand correctly what you want to do, try something like this crude outline based on my quick read of your code. It uses stored function pointers and song-numbers and shows how to call one of those functions with the associated, stored song number as a parameter:

// Ptr to a function and a song number
typedef struct {
 void (*pfunc)(int tune);
 int tuneNum;
} SONG_T;
#define COUNT 12
void songlearn(int);
void othersongfunc(int);
// void moresongfunctions(int);
// void moresongfunctions(int);
// Table of songs & functions:
SONG_T Songs[COUNT] = {
 {songlearn, 2},
 {othersongfunc, 1},
 {songlearn, 7},
 {othersongfunc, 3},
 // etc
};
void songlearn(int)
{
 ; // does whatever it does
}
void othersongfunc(int)
{
 ; // does whatever it does
}
void somefunc(uint8_t whichSong)
{
 if( whichSong < COUNT )
 (*Songs[whichSong].pfunc)(Songs[whichSong].tuneNum);
}
void setup(void)
{
 somefunc(3);
}
void loop(void)
{
 ;
}
answered Apr 17, 2017 at 12:04

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.