Digital read problem

Hi all, A little befuddled on the digital read function. It states the return is a high or a low. Does this mean you will get a 5v return for high and 0v for a low if you are using 5v? I was hoping to get a logic 1 or logic 0. Is it possible somehow to get a logic return from digital read as in binary maths rather than decimal? You can then get back to a decimal number by using 1x2^3 or 0x2^3 for instance for 8 in decimal.
It seems like the only way you can get something done with the return is to use something like 'if digital read ==HIGH' or 'if digital read ==LOW'.

I'm trying to figure out what is the issue you are having.

On a Uno 5V is a digital 1 and 0V is a digital 0. Why is this an issue?

You always get a binary result from a digital read. The whole computer runs with binary bit patterns, it is only ever converted into a decimal number when you ask the computer to print it out.

Or just treat the returned value from a digital read as a simple bit. So for example if you wanted to read the binary value repressing a two bit number read off two input pins you could use
Value = digitalRead(4) | ( digitalRead (5) << 1);

The | is a bitwise OR operation
The << is a bitwise shift to the left while the number following it saying how many places to the left you shift.

Or simply assign a variable to a digital read, in that case the variable will only ever be 0 or 1.

1 Like

No worries, you (usually) get the numbers 0 or 1 you want to have. On a Windows computer you might find the file Arduino.h in the directory

  • C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino

where HIGH and LOW are defined like this:

#define HIGH 0x1
#define LOW  0x0

How to understand "true, false, HIGH and LOW" is described here

https://www.arduino.cc/reference/en/language/variables/constants/constants/

Electrical lines are put to a certain potential (voltage) that represents a logical 0 or a logical 1. You only get "in contact" with the voltage if you use analog functions like analogread(), digitalread() and digitalwrite() does already convert the logical data to the corresponding analog voltage and vice versa.

do you mean something like

    int x;
    x  = digitalRead (Pin1) << 2;
    x |= digitalRead (Pin2) << 3;
    

Hi ec2021, So if I enter this at the start of my program every time I do a digital read instead getting a return of HIGH or LOW I will get 0x1 or 0x0. ie logic one or zero.
Would this still work if left out 0x?

Try it.
Experiment..
Please show us some test code if you get confused.

If the input is 5v, the digitalRead will return, binary 1 or true or HIGH, depends on how you want to interpret it.
Likewise with 0V, will return, binary 0 or false or LOW.

Use Serial.print and the IDE serial monitor.

Tom.. :smiley: :+1: :coffee: :australia:
PS, This is compiled code from C++, if you were to look at the pure machine code you would get 1's and 0's.

Yes, there is no difference between a decimal zero and one and a hexadecimal zero and one.
The 0x prefix says I want you to interpret this number as a hexadecimal one. In fact you can miss out those two lines and it would not make any difference.

However there is a difference between 0x10 and just 10. If you print out them both you will see one prints out as 16 and the other as 10.

1. For ATmega328P MCU of UNO Board --
Input voltage range for Logic High: 3.0 V - 5.0 V (IH); defined as HIGH in Arduino IDE
Output voltage range for Logic High: 4.20 V - 5.0 V (VOH); defined as HIGH in Arduino IDE

Input voltage range for Logic Low: 0.0 V - 1.0 V (VIL); defined as LOW in Arduino IDE
Output voltage range for Logic Low: 0.0 V - 0.9 V (VOL); defined as LOW in Arduino IDE

2. Syntax of digital.read() Function as per Arduino Reference Manual:

int pinValue = digital.Read(4); //int data type keeps consistency with ADC value
Serial.print(pinValue); //will show 1 for HIGH or 0 for LOW

3. My understanding is this:
Voltage of DPin-4 is read and then digitized by the internal ADC and then checked that the ADC value is within (1023/5)*3 to (1023/5)*5 (614 to 1023) and then declared it as HIGH and then displayed it as 1 on the Serial Monitor.

Please post a link to this page.

The reference page for digitalRead() says

Returns
HIGH or LOW

It does not say "returns 1 or 0".

As @ec2021 mentioned, HIGH and LOW are currently defined in that file as 0x0 and 0x1, but what if Arduino decide to change those constants in a future version? For example to 0x4 and 0xA? A huge number of previously working Arduino sketches would break, because they were written assuming 0x0 and 0x1. Would Arduino be to blame for that? Could they not defend themselves by referring to the page above?

Arduino is open source, so we can see how HIGH and LOW are defined. Does that mean that anything published as open source can never be changed in case that breaks someone else's code?

See our fellow members’ posts regarding "0x". It might be a good idea to read

https://inst.eecs.berkeley.edu/~cs61bl/r//cur/bits/decimal-binary-hex.html?topic=lab28.topic&step=2&course=

as this information is fundamental for programming.

I second your post. That's why I wrote “(usually)“, but your comment is much more explicit.

@petercl14: As @PaulRB wrote the definitions can change. Therefore it is safer to compare the results of digitalread() against the keywords HIGH and LOW. As LOW will quite surely stay Zero and HIGH different from Zero you could do as follows:

byte MyResult = digitalread(InputPin)/HIGH;

MyResult will be either 0 or 1 regardless of the definition. There would only occur an error if someone would define HIGH as 0 ... which is quite unlikely.

https://www.arduino.cc/reference/en/language/functions/digital-io/digitalread/

That page is for digitalRead(). I was hoping you would post a link to the page for digital.read() where the example code you posted can be found. I was interested to find out more about how the ADC is used by digital.read().

Hi Paul, That was my problem. It does not say returns 1 or 0. The fix is to make the digital read equal to a variable then you get from the variable a 1 for a high and a 0 for a low. Like x=digital read pin9. The answer was from GolamMostafa

What was the problem exactly?

You cannot make digitalRead() equal to a variable. It is a function which returns a value. Did you mean assign the result of the function to a variable? That changes nothing, and cannot have fixed your problem.

I think you should wait until @GolamMostafa gives the answer to my question before you decide who's advice you will take.

I am certainly getting old not only in age but also in memory recall -- how can I write digital.Read() in place of digitalRead()!? Extremely sorry for the inconvenience/discomfort.

"Use of ADC by the digitalRead() function in the background" is my own understanding at conceptual level for mapping the voltage values of Logic High/Low with that of Arduino's HIGH/LOW and then with 1/0.

The problem was to get a logic low 1 and logic high 0 . This could not happen if the return was HIGH or LOW as stated for digital read in the instructions. But if you make the digital read equal to a variable then you get for a HIGH a 1 and for a LOW a 0 in the variable. Sorry assign in the language of Arduino. That is '=' not '=='.

HIGH is defined as 1, and LOW is defined as 0, so most things work as you want them to.

In the old days, these were simple #defines, and digitalWrite() would actually treat anything that evaluated as true to writing a 1, and anyting that evaluated to false as writing a zero.

In newer code, "they" got "politically correct, and made these values part of a pinStatus enum, which is used in multiple places with slightly different meanings, so it now has other possible values of CHANGE, RISING, and FALLING (mostly for use by attachInterrupt(), but SOME boards also allow CHANGE in digitalWrite() to toggle a pin.)
(Note that LOW and HIGH continue to be 0 and 1, respectively.
This was a bad idea, in many people's opinion, and resulted in an "issue" being submitted ( Breakage caused by PinStatus and PinMode types · Issue #25 · arduino/ArduinoCore-API · GitHub ) Unfortunately, the powers that be do not seem inclined to fix this.

That's the "long" version. For the original poster's purposes, "HIGH" is the same a 1, and "LOW" is the same as 0. They are NOT strings, and not random magic values, and you can store them in integer (or byte) variables just fine.