【Rust】Raspberry PiとRustでLEDを呼吸するように点滅させる
概要
シンプルなLチカの回路を組みつつRustでLEDの点灯を複雑に制御し、呼吸するようにLEDが滑らかに点滅する処理を組みます。
部品
部品は以下の通りです。
- LEDx1
- 220Ωの抵抗x2
- ジャンパー線x2
回路
構成としてはLEDと抵抗を繋ぎ回路を作るだけのシンプルな構成です。詳細はリンクのページの4.1.3. Circuit
をご確認ください。
コード
cargoで事前にrppal
とctrlc
を追加してください。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側で遊んだ pic.twitter.com/zb7gMyNoqU
— K (@rmc_km) June 9, 2025
まとめ
回路自体は非常にシンプルですが、Rustでコードを工夫することによりシンプルな回路でありながらも複雑な機能を持たせることができます。これがソフトウェアとハードウェアを組み合わせる効果的な例の1つであると思います。回路がシンプルだからこそソフトウェアの効果がわかりやすく制御の学習の題材としても面白みがありますので色々なパターンで点滅させて遊ぶのも良いかもしれません。