Home Learning How DigitalWrite, DigitalRead, and AnalogRead Work in Arduino

How DigitalWrite, DigitalRead, and AnalogRead Work in Arduino

by shedboy71
[lebox id="1"]

At the heart of nearly every Arduino project are three core functions:

  • digitalWrite()
  • digitalRead()
  • analogRead()

Arduino interacts with the real world by turning pins on and off, reading button states, and measuring sensor values. Even though they seem simple, it’s important to know what they really do behind the scenes in order to write Arduino code that works correctly, quickly, and as expected.

This tutorial explains:

  • What each function does internally
  • How Arduino pins work electrically
  • Common mistakes and misconceptions
  • Many practical code examples
  • Performance and accuracy considerations

Arduino Pins: Digital vs Analog (Clarification)

Before diving into the functions, it’s important to understand Arduino pin types.

Digital Pins

  • Can read HIGH or LOW
  • Voltage-based logic
  • Typically labeled D0D13 (Uno)

Analog Pins

  • Can read variable voltage levels
  • Use an Analog-to-Digital Converter (ADC)
  • Labeled A0A5 (Uno)
  • Can also act as digital pins if needed

digitalWrite(): How Arduino Sets Pin Output

What digitalWrite() Does

digitalWrite() sets a digital output pin to one of two states:

  • HIGH → near 5V (or 3.3V on some boards)
  • LOW → 0V (ground)

This function controls hardware registers inside the microcontroller that physically drive the pin voltage.

Basic digitalWrite() Example

void setup() {
  pinMode(13, OUTPUT);
}

void loop() {
  digitalWrite(13, HIGH);
  delay(1000);
  digitalWrite(13, LOW);
  delay(1000);
}

This toggles the voltage on pin 13.

What Happens Internally

  1. Arduino checks which port the pin belongs to
  2. It sets or clears the appropriate bit in the output register
  3. The pin’s output driver sources or sinks current

This abstraction is slower than direct register access, but far safer and more portable.

digitalWrite() with INPUT Pins (Pull-Up Trick)

void setup() {
  pinMode(2, INPUT);
  digitalWrite(2, HIGH);
}

This enables the internal pull-up resistor.

Equivalent and clearer version:

pinMode(2, INPUT_PULLUP);

digitalWrite() Common Mistakes

Mistake: Forgetting pinMode()

digitalWrite(13, HIGH);  // Undefined behavior if not OUTPUT

Mistake: Driving too much current

digitalWrite(13, HIGH); // Pin cannot power motors or relays directly

digitalRead(): How Arduino Reads Digital Inputs

What digitalRead() Does

digitalRead() reads the logic level on a digital pin:

  • Returns HIGH or LOW
  • Compares pin voltage to internal thresholds

Basic digitalRead() Example

void setup() {
  pinMode(2, INPUT);
  Serial.begin(9600);
}

void loop() {
  int state = digitalRead(2);
  Serial.println(state);
}

Button Example with Pull-Up Resistor

void setup() {
  pinMode(2, INPUT_PULLUP);
  Serial.begin(9600);
}

void loop() {
  if (digitalRead(2) == LOW) {
    Serial.println("Button Pressed");
  }
}

Why LOW? With pull-ups enabled:

  • Button pressed → connects pin to ground
  • Button released → pin pulled HIGH internally

Floating Input Problem

pinMode(2, INPUT);

Without pull-up or pull-down resistors, the pin:

  • Picks up electrical noise
  • Produces random HIGH/LOW readings

Always define input state explicitly.

digitalRead() Timing and Speed

  • Typical execution time: ~4–5 microseconds
  • Fast enough for most applications
  • Not suitable for very high-speed signals

analogRead(): How Arduino Reads Voltages

What analogRead() Does

analogRead() measures a voltage on an analog pin and converts it into a number using the ADC.

On Arduino Uno:

  • ADC resolution: 10-bit
  • Output range: 0–1023
  • Voltage range: 0V–5V (default)

Basic analogRead() Example

void setup() {
  Serial.begin(9600);
}

void loop() {
  int value = analogRead(A0);
  Serial.println(value);
  delay(500);
}

Voltage Mapping

| Voltage | analogRead() Value | | – | | | 0V | 0 | | 2.5V | ~512 | | 5V | 1023 |

Converting analogRead to Voltage

int raw = analogRead(A0);
float voltage = raw * (5.0 / 1023.0);

Serial.println(voltage);

analogRead() Timing

  • Takes ~100 microseconds per read
  • Much slower than digitalRead
  • Important in time-sensitive applications

Changing Analog Reference Voltage

void setup() {
  analogReference(INTERNAL);
}

This improves resolution for low-voltage sensors.

analogRead vs digitalRead

int analogValue = analogRead(A0);
int digitalValue = digitalRead(A0);
  • analogRead() → measures voltage
  • digitalRead() → compares to threshold

Analog pins can be used as digital pins, but not vice versa.

Common Mistakes

Mistake 1: analogRead Produces Analog Values

Wrong. It produces digital numbers representing analog voltages.

Mistake 2: analogWrite Is Analog Output

analogWrite() produces PWM, not true analog voltage.

Mistake 3: digitalRead Is Instantaneous

Reads are fast, but not instantaneous. Electrical noise still matters.

Practical Example: Button Controls LED Brightness

int buttonPin = 2;
int potPin = A0;
int ledPin = 9;

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  if (digitalRead(buttonPin) == LOW) {
    int potValue = analogRead(potPin);
    int pwmValue = map(potValue, 0, 1023, 0, 255);
    analogWrite(ledPin, pwmValue);
  }
}

This example combines:

  • digitalRead() for control
  • analogRead() for measurement
  • analogWrite() for output modulation

Performance Optimization Tips

  • Cache pin states when possible
  • Avoid repeated analogRead in tight loops
  • Use pull-ups to stabilize inputs
  • Prefer INPUT_PULLUP over external resistors when possible

Function Comparison Summary

| Function | Purpose | Speed | Output | | | | | – | | digitalWrite | Set pin state | Fast | HIGH / LOW | | digitalRead | Read pin state | Fast | HIGH / LOW | | analogRead | Measure voltage | Slower | 0–1023 |

Final Thoughts

Function Purpose Speed Output
digitalWrite Set pin state Fast HIGH / LOW
digitalRead Read pin state Fast HIGH / LOW
analogRead Measure voltage Slower 0–1023
  • Avoid unstable behavior
  • Read sensors accurately
  • Design reliable hardware interfaces

Mastery of these three functions is foundational for all Arduino projects, from blinking LEDs to complex embedded systems.

 

Share
[lebox id="2"]

You may also like