見出し画像

【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にします。

Raspberry Piの設定

I2Cで使用可能な状態になっているか、ピン情報で確認します。

pinctrl -p

GPIO02(SDA1)とGPIO03(SCL1)が通信用として使えるようになりました。

pinctrl 結果


I2CデバイスとRaspberry Piを繋ぐ

今回は、手元にあった6軸センサ(MPU6050)を使っていきます。使用するピンは上記で調べているので、4本(電源/GND/SCL/SDA)を配線するだけでした。

6軸センサ

配線後は、下記コマンドで接続確認を実行。

i2cdetect -y 1

無事接続できているようです。

ic2detect 実行結果


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通信ができると、色々なセンサの値を取得したりできそうで、電子工作の幅が広がりそうですね。

最後までお読みいただき、ありがとうございました!


この記事が気に入ったらサポートをしてみませんか?