Passing HIGH or LOW to a function

I want to read two buttons in a function call, passing HIGH or LOW to the function.

#define ButtonOnePin 2 //physical pin 4, Atmel PD2/INT0
#define ButtonTwoPin 3 //physical pin 5 ,Atmel PD3/INT1
void setup() {
  pinMode(ButtonOnePin, INPUT_PULLUP);
  pinMode(ButtonTwoPin, INPUT_PULLUP);
}
void loop() {
  controllerStateMachine(digitalRead(ButtonOnePin),digitalRead(ButtonTwoPin));
}
void controllerStateMachine(byte buttonOne, byte buttonTwo) {
  //Create a State Machine for buttons
}

I am not sure what is the best variable type, or type of pointer, to initialize in the function to handle HIGH or LOW.

From Arduino.h:

#define HIGH 0x1
#define LOW  0x0

So, I’d go with something small like unit8_t.

I'd use a bool for things that can be either 1 or 0. It clearly shows your intentions.

boolean, byte and uint8_t are all the same thing, just aliases.

Why worry about such things ? What kind of optimization are you after ? Saving 1½ byte ?
By the way, I like to use 'int' because that is what the digitalRead() returns: https://github.com/arduino/ArduinoCore-avr/blob/b7c607663fecc232e598f2c0acf419ceb0b7078c/cores/arduino/wiring_digital.c#L165.

Now you have: 'byte', 'uint8_t', 'bool', 'boolean' and 'int' to choose from. I hope you can sleep at night worrying about this :astonished:

Why pass the values at all? Declare a couple of globally available "multi purpose" bytes:

#define ButtonOnePin 2 //physical pin 4, Atmel PD2/INT0
#define ButtonTwoPin 3 //physical pin 5 ,Atmel PD3/INT1

byte b1, b2; //Poorly choosen names, I know

void setup() {
  pinMode(ButtonOnePin, INPUT_PULLUP);
  pinMode(ButtonTwoPin, INPUT_PULLUP);
}

void loop() {

  //Following two digitalRead's could be moved to controllerStateMachine()
  //if they are not used for anything else in loop(), do the work where it is
  //required..
  b1 = digitalRead(ButtonOnePin);
  b2 = digitalRead(ButtonTwoPin);
  controllerStateMachine();

  //b1 and b2 are now available for other duties, saves a byte here and there..
}

void controllerStateMachine() {
  //Create a State Machine for buttons
  //Handle b1 and b2 here
}

Danois90:
byte b1, b2; //Poorly choosen names, I know

Not the only one, OP started :wink: At least you used variables instead of macro's :wink:

Koepel:
Why worry about such things ? What kind of optimization are you after ? Saving 1½ byte ?
By the way, I like to use ‘int’ because that is what the digitalRead() returns: ArduinoCore-avr/wiring_digital.c at b7c607663fecc232e598f2c0acf419ceb0b7078c · arduino/ArduinoCore-avr · GitHub.

Now you have: ‘byte’, ‘uint8_t’, ‘bool’, ‘boolean’ and ‘int’ to choose from. I hope you can sleep at night worrying about this :astonished:

Thank you. It may seem like splitting hairs to some. I’m not after optimization or saving a byte, but increasing my fluency of the language.

1 Like

What TYPE of variable function digitalRead() returns?
That is the parameter TYPE you want to declare in your function.

232:
What TYPE of variable function digitalRead() returns?
That is the parameter TYPE you want to declare in your function.

Not necessarily.
The digitalRead function returns an integer, (probably to be beginner-friendly), but the digitalWrite function expects a uint8_t as pin state.

Source

I think it's good practise to use bool for digital pin states, and they are less memory-hungry.

232:
What TYPE of variable function digitalRead() returns?
That is the parameter TYPE you want to declare in your function.

No, IMO you should always use the smallest data type possible. digitalRead basically returns one bit (0 or 1), using a 16 bit int is a waste of at least 8 bits.

Danois90:
No, IMO you should always use the smallest data type possible.

But always be sure to check and double check what "the smallest data type possible" is.
Especially when launching rockets, for example.

PieterP:
Not necessarily.
The digitalRead function returns an integer, (probably to be beginner-friendly), but the digitalWrite function expects a uint8_t as pin state.

Source

I think it's good practise to use bool for digital pin states, and they are less memory-hungry.

Good information.
bool is terribly memory hungry, 7 wasted bits. It's better to set up a struct to store 8 bits in a single address. This has the added benefit that all 8 bits can be read, set or cleared together as well as read, set or cleared independently. Cheers.

byte pins0_7;
const byte button = 4;

void setup()
{
  pinMode(button,INPUT_PULLUP);   
}
void loop()
{
  // the state of pin 4 is stored in 1 bit of byte "pins0_7",
  // can hold the states of 8 pins
  bitWrite(pins0_7,button,digitalRead(button));
}

This thread is getting so weird.

@PieterP is right that the digitalRead() returns an 'int', but the digitalWrite() takes a 'uint8_t' for the HIGH or LOW.

Some use a 'bool' for HIGH and LOW, but they are not 'true' or 'false', therefor I don't like that. Unless it is the status of a button which is defined as "activated" or "not activated", that is a bool.

One thing that is not mentioned yet: code size, casting and compiler optimizations.
When a sketch uses a lot of 'int', then changing some of them into 'byte' might increase the code size, because the compiler has to do more conversions between the types.
Due to compiler optimizations, it is almost unpredictable of the only the code size could increase, the SRAM (both global and stack) usage could increase as well.

Using a struct with bit-fields or functions to handle bits, that will cost more code. More code means more chance for bugs.

Trying to save 1½ byte could cost 20 bytes.
I prefer code that is clear and well organized and shows what is going on.

septillion:
Not the only one, OP started :wink: At least you used variables instead of macro's :wink:

By "macro" do you mean my use of #define to name pin constants instead of variables?
I have learned that as long as my name is unique enough so as not to break a header file, I can save memory because my alias is discarded at the time of compile. Can you elaborate on what pitfalls I am making?

Perehama:
By "macro" do you mean my use of #define to name pin constants instead of variables?
I have learned that as long as my name is unique enough so as not to break a header file, I can save memory because my alias is discarded at the time of compile. Can you elaborate on what pitfalls I am making?

That’s a fallacy.

Whether you do:

#define myButton 4

or

const uint8_t myButton = 4;

That “4” has to be stored SOMEWHERE.

PieterP:
I'd use a bool for things that can be either 1 or 0. It clearly shows your intentions.

boolean, byte and uint8_t are all the same thing, just aliases.

boolean is an alias for bool, which behaves differently from byte and uint8_t. Unlike byte or uint8_t, a boolean/bool can hold only one of two values: false or true (or the equivalents, 0 or 1). If you assign any non-zero value to a boolean/bool, it is set to true (try setting a byte variable to 256, and you'll get 0/false).

(If I remember correctly, Arduino's boolean used to be an alias for byte, but the Arduino devs have since fixed that.)

christop:
boolean is an alias for bool, which behaves differently from byte and uint8_t. Unlike byte or uint8_t, a boolean/bool can hold only one of two values: false or true (or the equivalents, 0 or 1). If you assign any non-zero value to a boolean/bool, it is set to true (try setting a byte variable to 256, and you'll get 0/false).

(If I remember correctly, Arduino's boolean used to be an alias for byte, but the Arduino devs have since fixed that.)

From Reference

A boolean holds one of two values, true or false. (Each boolean variable occupies one byte of memory.)

So were is "true" and "false" declared?

In digital world the binary value is either zero or !zero.
For example if (condition) construct evaluates "condition" as zero or not zero.

All these OT academic discussions / opinions / suggestions do not simplify the coding for beginners.
They just muddy the waters and show lack of basic understanding how fundamental digital coding works.

PS Read my post quickly before it gets deleted.

christop:
(If I remember correctly, Arduino's boolean used to be an alias for byte, but the Arduino devs have since fixed that.)

Correct. My mind must have been in 2015 when I said boolean was an alias for uint8_t. I remember reading discussions on the difference between bool and boolean.

Like you said, they fixed it since:

232:
So were is "true" and "false" declared?

They're defined by the C++ language.

232:
In digital world the binary value is either zero or !zero.
For example if (condition) construct evaluates "condition" as zero or not zero.

That's not in the "digital world"; it's only in languages like C and C++. You can't do that in languages like Java. You can't write if (5) in Java, for example.

232:
All these OT academic discussions / opinions / suggestions do not simplify the coding for beginners.
They just muddy the waters and show lack of basic understanding how fundamental digital coding works.

On the contrary, I believe they illustrate how the "Arduino" (C++) language works at a more detailed level. Nothing you wrote has actually shown that what I wrote is incorrect in any way (perhaps the misunderstanding comes from between your chair and keyboard?).