「weblog」カテゴリーアーカイブ

Arduinoで使うモータドライバ

よくArduinoでモータードライバといったら、東芝のTA7291Pあたりを買って…というケースが多いけれど、ふとROHMのBD6211F-E2イケんぢゃね?と思って使ってみたら…イケてるよ、これBD6211F-E2。

– TA7291PとBD6211F-E2の比較
まずは写真で見るとこんな感じ。一番左がTA7291P、真ん中がBD6211F-E2をSOP8にハンダしたもの、一番右がBD6211F-E2を実装したスイッチサイエンスさんのもの
pic1

まず思うのがサイズの小ささ。小さくていい感じ。そして何より安い。秋月さん価格で。
– TA7291P 300円/2個
– BD6211F-E2 100円/個
SOP8は9枚入りで100円だから、はんだ付けの手間くらいで、BD6211F-E2の方が良い。そして、TA7291PはVCC:4.5V-20Vなのに対して、BD6211F-E2:3.0V-5.5V。この3.0Vというのが自分的にはとっても魅力的。はんだの手間が面倒なら、スイッチサイエンスさん所からゲットしても良いと思う。

安い、小さい、3.0Vからという良いことづくめで使ってみることに。

回路や設定はこちら、BD62xxFモータードライバ(スイッチサイエンスさんのページから。)

よく利用されるDCモータのFA-130をつなげた感じはこんな感じ。

めっちゃ良い。良い。とっても良い。

スイッチサイエンスさんのを使うとこんな感じ。(BD6211F-E2のVREFがVCCに出荷時に接続されてあるから、もっと便利に)

良い。めっちゃ良い。これ好き。

小さいのは良い。何か実装しやすいし、めっちゃ良い。

ソレノイドを使う

モーターやサーボ、ステッピングモータに比べるとあまり情報がアップされていないソレノイド。大抵、12Vあたりで使われる事もあるみたいで、あまり使用頻度が高く無いのかも。

ちょっと使ってみようと思い、安い5Vで動くSparkfunのソレノイドをゲットした。

Solenoid – 5v (small)この子だけど千石さんでもゲットできる。

正式な型番はZHO-0420L/Sでゲットしたのはプッシュタイプ。戻りバネも付いているからサクっと簡単に使える。5Vな仕様だけど、19Vくらいまで流せるみたい。パワーが欲しい時は大きめで流しても良いかも。

んで、接続するとこんな感じ。

NPNトランジスタ(2SC3964), ソレノイドが戻る時に発生する電流制御用のダイオード(1N5818)を使って、5V電源はArduinoから利用する。コードはこんな感じ。

void setup(){
  pinMode(3, OUTPUT);
}

void loop(){
  digitalWrite(3, LOW);
  delay(1000);
  digitalWrite(3, HIGH);
  delay(100);
}

ちょっとコードは違うけど、こんな感じの動き。リズムを作れたりする。

6LoWPAN Ubuntu VM Image

This is “How to use 6LoWPAN(IPv6 over Bluetooth) on VMware Player Ubuntu LTS image”. 6LoWPAN is already included in linux kernel tree(net/bluetooth/6lowpan.c), and Nordic nRF51 IoT SDK is using Raspbian kernel for Raspberry Pi Linux kernel 3.17.4 as IPv6 gateway, but hardware(RPi) is needed if want to try the 6LoWPAN. so I build lastest Linux kernel 3.18.4 for Ubuntu 14.04 LTS, and use VMware Player instead of the Raspberry Pi. Even if you don’t have RPi, can use the 6LoWPAN!!

I use Nordic nRF51822(Red bear BLE nano: ARM Cortex-M0 SoC plus Bluetooth 4.1 Low Energy), and Bluetooth USB Dongle(Bluetooth4.0+EDR/LE), nRF51 IoT SDK, like a following.

1. download the Ubuntu Linux VM player image from my website.
Ubuntu_14.04.1_LTS_64bit_Kernel_3.18.3.zip

2. Run VMware Player
In my case, I use Windows7 VMware Player. This Ubuntu Linux 14.04.1 user and password is “ubuntu/ubuntu”. Linux Kernel is already updated to 3.18.4.

3. connect Bluetooth Dongle to the PC, check the Bluetooth dongle and VM Linux connection on VMware Player dialog.

3. config the 6lowpan and check the ping6 on VMware.

If want to build the linux kernel, check the “/boot/config-3.18.3” linux kernel build file. Maybe it’s easy to develop the linux 6lowpan kernel module by using the VM linux.

How to use 6LoWPAN on VMware Ubuntu Linux in MacOS

Raspberry Piを使って6LoWPANを試していたけど、ぶっちゃけRPiを持ち運ぶも面倒だし、Linux Kernel 3.18.3 とかで普通に6LoWPANは使えるから、OS上の仮想Linuxで使いたくなるのは自然の道理。

という事で、Virtual Box上のUbuntu Linuxから6LoWPANで物理デバイス(nRF51)と6LoWPAN(IPv6 over Bluetooth)で疎通を行うことにした。けどVirtualBoxのHost Controllerとの相性がダメなのか、仮想OSへBluetoothのつなぎが出来ない。色々と試してみたけど、どうやっても出来なかったから、VMwareを使うことに。

これでRPiを使う必要もなくなるし、VM上でサクサク6LoWPAN、IPv6の実験が出来る便利な環境になる。ルーティング・カーネルのテスト、6LoWPANもめちゃ簡単にテストできるようになるから、VM上のLinuxを使うのはお勧め。方法は簡単でカーネル取ってきてビルドするだけ。ぶっちゃけRaspberry Pi/Edison…etc とかarm向けのビルドも全部一緒のノリで出来ると思われ(全部検証したわけじゃないけど、だいたい一緒)。

カーネルの設定はこちらに載せている通りにすればOK。一応、Ubuntu Server 14.04にdpkg -i で打ち込んでバッチリ動いている。自分がビルドしたKernelパッケージはこちら。

3.18.3 Linux kernel for Ubuntu
build config

ダウンロードしてきたらインストール&再起動で最新カーネルに変えたら終了。めちゃ簡単。こんな感じ。

MacのUSBポートにはnRF51、BroadcomのBluetoothドングル(市販の普通のもの)を挿して、nRF51 BluetoothドングルがMac上のVM Linuxを介してIPv6 over Bluetoothとして疎通している。

何を思っているかというと、WiFiが使えなくてルータがない、シリアルも無くても、VMのUbuntu上でIPv6 over Bluetoothで疎通をしてネットワークを作ってテスト・開発・検証できる(Macは対応している訳じゃないからね)。VM上のLinuxを6LoWPANルータみたいな感じで使えるし、便利な環境も作れるようになる。

このイメージを配ったら、誰でもRPiとか無くてもすぐ6LoWPANを使った開発が進められるよーになると思っている。もちろん、Bluetoothの方は必要になるけどね。

ちなみに、VMのMacはYosemiteの環境で、VirtualBox上のUbuntu LinuxからBluetoothを利用・終了するときは、次のコマンドをMacOS上で行う必要がある。ただ、Host Controllerが突然dieするのは乗り越えられなかった…VMwareでは以下は不要。

# Load
sudo launchctl unload /System/Library/LaunchDaemons/com.apple.blued.plist
sudo kextunload -b com.apple.iokit.BroadcomBluetoothHostControllerUSBTransport
sudo kextunload -b com.apple.iokit.IOBluetoothHostControllerUSBTransport

# Unload
sudo kextload -b com.apple.iokit.IOBluetoothHostControllerUSBTransport
sudo kextload -b com.apple.iokit.BroadcomBluetoothHostControllerUSBTransport
sudo launchctl load /System/Library/LaunchDaemons/com.apple.blued.plist

6lowpan Linuxカーネルメモ

6lowpanのカーネル実装部分のメモ

– Bluetoothでの 6lowpan(IPv6 over bluetooth)のメイン部分
net/bluetooth/6lowpan.c
基本的にはl2capにbluetoothの足回りは依存していて、l2cap以上の上物を書けばOKという作り。l2capとIP層との繋ぎまで。l2capの実装は ”net/bluetooth/l2cap_core.c” とかを参照。
6LoWPANのRFCは現在絶賛ドラフト中。rfc7400のヘッダ圧縮も入っている。

– PAN内のPeer(Bluetooth同士)の扱い
6LoWPAN内のPeerの管理は “linux2.6/include/linux/list.h” を使った単純リスト構造。Peerの検索はlist。あれまぁDHT/Chordにしたら?とか一瞬思ったけど、そもそもBluetoothって同時接続で激しいルーティングする感じでも無いし、listでも十分と思われ。Peerはもちろん複数持ってもOK。
パケットがbt%dデバイスから送信時(ndo_start_xmit=bt_xmit)は、Peerが1個の場合はすぐに送信。2個以上の時は、OSのルーティングテーブルによろしく(bt%dが出来るから)。

– 6lowpanヘッダ処理
net/6lowpan/iphc.c
IPv6をBluetooth上に投げる時にヘッダ圧縮(rfc7400)。圧縮といってもヘッダを省く位な感じ。この時にHop Limitの処理も入る。超過したらソケットバッファからdropされる。
別のディレクトリになっているのは、必ずしもbluetoothのみを対象にする訳では無いという現れかな。

– bt%dで作成されるデバイス
 setup_netdev, netdev_setup
 ARPHRD_6LOWPAN
 IFF_POINTOPOINT

– /sys/kernel/debug/bluetooth/6lowpan_psm
 bluetoothのデバイスで、周辺のbtのlistenの開始・終了セット
 -> bt_6lowpan_listen

– /sys/kernel/debug/bluetooth/6lowpan_control
 実際のbt%dの作成とl2capで対向のBluetoothに接続
 -> lowpan_control_write

– bt%dへの読み書き
 bt_xmit -> send_pkt : Bluetooth上でl2capで送信
 chan_recv_cb -> recv_pkt : l2capからの受信

メインの構造は以上で、あとはヘッダ処理とかsetup/init系。6lowpan/bluetooth合わせても2000行程度だからサクサク読めるはず。

IPv6 over Bluetooth

IPv6かよっwwww って声がそこはかとなく聞こえてくる気もするけど、自分の中でまたIPv6が再燃している。それは何故かというと、Bluetooth 4.2の仕様にIPv6/6LoWPANが乗ってくるというインパクトのあるニュースが、ある一部のマニア層(w)で飛び交った。

ニュース的には、”Bluetooth 4.2 発表。Bluetooth Smart で直接インターネットに接続。通信速度とセキュリティ強化“とか、Bluetooth SIGの発表はこちら

IPv4は抜きで、まさかのIPv6/6LoWPANっすよ。一瞬、何の冗談だよ(w)って思えたけど、マヂでBluetoothにIPv6が乗ってくる。IPv6とかイマサラ感&使えねーだろ!!とか言っても乗ってくる。2015年(今年)にはBluetooth 4.2に対応した物が出荷され始めるとのことで、IPv6の再燃か!?まさかBluetoothからやってくるとは、誰も思わなかったと思われ(www

物自体は2015年からという事で、まだ先だろうなぁ…と思っていたら、既にNordicさんがIoT SDKのベータ版という事で出していた。CES 2015でも(何故か日本じゃニュースに出てないけど)デモをしていたようで。ということで、早速やってみることに。構成は次のような感じ、

端末 : Nordic nRF51
IPv6 Router : Raspberry PI/radvd/BroadcomのBluetooth dongle
上流は無し。

バッチリできたー!! 6lowpanでの端末のLED制御もできるし、link localでのIPv6の疎通もバッチリ。すっげー楽しい!!
64bit prefixをどこからか持ってきてradvdに食わせると、サクッと上流もできてGlobal IPv6でネット側から疎通ができる。Nordicのスタックを見ると、まさかのLwIPが全力で使われていた。軽め&既存物だし、ライセンスもBSDだからサクッと作ったものと思われ。簡単だもんね。けど、10年ぶり位にLwIPに遭遇するとは全く思ってもみなかったw
次はKoshian(Broadom)の環境でやってみようかなと。WICEDのSDKでFWを書き換えて使える所も確認しているし、スタック載せればサクッと動くはず。

そしてTIさんの6lowpanのサイトから絵をちょっとコピって、Bluetooth 4.2が出始める頃に出来上がると想定されるNWな絵はこちら。TIさんもIPv6 over Bluetoothをそのうち出してくるのかなー。

エッジルータは据え置き物がすぐ考えられるけど、iPhone/Androidのアプリ(Bluetoothと疎通して上流のIPv6をのコネクティビティを担保)が出てくる。というか作ろうと思っている。すると、絵の通りだけど。

1. Bluetoothだけで6lowpan(IPv6)での疎通ができる。
2. エッジとしてスマートフォンを使うと、Bluetoothの端末・ガジェットにIPv6でダイレクトに疎通できる。

こんな事ができる。ただし、問題点としては今・そしてすぐ上流がIPv6いっぱーい!!という事にはならないから、GlobalからアクセスしようとするとIPv6 over IPv4のトンネルといった事も必要になる。これはサーバサイドもちょっとした物が必要になってくるんだけど、この辺もいつものノリでやれば出来ると思われ。IPv6ダイレクト接続でIPv6 64bit prefixが振ってきたり、VolTEではIPv6が使われていて将来的にはトンネルとか不要になると思うけどね。
何故かスタックとか、ネットワーク周辺で興奮するんだけど、IoTというかモノとネットワーク間は凄く面白いところになってくる予感。

あと今すぐIPv6がBluetoothに乗ってくる訳じゃない。いまだに上流やサーバ/NW側のIPv6が進んでいない事、Bluetooth端末にダイレクトにGlobalからアクセスする時に間違いなく必要になるセキュリティが真っ先に考えられる。ただ、6lowpanでNWを構成してGlobal側は使わないという方法もあったりするし、この辺はこれから考えればまだ十分だと思うし、何にしてもBluetooth 4.2でIPv6が出始めるというのは、今からアプローチしておいた方が間違いなく良い所かな。

かまくらプロジェクション

お正月休みで実家の雪積もる岩手に帰ってきている。ただ実家でぐーたらするのも面白く無いと思って、雪を使ってプロジェクターで投影しか無いべ!!と思って、つい最近買ったP2Eを持ってきた。

雪の壁とかに投影したらわりと楽しかったから、かまくらの中に投影することに。雪とプロジェクタを使った物だと、雪の造型物とか壁に投影する物は見た事はあったけど、かまくらの中に投影している物は見た事が無かったのもあって、レッツかまくらプロジェクション!!ってことでoFで適当にプログラムを組んで遊ぶことに。

まずはかまくら作り…久々に雪と格闘すること1時間…

とりあえず大人3人くらいは入れる穴ができた。夜になるとこんな感じ。

まずは単色で投影したりすると…こんな感じに。思ったより幻想的な雰囲気が出て良い感じ。

雪というか氷が光をより際立たせてくれている感じがする。実家の子供達に見せてみたら、ワーキャー楽しんでくれて良い感じだった。

あとで単純なパーティクルを投影して、かまくらの中でグルグル動かすと割と面白いかしら?という事で、これも適当にやってみたら意外とたのしい。

位置合わせと素材を調整すればもっと面白いと思われ。
大変だったのが、かまくら作り。家の前に積もっていた雪にひたすら穴をあける作業はわりと疲れた…
あと、投影するからには夜だろうという事だけど、氷点下の中で設置したり位置合わせ、ちょっとしたプログラムの修正を外でするのは大変というか…とにかく寒い、寒すぎる。Macbook Airが氷のように冷たい中での作業で、とにかく寒い。けど、子供達に遊んで楽しんでもらえてよかったかな。

IoT的価値

来年は更にネットにつながるデバイス、いわゆるIoT端末というのが溢れてくると思われる。開発を行う拠点も、DMM.make Akiba品川産業支援交流施設SHIPTechshop(富士通)とか出来てきている。

モノ系スタートアップの支援や、Yahoo Japanも電通もIoTと言っている状況で、周りをざらっと見た感じだとIoTと言っている所が非常に多い。けど、ぶっちゃけ実際のモノ、IoTデバイスというカテゴリに類するもので出回っているのはまだそんなに無い。まさにこれから産声を上げていくといった感はある。

■ モノの価値
先日の展示で見せてきたポスト君もそうだし、AccessさんがBeacon端末を無料で配るというのもだけど、いわゆる原価がいくらで実際の売値がいくら?というのは、非常に考える点が多いと思っている。ネットに接続してあれこれやる、いわゆるIoTデバイスは、

・モノ
・ネットワーク
・サーバ

といった所がプレイヤーとして出て来る。ここで、モノは現物で売値がいくら?という点があって、ネットワークはWiFi/BTを使えばOK、そして最後のサーバ(WebAPとか)は何気に効いて来る。今までのモノは売っていくら?だったのが、そこにランニングとしてのサーバやWebAPが継続して乗ってくるわけで、いつまでサポートするの?サービスの継続期間は?とか考えると、初期の売値で回収すんの?売切りで良いの?って気がするわけで。モノの価値というのは、サービスのランニングも込みで決めないといけない。

■ モノは激安、広告・月額いくら?
初期の価格にサーバとかのランニングも載せるというのは現実的ではないし、じゃあどうすんの?というと広告やアプリを介してサービスを利用する時に月額課金といった方法が考えられる。そして初期のモノの値段は激安で。原価がいくらだから最低限この値段で売らないと採算が…というのはいわゆる旧来の売り方から考え方が抜け切れていないと思っている。

そう、IoT、Internet of Thingsというネットのサービスを利用するのに、原価がいくらで?というのは要素の1つとして考えられる訳だけど、ネットサービスなのにそっちは考えてないの?というかサービスで対価を頂くんだよね?という点が抜け落ちているよーな気がする。

■ ネット・Webとの連携
モノを作るときはメーカー寄りの人だったり、実際にモノ作りに携わっている人との関わりが多いけど、IoTというシーンではネットやWeb側の広告や月額いくら?でサービスをやっている方との連携が必ず必要になる。それはモノの価値、値段決めという点においても。原価がいくらだから、この値段で売らないと…というよりも売値は押さえて、サービスで対価を頂くモデルが主流になると思う。

モノとサービスが主体になるIoTという形態では、作り手と同じくらいネット・Web側との連携、サービス作りが大切になると考えている。ネットにつながるからIoTデバイスで…というんじゃなくってね。サービスを提供して利用者にどんなメリットが?そして、その対価としてのサービス利用料や広告を出させて頂くといった、ネット・Web側で培われてきたノウハウというのが一体となって実現するのがIoTなる物だと考えている。

(追記) 上記のような、サービスモデル以外にも、Web側のデータ保全やIoT的端末からアクセス集中した時の冗長化、システムを落とさない為の運用…etc とか端末/ハードとは違う、ネット側で培われた知見は必要になってくる部分と思っている。ハードだけでもなく、Web側・ソフト側…といった様々な要素が必要になるでしょう。それはWeb側のサービスと、現実世界にあるモノとして使う人への最終的な価値の提供といった側面に反映されてくる部分でもある。
あと、このIoTというバズワードが自分的にWeb2.0とかビックデータといった歴代のバズワードに比べて現実味を帯びているのは、Web/ネット上の状態を表した言葉じゃなく、現実世界にあるモノ、目の前に現物として存在している状態という所が大きいような気がしている。

ポスト君

ポスト君という物を作りました。アナログな郵便箱を、電子メールのようにプッシュで通知して電子メールボックスとしての役割にしてくれる、IoT的なアイテムです。

– 通知方法
iBeacon(BLE)、またはメール。
メールの場合は、端末がWiFiに接続されている必要があります。

– 動作
1. 郵便箱にガジェットを入れて起動する。
2. 起動時に赤外線センサーで郵便箱の中の距離を一定時間測定する。
3. 監視スタート、たまに監視を行なってポストに郵便が投函されて、距離に変化が起きたら郵便が来たと判断して通知を行なう。通知はiBeacon、メールの何れか。
4. 郵便を取って、郵便箱の中が元の状態と同じ感じになったら、また監視を開始する。

– 利用シーン
1. 郵便が届いたらメールが来る。(WiFiタイプ)
2. 家に帰る途中で、郵便が届いていたら、ケータイに通知が来る(iBeacon)。
3. 空の郵便箱を開けて確認する必要が無くなる。
4. 家でゴロゴロしている時でも、郵便が来たら通知をしてくれる。

動作は非常に簡単で、こんなサイズの物を郵便ポストに入れておくだけ。普通の郵便箱に設置できます。

こちらはgugen 2014で展示してきた時のもの。

よくあった質問としては…

– 電池ってどの位持つの?
デモの時はリアルタイムで監視をしていたので、すぐ電池が切れちゃうけど、郵便が来たかどうか?をリアルタイムで確認したい!!という高い欲求のある人はあまり居なくて、30分に1回確認をする位ならかなり電池が持ちます。逆に設定で、リアルタイムで確認をしたい!!という場合は、すぐ電池が無くなってしまいます。これはアプリ側から設定を行なって調整できるようにする感じですね。

– チラシとかも反応するんじゃ?
反応します。自分の場合は都内に住んでいるですが、チラシが全然来ないです。もちろん実家では来た事が殆ど無いですし、むしろチラシが来たら嬉しい位で、この点は受取手側の状態に依存します。また、チラシ状の封書であっても本当に欲しい郵便の場合もあるので、今の方法では判別不可能です。
そこでどうするか?というと、特注の郵便箱を作って、郵便が入ってきた時に、入って来た郵便物をスキャンして内容を確認するという方法で、来た物の属性を判断していく事も可能になるでしょう。つまり郵便箱の入ってくる口の部分をスキャナーのようにする、といった感じです。そこまでする必要があるかどうか?というのがポイントになります。

ODROID U3 and OpenNI2/Xtion Pro Live

here is how to use OpenNI2/Xtion Pro live on ODROID-U3. environment is here.

os : xubuntu-13.10-desktop-armhf_odroidu_20140107.img.xz
OpenNI2(build from https://github.com/OpenNI/OpenNI2)

# install library
apt-get update
apt-get upgrade
apt-get install g++ python libusb-1.0-0-dev libudev-dev openjdk-6-jdk freeglut3-dev doxygen graphviz

# build OpenNI2
mkdir work
cd work
git clone https://github.com/OpenNI/OpenNI2
cd OpenNI2

# default OpenNI repository build will fail, so I change following. here is diff.
diff --git a/Packaging/ReleaseVersion.py b/Packaging/ReleaseVersion.py
index e2fdf5f..710f590 100755
--- a/Packaging/ReleaseVersion.py
+++ b/Packaging/ReleaseVersion.py
@@ -163,11 +163,12 @@ elif platform.system() == 'Windows':
 elif platform.system() == 'Linux' or platform.system() == 'Darwin':
 
     devNull = open('/dev/null', 'w')
-    subprocess.check_call(['make', '-C', '../', '-j' + calc_jobs_number(), 'PLATFORM=' + plat, 'clean'], stdout=devNull, stderr=devNull)
+    # subprocess.check_call(['make', '-C', '../', '-j' + calc_jobs_number(), 'PLATFORM=' + plat, 'clean'], stdout=devNull, stderr=devNull)
+    subprocess.check_call(['make', '-C', '../', '-j1', 'PLATFORM=' + plat, 'clean'], stdout=devNull, stderr=devNull)
     devNull.close()
     
     buildLog = open(origDir + '/build.release.' + plat + '.log', 'w')
-    subprocess.check_call(['make', '-C', '../', '-j' + calc_jobs_number(), 'PLATFORM=' + plat, 'release'], stdout=buildLog, stderr=buildLog)
+    subprocess.check_call(['make', '-C', '../', '-j1', 'PLATFORM=' + plat, 'release'], stdout=buildLog, stderr=buildLog)
     buildLog.close()
     
     # everything OK, can remove build log
diff --git a/ThirdParty/PSCommon/BuildSystem/Platform.Arm b/ThirdParty/PSCommon/BuildSystem/Platform.Arm
index c4a112d..cd12569 100644
--- a/ThirdParty/PSCommon/BuildSystem/Platform.Arm
+++ b/ThirdParty/PSCommon/BuildSystem/Platform.Arm
@@ -1,7 +1,8 @@
 ifeq "$(CFG)" "Release"
 
     # Hardware specifying flags
-    CFLAGS += -march=armv7-a -mtune=cortex-a9 -mfpu=neon -mfloat-abi=softfp #-mcpu=cortex-a8
+    # CFLAGS += -march=armv7-a -mtune=cortex-a9 -mfpu=neon -mfloat-abi=softfp #-mcpu=cortex-a8
+    CFLAGS += -march=armv7-a -mtune=cortex-a9 -mfpu=neon -Wno-unused-local-typedefs #-mcpu=cortex-a8
 
     # Optimization level, minus currently buggy optimizing methods (which break bit-exact)
     CFLAGS += -O3 -fno-tree-pre -fno-strict-aliasing


# build OpenNI
cd OpenNI2/Packaging
python ReleaseVersion.py  Arm

# maybe 1 hour needed, check build status "tail -f build.release.Arm.log" 

# install OpenNI
cd Final
tar -jxvf OpenNI-Linux-Arm-2.2.tar.bz2 
cd OpenNI-Linux-Arm-2.2
sh install.sh
source OpenNIDevEnvironment

# run sample application.
cd Samples/Bin
./SimpleRead

# use dual xtion depth stream sample
cd Samples/MultipleStreamRead/
vi main.cpp
#include <OpenNI.h>
#include <iostream>
#include <vector>
#include "OniSampleUtilities.h"

using namespace openni;
using namespace std;

class DepthSensor {
private:
    openni::Device device;
    openni::VideoStream depthStream;
    vector<openni::VideoStream*> streams;
 
public:
    DepthSensor() {}
 
    void open( const char* uri ) {
        Status ret = device.open( uri );
        depthStream.create( device, SENSOR_DEPTH );
        depthStream.start();
        streams.push_back( &depthStream );
    }
 
    void run() {
        int changedIndex;
        openni::OpenNI::waitForAnyStream( &streams[0], streams.size(), &changedIndex );
        if ( changedIndex == 0 ) {
            openni::VideoFrameRef depthFrame;
            depthStream.readFrame( &depthFrame );
            if ( depthFrame.isValid() ) {
            }
        }
    }
};
 
int main() {
    try {
        openni::OpenNI::initialize();
        openni::Array<openni::DeviceInfo> deviceInfoList;
        openni::OpenNI::enumerateDevices( &deviceInfoList );
 
        DepthSensor* sensor = new DepthSensor[deviceInfoList.getSize()];
        for ( int i = 0; i < deviceInfoList.getSize(); ++i )
            sensor[i].open( deviceInfoList[i].getUri() );
 
        while ( 1 ) {
            for ( int i = 0; i < deviceInfoList.getSize(); ++i ) {
                sensor[i].run();
            }
 
        }
        delete[] sensor;
    } catch ( exception& ) {
        cout << openni::OpenNI::getExtendedError() << endl;
    }
    return 0;
}
make
cd Bin/Arm-Release
./MultipleStreamRead

# like this.