XBee(無線通信)の実験パート5
(XBeeとマイコンを接続しAPIモードで通信をしてみます)

〔パート1〕 〔パート2〕 〔パート3〕 〔パート4〕   〔パート6〕   〔マイコンのトップに戻る〕


前回(パート4)ではAPIモードで通信を行う為に、APIフレームデータ(APIパケット)の構造を調べて
みましたので、今回はXBeeとマイコンを接続しAPIモードをプログラミングして通信を行ってみたいと
思います、そして、今後XBeeを使用する場合にすぐ利用出来る様ある程度APIモード通信のソフトを
ライブラリ化して置きたいと思います。

尚、XBee基本(基礎)の話とX-CTU基本操作の話はパート1を参照下さい。
又、ここでの記述は秋月電子のXBee ZBモジュール(シリーズ2)PCBアンテナタイプでの内容となります
それとぉ、前回までの記事を読んでいるものとしてここの記事は少しはしょって書いています。

PS. *4)
2018/1月 現在、XBee S2モジュールは製造中止です、後継機は"S2C"です
こちらの製品です、ここのMyHPは旧記事ですがぁS2Cでも少し追記して置きます。

実験風景1
まずは実験風景です。
上側のXBee USBインターフェースボードに 乗ったXBeeが親機で、パソコンに繋がっています。
下側がXBee用2.54mmピッチ変換基板に 乗ったXBeeで子機です。
子機に接続している右側のマイコンがPIC16F1827でその上がLCDモニターです。

《子機の配線図》

親機側は配線有りません、PCに繋ぐだけですが、電源を入れる場合は親機・子機の順番に入れて下さい。

PICピンの構成 左は16F1827のピン構成図です。

PICの今回使用するピン番号は
14番(VDD:5V)と5番(VSS:GND)を
電源に配線します。

USART関連ピンは7番(RX)と8番(TX)です
RX=受信 TX=送信

10番RB4より別途作成のLCDモニター
接続しています。

18番RA1にタクトSWを繋いでいてこれを押すと親機にデータを送信させる為に使用します。

配線図1 電源は外部から5Vを繋ぎます。

XBee(2:DOUT)→PIC(7:RX)の配線
でPICは2.0V以上でHIGHと認識
するのでそのまま直結です。

PIC(8:TX)→XBee(3:DIN)の配線で
XBeeは3.3Vまでの入力なので
抵抗で分圧し3.3Vに落とします。
抵抗は手持ちから4.7Kと9.1Kの
組合わせにしています。

LEDはネットワーク参加状態ASSCを表示させる為ですが、無くても大丈夫でしょう。
繋ぐ場合はLEDの足が長い方をXBee側(15)に配線です。

《XBeeの設定》

XBeeの親機の設定はパート3の"親機の設定を行う"を参照下さい。
XBeeの子機の設定はパート4の"子機の設定を行う"を参照下さい。

《ダウンロードプログラムについて》

↓ここからサンプルプログラムソースファイルをダウンロードして下さい。
XBee1.lzh(Ver2.00 2014/02/02) *1)
XBee5.lzh ライブラリとMPLAB X用に変更 *2)

プログラムソースをダウンロードしたら、MPLAB Xにてプロジェクトを作成します。
以下のファイルをプロジェクトディレクトリにコピーしてプロジェクトに取込んで下さい。
次にコンパイルPIC書き込みを実行して下さい。 *2)
MPLAB(R) XC8 C Compiler Version 1.32コンパイラを使用しています。

ダウンロードファイルを解凍すると下記の様なファイル構成です。
XBee1.c・・・・・・・・・・・・・・・ 本体のサンプルプログラムソースファイル *2)
skXBeeS2lib.c・・・・・・・・・ XBee(シリーズ2)とAPIモードで通信を行う関数ソースファイル
skXBeeS2lib.h・・・・・・・・・ XBee(シリーズ2)とAPIモードで通信を行う関数のインクルードファイル
skUARTlib.c・・・・・・・・・・ USART通信を行う関数ソースファイル *2)
skUARTlib.h・・・・・・・・・・ USART通信を行う関数のインクルードファイル *2)

このプログラムにはデバッグモニタープログラム「skMonitorLCD.c」「skMonitorLCD.h」が必要です。
デバッグLCDモニターについてはこちらを参照して下さい。
「skMonitorLCD.c」は送信データをTimer2のタイミングで送る様に変更しました、
その為にXBee1.cプログラムを変更しています。
 *1)

また、LCDモニターの出力はRB4から行っているので「skMonitorLCD.h」を下記の様に変更します。
#define _XTAL_FREQ 8000000  // 使用するPIC等により動作周波数値を設定する
#define MONITOR_PIN RB4      // モニタ出力するピンの番号を設定する

skUARTlib.c/skUARTlib.h

この関数はXBeeとシリアル通信(USART)を行う為の関数集です、
使い方については、FT232RLモジュールの記事を参照下さい。
skUARTlib.hのファイルで、
#define UART_BUFFER_SIZE 64 // USARTの受信バッファサイズ
と有りますが、
64バイトより長いAPIパケットを送信する場合はこのサイズを増やして下さい。
因みに、最大APIパケットのサイズは255バイトまでの様ですが、増やす場合はPICのSRAM容量
に注意して下さい。

skXBeeS2lib.h

XBee(シリーズ2)とAPIモードで通信を行う為のライブラリ用のインクルードファイルです。
"skXBeeS2lib2.c"を利用する場合に
#include "skXBeeS2lib.h" をプログラムの先頭で記述して下さい。

skXBeeS2lib.c

このライブラリはXBee(シリーズ2)とAPIモードで通信を行う為の関数集です。
この関数集自体は他のPICでも使用出来ます。
また、このプログラムには、"skUARTlib.c"、"skUARTlib.h"が必要です。

この関数の使い方を説明します。
尚、今回のこの関数では"AP-API Enable"は"1"のみ対応していて"2"のエスケープモードは
未対応です。エスケープモードが欲しい人は自分で改造しましょう。
但し、同じネットワーク内で、"AP-API Enable"は"1"と統一して本ライブラリでデータのやり取りを
行う限り、途中に"7E"等のデータが現れても正常に通信可能です。

 ans = XBee_CheckSum_Make(*packet_dt,len)
  指定されたパケットのチェックサムを計算する処理
  APIパケットを送信する為のチェックサムを計算します。
   packet_dt:計算するパケットを格納した場所を指定します
   len    :パケットの長さを指定します(7E〜チェックサムまでの全部の長さ)
   ans    :計算したチェックサム値を返します

 ans = XBee_CheckSum_Scan(*packet_dt,len)
  指定されたパケットのチェックサムは正常な値かを調べる処理
  受信したAPIパケットのチェックサムは合っているのかをチェックします。
   packet_dt:計算するパケットを格納した場所を指定します
   len    :パケットの長さを指定します(7E〜チェックサムまでの全部の長さ)
   ans    :0=正常  0以外ならチェックサム値がおかしいぞぉ

 ans = XBee_GetPacket(*packet_dt)
  受信したAPIパケットを取り出す処理
  受信したUSART通信のバッファからAPIパケットを読み込みます。
  エスケープモードのデータでも読み込めます(変換はしていない、そのままです)
  APIパケット以外のデータは読み捨てます。
   packet_dt:受信したパケットを格納する場所を指定します
   ans    :受信したパケットの長さを返します 0ならパケットは受信していないです
  例)
     int  ans ;
     char dt[32] ;  // このバッファの長さより取出したパケットが大きかった場合は、PICの動作不定

     while(1) {
          ans = XBee_GetPacket(dt) ;
          if (ans != 0) {
               if (XBee_CheckSum_Scan(dt,ans) == 0) {  // チェックサムはOKか?
                    switch(dt[3]) {
                      case 0x8A :                      /** フレームタイプ "8A"  **/
                         break ;
                      case 0x90 :                      /** フレームタイプ "90"  **/
                         break ;
                      default :                        /** その他のフレーム     **/
                         break ;
                    }
               } else {
                    /* 受信したパケットのチェックサム値がおかしい */
               }
          }
     }
 ans = XBee_MakePacket10(*packet_dt,*adrs,*data,num)
  APIパケットのフレームタイプ"10"(送信要求APIフレーム)を作成する処理
  文字列や数値などのデータを相手に送信する為のAPIパケットです。
   packet_dt:作成したパケットを格納する場所を指定します
   adrs   :送信先の64ビットアドレスを指定します(8バイトデータ)
   data   :送信するデータを指定します
   num   :送信するデータの個数を指定します
   ans    :作成したパケットの長さを返します

 ans = XBee_SendPacket10(*packet_dt,len,sw)
  APIパケットのフレームタイプ"10"(送信要求APIフレーム)を送信する処理
  作成したフレームタイプ"10"のAPIパケットを相手に送信します。
   packet_dt:作成したパケットを格納した場所を指定します
   len    :送信するパケットの長さを指定します(7E〜チェックサムまでの全部の長さ)
   sw     :送信のタイプを指定します(0=返答を待たない 1=返答を待つ)
          0の場合は送りっぱなし。
          1の場合はフレームタイプ"8B"の返答が有るまで待ちます。
          もし待っている時に、"8B"以外のパケットが来た場合はエラーとなります。
   ans    :0=正常 0xFE=返答がなかった 0xFF="8B"以外のデータが有った
          その他の数値時は"8B"から返答されたステータス内容がセットされます。
  例)
     int  ans , len ;
     char dt[32] ;
     char adrs[] = {0x00,0x13,0xA2,0x00,0x40,0x98,0x21,0xA5} ;  // 相手XBeeのアドレス

     len = XBee_MakePacket10(dt,adrs,"TEST",4) ;
     ans = XBee_SendPacket10(dt,len,1) ;

  注意)このパケットでエンドデバイスにデータを送信する場合は"SW=0"にして下さい。
      エンドデバイスがスリープから目覚めた時に"8B"が返って来るからです、
      それまで待たされると他の処理が出来ません。

 ans = XBee_SendPacket08(*packet_dt,*atcmd,*cmddata,num)
  APIパケットのフレームタイプ"08"(ATコマンド要求)の作成と送信を行う処理
  PICが接続しているXBeeに対してATコマンドを発行するAPIパケットです。
   packet_dt:作成するパケットの格納先場所を指定します
   atcmd  :送信するコマンドを指定します("ATD1"の場合は"D1"の2バイトを指定)
   cmddata :送信するコマンドパラメータのデータを指定します
   num    :送信するコマンドデータの長さを指定します(データが無いなら0を設定)
   ans    :作成&送信したパケットの長さを返します
  例1)  コマンドパラメータがいらない場合
     char dt[32] ;

     // "ATSL"コマンドを送信する(自分のアドレスの下位4バイトを得る)
     XBee_SendPacket08(dt,"SL","",0) ;

  例2)  コマンドパラメータがいる場合
     char dt[32] ;
     char para[] = {0x00,0x13,0xA2,0x00} ;  // コマンドパラメータデータ 

     // "ATDH0013A200"コマンドを送信する
     XBee_SendPacket08(dt,"DH",para,4) ;
 ans = XBee_SendPacket17(*packet_dt,*atcmd,*cmddata,num)
  APIパケットのフレームタイプ"17"(リモートATコマンド要求)の作成と送信を行う処理
  接続相手のXBeeに対してATコマンドを発行するAPIパケットです。
   packet_dt:作成するパケットの格納先場所を指定します
   adrs   :送信先の64ビットアドレスを指定します(8バイトデータ)
   atcmd  :送信するコマンドを指定します("ATD1"の場合は"D1"の2バイトを指定)
   cmddata :送信するコマンドパラメータのデータを指定します
   num    :送信するコマンドデータの長さを指定します(データが無いなら0を設定)
   ans    :作成&送信したパケットの長さを返します
  例1)  コマンドパラメータがいらない場合
     char dt[32] ;
     char adrs[] = {0x00,0x13,0xA2,0x00,0x40,0x98,0x21,0xA5} ;  // 相手XBeeのアドレス

     // "ATIS"コマンドを送信する(相手にデジタルI/Oの情報を送るように指示する)
     XBee_SendPacket17(dt,adrs,"IS","",0) ;

  例2)  コマンドパラメータがいる場合

     char dt[32] ;
     char para[] = {0x05} ;  // コマンドパラメータデータ 
     char adrs[] = {0x00,0x13,0xA2,0x00,0x40,0x98,0x21,0xA5} ;  // 相手XBeeのアドレス

     // "ATD105"コマンドを送信する(相手のDI01端子を出力状態にする)
     XBee_SendPacket17(dt,adrs,"D1",para,1) ;

XBee1.c

XBeeにてAPIモードで通信を行う場合のサンプルです、親機と子機の何方でも共用出来ます。
あ、そうそうXBeeはシリーズ2のみ対応です。

LCD画面  左の様にLCDモニターに表示させていますが、
 何せ表示エリアが狭いのでデバック作業が
 一苦労です。

 1行目の下1ラインが欠けていますが...

PICは子機XBeeに接続されています、子機の電源が入ると自動的にAPIパケットのフレームタイプ"8A"
が2個送られてきます、上図の1行目表示でステータス内容は"00"と"02"となっていますね。
この内容については前回(パート4)の記事を参考にして下さい。

@ 親機側のPCからX-CTUを起動させ、APIパケットのフレームタイプ"10"を使って文字列の"TEST"を
  子機に送信しました、その結果子機がフレームタイプ"90"で"TEST"の文字を受け取って表示したの
  が上図2行目です。
  尚、データを子機に送る場合は、LCDモニターに表示出来る様に文字データ12文字以内として下さい

A 親機側のX-CTUを[Consoles Working Mode]画面にし、回線はオープンにして置きます。 *3)
  PIC側のタクトスイッチをポチッと押して見て下さい、
  X-CTU画面の「Frames log」にフレームタイプ"90"で"test"の文字が表示されます。

B 次に、
          // スイッチが押されたらパケットデータを送信する
          if (RA1 == 0) {
               // "ATSL"コマンドを送信する(自分のアドレスの下位4バイトを得る)
               XBee_SendPacket08(dt,"SL","",0) ;
               __delay_ms(1000) ;                      // スイッチチャタリング防止
          }
  とプログラムを書き換えてタクトスイッチを押して見て下さい、
  LCDモニターの2行目に自分(子機)のアドレスの下位4バイトが表示されます。

親機と子機のXBeeを入れ替えてみる

親機と子機のXBeeをそのまま交換します、子機側がPCに繋がり、PIC側が親機となります。
親機の電源が入ると[8A00][8A06]とLCDモニターに表示されます。

子機側のAD1/DIO1(19番端子)にLEDを取り付けます。
で、PICのプログラムを、
          // スイッチが押されたらパケットデータを送信する
          if (RA1 == 0) {
               // リモートで"ATD1"コマンドを相手に送信する
               XBee_SendPacket17(dt,adrs,"D1",para,1) ;// adrsは子機のアドレスを設定する
               __delay_ms(1000) ;                      // スイッチチャタリング防止
          }
とプログラムを書き換えてタクトスイッチを押して見て下さい、
子機側のLEDが点灯します、消灯させる為のロジックは無いので各自でプログラムして下さい。

動作周波数や通信速度を変えた場合

動作周波数は skMonitorLCD.h と skXBeeS2.h の下記(8MHz)を変更します。
#define _XTAL_FREQ 8000000  // 使用するPIC等により動作周波数値を設定する
skMonitorLCD.h の #define BAUDRATE 51 も変更する
尚、動作周波数を変えた場合は下の設定"51"も変わりますよ。

通信速度は XBee1.c の下記"51"を変更します。
   InitUART(7,8,51) ;    // RX=7 TX=8 9600bps で初期化

SPBRGレジスタの設定値"51"とボーレート(9600)の関係はデータシートを参照して下さい。
16F1827のデータシートはこちらの301-302ページを見て下さい。

X-CTU画面505
XBee側の設定は上図の"BD-Baud Rate"を変更します、
設定は"0"〜"7"までしか無いようですね。 *3)

X-CTU画面506
XBee側を変えたらX-CTUも上図の様に変えないとXBeeと通信は出来なくなりますよ。 *3)


《その他》

今回のライブラリは基本部分のみなので、各自が必要とする機能に合わせて改造して下さい。
このライブラリ自体はArduinoでも利用できるので、シリアル通信の部分だけArduinoに合わせればOK
と思います、まぁ、その内にArduino用も追記して置きます。
次回(パート6)は、エンドデバイスのスリープ機能を探って見たいと思います。



"S2C"モジュールでの見直し(*4) 2018/02/05
X-CTU(ver6.3.4)での見直し(*3) 2017/01/20
ライブラリとMPLAB X用に変更(*2) 2015/10/27
"skMonitorLCD.c"変更により"XBee1.c"のプログラム変更(*1) 2014/02/02


【きむ茶工房ガレージハウス】
Copyright (C) 2006-2018 Shigehiro Kimura All Rights Reserved.