So it's day 2 of my Arduino programming experience and amazingly I need help. I need to call a function chosen at random. So I can see how I could set up a string array containing the function names and then use a randomly generated index to pull the function name out of the array and assign it to a variable:
char* myFunctions[]={"myFunction1", "myFunction2", "myFunction3", "myFunction4", "myFunction5","myFunction6"};
long randNumber;
void setup(){
randomSeed(analogRead(0));
}
void loop() {
randNumber=random(6);
//so now myFunctions[randNumber] will give me my randomly chosen function name, but how do I call that function?
}
void myFunction1(){
//do something
}
void myFunction2(){
//do something
}
void myFunction3(){
//do something
}
etc up to myFunction6()
You can do it with an array of pointers to functions. Given that it's day two of your arduino adventure though, a switch statement would likely be an easier choice for this.
As long as all of the functions have the same return type and arguments, this will work:
typedef void (*FuncPtr)(void); //typedef 'return type' (*FuncPtr)('arguments')
FuncPtr myFunctions[]={&myFunction1, &myFunction2, &myFunction3,&myFunction4, &myFunction5,&myFunction6};
void loop() {
randNumber=random(6);
//so now myFunctions[randNumber] will give me my randomly chosen function name, but how do I call that function?
myFunctions[randNumber]();
}
Great advice everyone, thanks so much for your help. If I can avoid it I'd prefer not to go down the switch route as I'm likely to end up with a lot of these functions to call and switching will get clunky I think. So the array pointer approach has a lot of appeal for me, plus there's a real risk I might learn something along the way (and let's face it I have plenty to learn). I tried Tom's approach in the Virtronics Arduino simulator but it had a problem with the declaration and came up with this error msg:
So then of course it fell over when trying to call myFunctionsrandNumber.
Highly likely I've done something silly in which case please let me know, but I guess it could also be the simulator which still has a few kinks to iron out. Would I be better off trying this on the actual device? I'll also give the #include approach a go (haven't had time yet) and will report back. Thanks again, and all further advice very welcome.
Not sure what you did, but this example compiles and works:
typedef void (*FuncPtr)(void); //typedef 'return type' (*FuncPtr)('arguments')
FuncPtr myFunctions[]={&myFunction1, &myFunction2, &myFunction3,&myFunction4, &myFunction5,&myFunction6};
void setup()
{
// This code will only run once, after each powerup or reset of board
}
void loop() {
byte randNumber=random(6);
//so now myFunctions[randNumber] will give me my randomly chosen function name, but how do I call that function?
myFunctions[randNumber]();
}
void myFunction1(){
}
void myFunction2(){
}
void myFunction3(){
}
void myFunction4(){
}
void myFunction5(){
}
void myFunction6(){
}
Thanks Tom. Probably more by luck than judgement that's exactly what I did. So given that it compiles fine for you I had a closer look at the simulator and sure enough the docs say:
Limitations :
Custom Libraries, pointers, structures,classes and enums may or may not work
Other minor issues to do with complicated C++ commands
Firmata needs work
Mouse object will run but not yet implemented
Pointers are not implemented
typdef function pointers not implemented
MAC,iOS interface not implemented
simple typdefs work but typedef with enum or structs to be fixed
So I asume that's the issue. I guess you can't beat the real thing so I'll give that a go just as soon as I get my board back... Many thanks for your help.
Tom's code should work fine. I've taken his code, done away with the typedef and put in some print statements. Maybe that will help to debug it for you...
void (*myFunctions[])(void)={&myFunction1, &myFunction2, &myFunction3,&myFunction4, &myFunction5,&myFunction6};
void setup()
{
// This code will only run once, after each powerup or reset of board
Serial.begin(9600);
}
void loop() {
byte randNumber=random(6);
//so now myFunctions[randNumber] will give me my randomly chosen function name, but how do I call that function?
myFunctions[randNumber]();
}
void myFunction1(){
Serial.println("Function 1");
}
void myFunction2(){
Serial.println("Function 2");
}
void myFunction3(){
Serial.println("Function 3");
}
void myFunction4(){
Serial.println("Function 4");
}
void myFunction5(){
Serial.println("Function 5");
}
void myFunction6(){
Serial.println("Function 6");
}
CharlieMcF:
Thanks Tom. Probably more by luck than judgement that's exactly what I did. So given that it compiles fine for you I had a closer look at the simulator and sure enough the docs say:
Limitations :
So I asume that's the issue. I guess you can't beat the real thing so I'll give that a go just as soon as I get my board back... Many thanks for your help.
You can use the IDE to compile it whether you have a board or not - at least you can prove to yourself that it compiles (or not).
Using the IDE (thanks wildbill, I should've thought of that) both Tom's and econjack's code compile OK so hopefully all will be well when I can try it on the board itself. I was also keen to try nicoverduin's approach but can't find the pointertest library anywhere (I have looked, honest) and of course it won't compile without it. Would someone be able to point (haha) me at it?
In case it's of interest, when I tried econjack's code in the Virtronics simulator I got this error msg: