source code :
int buttonPin = 8;
boolean buttonState = 0;
void setup()
{
Serial.begin(9600);
pinMode (buttonPin, INPUT);
}
void loop()
{
buttonState = digitalRead(buttonPin);
Serial.println(buttonState);
delay(500);
}
But when, instead of boolean I specify an int data type for buttonState variable it produces the result I want i.e. 1 when pressed and 0 when not pressed. Is it related to the way these variables when stated with different data types give different values to the println() function to convert them into ASCII values?
1 Answer 1
First, you are not supposed to use boolean
with digitalRead.
The function prototype in Arduino.h is:
int digitalRead(uint8_t);
Thus, the correct data type for buttonState
in your code is int
. Then your other problem goes away. What I am guessing is happening is that the version of the IDE you are using does not have an overloaded function for Serial.println
that takes a boolean
argument, and the compiler is casting it to byte
, in which case it would print as 0x00 (LOW) or 0x01 (HIGH) which are not printable characters.
Unfortunately the documentation for digitalRead on the Arduino site does not mention the datatype, it just mentions that it returns HIGH
or LOW
which isn't very helpful to help you work out what data type to use. BTW, neither of those values are, per se, booleans. If they had said it returns true
or false
you might reasonably put the result into a boolean field.
I have tried to get the Arduino developers to improve the documentation in this respect, something they have declined to do. I raised the issue almost 4 years ago, and no-one is even assigned to this particular task.
If you insist on using the boolean type, then a reasonable way of printing would be:
Serial.println(buttonState ? "HIGH" : "LOW");
In response to some comments ...
Works fine for me. – Majenko
...
boolean is a typedef for bool. bool gets promoted to int, not byte - Majenko
What you mean by "is a typedef for bool" is in some (later) versions of the IDE.
Looking at, for example, Arduino pre-release version 0023 I see in the file wiring.h:
typedef uint8_t boolean;
typedef uint8_t byte;
So you can clearly see that boolean and byte are the same, and therefore that using boolean would be treated as byte. Now if you look at the Print class in that release:
class Print
{
private:
void printNumber(unsigned long, uint8_t);
void printFloat(double, uint8_t);
public:
virtual void write(uint8_t) = 0;
virtual void write(const char *str);
virtual void write(const uint8_t *buffer, size_t size);
void print(const String &);
void print(const char[]);
void print(char, int = BYTE);
void print(unsigned char, int = BYTE);
void print(int, int = DEC);
void print(unsigned int, int = DEC);
void print(long, int = DEC);
void print(unsigned long, int = DEC);
void print(double, int = 2);
void println(const String &s);
void println(const char[]);
void println(char, int = BYTE);
void println(unsigned char, int = BYTE);
void println(int, int = DEC);
void println(unsigned int, int = DEC);
void println(long, int = DEC);
void println(unsigned long, int = DEC);
void println(double, int = 2);
void println(void);
};
So you can see that the overload for print
and println
treats an unsigned char (effectively uint8_t
) to be printed with BYTE
default treatment and not DEC
treatment.
BYTE
is declared:
#define BYTE 0
And the writing is done thus:
void Print::print(unsigned long n, int base)
{
if (base == 0) write(n);
else printNumber(n, base);
}
What this boils down to is that both byte
and boolean
will be written as "binary" bytes, not converted into decimal.
As Majenko says, things are different today, and boolean
is now equivalent to bool
which is promoted to int
.
ElectroManiac did not respond to a question about what version of the IDE s/he is using, however my point is that for some versions of the IDE my explanation is true.
Oh, and assigning the return of digitalRead to a bool is perfectly valid ...
Yes, for bool
, but the question was about boolean
. Whilst we know, by reading the code and reading the documentation, that digitalRead will return a 0 or 1, the fact that the return type is int
means that the compiler can potentially see that you are stuffing a 16-bit return value into a 8-bit variable which will possibly lead to data truncation.
I must admit I don't get a warning when compiling with the Arduino IDE, however there is certainly the potential for truncation. A test program written in C++ and compiled with the -Wconversion
flag gives a suitable warning:
warning: conversion to ‘uint8_t {aka unsigned char}’ from ‘int’ may alter its value [-Wconversion]
(There is no warning if you are placing the result into bool
, however that is not the version of the IDE that the OP is using).
-
1aren't HIGH/LOW, true/false or 0/1 the same thing for the micro controller?Like these values are interpreted by the micro controller as the same bit 0 and bit 1.MrDeepThought– MrDeepThought2019年01月01日 06:14:19 +00:00Commented Jan 1, 2019 at 6:14
-
2Depends what you mean by "the same thing". Internally they are. However to the compiler, different types may mean that it calls a different function for printing, particularly when you use overloaded C++ functions, which
println
is an example of.2019年01月01日 06:48:20 +00:00Commented Jan 1, 2019 at 6:48 -
I am unable to get a complete insight into the print() or println() function from the Arduino site.MrDeepThought– MrDeepThought2019年01月01日 07:03:04 +00:00Commented Jan 1, 2019 at 7:03
-
1
boolean
is a typedef forbool
.bool
gets promoted toint
, notbyte
("the type bool can be converted to int with the value false becoming 0 and true becoming 1."). In Gnu Cbool
is a macro giving the internal (GCC specific)_Bool
type, not abyte
. In Gnu C++bool
is a natively supported internal type.Majenko– Majenko2019年01月01日 11:04:16 +00:00Commented Jan 1, 2019 at 11:04 -
2Oh, and assigning the return of
digitalRead
to abool
is perfectly valid, since "The value zero (for integral, floating-point, and unscoped enumeration) and the null pointer and the null pointer-to-member values become false. All other values become true.". And sinceLOW
just happens to be0
andHIGH
1
they map nicely tofalse
andtrue
in abool
.Majenko– Majenko2019年01月01日 11:14:11 +00:00Commented Jan 1, 2019 at 11:14
boolean
,bool
, andbyte
, they all worked correctly. Usingbool
with IDE version 1.0.6.2 and GCC version 4.2.1, increased the binary sketch size by 108 bytes (ouch). Ifboolean
doesn't work for you, try usingbyte
. Both variable types occupy one byte of memory.