Calling functions in loop - a different function each time loop plays

Hello again

So my head is in the right place today to tackle this so I might as well keep going!

How might one call a function during a loop, but call a different function each time.

In my loop, I want to call two of the funcitons every single cycle. No problem!

I have a bunch of other functions that I want to call, but I want to cycle through those funcitons...

How would I cycle through a dozen functions, calling just one each loop?

So:

loop()

one()

two()

three()

then next loop()

one ()

two()

four()

then:

loop()

one()

two()

five()

and so on...

Presumably this is done with an array?

would this be the correct way to approach it?

void zero();
void one();
void two();
void three();
void four();
void five();
void six();
void seven();
void eight();
void nine();

typedef void (*num_func) ();
num_func functions[] = { zero, one, two, three, four, five, six, seven, eight, nine};

and then do something in loop where I call then increment by one?

void loop()
    static int index = 3;
    one();
    two();
    functions[index++]();
    if (index > 9)
        index = 3;
}

johnwasser:

void loop()

static int index = 3;
    one();
    two();
    functionsindex++;
    if (index > 9)
        index = 3;
}

Well that was a very wordy way of saying "Yes" :slight_smile:

Thank you, squire!

Set up theories, write code, test and have fun discouvering new ways. Think outside the box.
As a blueberry I did that once and made experienced Ariadne people look like amatoers in a matter very similiar to Yours.
Good luck!

johnwasser:

void loop()

static int index = 3;
    one();
    two();
    functionsindex++;
    if (index > 9)
        index = 3;
}

Silly question. Where and how do I define "functions"? It isn't a int so where and how is it defined?

Planning and Implementing a Program

There are lots of useful links on the Useful Links Thread.

...R

Thanks Robin2 (out of interest, why 2?). It was treading those guides that got me as far as I did (and going off, finding more things to read etc). Knowing clearly what I wanted to do, but just not quite knowing how to get all the way there.

This is where I am right now:

void setup() {

//Array details

  typedef void (*num_func) ();
  num_func functions [] = { OilTemperature, OilPressure, OilPressureWarning, BoostPressure, FuelLevel, FuelLevelWarning, FuelPressure, FuelPressureWarning, Lambda, LambdaWarning, BatteryLevel, ChargeWarning};

}

void loop() {

 

  static int index = 1;
  functions[index++]();
  if (index > 12);
  index = 1;
}


//functions I want to call

void OilTemperature() {

  int val = analogRead(OilTempSensePin); // read the value from the oil temp sender

  val = constrain(val, 500, 900); // reset the value to within these parameters CHANGE ME

  int OilTempLevel = map (val, 500, 900, 0, 255); // CHANGE ME

  analogWrite(OilTempOutputPin, OilTempLevel); // write OilTemperature to OilTemperatureOutputPin
}

void OilPressure() {

  int val = analogRead(OilPressureSensePin); // read the value from the oil pressure sender

  val = constrain(val, 500, 900); // reset the value to within these parameters CHANGE ME

  int OilPressureLevel = map (val, 500, 900, 0, 255); // CHANGE ME

  analogWrite(OilPressureOutputPin, OilPressureLevel); // OilTemperature to OilTemperatureOutputPin

}

void OilPressureWarning() {

}

void BoostPressure() {
  int val = analogRead(BoostSensePin); // read the value from the boost pressure sender

  val = constrain(val, 500, 900); // reset the value to within these parameters CHANGE ME

  int BoostPressureLevel = map (val, 500, 900, 0, 255); // CHANGE ME

  analogWrite(BoostOutputPin, BoostPressureLevel); // write BoostPressureLevel to BoostOutputPin

}

void FuelLevel() {
  int val = analogRead(FuelLevelSensePin); // read the value from the fuel level sender

  val = constrain(val, 500, 900); // reset the value to within these parameters CHANGE ME

  int FuelLevel = map (val, 500, 900, 0, 255); // CHANGE ME

  analogWrite(FuelLevelOutputPin, FuelLevel); // write FuelLevel translates to FuelLevelOutputPin

}

void FuelLevelWarning() {

}

void FuelPressure() {
  int val = analogRead(FuelPressureSensePin); // read the value from the fuel pressure sender

  val = constrain(val, 500, 900); // reset the value to within these parameters CHANGE ME

  int FuelPressureLevel = map (val, 500, 900, 0, 255); // CHANGE ME

  analogWrite(FuelPressureOutputPin, FuelPressureLevel); // write FuelPressure to FuelLevelOutputPin

}

void FuelPressureWarning() {

}

void Lambda() {
  int val = analogRead(LambdaSensePin); // read the value from the lambda sender

  val = constrain(val, 500, 900); // reset the value to within these parameters CHANGE ME

  int LambdaLevel = map (val, 500, 900, 0, 255); // CHANGE ME

  analogWrite(LambdaOutputPin, LambdaLevel); // write LambdaLevel to LambdaLevelOutputPin
}

void LambdaWarning() {

}

void BatteryLevel() {
  int val = analogRead(BatteryVoltageSensePin); // read the value from the fuel level sender

  val = constrain(val, 500, 900); // reset the value to within these parameters CHANGE ME

  int BatteryLevel = map (val, 500, 900, 0, 255); // CHANGE ME

  analogWrite(BatteryVoltageOutputPin, BatteryLevel); // write BatteryVoltage to FuelLevelOutputPin

}

void ChargeWarning() {

}

each of the functions work (of course they do, they aren't complicated!), I've had them running, I just need to tweak each one to suit the sensors used when I come to fit it.

The functions I want to run every time will just be written directly in loop rather than called.

When I compile this lot, I get an error 'functions' was not defined in this scope. Of course I would get that. Thinking at first functions would be an integer, I defined it as int in the definitions at the top but before even hitting compile I knew that wasn't going to work, sure enough I get an invalid types 'int[int]'

//what I am trying to achieve is a set of different sketches to test when I get a chance (currently on a ship so don't have the things I need to test the scripts properly).
So, I have the nixie tube output in binary sketch, the rev counter sketch (which I will copy for speed and adjust the calculations to suit), and one or two others I haven't needed help with to test out and debug.

fall-apart-dave:
Thanks Robin2 (out of interest, why 2?).

Think about it.

...R

fall-apart-dave:
When I compile this lot, I get an error ‘functions’ was not defined in this scope.

You can’t do this
num_func functions [] = { OilTemperature, OilPressure, OilPressureWarning, BoostPressure, FuelLevel, FuelLevelWarning, FuelPressure, FuelPressureWarning, Lambda, LambdaWarning, BatteryLevel, ChargeWarning};
and this

 functions[index++]();

for the simple reason that all the names of both functions and variables are lost in the compiling process. So there is nothing in your compiled program called OilPressureWarning. It will have been replaced by some obscure number that will probably be different every time the program is compiled.

It is possible to use function pointers (hope I have the jargon correct) to create an array of the addresses in memory of the functions - but that is advanced programming. No doubt Google will guide you to suitable tutorials.

…R

Of course you can, you just have to declare the functions before you use them:

[color=#434f54]// function declarations/prototypes[/color]
[color=#00979c]void[/color] [color=#000000]OilTemperature[/color][color=#000000]([/color][color=#000000])[/color][color=#000000];[/color]
[color=#00979c]void[/color] [color=#000000]OilPressure[/color][color=#000000]([/color][color=#000000])[/color][color=#000000];[/color]
[color=#00979c]void[/color] [color=#000000]OilPressureWarning[/color][color=#000000]([/color][color=#000000])[/color][color=#000000];[/color]

[color=#00979c]typedef[/color] [color=#00979c]void[/color] [color=#000000]([/color][color=#434f54]*[/color][color=#000000]num_func[/color][color=#000000])[/color] [color=#000000]([/color][color=#00979c]void[/color][color=#000000])[/color][color=#000000];[/color]
[color=#000000]num_func[/color] [color=#000000]functions[/color] [color=#000000][[/color][color=#000000]][/color] [color=#434f54]=[/color] [color=#000000]{[/color]
  [color=#000000]OilTemperature[/color][color=#434f54],[/color]
  [color=#000000]OilPressure[/color][color=#434f54],[/color]
  [color=#000000]OilPressureWarning[/color][color=#434f54],[/color]
  [color=#434f54]// ...[/color]
[color=#000000]}[/color][color=#000000];[/color]

[color=#00979c]void[/color] [color=#5e6d03]setup[/color][color=#000000]([/color][color=#000000])[/color] [color=#000000]{[/color][color=#000000]}[/color]

[color=#00979c]void[/color] [color=#5e6d03]loop[/color][color=#000000]([/color][color=#000000])[/color] [color=#000000]{[/color]
  [color=#00979c]static[/color] [color=#00979c]int[/color] [color=#000000]index[/color] [color=#434f54]=[/color] [color=#000000]1[/color][color=#000000];[/color]
  [color=#000000]functions[/color][color=#000000][[/color][color=#000000]index[/color][color=#434f54]++[/color][color=#000000]][/color][color=#000000]([/color][color=#000000])[/color][color=#000000];[/color]
  [color=#5e6d03]if[/color] [color=#000000]([/color][color=#000000]index[/color] [color=#434f54]>[/color] [color=#000000]12[/color][color=#000000])[/color]
    [color=#000000]index[/color] [color=#434f54]=[/color] [color=#000000]1[/color][color=#000000];[/color]
[color=#000000]}[/color]

[color=#434f54]// function definitions[/color]
[color=#00979c]void[/color] [color=#000000]OilTemperature[/color][color=#000000]([/color][color=#000000])[/color] [color=#000000]{[/color]
  [color=#434f54]// ...[/color]
[color=#000000]}[/color]
[color=#00979c]void[/color] [color=#000000]OilPressure[/color][color=#000000]([/color][color=#000000])[/color] [color=#000000]{[/color]
  [color=#434f54]// ...[/color]
[color=#000000]}[/color]
[color=#00979c]void[/color] [color=#000000]OilPressureWarning[/color][color=#000000]([/color][color=#000000])[/color] [color=#000000]{[/color]
  [color=#434f54]// ...[/color]
[color=#000000]}[/color]

If you want to get really fancy, you can even use anonymous functions in an array:

[color=#00979c]typedef[/color] [color=#00979c]void[/color] [color=#000000]([/color][color=#434f54]*[/color][color=#000000]num_func[/color][color=#000000])[/color] [color=#000000]([/color][color=#00979c]void[/color][color=#000000])[/color][color=#000000];[/color]

[color=#000000]num_func[/color] [color=#000000]lambdas[/color][color=#000000][[/color][color=#000000]][/color] [color=#434f54]=[/color] [color=#000000]{[/color]
  [color=#434f54]+[/color][color=#000000][[/color][color=#000000]][/color][color=#000000]{[/color] [b][color=#d35400]Serial[/color][/b][color=#434f54].[/color][color=#d35400]println[/color][color=#000000]([/color][color=#000000]1[/color][color=#000000])[/color][color=#000000];[/color] [color=#000000]}[/color][color=#434f54],[/color]
  [color=#434f54]+[/color][color=#000000][[/color][color=#000000]][/color][color=#000000]{[/color] [b][color=#d35400]Serial[/color][/b][color=#434f54].[/color][color=#d35400]println[/color][color=#000000]([/color][color=#000000]2[/color][color=#000000])[/color][color=#000000];[/color] [color=#000000]}[/color][color=#434f54],[/color]
  [color=#434f54]+[/color][color=#000000][[/color][color=#000000]][/color][color=#000000]{[/color] [b][color=#d35400]Serial[/color][/b][color=#434f54].[/color][color=#d35400]println[/color][color=#000000]([/color][color=#000000]3[/color][color=#000000])[/color][color=#000000];[/color] [color=#000000]}[/color][color=#434f54],[/color]
  [color=#434f54]+[/color][color=#000000][[/color][color=#000000]][/color][color=#000000]{[/color] [b][color=#d35400]Serial[/color][/b][color=#434f54].[/color][color=#d35400]println[/color][color=#000000]([/color][color=#000000]4[/color][color=#000000])[/color][color=#000000];[/color] [color=#000000]}[/color][color=#434f54],[/color]
  [color=#434f54]+[/color][color=#000000][[/color][color=#000000]][/color][color=#000000]{[/color] [b][color=#d35400]Serial[/color][/b][color=#434f54].[/color][color=#d35400]println[/color][color=#000000]([/color][color=#000000]5[/color][color=#000000])[/color][color=#000000];[/color] [color=#000000]}[/color][color=#434f54],[/color]
[color=#000000]}[/color][color=#000000];[/color]

[color=#00979c]void[/color] [color=#5e6d03]setup[/color][color=#000000]([/color][color=#000000])[/color] [color=#000000]{[/color]
  [b][color=#d35400]Serial[/color][/b][color=#434f54].[/color][color=#d35400]begin[/color][color=#000000]([/color][color=#000000]115200[/color][color=#000000])[/color][color=#000000];[/color]
  [color=#5e6d03]while[/color][color=#000000]([/color][color=#434f54]![/color][b][color=#d35400]Serial[/color][/b][color=#000000])[/color][color=#000000];[/color]
  [color=#5e6d03]for[/color] [color=#000000]([/color][color=#00979c]const[/color] [color=#000000]num_func[/color] [color=#434f54]&[/color][color=#000000]f[/color] [color=#434f54]:[/color] [color=#000000]lambdas[/color][color=#000000])[/color]
    [color=#000000]f[/color][color=#000000]([/color][color=#000000])[/color][color=#000000];[/color]
[color=#000000]}[/color]

[color=#00979c]void[/color] [color=#5e6d03]loop[/color][color=#000000]([/color][color=#000000])[/color] [color=#000000]{[/color] [color=#000000]}[/color]

This just prints the numbers 1 through 5, as expected.

However, in your case, I think it would be better to have one function, and just pass different parameters to it, because all of your functions are exactly the same, except for the variables that you use. That's what's called WET programming. We Enjoy Typing, Wasting Everyone's Time or Write Everything Twice, you decide :slight_smile:

Pieter

fall-apart-dave:
Silly question. Where and how do I define "functions"? It isn't a int so where and how is it defined?

You already wrote that part in your original question. I just wrote some code to use the array. Here it is all together:

typedef void (*num_func) ();


void zero();
void one();
void two();
void three();
void four();
void five();
void six();
void seven();
void eight();
void nine();


num_func functions[] = { zero, one, two, three, four, five, six, seven, eight, nine};


void setup()
{
  Serial.begin(19200);
  Serial.println();
}


void loop()
{
  static int index = 3;
  one();
  two();
  functions[index++]();
  if (index > 9)
    index = 3;
}


void zero()
{
  Serial.println(F("zero"));
}
void one()
{
  Serial.println(F("one"));
}
void two()
{
  Serial.println(F("two"));
}
void three()
{
  Serial.println(F("three"));
}
void four()
{
  Serial.println(F("four"));
}
void five()
{
  Serial.println(F("five"));
}
void six()
{
  Serial.println(F("six"));
}
void seven()
{
  Serial.println(F("seven"));
}
void eight()
{
  Serial.println(F("eight"));
}
void nine()
{
  Serial.println(F("nine"));
}

Normally Arduino generates function prototypes so you wouldn't need to explicitly create them but for some reason it isn't working on this code so I left the prototypes in.

Robin2:
You can’t do this

 num_func functions [] = { OilTemperature, OilPressure, OilPressureWarning, BoostPressure, FuelLevel, FuelLevelWarning, FuelPressure, FuelPressureWarning, Lambda, LambdaWarning, BatteryLevel, ChargeWarning};

and this

 functions[index++]();

If I can’t then why is the code working? The code (see previous reply) compiles and runs and produces the expected output.
You can certainly create arrays of function pointers and call the functions they point to.

johnwasser:
You can certainly create arrays of function pointers and call the functions they point to.

Then it seems I did not appreciate that the OP had actually created an array of function pointers. I thought he just had an array of strings.

I had assumed (based on his other questions) that the OP was not likely to be aware of function pointers.

(Behind the ball as usual :slight_smile: )

...R

Thank you very much all!

Code squirted in and compiled.

I see what I did wrong. Thank you very much!