このページではXBee ZigBee を使ってリモートでLEDを制御したりスイッチ状態を取得する方法を説明しています。
以下からGPIO(汎用デジタル入出力)の制御や読み取りを行うサンプルプログラムをダウンロードすることができます。ソースリストにも説明をコメントしていますので、そちらをお読みいただいても流れが分かるようになっています。最新のものはダウンロードページにあります。
ファイル
内容
| 説明
| sample1_led.c
| サンプル1 リモートLED制御
| LEDのOn/Offを制御するためのサンプルです。
| sample2_sw.c
| サンプル2 スイッチ状態取得
| スイッチの状態を取得するためのサンプルです。
| xbee.c
| ライブラリ ソースリスト
| XBee管理用ライブラリ本体のソースコードです。
| xbee-download.html
| PC用/H8用 ZB Coordinator API
| 最新版ダウンロード用ページへのリンクです。
| xbee-cord_sch.pdf
| Coordinator/End Device回路図
| 本サンプルに対応したハードの回路図です。
| |
これらのソフトの説明に先立ってハードウェアやXBeeの設定について説明します。説明を飛ばしたい場合は「こちら」に進んでください。
ハードウェアは下図のようにPCに接続された親機XBeeと単体の子機XBeeから構成されます。製作方法については「XBee ZigBeeを使ってセンサネットワークを構築しよう」や「XBee-Fly USBの作り方」に記載しています。
注意:既に1台を「Coordinator AT」に設定されている方も以下の手順で「Coordinator API」に設定変更する必要があります。
X-CTUのファームウェアの種類「Function Set」をプルダウンして「ZIGBEE COORDINATOR API」を選択します。ここでは語尾に「API」のついたCoordinatorを選択してください。そして、「Write」で書き込みます。
まずは、PCに接続された親機のXBee Coordinatorから(PCに接続されていない)単体の子機XBee RouterのLEDのOn/Offを行うサンプルプログラムについて説明します。このサンプルではキーボードから0を入力すると消灯し、1を入れるとGPIOポート11のLEDが点灯、2だとGPIOポート12のLEDが点灯します。
サンプルプログラムを動かす前に、下記のソースの緑色部分に子機のXBeeのアドレスを入力しておきます。(親機であるCoordinator側のアドレスはライブラリ内で読み取って設定しているので不要です。)
変更が終わればコンソールでコンパイル(makeの実行)を行い、「./sample1_led 3」のように入力して実行します。数字はCOMポート番号をあらわしており、コマンドと数字の間にはスペースが必要です。
これより、main関数内の主要な動作を説明してまいります。
int main(int argc,char **argv){本サンプルのメイン関数です。
|
byte i; | char s[3]; byte port=0; 使用変数の宣言
|
byte dev_gpio[] | = {0x00,0x13,0xA2,0x00,0x00,0x11,0x22,0x33}; 子機(リモート先)XBeeのアドレスを入力してください。
|
if( argc==2 ) port = (byte)(argv[1][0]-'0'); | xbee_init( port ); COMポートを[port]番号で開きます。
|
xbee_atnj( 0xFF ); | XBeeデバイスを常に参加受け入れに設定。
|
xbee_gpio_init(dev_gpio); | デバイスdev_gpioにIO設定を行うための送信を実行
|
while(1){ | printf("input[0-2]:"); gets( s ); キーボードから数字を入力。
|
switch( s[0] ){ | case '0': '0'が入力されたとき
|
xbee_gpo(dev_gpio,12,1); | 子機(リモート先)のGPOポート12をHレベル(消灯)へ
|
xbee_gpo(dev_gpio,11,1); | break; 子機(リモート先)のGPOポート11をHレベル(消灯)へ
|
case '1': | xbee_gpo(dev_gpio,12,0); break; '1'が入力されたとき | (リモート先の)GPOポート12をLレベル(点灯)へ
case '2': | xbee_gpo(dev_gpio,11,0); break; } } } '2'が入力されたとき | 子機(リモート先)のGPOポート11をLレベル(点灯)へ |
main関数内では、使用変数の宣言、COMポートのオープンを行った後にxbee_atnj()に0xFFを渡してXBeeデバイスを参加受け入れ状態に設定しています。0x01〜0xFEまでの値を入れると、その秒数だけ参加受け入れとなり実用的に動作するようになります。
次に、xbee_gpio_init(dev_gpio);で、dev_gpioに代入されたアドレスのリモートXBeeのGPIOを初期化しています。そして、キーボードから数字を入力してもらってから、その数字に応じてxbee_gpo();でGPIOのポートの状態を変更しています。引数は3つあり、(1)アドレス、(2)GPIOポート番号、(3)出力値です。出力値が1だとHレベルに、0だとLレベルが出力されます。
さらっと書いてしまうと、普通にGPIOを設定しているかのように見えますが、PCに接続された親機からリモートで子機に無線でコマンドが送られてGPIOを変更しているのです。
今度は子機のスイッチの状態を取得します。子機のスイッチが押されると子機からコマンドが親機に送られ、その結果を受信するという、少しだけセンサーネットワークらしいサンプルです。先ほどのサンプルと同様に子機のアドレスを変更してコンパイルしてから実行します。
このライブラリでデータを待ち受けるにはxbee_rx_call()という関数を使用します。引数にはXBEE_RESULTで宣言した構造体の変数が必要です。前半はLEDと同じなのでwhile内の部分に注目してください。
int main(int argc,char **argv){本サンプルのメイン関数です。
|
byte port=0; | 使用変数の宣言
|
byte data; | XBEE_RESULT xbee_result; 受信データを保存する変数の宣言
|
byte dev_gpio[] | = {0x00,0x13,0xA2,0x00,0x00,0x11,0x22,0x33}; リモート先のXBeeのアドレスを入力してください。
|
if( argc==2 ) port = (byte)(argv[1][0]-'0'); | xbee_init( port ); COMポートを[port]番号で開きます。
|
xbee_atnj( 0xFF ); | XBeeデバイスを常に参加受け入れに設定。
|
xbee_gpio_init(dev_gpio); | デバイスdev_gpioにIO設定を行うための送信を実行
|
while(1){ | 永久ループ
|
data = xbee_rx_call( &xbee_result ); | データを受信し結果をdataとxbee_resultに代入。 | data:簡単な受信データが代入されます xbee_result:詳細な受信データが代入されます
if( xbee_result.MODE == MODE_GPIN){ | 受信結果がGPIO入力の時
|
lcd_disp_bin( data ); | } } } dataに代入された値をバイナリで表示します。
| |
while内では、xbee_rx_call()関数を使って受信データを確認します。この関数は受信データが無くても約0.1秒後に関数を抜けます。受信したデータは簡単な結果が変数dataに代入され、より詳細な受信データはXBEE_RESULTで宣言した構造体変数xbee_resultに代入されます。
下図はボタン(子機)の製作例です。この製作例ではZigBee End Deviceによる低消費電力での動作を考慮しています。詳しい製作方法は「ZigBee ボタンの製作方法」を参照してください。
xbee_rx_call関数の応答値には以下のようなデータが含まれています。ただし、実際に受信した内容によってデータの有無が異なります。
構造体
内容
| 一例
| (byte) MODE;
| 受信モード(Frame Type)
| MODE_GPIN、MODE_UART、MODE_RESP
| (byte) FROM[8];
| 送信元アドレス
| {0x00,0x13,0xA2,0x00,0x00,0x11,0x22,0x33}
| (byte) STATUS;
| 応答結果
| 0:OK 1:ERROR/AT結果/UART状態
| (byte) GPI.BYTE[2]
| GPIO入力データ
| {0x00,0x00}
| (byte) GPI.PORT.Dxx:1
| GPIO入力データ
| ポート毎の1ビットデータ0/1
| (unsigned int) ADCIN[4];
| ADC入力データ
| 0〜1023のAD変換データ
| (byte) DATA[];
| UART入力データ
| 関数の戻り値に文字数が入る
| |
次はセンサーからデータを入力するサンプルプルグラムの説明です