トップページ | 組込みソフト | Linux搭載ボード | Androidでセンサーを使えるようにする |
Androidでセンサーを使えるようにする |
Beagel Bone BlackでAndroidの開発はソースファイルからAndroid OSをビルドするというができました。 次はセンサーを使えるようにします。Begle Bone Blackはスマートフォンなどと違ってセンサーの類は何も実装されていません。つまり自分でセンサーを接続してそれを動かすためのプログラムを作成することになります。 センサーの接続方法は、この本を参考にしました。 しかし、ダメダメ! たぶんAndroidが初期の頃のソースを元に何とか動いた!レベルです。 何がダメかというと、 1.複数のセンサーが実装されることがまったく前提になっていない (加速度センサーをつけて動いたレベルです。) 普通にまともな設計なら、1つのセンサーを実装する例であっても2つ以上のセンサーの実装が容易になるようにすべきだが、そのような考えがまったくなさそうだ。 2.必要な処理をサボっている! 加速度センサーなら, sensorManager.registerListener(this, tempmeter,SensorManager.SENSOR_DELAY_UI); のようにセンサーに検出するインターバルを短くしないとデータを取り損ねることががる。いろいろ自力で調べてみると、次の関数で時間を渡していることがわかった。 static int poll__setDelay(struct sensors_poll_device_t *dev, int handle, int64_t ns) { // TODO return 0; } //TODO だって!結局必要な処理をやっていない。 調べた結果はSENSOR_DELAY_UIで66.66msだった。 またまた、この本の悪口になってしまいました。 ちなみに、この本の正誤表がでていますが、ぜんぜん足りないですよ。 2014/8/6現在: 2014年2月25日から正誤表が変わっていない。再度、以前と同じ文句を、 「著者や編集者がちゃんと記事をチェックしてば、こんなに余計な時間を費やさないですみました。オラは本のチェック要員じゃないぞ!」 ダメ本のおかげでいろいろ苦労させられました。 そこで、 複数のセンサーが実装できるように設計したソースを公開します。 結局、わかったことを元にしてソースファイルを全部書き直しです。 というわけで再度同じことやるのにこの本を元にしたら、また同じ記事の間違いで時間を浪費することを避けるため、備忘録的にメモしておきます。 |
どんな作業をすればいいのか? |
1.sensors.default.soを作成する 2.sensors.default.soをSDカードにコピーする 3.デバイスファイルのパーミッションを666にする 4.Androidアプリを作成する |
1.sensors.default.soを作成する |
Androidのソースファイルが実装されているディレクトリを ~/src-android として説明を進めます。 sunaga@android:~$ cd ~/src-android 次にターゲット製品を設定します。 sunaga@android:~/src-android$ export TARGET_PRODUCT=beagleboneblack 次に環境の設定をします。 sunaga@android:~/src-android$ source build/envsetup.sh including sdk/bash_completion/adb.bash ソースファイルを置くディレクトリを決めます。何も考えず上のダメ本にあったディレクトリを流用しました。 ~/src-android/hardware/libhardware/modules/sensors 上記ディレクトリがなければ新規作成してください。 上記でディレクトリに移動します。 sunaga@android:~/src-android$ cd hardware/libhardware/modules/sensors sunaga@android:~/src-android/hardware/libhardware/modules/sensors$ このディレクトリに以下のソースファイルを配置します。 my_i2c_sensors.c my_i2c_sensors.h my_sensors.c i2c-dev.h Android.mk ビルドは簡単です。mmとやるだけ! sunaga@android:~/src-android/hardware/libhardware/modules/sensors$ mm ライブラリが以下のフォルダーに作成されています。 ~/src-android/out/target/product/beagleboneblack/system/lib/hw/sensors.default.so |
2.sensors.default.soをSDカードにコピーする |
SDカードを入れます。 SDカードでライブラリを配置するディレクトリは、 /media/rootfs/system/lib/hw です。ここにsensors.default.soをコピーします。 sunaga@android:~/src-android/hardware/libhardware/modules/sensors$ sudo cp ~/src-android/out/target/product/beagleboneblack/system/lib/hw/sensors.default.so /media/rootfs/system/lib/hw |
3.デバイスファイルのパーミッションを666にする |
SDカードのinit.rcで/dev/i2c-3のパーミッションを666にします。 エディタで /media/rootfs/init.rc を開きます。このファイルは管理者権限でないと変更できないので、 sunaga@android:~/src-android/hardware/libhardware/modules/sensors$ sudo gedit /media/rootfs/init.rc で開きます。 検索でon bootがある場所で次のようにchmodを加えます。 -------------------------------------------------------------------- #set i2c chmod 0666 /dev/i2c-3 on boot # basic network init -------------------------------------------------------------------- 保存します。 |
センサーの接続 |
大気圧センサー 秋月電子通商 LPS331使用 高精度大気圧センサーモジュール 取得した気圧データが正しいのか?比較するための気圧計がないのでわかりません。なんとなくそれなりのデータかな?と思っています。温度も計測できます。ただし精度が±2度。ちょっとがっかりですね。(2014/8/8販売中止中みたいです。) 注意: 4番ピンをVDDにしてアドレス0x5dになります。GNDで0x5cです。どちらにも接続しないと0x5dになったり0x5cになったり不安定になります。必ずどちらかに繋いでください。 回路図: それ以外のセンサーを繋ぐ場合は、Raspberry Piで紹介した I2C 制御コード、サンプル公開 AM2321湿度センサーが使えた! を参考にしてください。 |
ソースファイルの説明 |
i2c-dev.h これは何も変更を加えてないヘッダーファイルです。 my_i2c_sensors.h int openI2C(char* deviceName); I2Cデバイスをオープンする関数です。 int activateLPS331AP(int fd); 電源投入時は、センサーはスリープになっています。これを起こしてやるための関数です。 float getTempareture(int fd); センサーから温度データを取得する関数です。 float getPressure(int fd); センサーから大気圧データを取得する関数です。 my_i2c_sensors.c 上記以外の関数の説明: int SetSmbus (int fd, char rw, int command, int size, union i2c_smbus_data *data) SMbusにデータをセットする関数です。 static u_char readSensor(int fd, int sensorAddr, u_char regNo) センサーからデータを読み出す関数です。 sensorAddr:センサーのアドレスを指定します。LPS331APは0x5dです。 regNo:読み出すレジスタ番号を指定します。 static int writeSensor(int fd, int sensorAddr, u_char regNo, u_char data) センサーにデータを書き込む関数です。 sensorAddr:センサーのアドレスを指定します。LPS331APは0x5dです。 regNo:書き込むレジスタ番号を指定します。 data:書き込むデータ my_sensors.c これがセンサーでのデータ取得とAndroidアプリにデータを渡すインターフェースになります。 Android Appプログラムではセンサーがあるか?リストを取得します。 //センサーマネージャの取得(1) sensorManager=(SensorManager)getSystemService( Context.SENSOR_SERVICE); //センサーの取得(2) List<Sensor> list; list=sensorManager.getSensorList(Sensor.TYPE_TEMPERATURE); if (list.size()>0) tempmeter=list.get(0); list=sensorManager.getSensorList(Sensor.TYPE_PRESSURE); if (list.size()>0) pressmeter=list.get(0); このリストを定義しているのが、g_SensorList[]です。
温度が4秒周期、大気圧が2秒周期になっていることが、確認できた。 |
4.Androidアプリを作成する |
たぶん、Androidの入門書に例が出ていると思うので省略します。(すごい不親切かも....) やはりキャラクタLCDに比べると手抜きで作った表示でも見栄えがぜんぜん違います。 電池駆動で動作させ、車で移動してみる。 10kmくらい走ってみると自宅と10hPaも違いがあった。 見かけは平地なのですが、少しずつ標高が上がっているようです。 そういえば、昔自転車で駅まで通学していた頃、行きは楽勝、帰りはしんどいことを思い出しました。 やはり、緩やかな坂が続いていたのだな。と実感しました。 |