ブログ

Armadillo-440:3軸加速度センサー(MMA8452Q)から取得した加速度をGTKでLCDに表示するサンプルプログラム

at_kazutaka.bito
2016年5月4日 10時12分

Armadillo-440からNXPの3軸加速度センサーMMA8452Qの加速度を取得して、 下の写真のようにGTKでLCDに表示するサンプルプログラムを作成してみました。
・加速度に応じて、赤丸が疑似3D風の座標でリアルタイム(といっても50ms毎)に動きます。

・50ms毎に取得した加速度を1秒毎にグラフ表示します。

動作確認の手順とサンプルプログラムについて下記に説明します。

補足)
サンプルプログラムは、Armadillo-440のLinux-3.14版で動作確認しました。

●1.機材

機材は下記のものを使用しました。
・Armadillo-440開発セット
LFSTBEB845X(MMA845X開発ボード)に含まれるMMA8452Qモジュールに周辺部品を追加したもの
(周辺部品を含めた回路は、MMA8452Qデータシートのアプリケーション図を参考にしました。)

●2.Armadillo-440とMMA8452Qの接続

Armadillo-440とMMA8452Qとの通信はI2Cで行います。
ここでは、Armadillo-440のCON14のI2C(3pin:SCL、4pin:SDA)に、MMA8452QのI2C端子(4pin:SCL、6pin:SDA)を接続しました。

補足)
Armadillo-440のCON14のI2Cは、標準のカーネルで"/dev/i2c-1"というデバイスファイル名になっています。
CON14のI2C以外のI2Cを使用する場合、下記説明内のデバイスファイル"/dev/i2c-1"の箇所は、該当するデバイスファイル名に読み替える必要があります。

●3.MMA8452Qから加速度を取得して、GTKでLCDに表示するサンプルプログラム

MMA8452Qから加速度を取得して、GTKでLCDに表示するサンプルプログラムを添付します。
acc_mma8452_gtk.tar.gz

<サンプルプログラムの用法>
添付のサンプルプログラムをATDE上に解凍して、acc_mma8452_gtkディレクトリ内でmakeすると、acc_mma8452_gtkという実行ファイルができます。

この実行ファイルをArmadillo-440に置いて、下記のように実行権限をつけて実行します。
(下記は、acc_mma8452_gtkを/rootディレクトリに置いた場合)

[root@armadillo440-0 (ttymxc1) ~]# chmod +x acc_mma8452_gtk
[root@armadillo440-0 (ttymxc1) ~]# GDK_NATIVE_WINDOWS=true DISPLAY=:0 /root/acc_mma8452_gtk

実行すると、
 LCDの表示を切り替えるボタン(Acceleration(R)、Acceleration(G))
 加速度に応じて、赤丸が疑似3D風の座標でリアルタイムに動く表示
が表示されます。
 Acceleration(R)ボタンで、加速度に応じて、赤丸が疑似3D風の座標でリアルタイムに動く表示
 Acceleration(G)ボタンで、50ms毎に取得した加速度を1秒毎にグラフ表示
に切り替えることができます。

加速度センサーを揺らしたりすると、加速度に応じて表示が変化します。
・加速度に応じて、赤丸が疑似3D風の座標でリアルタイムに動く表示

・50ms毎に取得した加速度を1秒毎にグラフ表示

後者のグラフ表示の場合には、1秒ごとに /home/www-data/log_acc.txt に下記のようなログを出力します。
 acc=(X軸方向加速度(※)、Y軸方向加速度(※)、Z軸方向加速度(※))
  ※)加速度はMMA8452Qから読み出した値を10進数にしてそのまま表示。([m/s^2]単位に算出はしていない。)
 time=Armadillo-440のタイマーの値

[root@armadillo440-0 (ttymxc1) ~]# cat /home/www-data/log_acc.txt
acc=(  -20,    17,  1026)::time=1450698301[s](199661[us])
acc=(  -30,    21,  1029)::time=1450698301[s](250359[us])
acc=(  -31,    25,  1015)::time=1450698301[s](300930[us])
acc=(  -27,    21,  1030)::time=1450698301[s](351516[us])
acc=(  -27,    18,  1025)::time=1450698301[s](402068[us])
acc=(  -29,    25,  1023)::time=1450698301[s](452613[us])
acc=(  -29,    20,  1021)::time=1450698301[s](503229[us])
acc=(  -26,    28,  1025)::time=1450698301[s](553823[us])
acc=(  -30,    26,  1021)::time=1450698301[s](604386[us])
acc=(  -29,    20,  1027)::time=1450698301[s](654941[us])
acc=(  -32,    24,  1025)::time=1450698301[s](705497[us])
acc=(  -32,    21,  1023)::time=1450698301[s](756069[us])
acc=(  -27,    31,  1016)::time=1450698301[s](806610[us])
acc=(  -23,    30,  1020)::time=1450698301[s](857167[us])
acc=(  -31,    21,  1021)::time=1450698301[s](907725[us])
acc=(  -26,    25,  1024)::time=1450698301[s](958277[us])
acc=(  -28,    21,  1027)::time=1450698302[s](  8843[us])
acc=(  -30,    27,  1021)::time=1450698302[s]( 59418[us])
acc=(  -34,    20,  1023)::time=1450698302[s](109975[us])
acc=(  -25,    27,  1024)::time=1450698302[s](160557[us])

<サンプルプログラムの補足>
添付のサンプルプログラムacc_mma8452_gtk.tar.gzを展開するとacc_mma8452_gtkディレクトリ内に Makefile main.c mma8452.h task_acc_real.c common.h mma8452.c task_acc_graph.c というファイルが展開されます。

MMA8452Qから加速度を取得する部分
 mma8452.h、mma8452.c:MMA8452QとI2C通信する部分
 task_acc_real.c、task_acc_graph.c:MMA8452Qから加速度をReadする部分
は、Armadillo-400シリーズ:3軸加速度センサー(MMA8452Q)から加速度を取得するサンプルプログラム をベースにしています。

GTKでLCDに表示する部分は、 Armadillo-440の標準イメージに含まれているfunctester(起動すると自動的にLCDに表示されるプログラム)をベースにしています。
添付のサンプルプログラム特有な部分は下記になります。
・task_acc_real.c
(MMA8452Qから50ms毎に加速度を取得して、加速度に応じて赤丸が疑似3D風の座標に表示)

static void acc_real_activate(gpointer *data)
{
// 開始処理
// MMA8452Qとの通信のためにI2Cデバイスファイルをオープン
// MMA8452Qの加速度センサーをACTIVEにする
// 50ms毎に描画更新のイベントを行うようにタイムアウトを設定
}
 
static void acc_real_activate(gpointer *data) 
{
// 終了処理
// MMA8452Qとの通信のためのI2Cデバイスファイルをクローズ
// 50ms毎のタイムアウトを解除
}
 
static gboolean acc_real_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
// 加速度の取得と描画処理
// MMA8452Qから加速度を取得
// 加速度の値を描画の座標に変換(算出方法は当方独自)
// 軸、上記で算出した座標に赤玉、MMA8452Qから取得した加速度(10進数)を表示
}

・task_acc_graph.c
(MMA8452Qから50ms毎に加速度を取得して、1秒毎にグラフ表示と/home/www-data/log_acc.txtファイルにログ出力)

static gint acc_event(gpointer data)
{
// 加速度の取得
// MMA8452Qから加速度を取得
// 20回毎(50ms×20=1秒毎)にグラフ表示と/home/www-data/log_acc.txtファイルにログ出力
}
 
static void acc_graph_activate(gpointer *data)
{
// 開始処理
// MMA8452Qとの通信のためにI2Cデバイスファイルをオープン
// MMA8452Qの加速度センサーをACTIVEにする
// 50ms毎に加速度取得のイベントを行うようにタイムアウトを設定
}
 
static void acc_graph_activate(gpointer *data) 
{
// 終了処理
// MMA8452Qとの通信のためのI2Cデバイスファイルをクローズ
// 50ms毎のタイムアウトを解除
}
 
static gboolean acc_graph_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
// 描画処理
// 加速度の値を描画の座標に変換
// 軸を表示し、上記で算出した座標を線で結んで折れ線グラフで表示
}

備考1)I2Cデバイスファイルは、task_acc_real.c、task_acc_graph.c内の

#define I2C_DEVICE    "/dev/i2c-1"

で指定しています。
上記は、手順2のArmadillo-440のCON14のI2C(デバイスファイル:"/dev/i2c-1")を指定した場合です。

備考2)task_acc_real.c、task_acc_graph.c内の

 timeout_tag = gtk_timeout_add(50, acc_event, data);

gtk_timeout_addの第一引数"50"で、MMA8452Qから加速度を取得する間隔を"50ms"にしています。 当方の確認では、この値を"10"(10ms)にすると描画が間に合わないのか、 MMA8452Qから加速度を取得する間隔が不安定(数msになったり、数100msになったり)になりました。