はじめに
手元にあったMPU6050(ジャイロ、加速度センサ)をNervesでコントロールして値の読み取りを行ってみました。
MPU6050とは
X-Y-Z軸それぞれの角速度を測定するジャイロセンサと、X-Y-Z軸方向の加速度センサーを持っています。I2CとSPI接続が可能です。
今回は、I2Cで接続して測定データの読み取りを行ってみました。
データの取り込み方法
基本的には次の方法で読み取りを行います。
- MPU6050のレジスタにサンプリング周期、やどの値を取得するかを設定する
- 計測されて新しい値がレジスターにセットされると割り込みが発生する
- 計測結果のレジスターの値を読み取る
I2C
I2Cの読み書きはCircuits.I2Cを使います。
Elixirでi2Cの通信を行う場合、Circuits.I2C一択だとおもいます。詳細はドキュメントや他の記事を参照してください。
実装方法
Circuits.I2Cには指定したPINの値が変化した時(立ち上がり、立下り、両方のどれか指定できる)にメッセージを送信する機能があります。
GenServerと組み合わせる事で、割り込みがあったら、GenserverのHandle関数を呼び出して、データの取り込みを行うという実装がよさそうです。
この方針で実装してみます。
defmodule InterruptHandler do
use GenServer
alias Circuits.GPIO
@interrupt_pin 4
def start_link() do
GenServer.start_link(__MODULE__, %{}, name: __MODULE__)
end
def init(_state) do
mpu = Mpu6050Lib.new()
{:ok, gpio} = GPIO.open(@interrupt_pin, :input)
Mpu6050Lib.initialize(mpu, 1, 6)
# GPIOピンの変化を監視し、メッセージとして受け取るように設定
GPIO.set_interrupts(gpio, :rising)
time = System.system_time(:microsecond)
Mpu6050Lib.clear_interrupt(mpu)
{:ok, %{gpio: gpio, mpu: mpu, log: [], log_size: 0, start_time: time}}
end
def handle_info({:circuits_gpio, _pin, _timestamp, _value}, state) do
# データの取り込み処理を行う
acc = Mpu6050Lib.get_acc(state.mpu)
gyro = Mpu6050Lib.get_gyro(state.mpu)
time = System.system_time(:microsecond) - state.start_time
# データの保存(最初の10000件を保存する)
new_state =
cond do
state.log_size < 10000 ->
%{state | log: [[acc, gyro, time] |state.log] , log_size: state.log_size + 1}
true ->
state
end
{:noreply, new_state}
end
end
動作確認
MPU605を500サンプリング/秒(2ms間隔)で測定をする設定にします。
割り込み信号(CH1)は、測定が完了するとが1となり、データの読み取りを開始すると0になります。
想定通り、2msごとにデータの取り込みができていました。
CH1の割り込み発生(1になる)
↓
加速度と角速度の読み取り(それぞれ6byte)を読み取る
↓
2msの間に完了。取りこぼしなくデータを取得できています。
割り込み処理の考察
CH1が1になっている時間が、割り込みが発生してからデータの取り込みを開始するまでの遅延時間となります。この時間は約610usでした。
この測定した範囲でもMax 600us Min 600usでぶれもなく割り込み処理ができている様です。
細かい条件が異なるので一概には比較できないかもしれませんが、Pythonでは、ここまで一定した時間ではなかったです。
この安定した値になるとは、驚きました。
Elixirでは、GILが無い事もこの原因かもしれません。
まとめ
- GenServerを使い、500サンプリング/秒で安定したデータの取り込みができる事を確認できた
- C言語で書いた場合の遅延には及びませんが、毎秒100回くらいの処理だったら余裕をもってできそう
- リアルタイムOSに求められるような性能は無理だが、安定した処理ができそう
- 通信やファイル保存等を同時に行った場合の影響についても今後確認してみたい