Scriptone Scriptone

【Rust】Raspberry PiとRustでLEDを呼吸するように点滅させる

概要

シンプルなLチカの回路を組みつつRustでLEDの点灯を複雑に制御し、呼吸するようにLEDが滑らかに点滅する処理を組みます。

部品

部品は以下の通りです。

  • LEDx1
  • 220Ωの抵抗x2
  • ジャンパー線x2

回路

構成としてはLEDと抵抗を繋ぎ回路を作るだけのシンプルな構成です。詳細はリンクのページ4.1.3. Circuitをご確認ください。

コード

cargoで事前にrppalctrlcを追加してください。main.rsに以下を記述してRaspberry Pi向けにクロスコンパイルしてください。

use rppal::gpio::{Gpio, OutputPin};
use rppal::pwm::{Channel, Polarity, Pwm};
use std::error::Error;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::thread;
use std::time::Duration;

const LED_PIN: u8 = 18;
const PWM_FREQUENCY: f64 = 1000.0;

fn main() -> Result<(), Box<dyn Error>> {
    println!("Starting Breathing LED...");
    println!("Press Ctrl+C to quit");

    let running = Arc::new(AtomicBool::new(true));
    let r = running.clone();

    ctrlc::set_handler(move || {
        println!("\nExiting...");
        r.store(false, Ordering::SeqCst);
    })?;

    let gpio = Gpio::new()?;
    let mut led = gpio.get(LED_PIN)?.into_output();

    println!("Starting software PWM on GPIO pin {}", LED_PIN);

    let mut brightness = 0.0;
    let mut increasing = true;
    let step = 0.01;
    let delay = Duration::from_millis(10);

    while running.load(Ordering::SeqCst) {
        led.set_pwm_frequency(PWM_FREQUENCY, brightness)?;

        if increasing {
            brightness += step;
            if brightness >= 1.0 {
                brightness = 1.0;
                increasing = false;
            }
        } else {
            brightness -= step;
            if brightness <= 0.0 {
                brightness = 0.0;
                increasing = true;
            }
        }

        thread::sleep(delay);
    }

    led.clear_pwm()?;
    led.set_low();
    println!("Breathing LED stopped");

    Ok(())
}

明るさを0.00~1.00の間で変動させる仕組みです。初期値は0.0です。1.0になるまで0.01ずつ加算して、明るさが1.00になったら今度はbrightnessを0.01ずつ減算します。0になったらまた加算に切り替わります。これを繰り返し行うことでLEDが呼吸をするようになめらかに点滅します。

動作の様子

まとめ

回路自体は非常にシンプルですが、Rustでコードを工夫することによりシンプルな回路でありながらも複雑な機能を持たせることができます。これがソフトウェアとハードウェアを組み合わせる効果的な例の1つであると思います。回路がシンプルだからこそソフトウェアの効果がわかりやすく制御の学習の題材としても面白みがありますので色々なパターンで点滅させて遊ぶのも良いかもしれません。

関連記事