【Raspberry Pi 5 × Rust】GPIOでI2C通信
こんにちは!おじテックです。
今回は、Raspberry Pi 5のGPIOを使ってI2C通信をしていきます。本当はPWMを先に試そうとしましたが、手元に電子部品が無く・・・。ラズパイ本体が壊れるリスクを取りたくないので、後回しにしました。
今回も、以前に構築した開発環境を使いますので、環境構築については下記を参照ください。
https://note.com/oji_tech/n/n58425c15f418
早速、I2C通信をやっていきましょう!
I2Cの設定を有効にする
Raspberry Piの設定を開き、インターフェースタブ内にある[I2C]の設定をONにします。
I2Cで使用可能な状態になっているか、ピン情報で確認します。
pinctrl -p
GPIO02(SDA1)とGPIO03(SCL1)が通信用として使えるようになりました。
I2CデバイスとRaspberry Piを繋ぐ
今回は、手元にあった6軸センサ(MPU6050)を使っていきます。使用するピンは上記で調べているので、4本(電源/GND/SCL/SDA)を配線するだけでした。
配線後は、下記コマンドで接続確認を実行。
i2cdetect -y 1
無事接続できているようです。
Rustのプロジェクトを作成
コマンドプロンプトを開き、Rustプロジェクトを格納するフォルダへ移動し、下記コマンドで新規プロジェクト(今回はi2c)を作成します。
cargo new i2c
GPIOを操作するCrate(rppal)を追加
VS CodeのEXPLORER内にある[Cargo.toml]ファイルを開きます。
今回使用するCrateを[dependencies]の下に追加します。
本記事でも"rppal"というcrateのv0.19.0を使っていきます。
https://crates.io/crates/rppal
[dependencies]
rppal = "0.19.0"
コードを作成
上記crate.ioのページにあるサンプルコードを見ながらコードを作成。とりあえず、加速度センサーの値を取得して表示させます。どのアドレスからセンサの値を取得するかは、センサのレジスタマップの仕様書で確認できます。
use rppal::i2c::I2c;
use std::thread::sleep;
use std::time::Duration;
const MPU6050_ADDR: u16 = 0x68;
const PWR_MGMT_1: u8 = 0x6B;
const ACCEL_XOUT_H: u8 = 0x3B;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut i2c = I2c::new()?;
i2c.set_slave_address(MPU6050_ADDR)?;
i2c.smbus_write_byte(PWR_MGMT_1, 0x00)?;
loop {
let accel_x_h = i2c.smbus_read_byte(ACCEL_XOUT_H)?;
let accel_x_l = i2c.smbus_read_byte(ACCEL_XOUT_H + 1)?;
let accel_y_h = i2c.smbus_read_byte(ACCEL_XOUT_H + 2)?;
let accel_y_l = i2c.smbus_read_byte(ACCEL_XOUT_H + 3)?;
let accel_z_h = i2c.smbus_read_byte(ACCEL_XOUT_H + 4)?;
let accel_z_l = i2c.smbus_read_byte(ACCEL_XOUT_H + 5)?;
let accel_x = ((accel_x_h as i16) << 8) | (accel_x_l as i16);
let accel_y = ((accel_y_h as i16) << 8) | (accel_y_l as i16);
let accel_z = ((accel_z_h as i16) << 8) | (accel_z_l as i16);
println!("Accel X: {}, Y: {}, Z: {}", accel_x, accel_y, accel_z);
sleep(Duration::from_millis(100));
}
}
プログラムを実行する
VS Codeでプログラムを実行します。main関数上に出てくる[Run]を押下します。Terminal上で[cargo run]コマンドを入力し実行することも可能です。
無事、加速度センサの値が取得できた模様です。
(おまけ)tauriを使って姿勢を描画してみる
「コンソール上にセンサの値が表示されたところで・・・」と、思ってしまったので、センサの値から適当に姿勢を計算し、リアルタイム描画してみました。RustでGUIアプリを作成するにあたり、tauriを使いました。
Web系のフロントエンドの知識があれば、GUIもサクサク作れそうです。私は全くありませんが(笑)。
ということで、tauriを使って姿勢を描画した結果がこちら!
※座標系は見やすいように勝手に変えています
ブレッドボードを傾けてみると・・・
それっぽい角度を算出し、リアルタイム描画出来ました。動画だと重そうなので、GIFを貼り付けてみました。ただ、サイズをかなり小さくしないとアップロードできませんでした。
まとめ
Raspberry Pi 5のGPIOを使ってI2C通信しました。I2C通信ができると、色々なセンサの値を取得したりできそうで、電子工作の幅が広がりそうですね。
最後までお読みいただき、ありがとうございました!