how to properly create a "returning" non-void function

Hi to everyone,
I have in mind a project for a light controller, I’ve already made a functional code for controlling a relay based on the hour of the day

void checkLights() {
  int t = hour();
  if (Lights[1] > Lights [0]) {
    if ((t >= Lights[1]) || (t < Lights[0])) {
      digitalWrite(relay1, HIGH);
    }
    else {
      digitalWrite(relay1, LOW);
    }
  }
  else if (Lights[1] < Lights [0]) {
    if ((t >= Lights[1]) && (t < Lights[0])) {
      digitalWrite(relay1, HIGH);
    }
    else {
      digitalWrite(relay1, LOW);
    }
  }
  else if (Lights[1] == Lights [0]) {
    digitalWrite(relay1, HIGH);
  }
}

The recall for the function is inside the void loop, and everything works fine.
The problem is, I want to have the possibility to swap the results and i thought to use a function that will give me a HIGH or LOW value based on the same code, and then inside the void loop i’ll just put a digitalwrite like this:

void loop() {
digitalWrite (relay1, checkLights);
}

int checkLights() {
  int t = hour();
  if (Lights[1] > Lights [0]) {
    if ((t >= Lights[1]) || (t < Lights[0])) {
      return HIGH;
    }
    else {
      return LOW;
    }
  }
  else if (Lights[1] < Lights [0]) {
    if ((t >= Lights[1]) && (t < Lights[0])) {
      return HIGH;
    }
    else {
      return LOW;
    }
  }
  else if (Lights[1] == Lights [0]) {
    return LOW;
  }
}

not considering the reverse thing by now, I just want that checkLights will return me HIGH or LOW for now, why is this not responding? the code still compiles, but the digitalwrite is dead, why? :confused:

I’ve started to use a lot of void functions, they’re great, but when it comes to returning, I’ve never done it, so I only have the reference site. Thanks to any who will respond :slight_smile:

Something like this ?

int sumOfTwoNumbers(int numA, int numB) {
   int myResult = numA + numB;
   return myResult;
}

and then you would call it like this

int myAnswer = sumOfTwoNumbers(12, 23);

...R

digitalWrite (relay1, checkLights);

should be

digitalWrite (relay1, checkLights());

and the checkLights() function should more properly return a byte rather than an int

ehh… how about

void loop() {
digitalWrite (relay1, checkLights());  // dont forget about the braces !!
}

bool checkLights() {  // probably works as an int but it isn't.
  int t = hour();
  etc...

UKHeliBob: digitalWrite (relay1, checkLights);

should be

digitalWrite (relay1, checkLights());

and the checkLights() function should more properly return a byte rather than an int

this worked! thanks. I wonder why it was still compiling without the parenthesis

I wonder why it was still compiling without the parenthesis

because, syntactically, there was nothing wrong with what you wrote, but would always evaluate to HIGH.

void setup ()
{}
void loop ()
{
  42;
}

will also compile

simone91perale: this worked! thanks. I wonder why it was still compiling without the parenthesis

Perhaps you didn't enable compiler warnings and/or didn't look at them? They are well worth always checking out.

When you use a function name without its associated parentheses, the expression resolves to the memory address (lvalue) of where that function resides in memory. In other words, a lone function name resolves to pointer to function. My guess is that your code would always interpret the function pointer as what you thought was a value of HIGH.

econjack: When you use a function name without its associated parentheses, the expression resolves to the memory address (lvalue) of where that function resides in memory. In other words, a lone function name resolves to pointer to function. My guess is that your code would always interpret the function pointer as what you thought was a value of HIGH.

that's precisely what was happening, always HIGH :D now everything works like a charm

TURN UP YOUR WARNINGS!

If you set Preferences->Compiler warnings: [ALL] you will see that some stuff compiles even though the compiler thinks you made a mistake. For example:

void setup() {pinMode(2, OUTPUT);}
void loop() {digitalWrite(2, setup);}

This gets you:

/Users/john/Documents/Arduino/sketch_dec06a/sketch_dec06a.ino: In function 'void loop()':
/Users/john/Documents/Arduino/sketch_dec06a/sketch_dec06a.ino:2:35: warning: invalid conversion from 'void (*)()' to 'uint8_t {aka unsigned char}' [-fpermissive]
 void loop() {digitalWrite(2, setup);}
                                   ^
In file included from sketch/sketch_dec06a.ino.cpp:1:0:
/Applications/Arduino 1.8.7.app/Contents/Java/hardware/arduino/avr/cores/arduino/Arduino.h:134:6: note:   initializing argument 2 of 'void digitalWrite(uint8_t, uint8_t)'
 void digitalWrite(uint8_t, uint8_t);
      ^
Sketch uses 752 bytes (2%) of program storage space. Maximum is 32256 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. Maximum is 2048 bytes.

If you get the syntax right to call the function instead of using the address of the function as data:

void setup() {pinMode(2, OUTPUT);}
void loop() {digitalWrite(2, setup());}

You then get told that the code you 'fixed' won't compile because you can't use the 'void' value returned by that function as data:

/Users/john/Documents/Arduino/sketch_dec06a/sketch_dec06a.ino: In function 'void loop()':
sketch_dec06a:2:37: error: invalid use of void expression
 void loop() {digitalWrite(2, setup());}
                                     ^
exit status 1
invalid use of void expression