Digital Pin Value


#1

Folks,

Not sure if this should be in another category or not but it relates to code on my Arduino.

Bought an AdaFruit PiR sensor from PiHut for an Arduino project. Downloaded and copied a sketch from Adafruit’s page but something has confused me slightly.

Digital Pins are assigned a value of HIGH or LOW. Is this really 1 or 0?

Reason I ask is that their code does read as HIGH or LOW but in assigning variables to start they assign the key as equaling ZERO

Geoff


#2

Yes, you can even see this right in the ArduinoCore-avr source-

#define HIGH 0x1
#define LOW  0x0

They use hexadecimal notation, but those numbers are still just HIGH = 1 and LOW = 0.

This is because digital IO pins basically abstract away all of the analog nonsense that a digital signal really consists off, and tend to be HIGH when a signal passes a certain threshold and LOW when that signal is below another threshold. These values can be found in the part datasheet, and will say something like HIGH = 0.7VCC and LOW = 0.3VCC.

With 5V power these values might be 5*0.7 = 3.5V and 5*0.3 = 1.5V.

The astute reader will notice that there’s a huge gap between “less than or equal to 0.3VCC” and “greater than or equal to 0.7VCC”. This gap is dubbed “hysteresis” or “undefined” and represents the voltage at which your signal might be HIGH, or might be LOW, but there’s no guarantee.

An interesting aside to this, is that the “3.5V” digital input some devices (like NeoPixels) require at 5V make them quite often work at 3.3V logic because the input pins tend toward reading as HIGH at 3.3V even if there’s absolutely no guarantee this is the case.

The chip on the Arduino UNO - the 328p - (described in great detail here: http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-42735-8-bit-AVR-Microcontroller-ATmega328-328P_Datasheet.pdf) has:

  • Input Low-voltage: -0.5V to 0.3 Vcc
  • Input High-voltage: 0.7 Vcc to Vcc + 0.5

So at 5V that would give a range of -0.5V to 1.5V as “definitely LOW” and a range of “3.5V” to “5.5V” as “definitely HIGH” and everything between >1.5V and <3.5V is “uh, dunno!”.

TLDR: HIGH and LOW are literally drop-in replacements for 1 and 0, they are actually just placeholders that are replaced by a preprocessor which finds tokens like this and replaces them with their literal values before the compiler comes along. Heck you can even do maths with them: 5 * HIGH == 5 :D