Raspberry Pi - Blinking an LED with Rust
Tags: raspberrypi, rust, beginners, tutorial
Published: 2023-09-01 06:14:24

## Prerequisites

- Raspberry Pi (I am using Raspberry Pi 4 Model B)
- LED (8mm, 3.5V, 30mA)
- Resistor (220Ω)
- Breadboard
- Jumper wires (2 MF)

We assume that you have already installed Rust on your Raspberry Pi. If not, you can follow the instructions [here](https://gauravgahlot.in/rust-getting-started/).

<br>

## GPIO Pins

GPIO stands for General Purpose Input/Output. Raspberry Pi has 40 GPIO pins. These pins are used to connect external devices to the Raspberry Pi. These pins can be used as either input or output pins. We will be using these pins to connect our LED to the Raspberry Pi.

| ![GPIO Pins](https://www.raspberrypi.com/documentation/computers/images/GPIO-Pinout-Diagram-2.png) | 
|:--:| 
| Image Source - [Raspberry Pi Documentation](https://www.raspberrypi.com/documentation/computers/raspberry-pi.html) |


The numbers in the above image are the Physical Pin Numbers. Also known as the Board Pin Numbers. The numbers in the image below are the BCM Pin Numbers. Also known as the GPIO Pin Numbers. These numbers are used in the code to refer to the GPIO pins.

| ![BCM Pin Number](https://www.raspberrypi.com/documentation/computers/images/GPIO.png) | 
|:--:| 
| Image Source - [Raspberry Pi Documentation](https://www.raspberrypi.com/documentation/computers/raspberry-pi.html) |

<br>

## The Circuit

The LED that I am using has the following specifications:

- Forward Voltage: 3.5V
- Forward Current: 30mA (0.03A)

One can tap into 3.3V or 5V power provided by the Raspberry Pi pins. Since, the LED requires 3.5V, we will be using the 5V pin. Also, we need a resistor to limit the current flowing through the LED. We can use the following formula to calculate the value of the resistor:

```bash
R = (V - Vf) / I

where,
R = Resistor value in Ohms
V = Voltage of the power source
Vf = Forward Voltage of the LED
I = Forward Current of the LED
```

<br>

The value of the resistor in Ohms will be:

```bash
R = (5 - 3.5) / 0.03
R = 50Ω
```

So, we need at least a 50 ohm resistor. I’ll choose 220 ohms. _The higher the resistor value you use, the dimmer the LED._

Here is the circuit diagram we will be referring:

| ![Circuit Diagram for LED](https://gauravgahlot.in/raspberry-pi-blinking-led-rust/circuit-diagram.jpeg) | 
|:--:|
| Circuit Diagram for LED |

We will be using the BCM Pin 23 (Physical Pin 16) to power the circuit. The power flows through a 220Ω resistor and then through the LED. Note that the longer leg of the LED is connected to the resistor, while the shorter leg of the LED is connected to the ground pin 6 of the Raspberry Pi.

<br>

## The Code

It's time to write the code that will make our LED blink. Create a new Rust project named `led-blinking`:

```bash
cargo new led-blinking
```

Add the following dependency to the `Cargo.toml` file:

```toml
[dependencies]
rppal = "0.14.1"
```

The `rppal` (Raspberry Pi Peripheral Access Library) crate provides access to the Raspberry Pi's GPIO, I2C, PWM, SPI and UART peripherals. You can read more about it [here](https://crates.io/crates/rppal).

<br>

Now, update the `src/main.rs` file with the following code:

```rust
use std::thread;
use std::time::Duration;

use rppal::gpio::Gpio;
use rppal::system::DeviceInfo;

// GPIO uses BCM pin numbering. BCM GPIO 23 is tied to physical pin 16.
const GPIO_LED: u8 = 23;

fn main() {
    println!("Blinking an LED on a {}.", DeviceInfo::new()?.model());
    
    let gpio = Gpio::new().unwrap();
    let mut pin = gpio.get(GPIO_LED).unwrap().into_output();

    loop {
        // Blink the LED by setting the pin's logic level high for a second.
        pin.set_high();
        thread::sleep(Duration::from_millis(1000));
        
        pin.set_low();
        thread::sleep(Duration::from_millis(1000));
    }
}
```

Let’s understand the code. First, we import the `thread` and `time` modules from the standard library. Then, we import the `Gpio` struct from the `rppal::gpio` module. The `Gpio` struct provides access to the GPIO pins. Then, we import the `DeviceInfo` struct from the `rppal::system` module. The `DeviceInfo` struct provides information about the Raspberry Pi device in use.

Next, we create a new instance of the `Gpio` struct. Then, we get the pin 23 using the `get` method. The `get` method returns a `Result<OutputPin, Error>`. We use the `unwrap` method to get the `OutputPin` struct. Then, we convert the `OutputPin` struct into an output pin using the `into_output` method.

Finally, we enter an infinite loop. In each iteration of the loop, we set the pin to high using the `set_high` method. Then, we sleep for a second using the `sleep` method. Then, we set the pin to low using the `set_low` method and sleep for a second again.

<br>

## Build and Run

Now, let’s build the project with `cargo build`:

```bash
led-blinking on master [?] via 🦀 v1.55.0
➜ cargo build
   Compiling libc v0.2.101
   Compiling rppal v0.12.0
   Compiling led-blinking v0.1.0 (/home/gaurav/Projects/led-blinking)
    Finished dev [unoptimized + debuginfo] target(s) in 2.25s
```

Then, let’s run the project with `cargo run`:

```bash
led-blinking on master [?] via 🦀 v1.55.0
➜ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.00s
     Running `target/debug/led-blinking`
```

You should see the LED blinking. If you want to stop the program, press `Ctrl + C`.

| ![Glowing LED](https://gauravgahlot.in/raspberry-pi-blinking-led-rust/glowing-led.jpeg) | 
|:--:|
| Glowing LED |

<br>

## Conclusion

In this blog post, we learned how to blink an LED with Rust on Raspberry Pi. We also learned how to calculate the value of the resistor required to limit the current flowing through the LED. If you have any questions or suggestions, feel free to drop a comment. A few useful links are given below:

- [Raspberry Pi Documentation](https://www.raspberrypi.com/documentation/computers/raspberry-pi.html)
- [RPPAL](https://crates.io/crates/rppal)
- [RPPAL Documentation](https://docs.rs/rppal/0.14.1/rppal/)

Thanks for reading, see you in the next one!