Global variables in function with arguements

Hi all!

I have been working on a program in which I want to include an off-delay timer.
The off-delay timer has an output that buffers the input, that's kind of basic.
Also I want it to write the remaining time and the endtime as an output variable.

therefore I wrote this little sequence:

 nowMillis= millis();
  
  if (PIROut==HIGH){
   PIRBufferTimeRemaining=PIRBufferSettime;
   PIRBufferEndtime=nowMillis+PIRBufferSettime;
   }
   
  if (PIRBufferEndtime > nowMillis){     
   PIRBufferTimeRemaining= PIRBufferEndtime-nowMillis; 
   PIROutBuffered= HIGH;
   }
  else{
   PIRBufferTimeRemaining=0UL;
   PIROutBuffered=LOW;
   }

This buffers the output of a PIR sensor. It resets the timer every time the output from the PIR is HIGH. When the input is LOW, it compares the current millis() with the endtime() that was written on the last time the input was HIGH. Tested it, and works as it should.

Now since I want to use this function multiple times, so I want it to be callable (don't know if that's even a word) in a way like this:

 PIROutBuffered = offDelay(PIROut, PIRBufferSettime, PIRBufferTimeRemaining, PIRBufferEndtime);

with that in mind, I wrote the following code as a function:

bool offDelay(bool input, unsigned long timeDelayMillis, unsigned long dataRemainingTime, unsigned long dataEndTime){
  
  bool output=LOW;
  nowMillis= millis();
  
  if (input==HIGH){
   dataRemainingTime=timeDelayMillis;
   dataEndTime=nowMillis+timeDelayMillis;
   }
   
  if (dataEndTime > nowMillis){     
   dataRemainingTime= dataEndTime-nowMillis; 
   output= HIGH;
   }
  else{
   dataRemainingTime=0UL;
   output=LOW;
   }
   
  return output;
 }

So having this implemented inside the loop()-function, with the attributes filled in, it seems that my function doesn't accept global/public variables, or can't use or write them.

They are initiated with the following code (above the setup()-function):

//Timers
  //All timervalues are in milliseconds and are unsigned long-datatype. For this reason there is "UL" after every value.
unsigned long PIRBufferSettime=60000UL;
unsigned long PIRBufferTimeRemaining=0UL;
unsigned long PIRBufferEndtime=0UL;
unsigned long nowMillis=0UL;

But when I use this, the output is just a copy of the input, no buffering is present and I don't even see why my output is set to HIGH in the first place.

I'm probably making some horrible mistakes in here, but it would be nice if someone could point out what my mistake is.

I have some very basic knowledge of class-programmed java-things, but my knowledge of coding isn't that great, so please take it easy on me :slight_smile: Also English is not my primary language, so sorry for grammar mistakes etc.

Thanks!

Delta_G:
Are you wanting the values of the global variables to change due to the function? Have a google at something called "call by reference". Right now you are calling by value, so only the value of those globals is being put into the function. All of the operations you do only change these local copies and the actual global variables won't change. If you call by reference then the actual global variable itself gets used in the function and its value can be changed.

Yes, that's exactly what I want to do, I'll have a look at it right away!

If your variables are declared as global, you should not use them as parameters in your function call, and in the function.
If you use parameter variables in your function, they will be considered local to that function only, and their contents will be lost, once you return from the function.

If you still want to use local variables, you must set the global variables to the content of the local variables, before you return from the funtion - if you want to update the globals.

Delta_G:
Or call by reference. That would be the simpler answer wouldn't it?

Delta_G:
It should be added that if this function is to be called with only that one set of variables, then it shouldn't take any parameters at all. You can just use the globals themselves inside the function as they are global.

My answer assumes you will be calling this function with differing sets of variables at different times.

As he wont, if you look at the code.

So that would make for a simpler answer wouldnt it ?

I applied the call-by-reference method by simply adding an "&" before every variable that needs to change trough the function. This solved it, it now works! Thanks Delta_G!

bool offDelay(bool input, unsigned long &timeDelayMillis, unsigned long &dataRemainingTime, unsigned long &dataEndTime){
  
  bool output=LOW;
  nowMillis= millis();
  
  if (input==HIGH){
   dataRemainingTime=timeDelayMillis;
   dataEndTime=nowMillis+timeDelayMillis;
   }
   
  if (dataEndTime > nowMillis){     
   dataRemainingTime= dataEndTime-nowMillis; 
   output= HIGH;
   }
  else{
   dataRemainingTime=0UL;
   output=LOW;
   }
   
  return output;
 }

Anders53:
If your variables are declared as global, you should not use them as parameters in your function call, and in the function.
If you use parameter variables in your function, they will be considered local to that function only, and their contents will be lost, once you return from the function.

If you still want to use local variables, you must set the global variables to the content of the local variables, before you return from the funtion - if you want to update the globals.

I will be using different variables for every time I will recall this function. (ex: a digital output from a sounddetector), so the variable which stores for example the remaining time, that will be : soundBufferRemainingTime, etc. . Since I want to use these variables for things like lighting (ex: lights dim out, linear with the elapsed time) I want them to be global.

In the function I also used local variables : output and nowMillis. They have no need to be used elsewhere in the function.

But I might misunderstand what you're saying?

I will be using different variables for every time I will recall this function. (ex: a digital output from a sounddetector), so the variable which stores for example the remaining time, that will be : soundBufferRemainingTime, etc. . Since I want to use these variables for things like lighting (ex: lights dim out, linear with the elapsed time) I want them to be global.

In the function I also used local variables : output and nowMillis. They have no need to be used elsewhere in the function.

But I might misunderstand what you're saying?

No, you understood me loud and clear, as you are not using the calls I assumed you would.

I just love to read these arrogant British style comments.
They are typical british and makes this forum so stylish to the rest of the world :grin:

Delta_G:
What I was saying is this:

int someInt = 4;

int someOtherInt = 5;

void someFunction(int aParameter){
   // some code for the function
}





If I am only ever going to call someFunction with someInt and never anything else, then I don't need someFunction to take a parameter. I can just use someInt inside the function. It is only if I have need to call someFunction sometimes with someInt and sometimes with someOtherInt that I need the function to take a parameter.

Aah! I see what you mean now! sorry for misunderstanding.

All the parameters the function asks can be different from each other, so they are in my point of view needed.

One time I might use it for a led I want to fade out, which will have a settime about 2 seconds. So the remaining time will be different and so is the endtime, since also the millis() time is progressing.

everytime I will use the function, it will use different variables.

But thanks for the input, it's a good point!