> For the complete documentation index, see [llms.txt](https://monasheng.gitbook.io/zerotohero/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://monasheng.gitbook.io/zerotohero/arduino-zero-to-hero/core-skills/input-output-pins/digital-pins/digitalwrite/built-in-led-pin-13.md).

# Built-in LED (Pin 13)

{% embed url="<https://youtu.be/tjGrcDnnrNs>" %}

Most MCUs have a built-in LED-Resistor circuit available for general indication/troubleshooting/debugging. On Arduino platforms, the built-in LED circuit is internally connected to digital `PIN 13`.

<figure><img src="/files/7vGLBdyvBVvQA5TwdLlN" alt=""><figcaption><p>Unlike the power LED (green), which is always ON when the board is powered, the built-in LED (labelled "L", and yellow) on an Arduino is controllable using code.</p></figcaption></figure>

In other words, we can drive the built-in LED the same way we would any other digital pin.

{% hint style="danger" %}
:zap: **Warning:** Because it is connected to an LED circuit, `PIN 13` should be used with care.&#x20;

Some official/first-party Arduino boards work some electrical wizardry to 'protect' the pin from the onboard LED, but clones often omit protection circuits and directly expose the pin.&#x20;

This can lead to [Floating Voltages and Pull-Up/Pull-Down Resistors](/zerotohero/arduino-zero-to-hero/core-skills/input-output-pins/floating-voltages-and-pull-up-pull-down-resistors.md#accidental-voltage-dividers) when using `PIN 13` as an input, or even short circuits!&#x20;

**When using the onboard LED, it is best practice to avoid using** `PIN 13` **if possible.**
{% endhint %}

## Using the onboard LED (Pin 13)

An onboard LED is a surprisingly useful tool for commissioning hardware, testing software, providing a sign-of-life, or fault-finding in your code. Because the onboard LED is directly linked to `PIN 13`, it can be driven with a simple `digitalWrite()` call after initialising:

{% code overflow="wrap" %}

```arduino
void setup() {
  // Set the LED pin as an output.
  // Note that LED_BUILTIN is an arduino default #define for the number 13
  // An equivalent line of code is pinMode(13, OUTPUT);
  
  pinMode(LED_BUILTIN, OUTPUT);
  // Turn the LED on
  digitalWrite(LED_BUILTIN, HIGH);
}

void loop() {

}

```

{% endcode %}

## Typical Uses

### Heartbeat / Sign-of-life

While first-party Arduino boards do have `ON` LEDs that indicate the presence of input power, there may be situations where you are unsure if your code is running correctly, or whether the board has frozen/crashed.

It is reasonably common practice to utilise a 'heartbeat' to provide visual or other feedback that a board is still alive and functioning. Via [Clean Code](/zerotohero/arduino-zero-to-hero/core-skills/clean-code.md#functional-programming) this can be easily added to your main loop without clogging up the codebase or using a `delay()`:

```arduino
// Define a global variable for time since last heartbeat
int lastHeartBeatTime = 0;

void setup() {
  // Set the LED pin as an output
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  // Call the heartBeat function
  heartBeat();
}

void heartBeat() {
  // the millis() function returns the time in ms since boot
  int timeNow = millis();
  // Check if it's been 1000 ms since last beat time
  if ((timeNow - lastHeartBeatTime) >= 1000) {
    // if so, reset lastHeartBeatTime
    lastHeartBeatTime = timeNow;
    // and toggle the state of the LED. The ! is a not (inverse) operator.
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
  }
}
```

### Commissioning Hardware

In addition to using the [Serial Monitor](/zerotohero/arduino-zero-to-hero/core-skills/serial-monitor.md), the onboard LED can also be a good way to verify whether your hardware is wired correctly.

For instance, you might intend to read the state of a button on `PIN 5`. By mirroring the button state on the onboard LED, you can visually inspect the state of the memory:

```arduino
void setup() {
  // Set the LED pin as an output
  pinMode(LED_BUILTIN, OUTPUT);
  // Set the input pin as an input, use the built-in pull-up resistor
  pinMode(5, INPUT_PULLUP);
}

void loop() {
  // Read the state of the input pin
  int buttonState = digitalRead(5);

  // reflect the state of the input pin to the LED
  digitalWrite(LED_BUILTIN, buttonState);
}
```

<figure><img src="/files/F1txp2YqgIWp533Ak4L5" alt=""><figcaption></figcaption></figure>

Note that this intentionally differs from wiring a physical LED into the switch circuit. Had we done that, we could potentially verify that the electronics are functioning as expected (though that is all we could verify). By separately driving the onboard LED using the Arduino, we are also verifying our software.

<figure><img src="/files/dl440owrvZkpEVCvXgTq" alt=""><figcaption></figcaption></figure>

### Fault Finding / Debugging

You might be familiar with using `Serial.print()` statements to help debug your programs. The onboard LED can also be used for this purpose - especially where you might struggle to keep a computer close by. You can hide `digitalWrite()` statements at strategic points in your code to observe a chance in the LED state under a fault.

In these cases, it may be worthwhile initialising the LED in a `HIGH` state, and driving it `LOW` if the code reaches a fault condition, so that you have some positive feedback that the code is operating as expected.

```arduino
void setup() {
  // Set the LED pin as an output
  pinMode(LED_BUILTIN, OUTPUT);
  // Initialize the LED in a HIGH state
  digitalWrite(LED_BUILTIN, HIGH);
  // Begin serial communication at 9600 baud
  Serial.begin(9600);
}

void loop() {
  // Create a random fault condition (for demonstration purposes)
  if (random(0, 10) < 5) {
    // Indicate a fault by turning on the LED
    digitalWrite(LED_BUILTIN, HIGH);
    
    // Print a debug message to the serial monitor
    Serial.println("Fault detected!");
  } else {
    // Reset the LED state
    Serial.println("No Fault");
    digitalWrite(LED_BUILTIN, LOW);
  }
  
 // Add a small delay to make this visible
  delay(500);
}
```
