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);
}
-
1You 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.dannyf– dannyf2017年04月17日 10:56:19 +00:00Commented Apr 17, 2017 at 10:56
2 Answers 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);
}
-
yeah but i want to be able to store the function in an array with the set parametersHjhk90– Hjhk902017年04月17日 06:20:47 +00:00Commented Apr 17, 2017 at 6:20
-
i am getting an error: exit status 1 conflicting declaration 'void (* SongSeq [100])()'Hjhk90– Hjhk902017年04月17日 10:51:38 +00:00Commented 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?2017年04月17日 11:41:16 +00:00Commented 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 guidanceHjhk90– Hjhk902017年04月17日 13:09:03 +00:00Commented Apr 17, 2017 at 13:09
-
Leave it to you, @Gammon. Very clever use of code.SDsolar– SDsolar2017年05月29日 04:25:41 +00:00Commented May 29, 2017 at 4:25
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)
{
;
}