Rust+RassberyPiPico+DHT11で温度センサー取得

ラズパイ
この記事は約6分で読めます。

Rustで温度センサを取るよ

温度センサー

前回簡単なチュートリアルを動かしました。

Baker link. Devのチュートリアルを参照すればなんとボタンによるトリガーも動かせます

それに関しては本家のチュートリアルを参考してもらうとして今回はたまたまおもちゃ箱の中にあったDHT11という温度センサーを繋いで温湿度を取得していきます。

セットアップ

DHT11に直接接続する場合は抵抗が必要ですが、このボードはすでに接続されているので抵抗は不要です。

上段のRaspberryPiPicoはデバッグプローブ用で、下段がターゲットデバイスになります。
(今回はBaker link. DevではなくRaspberryPi Picoをデバッグプローブとして動かします)

ブレッドボードとワイヤーの関係で空中配線ですが、同等の物です

DHT温度センサーのクレート(ライブラリ)があるので追加します

 cargo add dht-pio --features rp2040

あとはDHT11の接続している端子を指定して初期化してあげるだけでセンサを取得できます

// stdと標準メイン関数を使用しない
#![no_std]
#![no_main]

// 宣言
// デバッグ出力
use defmt::*;
use defmt_rtt as _;
// panicハンドラ(panic発生時にデバッグヒントを出力)
use panic_probe as _;
// Raspberry Pi Picoのハードウェアアクセスライブラリ
use rp2040_hal as hal;

use hal::pac;
use hal::pio::PIOExt;

// 遅延関数
use embedded_hal::{delay::DelayNs, digital::{OutputPin, StatefulOutputPin}};
// デジタル出力
// use embedded_hal::digital::OutputPin;

// ブートローダー宣言
#[link_section = ".boot2"]
#[used]
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER_GENERIC_03H;

// 定数
const XTAL_FREQ_HZ: u32 = 12_000_000u32;

// メインの関数
#[rp2040_hal::entry]
fn main() -> ! {
    info!("Program start!");
    // ペリフェラル(マイコン内蔵機能)の取得
    let mut pac = pac::Peripherals::take().unwrap();
    //  ウォッチドッグの宣言
    let mut watchdog = hal::Watchdog::new(pac.WATCHDOG);

    //  クロックの初期化
    let clocks = hal::clocks::init_clocks_and_plls(
        XTAL_FREQ_HZ,
        pac.XOSC,
        pac.CLOCKS,
        pac.PLL_SYS,
        pac.PLL_USB,
        &mut pac.RESETS,
        &mut watchdog,
    )
    .ok()
    .unwrap();

    //  タイマーの宣言
    let mut timer = rp2040_hal::Timer::new(pac.TIMER, &mut pac.RESETS, &clocks);

    //  SIO(Single-cycle I/O)の宣言
    let sio = hal::Sio::new(pac.SIO);

    //  GPIOの宣言
    let pins = hal::gpio::Pins::new(
        pac.IO_BANK0,
        pac.PADS_BANK0,
        sio.gpio_bank0,
        &mut pac.RESETS,
    );

    // DHT11センサー

    let (dht_pio, dht_sm, ..) = pac.PIO0.split(&mut pac.RESETS);
    let mut dht = dht_pio::Dht11::new(dht_pio, dht_sm, pins.gpio16.into_function(), &clocks);
    let mut led_pin = pins.gpio25.into_push_pull_output();


    info!("DHT11 rp-pico");
    led_pin.set_high().unwrap();

    info!("waiting sensor");
    timer.delay_ms(2000);
    info!("done.");

    loop {
        match dht.read(&mut timer) {
            Ok(res) => {
                info!(
                    "tmp: {}, hum: {}",
                    res.temperature,
                    res.humidity
                );
            }
            Err(_) => {
                error!("DHT error: ");
            }
                
        }
        timer.delay_ms(2000);
        led_pin.toggle().unwrap();
    }
}

他のファイルを含めたソースはこちら

GitHub - zinntikumugai/rasberrypi-pico-dht11-rust
Contribute to zinntikumugai/rasberrypi-pico-dht11-rust development by creating an account on GitHub.

別のクレートの説明では2秒未満で取得するのは良くないようですので適切にタイマーを指定してます。

デバッグモードに入れば温度センサーが取得できているのが確認できました

DHT11に息を吹きかけると温度と湿度が変化します。

ただDHT11自体精度が低い(±5%程度)のでざっくり感覚になってしまいますねー

難しいところ

資料が全然無いのでGPIOの動作モードを変更するところが全然出てきませんでした

誰かまとめておくれー

参考

Raspberry Pi Pico 2の性能を引き出す——Picoprobeでネイティブコード開発に挑戦|fabcross
新連載「Raspberry Pi Picoを始めよう! 週末工作でステップアップ」がスタート。第1回はデバッグプローブPicoprobeを自作して、VSCodeを使ったネイティブコード開発の実例を紹介します。
Rust で Raspberry Pi Pico の組み込み開発 | あしたからがんばる
Rust で RP2040 の組み込み開発を行うためのメモ書きを残しています。
https://crates.io/crates/dht-pio
はんだ付けから始めるEmbedded Rust on Espressif(2)
Raspberry Pi PicoとRustで組み込みプログラム環境を整える
昔は組み込み=Cという感じだったが、2023年現在に、組み込み(ベアメタル)プログラミングを試してみるのであればRust+Raspberry Pi Picoの組み合わせが良いだろう。理由はいろいろあるが、1:クロスコンパイラの導入が楽。Wi...

コメント