Passing a function with arguments

I need to pass a function with its variables to the simple timer library and i keep getting errors about passing a void function. when I set it to int only the return value is passed and then the loop doesn’t work.

Snippet of the example.

void activateAlarm(int alarmNumber, bool startup){ 
    if(!startup){
        if(stateAlarm[alarmNumber]){//Reset Alarm
            if(triggerAlarm){//If the alarms are active
                digitalWrite(alarmPins[alarmNumber], LOW);
            }
            timer.setTimeout(randomize(meanDeactivateAlarm), activateAlarm(alarmNumber, false));
            stateAlarm[alarmNumber] = false;
            Serial.println("Alarm Off" + word(alarmNumber));
        }
        else{//Trigger alarm
            if(triggerAlarm){//If the alarms are active
                digitalWrite(alarmPins[0], HIGH);
            }
            timer.setTimeout(randomize(meanActivateAlarm), activateAlarm(alarmNumber, false));
            stateAlarm[alarmNumber] = true;
            Serial.println("Alarm On" + word(alarmNumber));
        }
    }
    else{ //Initiate Startup
        //Serial.println("Starting Alarm" + word(alarmNumber));
        digitalWrite(alarmPins[alarmNumber], HIGH);
        timer.setTimeout(randomize(10), activateAlarm(alarmNumber, false));
        stateAlarm[alarmNumber] = true;
    }
}

full code

#include <SimpleTimer.h>
//Declare Switch pins
const int randomSwitchPin = 2;
const int alarmSwitchPin = 3;
const int tamperSwitchPin = 4;
const int troubleSwitchPin = 5;
//Declare Mean Time
const unsigned long meanActivateAlarm = 1000;
const unsigned long meanActivateTamper = 1000;
const unsigned long meanActivateTrouble = 1000;
const unsigned long meanDeactivateAlarm = 1000;
const unsigned long meanDeactivateTamper = 1000;
const unsigned long meanDeactivateTrouble = 1000;

bool constantTime = false; //False for randomized times, True for static times. tied to switch
bool triggerAlarm = true; //Tied to switch, specifies whether or not to tigger the alarm signals
bool triggerTamper = true; //Tied to switch, specifies whether or not to tigger the tamper signals
bool triggerTrouble = true; //Tied to switch, specifies whether or not to tigger the trouble signals

int alarmPins[] = {22,25,28,31,34,37,40,43,46,49}; //Pin definitions for the alarm signal. First is alarm 1, second alarm 2, etc..
int tamperPins[] = {23,26,29,32,35,38,41,44,47,50}; //Pin definitions for the tamper signal. First is alarm 1, second alarm 2, etc.. 
int troublePins[] = {24,27,30,33,36,39,42,45,48,51};  //Pin definitions for the trouble signal. First is alarm 1, second alarm 2, etc..
int numberOfSets = 10;
bool stateAlarm[10], stateTamper[10], stateTrouble[10]; //Declare Alarm State Trackers 
SimpleTimer timer;

void setup(){
    Serial.begin(9600);
    Serial.println("Hello World");
    for(int i=0; i < numberOfSets; i++){ //Declare all alarm pins and Startup system
        pinMode(alarmPins[i],OUTPUT);
       activateAlarm(i,true);
    }
    for(int i=0; i < numberOfSets; i++){ //Declare all a tamper pins and Startup system
        pinMode(tamperPins[i],OUTPUT);
        activateTamper(i,true);
    }
    for(int i=0; i < numberOfSets; i++){ //Declare all trouble pins and Startup system
        pinMode(troublePins[i],OUTPUT);
        activateTrouble(i,true);
    }

    //Declare Switch pins
    pinMode(alarmSwitchPin,INPUT_PULLUP);
    pinMode(tamperSwitchPin, INPUT_PULLUP);
    pinMode(troubleSwitchPin, INPUT_PULLUP);
    pinMode(randomSwitchPin, INPUT_PULLUP);

    randomSeed(analogRead(0)); //Seed random number generator
    srand(random(2000000000));
    Serial.println("Startup Finished");
}
void loop(){ 
    triggerAlarm = !digitalRead(alarmSwitchPin);
    triggerTamper = !digitalRead(tamperSwitchPin);
    triggerTrouble = !digitalRead(troubleSwitchPin);
    constantTime = !digitalRead(randomSwitchPin);
    timer.run();//run the timer
}
void activateAlarm(int alarmNumber, bool startup){ 
    if(!startup){
        if(stateAlarm[alarmNumber]){//Reset Alarm
            if(triggerAlarm){//If the alarms are active
                digitalWrite(alarmPins[alarmNumber], LOW);
            }
            timer.setTimeout(randomize(meanDeactivateAlarm), *activateAlarm(alarmNumber, false));
            stateAlarm[alarmNumber] = false;
            Serial.println("Alarm Off" + word(alarmNumber));
        }
        else{//Trigger alarm
            if(triggerAlarm){//If the alarms are active
                digitalWrite(alarmPins[0], HIGH);
            }
            timer.setTimeout(randomize(meanActivateAlarm), *activateAlarm(alarmNumber, false));
            stateAlarm[alarmNumber] = true;
            Serial.println("Alarm On" + word(alarmNumber));
        }
    }
    else{ //Initiate Startup
        //Serial.println("Starting Alarm" + word(alarmNumber));
        digitalWrite(alarmPins[alarmNumber], HIGH);
        timer.setTimeout(randomize(10), *activateAlarm(alarmNumber, false));
        stateAlarm[alarmNumber] = true;
    }
}
void activateTamper(int tamperNumber, bool startup){ 
    if(!startup){
        if(stateTamper[tamperNumber]){//Reset Tamper
            if(triggerTamper){//If the alarms are active
                digitalWrite(tamperPins[tamperNumber], LOW);
            }
            timer.setTimeout(randomize(meanDeactivateTamper), activateTamper(tamperNumber, false));
            stateTamper[tamperNumber] = false;
        }
        else{//Trigger Tamper
            if(triggerTamper){//If the alarms are active
                digitalWrite(tamperPins[tamperNumber], HIGH);
            }
            timer.setTimeout(randomize(meanActivateTamper), activateTamper(tamperNumber, false));
            stateTamper[tamperNumber] = true;
        }
    }
    else{ //Initiate Startup
        digitalWrite(tamperPins[tamperNumber], HIGH);
        timer.setTimeout(randomize(10), activateTamper(tamperNumber, false));
        stateTamper[tamperNumber] = true;
    }
}
void activateTrouble(int troubleNumber, bool startup){ 
    if(!startup){
        if(stateTrouble[troubleNumber]){//Reset Trouble
            if(triggerTrouble){//If the troubles are active
                digitalWrite(troublePins[troubleNumber], LOW);
            }
            timer.setTimeout(randomize(meanDeactivateTrouble), activateTrouble(troubleNumber, false));
            stateTrouble[troubleNumber] = false;
        }
        else{//Trigger trouble
            digitalWrite(troublePins[troubleNumber], HIGH);
            timer.setTimeout(randomize(meanActivateTrouble), activateTrouble(troubleNumber, false));
            stateTrouble[troubleNumber] = true;
        }
    }
    else{ //Initiate Startup
        digitalWrite(troublePins[troubleNumber], HIGH);
        timer.setTimeout(randomize(10), activateTrouble(troubleNumber, false));
        stateTrouble[troubleNumber] = true;
    }
}
unsigned long randomize(unsigned long mean){
  if(constantTime == false && mean != 1000){
    double U = (double) ((double) rand()/ (double) RAND_MAX);
    unsigned long randomVariable = -1*log(U)*mean;
    //if(randomVariable < 11000){
      //Serial.print(randomVariable);
      //randomVariable = randomize(mean);
    //}
    return randomVariable;
    }
  else{
    return mean;
  }
}

The timer library expects a pointer to a function to call. It doesn't have any space to remember what values to send to that function. So it must be a function without arguments.

Those arguments must be stored some other way. Maybe the arguments are global?

Hold on, you create a function and the first thing you do is call it from inside itself ? that is not a good plan

void activateAlarm(int alarmNumber, bool startup){ 
            activateAlarm(alarmNumber, false);
    if(!startup){

I would remove the call to itself.

The type of function you can pass into timer.setTimeout() is a void function containing no arguments. You do that by specifying the function name without the parenthesis. You may have to rethink your design...

But is there any way to wrap that function in a void function?

void activateAlarm() {
  activateAlarm(globalAlarmNumber, false);
}

MorganS:

void activateAlarm() {

activateAlarm(globalAlarmNumber, false);
}

Unfortunately, that won't work because you can't declare a function within a function. 10 instances of each activation type are created base off of the one function and I didn't want to have to create 10 copies of the function. Each copy is controlling a relay setup on an external board for a total of 30 relays

CamoJackson:
Unfortunately, that won't work because you can't declare a function within a function. 10 instances of each activation type are created base off of the one function and I didn't want to have to create 10 copies of the function.

That's calling a function, not declaring a function.
That's allowed (Thank goodness!)

@Deva_Rishi whoops that was a miss type and isn't meant to be there

AWOL:
That's calling a function, not declaring a function.
That's allowed (Thank goodness!)

I need a void function with no arguments to pass to the SimpleTimer library. The way I have it in the code has the wrong type in it and that needs to change. I need to make a wrapper for the function that I can change. There are 10 instances that call back to that function that are running asynchronously, each passing in the relay pin number it is responsible for. I did not want to have to make 10 copy of the function for each alarm and hard code which one was which.

Yes you have to make 10 copies of the function. But you can use arrays to make it easier.

Or think of some other method. Maybe you need 10 timers?