ラズピコでRust(17) 温度・湿度・気圧を計測して保存する

  • 2024.10.27
  • HAL
ラズピコでRust(17) 温度・湿度・気圧を計測して保存する

皆さん こんにちは。
ポンコツRustacean の moon です。

今回は、これまでにご紹介して来た記事の内容をまとめてみます。

BME280センサーから温度・湿度・気圧を計測してLCDに表示し、1分間隔でこれらの値をSDカードに保存します。
ここまで動かすことができると、ものをつくった実感が湧いてきますのでぜひチャレンジしてください。

この記事は開発環境を構築することを前提にしています。
環境構築について知りたい方は こちらの記事 をご覧になってください。

このサイトは 書籍 基礎から学ぶ組込みRust を参考にしています。

ブロック図・回路図

Raspberry Pi Pico といくつかのモジュールを組み合わせていきます。

ブロック図を以下に示します。

回路図を以下に示します。

(注)デバッガーの部分は省略しています。

この回路が動作するRustのコードも公開します。

使っているモジュール等のご紹介

今回のプロジェクトで使っている主なモジュールを掲載しておきます。

ラズペリーパイ ピコ

BME280温度・湿度・気圧センサーモジュール

SDカード配線引出基板

RTCモジュール

LCDモジュール白色バックライト付

ジョイスティック

ブロッキング処理

私がこれまで書いてきたRustのコードは全てブロッキングI/O処理です。

ブロッキングI/O処理に対して、ノンブロッキングI/O処理と非同期I/O処理があります。

ブロッキングI/O処理は関数を呼び出すと、その処理が終わるまで関数から戻ってきません。
ノンブロッキングI/O処理は処理が終わるまでエラーを返します。

非同期I/O処理は、処理が終わる前でもすぐに関数から戻ってきます。
その完了をポーリングで確認するかコールバック関数で処理します。

ブロッキングI/O処理は、その間他の仕事ができないというデメリットがありますが、処理が簡単ですから初心者向きであると言えます。
まずはブロッキングI/O処理でRustのコードに慣れていくのが良いのではないでしょうか。

ペリフェラル

ラズピコのマイコンであるRP2040には以下のペリフェラルがあります。

・UART * 2
・SPI * 2
・I2C * 2

このうちの SPI 2系統はセンサーモジュールとSDカードに使っています。
それから I2C 1系統を RTCに使っています。
UART 1系統は println() の出力に使っています。

LCDには GPIO出力を、ジョイスティックの読み込みにはGPIO入力を使っています。

コードの概要

embedded-hal

今回のコードは embedded-hal Ver1.0 に対応しています。
UARTは embedded-io を使っています。

このクレートのトレイトに合わせて各マイコンのペリフェラルのHALも実装されるようです。
HALが対応していなければ、古いバージョンのもので我慢するしかないようです。

embedded-hal のトレイトのメソッドが HAL に実装されているか確認しながらコーディングしました。

全てのコードは(非同期I/Oではなく)ブロッキングI/Oで処理しています。

スイッチの読み込み

ジョイスティックには5ビットのスイッチが内蔵されています。
5つのGPIO入力を使って、これらが押されたかどうかを割り込みで検出しています。

グローバル変数を使っていますが、Mutexは使っていません。
処理自体がアトミックなので、その必要はないからです。
unsafe なコードになりますが、それは仕方ないですね。

温度・湿度・気圧センサー

モジュールは SPI / I2C いずれかのインターフェースを使うことができますが、今回はSPIを使いました。
校正値とデータをレジスタから読み込み、温度・湿度・気圧の値に変換します。

bme280\spi.rs が SPI インターフェースのコードになります。

I2Cでも動作確認済です。

bme280\i2c.rs が I2C インターフェースのコードになります。
main.rs で適切な初期化をすればこちらでも動作します。

レジスタに必要な値を書く初期化処理を終えた後は、キャリブレーションするための値とデータを読み出して変換します。

BME280に関する非同期I/Oのクレートがあったのですが、こちらではブロッキングI/O処理に統一したかったので、C言語のサンプルコードを見ながらRustのコードに変換しました。

と言うか非同期I/Oのコードを書けない(汗)

LCD

cretes.io にhd44780-driverという外部クレートがあったので、それを使わせて頂きました。
ジョイスティックのスイッチを上下に操作して、

1.Display elements
2.Set Date Time

のいずれかを選択して、スイッチを押します。

1番は計測した温度、湿度、気圧の値を表示します。
2番はRTCの日時を変更します。

日時変更:

スイッチを左右に押すことで日時の桁を移動します。
スイッチを上下に押すことで値を変更します。

一番左までいくと、日時変更画面をぬけてメインメニューに戻ります。
設定完了後、スイッチを押すと設定値をRTCに書き込みます。

RTC

外部クレートが見当たらなかったので、データシートを見ながら必要な機能だけコーディングしました。
rtc8564.rs がそのコードです。
電池でバックアップしているので、電源オフ時にも計時します。

SDカード

FATの実装がうまくいっていないので、ディレクトリをつくることができていません。
1分毎に、温度・湿度・気圧の値をSDカードに保存します。

以下のように保存されれば成功です。

2024/10/27 12:05 T: 26.5, H: 70.4, P: 1013.9
2024/10/27 12:06 T: 26.5, H: 71.0, P: 1013.8
2024/10/27 12:07 T: 26.5, H: 70.9, P: 1013.8

ソースコード

GitHubの rp2040-ehv1-spi-bme280 にプロジェクトをアップしましたので参考になさってください。

皆さんも組み込みRustを楽しんで頂ければ嬉しいです。
お疲れさまでした。

HALカテゴリの最新記事