ZB Coord API for XBee: This XBee library drives Digi XBee ZB Modules in API Operation mode. Most commands include remote communication's are supported by the functions of this library. You can control XBee devices through the API software modules in this, without using any AT commands. Please refer to the following page and some of sample codes:

Dependents:   sample02_sw xbee_aging sample01_led sample04_sens

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers xbee.cpp Source File

xbee.cpp

00001 //  for ARM mbed Compiler
00002 #define ARM_MBED
00003 #include <mbed.h>
00004 RawSerial _xbee_serial(SERIAL_TX, SERIAL_RX);   // for STM32 Nucleo
00005 //  Please set serial ports in conformity to your microcomputer board.
00006 //  上記の括弧内をお手持ちのマイコンボードのシリアルピン名に書き換えてください。
00007 
00008 /*********************************************************************
00009 本ソースリストおよびソフトウェアは、ライセンスフリーです。(詳細は別記)
00010 利用、編集、再配布等が自由に行えますが、著作権表示の改変は禁止します。
00011 
00012 ZB Coord API for XBee
00013 
00014 This XBee library drives Digi XBee ZB Modules in API Operation mode.
00015 Most commands include remote communication's are supported by the
00016 functions of this library. You can control XBee devices through the
00017 API software modules in this, without using any AT commands.
00018 
00019                                Copyright (c) 2010-2014 Wataru KUNINO
00020                                http://www.geocities.jp/bokunimowakaru/
00021 *********************************************************************/
00022 
00023 /*
00024 既知のバグ
00025     [PC用/H8用/Arduino共通]
00026     ・xbee_force/ATISでERRORもしくは正しい値が得られない場合がある。
00027      一度、xbee_gpo/ATP104などで子機のGPIOなどに出力すると治る。
00028       (XBeeモジュールの不具合と思われる)
00029     ・XBee Smart Plug/XBee Sensor等でネットワーク参加直後、
00030      正しい値を応答しない場合がある。上記と似た症状かもしれない。
00031      一度、XBee Smart PlugのACコンセントを抜いて挿しなおせば治る。
00032       (Smart Plug側のファームウェア「XBP24-ZB_2264」の問題と思われる)
00033     ・Ver 1.90でLITEモードの仕様を変更。(濱崎氏によるBeeBee Lite)
00034     
00035     ★XBee Wi-FiでのRAT実行時にXBeeから応答のパケットが無い場合がある。
00036       IP_PINGは通る。
00037       再現方法、動作中にXBeeをリセットし、その後にArduinoをリセット。
00038       XBeeモジュールをリセットすると治る。
00039       Arduino版で発覚。PC版は未確認。
00040     
00041     [パソコン用]
00042     ・おかげさまで特記事項なし。安定して動作します。
00043     
00044     [Arduino用]
00045     ・標準SDライブラリ使用時にメモリ不足になる場合があります。
00046      そのような場合はxbee_liteをincludeし、LITEモードにしてください。
00047     
00048     [ARM mbed用]
00049     ・試作品です。バグ多数かもしれません。
00050     ・STマイクロ製 Nucleo Board STM32F401で動作確認しています。
00051     ・XBeeとの接続にはArduino用Wireless SD Shieldを使用します。
00052      ※Nucleoボードの裏側のジャンパー抵抗の変更が必要です。
00053                 「SB14」をオープンにします(抵抗を取り外します。)
00054                 「SB62」をショートします。(半田で接続します。)
00055                 「SB63」をショートします。(半田で接続します。)
00056     ・液晶はDF ROBOT製 LCD Keypad Shieldで動作確認しています。
00057     
00058     [H8マイコン用]
00059     ・Ver1.52以降は動作確認をしておらず、動作しない恐れがあります。
00060      お使いになる方は連絡ください。動作確認版を個別リリースいたします。
00061     
00062 制限事項
00063     ・ソースはPC/H8/Arduino/ARM mbed用で共通ですが拡張子が異なります。
00064      PC/H8「xbee.c」をArduino用は「xbee_arduino」フォルダ内のライブラリ
00065      「xbee.h」をincludeしてください。
00066     ・xbee_forceで指示を出してxbee_rx_callで待ち受ける用法を推奨します。
00067     ・受信パケットの最大APIフレーム長は255Bytes等に制限されます。(64KB)
00068     ・複数のXBeeデバイスの選択はアプリでIEEEアドレスを指定してください。
00069     ・ショートアドレスは使っていません(IEEEアドレスで指定してください)
00070     ・温度測定を行う場合は内部発熱分を補正(減算)する必要があります。
00071      Digi純正のWall RouterやSmart Plugの場合は内部発熱の4℃を考慮して
00072      測定値から減算必要があります。
00073     ・送信者アドレスを得る関数xbee_fromは、xbee_rx_callで受信した場合に
00074      正しく得られない場合があります。(受信キャッシュが保持されている時)
00075      xbee_rx_callに渡したxbee_result.FROM[8]から送信者を得てください。
00076 
00077 アプリ向け提供関数
00078 
00079     byte xbee_myaddress( byte *address );
00080     void xbee_address( const byte *address );
00081     byte xbee_atd( const byte *address );
00082     byte xbee_ratd(const byte *dev_address, const byte *set_address );
00083     byte xbee_ratd_myaddress(const byte *address);
00084     void xbee_from( byte *address );
00085     byte xbee_at(const char *in);
00086     byte xbee_rat(const byte *address, const char *in);
00087     byte xbee_rat_force(const byte *address, const char *in);
00088     byte xbee_uart(const byte *address, const char *in);
00089     byte xbee_bytes(const byte *address, const byte *in, byte len);
00090     byte xbee_atvr( void );
00091     byte xbee_atai( void );
00092     byte xbee_atcb( byte cb );
00093     unsigned short xbee_atop(byte *pan_id);
00094     byte xbee_atee_on(const char *key );
00095     byte xbee_atee_off( void );
00096     byte xbee_atnc( void );
00097     byte xbee_ratnc( const byte *address );
00098     byte xbee_atnj( const byte timeout );
00099     byte xbee_ratnj( const byte *address, const byte timeout );
00100     byte xbee_ping( const byte *address );
00101     int xbee_batt(const byte *address );
00102     byte xbee_batt_force(const byte *address );
00103     byte xbee_gpio_config(const byte *address, const byte port, const enum xbee_port_type type ); //(PC/H8)
00104     byte xbee_gpio_config(const byte *address, const byte port, const byte type );          //(arduino) 
00105     byte xbee_gpio_init( const byte *address );
00106     byte xbee_gpo( const byte *address, const byte port,const byte out );
00107     byte xbee_gpi(const byte *address, const byte port);                                    //(EASY)
00108     unsigned int xbee_adc(const byte *address, const byte port);                            //(EASY)
00109     byte xbee_force( const byte *address );
00110     float xbee_sensor_result( XBEE_RESULT *xbee_result, const enum xbee_sensor_type type ); //(PC/H8)
00111     float xbee_sensor_result( XBEE_RESULT *xbee_result, const byte type);                   //(arduino)
00112     byte xbee_rx_call( XBEE_RESULT *xbee_result );
00113     void xbee_clear_cache(void);
00114     xbee_sensor(const byte *address, const enum xbee_sensor_type type );                    //(EASY)
00115     byte xbee_init( const byte port );
00116     byte xbee_reset( void );
00117     byte xbee_end_device(const byte *address, byte sp, byte ir, const byte pin);
00118     byte xbee_i2c_read(const byte *address, byte adr, byte *rx, byte len);
00119     byte xbee_i2c_write(const byte *address, byte adr, byte *rx, byte len);
00120     byte xbee_delay(unsigned int ms);
00121     void lcd_disp( char *s );
00122 
00123 主要な変更履歴
00124     2010/08/15  0.10    - 初回の公開版をリリース 基本動作部分の実験用
00125     2011/08/14  0.30    - ライブラリ化のためにAPI関数の内容を全面見直し
00126     2012/04/07  0.80    - 総合試験の実施とバグ修正、仕様見直しなど
00127     2012/04/22  0.91    - パソコン(cygwin)への移植
00128     2012/07/15  1.00    - 基本機能(sample1~8)のデバッグ完了。正式版
00129     2012/08/25  1.15    - Arduino用へ移植
00130                         - enum xbee_port_typeのADCをAINに変更
00131                         - 起動時にシリアル速度が設定されない不具合を修正
00132     2012/11/25  1.20    - 電池電圧確認用コマンドを非同期型に変更
00133                           xbee_batt⇒xbee_batt_force。応答はxbee_rx_call
00134     2012/12/09  1.30    - 液晶なしオプション(#define LCD_H)の追加
00135                         - Liteモード(#define LITE)の追加。ARDUINO版のみ
00136                         - PC版シリアルポートをcom1~com10に拡張
00137                         - グローバル変数アドレスのADR_MYとSADR_MYを廃止
00138     2012/12/16  1.50    - Arduino版のライブラリ化
00139                         - コマンド応答待ち時に他のパケットをキャッシュ
00140                           (#define CACHE_RES 10でキャッシュが有効になる)
00141     2012/12/17  1.51    - リモートATの応答確認にAT値からMODE値に変更
00142                         - H8のバグ対応(lcd_h8.cの2重呼び出し対策等)
00143     2012/12/18  1.52    - [重要] 関数lcd()をlcd_disp()に変更。
00144                         - Arduino版ライブラリ側ハードLCD,LED,SWの無効化
00145     2012/12/22  1.53    - [重要] atnjとratnjの戻り値を失敗時255に変更
00146                         - ATコマンドを送信する関数を追加
00147     2012/12/23  1.54    - 1.53のエンバグの修正(テスト用printfの残留)
00148     2012/12/30  1.55    - Arduino LEONARDOへの対応
00149                         - Arduino標準LCDの配線変更(DF ROBOT互換に)
00150     2013/01/12  1.56    - xbee_result.GPI[0]とGPI[1]の戻り値を入れ替え
00151     2013/01/14  1.57    - xbee_gpio_configでアドレス取得失敗時のバグ修正
00152     2013/01/20  1.58    - xbee状態取得 xbee_ataiとxbee_atopコマンド追加
00153     2013/04/03  1.60    - xbee_initによるXBeeリセット時の応答の廃棄処理
00154                         - エラー出力を stderrに変更PC用(のみ)
00155                         - xbee_result.GPI.PORT.Dnのエンバグ(1.56~)修正
00156     2013/04/08  1.71    - [重要] Arduino xbee_rx_callを構造体受取に変更
00157                         - [重要] Arduino xbee_sensor_resultの引数の同上
00158                         - [重要] xbee_rx_callパケット選択受信機能を削除
00159                         - [重要] PC/H8 xbee_result.ADCをADCINに変更
00160                         - xbee_atに16進数のテキスト引数の処理のバグ修正
00161                         - xbee_atnjでjoin後にatnj=5を設定(5秒Join有効)
00162                         - PC/H8/Arduinoでライブラリを共通ソースに統合
00163     2013/04/21  1.72    - コマンド応答をxbee_rx_callで得るxbee_rat_force
00164                         - テキストをシリアル送信するxbee_uartの追加
00165                         - ZigBeeデバイスタイプを取得するxbee_atvrの追加
00166                         - ネットワーク参加状況を確認するxbee_ataiの追加
00167                         - コミッショニング操作を行うxbee_atcbの追加
00168                         - ネットワークIDを取得するxbee_atopの追加
00169                         - 暗号化xbee_atee_onと解除xbee_atee_offの追加
00170     2013/04/30  1.73    - PC版&Arduino版リリース
00171                         - 受信キャッシュオーバー時パケット廃棄(仕様変更)
00172     2013/05/09  1.74    - 初期化時にAPモード1の設定を追加
00173                         - #define LCD_H有効時以外のログ呼び出し停止
00174                         - 子機に本機アドレスを設定するxbee_set_myaddress
00175     2013/05/10  1.75    - End Deviceにスリープを設定するxbee_end_device
00176     2013/05/18  1.76    - [重要] 戻り値を送信パケット番号PACKET_IDに変更
00177                           xbee_gpo,同_force,同_batt,同_rat_force,同_uart
00178                         - [重要] Arduino xbee_resultにxbee_result.ID追加
00179     2013/05/25  1.77    - XBee Wi-Fi XBee IPによるリモートAT制御に対応
00180     2013/06/30  1.78    - 全マスクGPIO入力時xbee_result.GPI.BYTEを0xFFFF
00181                         - GPIO出力(xbee_gpo)の利用可能ポート範囲を拡大
00182     2013/08/28  1.79    - XBee Sensorのデバイス名(define)の追加
00183                         - xbee_end_deviceの親機のSP値を28秒固定に変更
00184     2013/09/28  1.80    - xbee_end_device Router時の自動送信設定を可能に
00185                         - xbee_resultのGPINに電池電圧ADC[0]にmV値を応答
00186                         - xbee_atnjでjoin後のatnj=5設定をatnj=0に変更
00187                         - リモートAT応答の送信元が取得できないバグ修正
00188                         - XBee Wi-Fi xbee_gpoを送信時の応答バグ修正
00189     2013/10/14  1.81    - Arduino版XBee Wi-Fi対応。XBee ZBは未テスト
00190                         - xbee_atd追加(End Device時に宛先アドレスを保存)
00191                         - xbee_ratd追加(親機アドレス以外も設定可能に)
00192                         - xbee_set_myaddress⇒xbee_ratd_myaddress名変更
00193                         - XBee Wi-Fi 3バイト以下UART受信不具合の修正
00194                         - XBee Wi-Fi ATDDで不適切な値を応答するバグ対策
00195                         - XBee Wi-Fiのフレーム受信でメモリーリーク対策
00196     2014/01/14  1.82    - ATmega32U4が使われている時はLEONARDOを自動定義
00197                         - シリアルポート異常時のSegFault不具合の修正
00198                         - 日時付エラーログ出力(PC用XBEE_ERROR_TIME定義)
00199     2014/02/17  1.83    - XBee Wi-Fi サンプルの各種不具合修正
00200                         - XBee Wi-Fi S2B対応(机上検討による実装)
00201                         - バイナリデータを子機UARTへ送信するxbee_bytes
00202                         - I2Cインタフェースを読み取るxbee_i2c_readの追加
00203                         - I2Cインタフェースで書き込むxbee_i2c_write追加
00204                         - 受信キャッシュをクリアするxbee_clear_cache追加
00205                         - 特定者向けリリース(I2C接続LCD,XBee Wi-Fi S2B)
00206     2014/02/23  1.84    - 無駄使いメモリの修正、表示の調整、累積バグ修正
00207                         - ATコマンド解析ツールxbee_test.cのhelpコマンド
00208                         - README内のバージョン齟齬に関する修正
00209     2014/03/01  1.85    - XBee WiFi S6B Ver.20xx対応(Ver.10xxと自動切替)
00210                          対応モジュール XBee WiFi S6 Ver.102D
00211                                  XBee WiFi S6B Ver.2021
00212     2014/03/17  1.86    - CQ出版様向けサンプルソフトウェアの正式リリース
00213     2014/06/21  1.87    - ARM mbed対応(試作品)
00214     2014/08/02  1.88    - シリアルCOMポート拡張(ポート番号1~64に対応)
00215                         - Arduino xbee_initでリトライ回数指定に。0で永久
00216                         - xbee_initに戻り値。異常時0。正常時リトライ数
00217                         - 受信しながら時間待ちするxbee_delay関数の追加
00218                         - 宛先ショートアドレス指定関数xbee_short_address
00219                         - ZigBee ZCL使用時(PC用)に関するバグ修正
00220     2014/08/24  1.89    - 内部関数xbee_resetの公開(ヘッダファイルへ追加)
00221                         - xbee_init 失敗時の戻り値の不具合を修正
00222                         - PC版 GCC Ver 4.7対応,最適化オプション-O1の付与
00223                         - 戻り値が不定になる内部関数の不具合修正
00224     2014/09/15  1.90    - 有志によるライブラリBeeBee Liteの一部機能採用
00225                          ・試験ツールxbee_agingを通過しない項目の調整
00226                          ・効果はArduino上でSD使用時のメモリ確保など
00227                         - xbee_bytesで規定サイズを超えた場合のリーク対策
00228                         - 下位マスク0x00のGPIN受信時にエラー出力バグ修正
00229     2014/10/25  1.91    - CQ出版 ZigBee Arduinoプログラム全集 第2版用
00230                         - ARM mbedでのシリアル受信時のロックアップ対策
00231                         - ARM mbedを用いた時のシリアル送信タイミング調整
00232                         - xbee_end_deviceでRouterへ送信時にIR値を設定
00233                          (従来はエラー応答だったが、設定後に正常応答)
00234     2014/10/31  1.92    - ARM mbed対応
00235 
00236 *********************************************************************/
00237 /*
00238 本ライブラリのバージョン
00239 */
00240 #ifndef VERSION
00241 
00242     #define     VERSION "1.91"      // 1.XX 4バイト形式 XXは半角文字
00243 
00244 #endif
00245 /*
00246 参考文献
00247 
00248     (1) Digi International Inc.
00249         XBee ZB RF Modules 90000976_D 8/18/2009
00250         XBee Wi-Fi RF Module 90002124_F 2011
00251     (2) Massimo Banzi著 船田功訳
00252         Arduinoをはじめよう (オライリージャパン)
00253     (3) BestTechnology CO.,LTD.
00254         H8/3664F I/O address definition Release 3.5 2005-11-08 (3694.h) 
00255     (4) 粕谷友章
00256         PC-UNIX関連ドキュメント「シリアルポートプログラミング」
00257         www006.upp.so-net.ne.jp/kasuya/linux/serial_io_programing.html
00258     (5) JM Project Linux Programmer's Manual
00259         Linux man-pages プロジェクト リリース 3.52 (GPL V2)
00260         linuxjm.sourceforge.jp/html/LDP_man-pages/man2/select.2.html
00261     (6) mbed Handbook
00262         mbed.org/handbook/Homepage
00263         
00264 ライセンスについて
00265 
00266     本ソースコードはライセンスフリーですが、参考文献の情報については
00267     それぞれの権利者にお問い合わせください。
00268 
00269 注意点
00270     本ソフトの利用による損害について当方は一切の補償をいたしません。
00271     全て自己責任で利用ください。
00272 */
00273 
00274 /*********************************************************************
00275 ライブラリ使用説明書
00276 
00277 ハードウェア
00278 
00279     PC用 以下のハードが必要です。
00280             ・USBを搭載したIBM PC/AT互換機(通常のWindows PC)
00281             ・XBee USBエクスプローラ、XBee-Fly USB または 純正XBIB-U-DEVなど
00282              (http://www.geocities.jp/bokunimowakaru/diy/xbee/xbee-usb.html)
00283             ・XBee Series 2 (ZB) モジュール
00284             
00285     Arduino 以下のハードが必要です。
00286             ・Arduinoマイコンボード Arduino UNO Arduino Leonardo等
00287             ・XBee Shield (Arduino Wireless SD Shieldなど)
00288             ・XBee Series 2 (ZB) モジュール
00289             ・LCDキャラクタディスプレイモジュール[20×4行] SC2004CS-B
00290             
00291              キャラクタ液晶は以下のように接続する
00292             
00293                                     rs rw en d0 d1 d2 d3
00294              // LiquidCrystal xbee_ardlcd( 8, 7, 6, 5, 4, 3, 2)
00295              
00296     ARM mbed用
00297             ・STマイクロ製 Nucleo Board STM32F401で動作確認しています。
00298             ・XBeeとの接続にはArduino用Wireless SD Shieldを使用します。
00299              ※Nucleoボードの裏側のジャンパー抵抗の変更が必要です。
00300                     「SB14」をオープンにします(抵抗を取り外します。)
00301                     「SB62」をショートします。(半田で接続します。)
00302                     「SB63」をショートします。(半田で接続します。)
00303             ・液晶を使用したサンプルはDF ROBOT製 LCD Keypad Shieldで
00304              動作確認しています。
00305 
00306     H3694用  秋月電子通商で販売されている以下のハードウェアが必要です。
00307             ・AKI-H8/3694F(QFP) タイニーマイコンキット
00308             ・H8タイニーI/O(アイ・オー)ボード
00309             ・小型スライドスイッチ 1回路2接点 SS12D01G4
00310             ・LCDキャラクタディスプレイモジュール[20×4行] SC2004CS-B
00311             ・XBeeモジュールをRS-232Cに接続する基板(純正XBIB-R-DEVなど)
00312              (http://www.geocities.jp/bokunimowakaru/pict/xbee-cord_sch.gif)
00313             ・RS-232Cケーブル
00314             ・XBee Series 2 (ZB) モジュール
00315             
00316              キャラクタ液晶はH8/3694のCN1の14~19ピンの各出力と電源、
00317              GNDを液晶モジュールのDB4~7およびE、RSの各入力、および
00318              電源に接続して製作します(下図参照)。 
00319 
00320                     AKI-H8      液晶モジュール
00321                     (CN1)       (HD44780搭載)
00322                     ━━┓      ┏━━━━━┓    ┯ 5V
00323                       ┃P50     ┃     ┃    |
00324                      14┠──────┨DB4  Vdd┠───●┘
00325                       ┃P51     ┃     ┃   |
00326                      15┠──────┨DB5    ┃   <
00327                       ┃P52     ┃     ┃ ┌→>
00328                      16┠──────┨DB6  VLC┠─┘ < 10k
00329                       ┃P53     ┃     ┃   |
00330                      17┠──────┨DB7 DB0-3┠─┐ |
00331                       ┃P54     ┃     ┃ | |
00332                      18┠──────┨E   R/W┠─● |
00333                       ┃P55     ┃     ┃ | |
00334                      19┠──────┨RS   Vss┠─●─●┐
00335                       ┃      ┗━━━━━┛   ┯┿┯
00336                       
00337 
00338     port:   port指定  IO名 ピン番号    共用     主な用途
00339             port= 0     DIO0    XBee_pin 20 (Cms)       Commision コミッションボタン
00340             port= 1     DIO1    XBee_pin 19 (AD1)       汎用入力用(DIN or AIN)
00341             port= 2     DIO2    XBee_pin 18 (AD2)       汎用入力用(DIN or AIN)
00342             port= 3     DIO3    XBee_pin 17 (AD3)       汎用入力用(DIN or AIN)
00343             port= 4     DIO4    XBee_pin 11             汎用出力用
00344             port= 5     DIO5    XBee_pin 15 (Ass)       ASSOSIATE indication
00345             port= 6     DIO6    XBee_pin 16 (RTS)       汎用出力用
00346             port=10     DIO10   XBee_pin  6 (RSSI)      RSSI indication (PWM)
00347             port=11     DIO11   XBee_pin  7             汎用出力用
00348             port=12     DIO12   XBee_pin  4             汎用出力用
00349 
00350 ソフト開発環境
00351 
00352     共通
00353             ・X-CTU (Digi社)
00354              PCもしくはH3694、Arduinoに接続する親機側のXBeeモジュールへ
00355              Coordinatorのファームウェアを書き込むのに必要です。
00356             
00357                 Device Type XBee Firmware    Ver. ハードウェア    
00358                 -----------------------------------------------------
00359                 Coordinator COORDINATOR API  2141 パソコンのシリアル端子
00360                                                   または秋月H8Tiny IO BOARD
00361                                                   またはArduino側に接続
00362                 End Device  END DEVICE AT    2841 単体で駆動  
00363 
00364     Arduino用
00365             ・Arduino IDE
00366     
00367     ARM mbed用
00368             ・https://mbed.org/compiler/
00369     
00370     PC用
00371             ・cygwin (http://www.cygwin.com/)
00372             ・インストール時にdevl内のgcc coreとmakeを選択すること
00373             
00374     H3694用
00375             ・GCC Developer Lite(株式会社ベストテクノロジー)
00376              http://www.besttechnology.co.jp/modules/knowledge/
00377 
00378             上記ホームページの「ナレッジベース」より、技術情報/ソフト
00379             ウェア/GCC Developer Liteからダウンロードできます。
00380             この開発環境に含まれるH3694用のターゲットファイルを使用し
00381             ていますので、他の環境で開発する場合は注意が必要です。
00382 */
00383 
00384 /*********************************************************************
00385 インポート処理
00386 *********************************************************************/
00387 
00388 #ifndef LCD_TYPE_H
00389     #define LCD_TYPE_H
00390     #ifdef ARDUINO
00391         #if defined(__AVR_ATmega32U4__)
00392             #define LEONARDO    // Arduino LEONARDを使用する場合に自動的に定義されます。
00393         #endif
00394     //  #define LCD_H       // 本ライブラリ動作を液晶表示する場合に定義する
00395     //  #define ADAFRUIT    // 使用する液晶が Adafruit LCD Sheild の時に定義する
00396     #else // H8 or ARM or PC
00397         #ifndef ARM_MBED    // H8 or PC
00398             #define LCD_H
00399         #endif
00400     #endif
00401 //  #define XBEE_WIFI   // XBee Wi-Fiを使用するときに定義する
00402 //  #define XBEE_WIFI_DEBUG
00403 //  #define LITE        // ライトモード(メモリ節約・機能制限)の時に定義する
00404     #define EASY_GPI    // xbee_gpi関数(リモートGPIO)を使用するときに定義する
00405     #define EASY_ADC    // xbee_adc関数(リモートADC)を使用するときに定義する
00406 //  ##define EASY_SENSOR
00407 #endif
00408 
00409 #ifndef XB_IMPORT_H
00410     #ifdef H3694
00411         #ifndef __3694_H__
00412             #include <3694.h>
00413         #endif
00414         #ifdef LCD_H
00415             #ifndef LCD_ROW_1
00416                 #include "lcd_h8.c"
00417             #endif
00418         #endif
00419         /*  // lcd_h8ライブラリの関数
00420         void lcd_delay(unsigned int data);
00421         void lcd_toggle_E(void);
00422         void lcd_cls(void);
00423         void lcd_home(void);
00424         void lcd_control(unsigned char disonoff, unsigned char curonoff, unsigned char curblink);
00425         void lcd_goto(unsigned char mesto);
00426         void lcd_shift(unsigned char data);
00427         void lcd_putch(char data);
00428         void lcd_putstr(const char *data);
00429         void lcd_disp_bin(unsigned char x);
00430         void lcd_disp_hex(unsigned char i);
00431         void lcd_disp_1(unsigned int x);
00432         void lcd_disp_2(unsigned int x);
00433         void lcd_disp_3(unsigned int x);
00434         void lcd_disp_5(unsigned int x);
00435         void lcd_init(void);
00436         */
00437     #elif ARDUINO
00438         //  #include <inttypes.h>
00439         #include "Arduino.h"
00440         //  #include "WProgram.h"   // #if ARDUINO < 100
00441         #ifdef LCD_H
00442             #ifndef ADAFRUIT
00443                 // 通常のキャラクタLCDの場合
00444                 #include <LiquidCrystal.h>
00445             #else
00446                 // Adafruit I2C接続LCDの場合(Adafruit_RGBLCDShieldライブラリが必要)
00447                 #include <Wire.h>
00448                 #include <Adafruit_MCP23017.h>
00449                 #include <Adafruit_RGBLCDShield.h>
00450             #endif
00451         #endif
00452         #ifdef XBEE_WIFI
00453             #include <SPI.h>
00454             #include <Ethernet.h>
00455             #include <EthernetUdp.h>
00456         #endif
00457         #ifndef LCD_ROW_1
00458             #define     LCD_ROW_1       0x00    //1行目先頭アドレス
00459             #define     LCD_ROW_2       0x40    //2行目先頭アドレス
00460             #define     LCD_ROW_3       0x14    //3行目先頭アドレス
00461             #define     LCD_ROW_4       0x54    //4行目先頭アドレス
00462         #endif
00463     #else
00464         #ifdef ARM_MBED // ARM
00465         //  #include "mbed.h"
00466             #ifdef DEBUG
00467                 #define LCD_H
00468                 #define ERRLOG
00469                 #define     LCD_ROW_1       0x00    //1行目先頭アドレス
00470                 #define     LCD_ROW_2       0x40    //2行目先頭アドレス
00471                 #define     LCD_ROW_3       0x14    //3行目先頭アドレス
00472                 #define     LCD_ROW_4       0x54    //4行目先頭アドレス
00473             #endif
00474         #else // PC
00475             #include <stdio.h>
00476             #include <stdlib.h>
00477             #include <string.h>
00478             #include <termios.h>
00479             #include <sys/signal.h>
00480             #include <sys/time.h>
00481             #include <fcntl.h>
00482             #include <unistd.h>
00483             #include <arpa/inet.h>
00484             #ifdef XBEE_WIFI
00485                 #include <sys/types.h>
00486                 #include <sys/socket.h>
00487                 #include <netinet/in.h>
00488                 #include <ctype.h>
00489                 #include <sys/ioctl.h>
00490                 #include <string.h>
00491             #endif
00492             #define BAUDRATE B9600
00493             #ifndef LCD_ROW_1
00494                 #include "lcd_pc.c"
00495             #endif
00496             #include <time.h>           // クロックタイマー用
00497         #endif
00498     #endif
00499     #define xbee_set_myaddress(adr) xbee_ratd_myaddress(adr)
00500 #endif
00501 
00502 /*********************************************************************
00503 定数の設定
00504 *********************************************************************/
00505 #ifndef XB_DEFINE_H
00506     #define XB_DEFINE_H
00507     #ifndef NAME
00508         #ifdef LITE // BeeBee Lite by 蘭
00509             #define     NAME        "BeeBee Lite"
00510             #define     COPYRIGHT   "by Wataru & Ran"
00511         #else
00512             #define     NAME        "ZB Coord"
00513             #define     COPYRIGHT   "by Wataru KUNINO"
00514         #endif
00515     #endif
00516 
00517     #ifdef H3694
00518         #define ERRLOG
00519         #define LED1_OUT    IO.PDR8.BIT.B0  // LED赤の接続ポート(エラー用)
00520         #define LED2_OUT    IO.PDR8.BIT.B1  // LED緑の接続ポート(動作確認用)
00521         #define LCD_EN      IO.PDR8.BIT.B6  // 液晶用電源
00522         #define BUTN        IO.PDR8.BIT.B2  // ボタンの接続ポート
00523         #define SCI_SIZE    256             // シリアルデータ長(大きすぎるとRAMが不足する)
00524         #define API_SIZE    128             // 受信用APIデータ長(32~255)
00525         #define API_TXSIZE  64              // 送信用APIデータ長(32~255) シリアル送信最大長=API_TXSIZE-18バイト
00526         #define CALL_SIZE   32              // xbee_rx_call用戻りデータ(10~256)
00527         #define XB_AT_SIZE  32              // ATコマンドの最大長
00528     #elif ARDUINO
00529     //  #define LED1_OUT    15              // 赤色LED(エラー用)用デジタルポート(15=analog 1)
00530     //  #define LED2_OUT    16              // 緑色LED(動作確認用)用デジタルポート(16=analog 2)
00531     //  #define LCD_EN       6              // 液晶用電源デジタルポート
00532     //  #define BUTN        14              // ボタンの接続ポート(14 = analog 0)
00533         #ifdef LITE // BeeBee Lite by 蘭
00534             #define     API_SIZE    48      // 受信用APIデータ長(32~255)
00535             #define     API_TXSIZE  34      // 送信用APIデータ長(32~255) シリアル送信最大長=API_TXSIZE-18バイト
00536             #define     CALL_SIZE   16      // xbee_rx_call用戻りデータ(10~256)
00537             #define     XB_AT_SIZE  16      // ATコマンドの最大長
00538         #else
00539             #define     CACHE_RES   2       // 応答時のキャッシュ数(無効にするには定義を消す)
00540             #define     API_SIZE    64      // 受信用APIデータ長(32~255)
00541             #define     API_TXSIZE  64      // 送信用APIデータ長(32~255)
00542             #define     CALL_SIZE   32      // xbee_rx_call用戻りデータ(10~256)
00543             #define     XB_AT_SIZE  32      // ATコマンドの最大長
00544         #endif
00545         #define LIGHT           1
00546         #define TEMP            2
00547         #define HUMIDITY        3
00548         #define WATT            4
00549         #define BATT            5
00550         #define DISABLE         0
00551         #define VENDER          1
00552         #define AIN             2
00553         #define DIN             3
00554         #define DOUT_L          4
00555         #define DOUT_H          5
00556     #else
00557         #ifdef ARM_MBED // ARM      <条件は調整していない。ほぼArduinoのまま>
00558             #define     CACHE_RES   3       // 応答時のキャッシュ数(無効にするには定義を消す)
00559             #define     API_SIZE    64      // 受信用APIデータ長(32~255)
00560             #define     API_TXSIZE  64      // 送信用APIデータ長(32~255)
00561             #define     CALL_SIZE   32      // xbee_rx_call用戻りデータ(10~256)
00562             #define     XB_AT_SIZE  32      // ATコマンドの最大長
00563             #define     delay(ms)       wait_millisec(ms)   // 関数名の複製
00564             #define LIGHT           1
00565             #define TEMP            2
00566             #define HUMIDITY        3
00567             #define WATT            4
00568             #define BATT            5
00569             #define DISABLE         0
00570             #define VENDER          1
00571             #define AIN             2
00572             #define DIN             3
00573             #define DOUT_L          4
00574             #define DOUT_H          5
00575         #else // PC
00576             // #define DEBUG                    // デバッグモード
00577             // #define DEBUG_TX                 // 送信パケットの表示
00578             // #define DEBUG_RX                 // 受信パケットの表示
00579             #define     ERRLOG                  // エラー時にログを出力
00580         //  #define     XBEE_ERROR_TIME         // エラー時のログに日時を付与
00581             #ifdef LITE // BeeBee Lite by 蘭
00582                 #define     API_SIZE    48      // 受信用APIデータ長(32~255)
00583                 #define     API_TXSIZE  34      // 送信用APIデータ長(32~255)
00584                 #define     CALL_SIZE   16      // xbee_rx_call用戻りデータ(10~256)
00585                 #define     XB_AT_SIZE  16      // ATコマンドの最大長
00586             #else
00587                 #define     CACHE_RES   5           // 応答時のキャッシュ数(無効にするには定義を消す)
00588                 #define     API_SIZE    128         // 受信用APIデータ長(32~255)
00589                 #define     API_TXSIZE  64          // 送信用APIデータ長(32~255)
00590                 #define     CALL_SIZE   64          // xbee_rx_call用戻りデータ(10~256)
00591                 #define     XB_AT_SIZE  32          // ATコマンドの最大長
00592                 #define     delay(ms)       wait_millisec(ms)   // 関数名の複製
00593             #endif
00594         #endif
00595     #endif
00596     #define     TIME_DEL    3               // デリミタ検出のタイムアウト時間(秒)
00597     #define     MODE_AUTO   0x00            // 自動受信モード
00598     #define     MODE_GPIN   0x92            // GPI data を受信するモード
00599     #define     MODE_UART   0x90            // UART data を受信するモード
00600     #define     MODE_UAR2   0x91            // UART data を受信するモード2(AO=1)
00601     #define     MODE_SENS   0x94            // XB Sensorを受信するモード(1wire専用→通常のSensorはATISを使用)
00602     #define     MODE_IDNT   0x95            // Node Identifyを受信するモード
00603     #define     MODE_RES    0x88            // ローカルATコマンドの結果を受信
00604     #define     MODE_RESP   0x97            // リモートATコマンドの結果を受信(仕様書はATNDで説明ATISもこれ)
00605     #define     MODE_MODM   0x8A            // Modem Statusを受信
00606     #define     MODE_TXST   0x8B            // UART Transmit Status を受信
00607     #define     MODE_BATT   0xE1            // (独自定義)バッテリステータス RAT%Vの応答時
00608                 // XBeeのFrame Typeに準拠する。
00609                 // 注意:モードを増やしたときはxbee_from_acumとxbee_rx_call内の対応を追加すること
00610                 // 独自定義の時はxbee_rx_call内のみ。
00611                 // MODE値はenum定義にしない。
00612                 
00613     #define     STATUS_OK       0x00        // ATコマンドの結果がOK
00614     #define     STATUS_ERR      0x01        // ATコマンドの結果がERROR
00615     #define     STATUS_ERR_AT   0x02        // 指定されたATコマンドに誤りがある
00616     #define     STATUS_ERR_PARM 0x03        // 指定されたパラメータに誤りがある
00617     #define     STATUS_ERR_AIR  0x04        // リモートATコマンドの送信の失敗(相手が応答しない)
00618     
00619     #define     MODM_RESET      0x01        // ローカルのXBeeがリセットした
00620     #define     MODM_WATCHDOG   0x02        // ローカルのXBeeがWatch dogタイマーによってリセットした
00621     #define     MODM_JOINED     0x03        // (RouterまたはEnd Deviceで使用しているときに)ネットワークJoinした
00622     #define     MODM_LEFT       0x04        // ネットワークからdis_assosiateした
00623     #define     MODM_STARTED    0x06        // (coordinatorで使用しているときに)Coordinatorを開始した
00624     
00625     #define     DEV_TYPE_XBEE   0x00        // XBeeモジュール
00626     #define     DEV_TYPE_RS232  0x05        // RS-232Cアダプタ
00627     #define     DEV_TYPE_SENS   0x07        // Sensor (1wire専用)
00628     #define     DEV_TYPE_WALL   0x08        // Wall Router
00629     #define     DEV_TYPE_SEN_LT     0x0E        // Sensor (照度・温度)
00630     #define     DEV_TYPE_SEN_LTH    0x0D        // Sensor (照度・温度・湿度)
00631     #define     DEV_TYPE_PLUG   0x0F        // Smart Plug
00632     
00633     #define     ZB_TYPE_COORD   0x21        // ZigBee Coordinator
00634     #define     ZB_TYPE_ROUTER  0x23        // ZigBee Router
00635     #define     ZB_TYPE_ENDDEV  0x29        // ZigBee End Device
00636     #define     XB_TYPE_NULL    0x00        // XBee Wi-Fi バージョン未取得
00637     #define     XB_TYPE_WIFI10  0x10        // XBee Wi-Fi Ver. 10xx
00638     #define     XB_TYPE_WIFI20  0x20        // XBee Wi-Fi Ver. 20xx
00639 
00640     #define     NET_ADR     FFFE            // ネットワークアドレス
00641 #endif
00642 
00643 /*********************************************************************
00644 型の定義とグローバル変数の宣言
00645 *********************************************************************/
00646 #ifndef XB_GLOBAL_H
00647     #define XB_GLOBAL_H
00648     typedef unsigned char byte;             // Arduinoでも必要
00649     #ifdef H3694
00650         byte        TIMER_SEC   =   0   ;   //RTCカウント用1秒単位
00651         char sci_tx[SCI_SIZE];              // シリアル用
00652         char sci_rx[SCI_SIZE];
00653     #elif ARDUINO
00654         #define TIMER_SEC   time1s256()
00655     #else
00656         #ifdef ARM_MBED
00657             #define TIMER_SEC   time1s256()
00658         #else  // PC
00659             #define TIMER_SEC   time1s256()     // TIMER_SECのカウントアップの代わり
00660             volatile byte LED1_OUT;
00661             volatile byte LED2_OUT;
00662             volatile byte LCD_EN;
00663         #endif
00664     #endif
00665 
00666     #ifdef ARDUINO
00667         #ifdef LCD_H
00668             #ifndef ADAFRUIT
00669                 // 通常のキャラクタLCDの場合
00670                 LiquidCrystal xbee_ardlcd(8, 9, 4, 5, 6, 7);
00671                                 //LCD設定 rs en d0 d1 d2 d3
00672             #else
00673                 // Adafruit I2C接続LCDの場合(Adafruit_RGBLCDShieldライブラリが必要)
00674                 Adafruit_RGBLCDShield xbee_ardlcd = Adafruit_RGBLCDShield();
00675             #endif
00676         #endif
00677         
00678         // 構造体の宣言
00679         typedef struct{
00680             byte MODE;              // 受信モード(Frame Type)
00681             byte FROM[8];           // 送信元IEEEアドレス
00682             byte AT[2];             // ATコマンド
00683             byte ID;                // 応答パケットID(Frame ID)
00684             byte STATUS;            // 応答結果(0:OK 1:ERROR)/AT結果/UART状態
00685             union {                 // GPIOデータ
00686                 byte BYTE[2];
00687                 struct {            // バイト毎に下位ビットから代入(リトルエンディアン)
00688                     byte D0 :1; byte D1 :1; byte D2 :1; byte D3 :1; // BYTE[1]
00689                     byte D4 :1; byte D5 :1; byte D6 :1; byte D7 :1;
00690                     byte    :1; byte    :1; byte D10:1; byte D11:1; // BYTE[0]
00691                     byte D12:1; byte    :1; byte    :1; byte    :1;
00692                 } PORT;
00693             } GPI;
00694             //  byte GPI[2];            // GPIOデータ
00695             unsigned int ADCIN[4];  // ADCデータ
00696             byte DATA[CALL_SIZE];   // 受信データ
00697         } XBEE_RESULT;              // 構造体の型名
00698     #else
00699         #ifdef ARM_MBED // ARM
00700             // 構造体の宣言
00701             typedef struct{
00702                 byte MODE;              // 受信モード(Frame Type)
00703                 byte FROM[8];           // 送信元IEEEアドレス
00704                 byte AT[2];             // ATコマンド
00705                 byte ID;                // 応答パケットID(Frame ID)
00706                 byte STATUS;            // 応答結果(0:OK 1:ERROR)/AT結果/UART状態
00707                 union {                 // GPIOデータ
00708                     byte BYTE[2];
00709                     struct {            // バイト毎に下位ビットから代入(リトルエンディアン)
00710                         byte D0 :1; byte D1 :1; byte D2 :1; byte D3 :1; // BYTE[1]
00711                         byte D4 :1; byte D5 :1; byte D6 :1; byte D7 :1;
00712                         byte    :1; byte    :1; byte D10:1; byte D11:1; // BYTE[0]
00713                         byte D12:1; byte    :1; byte    :1; byte    :1;
00714                     } PORT;
00715                 } GPI;
00716                 //  byte GPI[2];            // GPIOデータ
00717                 unsigned int ADCIN[4];  // ADCデータ
00718                 byte DATA[CALL_SIZE];   // 受信データ
00719             } XBEE_RESULT;              // 構造体の型名
00720         #else // PC
00721             enum xbee_sensor_type{ LIGHT,TEMP,HUMIDITY,WATT,BATT,PRESS,VALUE,TIMES,NA };    // センサタイプの型
00722             enum xbee_port_type{ DISABLE=0, VENDER=1, AIN=2, DIN=3, DOUT_L=4, DOUT_H=5 };
00723                                                                     // GPIOの設定の型
00724             typedef struct{
00725                 byte MODE;              // 受信モード(Frame Type)
00726                 byte FROM[8];           // 送信元IEEEアドレス
00727                 byte SHORT[2];          // 送信元ショートアドレス
00728                 byte AT[2];             // ATコマンド
00729                 byte ID;                // 応答パケットID(Frame ID)
00730                 byte STATUS;            // 応答結果(0:OK 1:ERROR)/AT結果/UART状態
00731                 union {                 // GPIOデータ
00732                     byte BYTE[2];
00733                     struct {
00734                         #ifdef H3694    // H8ではバイト毎に上位ビットから代入(ビッグエンディアン)
00735                         byte D7 :1; byte D6 :1; byte D5 :1; byte D4 :1; // BYTE[1]
00736                         byte D3 :1; byte D2 :1; byte D1 :1; byte D0 :1;
00737                         byte    :1; byte    :1; byte    :1; byte D12:1; // BYTE[0]
00738                         byte D11:1; byte D10:1; byte    :1; byte    :1;
00739                         #else           // PCではバイト毎に下位ビットから代入(リトルエンディアン)
00740                         byte D0 :1; byte D1 :1; byte D2 :1; byte D3 :1; // BYTE[1]
00741                         byte D4 :1; byte D5 :1; byte D6 :1; byte D7 :1;
00742                         byte    :1; byte    :1; byte D10:1; byte D11:1; // BYTE[0]
00743                         byte D12:1; byte    :1; byte    :1; byte    :1;
00744                         #endif
00745                     } PORT;
00746                 } GPI;
00747                 unsigned int ADCIN[4];  // ADCデータ
00748                 byte ZCL[6];            // [0]送信元EndPoint, [1]宛先EndPoint, [2-3]クラスタID, [4-5]プロファイルID
00749                 byte DATA[CALL_SIZE];   // ペイロードデータ/ZCLヘッダ+受信データ
00750             } XBEE_RESULT;
00751         #endif
00752     #endif
00753     #ifdef CACHE_RES
00754         byte CACHE_MEM[CACHE_RES][API_SIZE];
00755         byte CACHE_COUNTER = 0;
00756     #endif
00757 #endif
00758 
00759 #ifdef XBEE_WIFI
00760 byte ADR_MY[] = {0xFF,0xFF,0xFF,0xFF};
00761     #ifdef ARDUINO
00762         extern byte mac[6];
00763         EthernetUDP UdpXBeeR;
00764         EthernetUDP UdpXBeeT;
00765         EthernetUDP UdpXBeeU;
00766     #endif
00767 #endif
00768 
00769 /*********************************************************************
00770 スタティック変数の宣言
00771 *********************************************************************/
00772 
00773 /* エラーログ用 */
00774 #ifdef ERRLOG
00775 static byte     TIMER_ERR   =   0   ;       //エラー経過時間1秒単位
00776 static char     ERR_LOG[API_TXSIZE-18];
00777 static byte     ERR_CODE=0x00;
00778 #endif
00779 
00780 /* IEEEアドレス(最小限の通信対象をライブラリ側で保持する)/複数のデバイスへの対応はアプリ側で行う*/
00781 static byte ADR_FROM[]=     {0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF};  //差出人のIEEEアドレス(変更可)
00782 
00783 // 以下にお手持ちのXBeeのアドレスを予め設定しておくと毎回の検索が不要です。
00784 static byte ADR_DEST[]=     {0x00,0x13,0xA2,0x00,0x00,0x00,0x00,0x00};  //宛先のIEEEアドレス(変更可)
00785 
00786 /* ショートアドレス/本ライブラリでの宛先指定はIEEEのみを使う */
00787 static byte SADR_DEST[]=    {0xFF,0xFE};            //ブロード(ショート)アドレス
00788 static byte PACKET_ID = 0;                          //送信パケット番号
00789 
00790 /* XBeeのデバイスタイプ ATVRの上2ケタ */
00791 static byte DEVICE_TYPE = ZB_TYPE_COORD;            // Coord=0x21 Router=23 ED=29 Wi-Fi=10
00792 
00793 #ifndef H3694
00794 #ifndef ARDUINO
00795 #ifndef ARM_MBED // PC
00796     #ifndef XBEE_WIFI
00797         static byte xbee_com_port;
00798         static int xbeeComFd;
00799         static struct termios oldtio; /* current serial port settings (現在のシリアルポートの設定を待避)*/
00800     //  static byte *receive_buffer; 
00801     #else // XBEE_WIFI
00802          int xbeeTSFd;                          // XBee Wi-Fi 送信ソケット用 ディスクリプタ
00803          int xbeeRSFd;                          // XBee Wi-Fi 受信ソケット用 ディスクリプタ
00804          int xbeeUSFd;                          // XBee Wi-Fi UARTソケット用 ディスクリプタ
00805          struct sockaddr_in xbeeT_addr;         // XBee Wi-Fi 送信アドレス構造体変数
00806          struct sockaddr_in xbeeR_addr;         // XBee Wi-Fi 受信アドレス構造体変数
00807          struct sockaddr_in xbeeU_addr;         // XBee Wi-Fi UARTアドレス構造体変数
00808     #endif
00809 #endif
00810 #endif
00811 #endif
00812 
00813 /*********************************************************************
00814 ハードウェア
00815 *********************************************************************/
00816 
00817 /* H8タイニーマイコン H3694用のタイマー設定、GPIOポート設定 */
00818 #ifdef H3694
00819     void port_init(void){
00820         
00821         /*ポート1          76543210*/
00822         IO.PMR1.BYTE  = 0b00000000;     // モード(P1,5)  入出力=0  その他=1
00823         IO.PCR1       = 0b11110110;     // 入出力設定      入力  =0  出力  =1  B3=リザーブ
00824         IO.PUCR1.BYTE = 0b00000000;     // プルアップ(P1,5) しない=0  する    =1
00825         IO.PDR1.BYTE  = 0b00000000;     // アクセス         L出力=0  H出力=1
00826 
00827         /*ポート8          76543210*/   // 秋月 H8 Tiny I/O BOARD TERA2 [K-00207]用
00828         IO.PCR8       = 0b11111011;     // 入出力設定      入力  =0  出力  =1
00829         IO.PDR8.BYTE  = 0b00000000;     // アクセス         L出力=0  H出力=1
00830     }
00831 
00832     /* タイマー初期化 */
00833     void timer_sec_init(void){
00834         DI; 
00835         TA.TMA.BYTE     =0b00001000;  /* 時計用クロック  */
00836     /*                     |  |||-|__ 分周比 000~111(高速時) 000~011(低即時)
00837                  固定値 ___|--||          000:0.5120 sec.  000 1000 msec.
00838                                |             001:0.2560 sec.  001  500 msec.
00839          高速=0, 低速=1 _______|             100:0.0160 sec.  010  250 msec.
00840                                            111:0.0005 sec.  011   31.25 msec.*/
00841 
00842         IRR1.BIT.IRRTA  =0;           /* タイマーA割込みフラグのリセット */
00843         IENR1.BIT.IENTA =1;           /* タイマーA割込みを利用可能にする */
00844         EI;
00845     }
00846 
00847     /* AKI H8 TINY IO BOARD TERA2 用/PC用の接続デバイス設定*/
00848     byte led_red( const byte in ){
00849         if      ( in == 0 ) LED1_OUT=0;
00850         else if ( in == 1 ) LED1_OUT=1;
00851         return( LED1_OUT );
00852     }
00853     byte led_green( const byte in ){
00854         if      ( in == 0 ) LED2_OUT=0;
00855         else if ( in == 1 ) LED2_OUT=1;
00856         return( LED2_OUT );
00857     }
00858     byte button( void ){
00859         return( BUTN );
00860     }
00861     void lcd_enable( const byte in ){
00862         LCD_EN = in;
00863     }
00864 #endif
00865 
00866 /* ARM mbed 用 のタイマー設定 */
00867 #ifdef ARM_MBED         // http://mbed.org/handbook/Timer
00868     Timer _xbee_time;   // http://mbed.org/teams/Aerodyne/code/Timer/file/1d3fd5616c0a/Timer.cpp
00869     void _xbee_time_init(){
00870         _xbee_time.start();
00871     }
00872 #endif
00873 
00874 /* RTC使用1秒カウント */
00875 byte time1s256(){
00876     #ifdef H3694
00877         return(0x00);
00878     #elif ARDUINO
00879         return( (byte)(millis()/1000) );
00880     #else
00881         #ifdef ARM_MBED
00882         //  return( (byte)(_xbee_time.read_ms()/1024) );
00883             if(_xbee_time.read()>=262144.0f)_xbee_time.reset();
00884             return( (byte)(_xbee_time.read()) );
00885         //  return(0);
00886         #else //PC
00887             // char c='\0';
00888             // if (kbhit()) c = getch();
00889             time_t sec;
00890             time( &sec );
00891             return( (byte)sec );
00892         #endif
00893     #endif
00894 }
00895 
00896 /*  RTCによる割り込み処理(1秒毎)  */
00897 #ifdef H3694
00898     void int_timera(void){
00899         led_green( TIMER_SEC & 0x01 );  // LEDの正常点滅
00900         #ifdef ERRLOG
00901             if( led_red( 0xFF ) == 1 ) TIMER_ERR++;     // エラー秒数(LED_赤でエラー検出)
00902         #endif
00903         TIMER_SEC++;                // タイマーのカウントアップ
00904         IRR1.BIT.IRRTA=0;           // タイマーA割込フラグのリセット
00905     }
00906 #endif
00907 
00908 /* シリアル待ち時間の時間カウント用、RTC使用1秒間に256カウント */
00909 byte timera(void){
00910     #ifdef H3694
00911         return( (byte)TA.TCA );
00912     #elif ARDUINO
00913         return( (byte)( (millis()/4)%256 ) );
00914     #else
00915         #ifdef ARM_MBED
00916             return( (byte)((_xbee_time.read_ms()/4)%256) );
00917         //  return( (byte)(_xbee_time.read()*256) );
00918         //  return(0);
00919         #else //PC
00920             return( (byte)(clock()/(CLOCKS_PER_SEC/256))  );
00921         #endif
00922     #endif
00923 }
00924 
00925 /* ミリ秒待ち(250ms以下の高精度用) 入力範囲=4~250 ms */
00926 #ifndef ARDUINO // BeeBee Lite by 蘭
00927 void wait_millisec_250( byte ms ){
00928     #ifdef H3694
00929         byte counter;
00930         
00931         if( ms < 0x04 ) ms = 0x04;
00932         counter = timera() + (byte)( ms>>2 );
00933         if( counter == timera() ) counter++;
00934         while( counter != timera() );
00935     #elif ARDUINO
00936         delay( (unsigned long) ms );
00937     #else
00938         #ifdef ARM_MBED
00939             wait((float)ms/1000);
00940         #endif
00941     #endif
00942 }
00943 #endif
00944 
00945 /* ミリ秒待ち(30秒までの広範囲版) 入力範囲=4~30,000 ms */
00946 void wait_millisec( const unsigned int ms ){
00947     #ifdef H3694
00948         byte loops;
00949         if( ms < 250 ){
00950             wait_millisec_250( (byte)ms );
00951         }else{
00952             loops = (byte)( ms / 250);
00953             wait_millisec_250( (byte)(ms-loops*250) );
00954             while( loops > 0x00 ){
00955                 wait_millisec_250( 0xFA );
00956                 loops--;
00957             }
00958         }
00959     #elif ARDUINO
00960         delay( (unsigned long) ms );
00961     #else
00962         #ifdef ARM_MBED
00963             wait((float)ms/1000.0f);
00964         #else // PC
00965             time_t target;
00966             
00967             target = (time_t)(clock()/(CLOCKS_PER_SEC/1000)) + (time_t)ms;
00968             if( target >= (time_t)ms ){
00969                 while( (time_t)(clock()/(CLOCKS_PER_SEC/1000)) <= target );
00970             }else{
00971                 while( (time_t)(clock()/(CLOCKS_PER_SEC/1000)) > (time_t)ms );      // クロックがリセットされるまで待つ
00972                 while( (time_t)(clock()/(CLOCKS_PER_SEC/1000)) <= target );
00973             }
00974         #endif
00975     #endif
00976 }
00977 
00978 /* 経過時間測定=4~1000 ms 以内 単位は1/256秒毎 */
00979 byte past_time(const byte time_from){
00980     return( timera() - time_from );
00981 }
00982 
00983 /* XBeeのADCの有効ポート数を調べる ADC1~3のみ 入力=バイトデータ 応答0~3個 */
00984 byte xbee_adc_count( byte d ){
00985     return( ((d>>1)&0x01)+((d>>2)&0x01)+((d>>3)&0x01) );
00986 }
00987 
00988 /* XBee用シリアル通信ドライバ */
00989 #ifndef ARDUINO
00990 #ifndef H3694
00991 #ifndef ARM_MBED
00992 #ifndef XBEE_WIFI
00993     int open_serial_port(char *modem_dev){
00994         /*
00995         PC-UNIX関連ドキュメント
00996         「シリアルポートプログラミング」
00997         http://www006.upp.so-net.ne.jp/kasuya/linux/serial_io_programing.html
00998         writer:粕谷友章 kasuya@pd5.so-net.ne.jp 
00999         */
01000         struct termios newtio;
01001         speed_t speed = B9600;
01002         xbeeComFd=open(modem_dev,O_RDWR);
01003         if(xbeeComFd < 0){
01004             perror(modem_dev);
01005             return -1;
01006         }else{
01007             tcgetattr(xbeeComFd,&oldtio);
01008             newtio.c_iflag = 0;
01009             newtio.c_oflag = 0;
01010             newtio.c_cflag = 0;
01011             newtio.c_lflag = 0;
01012             newtio.c_line = 0;
01013             bzero(newtio.c_cc,sizeof(newtio.c_cc));
01014             cfsetispeed( &newtio, speed );
01015             cfsetospeed( &newtio, speed );
01016             newtio.c_cflag = BAUDRATE | CLOCAL | CREAD ;
01017             newtio.c_cflag &= ~CSIZE;
01018             newtio.c_cflag |= CS8;
01019             newtio.c_oflag = 0;
01020             newtio.c_lflag = 0;
01021             newtio.c_cc[VMIN] = 0;
01022             newtio.c_cc[VTIME] = 0;
01023             tcflush(xbeeComFd,TCIFLUSH);
01024             tcsetattr(xbeeComFd,TCSANOW,&newtio);
01025         }
01026         return 0;
01027     }
01028     void close_serial_port(void){
01029         tcsetattr(xbeeComFd,TCSANOW,&oldtio);
01030         close(xbeeComFd);
01031     }
01032 #else   // XBEE_WIFI(arduino除く)
01033     int open_serial_port_tx(const byte *address){               // modem_dev=IPアドレスのポインタ
01034         byte i;
01035         in_addr_t ip=0;                                 // 送信アドレス
01036         
01037         for(i=0;i<4;i++){
01038             ip *= 256;
01039             ip += (in_addr_t)(byte)address[3-i];        // アドレス順序は反転する
01040         }
01041         /* 送信アドレス設定 */
01042         memset(&xbeeT_addr, 0, sizeof(xbeeT_addr));     // xbeeT_addrの初期化
01043         xbeeT_addr.sin_family = AF_INET;                // アドレスファミリー AF_INET
01044         xbeeT_addr.sin_port = htons( 0xBEE );                   // 送信ポート番号
01045         xbeeT_addr.sin_addr.s_addr = ip;                        // 送信IPアドレス
01046         /* ソケット生成 */
01047         xbeeTSFd = socket(AF_INET, SOCK_DGRAM, 0);  // 送信用ソケットの生成
01048         #ifdef DEBUG
01049             printf("IP(TX)=%s\n", inet_ntoa( xbeeT_addr.sin_addr ) );
01050         #endif
01051         return 0;
01052     }
01053     int open_serial_port_rx( void ){                // modem_dev=IPアドレスのポインタ
01054         /* 受信アドレス設定 */
01055         memset(&xbeeR_addr, 0, sizeof(xbeeR_addr));     // xbeeR_addrの初期化
01056         memset(&xbeeU_addr, 0, sizeof(xbeeU_addr));     // xbeeU_addrの初期化
01057         xbeeR_addr.sin_family = AF_INET;                // アドレスファミリー AF_INET
01058         xbeeU_addr.sin_family = AF_INET;                // アドレスファミリー AF_INET
01059         xbeeR_addr.sin_port = htons( 0xBEE );                   // 受信ポート番号(3054)
01060         xbeeU_addr.sin_port = htons( 0x2616 );                  // 受信ポート番号(9750 board-voip)
01061         xbeeR_addr.sin_addr.s_addr = htonl(INADDR_ANY);         // 受信IPアドレス(ANY)
01062         xbeeU_addr.sin_addr.s_addr = htonl(INADDR_ANY);         // 受信IPアドレス(ANY)
01063         /* ソケット生成 */
01064         xbeeRSFd = socket(AF_INET, SOCK_DGRAM, 0);  // 受信用ソケットの生成
01065         xbeeUSFd = socket(AF_INET, SOCK_DGRAM, 0);  // 受信用ソケットの生成
01066         /* バインド */
01067         return( 
01068             bind(xbeeRSFd, (struct sockaddr *)&xbeeR_addr, sizeof(xbeeR_addr)) +
01069             bind(xbeeUSFd, (struct sockaddr *)&xbeeU_addr, sizeof(xbeeU_addr))
01070         );
01071     }
01072     int open_serial_port(const byte *modem_dev){                // modem_dev=IPアドレスのポインタ
01073         /*  UDPソケットを生成する。戻り値:0=成功、-1=エラー 
01074         入力はcharだけど中ではbyteとして扱う。byteアドレス→char入力→byte使用なので変換は不要 */
01075         open_serial_port_tx( modem_dev );
01076         return( open_serial_port_rx( ) );
01077     }
01078     void close_serial_port_tx(void){
01079         close(xbeeTSFd);
01080         #ifdef DEBUG
01081             printf("DEBUG:close xbee tx sock\n");
01082         #endif
01083     }
01084     void close_serial_port(void){
01085         close(xbeeTSFd);
01086         close(xbeeRSFd);
01087         close(xbeeUSFd);
01088         #ifdef DEBUG
01089             printf("DEBUG:close xbee tx and rx sock\n");
01090         #endif
01091     }
01092 #endif
01093 #endif  // not ARM
01094 #endif  // not H3694
01095 #endif  // not ARDUINO
01096 
01097 #ifdef ARDUINO
01098 #ifdef XBEE_WIFI
01099 int open_serial_port(void){
01100     Ethernet.begin(mac);
01101     delay(1000);
01102     UdpXBeeU.begin(0x2616);         // UART受信用のUDP開始
01103     UdpXBeeR.begin(0xBEE);          // URAT リモートATコマンド受信用のUDPの開始
01104     UdpXBeeT.begin(0xBEE);          // URAT リモートATコマンド送信用のUDPの開始
01105     return( 0 );
01106 }
01107 #endif  // XBEE_WIFI
01108 #endif  // ARDUINO
01109 
01110 /* シリアルの初期化 */
01111 /*
01112 #ifdef ARM_MBED
01113     RawSerial _xbee_serial(SERIAL_TX, SERIAL_RX); // USART2
01114     // RawSerial _xbee_serial(D1, D0); // 
01115     #ifdef DEBUG
01116         RawSerial _xbee_debug(PA_9, NC);          // USART1
01117     //  RawSerial _xbee_debug(PA_9, PA_10);       // USART1
01118     #endif
01119 #endif
01120 */
01121 
01122 /* シリアル受信用コールバック(ARM専用) */
01123     /* Serial.readableで確認してからSerial.getcする方法だと、連続した2バイト以上の
01124      データ列を受信できなかった。STマイクロの問題なのかmbedの問題かは不明だが、
01125      ハードウェアの受信バッファ内のデータをうまく読めないものと思う。
01126      したがって、割込みで取り込んでソフト受信バッファを実装することにした。
01127      バッファサイズはとりあえず128バイト */
01128 #ifdef ARM_MBED
01129 #define ARM_RX_BUFFER   64
01130 volatile byte _xbee_serial_buf[ARM_RX_BUFFER];
01131 volatile byte _xbee_serial_bp=0;
01132 volatile byte _xbee_serial_rp=0;
01133 void _xbee_serial_callback(){
01134     _xbee_serial_buf[_xbee_serial_bp] = _xbee_serial.getc();
01135     if(_xbee_serial_bp < (ARM_RX_BUFFER-1))_xbee_serial_bp++;
01136     else{
01137         #ifdef DEBUG
01138         _xbee_debug.printf("ERR:Buffer Full(%d)\r\n",_xbee_serial_bp);
01139         #endif
01140     }
01141 }
01142 #endif
01143 
01144 /* シリアルの初期化 */
01145 byte sci_init( byte port ){
01146     #ifdef H3694
01147         SCI3_INIT(br9600, sci_tx, SCI_SIZE, sci_tx, SCI_SIZE);
01148         EI;                                 // 割り込み許可
01149         return(1);
01150     #elif ARDUINO
01151         #ifndef XBEE_WIFI
01152             #ifdef LEONARDO
01153                 Serial1.begin(9600);
01154             #else
01155                 Serial.begin(9600);
01156             #endif
01157             return(1);
01158         #else // Arduino XBee_WIFI
01159             byte i;
01160             #ifdef XBEE_WIFI_DEBUG
01161                 Serial.begin(9600);         // TEST用
01162                 Serial.println("Hello!");
01163             #endif
01164             open_serial_port();
01165             return(1);
01166         #endif
01167     #else
01168         #ifdef ARM_MBED
01169             _xbee_serial.baud(9600);
01170             _xbee_serial.attach(&_xbee_serial_callback);
01171             #ifdef DEBUG
01172                 _xbee_debug.baud(38400);
01173             #endif 
01174             return(1);
01175         #else // PC  の時(ZigBeeシリアル or WiFi_LAN)
01176             #ifndef XBEE_WIFI   // ZigBeeシリアル
01177                 /* tasasaki様よりポート11~64の拡張対応方法を教えていただいて追加した。*/
01178                 char modem_dev[12] = "/dev/ttyS00";
01179                 
01180                 if( port <= 10){
01181                     modem_dev[9] = (char)( port - 1 + (byte)'0' );
01182                     modem_dev[10]= '\0';
01183                 }else if( port <= 64 ){
01184                     snprintf(&modem_dev[9], 3, "%d", port - 1);
01185                 }else{
01186                     fprintf(stderr,"ERR:sci_init port=%d\n",port);
01187                     return(0);
01188                 }
01189                 if( open_serial_port( modem_dev ) ){
01190                     wait_millisec( 100 );
01191                     close_serial_port();    // open出来ていないが念のために閉じる
01192                     wait_millisec( 100 );
01193                     fprintf(stderr,"Failed serial COM%d (%s)\n",port,modem_dev);
01194                     port = 0;
01195                 }else{
01196                     fprintf(stderr,"Serial port = COM%d (%s)\n",port,modem_dev);
01197                     xbee_com_port = port;
01198                 }
01199                 return( port );
01200             #else   // XBEE_WIFI PC用
01201                 byte i,j;
01202                 for(i=0;i<3;i++){
01203                     if( open_serial_port( ADR_DEST ) < 0 ){
01204                         fprintf(stderr,"Failed UDP[%d/3]:",i+1);
01205                         for(j=0;j<4;j++) fprintf(stderr,"%d.",(int)ADR_DEST[j]);
01206                         fprintf(stderr,"\b\n");
01207                         wait_millisec( 100 );
01208                         close_serial_port();    // open出来ていないが念のために閉じる
01209                         wait_millisec( 900 );
01210                     }else break;
01211                 }
01212                 #ifdef DEBUG
01213                     printf("DEBUG:SCI init for WiFi done\n");
01214                 #endif
01215                 return( 3-i );
01216             #endif // Wifi
01217         #endif // ARM/PC
01218     #endif
01219 }
01220 
01221 /* シリアル送受信バッファクリア */
01222 void sci_clear(void){
01223     #ifdef H3694
01224         SCI3_IN_DATA_CLEAR();
01225         SCI3_OUT_DATA_CLEAR();
01226     #elif ARDUINO
01227         #ifndef XBEE_WIFI
01228             #ifdef LEONARDO
01229                 Serial1.flush();
01230             #else
01231                 Serial.flush();
01232             #endif
01233         #endif
01234     #else
01235         #ifdef ARM_MBED
01236             while( _xbee_serial.readable() ){
01237                 _xbee_serial.getc();
01238                 wait(0.002);
01239             }
01240             while( !_xbee_serial.writeable() ){
01241                 _xbee_serial.send_break();
01242                 wait(1);
01243             }
01244         #else //PC
01245             #ifndef XBEE_WIFI   // ZigBee
01246                 tcflush(xbeeComFd,TCIOFLUSH);
01247             #else   // XBEE_WIFI
01248                 close_serial_port();
01249                 sci_init( 0 );
01250             #endif
01251         #endif
01252     #endif
01253 }
01254 
01255 /* シリアル受信(1バイト) */
01256 byte sci_read(byte timeout){
01257     #ifdef H3694
01258         byte timer;
01259         byte ret=0;
01260         timer = timera() + (timeout)+1;     // timeout[ms] = timer/256*1000
01261         while( timer != timera() && SCI3_IN_DATA_CHECK() < 1 );
01262         if( SCI3_IN_DATA_CHECK() ) ret=(byte)SCI3_IN_DATA();
01263         return( ret );
01264     #elif ARDUINO   // 蘭様による改良あり
01265         #ifndef XBEE_WIFI
01266             byte timer;
01267             timer = timera() + (timeout)+1;     // timeout[ms] = timer/256*1000
01268         //  led_green(0);
01269             #ifdef LEONARDO
01270                 while( timer != timera() && Serial1.available() <= 0 );
01271             //  led_green(1);
01272                 if( Serial1.available() > 0 ) return( (byte)Serial1.read() );
01273             #else
01274                 while( timer != timera() && Serial.available() <= 0 );
01275             //  led_green(1);
01276                 if( Serial.available() > 0 ) return( (byte)Serial.read() );
01277             #endif
01278         #else
01279             return(0x00);   // フレームで受信するのでバイト毎受信は不要
01280         #endif
01281     #else
01282         #ifdef ARM_MBED
01283             // http://mbed.org/users/mbed_official/code/mbed-src/docs/e8b66477f5bf/classmbed_1_1RawSerial.html
01284             int value = 0,i=0;
01285             volatile byte timer;
01286             
01287             timer = timera() + (timeout)+1;
01288 
01289             // while( timer != timera() && i == 0 ) i=_xbee_serial.readable();
01290             while( timer != timera() && i == 0 ) i=_xbee_serial_bp;       
01291             if( i > 0 ){
01292                 // value = _xbee_serial.getc();
01293                 value = _xbee_serial_buf[_xbee_serial_rp];
01294                 if(_xbee_serial_rp < (ARM_RX_BUFFER-1))_xbee_serial_rp++;
01295                 if(_xbee_serial_bp <= _xbee_serial_rp ){
01296                     _xbee_serial_bp=0;
01297                     _xbee_serial_rp=0;
01298                 }
01299             //  #ifdef DEBUG_RX
01300             //      _xbee_debug.printf("%c(%02X) ",value,value);
01301             //  #endif
01302             }
01303             if(value<0 || value>255) value=0;
01304             return( (byte)value );
01305         #else // PC
01306             /* 受信の有無の判断にFDの待ち受け関数selectを使用する。
01307             参考文献
01308             http://linuxjm.sourceforge.jp/html/LDP_man-pages/man2/select.2.html
01309             */
01310             #ifndef XBEE_WIFI
01311                 byte c;
01312                 struct timeval tv;
01313                 fd_set readfds;
01314                 
01315                 FD_ZERO(&readfds);
01316                 FD_SET( xbeeComFd , &readfds);
01317                 tv.tv_sec = 0;
01318                 #ifdef LITE // BeeBee Lite by 蘭
01319                     /*
01320                     if( timeout > 50 ){
01321                         tv.tv_usec = timeout*600;
01322                     }else if( timeout > 10 ){
01323                         tv.tv_usec = timeout*750;
01324                     }else{
01325                         tv.tv_usec = 0;
01326                     }
01327                     */
01328                     // 今回は見送ります(本関数を呼び出す前に調整しているので不要)
01329                     tv.tv_usec = timeout*1000;
01330                 #else
01331                     tv.tv_usec = timeout*1000;
01332                 #endif
01333                 if( select( (xbeeComFd+1), &readfds, NULL, NULL ,&tv ) ){
01334                     read(xbeeComFd,(char *)&c,1);
01335                 }else{
01336                     c = 0x00;
01337                 }
01338                 return( c );
01339             #else   // XBEE_WIFI
01340                 return(0);  // フレームで受信するのでバイト毎受信は不要
01341             #endif
01342         #endif
01343     #endif
01344 }
01345 
01346 #ifdef XBEE_WIFI
01347 /* シリアル受信(1フレーム) 始めの4バイトは送信元のアドレス */
01348 byte sci_read_frame(byte *data){
01349     #ifndef H3694
01350     #ifndef ARDUINO // XBEE_WIFI PC受信
01351         byte i,ret;
01352         int len=0;
01353         struct sockaddr_in xbeeF_addr;                  // FROMアドレス入力用
01354         struct timeval tv;                              // タイムアウト用
01355         fd_set readfds;
01356 
01357         /* 受信の有無の判断にFDの待ち受け関数selectを使用する。*/
01358         FD_ZERO(&readfds);                              // FD初期化
01359         FD_SET(xbeeRSFd, &readfds);                     // 待ちソケットの登録
01360         tv.tv_sec = (long)0;
01361         tv.tv_usec = (long)9000;                        // 9ms
01362         /* データ受信 */
01363         if( select( (xbeeRSFd+1), &readfds, NULL, NULL, &tv) > 0 ){
01364             len = sizeof(xbeeF_addr);
01365             len = recvfrom(xbeeRSFd, &(data[4]), (API_SIZE-14), 0, (struct sockaddr *)&xbeeF_addr, &len );
01366             if( len > 0 ){
01367                 len += 4;
01368                 #ifdef DEBUG
01369                     printf("IP(RX)=%s\n", inet_ntoa( xbeeF_addr.sin_addr ) );
01370                 #endif
01371                 for(i=0;i<4;i++){
01372                     data[i]=(byte)(xbeeF_addr.sin_addr.s_addr % (long)256);
01373                     xbeeF_addr.sin_addr.s_addr /= (long)256;
01374                 }
01375             }
01376         }else{  // 受信データが無い時はUARTを受信する
01377             FD_ZERO(&readfds);                              // FD初期化
01378             FD_SET(xbeeUSFd, &readfds);                     // 待ちソケットの登録
01379             tv.tv_usec = (long)1000;                        // 1ms
01380             if( select( (xbeeUSFd+1), &readfds, NULL, NULL, &tv) > 0 ){
01381                 len = sizeof(xbeeU_addr);
01382                 len = recvfrom(xbeeUSFd, &(data[6]), (API_SIZE-16), 0, (struct sockaddr *)&xbeeU_addr, &len );
01383                 if( len > 0 ){                              // データはdata[6]以降に入る
01384                     data[4] = 0x00; // UART受信を示す。
01385                     data[5] = len;  // UART長を示す(data[]長では無い)。
01386                     len += 6;
01387                     #ifdef DEBUG
01388                         printf("IP(UART)=%s\n", inet_ntoa( xbeeU_addr.sin_addr ) );
01389                     #endif
01390                     for(i=0;i<4;i++){
01391                         data[i]=(byte)(xbeeU_addr.sin_addr.s_addr % (long)256);
01392                         xbeeU_addr.sin_addr.s_addr /= (long)256;
01393                     }
01394                 }
01395             }
01396         }
01397         if( len < 0 ) ret = 0; else if( len>255 ) ret = 0xFF; else ret =(byte)len;
01398         #ifdef DEBUG_RX
01399             if( ret ){
01400                 printf("Recieved Packet rx[%3d]\nip0,ip1,ip2,ip3,urt,len,", len);
01401                 for(i=6;i<len;i++) printf("%3d,",i);
01402                 printf("\n");
01403                 for(i=0;i<len;i++) printf(" %02X,",data[i]);    // dataはbyte型
01404                 printf("\n");
01405                 for(i=0;i<len;i++) if( isgraph(data[i]) )   printf("'%c',",data[i]); else printf("%3d,",(int)data[i]);
01406                 printf("\n");
01407             }
01408         #endif
01409         return( ret );
01410     #else   // XBEE_WIFI ARDUINO受信
01411         int packetSize;
01412         IPAddress remote;
01413         byte i;
01414         byte ret=0;
01415         
01416         /* UdpXBeeR受信 */
01417         packetSize = UdpXBeeR.parsePacket();
01418         if(packetSize){
01419             remote = UdpXBeeR.remoteIP();
01420             for(i=0;i<4;i++) data[i]=(byte)remote[i];
01421             if( packetSize > (API_SIZE-14) ) ret = API_SIZE-14; //API_SIZEはIPのため-4で良いと思ったが、ZBフォーマット移行の-9-1-4が上限)
01422             else ret = (byte)packetSize;
01423             UdpXBeeR.read(&(data[4]), ret);
01424             ret += 4;
01425         }else{
01426         /* UdpXBeeU受信 */
01427             packetSize = UdpXBeeU.parsePacket();
01428             if(packetSize){
01429                 remote = UdpXBeeU.remoteIP();
01430                 for(i=0;i<4;i++) data[i]=(byte)remote[i];
01431                 if( packetSize > (API_SIZE-16) ) ret = API_SIZE-16; //API_SIZEはIPのため-6で良いと思ったが、ZBフォーマット移行の-9-1-6が上限)
01432                 else ret = (byte)packetSize;        // Ver 1.80で抜けていた(バグ)
01433                 data[4] = 0x00; // UART受信を示す。
01434                 data[5] = ret;  // UART長を示す(data[]長では無い)。
01435                 UdpXBeeU.read(&(data[6]), ret);
01436                 ret += 6;
01437             }
01438         }
01439         #ifdef XBEE_WIFI_DEBUG
01440             Serial.print("RX udp size=");
01441             Serial.print(ret);
01442             Serial.print(", ");
01443             for(i=0;i<ret;i++){
01444                 Serial.print(data[i],HEX);
01445                 Serial.print(" ");
01446             }
01447             Serial.println("");
01448         #endif
01449         return( ret );
01450     #endif
01451     #endif
01452 }
01453 #endif
01454 
01455 /* シリアル送信バッファが空になるのを待つ */
01456 #ifndef LITE
01457 byte sci_write_check(void){
01458     #ifdef H3694
01459         byte timer;
01460         timer = timera() + 0x7F;    // timeout = 500ms
01461         while( (timer != timera()) && ( SCI3_OUT_DATA_CHECK() < 1 ) );
01462         return( (byte)SCI3_OUT_DATA_CHECK() );
01463     #elif ARDUINO
01464         return( 1 );    // 関数があるかもしれないので、そのうち要調査&確認
01465     #else
01466         #ifdef ARM_MBED
01467             if( !_xbee_serial.writeable() ){
01468                 wait(0.1);
01469                 while( !_xbee_serial.writeable() ) sci_clear();
01470             }
01471             return( 1 );
01472         #else // PC
01473             #ifndef XBEE_WIFI   // ZigBee
01474                 tcdrain( xbeeComFd );
01475             #endif
01476             return( 1 );
01477         #endif
01478     #endif
01479 }
01480 #endif // LITE
01481 
01482 /* シリアル送信 */
01483 byte sci_write( char *data, byte len ){
01484     byte ret=1; // 戻り値 0でエラー
01485 
01486     #ifdef H3694
01487         SCI3_OUT_STRINGB( data , (short)len );  // 戻り値なし
01488     #elif ARDUINO
01489         byte i;
01490         #ifdef XBEE_WIFI
01491             UdpXBeeT.beginPacket(ADR_DEST, 0xBEE );
01492         #endif
01493         for(i=0;i<len;i++){
01494             #ifndef XBEE_WIFI
01495                 #ifdef LEONARDO
01496                     ret = Serial1.write( data[i] ); // 戻り値は書き込みバイト数
01497                 #else
01498                     ret = Serial.write( data[i] );  // 戻り値は書き込みバイト数
01499                 #endif
01500             #else // XBEE_WIFI ARDUINO
01501                 ret = UdpXBeeT.write( data[i] );    // 戻り値は書き込みバイト数
01502                 /*
01503                     Serial.print("TX udp size=");
01504                     Serial.print(len,DEC);
01505                     Serial.print(", ");
01506                     for(i=0;i<len;i++){
01507                         Serial.print(data[i],HEX);
01508                         Serial.print(" ");
01509                     }
01510                     Serial.println("");
01511                 */
01512             #endif
01513             if( ret == 0 ){
01514                 i = len;        // break;
01515             }
01516         }
01517         #ifdef XBEE_WIFI
01518             UdpXBeeT.endPacket();
01519         #endif
01520     #else
01521         #ifdef ARM_MBED
01522             byte i;
01523             sci_write_check();
01524             for(i=0;i<len;i++){
01525                 if( _xbee_serial.putc((int)data[i]) < 0 ) ret=0;
01526             }
01527             if(ret) ret=len;
01528         #else // PC
01529             #ifndef XBEE_WIFI
01530                 byte i;
01531                 for(i=0;i<len;i++){
01532                     if(write(xbeeComFd,&data[i],1) != 1){
01533                         fprintf(stderr,"sci_write ERR:d[%02d]=0x%02x\n",i,(byte)data[i]);
01534                         ret = 0;
01535                     }
01536                 }
01537                 #ifdef DEBUG_TX
01538                     printf("Transmitted Packet tx[%3d] to ", len);
01539                     for(i=0;i<4;i++) printf("%02X",ADR_DEST[i]);
01540                     printf(" ");
01541                     for(i=4;i<8;i++) printf("%02X",ADR_DEST[i]);
01542                     printf("\n");           
01543                     for(i=0;i<len;i++) printf("%3d,",i);
01544                     printf("\n");
01545                     for(i=0;i<len;i++) printf(" %02X,",(byte)data[i]);  // dataはchar型
01546                     printf("\n");
01547                     for(i=0;i<len;i++) if( (byte)data[i]>=0x20 ) printf("'%c',",data[i]); else printf("%3d,",(int)((byte)data[i]));
01548                     printf("\n");
01549                 #endif
01550             #else // XBEE_WIFI
01551                 #ifdef DEBUG_TX
01552                     int i;
01553                 #endif
01554                 int ret_i;  // 戻り値 0でエラー
01555                 ret_i = sendto(xbeeTSFd, data, len, 0, (struct sockaddr *)&xbeeT_addr, sizeof(xbeeT_addr));
01556                 if( ret_i<0 ) ret=0; else if( ret_i>255 ) ret = 0xFF; else ret = (byte)ret_i;
01557                 #ifdef DEBUG_TX
01558                     printf("Transmitted Packet tx[%3d] to ", len);
01559                     for(i=0;i<4;i++) printf("%d.",ADR_DEST[i]);
01560                     printf(":0xBEE\n");             
01561                     for(i=0;i<len;i++) printf("%3d,",i);
01562                     printf("\n");
01563                     for(i=0;i<len;i++) printf(" %02X,",(byte)data[i]);  // dataはchar型
01564                     printf("\n");
01565                     for(i=0;i<len;i++) if( isgraph((byte)data[i]) ) printf("'%c',",data[i]); else printf("%3d,",(int)((byte)data[i]));
01566                     printf("\n");
01567                 #endif
01568             #endif
01569         #endif // ARM/PC
01570     #endif
01571     #ifdef DEBUG
01572         #ifdef ARM_MBED
01573             _xbee_debug.printf("DEBUG:TX OUT DONE(%d)\r\n",ret);
01574         #else
01575             printf("DEBUG:TX OUT DONE(%d)\n",ret);
01576         #endif
01577     #endif
01578     return( ret );
01579 }
01580 
01581 /* string byte操作 */
01582 void strcopy(char *s1, const char *s2){             // string.hのstrcpyの真似版
01583     while( *s2 != 0x00 ) *s1++ = *s2++;
01584     *s1 = 0x00;
01585 }
01586 void bytecpy(byte *s1, const byte *s2, byte size){  // strcpyのバイト長可変版
01587     byte i;
01588     for(i=0; i< size ;i++ ){
01589         s1[i] = s2[i];
01590     }
01591 }
01592 byte bytecmp(byte *s1, const byte *s2, byte size){  // strcmpの簡易版(大小比較なし)
01593 /*バイトデータの比較
01594     入力:byte *s1 = 比較データ1
01595     入力:byte *s2 = 比較データ2
01596     入力:byte size = 比較データ長
01597     出力:戻り値 = 0:一致 1:不一致
01598 */
01599     byte i=0;                                       // 同一なら0を応答
01600     for(i=0; i< size ;i++ ){
01601         if( s1[i] != s2[i] ) return(1);
01602     }
01603     return(0);
01604 }
01605 
01606 /* LCD用関数 for ARDUINO */  // H8版とPC版は別ファイル lcd_h8.c lcd_pc.c
01607 #ifdef ARDUINO
01608 #ifdef LCD_H
01609     void lcd_cls(void){
01610         xbee_ardlcd.clear();
01611     }
01612     void lcd_home(void){
01613         xbee_ardlcd.home();
01614     }
01615     void lcd_control(byte disonoff, byte curonoff, byte curblink){
01616     }
01617     void lcd_goto(const byte mesto){
01618         byte row=0;
01619         
01620         switch( mesto ){
01621             case LCD_ROW_1: row=0; break;
01622             case LCD_ROW_2: row=1; break;
01623             case LCD_ROW_3: row=2; break;
01624             case LCD_ROW_4: row=3; break;
01625         }
01626         xbee_ardlcd.setCursor(0,(int)row);
01627     }
01628     void lcd_shift(const byte data){
01629         xbee_ardlcd.write(' ');
01630     }
01631     void lcd_putch(const char data){
01632         xbee_ardlcd.write( data );
01633     }
01634     void lcd_putstr(const char *data){
01635         while(*data != 0) {
01636             xbee_ardlcd.write(*data);
01637             data++;
01638         }
01639     }
01640     void lcd_disp_bin(const byte x){
01641         // xbee_ardlcd.print( x, BIN );
01642         byte i;
01643         for (i=128;i>0;i>>=1){
01644             if ((x&i)==0){
01645                 lcd_putch('0');
01646             }else{
01647                 lcd_putch('1');
01648             }
01649         }
01650     }
01651     void lcd_disp_hex(const byte i){
01652         // xbee_ardlcd.print( i, HEX );
01653         byte hi,lo;
01654         hi=i&0xF0;               // High nibble
01655         hi=hi>>4;
01656         hi=hi+'0';
01657         if (hi>'9'){
01658             hi=hi+7;
01659         }
01660         lo=(i&0x0F)+'0';         // Low nibble
01661         if (lo>'9'){
01662             lo=lo+7;
01663         }
01664         lcd_putch((char)hi);
01665         lcd_putch((char)lo);
01666     }
01667     void lcd_disp_1(const unsigned int x){
01668         if (x<10){
01669             xbee_ardlcd.write((char)(x+0x30));
01670         }else if (x<16){
01671             xbee_ardlcd.write((char)(x-10+'A'));
01672         }else{
01673             xbee_ardlcd.write('X');
01674         }
01675     }
01676     void lcd_disp_2(unsigned int x){
01677         unsigned int y;
01678         if (x<100){
01679             y=x/10;
01680             xbee_ardlcd.write((char)(y+0x30));
01681             x-=(y*10);
01682             xbee_ardlcd.write((char)(x+0x30));
01683         }else{
01684             xbee_ardlcd.print("XX");
01685         }
01686     }
01687     void lcd_disp_3(unsigned int x){
01688         unsigned int y;
01689         if (x<1000){
01690             y=x/100;
01691             xbee_ardlcd.write((char)(y+0x30));
01692             x-=(y*100);
01693             y=x/10;
01694             xbee_ardlcd.write((char)(y+0x30));
01695             x-=(y*10);
01696             xbee_ardlcd.write((char)(x+0x30));
01697         }else{
01698             xbee_ardlcd.print("XXX");
01699         }
01700     }
01701     void lcd_disp_5(unsigned int x){
01702         unsigned int y;
01703         if (x<=65535){
01704             y=x/10000;
01705             xbee_ardlcd.write((char)(y+0x30));
01706             x-=(y*10000);
01707             y=x/1000;
01708             xbee_ardlcd.write((char)(y+0x30));
01709             x-=(y*1000);
01710             y=x/100;
01711             xbee_ardlcd.write((char)(y+0x30));
01712             x-=(y*100);
01713             y=x/10;
01714             xbee_ardlcd.write((char)(y+0x30));
01715             x-=(y*10);
01716             xbee_ardlcd.write((char)(x+0x30));
01717         }else{
01718             xbee_ardlcd.print("XXXXX");
01719         }
01720     }
01721     void lcd_init(void){
01722         xbee_ardlcd.begin(20, 4);           // 液晶の桁数×行数の設定
01723         xbee_ardlcd.clear();                // 表示クリア
01724     }
01725 #endif
01726 #endif
01727 
01728 /* LCD用関数 for ARM_MBED */ // 注意=液晶では無くシリアルに出力する
01729 #ifdef ARM_MBED                 // D8(PA_9)からログをUART(38400baud)出力します
01730 #ifdef DEBUG
01731     void lcd_cls(void){
01732         _xbee_debug.printf("----------------\r\n");
01733     }
01734     void lcd_home(void){
01735         _xbee_debug.printf("\r\n");
01736     }
01737     void lcd_control(byte disonoff, byte curonoff, byte curblink){
01738     }
01739     void lcd_goto(const byte mesto){
01740         lcd_home();
01741     }
01742     void lcd_shift(const byte data){
01743         _xbee_debug.putc(' ');
01744     }
01745     void lcd_putch(const char data){
01746         _xbee_debug.putc( data );
01747     }
01748     void lcd_putstr(const char *data){
01749         while(*data != 0) {
01750             _xbee_debug.putc(*data);
01751             data++;
01752         }
01753     }
01754     void lcd_disp_bin(const byte x){
01755         byte i;
01756         for (i=128;i>0;i>>=1){
01757             if ((x&i)==0){
01758                 lcd_putch('0');
01759             }else{
01760                 lcd_putch('1');
01761             }
01762         }
01763     }
01764     void lcd_disp_hex(const byte i){
01765         byte hi,lo;
01766         hi=i&0xF0;               // High nibble
01767         hi=hi>>4;
01768         hi=hi+'0';
01769         if (hi>'9'){
01770             hi=hi+7;
01771         }
01772         lo=(i&0x0F)+'0';         // Low nibble
01773         if (lo>'9'){
01774             lo=lo+7;
01775         }
01776         lcd_putch((char)hi);
01777         lcd_putch((char)lo);
01778     }
01779     void lcd_disp_1(const unsigned int x){
01780         if (x<10){
01781             _xbee_debug.putc((char)(x+0x30));
01782         }else if (x<16){
01783             _xbee_debug.putc((char)(x-10+'A'));
01784         }else{
01785             _xbee_debug.putc('X');
01786         }
01787     }
01788     void lcd_disp_2(unsigned int x){
01789         unsigned int y;
01790         if (x<100){
01791             y=x/10;
01792             _xbee_debug.putc((char)(y+0x30));
01793             x-=(y*10);
01794             _xbee_debug.putc((char)(x+0x30));
01795         }else{
01796             _xbee_debug.printf("XX");
01797         }
01798     }
01799     void lcd_disp_3(unsigned int x){
01800         unsigned int y;
01801         if (x<1000){
01802             y=x/100;
01803             _xbee_debug.putc((char)(y+0x30));
01804             x-=(y*100);
01805             y=x/10;
01806             _xbee_debug.putc((char)(y+0x30));
01807             x-=(y*10);
01808             _xbee_debug.putc((char)(x+0x30));
01809         }else{
01810             _xbee_debug.printf("XXX");
01811         }
01812     }
01813     void lcd_disp_5(unsigned int x){
01814         unsigned int y;
01815         if (x<=65535){
01816             y=x/10000;
01817             _xbee_debug.putc((char)(y+0x30));
01818             x-=(y*10000);
01819             y=x/1000;
01820             _xbee_debug.putc((char)(y+0x30));
01821             x-=(y*1000);
01822             y=x/100;
01823             _xbee_debug.putc((char)(y+0x30));
01824             x-=(y*100);
01825             y=x/10;
01826             _xbee_debug.putc((char)(y+0x30));
01827             x-=(y*10);
01828             _xbee_debug.putc((char)(x+0x30));
01829         }else{
01830             _xbee_debug.printf("XXXXX");
01831         }
01832     }
01833     void lcd_init(void){
01834         _xbee_debug.printf("-----\r\n");
01835     }
01836 #endif
01837 #endif
01838 
01839 #ifdef LCD_H
01840 void lcd_disp(const char *s){
01841             lcd_cls();
01842             lcd_goto(LCD_ROW_1);
01843             lcd_putstr( s );
01844         #ifndef H3694
01845         #ifndef ARDUINO
01846             #ifdef ARM_MBED
01847                 _xbee_debug.printf("\r\n");
01848             #else // PC
01849                 lcd_putch( '\n' );
01850             #endif
01851         #endif
01852         #endif
01853 }
01854 #endif
01855 
01856 /*********************************************************************
01857 XBeeドライバ関数
01858 *********************************************************************/
01859 
01860 /*
01861            00 01 02 03 04 05 06 07 08....
01862     ATNJ = 7E 00 05 08 01 4E 4A FF 5F
01863           |  | len |mo|FI| NJ=0xFF|CS|
01864           |  |     |de|  |        |__|___ Check Sum
01865           |  |     |  |  |________|______ AT コマンド
01866           |  |     |  |__|_______________ Frame ID
01867           |  |     |__|__________________ AT=0x08 Remote=0x17
01868           |  |_____|_____________________ Data Lengrh (ATコマンド+2文字)
01869           |__|___________________________ 固定値
01870 
01871     char *at "AT"   ATコマンド          len=4バイト~最大255 (フレーム8バイト~)
01872              "RAT"  リモートATコマンド  len=15バイト~最大255 (フレーム19バイト~)
01873              "TX"   データ送信コマンド  len=15バイト~最大255 (フレーム19バイト~)
01874                                         ※API_SIZE=32の時valueは12バイトまで
01875 */
01876 
01877 /* (ドライバ)ATコマンド送信 */
01878 byte xbee_at_tx(const char *at, const byte *value, const byte value_len){
01879 /*
01880     処理:リモートATコマンドの送信を行うXBeeドライバ部
01881     入力:ATコマンドat[] = "AT**"はローカルATで、"RAT***"がリモートAT
01882                 TXがデータ送信モード
01883        データvalue[] = 各ATコマンドで引き渡すデータ値
01884        value_len   = その長さ
01885     戻り値:送信したAPIサービス長。送信しなかった場合は0
01886 */
01887     char data_api[API_TXSIZE];
01888     byte i;
01889     byte len;               // APIサービス長
01890     #ifndef XBEE_WIFI
01891     byte check=0xFF;        // チェックサム
01892     byte data_position=5;   // 送信データdata_api[]の何処にvalue[]を入れるか
01893     #endif
01894     byte ret=0;
01895     
01896     if( PACKET_ID == 0xFF ){
01897         PACKET_ID=0x01;
01898     }else{
01899         PACKET_ID++;
01900     }
01901     len=0;
01902     #ifndef XBEE_WIFI
01903         switch( at[0] ){
01904             case 'A':
01905             case 'F':
01906                 if( at[1]=='T'){
01907                     data_api[3]=(char)0x08;         // ATコマンドモード
01908                     if( at[0] == 'A') data_api[4]=(char)PACKET_ID;      // フレームID (at="ATxx")
01909                     else data_api[4]=0x00;                  // IDなし(at="FTxx")
01910                     data_api[5]=(char)at[2];            // ATコマンド上位
01911                     data_api[6]=(char)at[3];            // ATコマンド下位
01912                     data_position=7;    
01913                     len=4;                      // サービスデータにMD+FI+AT(2)バイトが入る
01914                 }
01915                 break;
01916             case 'R':
01917             case 'S':
01918                 if( at[1]=='A' && at[2]=='T'){
01919                     data_api[3]=(char)0x17;     // リモートATコマンドモード
01920                     if( at[0] == 'R') data_api[4]=(char)PACKET_ID;      // フレームID (at="RATxx")
01921                     else data_api[4]=0x00;                  // IDなし(at="SATxx")
01922                     for( i=5 ; i<=12 ; i++)  data_api[i]=(char)ADR_DEST[i-5];
01923                     for( i=13 ; i<=14 ; i++) data_api[i]=(char)SADR_DEST[i-13];
01924                     data_api[15]=(char)0x02;    // apply changes
01925                     data_api[16]=(char)at[3];   // ATコマンド上位
01926                     data_api[17]=(char)at[4];   // ATコマンド下位
01927                     data_position=18;           // value[]を入れる場所
01928                     len=15;                     // サービスデータにMD+FI+ADR(8)+SAD(2)+OPT+AT(2)が入る
01929                 }
01930                 break;
01931             case 'T':
01932                 if( at[1]=='X'){
01933                     data_api[3]=(char)0x10;     // TXデータ送信モード
01934                     data_api[4]=(char)0x00;     // フレームIDを使用しない(no responce)
01935                     for( i=5 ; i<=12 ; i++)  data_api[i]=(char)ADR_DEST[i-5];
01936                     for( i=13 ; i<=14 ; i++) data_api[i]=(char)SADR_DEST[i-13];
01937                     data_api[15]=(char)0x00;    // ZigBeeホップ数
01938                     data_api[16]=(char)0x00;    // 暗号化=しない
01939                     data_position=17;
01940                     len=14;                     // サービスデータにMD+FI+ADR(8)+SAD(2)+OPT(2)が入る
01941                 }
01942                 break;
01943             #ifndef ARDUINO
01944             #ifndef ARM_MBED
01945             case 'Z':
01946                 // [0]送信元EndPoint, [1]宛先EndPoint, [2-3]クラスタID, [4-5]プロファイルID
01947                 // [6]Radius=00 [7]Option=00 [8]Fram Ctrl [9]SeqNum [10]Command [11-12] Attribute
01948                 if( at[1]=='C' && value_len>12){
01949                     data_api[3]=(char)0x11;             // ZCL送信モード
01950                     data_api[4]=(char)PACKET_ID;        // フレームID
01951                     for( i=5 ; i<=12 ; i++)  data_api[i]=(char)ADR_DEST[i-5];
01952                     for( i=13 ; i<=14 ; i++) data_api[i]=(char)SADR_DEST[i-13];
01953                     data_position=15;
01954                     len=12;
01955                 }
01956                 break;
01957             #endif
01958             #endif
01959             default:
01960                 break;
01961         }
01962         if( len ){
01963             data_api[0]=(char)0x7E;             // デリミタ
01964             data_api[1]=(char)0x00;             // パケット長の上位(送らない前程)
01965             for( i=3 ; i < data_position ; i++) check -= (byte)data_api[i];
01966             if( value_len > 0 ){
01967                 for( i=0 ; i<value_len; i++){
01968                     data_api[data_position + i] = (char)value[i];
01969                     check -= (byte)data_api[data_position + i];
01970                     len++;
01971                 }
01972             }
01973             data_api[2]    =(char)len;
01974             data_api[len+3]=(char)check;
01975             #ifdef LITE // BeeBee Lite by 蘭
01976                 sci_write( data_api, (byte)(len+4) );
01977                 ret=len+3;
01978             #else
01979                 check = sci_write_check();      // 以降 checkはシリアルバッファ確認に使用する
01980                 /*シリアルデータ送信 */
01981                 if(  check > 0 ){
01982                     if( sci_write( data_api, (byte)(len+4) ) == 0 ){
01983                         /* シリアルリセット */
01984                         #ifndef H3694
01985                         #ifndef ARDUINO
01986                         #ifndef ARM_MBED // PC
01987                             wait_millisec( 100 );
01988                             close_serial_port();            // シリアルを閉じる
01989                             wait_millisec( 300 );
01990                             printf("RESET serial\n");
01991                             while( sci_init( xbee_com_port )==0){   // 再度オープン
01992                                 wait_millisec( 3000 );
01993                                 close_serial_port();        // シリアルを閉じる
01994                                 wait_millisec( 3000 );
01995                                 printf("RESET serial\n");
01996                             }
01997                             wait_millisec( 300 );
01998                             sci_write( data_api, (byte)(len+4) );   // 再送信
01999                         #endif
02000                         #endif
02001                         #endif
02002                     }
02003                     ret=len+3;
02004                 }else{
02005                     #ifdef H3694
02006                         led_red( 1 );
02007                     #endif
02008                     #ifdef ERRLOG
02009                         strcopy( ERR_LOG , "ERR:TX Buffer Over" );
02010                         ERR_CODE = check;
02011                     #endif
02012                     ret=0;
02013                 }
02014             #endif
02015         }
02016     #else // XBEE_WIFI
02017         switch( at[0] ){
02018             case 'A':
02019             case 'F':
02020                 if( at[1]=='T' ){
02021                     data_api[0]=(char)0x02;             // ATコマンドモード
02022                     data_api[1]=(char)0x00;             // 固定
02023                     if( at[0] == 'A' ) data_api[2]=(char)PACKET_ID;     // フレームID
02024                     data_api[3]=(char)0x02;
02025                     data_api[4]=(char)at[2];            // ATコマンド上位
02026                     data_api[5]=(char)at[3];            // ATコマンド下位
02027                     len=6;
02028                 }
02029                 break;
02030             case 'R':
02031             case 'S':
02032                 if( at[1]=='A' && at[2]=='T' ){
02033                     data_api[0]=(char)0x02;             // ATコマンドモード
02034                     data_api[1]=(char)0x00;             // 固定
02035                     if( at[0] == 'R'){
02036                         data_api[2]=(char)PACKET_ID;    // フレームID
02037                         data_api[3]=(char)0x02;
02038                     }else{
02039                         data_api[2]=(char)0x00;
02040                         data_api[3]=(char)0x00;
02041                     }
02042                     data_api[4]=(char)at[3];            // ATコマンド上位
02043                     data_api[5]=(char)at[4];            // ATコマンド下位
02044                     len=6;
02045                 }
02046             case 'T':
02047                 if( at[1]=='X'){
02048                     data_api[0]=(char)0x00;             // シリアルデータモード
02049                     data_api[1]=(char)0x00;             // ackが必要なときは01
02050                     len=2;  // datasheetでは3だが誤り。実装は2
02051                 }
02052                 break;
02053             default:
02054                 break;
02055         }
02056         if( len ){
02057             if( value_len > 0 ){
02058                 for( i=0 ; i<value_len; i++){
02059                     data_api[len] = (char)value[i];
02060                     len++;
02061                 }
02062             }
02063             if(DEVICE_TYPE == XB_TYPE_WIFI20){
02064                 #ifdef DEBUG
02065                     printf("DEBUG:TX_10(%3d):",len);
02066                     for(i=0;i<len;i++) printf("%02X,",data_api[i]);
02067                     printf("\n");
02068                 #endif
02069                 len+=6;
02070                 if( len <= API_TXSIZE ){
02071                     for(i=len-6; i>0; i--){
02072                         data_api[i+5]=data_api[i-1];
02073                     }
02074                     data_api[0]=0x42;
02075                     data_api[1]=0x42;
02076                     data_api[2]=0x0;
02077                     data_api[3]=0x0;
02078                     data_api[4]=0x0;
02079                     data_api[5]=0x0;
02080                 }
02081                 #ifdef DEBUG
02082                     printf("DEBUG:TX_20(%3d):",len);
02083                     for(i=0;i<len;i++) printf("%02X,",data_api[i]);
02084                     printf("\n");
02085                 #endif
02086             }
02087             if( sci_write_check() > 0 ){    // XBEE_WIFIなのでifdef LITEは不要
02088                 #ifdef XBEE_WIFI_DEBUG
02089                     Serial.print("TX udp size=");
02090                     Serial.print(len);
02091                     Serial.print(", ");
02092                     for(i=0;i<len;i++){
02093                         Serial.print(data_api[i],HEX);
02094                         Serial.print(" ");
02095                     }
02096                     Serial.println("");
02097                 #endif
02098                 #ifdef DEBUG
02099                     printf("TX udp size=%d\n",len);
02100                 #endif
02101                 if( sci_write( data_api, len ) == 0 ){
02102                     #ifdef H3694
02103                         led_red( 1 );
02104                     #endif
02105                     #ifdef ERRLOG
02106                         strcopy( ERR_LOG , "ERR:TX Write Error" );
02107                         ERR_CODE = 0x00;
02108                     #endif
02109                     #ifdef XBEE_WIFI_DEBUG
02110                         Serial.println("ERR:TX Write Error" );
02111                     #endif
02112                     #ifdef DEBUG
02113                         printf("ERR:TX Write Error\n");
02114                     #endif
02115                     ret=0;
02116                 }else ret = len;
02117             }else{
02118                 #ifdef H3694
02119                     led_red( 1 );
02120                 #endif
02121                 #ifdef ERRLOG
02122                     strcopy( ERR_LOG , "ERR:TX Buffer Over" );
02123                     ERR_CODE = 0x00;
02124                 #endif
02125                 #ifdef DEBUG
02126                     printf("ERR:TX Buffer Over\n");
02127                 #endif
02128                 ret=0;
02129             }
02130         }
02131     #endif
02132     return( ret );
02133 }
02134 
02135 /* (ドライバ)ATコマンド受信 */
02136 byte xbee_at_rx(byte *data){
02137 /*
02138     リモートATコマンドの応答を受信するXBeeドライバ部
02139     処理:XBeeからの受信データをdata[]へ代入(応答)する
02140     入出力:APIデータdata[] 前3バイトは'7E'+len(2) data[0]が0x00の場合はタイムアウト
02141     リターン:APIサービス長、0はタイムアウト
02142 */
02143     byte i;
02144     byte len;           // APIサービス長-3 (APIフレームの前3バイトとチェックサム1バイトを除く)
02145     #ifndef XBEE_WIFI
02146     unsigned int leni;  // 実際のAPIサービス長と使用するAPIサービス長の差(データ破棄用)
02147     byte check = 0xFF;  // チェックサム
02148     #endif
02149     byte ret=0;
02150 
02151     /* 受信処理 */
02152     #ifndef XBEE_WIFI   // ZigBee
02153         data[0] = sci_read( 1 );                // 1ms待ち受けで受信
02154         if( data[0] == 0x7E ) {                 // 期待デリミタ0x7E時
02155             for( i=1;i<=2;i++ ){
02156                 #ifdef LITE // BeeBee Lite by 蘭
02157                     data[i] = sci_read( 35 );   // 1割だけ緩和しました。sci_read 32⇒35(Wataru)
02158                 #else
02159                     data[i] = sci_read( 50 );
02160                 #endif
02161             }
02162             if(data[1] == 0x00) len = data[2];
02163             else len = 0xFF - 4;        // API長が255バイトまでの制約(本来は64KB)
02164             if( len > (API_SIZE-4) ) len = API_SIZE-4;
02165             leni = (unsigned int)data[1] * 256 + (unsigned int)data[2] - (unsigned int)len;
02166                 // 通常は0。lenが本来の容量よりも少ない場合に不足分が代入されれる
02167             for( i=0 ; i <= len ; i++){ // i = lenはチェックサムを入力する
02168                 #ifdef LITE // BeeBee Lite by 蘭
02169                     data[i+3] = sci_read( 35 ); // 1割だけ緩和しました。sci_read 32⇒35(Wataru)
02170                 #else
02171                     data[i+3] = sci_read( 50 );
02172                 #endif
02173                 if( i != len) check -= data[i+3];   // チェックサムのカウント
02174             }
02175             while( leni > 0 ){
02176                 data[len+3] = sci_read( 50 );   // データの空読み(lenは固定)
02177                 if( leni != 1 ) {
02178                     check -= data[len+3];       // leni=0の時はCheck sumなので減算しない
02179                 }
02180                 leni--;
02181             }
02182             if( check == data[len+3] ) ret = len +3;
02183             else ret = 0;
02184             #ifdef DEBUG_RX
02185                 lcd_cls(); lcd_goto(LCD_ROW_1);
02186                 lcd_putstr("->");
02187                 for( i=0 ; i <= len+3 ; i++){
02188                     lcd_disp_hex( data[i] );
02189                     if( i == 8 ) lcd_goto(LCD_ROW_2);
02190                     if( i == 18 ) lcd_goto(LCD_ROW_3);
02191                     if( i == 28 ) lcd_goto(LCD_ROW_4);
02192                     if( i == 38 ) lcd_goto(LCD_ROW_1);
02193                 }
02194                 lcd_goto(LCD_ROW_4);
02195                 lcd_putstr("ID=");
02196                 lcd_disp_hex( PACKET_ID );
02197                 lcd_putstr(":");
02198                 lcd_disp_hex( data[4] );
02199                 if( check != data[len+3]){
02200                     lcd_putstr(" ER=");
02201                 }else{
02202                     lcd_putstr(" OK=");
02203                 }
02204                 lcd_disp_hex( check );
02205                 lcd_putstr(":");
02206                 lcd_disp_hex( data[len+3] );
02207             #endif
02208         }
02209     #else // XBEE_WIFI
02210         ret = sci_read_frame( data );
02211 
02212         if( ret >= 7){          // もともと10バイト以上にしていたけどUARTは最低7バイトからなので変更
02213             #ifdef XBEE_WIFI
02214                 if(DEVICE_TYPE == XB_TYPE_WIFI20 && data[4] != 0x00){ // UARTのときは処理不要
02215                     #ifdef DEBUG
02216                         printf("DEBUG:RX_10(%3d):",ret);
02217                         for(i=0;i<ret;i++) printf("%02X,",data[i]);
02218                         printf("\n");
02219                     #endif
02220                     if( ret > 10 ){
02221                         for(i=10; i<ret; i++)data[i-6]=data[i];
02222                         ret -=6;
02223                     }
02224                     #ifdef DEBUG
02225                         printf("DEBUG:RX_20(%3d):",ret);
02226                         for(i=0;i<ret;i++) printf("%02X,",data[i]);
02227                         printf("\n");
02228                     #endif
02229                 }
02230             #endif
02231             switch( data[4] ){
02232                 case 0x82:  // Remote AT Resp.  アドレス4バイト+基本レスポンス6バイト+オプション0バイト以上
02233                     if(ret >= 10){
02234                         for(i=ret;i>=10; i--){
02235                             data[i+8] = data[i];    // 破壊 18以降全て ※メモリリークするのでUdpXBeeR受信で制限している
02236                         }
02237                         data[17] = data[9];     // AT Command status
02238                         data[16] = data[8];     // AT Command LSB
02239                         data[15] = data[7];     // AT Command MSB
02240                         data[14] = 0xFE;
02241                         data[13] = 0xFF;
02242                         data[4]=data[6];        // Frame ID 破壊 4
02243                         for(i=0;i<4;i++){       // IPアドレス
02244                             data[5+i]=data[i];  // 破壊 5,6,7,8
02245                             data[9+i]=0x00;     // 破壊 9,10,11,12
02246                         }
02247                         data[3]=0x97;           // rat res
02248                         data[0]=0x7E;           // 受信成功
02249                         ret += 9;
02250                         data[1]=0x00;           // length上位
02251                         data[2]=ret-3;          // length下位
02252                     }
02253                     break;
02254                 case 0x04:  // IO RX Sample アドレス4バイト+基本レスポンス6バイト+オプション0バイト以上
02255                     if(ret >= 10){
02256                         for(i=ret;i>=6; i--){   // datasheetの誤り Number SamplesのOffsetはdatesheetでは3だが実際は2
02257                                                 // これにIPの4バイトが追加されるので6
02258                             data[i+9] = data[i];    // 破壊 15以降全て ※メモリリークするのでUdpXBeeR受信で制限している
02259                         }
02260                         data[14] = 0x02;        // Packet was a broadcast
02261                         data[13] = 0xFE;
02262                         data[12] = 0xFF;
02263                         for(i=0;i<4;i++){       // IPアドレス
02264                             data[4+i]=data[i];  // 破壊 5,6,7,8
02265                             data[8+i]=0x00;     // 破壊 9,10,11,12
02266                         }
02267                         data[3]=0x92;           // io sample
02268                         data[0]=0x7E;           // 受信成功
02269                         ret += 10;
02270                         data[1]=0x00;           // length上位
02271                         data[2]=ret-3;          // length下位
02272                     }
02273                     break;
02274                 case 0x00:  // UART
02275                     len = data[5];              // 破壊されるのでUART長はバックアップ
02276                     for(i=ret;i>=6; i--){
02277                         data[i+9] = data[i];    // 破壊 15以降全て ※メモリリークするのでUdpXBeeU受信で制限している
02278                     }
02279                     data[14] = 0x02;            // Packet was a broadcast
02280                     data[13] = 0xFE;
02281                     data[12] = 0xFF;
02282                     for(i=0;i<4;i++){           // IPアドレス
02283                         data[4+i]=data[i];      // 破壊 5,6,7,8
02284                         data[8+i]=0x00;         // 破壊 9,10,11,12
02285                     }
02286                     data[1]=0x00;               // 243バイトまでしか考慮しない
02287                     data[2]=len + 0x0C;         // 243バイトまでしか考慮しない
02288                     data[3]=0x90;               // UART
02289                     data[0]=0x7E;               // 受信成功
02290                     ret += 10;
02291                     break;
02292                 default:
02293                     for(i=ret;i>=7; i--){
02294                         data[i+8] = data[i];    // 破壊 18以降全て ※メモリリークするのでUdpXBeeR受信で制限している
02295                     }
02296                     data[4]=data[6];            // Frame ID 破壊 4
02297                     for(i=0;i<4;i++){           // IPアドレス
02298                         data[5+i]=data[i];      // 破壊 5,6,7,8
02299                         data[9+i]=0x00;         // 破壊 9,10,11,12
02300                     }
02301                     data[3]=data[4];
02302                     ret=0;
02303             }
02304             #ifdef DEBUG
02305                 printf("DEBUG:RX_ZB(%3d):",ret);
02306                 for(i=0;i<ret;i++) printf("%02X,",data[i]);
02307                 printf("\n");
02308             #endif
02309         }else ret=0;
02310         #ifdef XBEE_WIFI_DEBUG
02311             Serial.print("RX api size=");
02312             Serial.print(ret);
02313             Serial.print(", ");
02314             for(i=0;i<ret;i++){
02315                 Serial.print(data[i],HEX);
02316                 Serial.print(" ");
02317             }
02318             Serial.println("");
02319         #endif
02320     #endif
02321     return( ret );
02322 }
02323 
02324 /* (ドライバ)パケット差出人の抽出 */
02325 byte xbee_from_acum( const byte *data ){
02326 /*
02327     処理:受信データの差出人をグローバル変数へ登録 ※xbee_at_rxでは登録しない
02328     入力:data[] APIデータ
02329     出力:byte 受信データの種別mode値を戻り値に代入
02330        受信データの差出人をグローバル変数ADR_FROMに代入
02331     再起動で8Aのモード応答あり
02332 */
02333     byte i;
02334     byte ret=0;
02335 
02336     if( data[3]==MODE_UART          // 0x90 UART Receive
02337      || data[3]==MODE_UAR2          // 0x91 UART AO=0
02338      || data[3]==MODE_GPIN          // 0x92 GPI data
02339      || data[3]==MODE_SENS          // 0x94 XB Sensor
02340      || data[3]==MODE_IDNT){        // 0x95 Node Identify
02341         for(i=0;i<8;i++) ADR_FROM[i]=data[4+i];
02342         ret = data[3];              // mode値
02343     }else if( 
02344         data[3]==MODE_RESP){        // 0x97 リモートATコマンドの結果
02345         for(i=0;i<8;i++) ADR_FROM[i]=data[5+i];
02346         ret = data[3];              // mode値
02347     }else if( 
02348         data[3]==MODE_RES           // 0x88 ローカルATコマンドの結果
02349      || data[3]==MODE_MODM){        // 0x8A Modem Statusを受信
02350         ret = data[3];              // mode値
02351     }else{
02352         #ifdef H3694
02353             led_red( 1 );
02354         #endif
02355         #ifdef ERRLOG
02356             strcopy( ERR_LOG , "ERR:xbee_from" );
02357             ERR_CODE = data[3];
02358         #endif
02359         ret = 0;
02360     }
02361     return( ret );
02362 }
02363 
02364 /* (ドライバ)GPIO入力データの計算部 */
02365 byte xbee_gpi_acum( byte *data ){
02366 /*  リモート先(ADR_FROMに入力)のGPIOの入力値(下位バイト)を応答する。
02367     リモート先は(こちらから呼ばなくても)GPIOの変化などで自動送信する設定にしておく必要がある。
02368     具体的にはリモート先をATIC設定するなど。本演算関数はxbee_rx_callから呼ばれる。
02369     port:   port指定  IO名 ピン番号         USB評価ボード(XBIB-U-Dev)
02370             port= 1     DIO1    XBee_pin 19 (AD1)        SW2
02371             port= 2     DIO2    XBee_pin 18 (AD2)        SW3
02372             port= 3     DIO3    XBee_pin 17 (AD3)        SW4
02373     out:    port 1~7の入力値をバイトで応答。
02374             上位バイトのポートには対応しない
02375             DIOのport1~7がオフでかつADCが有効の場合は有効ADC(1~3の最も若い番号)のAD変換結果を応答する。
02376             ADC結果は8ビットに間引かれる。電圧は0~1.2Vに対応する。以下でADC電圧を得ることが可能。
02377                     (unsigned int)xbee_gpi_acum(data)/255*1200 [mV]
02378     注意1:DIO/ADCの切り換え方法:DIOのport1~7が一つでも有効であればDIOとして動作します。
02379             port1~7のDIOが全て無効でADCが有効であれば有効なADC(1~3の最も若い番号)が動作します。
02380             port1~7のDIOとADC1~3が全て無効で電源電圧検出ADCが有効であれば電圧を応答します。(要確認)
02381             未対応:電源電圧ADCの範囲と単位を要確認。必要に応じて値を変換する必要がある。
02382     mode = MODE_GPIN(0x92)   GPI data
02383     
02384     data[17]:mask(下位)
02385 */
02386     byte ret=0xFF;
02387 
02388     if( data[3] == MODE_GPIN ){                                     // data[3]:MODE_GPIN(92) 
02389         if( xbee_from_acum( data ) > 0 ){                           // 差出人をグローバル変数へ
02390             if( (data[17]&0xFE) != 0x00 ){                          // DIO(port 1~7)がある時
02391                 ret = (data[17] & data[20]);                        // 20:DIOデータ(下位バイト) 17:マスク
02392             }else if( (data[18]&0x8E) != 0 ){                       // ADCがあるとき
02393                 if( data[16] == 0x00 && data[17] == 0x00 ){         // DIOが全てマスクされているとき
02394                     ret = (data[19]<6) | (data[20]>2);              // 19:ADCデータ(上位)、20:下位
02395                 }else{                                              // 
02396                     ret = (data[21]<6) | (data[22]>2);              // 21:ADCデータ(上位)、22:下位
02397                 }
02398             }
02399         }else{
02400             #ifdef H3694
02401                 led_red( 1 );
02402             #endif
02403             #ifdef ERRLOG
02404                 strcopy( ERR_LOG , "ERR:xbee_gpi acum" );
02405                 ERR_CODE = xbee_from_acum( data );
02406             #endif
02407         }
02408     }else{
02409         #ifdef H3694
02410             led_red( 1 );
02411         #endif
02412         #ifdef ERRLOG
02413             strcopy( ERR_LOG , "ERR:xbee_gpi mode" );
02414             ERR_CODE = data[3];
02415         #endif
02416     }
02417     #ifdef DEBUG_RX
02418         lcd_goto(LCD_ROW_2);
02419         lcd_putstr(" M:");              // MASK表示
02420         lcd_disp_hex( data[16] );
02421         lcd_disp_hex( data[17] );
02422         lcd_putstr(" D:");              // デジタルサンプル値
02423         lcd_disp_hex( data[19] );
02424         lcd_disp_hex( data[20] );
02425     #endif
02426     return(ret);
02427 }
02428 
02429 /* (ドライバ)UART入力データの計算部 */
02430 byte xbee_uart_acum( byte *data ){
02431 /*
02432     mode =MODE_UART(0x90)   UART Receive
02433     mode =MODE_UAR2(0x91)   UART AO=0
02434 */
02435     #ifdef DEBUG_RX
02436     byte i; // DEGUG用
02437     byte len;
02438     #endif
02439     byte ret=0;
02440 
02441     if( data[3] == 0x90 ){  // data[3]:データ種別=ZigBee Recieve Packet
02442         if( xbee_from_acum( data ) > 0 ){
02443             ret = data[15];                     // 15:データ1文字 ※Digi仕様書P100記載誤り
02444             #ifdef DEBUG_RX
02445                 len = data[2]-0x0C;                 // 12バイト減算
02446             #endif
02447         }else{
02448             #ifdef H3694
02449                 led_red( 1 );
02450             #endif
02451             #ifdef ERRLOG
02452                 strcopy( ERR_LOG , "ERR:xbee_uart from" );
02453                 ERR_CODE = xbee_from_acum( data );
02454             #endif
02455         }
02456     }else if( data[3] == 0x91 ){    // data[3]:データ種別=ZigBee Explict Rx Indicator
02457         if( xbee_from_acum( data ) > 0 ){
02458             ret = data[21];                     // 14:データ1文字
02459             #ifdef DEBUG_RX
02460                 len = data[2]-0x12;                 // 18バイト減算
02461             #endif
02462         }else{
02463             #ifdef H3694
02464                 led_red( 1 );
02465             #endif
02466             #ifdef ERRLOG
02467                 strcopy( ERR_LOG , "ERR:xbee_uart2 from" );
02468                 ERR_CODE = xbee_from_acum( data );
02469             #endif
02470         }
02471     }else{
02472         #ifdef H3694
02473             led_red( 1 );
02474         #endif
02475         #ifdef ERRLOG
02476             strcopy( ERR_LOG , "ERR:xbee_uart mode" );
02477             ERR_CODE = data[3];     
02478         #endif
02479     }
02480     #ifdef DEBUG_RX
02481         lcd_goto(LCD_ROW_3);
02482         lcd_putstr("[");
02483         if( data[3]==0x90 && len>1 ) for(i=0; i< len ; i++) lcd_putch( data[15+i] );
02484         else if( data[3]==0x91 && len>1 ) for(i=0; i< len ; i++) lcd_putch( data[21+i] );
02485         else lcd_putch( ret );
02486         lcd_putstr( "](0x" );
02487         lcd_disp_hex( ret );
02488         lcd_putstr( ") l=" );
02489         lcd_disp_hex( len );
02490         if( data[3]==0x91 ){
02491             lcd_putstr(" CI:");
02492             lcd_disp_hex( data[16] );
02493             lcd_disp_hex( data[17] );
02494             lcd_putstr(".");
02495             lcd_disp_hex( data[18] );
02496             lcd_disp_hex( data[19] );
02497         }
02498     #endif
02499     return(ret);
02500 }
02501 
02502 /* (ドライバ)ATコマンドの送信+受信 */
02503 byte xbee_tx_rx(const char *at, byte *data, byte len){
02504 /*
02505 コマンド送信と受信がセットになったAPI(受信コマンドの簡単なチェックも実施)
02506     at:     ATコマンド(文字列)
02507     data[API_SIZE]: 入力データ/出力データ(共用)
02508     ※本コマンドの処理中に受信した他のパケット(送信IDとATコマンド名で判定)は破棄する。
02509     (始めに受信キャッシュクリアしている)
02510     戻り値:エラー時 0x00
02511     
02512 注意:本コマンドは応答待ちを行うので干渉によるパケット損失があります。
02513 */
02514 
02515     byte err,retry;
02516     byte r_dat = 10;    // AT=0、RAT=10、TX=未定    リモートATと通常ATの応答値dataの代入位置の差
02517     byte r_at = 1;      // AT=0、RAT=1              リモートの可否
02518     #ifndef XBEE_WIFI // ZigBee
02519     unsigned int wait_add = 0;
02520     #endif
02521     #ifdef CACHE_RES
02522         byte i;
02523     #endif
02524     
02525     #ifndef LITE    // BeeBee Lite by 蘭
02526         sci_write_check();
02527     #endif
02528     #ifdef H3694
02529         sci_clear();
02530     #endif
02531 
02532     #ifndef XBEE_WIFI // ZigBee
02533         if( at[0] == 'A' && at[1] == 'T' ){
02534             r_dat = 0; r_at=0;
02535             if( at[2] == 'W' && at[3] == 'R' ) wait_add = 100;          // ATWR 110~1100ms
02536         } else if ( at[0] == 'R' && at[1] == 'A' && at[2] == 'T' ){
02537             r_dat = 10; r_at=1;
02538             if( at[3] == 'W' && at[4] == 'R' ) wait_add = 100;  // RATWR 120~1200ms
02539         }   
02540         if( xbee_at_tx( at ,data ,len ) > 0){
02541             err = 12;                           // 受信なしエラー
02542             for( retry = 10 ; ( retry > 0 && err != 0 ) ; retry-- ){
02543                 wait_millisec( 10 + (unsigned int)r_dat );  // 応答時間待ち AT 10~100ms / RAT 20~200ms
02544                 if( wait_add != 0 ){
02545                     wait_millisec( wait_add );  // 追加ウェイト
02546                 }
02547                 if( xbee_at_rx( data ) > 0){
02548                     if(     (
02549                                 ( data[3] == MODE_RES  && r_at == 0 ) || ( data[3] == MODE_RESP && r_at == 1 )
02550                             ) && (
02551                                 data[4] == PACKET_ID
02552                             )
02553                         ){
02554                          /* ATコマンドが正しいかどうかの確認を削除(Ver 1.51)
02555                             ※MODE_RESPの条件を追加したので不要のはず。
02556                          && data[5+r_dat] == (byte)at[2+r_at] && data[6+r_dat] == (byte)at[3+r_at]
02557                          */
02558                         if( data[7+r_dat] == 0x00 ){
02559                             err=0;
02560                         }else err = data[7+r_dat];  // ATのERRORコード (AT:data[7] RAT:data[17])
02561                     }else{              // 受信したパケットIDまたはATコマンドが相違しているとき
02562                         #ifdef CACHE_RES
02563                             if( CACHE_COUNTER < CACHE_RES ){
02564                                 for( i=0 ; i < API_SIZE ; i++) CACHE_MEM[CACHE_COUNTER][i] = data[i];
02565                                 CACHE_COUNTER++;
02566                                 #ifdef DEBUG
02567                                     lcd_putstr("### CACHE_RES ### <- ");    // DEBUG
02568                                     lcd_disp_hex( CACHE_COUNTER );
02569                                     lcd_putch('\n');
02570                                 #endif
02571                             }
02572                         #endif
02573                         // キャッシュ容量が無い場合は受信データを保持せずにリトライする
02574                     }
02575                 }
02576             }
02577             //printf("\nretry=%d\n",retry);
02578         }else               err = 11;               // 送信失敗
02579     #else // XBEE_WIFI (PC + Arduino)
02580         #ifdef XBEE_WIFI_DEBUG
02581             for(i=0;i<(5+len);i++) Serial.print(at[i]);
02582             Serial.print('(');
02583             Serial.print(PACKET_ID,HEX);
02584             Serial.println(')');
02585         #endif
02586         
02587         if(DEVICE_TYPE == XB_TYPE_NULL){
02588             #ifdef DEBUG
02589                 printf("DEBUG:check DEVICE_TYPE = XB_TYPE_WIFI20\n");
02590             #endif
02591             DEVICE_TYPE = XB_TYPE_WIFI20;
02592             if( xbee_tx_rx(at, data, len) > 0 ){
02593                 return(1);
02594             }else{
02595                 #ifdef DEBUG
02596                     printf("DEBUG:check DEVICE_TYPE = XB_TYPE_WIFI10\n");
02597                 #endif
02598                 DEVICE_TYPE = XB_TYPE_WIFI10;
02599                 if( xbee_tx_rx(at, data, len) > 0 ) return(1);
02600                 else{
02601                     #ifdef DEBUG
02602                         printf("DEBUG:no Response at check DEVICE_TYPE\n");
02603                     #endif
02604                     DEVICE_TYPE = XB_TYPE_NULL;
02605                     #ifdef ERRLOG
02606                         ERR_CODE=12;
02607                         strcopy( ERR_LOG ,"ERR:tx_rx no Rx Res. wifi check");
02608                     #endif
02609                     return(0); // エラー終了
02610                 }
02611             }
02612         }
02613         if( xbee_at_tx( at ,data ,len ) > 0){
02614             err = 12;                           // 受信なしエラー
02615             for( retry = 10 ; ( retry > 0 && err != 0 ) ; retry-- ){
02616                 if( xbee_at_rx( data ) > 0){
02617                     if(     (
02618                                 ( data[3] == MODE_RES  && r_at == 0 ) || ( data[3] == MODE_RESP && r_at == 1 )
02619                             ) && (
02620                                 data[4] == PACKET_ID
02621                             )
02622                         ){
02623                          /* ATコマンドが正しいかどうかの確認を削除(Ver 1.51)
02624                             ※MODE_RESPの条件を追加したので不要のはず。
02625                          && data[5+r_dat] == (byte)at[2+r_at] && data[6+r_dat] == (byte)at[3+r_at]
02626                          */
02627                         if( data[7+r_dat] == 0x00 ){
02628                             err=0;
02629                         }else err = data[7+r_dat];  // ATのERRORコード (AT:data[7] RAT:data[17])
02630                     }else{              // 受信したパケットIDまたはATコマンドが相違しているとき
02631                         #ifdef CACHE_RES
02632                             if( CACHE_COUNTER < CACHE_RES ){
02633                                 for( i=0 ; i < API_SIZE ; i++) CACHE_MEM[CACHE_COUNTER][i] = data[i];
02634                                 CACHE_COUNTER++;
02635                                 #ifdef DEBUG
02636                                     lcd_putstr("### CACHE_RES ### <- ");    // DEBUG
02637                                     lcd_disp_hex( CACHE_COUNTER );
02638                                     lcd_putch('\n');
02639                                 #endif
02640                             }
02641                         #endif
02642                         // キャッシュ容量が無い場合は受信データを保持せずにリトライする
02643                     }
02644                 }else{                  // 受信データが無い時(リトライ前)
02645                     wait_millisec(50);  // 50msの待ち時間
02646                 }
02647             }
02648         }else err = 11;             // 送信失敗
02649         delay(1);   // 直前のコマンド応答がすぐに返った時にキャッシュに貯めれないことを防止する
02650 
02651     #endif
02652 
02653     if( err ){
02654         wait_millisec( 1000 );      // 応答待ち状態で、次々にコマンドを送るとXBeeモジュールが非応答になる対策
02655         #ifdef H3694
02656             led_red( 1 );
02657         #endif
02658         #ifdef ERRLOG
02659             ERR_CODE=err;
02660             switch(err){
02661                 case 2:             // 01234567890123456789
02662                     strcopy( ERR_LOG ,"ERR:tx_rx AT Command");
02663                     break;
02664                 case 3:
02665                     strcopy( ERR_LOG ,"ERR:tx_rx AT Param. ");
02666                     break;
02667                 case 4:
02668                     strcopy( ERR_LOG ,"ERR:tx_rx AT Commu. ");
02669                     break;
02670                 case 10:
02671                     strcopy( ERR_LOG ,"ERR:tx_rx not AT CMD");
02672                     break;
02673                 case 11:
02674                     strcopy( ERR_LOG ,"ERR:tx_rx TX Failed ");
02675                     break;
02676                 case 12:
02677                     strcopy( ERR_LOG ,"ERR:tx_rx no Rx Res.");
02678                     break;
02679                 case 13:
02680                     strcopy( ERR_LOG ,"ERR:tx_rx AT Pckt ID");
02681                     break;
02682                 case 14:
02683                     strcopy( ERR_LOG ,"ERR:tx_rx Diff.Adrs.");
02684                     break;
02685                 default:
02686                     strcopy( ERR_LOG ,"ERR:tx_rx AT unknown");
02687                     break;
02688             }
02689             ERR_LOG[20] = ':'; 
02690             if( at[0] == 'A' ){
02691                 ERR_LOG[21] = at[2];
02692                 ERR_LOG[22] = at[3];
02693             }else{
02694                 ERR_LOG[21] = at[3];
02695                 ERR_LOG[22] = at[4];
02696             }
02697         #endif
02698     }
02699     #ifdef XBEE_WIFI_DEBUG
02700         if( err ){
02701             Serial.print("ERR in tx_rx ");
02702             Serial.println(err,DEC);
02703         }
02704     #endif
02705     #ifdef DEBUG
02706         #ifdef ARM_MBED
02707             if( err ){
02708                 _xbee_debug.printf("DEBUG: %s ", ERR_LOG);
02709                 _xbee_debug.printf("(err=%d)\r\n", err);
02710             }
02711         #else
02712             if( err ) fprintf(stderr,"DEBUG: %s (err=%d)\n", ERR_LOG,err);
02713         #endif
02714     #endif
02715     return( !err );
02716 }
02717 
02718 /***********************************************************************
02719 XBee用 UART出力API
02720 byte xbee_putch( const char c );
02721 byte xbee_putstr( const char *s );
02722 void xbee_disp_hex( const unsigned char i );
02723 void xbee_disp_1( const unsigned int x );
02724 void xbee_disp_2( unsigned int x );
02725 void xbee_disp_3(unsigned int x);
02726 void xbee_disp_5(unsigned int x);
02727 void xbee_log( const byte level, const char *err , const byte x );
02728 ***********************************************************************/
02729 
02730 #ifndef LITE    // BeeBee Lite by 蘭
02731 byte xbee_putch( const char c ){
02732     byte data[2];
02733     byte len;
02734     data[0] = (byte)c;
02735     if( xbee_at_tx( "TX", data , 1) == 0 ) len=0; else len=1;
02736     return( len );
02737 }
02738 #endif
02739 
02740 byte xbee_putstr( const char *s ){
02741 /*
02742     文字を送信する
02743     入力:char *s
02744     出力:送信データ長を応答。0の場合は異常
02745 */  
02746     byte data[API_TXSIZE-17];       // 17バイトはAPIヘッダ+CRC1バイトなのでデータ長は[API_TXSIZE-18]+null文字で+1する-17
02747     byte i;
02748 
02749     for(i=0; (i< (API_TXSIZE-18) ) && (s[i] != 0x00) ; i++){    // データ長はAPI_TXSIZE-18
02750         data[i] = (byte)s[i];       // テキストデータをバイナリデータ(バイト値)に変換する
02751     }
02752     data[i] = 0x00;
02753     if( xbee_at_tx( "TX", data , i) == 0) i=0;
02754     return( i );
02755 }
02756 
02757 #ifndef LITE    // BeeBee Lite by 蘭
02758 void xbee_disp_hex( const byte i ){
02759     byte data[3];
02760     data[0] = i&0xF0;
02761     data[0] = data[0]>>4;
02762     data[0] += '0';
02763     if (data[0]>'9') data[0] += 7;
02764     data[1]=(i&0x0F)+'0';
02765     if (data[1]>'9') data[1]+=7;
02766     xbee_at_tx( "TX", data , 2);
02767 }
02768 
02769 void xbee_disp_1( const unsigned int x ){
02770     if      (x<10)  xbee_putch((char)(x+0x30));
02771     else if (x<16)  xbee_putch((char)(x-10+'A'));
02772     else            xbee_putch('X');
02773 }
02774 
02775 void xbee_disp_2( unsigned int x ){
02776     char s[3];
02777     unsigned int y;
02778     if (x<100){
02779         y=x/10; s[0]=(char)(y+0x30); x-=(y*10);
02780         s[1]=(char)(x+0x30);
02781         s[2]='\0';
02782         if( s[0]=='0' ){
02783             s[0]=' ';
02784         }
02785         xbee_putstr( s );
02786     }else xbee_putstr("XX");
02787 }
02788 
02789 void xbee_disp_3(unsigned int x){
02790     char s[4];
02791     unsigned int y;
02792     if (x<1000){
02793         y=x/100; s[0]=(char)(y+0x30); x-=(y*100);
02794         y=x/10;  s[1]=(char)(y+0x30); x-= (y*10);
02795         s[2]=(char)(x+0x30);
02796         s[3]='\0';
02797         if( s[0]=='0' ){
02798             s[0]=' ';
02799             if( s[1]=='0' ){
02800                 s[1]=' ';
02801             }
02802         }
02803         xbee_putstr( s );
02804     }else xbee_putstr("XXX");
02805 }
02806 
02807 void xbee_disp_5(unsigned int x){
02808     char s[6];
02809     unsigned int y;
02810     if (x<=65535){
02811         y=x/10000; s[0]=(char)(y+0x30); x-=(y*10000);
02812         y=x/1000;  s[1]=(char)(y+0x30); x-= (y*1000);
02813         y=x/100;   s[2]=(char)(y+0x30); x-=  (y*100);
02814         y=x/10;    s[3]=(char)(y+0x30); x-=   (y*10);
02815         s[4]=(char)(x+0x30);
02816         s[5]='\0';
02817         if( s[0]=='0' ){
02818             s[0]=' ';
02819             if( s[1]=='0' ){
02820                 s[1]=' ';
02821                 if( s[2]=='0' ){
02822                     s[2]=' ';
02823                     if( s[3]=='0' ){
02824                         s[3]=' ';
02825                     }
02826                 }
02827             }
02828         }
02829         xbee_putstr( s );
02830     }else xbee_putstr("XXXXX");
02831 }
02832 #endif // LITE
02833 
02834 void xbee_log(const byte level, const char *err, const byte x ){
02835 /*
02836     エラーログ用レベルガイド
02837         LEVEL 5 ERROR   致命的なエラー、バグ発生
02838         LEVEL 4 ERR     通信エラー等のうち不具合動作を伴う懸念のあるもの。500ms待ち挿入
02839         LEVEL 3 CAUTION 通信エラー、使い方の問題など
02840         LEVEL 2 未定義
02841         LEVEL 1 LOG     各関数の動作確認用
02842 */
02843     #ifdef ERRLOG
02844         /* PCの場合 */
02845         #ifndef ARDUINO
02846         #ifndef H3694
02847         #ifdef XBEE_ERROR_TIME
02848             time_t error_time;
02849             struct tm *error_time_st;
02850             
02851             time(&error_time);
02852             error_time_st = localtime(&error_time);
02853         #endif
02854         #endif
02855         #endif
02856             
02857         #ifdef DEBUG
02858             if( level >= 1 ){
02859         #else
02860             if( level >= 3 ){
02861         #endif
02862             /* マイコンの場合 */
02863             #ifdef ARDUINO
02864                 lcd_goto(LCD_ROW_4);
02865                 lcd_putch('[');
02866                 lcd_disp_hex( TIMER_SEC );
02867                 lcd_putch(':');
02868                 lcd_disp_hex( timera() );
02869                 lcd_putch(']');
02870                 lcd_putstr( err );
02871                 lcd_putch('(');
02872                 lcd_disp_hex( x );
02873                 lcd_putch(')');
02874             #endif
02875             #ifdef H3694
02876                 lcd_goto(LCD_ROW_4);
02877                 lcd_putch('[');
02878                 lcd_disp_hex( TIMER_SEC );
02879                 lcd_putch(':');
02880                 lcd_disp_hex( timera() );
02881                 lcd_putch(']');
02882                 lcd_putstr( err );
02883                 lcd_putch('(');
02884                 lcd_disp_hex( x );
02885                 lcd_putch(')');
02886             #endif
02887             #ifdef ARM_MBED
02888                 lcd_goto(LCD_ROW_4);
02889                 lcd_putch('[');
02890                 lcd_disp_hex( TIMER_SEC );
02891                 lcd_putch(':');
02892                 lcd_disp_hex( timera() );
02893                 lcd_putch(']');
02894                 lcd_putstr( err );
02895                 lcd_putch('(');
02896                 lcd_disp_hex( x );
02897                 lcd_putch(')');
02898                 lcd_putch( 0x0D );              // CR(\r)
02899                 lcd_putch( 0x0A );              // LF(\n)
02900             #endif
02901                         
02902             /*
02903             lcd_putch( 0x0D );              // CR(\r)
02904             lcd_putch( 0x0A );              // LF(\n)
02905             */
02906             /* PCの場合 */
02907             #ifndef ARDUINO
02908             #ifndef H3694
02909             #ifndef ARM_MBED
02910                 #ifdef XBEE_ERROR_TIME
02911                     fprintf(stderr,"%4d/%02d/%02d %02d:%02d:%02d[%02X:%02X]%s(%02X)\n",
02912                         error_time_st->tm_year+1900,
02913                         error_time_st->tm_mon+1,
02914                         error_time_st->tm_mday,
02915                         error_time_st->tm_hour,
02916                         error_time_st->tm_min,
02917                         error_time_st->tm_sec,
02918                         TIMER_SEC,
02919                         timera(),
02920                         err,
02921                         x);
02922                 #else
02923                     fprintf(stderr,"[%02X:%02X]%s(%02X)\n",
02924                         TIMER_SEC,
02925                         timera(),
02926                         err,
02927                         x);
02928                 #endif
02929             #endif
02930             #endif
02931             #endif
02932         }
02933         if( level > 3 ) wait_millisec( 500 );   // LEVEL 4以上に対して待ち時間を設定
02934     #endif
02935 }
02936 
02937 /***********************************************************************
02938 アプリ向け提供関数
02939 XBee用 各種制御 入出力定義を変更した場合は履歴に記載します
02940 ***********************************************************************/
02941 
02942 byte xbee_reset( void ){
02943 /*  XBeeモジュールのリセット
02944     戻り値:0=エラー、強制終了あり(PC版)、無限定しあり(H8版)
02945 */
02946     #ifndef LITE    // BeeBee Lite by 蘭
02947     byte i;
02948     #endif
02949     byte ret=0; // 戻り値 0:異常終了
02950     #ifndef XBEE_WIFI // ZigBee
02951         byte value[API_SIZE];
02952         value[0] = 0x00;
02953     #endif
02954     
02955     #ifndef XBEE_WIFI
02956     #ifndef LITE    // BeeBee Lite by 蘭
02957         sci_write_check();
02958     #endif
02959     sci_clear();                        // シリアル異常をクリア
02960     DEVICE_TYPE = 0x20;                 // タイプ名を初期化
02961     #endif
02962     
02963     #ifdef LITE // BeeBee Lite by 蘭
02964         ret = xbee_tx_rx( "ATVR", value ,0 );   // ZigBee 種類の取得
02965         if( ret == 0 ){
02966             #ifdef ARDUINO
02967                 return(0);
02968             #else
02969                 exit(-1);
02970             #endif
02971         }else{
02972             DEVICE_TYPE = value[8];
02973         }                                       // LITEはリセットしない
02974     #else // normal
02975         wait_millisec(100);
02976         for( i=1 ; i< 4 ; i++){
02977             #ifndef XBEE_WIFI // ZigBee
02978                 ret = xbee_tx_rx( "ATVR", value ,0 );
02979             #else
02980                 ret = 1;
02981             #endif
02982             if( ret > 0){
02983                 #ifndef XBEE_WIFI
02984                     DEVICE_TYPE = value[8];
02985                     if( DEVICE_TYPE != ZB_TYPE_COORD && 
02986                         DEVICE_TYPE != ZB_TYPE_ROUTER && 
02987                         DEVICE_TYPE != ZB_TYPE_ENDDEV){ // VRの確認
02988                         #ifdef LCD_H
02989                             lcd_cls();
02990                             #ifdef H3694
02991                                 led_red( 1 );
02992                             #endif
02993                             lcd_putstr( "EXIT:XBEE NOT IN API MODE" );
02994                         #endif
02995                         #ifdef H3694
02996                             return(0);
02997                         #elif ARDUINO
02998                             return(0);
02999                         #else
03000                             exit(-1);
03001                         #endif
03002                     }
03003                 #else // XBEE_WIFI
03004                     DEVICE_TYPE = XB_TYPE_NULL;
03005                 #endif
03006             }else{
03007                 if( i == 3 ){
03008                     #ifdef LCD_H
03009                         lcd_cls();
03010                         #ifdef H3694
03011                             led_red( 1 );
03012                         #endif
03013                         lcd_putstr( "EXIT:NO RESPONCE FROM XBEE" );
03014                     #endif
03015                     #ifdef H3694
03016                         return(0);
03017                     #elif ARDUINO
03018                         return(0);
03019                     #else
03020                         exit(-1);
03021                     #endif
03022                 }
03023                 wait_millisec(1000);
03024             }
03025         }
03026         #ifndef XBEE_WIFI // ZigBee
03027             wait_millisec(100);
03028             ret = xbee_tx_rx( "ATFR", value ,0 );
03029             if( ret == 0){
03030                 #ifdef LCD_H
03031                     lcd_cls();
03032                     #ifdef H3694
03033                         led_red( 1 );
03034                     #endif
03035                     lcd_putstr( "EXIT:CANNOT RESET XBEE" );
03036                 #endif
03037                 #ifdef H3694
03038                     return(0);
03039                 #elif ARDUINO
03040                     return(0);
03041                 #else
03042                     exit(-1);
03043                 #endif
03044             }
03045             wait_millisec(3000);                // リセット指示後3秒後に起動
03046             sci_clear();                        // 再起動のメッセージをクリア
03047         //  while( xbee_at_rx( value ) == 0 );  // パケットの破棄(永久ループの懸念がある)
03048             value[0] = 0x01;                    // API MODE=1に設定
03049             xbee_tx_rx("ATAP", value , 1 );
03050             value[0] = 0x05;                    // RSSI LEDを点灯
03051             xbee_tx_rx("ATP0", value , 1 );
03052             wait_millisec(500);
03053             value[0] = 0x01;                    // RSSI LEDを受信強度に戻す
03054             xbee_tx_rx("ATP0", value , 1 );
03055         #endif
03056     #endif // LITE
03057     return( ret );
03058 }
03059 
03060 byte xbee_myaddress( byte *address ){
03061 /*
03062 自分自身のIEEEアドレスを取得する / XBee Wifi(PC)の場合は設定する
03063     byte *address : IEEEアドレスを代入する
03064     戻り値=1で正常読み込み、2は書き込み。0は異常
03065 */
03066     #ifndef XBEE_WIFI
03067         byte data[API_SIZE];
03068         byte i=0;
03069         byte ret=0;
03070         
03071         data[0]=0x00;
03072         /* ショートアドレスの取得はしないことにする。(Coordinatorは常に00)
03073         if( xbee_tx_rx( "ATMY",data,0) ){
03074             for(i=0;i<2;i++){
03075                 SADR_MY[i]=data[8+i];
03076             }
03077         }
03078         */
03079         data[0]=0x00;
03080         if( xbee_tx_rx( "ATSH",data,0) ){
03081             for(i=0;i<4;i++){
03082                 address[i]=data[8+i];
03083             }
03084             data[0]=0x00;
03085             if( xbee_tx_rx( "ATSL",data,0) ){
03086                 for(i=0;i<4;i++){
03087                     address[4+i]=data[8+i];
03088                 }
03089                 ret=1;
03090             }
03091         }
03092         #ifdef LCD_H
03093             if( ret==0 ) xbee_log( 5, "ERROR: at at_my" , 0 );
03094             xbee_log( 1, "done:xbee_myaddress" , ret );
03095         #endif
03096         return( ret );
03097     #else // XBEE_WIFI      /******* ADR_MYに登録されているIPアドレスを設定する **********/
03098         #ifdef ARDUINO
03099             byte i=0;
03100             IPAddress ip = Ethernet.localIP();
03101             for(i=0;i<4;i++) ADR_MY[i] = ip[i];
03102             for(i=0;i<4;i++) address[i] = ADR_MY[i];
03103             return( 1 );
03104         #else // PC
03105             byte i;
03106             byte ret=2;
03107             for(i=0;i<4;i++) if( ADR_MY[i] != 0xFF ) ret=1;
03108             if(ret==1) for(i=0;i<4;i++) address[i]=ADR_MY[i];   // ADR_MYが設定されているときは読み込む
03109             else for(i=0;i<4;i++) ADR_MY[i]=address[i]; // ADR_MYが全てFFの時は入力addressを設定する。
03110             #ifdef DEBUG
03111                 printf("ADR_MY=");
03112                 for(i=0;i<4;i++) printf("%d.",(int)ADR_MY[i]);
03113                 printf("\b\n");
03114             #endif
03115             return( ret );
03116         #endif
03117     #endif
03118 }
03119 
03120 void xbee_address(const byte *address){
03121 /*
03122 送信用の宛先アドレス設定用の関数
03123     入力:byte *address = 宛先(子機)アドレス
03124 */
03125     byte i;
03126 
03127     #ifndef XBEE_WIFI // XBee ZB用
03128         for(i=0; i< 8 ;i++ ) ADR_DEST[i] = address[i];
03129         #ifndef ARDUINO
03130         #ifndef ARM_MBED
03131             SADR_DEST[0] = 0xFF;
03132             SADR_DEST[1] = 0xFE;
03133         #endif
03134         #endif
03135     #else // XBEE_WIFI
03136         #ifdef ARDUINO
03137             for( i=0;i<4;i++) ADR_DEST[i] = address[i];
03138         #else
03139             if( bytecmp(ADR_DEST,address,4) != 0 ){
03140                 close_serial_port_tx();
03141                 open_serial_port_tx( address );
03142                 for( i=0;i<4;i++) ADR_DEST[i] = address[i];
03143             }else{
03144                 #ifdef LCD_H
03145                     xbee_log( 2, "same address" , address[7] );
03146                 #endif
03147             }
03148         #endif
03149     #endif
03150     
03151     #ifdef DEBUG
03152         #ifndef XBEE_WIFI
03153             lcd_cls(); lcd_goto(LCD_ROW_1); lcd_putstr("DEST=");
03154             for(i=4;i<8;i++){ lcd_disp_hex( ADR_DEST[i] ); lcd_putstr(" "); }
03155         #else // XBEE_WIFI
03156             printf("DEST=");
03157             for(i=0;i<4;i++) printf("%d.",(int)ADR_DEST[i]);
03158             printf("\b\n");
03159         #endif
03160     #endif
03161     #ifdef LCD_H
03162         xbee_log( 1, "done:xbee_address" , address[7] );
03163     #endif
03164 }
03165 
03166 #ifndef XBEE_WIFI
03167 #ifndef ARDUINO
03168 #ifndef ARM_MBED
03169 void xbee_short_address(const byte *address){
03170     SADR_DEST[0] = address[0];
03171     SADR_DEST[1] = address[1];
03172 }
03173 #endif
03174 #endif
03175 #endif
03176 
03177 byte xbee_atd( const byte *address ){
03178 /*
03179 送信用の宛先アドレス設定用の関数 XBeeへの設定
03180     入力:byte *address = 宛先(子機)アドレス
03181     戻り値:戻り値=1で正常、0は異常
03182 */
03183     #ifndef XBEE_WIFI
03184         byte data[API_SIZE];
03185         byte i;
03186         byte ret=0;
03187         
03188         for(i=0;i<4;i++)data[i]=address[i];
03189         if( xbee_tx_rx( "ATDH",data,4) ){
03190             for(i=0;i<4;i++)data[i]=address[i+4];
03191             if( xbee_tx_rx( "ATDL",data,4) ){
03192                 ret=1;
03193             }
03194         }
03195         return( ret );
03196     #else // XBEE_WIFI
03197         return( 0 );
03198     #endif
03199 }
03200 
03201 byte xbee_ratd(const byte *dev_address, const byte *set_address ){
03202 /*
03203 指定したアドレスのXBee子機に任意のアドレスを(宛先として)設定する
03204     byte *dev_address : 設定先のXBeeデバイスのアドレス
03205     byte *set_address : 設定するアドレス
03206     戻り値=XBeeデバイス名。0xFFは異常
03207 */
03208     byte i=0;
03209     #ifdef XBEE_WIFI
03210     byte len=0;
03211     #endif
03212     byte data[API_SIZE];
03213     byte dd=0xFF;           // デバイス名
03214 
03215     xbee_address(dev_address);                              // 宛先のアドレスを設定
03216     #ifndef XBEE_WIFI
03217         for( i=0;i<4;i++) data[i]=set_address[i];               // 上位4バイトをdataに代入
03218         if( xbee_tx_rx( "RATDH", data ,4 ) > 0 ){               // 上位4バイトを設定
03219             for( i=0;i<4;i++) data[i]=set_address[i+4];         // 下位4バイトをdataに代入
03220             if( xbee_tx_rx( "RATDL", data ,4 ) > 0 ){           // 下位4バイトを設定
03221                 if( xbee_tx_rx( "RATDD", data ,0 ) > 0 ){       // デバイス名を取得
03222                     if( data[18]==0x00 && data[19]==0x03 && data[20]==0x00 ){   // XBeeデバイス
03223                         dd=data[21];                            // デバイス名をddに代入
03224                     }
03225                 }else{
03226                     #ifdef LCD_H
03227                         xbee_log( 4, "ERR:tx_rx RATDD at ratd" , 1 );
03228                     #endif
03229                 }
03230             }else{
03231                 #ifdef LCD_H
03232                     xbee_log( 4, "ERR:tx_rx RATDL at ratd" , 1 );
03233                 #endif
03234             }
03235         }else{
03236             #ifdef LCD_H
03237                 xbee_log( 4, "ERR:tx_rx RATDH at ratd" , 1 );
03238             #endif
03239         }
03240     #else // XBEE_WIFI
03241         for( i=0;i<4;i++){
03242             if(set_address[i] >= 100){
03243                 data[len] = (byte)(set_address[i]/100);
03244                 data[len+1] = (byte)(set_address[i]/10)-10*data[len]+(byte)'0';
03245                 data[len] += (byte)'0';
03246                 len += 2;
03247             }else if(set_address[i] >= 10){
03248                 data[len] = (byte)(set_address[i]/10)+(byte)'0';
03249                 len += 1;
03250             }
03251             data[len] = (byte)(set_address[i]%10)+(byte)'0';
03252             data[len+1] = (byte)'.';        // 最後のデータdata[len]に「.」が入るが
03253             len += 2;                       
03254         }
03255         len--;                              // 最後の「.」は送信しない。
03256         if( xbee_tx_rx( "RATDL", data ,len ) > 0 ){         // 下位4バイトを設定
03257             dd = 0x00;
03258         }else{
03259             #ifdef LCD_H
03260                 xbee_log( 4, "ERR:tx_rx RATDL at ratd" , 1 );
03261             #endif
03262         }
03263     #endif
03264     return(dd);
03265 }
03266 
03267 byte xbee_ratd_myaddress(const byte *address){
03268 /*
03269 指定したアドレスのXBee子機に本機のアドレスを(宛先として)設定する
03270     byte *address : 設定先のXBeeデバイスのアドレス
03271     戻り値=XBeeデバイス名。0xFFは異常
03272 
03273 */
03274     byte i=0;
03275     #ifdef XBEE_WIFI
03276     byte len=0;
03277     #endif
03278     byte data[API_SIZE];
03279     byte adr_my[8];
03280     byte dd=0xFF;           // デバイス名
03281 
03282     if( xbee_myaddress(adr_my) ){                               // 自分のアドレスを取得
03283         #ifdef DEBUG
03284             #ifndef XBEE_WIFI
03285                 #ifdef ARM_MBED
03286                     _xbee_debug.printf("adr_my =");
03287                     for( i=0 ; i<8 ; i++) _xbee_debug.printf("%02x ",adr_my[i]);        
03288                     _xbee_debug.printf("\b\n");
03289                 #else // PC
03290                     printf("adr_my =");
03291                     for( i=0 ; i<8 ; i++) printf("%02x ",adr_my[i]);        
03292                     printf("\b\n");
03293                 #endif
03294             #else // XBEE_WIFI
03295                 printf("adr_my =");
03296                 for( i=0 ; i<4 ; i++) printf("%d.",adr_my[i]);      
03297                 printf("\b\n");
03298             #endif
03299         #endif
03300         xbee_address(address);                              // 宛先のアドレスを設定
03301         #ifndef XBEE_WIFI
03302             for( i=0;i<4;i++) data[i]=adr_my[i];                // 上位4バイトをdataに代入
03303             if( xbee_tx_rx( "RATDH", data ,4 ) > 0 ){               // 上位4バイトを設定
03304                 for( i=0;i<4;i++) data[i]=adr_my[i+4];          // 下位4バイトをdataに代入
03305                 if( xbee_tx_rx( "RATDL", data ,4 ) > 0 ){           // 下位4バイトを設定
03306                     if( xbee_tx_rx( "RATDD", data ,0 ) > 0 ){       // デバイス名を取得
03307                         if( data[18]==0x00 && data[19]==0x03 && data[20]==0x00 ){   // XBeeデバイス
03308                             dd=data[21];                            // デバイス名をddに代入
03309                         }
03310                     }else{
03311                         #ifdef LCD_H
03312                             xbee_log( 4, "ERR:tx_rx RATDD at set_myadd" , 1 );
03313                         #endif
03314                     }
03315                 }else{
03316                     #ifdef LCD_H
03317                         xbee_log( 4, "ERR:tx_rx RATDL at set_myadd" , 1 );
03318                     #endif
03319                 }
03320             }else{
03321                 #ifdef LCD_H
03322                     xbee_log( 4, "ERR:tx_rx RATDH at set_myadd" , 1 );
03323                 #endif
03324             }
03325         #else // XBEE_WIFI
03326             for( i=0;i<4;i++){
03327                 if(adr_my[i] >= 100){
03328                     data[len] = (byte)(adr_my[i]/100);
03329                     data[len+1] = (byte)(adr_my[i]/10)-10*data[len]+(byte)'0';
03330                     data[len] += (byte)'0';
03331                     len += 2;
03332                 }else if(adr_my[i] >= 10){
03333                     data[len] = (byte)(adr_my[i]/10)+(byte)'0';
03334                     len += 1;
03335                 }
03336                 data[len] = (byte)(adr_my[i]%10)+(byte)'0';
03337                 data[len+1] = (byte)'.';        // 最後のデータdata[len]に「.」が入るが
03338                 len += 2;                       
03339             }
03340             len--;                              // 最後の「.」は送信しない。
03341             if( xbee_tx_rx( "RATDL", data ,len ) > 0 ){         // 下位4バイトを設定
03342                 dd = 0x00;
03343             }else{
03344                 #ifdef LCD_H
03345                     xbee_log( 4, "ERR:tx_rx RATDL at set_myadd" , 1 );
03346                 #endif
03347             }
03348             // XBee Wi-Fi 2.0だと情報をクラウドに送信してしまう。LAN内に送信するように変更する
03349             if(DEVICE_TYPE == XB_TYPE_WIFI20){
03350                 data[0]=0x00;   xbee_tx_rx( "RATDO", data ,1 ); // DO: XBee WiFi 2.0用 Device Option=0
03351             }
03352         #endif
03353     }else{
03354         #ifdef LCD_H
03355             xbee_log( 4, "ERR:at_my at set_myadd" , 1 );
03356         #endif
03357     }
03358     return(dd);
03359 }
03360 
03361 void xbee_from(byte *address){
03362 /*
03363     最後に受信したデバイスの送信元アドレスの読み込み。
03364     但し、xbee_rx_callで受信した場合の送信元アドレスは
03365     「構造体XBEE_RESULT変数.FROM」で読むこと。
03366     (キャッシュ値での受信の場合があるので) 
03367     出力:byte *address IEEEアドレス
03368 */
03369     byte i;
03370     
03371     #ifndef XBEE_WIFI
03372         for(i=0; i< 8 ;i++ ) address[i] = ADR_FROM[i];
03373     #else // XBEE_WIFI
03374         for(i=0; i< 4 ;i++ ) address[i] = ADR_FROM[i];
03375     #endif
03376     #ifdef LCD_H
03377         xbee_log( 1, "done:xbee_from" , 0 );
03378     #endif
03379 }
03380 
03381 byte text2hex4data( byte *data, const char *in , const byte com_len){
03382 /*
03383     data        出力:変換後の数値データ(バイナリデータ)
03384     in          入力:文字としての16進数(テキストデータ)
03385     com_len     入力:ATコマンドの文字数(ATを含む)。16進数に変換する部分以外の先頭文字数
03386     戻り値      出力:変換したバイト数
03387 */
03388     byte i, j, len, val;
03389     
03390     /* ATコマンドに続く16進数の引数入力 */
03391     for( len = 0 ; len < API_SIZE ; len++ ){
03392         j = (byte)in[len * 2 + com_len];
03393         i = (byte)in[len * 2 + com_len + 1];
03394         if( j == (byte)'\0' || i == (byte)'\0' )break;
03395         // 16進数の文字を数字にしてdataに代入。1桁は考慮。奇数桁は考慮せずに処理。
03396         if( (j >= (byte)'0' && j <= (byte)'9') || (j >= (byte)'A' && j <= (byte)'F') ){
03397             if( j > '9' ) data[len] = j - (byte)'A' + 10;
03398             else data[len] = j - (byte)'0';
03399             if( (i >= (byte)'0' && i <= (byte)'9') || (i >= (byte)'A' && i <= (byte)'F') ){
03400                 if( i > '9' ) val = i - (byte)'A' + 10;
03401                 else val = i - (byte)'0';
03402                 data[len] *= 16;
03403                 data[len] += val;
03404             }
03405         }else break;
03406     }
03407     return( len );
03408 }
03409 
03410 byte xbee_rat(const byte *address, const char *in){
03411 /*
03412     リモートATコマンドを送信するユーザ提供関数
03413     入力:byte *address = 宛先(子機)アドレス 
03414        char *in = 入力するATコマンド 例: ATDL0000FFFF 最大文字数は XB_AT_SIZE-1
03415     出力:ATコマンドの結果 STATUS_OK / STATUS_ERR / STATUS_ERR_AT / STATUS_ERR_PARM / STATUS_ERR_AIR
03416        0xFFで送信失敗もしくはデータ異常
03417 */
03418     byte i;
03419     char at[6];
03420     byte data[API_SIZE];
03421     byte len;
03422     byte ret = 0xFF;
03423     byte com_len =0;
03424     byte null_adr[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
03425     
03426     if( in[0]=='A' && in[1]=='T' ){
03427         if( bytecmp(null_adr,address,8) == 0 ){
03428             // xbee_atから呼ばれた場合 ATxx_;ローカルAT
03429             com_len = 4;                        // 入力ATコマンド長 ATxx 4
03430             at[0]='A'; at[1]='T';
03431             if( in[2] == '\0' ){
03432                 at[2]='D'; at[3]='D';
03433             }else{
03434                 at[2]=in[2]; at[3]=in[3];
03435             }
03436             at[4]='\0';
03437         }else{
03438             // リモートat(xbee_rat)指定で呼び出された場合 RATxx_;実際のリモートAT
03439             com_len = 4;                        // 入力ATコマンド長 ATxx 4
03440             at[0]='R'; at[1]='A'; at[2]='T';
03441             // アプリ呼び出しにつき、ATの後に何もない場合が想定される。その時はATDDとみなす
03442             if( in[2] == '\0' ){
03443                 at[3]='D'; at[4]='D';
03444             }else{
03445                 at[3]=in[2]; at[4]=in[3];
03446             }
03447             at[5]='\0';
03448         }
03449     }else if( in[0]=='R' && in[1]=='A' && in[2]=='T' ){
03450         com_len = 5;                            // 入力ATコマンド長 RATxx 5
03451         at[0]='R'; at[1]='A'; at[2]='T';
03452         at[3]=in[3]; at[4]=in[4];
03453         at[5]='\0';
03454     }else if( in[0]=='T' && in[1]=='X' ){
03455         com_len = 2;                            // 入力ATコマンド長 TX 2
03456         at[0]='T'; at[1]='X'; 
03457         at[2]='\0';
03458     }
03459     #ifndef ARDUINO
03460     #ifndef ARM_MBED
03461     else if(in[0]=='Z' && in[1]=='C'){
03462         com_len = 2;                            // 入力ATコマンド長 TX 2
03463         at[0]='Z'; at[1]='C'; 
03464         at[2]='\0';
03465         if( SADR_DEST[0]==0xFF && SADR_DEST[1] == 0xFE) xbee_address(address);
03466         len = text2hex4data( data, in , com_len);
03467         if( xbee_at_tx( at, data ,len ) > 0 ) ret=0;
03468         com_len = 0;
03469     }
03470     #endif
03471     #endif
03472     if( com_len > 0 ){
03473         if( at[0] != 'A' && SADR_DEST[0] == 0xFF && SADR_DEST[1] == 0xFE) xbee_address(address);
03474         len = text2hex4data( data, in , com_len);
03475         // test
03476         // printf("xbee_tx_rx %s len=%d\n",at,len);
03477         #ifdef LCD_H
03478             xbee_log( 1, "started:xbee_rat" , len );
03479         #endif
03480         if( xbee_tx_rx( at, data ,len ) > 0 ){
03481             #ifdef LCD_H
03482                 xbee_log( 1, "done:rat" , len );
03483             #endif
03484             if( data[3] == MODE_RES ){
03485                 ret = data[7];
03486             }else if( data[3] == MODE_RESP ){
03487                 for(i=0;i<8;i++) ADR_FROM[i]=data[5+i]; // 2013.9.15 追加
03488                 ret = data[17];
03489             }else{
03490                 ret = 0xFF;
03491             }
03492         }else{
03493             #ifdef LCD_H
03494                 xbee_log( 4, "ERR:tx_rx at xbee_rat" , 1 );
03495             #endif
03496         }
03497     }
03498     #ifdef LCD_H
03499         xbee_log( 1, "done:xbee_rat" , ret );
03500     #endif
03501     return( ret );
03502 }
03503 
03504 byte xbee_rat_force(const byte *address, const char *in){
03505 /*
03506     リモートATコマンドを送信するユーザ提供関数。応答値をxbee_rx_callで得る。
03507     入力:byte *address = 宛先(子機)アドレス 
03508        char *in = 入力するATコマンド 例: ATDL0000FFFF 最大文字数は XB_AT_SIZE-1
03509     出力:0x00で送信失敗もしくはデータ異常
03510 */
03511     char at[6];
03512     byte data[API_SIZE];
03513     byte len;
03514     byte ret = 0x00;
03515     
03516     if( in[0]=='A' && in[1]=='T' ){
03517         at[0]='S'; at[1]='A'; at[2]='T';
03518         at[3]=in[3]; at[4]=in[4];
03519         at[5]='\0';
03520         xbee_address(address);
03521         len = text2hex4data( data, in , 5 );
03522         #ifdef LCD_H
03523             xbee_log( 1, "started:xbee_ratf" , len );
03524         #endif
03525         if( xbee_at_tx( at, data ,len ) > 0 ){
03526             #ifdef LCD_H
03527                 xbee_log( 1, "done:ratf" , len );
03528             #endif
03529             ret = PACKET_ID;
03530         }
03531         #ifdef XBEE_WIFI
03532             if(ret){    // 送信データを即確定する
03533                 at[0]='S'; at[1]='A'; at[2]='T';
03534                 at[3]='A'; at[4]='C';
03535                 xbee_at_tx( at, data ,0 );
03536             }
03537         #endif
03538     }
03539     #ifdef LCD_H
03540         xbee_log( 1, "done:xbee_rat_force" , 1 );
03541     #endif
03542     return( ret );
03543 }
03544 
03545 byte xbee_at(const char *in){
03546 /*
03547     ローカルATコマンドを送信するユーザ提供関数。
03548     入力:char *in = 入力するATコマンド 例: ATDL0000FFFF 最大文字数は XB_AT_SIZE-1
03549     出力:ATコマンドの結果 STATUS_OK / STATUS_ERR / STATUS_ERR_AT / STATUS_ERR_PARM / STATUS_ERR_AIR
03550        0xFFで送信失敗もしくはデータ異常
03551        別関数xbee_atnjとエラー時の戻り値が異なる。
03552        atnjは正常が複数あるので異常時がNULL、atはエラーが複数あるので正常時がNULL
03553 */
03554     #ifndef XBEE_WIFI
03555         byte address[] =    {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
03556         byte ret;
03557         ret = xbee_rat( address, in);
03558     #else // XBEE_WIFI
03559         byte ret;
03560         ret = xbee_rat( ADR_DEST, in);
03561     #endif
03562     
03563     #ifdef LCD_H
03564         if( ret == 0xFF ) xbee_log( 4, "ERR:tx_rx at xbee_at" , ret );
03565         xbee_log( 1, "done:xbee_at" , 1 );
03566     #endif
03567     return( ret );
03568 }
03569 
03570 byte xbee_uart(const byte *address, const char *in){
03571 /*
03572     入力:byte *address = 宛先(子機)アドレス 
03573        char *in = 送信するテキスト文字。最大文字数はAPI_TXSIZE-1
03574     出力:戻り値 = 送信パケット番号PACKET_ID。0x00は失敗。
03575 */
03576     byte ret=0;
03577 
03578     xbee_address( address );                        // 宛先のアドレスを設定
03579     if( xbee_putstr( in ) > 0 ) ret = PACKET_ID;
03580     #ifdef LCD_H
03581         xbee_log( 1, "done:xbee_uart" , 1 );
03582     #endif
03583     return( ret );
03584 }
03585 
03586 byte xbee_bytes(const byte *address, const byte *in, byte len){
03587 /*
03588     入力:byte *address = 宛先(子機)アドレス 
03589        byte *in = 送信するバイナリ情報。最大文字数はAPI_TXSIZE-1
03590        byte len = バイト数
03591     出力:戻り値 = 送信パケット番号PACKET_ID。0x00は失敗。
03592 */
03593     byte ret=0;
03594 
03595     #ifdef LCD_H
03596         xbee_log( 1, "started:xbee_bytes" , 1 );
03597     #endif
03598     xbee_address( address );                            // 宛先のアドレスを設定
03599     if(len > API_TXSIZE-18 ){
03600         #ifdef LCD_H
03601             xbee_log( 3, "CAUTION:xbee_bytes length" , len );
03602         #endif
03603         len = API_TXSIZE-18;
03604     }
03605     if( xbee_at_tx( "TX", in , len) > 0 ) ret = PACKET_ID;
03606     #ifdef LCD_H
03607         xbee_log( 1, "done:xbee_bytes" , 1 );
03608     #endif
03609     return( ret );
03610 }
03611 
03612 byte xbee_atvr( void ){
03613 /*
03614     XBeeのデバイスタイプを取得するコマンド
03615     出力:戻り値= define値 ZB_TYPE_COORD、ZB_TYPE_ROUTER、ZB_TYPE_ENDDEV、0xFF=エラー
03616 */
03617     #ifndef XBEE_WIFI
03618         byte data[API_SIZE];
03619         byte ret=0xFF;
03620 
03621         if( xbee_tx_rx( "ATVR", data ,0 ) > 0){
03622             DEVICE_TYPE = data[8];
03623             if( DEVICE_TYPE != ZB_TYPE_COORD &&
03624                 DEVICE_TYPE != ZB_TYPE_ROUTER &&
03625                 DEVICE_TYPE != ZB_TYPE_ENDDEV) ret = 0xFF;
03626             else ret = DEVICE_TYPE;
03627         }
03628         #ifdef LCD_H
03629             xbee_log( 1, "done:xbee_atvr" , ret );
03630         #endif
03631         return( ret );
03632     #else
03633         return( DEVICE_TYPE );
03634     #endif
03635 }
03636 
03637 byte xbee_atcb( byte cb ){
03638 /*
03639     XBeeのコミッション制御
03640     入力:コミッションボタンの押下数(1:ジョイン開始、2:ジョイン許可、4:初期化)
03641     出力:戻り値= 0xFF 異常終了、 0x00 指示成功
03642 */
03643     #ifndef XBEE_WIFI
03644         byte data[API_SIZE];
03645         byte ret = 0xFF;
03646 
03647         data[0] = cb;
03648         if( cb == 1 || cb == 2 ){
03649             if( xbee_tx_rx( "ATCB", data ,1 ) > 0) ret = 0x00;
03650         }else if( cb == 4){
03651             if( xbee_tx_rx( "ATCB", data ,1 ) > 0){
03652                 if( DEVICE_TYPE == ZB_TYPE_COORD ){
03653                     wait_millisec(1000);
03654                     sci_clear();
03655                     wait_millisec(5000);
03656                     xbee_at_rx( data );
03657                     if( data[3] == MODE_MODM && data[4] == MODM_STARTED ){
03658                         ret = 0x00;
03659                     }
03660                 }else ret = 0x00;
03661             }
03662         }
03663         #ifdef LCD_H
03664             xbee_log( 1, "done:xbee_atcb" , ret );
03665         #endif
03666         return( ret );
03667     #else
03668         return( 0xFF );
03669     #endif
03670 }
03671 
03672 byte xbee_atai(void){
03673 /*
03674     XBeeモジュールの状態を確認するコマンド AT Association Indication
03675     出力:
03676         0x00 - Successfully formed or joined a network. (Coordinators form a network, routers
03677                 and end devices join a network.)
03678                 ※Routerに対して実行すると01が返ってくる場合があるが仕様書には記載なし。
03679         0x21 - Scan found no PANs
03680         0x22 - Scan found no valid PANs based on current SC and ID settings
03681         0x23 - Valid Coordinator or Routers found, but they are not allowing joining (NJ expired)
03682         0x24 - No joinable beacons were found
03683         0x25 - Unexpected state, node should not be attempting to join at this time
03684         0x27 - Node Joining attempt failed (typically due to incompatible security settings)
03685         0x2A - Coordinator Start attempt failed‘
03686         0x2B - Checking for an existing coordinator
03687         0x2C - Attempt to leave the network failed
03688         0xAB - Attempted to join a device that did not respond.
03689         0xAC - Secure join error - network security key received unsecured
03690         0xAD - Secure join error - network security key not received
03691         0xAF - Secure join error - joining device does not have the right preconfigured link key
03692         0xFF - Scanning for a ZigBee network (routers and end devices)
03693     
03694 注意:本コマンドは応答待ちを行うので干渉によるパケット損失があります。
03695    本コマンドをXBeeに送ると、XBeeからの応答用キャッシュがクリアされる場合があります。
03696    例えば、xbee_forceなどの応答を後から得るコマンドを実行後に本コマンドを実行すると
03697    xbee_rx_callで応答が受け取れなくなる場合があります。
03698    このような場合、xbee_ataiを実行してからxbee_forceを実行するような手順にしてください。
03699 */
03700     byte data[API_SIZE];
03701     byte ret=0xFF;
03702 
03703     #ifdef LCD_H
03704         xbee_log( 1, "started:xbee_atai" , 0x00 );
03705     #endif
03706     if( xbee_tx_rx( "ATAI", data ,0 ) > 0 ){
03707     //  wait_millisec(100);
03708         #ifndef XBEE_WIFI
03709             if( data[7] == 0x00 ) ret = data[8];
03710         #else
03711             if( data[17] == 0x00 ) ret = data[18];
03712         #endif
03713     }
03714     #ifdef LCD_H
03715         xbee_log( 1, "done:xbee_atai" , ret );
03716     #endif
03717     return( ret );
03718 }
03719 
03720 unsigned short xbee_atop(byte *pan_id){
03721 /*
03722     PAN Idを求めるコマンド(書き込めないD
03723     出力:byte pan_id[8] PAN_ID 64bit (8bytes)
03724        unsigned short 戻り値 = PAN_ID 16bit
03725 注意:本コマンドは応答待ちを行うので干渉によるパケット損失があります。
03726 */
03727     #ifndef XBEE_WIFI
03728         byte data[API_SIZE];
03729         byte i;
03730         unsigned short pan_id_s=0xFFFF;
03731 
03732         for( i=0 ; i<8 ; i++ ) pan_id[i] = 0x00;
03733         #ifdef LCD_H
03734             xbee_log( 1, "started:xbee_atop" , 0x00 );
03735         #endif
03736         if( xbee_tx_rx( "ATOP", data ,0 ) > 0 ){
03737             wait_millisec(100);
03738             if( data[7] == 0x00 ){
03739                 for( i=0 ; i<8 ; i++ ) pan_id[i] = data[8+i];
03740             }
03741             xbee_tx_rx( "ATOI", data ,0 );
03742             if( data[7] == 0x00 ){
03743                 pan_id_s = (unsigned short)data[8] * 16 + (unsigned short)data[9];
03744             }
03745         //  wait_millisec(100);
03746         }
03747         #ifdef LCD_H
03748             xbee_log( 1, "done:xbee_atop" , 0x00 );
03749         #endif
03750         return( pan_id_s );
03751     #else
03752         return( 0x00 );
03753     #endif
03754 }
03755 
03756 byte xbee_atee_on(const char *key ){
03757 /*
03758     暗号化通信の設定(コーディネータ、ルータ共用)
03759     入力:const char *key セキュリティ共通キー16文字まで
03760     出力:byte 戻り値 = 0xFF失敗 0x00書き込み 0x01何もせず(設定されていた)
03761 */
03762     #ifndef XBEE_WIFI
03763         byte i;
03764         byte ret = 0xFF;
03765         byte data[API_SIZE];
03766         
03767         /* 現在のモードを確認(あとでATWRする。フラッシュ書き換え回数低減のため) */
03768     //  xbee_tx_rx( "ATVR", data ,0 );
03769     //  vr = data[8];           // xbee VRを取得
03770         if( xbee_tx_rx( "ATEE", data ,0 ) > 0 ){
03771             if( data[8] == 0x00 ){  // ATEEの応答が00の時
03772                 data[0] = 0x01;                 // ATEE = 0x01に設定
03773                 if( xbee_tx_rx( "ATEE", data ,1 ) > 0 ){
03774                     if( DEVICE_TYPE == ZB_TYPE_COORD ){
03775                         wait_millisec(1000);
03776                         sci_clear();
03777                         wait_millisec(5000);
03778                         xbee_at_rx( data );
03779                         if( data[3] == MODE_MODM && data[4] == MODM_STARTED ){
03780                             data[0] = 0x00;     // ATNK = 0x00 random network key
03781                             ret = xbee_tx_rx( "ATNK", data ,1 );
03782                         }
03783                     }else ret = 0x01;
03784                     /* KY 設定 */
03785                     for(i=0;i<16;i++){
03786                         if( key[i] == '\0' ) break;
03787                         data[i] = (byte)key[i];
03788                     } // ここで使ったiはキーの文字数として使用する
03789                     if( i == 0 ){
03790                         #ifdef LCD_H
03791                             xbee_log( 3, "CAUTION:ATKY=" , 0 );
03792                         #endif
03793                         data[0] = 0x00;
03794                         i = 1;
03795                     }
03796                     if( xbee_tx_rx( "ATKY", data ,i ) > 0 ){
03797                         if( xbee_tx_rx( "ATWR", data ,0 ) > 0 ){
03798                             if( ret != 0xFF ) ret = 0x00;
03799                         }
03800                     }
03801                 }
03802             }else ret = 0x01;
03803         }
03804         #ifdef LCD_H
03805             xbee_log( 1, "done:xbee_atee_on" , ret );
03806         #endif
03807         return(ret);
03808     #else
03809         return( 0x00 );
03810     #endif
03811 }
03812 
03813 byte xbee_atee_off( void ){
03814 /*
03815     暗号化通信のオフ(コーディネータ、ルータ共用)
03816     出力:byte 戻り値 = 0xFF失敗 0x00書き込み 0x01何もせず(設定されていた)
03817 */
03818     #ifndef XBEE_WIFI
03819         byte data[API_SIZE];
03820         byte ret = 0xFF;
03821 
03822         if( xbee_tx_rx( "ATEE", data ,0 ) > 0 ){
03823             if( data[8] == 0x01 ){  // ATEEの応答が01(enable)の時
03824                 data[0] = 0x00;                 // ATEE = 0x00に設定
03825                 if( xbee_tx_rx( "ATEE", data ,1 ) > 0 ){
03826                     if( DEVICE_TYPE == ZB_TYPE_COORD ){ // ZigBeeコーディネータの場合は再起動がある
03827                         wait_millisec(1000);
03828                         sci_clear();
03829                         wait_millisec(5000);
03830                         xbee_at_rx( data );
03831                         if( data[3] == MODE_MODM && data[4] == MODM_STARTED ){
03832                             data[0] = 0x00;     // ATNK = 0x00 random network key
03833                             ret = xbee_tx_rx( "ATNK", data ,1 );
03834                         }
03835                     }else ret = 0x01;               
03836                     if( xbee_tx_rx( "ATWR", data ,0 ) > 0 ){
03837                         if( ret != 0xFF ) ret = 0x00;
03838                     }
03839                 }
03840             }else ret= 0x01;
03841         }
03842         #ifdef LCD_H
03843             xbee_log( 1, "done:xbee_atee_off" , ret );
03844         #endif
03845         return(ret);
03846     #else
03847         return( 0x00 );
03848     #endif
03849 }
03850 
03851 byte xbee_atnc(void){
03852 /*
03853     XBeeモジュールのEnd Device子機のジョイン可能な台数を取得するコマンドです。
03854     出力:ジョイン可能数(0~)、0xFFで取得エラー
03855     
03856 注意:本コマンドは応答待ちを行うので干渉によるパケット損失があります。
03857 */
03858     #ifndef XBEE_WIFI
03859         byte data[API_SIZE];
03860         byte ret=0xFF;
03861         if( xbee_tx_rx( "ATNC", data ,0 ) > 0 ){
03862             if( data[7] == 0x00 ) ret = data[8];
03863         }
03864         #ifdef LCD_H
03865             if(ret<3) xbee_log( 3, "CAUTION:Many Children" , ret );
03866             if(ret==0) xbee_log( 3, "CAUTION:Cannot Join More" , ret );
03867             xbee_log( 1, "done:xbee_atnc" , ret );
03868         #endif
03869         return( ret );
03870     #else
03871         return( 0 );
03872     #endif
03873 }
03874 
03875 byte xbee_ratnc( const byte *address ){
03876 /*
03877     XBeeモジュールのEnd Device子機のジョイン可能な台数を取得するコマンドです。
03878     出力:ジョイン可能数(0~)、0xFFで取得エラー
03879     
03880 注意:本コマンドは応答待ちを行うので干渉によるパケット損失があります。
03881    本コマンドをXBeeに送ると、XBeeからの応答用キャッシュがクリアされる場合があります。
03882 */
03883     #ifndef XBEE_WIFI
03884         byte data[API_SIZE];
03885         byte ret=0xFF;
03886         
03887         xbee_address(address);                          // 宛先のアドレスを設定
03888         if( xbee_tx_rx( "RATNC", data ,0 ) > 0 ){
03889             if( data[17] == 0x00 ) ret = data[18];
03890         }
03891         #ifdef LCD_H
03892             if(ret<3) xbee_log( 3, "CAUTION:Many Children" , ret );
03893             xbee_log( 1, "done:xbee_ratnc" , ret );
03894         #endif
03895         return( ret );
03896     #else
03897         return( 0 );
03898     #endif
03899 }
03900 
03901 byte xbee_atnj(const byte timeout){
03902 /*
03903     制限時間timeoutで設定した間にネットワークに参加したデバイスを通信相手に設定する関数 
03904     AT Node Join Time
03905     入力:timeout = 時間(6~254秒)、0x00で参加拒否、0xFFの場合は常に参加許可
03906     出力:byte 戻り値 = 0x00失敗、成功時はMODE_IDNT(0x95)が代入される 
03907        xbee_atとエラー時の戻り値が異なる。
03908        atnjは正常が複数あるので異常時がNULL
03909        また、atnjはfopenと似た記述になるので、特殊な応答でもない(と思う)
03910     
03911 注意:本コマンドは応答待ちを行うので干渉によるパケット損失があります。
03912 */
03913     #ifndef XBEE_WIFI
03914         byte data[API_SIZE];
03915         byte i=0, ret, timer;
03916 
03917         #ifdef LCD_H
03918             xbee_log( 1, "started:xbee_atnj" , timeout );
03919         #endif
03920         data[0]=timeout;
03921         ret = xbee_tx_rx( "ATNJ", data ,1 );
03922         if( ret > 0 ){
03923             wait_millisec(100);
03924             if( timeout == 0xFF ){
03925                 /*常に参加待ち受けするテスト専用(非実用)*/
03926                 ret=0xFF;
03927                 #ifdef LCD_H
03928                     xbee_log( 3, "CAUTION:ATNJ=" , timeout );
03929                 #endif
03930                 wait_millisec(1000);            // NJ値の書込み時間待ち
03931             }else{
03932                 if( timeout > 0x09 ){
03933                     /*参加待ち受けの開始*/
03934                     timer = TIMER_SEC + timeout + 0x01 ;
03935                     ret = 0x00;
03936                     while( timer != TIMER_SEC && ret != MODE_IDNT){ // MODE_IDNT(0x95)はネットワーク参加
03937                         #ifdef H3694
03938                             if( (timera()>>6)&0x01 ){
03939                                 led_green( 0 ); // LEDのトグル1秒に4回
03940                             } else {
03941                                 led_green( 1 );
03942                             }                       
03943                         #endif
03944                         if( xbee_at_rx( data ) > 0x00 ){    // データの受信(戻り値は受信種別mode値)
03945                             ret = xbee_from_acum(data);
03946                             if( ret == MODE_IDNT ){     // 受信モードがMODE_IDNT(0x95) Node Identifyの場合
03947                                 #ifdef LCD_H
03948                                     xbee_log( 1, "Found device " , ret );
03949                                 #endif
03950                                 for(i=0;i<8;i++) ADR_DEST[i]=ADR_FROM[i];           // 宛先を発見デバイスに設定
03951                                 #ifndef LITE    // BeeBee Lite by 蘭
03952                                     sci_write_check();
03953                                 #endif
03954                                 sci_clear();
03955                                 }else ret=0x00;
03956                         }
03957                     }
03958                     #ifdef LCD_H
03959                         if( ret == 0x00 ) xbee_log( 1, "no new device" , ret );
03960                     #endif
03961                 }
03962                 /*ジョイン拒否設定*/
03963                 data[0]=0x00;
03964                 xbee_tx_rx( "ATNJ", data ,1 );
03965                 #ifdef LCD_H
03966                     xbee_log( 1, "done:atnj=0x00" , 0x00 );
03967                 #endif
03968             }
03969         }else{
03970             #ifdef LCD_H
03971                 xbee_log( 5, "ERROR:xbee_atnj" , ret );
03972             #endif
03973         }
03974         #ifdef LCD_H
03975             xbee_log( 1, "done:xbee_atnj" , ret );
03976         #endif
03977         return( ret );
03978     #else
03979         return( 0x95 );
03980     #endif
03981 }
03982 
03983 byte xbee_ratnj(const byte *address, const byte timeout){
03984 /*
03985     前記xbee_atnjをリモート先(子機)に対して設定する関数 
03986     入力:byte *address = 宛先(子機)アドレス 
03987     入力:timeout = 0でジョイン拒否、1~254で待ち秒数、255で常時ジョイン許可 
03988     出力:byte 戻り値 = 0x00失敗、0xFF成功 
03989     
03990 注意:本コマンドは応答待ちを行うので干渉によるパケット損失があります。
03991 */
03992     #ifndef XBEE_WIFI
03993         byte data[API_SIZE];
03994         byte ret=0x00;
03995 
03996         xbee_address(address);                          // 宛先のアドレスを設定
03997         data[0]=timeout;
03998         if( xbee_tx_rx( "RATNJ", data ,1 ) > 0 ){
03999             #ifdef LCD_H
04000                 xbee_log( 1, "done:ratnj" , xbee_tx_rx( "ATAC", data ,0 ) );
04001             #endif
04002             ret=0xFF;
04003         }
04004         #ifdef LCD_H
04005             xbee_log( 1, "done:xbee_ratnj" , ret );
04006         #endif
04007         return( ret );
04008     #else
04009         return( 0x95 );
04010     #endif
04011 }
04012 
04013 byte xbee_ping(const byte *address ){
04014 /*
04015 入力:IEEEアドレスaddress
04016 出力:                  0xFF        エラー
04017         DEV_TYPE_XBEE   0x00        // XBeeモジュール
04018         DEV_TYPE_RS232  0x05        // RS-232Cアダプタ
04019         DEV_TYPE_SENS   0x07        // Sensor (1wire専用)
04020         DEV_TYPE_PLUG   0x0F        // SmartPlug
04021     
04022     byte 戻り値 = 0xFF失敗、成功時は0x00などのデバイス名(ATDD)の下2桁 
04023     
04024 注意:本コマンドは応答待ちを行うので干渉によるパケット損失があります。
04025 */
04026     byte i;
04027     byte ret=0xFF;      // デバイス名
04028     byte data[API_SIZE];
04029 
04030     xbee_address(address);                          // 宛先のアドレスを設定
04031     if( xbee_tx_rx( "RATDD", data ,0 ) > 0 ){       // デバイス名を取得
04032         #ifdef XBEE_WIFI            // Device Type Identifier. Stores a device type value
04033                                     // 20 00 20 24 ← 電源投入した後は、こんな応答がある。モジュールによらず。
04034                                     // 00 90 00 00      仕様書に書かれていないと思う
04035         if( (data[18]==0x00 && data[19]==0x09 && data[20]==0x00 && data[21]==0x00) ||
04036             (data[18]==0x20 && data[19]==0x00 && data[20]==0x20 && data[21]==0x24) ){   // XBee WiFiデバイス
04037             data[21]=0x00;
04038         #else
04039         if( data[18]==0x00 && data[19]==0x03 && data[20]==0x00 ){   // XBeeデバイス
04040         #endif
04041             for(i=0;i<8;i++) ADR_FROM[i]=data[5+i]; // 2013.9.15 追加
04042             ret=data[21];                           // デバイス名をddに代入
04043         }
04044         #ifdef DEBUG
04045             #ifdef ARM_MBED
04046                 for(i=18;i<=21;i++) _xbee_debug.printf("%2X ",data[i]);
04047                 _xbee_debug.printf("\n");
04048             #else //PC
04049                 for(i=18;i<=21;i++) printf("%2X ",data[i]);
04050                 printf("\n");
04051             #endif
04052         #endif
04053     }
04054     #ifdef LCD_H
04055         xbee_log( 1, "done:xbee_ping" , ret );
04056     #endif
04057     #ifdef XBEE_WIFI_DEBUG
04058         Serial.print("DD=");
04059         for(i=18;i<=21;i++){
04060             Serial.print(data[i],HEX);
04061             Serial.print(" ");
04062         }
04063         Serial.println("");
04064     #endif
04065     return( ret );
04066 }
04067 
04068 int xbee_batt(const byte *address ){
04069 /*
04070 電池電圧の確認
04071 入力:IEEEアドレスaddress
04072 出力:約2100~3600[mV]、-1=エラー 
04073 注意:本コマンドは応答待ちを行うので干渉によるパケット損失があります。
04074 */
04075     int ret=-1;
04076     byte data[API_SIZE];
04077 
04078     xbee_address(address);                          // 宛先のアドレスを設定
04079     if( xbee_tx_rx( "RAT%V", data ,0 ) > 0 ){       // 電池電圧を取得
04080         ret = (int)(((float)data[18] * 256.0f + (float)data[19] ) * 1.17f);
04081     }
04082     #ifdef LCD_H
04083         xbee_log( 1, "done:xbee_batt" , (byte)(ret/100) );
04084     #endif
04085     return( ret );
04086 }
04087 
04088 byte xbee_batt_force(const byte *address ){
04089 /*
04090 電池電圧の確認
04091 入力:IEEEアドレスaddress
04092 xbee_batt_forceで測定指示を出して、xbee_rx_callで受け取ります。
04093 XBEE_RESULT.MODEに「MODE_BATT(0xE1)」が設定されるので他のリモートATレスポンスと区別することが出来ます。
04094 電圧値はXBEE_RESULT.ADC[0]に約2100~3600[mV]の範囲で応答します。
04095 */
04096     byte data[XB_AT_SIZE];
04097     byte ret = 0x00;
04098     
04099     xbee_address( address );                            // 送信先を指定
04100     ret = xbee_at_tx("RAT%V", data , 0);                // ATISを送信
04101     if( ret > 0 ) ret = PACKET_ID;
04102     #ifdef LCD_H
04103         xbee_log( 1, "done:xbee_batt_force" , ret );
04104     #endif
04105     return ( ret );
04106 }
04107 
04108 #ifdef ARDUINO
04109 byte xbee_gpio_config(const byte *address, const byte port, byte type ){
04110 #else
04111 #ifdef ARM_MBED
04112 byte xbee_gpio_config(const byte *address, const byte port, byte type ){
04113 #else
04114 byte xbee_gpio_config(const byte *address, const byte port, const enum xbee_port_type type ){
04115 #endif
04116 #endif
04117 /*
04118 入力:IEEEアドレスaddress、GPIOポート番号port、設定値type
04119         enum xbee_port_type{ DISABLE=0, VENDER=1, AIN=2, DIN=3, DOUT_L=4, DOUT_H=5 };
04120 
04121     port:   port指定  IO名 ピン番号    共用     USB評価ボード(XBIB-U-Dev)
04122             port= 0     DIO0    XBee_pin 20 (Cms)       SW Commision コミッションボタン
04123             port= 1     DIO1    XBee_pin 19 (AD1)       SW2 汎用入力用(DIN or AIN)
04124             port= 2     DIO2    XBee_pin 18 (AD2)       SW3 汎用入力用(DIN or AIN)
04125             port= 3     DIO3    XBee_pin 17 (AD3)       SW4 汎用入力用(DIN or AIN)
04126             port= 4     DIO4    XBee_pin 16 (RTS)       LED3 汎用出力用
04127             port= 5     DIO5    XBee_pin 15 (Ass)       ASSOSIATE indication
04128             port=10     DIO10   XBee_pin  6 (RSSI)      RSSI indication (PWM)
04129             port=11     DIO11   XBee_pin  7             LED2 汎用出力用
04130             port=12     DIO12   XBee_pin  4             LED1 汎用出力用
04131 
04132 注意:本コマンドは応答待ちを行うので干渉によるパケット損失があります。
04133 */
04134     byte ret=0xFF;
04135     byte data[API_SIZE];
04136     char at[] = "RATD0" ;   // ATコマンド
04137     byte dd=0xFF;           // デバイス名
04138 
04139     switch( type ){
04140         case DISABLE:
04141             if( (port >= 1 && port <= 5) || (port >= 10 && port <= 12) ) {
04142                 at[4] = '0' + port;
04143                 ret=0;
04144             }
04145             break;
04146         case VENDER:
04147             if( port == 0 || port == 5 || port == 10) ret=0;
04148             break;
04149         case AIN:
04150             if( port >= 1 && port <= 4 ){
04151                 at[4] = '0' + port;
04152                 ret=0;
04153             }else if( port == 0xFF ){
04154                 ret=0;
04155             }
04156             break;
04157         case DIN:
04158         case DOUT_L:
04159         case DOUT_H:
04160             if( port >= 1 && port <= 5 ){
04161                 at[4] = '0' + port;
04162                 ret=0;
04163             }else if( port >= 10 && port <= 12 ){
04164                 at[3] = 'P';
04165                 at[4] = '0' + (port - 10);
04166                 ret=0;
04167             }else if( port == 0xFF ){
04168                 ret=0;
04169             }
04170             break;
04171         default:
04172             break;
04173     }
04174     if( ret==0 ){
04175         dd = xbee_ratd_myaddress(address);
04176         if( dd != 0xFF ){                   // アドレス設定が正常に実施された時
04177             /*
04178             入力されたtypeがDINの時にRATICを変更する処理に対応予定(将来)
04179             RATICで状態を取得して状態or設定を追加(ポート1~5と10~12)
04180             */
04181             data[0]=(byte)type;
04182             xbee_tx_rx( at , data ,1 );
04183         }
04184     }
04185     #ifdef LCD_H
04186         xbee_log( 1, "done:xbee_gpio_config" , dd );
04187     #endif
04188     return( dd );
04189 }
04190 
04191 byte xbee_gpio_init(const byte *address){
04192 /*
04193 子機XBeeデバイス(リモート先)のGPIOを入力に設定する関数
04194 リモート端末の宛先を本機アドレスに設定(リモート側のボタンで親機に送信するために)
04195 入力:なし
04196 出力:デバイス名(ATDDの下2桁)、FFでエラー
04197 注意:本コマンドは応答待ちを行うので干渉によるパケット損失があります。
04198 */
04199     byte data[API_SIZE];
04200     byte dd;                // デバイス名
04201 
04202     dd = xbee_ratd_myaddress(address);
04203     if( dd != 0xFF){
04204         data[0]=0x01;       xbee_tx_rx( "RATD0", data ,1 ); // ポート0をコミッションボタンに設定
04205         switch(dd){
04206             case DEV_TYPE_XBEE:
04207                 data[0]=0x03;   xbee_tx_rx( "RATD1", data ,1 ); // ポート1をデジタル入力に設定
04208                 data[0]=0x03;   xbee_tx_rx( "RATD2", data ,1 ); // ポート2をデジタル入力に設定
04209                 data[0]=0x03;   xbee_tx_rx( "RATD3", data ,1 ); // ポート3をデジタル入力に設定
04210                 data[0]=0x05;   xbee_tx_rx( "RATD4", data ,1 ); // ポート4をデジタル出力に設定
04211                 data[0]=0x05;   xbee_tx_rx( "RATP1", data ,1 ); // ポート11をデジタル出力に設定
04212                 data[0]=0x05;   xbee_tx_rx( "RATP2", data ,1 ); // ポート12をデジタル出力に設定
04213                 data[0]=0x00;
04214                 data[1]=0x0E;                   // ポート1~3の↓
04215                 xbee_tx_rx( "RATIC", data ,2 ); // 入力値が変化したら通知するIC設定
04216                 break;
04217             case DEV_TYPE_PLUG:
04218                 data[0]=0x02;   xbee_tx_rx( "RATD3", data ,1 ); // ポート3をアナログ入力に設定
04219                 data[0]=0x04;   xbee_tx_rx( "RATD4", data ,1 ); // ポート4をデジタル出力に設定
04220                 // breakしない
04221             case DEV_TYPE_WALL:
04222                 data[0]=0x02;   xbee_tx_rx( "RATD1", data ,1 ); // ポート1をアナログ入力に設定
04223                 data[0]=0x02;   xbee_tx_rx( "RATD2", data ,1 ); // ポート2をアナログ入力に設定
04224                 break;
04225             default:
04226                 #ifdef LCD_H
04227                     xbee_log( 4, "ERR:gpio_init DD" , dd );
04228                 #endif
04229                 break;
04230         }
04231     }
04232     #ifdef LCD_H
04233         xbee_log( 1, "done:gpio init" , dd );
04234     #endif
04235     return( dd );
04236 }
04237 
04238 byte xbee_gpo(const byte *address, const byte port,const byte out){
04239 /*
04240 子機XBeeデバイス(リモート先)のGPIOへ出力する関数
04241 portは1~4と11~12が指定できる→port0~7と10~12に拡大
04242 出力:byte 戻り値 = 送信パケット番号PACKET_ID。0x00は失敗。 
04243     port:   port指定  IO名 ピン番号         USB評価ボード(XBIB-U-Dev)
04244             port= 0     DIO0    XBee_pin 20 (Cms)       SW1 Commision
04245             port= 1     DIO1    XBee_pin 19 (AD1)       SW2
04246             port= 2     DIO2    XBee_pin 18 (AD2)       SW3
04247             port= 3     DIO3    XBee_pin 17 (AD3)       SW4
04248             port= 4     DIO4    XBee_pin 11             LED3    ※port4 がLED3
04249             port=10     DIO10   XBee_pin  6             RSSI
04250             port=11     DIO11   XBee_pin  7             LED2    ※port11がLED2
04251             port=12     DIO12   XBee_pin  4             LED1    ※port12がLED1
04252 */
04253     char at[6];
04254     byte data[API_SIZE];
04255 //  byte i=0;
04256     byte ret=0;
04257     
04258     xbee_address(address);                                  // 宛先のアドレスを設定
04259     at[0]='S'; at[1]='A'; at[2]='T'; at[3]=0; at[5]='\0'; 
04260     // at[0]='R';   // RAT(応答待ち)の場合は本行のコメントを外してRATに変更する(かなり遅くなる)
04261     if( port <= 7 ){    // port >= 0 &&
04262         at[3] = 'D';
04263         at[4] = '0' + port;
04264     }else if( port >= 10 && port <= 12 ){
04265         at[3] = 'P';
04266         at[4] = '0' + (port - 10);
04267     }
04268     if( at[3] ){
04269         data[0]=0x05;                   // output = H
04270         if( out == 0 ) data[0]=0x04;    // output = L
04271         data[1]=0x00;
04272         ret = xbee_at_tx( at, data ,1 );
04273         if( ret > 0 ) ret = PACKET_ID;
04274         // ret = xbee_tx_rx( at, data ,1 ); // RAT(応答待ち)の場合にコメントを外す
04275         #ifdef XBEE_WIFI
04276             if( DEVICE_TYPE == XB_TYPE_WIFI20) delay(10);
04277                     // S6Bで安定動作させるために必要(理由は不明)
04278             /*
04279             XBee Wi-Fiの場合はPACKET IDを0にしても応答がある。
04280             したがってSATでは応答なしATコマンドを明示して送信している。
04281             ところが、その場合ACを受信するまでコマンドが確定しない。
04282             その対策としてATACを追加で送信する。
04283             XBee ZBでもATACで応答遅延が無くなる利点があるが、パケット増加で
04284             かえって高速動作が出来なくなるので、Wi-Fiのみの対応とする。
04285             */
04286             if(ret){    // 送信データを即確定する
04287                 at[0]='S'; at[1]='A'; at[2]='T';
04288                 at[3]='A'; at[4]='C';
04289                 xbee_at_tx( at, data ,0 );
04290             }
04291         #endif
04292     }
04293     #ifdef DEBUG
04294         lcd_goto(LCD_ROW_3);
04295         if( ret==0 ){
04296             lcd_putstr("GPO ERR:");
04297         }else{
04298             lcd_putstr("GPO OK:");
04299         }
04300         lcd_disp_hex( data[17] );
04301     #endif
04302     #ifdef LCD_H
04303         xbee_log( 1, "done:xbee_gpo" , ret );
04304     #endif
04305     return(ret);
04306 }
04307 
04308 #ifdef EASY_GPI
04309 byte xbee_gpi(const byte *address, const byte port){
04310 /*  リモート先(ADR_FROMに入力)のGPIOの入力値を応答するAPI
04311 
04312 ★注意:本コマンドは応答待ちを行うので干渉によるパケット損失があります。
04313 本コマンドでは無くxbee_forceとxbee_rx_callの組み合わせでの利用を推奨します。
04314 
04315 portは1~4と11~12と0xFFが指定できる。
04316 port=0xFFでポート0~7をHEXで応答する。
04317 AINはxbee_adcを使用する。
04318     port:   port指定  IO名 ピン番号         USB評価ボード(XBIB-U-Dev)
04319             port= 1     DIO1    XBee_pin 19 (AD1)        SW2
04320             port= 2     DIO2    XBee_pin 18 (AD2)        SW3
04321             port= 3     DIO3    XBee_pin 17 (AD3)        SW4
04322     out: 指定ポートの状態 0または1、エラー時は0xFF
04323 
04324 設計情報
04325     リターン信号例
04326     00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
04327     7E 00 15 97 01 00 13 A2 00 -- -- -- -- -- -- 49 53 00 01 18 1E 00 00 0E 8A
04328       | len |mo|FI|送信元IEEEアドレス      |Short|AT(IS)  |01|MASK |AD|DATA |CS|
04329       |     |de|
04330       |     |__|__________________ MODE_RESP(0x97)= ATIS応答
04331       |_____|_____________________ Data Length
04332 */
04333     byte data[API_SIZE];
04334     byte ret=0xFF;
04335 
04336     xbee_address(address);                              // 宛先のアドレスを設定
04337     if( xbee_tx_rx("RATIS", data , 0) > 0 ){
04338     //  if( data[3]==MODE_RESP ){                       // d[3] flame ID = 97(RAT応答)
04339                                                         // tx_rxで data[3]はチェック済み
04340             if( port == 0xFF) ret = (data[23] & data[20]);
04341             else{
04342                 if( (port >= 1) && (port <= 4) ){
04343                     if( ((data[20]>>port)&0x01) == 0x00 ){  // MASK_L(20)の該当ビットが否の時
04344                         data[0]=0x03; // リモート端末のポート1~3をデジタル入力(0x03)に設定
04345                         if( port ==1 ) xbee_tx_rx( "RATD1", data ,1 );
04346                         if( port ==2 ) xbee_tx_rx( "RATD2", data ,1 );
04347                         if( port ==3 ) xbee_tx_rx( "RATD3", data ,1 );
04348                         if( port ==4 ) xbee_tx_rx( "RATD4", data ,1 );
04349                         wait_millisec(200);
04350                         xbee_tx_rx("RATIS", data , 0);  // 再度ISを実行
04351                     }
04352                     if( data[3]==MODE_RESP ) ret= ((data[23] >> port ) & 0x01); // 取得データDATA_L(23)を戻り値に
04353                 } else if( (port >= 11) && (port <= 12) ){
04354                     if( ((data[19]>>(port-8))&0x01) == 0x00 ){  // MASK_H(19)の該当ビットが否の時
04355                         data[0]=0x03; // リモート端末のポート11~12をデジタル入力(0x03)に設定
04356                         if( port ==11 ) xbee_tx_rx( "RATP1", data ,1 );
04357                         if( port ==12 ) xbee_tx_rx( "RATP2", data ,1 );
04358                         wait_millisec(200);
04359                         xbee_tx_rx("RATIS", data , 0);  // 再度ISを実行
04360                     }
04361                     if( data[3]==MODE_RESP ) ret= ((data[22] >> (port-8))& 0x01);   // 取得データDATA_H(22)を戻り値に
04362                 }
04363             }
04364     //  }
04365     }
04366     #ifdef DEBUG
04367         lcd_goto(LCD_ROW_3);
04368         lcd_putstr("port"); lcd_disp_hex( port ); lcd_putstr("="); lcd_disp_hex( ret ); // 戻り値
04369         lcd_goto(LCD_ROW_4);
04370         lcd_putstr(" f:"); lcd_disp_hex( data[3]); 
04371         lcd_putstr(" M:"); lcd_disp_hex( data[19] ); lcd_disp_hex( data[20] );  // MASK表示
04372         lcd_putstr(" D:"); lcd_disp_hex( data[22] ); lcd_disp_hex( data[23] );  // デジタルサンプル値
04373     #endif
04374     #ifdef LCD_H
04375         xbee_log( 1, "done:xbee_gpi" , ret );
04376     #endif
04377     return( ret );
04378 }
04379 #endif // EASY_GPI
04380 
04381 #ifdef EASY_ADC
04382 unsigned int xbee_adc(const byte *address, const byte port){
04383 /*  リモート先(addressに入力)のADCの入力値を応答するAPI
04384 portは1~3が指定できる。指定したportがADC入力でない場合はADC入力に切り替える。
04385     port:   port指定  IO名 ピン番号         USB評価ボード(XBIB-U-Dev)
04386             port= 1     DIO1    XBee_pin 19 (AD1)       SW2
04387             port= 2     DIO2    XBee_pin 18 (AD2)       SW3
04388             port= 3     DIO3    XBee_pin 17 (AD3)       SW4
04389     out:    ADC値
04390     
04391 設計情報
04392     リターン信号例
04393     00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
04394     7E 00 17 97 01 00 13 A2 00 -- -- -- -- -- -- 49 53 00 01 18 16 08 18 06 00 00 7A
04395       | len |mo|FI|送信元IEEEアドレス      |Short|AT(IS)  |01|GPIO |AD|GPIO |ADC  |CS
04396       |     |de|  |                       |Adrss|        |01|MASK |MS|DATA |DATA |
04397       |     |  |  |                                               |  |
04398       |     |  |                          ADC MASK________________|__|
04399       |     |__|__________________ MODE_RESP(0x97)= ATIS応答
04400       |_____|_____________________ Data Length
04401 
04402 注意:本コマンドは応答待ちを行うので干渉によるパケット損失があります。
04403 */
04404     byte data[API_SIZE];
04405     byte ports=1;
04406     unsigned int ret=0xFFFF;
04407 
04408     xbee_address(address);                              // 宛先のアドレスを設定
04409     if( xbee_tx_rx("RATIS", data , 0) > 0 ){
04410         if( data[3]==MODE_RESP ){                       // d[3] flame ID = 97(MODE_RESP)
04411             if( (port >= 1) && (port <= 3) ){
04412                 if( ((data[21]>>port ) & 0x01) == 0x00 ){   // MASKの該当ビットが否の時
04413                     data[0]=0x02; // リモート端末のポート1~3をADC入力(0x02)に設定
04414                     if( port == 1 ) xbee_tx_rx( "RATD1", data ,1 );
04415                     if( port == 2 ) xbee_tx_rx( "RATD2", data ,1 );
04416                     if( port == 3 ) xbee_tx_rx( "RATD3", data ,1 );
04417                     wait_millisec(1000);
04418                     xbee_tx_rx("RATIS", data , 0);  // 再度ISを実行
04419                 }
04420                 if( (port == 2) && ((data[21]>>1)&0x01) ) ports =2;     // port2指定でport1がADCならデータは2個
04421                 else if ( port == 3 ){
04422                     if( (data[21]>>2)&(data[21]>>1)&0x01 ) ports =3; // port3指定でport1と2がADCならデータは3個
04423                     else if( ((data[21]>>2)|(data[21]>>1))&0x01 ) ports =2; // port3指定でport1か2の片方がADCならデータは2個
04424                 }
04425                 if( data[3]==MODE_RESP ) ret= (unsigned int)data[22+ports*2]*256 + (unsigned int)data[23+ports*2];
04426                                                                         // 取得データを戻り値に
04427             }
04428         }
04429     }
04430     #ifdef DEBUG
04431         lcd_goto(LCD_ROW_4); lcd_putstr("ADC "); lcd_disp_hex( port ); lcd_putstr("=");
04432         lcd_disp_hex( data[21] ); lcd_putstr(" "); lcd_disp_5( ret );
04433     #endif
04434     #ifdef LCD_H
04435         xbee_log( 1, "done:xbee_adc" , ret );
04436     #endif
04437     return( ret );
04438 }
04439 #endif // EASY_ADC
04440 
04441 byte xbee_force(const byte *address ){
04442 /*
04443     GPIOやXBee Sensor(XBee Sensor /L/T または /L/T/H) へ測定指示(ATIS)を送るコマンド
04444     本xbee_forceで測定指示を出して、xbee_rx_callで受け取ることを推奨します。
04445     XBee Sensor はxbee_sensor_resultでセンサー値を計算できます。
04446     入力:送信アドレス
04447     出力:送信結果(送信したAPIサービス長。送信しなかった場合は0)
04448 */
04449     byte ret = 0x00;
04450     byte null_data [] = { 0x00 };
04451     
04452     xbee_address( address );                            // 送信先を指定
04453     ret = xbee_at_tx("RATIS", null_data , 0);               // ATISを送信
04454     if( ret > 0 ) ret = PACKET_ID;
04455     #ifdef LCD_H
04456         xbee_log( 1, "done:xbee_force" , ret );
04457     #endif
04458     return ( ret );
04459 }
04460 
04461 #ifdef ARDUINO
04462 float xbee_sensor_result( XBEE_RESULT *xbee_result, const byte type){
04463 #else
04464 #ifdef ARM_MBED
04465 float xbee_sensor_result( XBEE_RESULT *xbee_result, const byte type){
04466 #else
04467 float xbee_sensor_result( XBEE_RESULT *xbee_result, const enum xbee_sensor_type type ){
04468 #endif
04469 #endif
04470 /*
04471 xbee_rx_callで取得したxbee_sensorデータを値に変換するAPI(非通信) 
04472 call_result情報から変換
04473 LIGHTはXBee Sensor用
04474 WATTはXBee Smart Plug用
04475 
04476     入力:enum xbee_sensor_type {LIGHT,TEMP,HUMIDITY,WATT};    // センサタイプの型
04477     出力:float センサ読み取り値
04478 
04479     XBee Sensor(XBee Sensor /L/T または /L/T/H) ※ 1-wire Sensor Adapterではない
04480 
04481     設計情報
04482         リターン信号例
04483         00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
04484         7E 00 1B 97 01 00 13 A2 00 -- -- -- -- -- -- 49 53 00 01 08 00 0E 08 00 03 E2 02 62 02 16 A1
04485           | len |mo|FI|送信元IEEEアドレス      |Short|AT(IS)  |01|GPIO |AD|GPIO |ADC1 |ADC2 |ADC3 |CS
04486           |     |de|  |                       |Adrss|        |01|MASK |MS|DATA |DATA |DATA |DATA |
04487           |     |  |  |                                               |  |     |Light|Temp |Humidity
04488           |     |  |                          ADC MASK________________|__|
04489           |     |__|__________________ MODE_RESP(0x97)= ATIS応答        [手間!]この先はMASKによって
04490           |_____|_____________________ Data Length                        データの無い部分は省略される
04491 */
04492 
04493     float ret = -1.0f;
04494     
04495     switch(type){
04496         case LIGHT:
04497             #ifndef XBEE_WIFI
04498                 ret = ((float)(xbee_result->ADCIN[1]))*1.173f;
04499                                                     // (ADC1) /1023.0) * 1200
04500             #else
04501                 ret = ((float)(xbee_result->ADCIN[1]))*2.444f;
04502                                                     // (ADC1) /1023.0) * 2500
04503             #endif
04504             break;
04505         case TEMP:
04506             #ifndef XBEE_WIFI
04507                 ret = ((float)(xbee_result->ADCIN[2]))*0.1173f-50.0f;
04508                                                     // (((ADC2/1023.0) * 1200) - 500.0)/ 10.0
04509             #else
04510                 ret = ((float)(xbee_result->ADCIN[2]))*0.2444f-50.0f;
04511             #endif
04512             /*
04513             XBee ルータの温度測定結果は内部温度による上昇分が加算されます。
04514             Digi社によると約4℃の上昇があるので4℃を減算して使用することを推奨している。
04515             本ライブラリでは減算していませんが、実際の温度差を測定したところ
04516             平均7.12℃の差がありました。(27.2℃~28.0℃の環境下での平均誤差)
04517             */
04518             break;
04519         case HUMIDITY:
04520             #ifndef XBEE_WIFI
04521                 ret = ((float)(xbee_result->ADCIN[3]))*1.173f;
04522                                                     // mVanalog = (ADC3/1023.0) * 1200
04523             #else
04524                 ret = ((float)(xbee_result->ADCIN[3]))*2.444f;
04525             #endif
04526             ret = ( ((ret * 108.2f / 33.2f) / 5000.0f - 0.16f) / 0.0062f );
04527                                                     // hum = (((mVanalog * 108.2 / 33.2) / 5000 - 0.16) / 0.0062)
04528             break;
04529         case WATT:
04530             #ifndef XBEE_WIFI
04531                 ret = ((float)(xbee_result->ADCIN[3]))*1.17302f;
04532             #else
04533                 ret = ((float)(xbee_result->ADCIN[3]))*2.44379f;
04534             #endif
04535             ret = (ret * 156.0f / 47.0f - 520.0f) / 180.0f * 70.71f ;
04536             if( ret < 0 ) ret = 0;
04537                                                     // current = (mV*(156.0/47.0) - 520.0) /180.0 * .7071
04538             /*  電圧を測定していないのでワットへの変換は100Vを乗算している。*/
04539             /*  XBee Smart Plugは誘導負荷が考慮されないので測定値は参考値にしかならない。
04540                 (モーターなどの力率の悪いものは測れない)
04541                 The XBee Smart Plug uses a hall-effect current sensor IC to detect RMS current draw
04542                 from the user controlled outlet. As there is no power factor correction for inductive loads,
04543                 sensor accuracy is only specified for resistive loads. Current measurements can still be
04544                 made on inductive loads that fall within the product load rating, but accuracy is not
04545                 guaranteed. */
04546             break;
04547         default:
04548             break;
04549     }
04550     #ifdef LCD_H
04551         xbee_log( 1, "done:xbee_sensor_result" , (byte)ret );
04552     #endif
04553     return( ret );
04554 }
04555 
04556 unsigned int xbee_batt_acum(byte a1, byte a2  ){
04557     return( (unsigned int)( ( (float)a1 * 256.0f + (float)a2 ) * 1.17f ) );
04558 }
04559 
04560 byte xbee_rx_call( XBEE_RESULT *xbee_result ){
04561 /*
04562     XBeeからの受信を行うための待ち受け関数
04563     Ver 1.70以降はモード指定での待ち受け機能を削除した。
04564     mode MODE_AUTO  0x00    // 自動選択(modeに選択後のモード名が入る)
04565     mode MODE_UART  0x90    // UART Receive
04566     mode MODE_UAR2  0x91    // UART AO=0
04567     mode MODE_GPIN  0x92    // GPI data
04568     mode MODE_SENS  0x94    // XB Sensor
04569     mode MODE_IDNT  0x95    // Node Identify
04570     mode MODE_RES   0x88    // ローカルATコマンドの結果を受信
04571     mode MODE_RESP  0x97    // リモートATコマンドの結果を受信
04572     mode MODE_MODM  0x8A    // Modem Statusを受信
04573     mode MODE_TXST  0x8B    // UART Transmit Status を受信
04574     mode MODE_BATT  0xE1    // (独自定義)バッテリステータス RAT%Vの応答時
04575     
04576     出力   :byte データ
04577     入力・出力:byte *mode モード値
04578     出力   :byte *xbee_result データの戻り値
04579           GPIデータ(無いGPIデータは0になるADCはFFFFになる)
04580              00 01 02 03 04 05 06 07 08 09 0A 0B 0C ....
04581             |GPI    |ADC0 |ADC1 |ADC2 |ADC3 |\0|\0|\0|....
04582           UARTデータは最後が\0で戻り値がlength
04583 */
04584     byte data[API_SIZE];
04585     byte ret=0;
04586     byte return_MODE = 0x00;
04587     byte cache_en = 0x00;
04588     byte i, j;
04589 
04590     // 各種APIによるエラー発生の解除処理
04591     #ifdef ERRLOG
04592         if( TIMER_ERR ){
04593             #ifdef LCD_H
04594                 xbee_log( 5, ERR_LOG , ERR_CODE );  // エラーログを出力
04595             #endif
04596             xbee_reset();                           // リセットに約3秒がかかる
04597             #ifdef LCD_H
04598                 xbee_log( 3, "XBee Restarted" , TIMER_ERR );
04599             #endif
04600             #ifdef H3694
04601                 led_red( 0 );
04602             #endif
04603             TIMER_ERR = 0;
04604         }
04605     #endif
04606     
04607     // 応答値の初期化
04608     xbee_result->MODE = 0x00;   // Ver 1.70から自動受信を廃止。そのための追加
04609     xbee_result->ID = 0x00;
04610     for( i=0 ; i<8 ; i++ ) xbee_result->FROM[i] = 0x00;
04611     #ifndef ARDUINO
04612     #ifndef ARM_MBED
04613         for( i=0 ; i<2 ; i++ ) xbee_result->SHORT[i] = 0x00;
04614     #endif
04615     #endif
04616     for( i=0 ; i<2 ; i++ ){
04617         xbee_result->AT[i] = 0xFF;
04618         xbee_result->GPI.BYTE[i] = 0xFF;
04619     }
04620     xbee_result->STATUS = 0xFF;
04621     for( i=1 ; i<4 ; i++ ) xbee_result->ADCIN[i] = (unsigned int)(0xFFFF);
04622     xbee_result->ADCIN[0] = 0;
04623     #ifndef ARDUINO
04624     #ifndef ARM_MBED
04625         for( i=0 ; i<6 ; i++ ) xbee_result->ZCL[i] = 0xFF;
04626     #endif
04627     #endif
04628     for( i=0 ; i<CALL_SIZE ; i++ ) xbee_result->DATA[i] = 0x00;
04629     
04630     j = 0;
04631     #ifdef CACHE_RES
04632     if( CACHE_COUNTER > 0 ){
04633         for( i=0 ; i < API_SIZE ; i++) data[i] = CACHE_MEM[0][i];
04634         /* FIFO 処理 面倒なのでメモリーをコピー */
04635         for( j=1 ; j < CACHE_COUNTER ; j++)
04636             for( i=0 ; i < API_SIZE ; i++) CACHE_MEM[j-1][i] = CACHE_MEM[j][i];
04637         CACHE_COUNTER--;
04638         return_MODE = 0xFF;
04639         cache_en = 0xFF;        // キャッシュ有効 フラグ
04640         #ifdef DEBUG
04641             lcd_putstr("### CACHE_OUT ### -> ");    // DEBUG
04642             lcd_disp_hex( CACHE_COUNTER );
04643             lcd_putch('\n');
04644         #endif
04645     }
04646     #endif
04647     if( cache_en == 0x00 ) return_MODE = xbee_at_rx( data );    // 受信
04648     if( return_MODE > 0x00 ){   // キャッシュがある、または受信データがある時
04649         //  if( xbee_result->MODE == 0x00 ||    // 指定(入力)されたモード値が00(オート)
04650         //  xbee_result->MODE == data[3] ||     // または、受信結果と一致
04651         //  cache_en ){                         // キャッシュ動作の時
04652         return_MODE = xbee_from_acum( data );
04653         switch( return_MODE ){
04654             case MODE_RESP: // 0x97 リモートATコマンドの結果を受信 Remote Command Response
04655                 for(i=0;i<8;i++) xbee_result->FROM[i] = data[5+i];      // アドレスはdata[5]から
04656                 #ifndef ARDUINO
04657                 #ifndef ARM_MBED
04658                     for(i=0;i<2;i++) xbee_result->SHORT[i] = data[13+i];// アドレスはdata[13]から
04659                 #endif
04660                 #endif
04661             //  for( i=0 ; i<2 ; i++ ) xbee_result->AT[i] = data[15+i]; // ATはdata[15]から
04662                 xbee_result->AT[0] = data[15];
04663                 xbee_result->AT[1] = data[16];
04664                 xbee_result->ID = data[4];                              // PACKET_ID
04665                 xbee_result->STATUS = data[17];                         // statusはdata[17]
04666                 ret = data[17];
04667                 if( xbee_result->STATUS==0x00 ){
04668                     if( xbee_result->AT[0]=='I' && xbee_result->AT[1]=='S' ){   // ATISの受信
04669                         ret=(data[23] & data[20]);  // GPIOの下位を受信マスクで&して応答(要約応答)
04670                         if( data[19] == 0x00 && data[20] == 0x00 ){
04671                             j = 1;                                          // デジタルデータが無いとき
04672                         }else{
04673                             j = 0;                                          // デジタルデータがある時
04674                             xbee_result->GPI.BYTE[1] = (data[22] & data[19]);   // 上位をマスクして応答
04675                             xbee_result->GPI.BYTE[0] = (data[23] & data[20]);   // 下位をマスクして応答
04676                             for( i = 0 ; i<2 ; i++) xbee_result->DATA[i] = xbee_result->GPI.BYTE[i];
04677                         }
04678                         for( i=0; i < 4 ; i++ ){                            // この中でjを使用している
04679                             if( (data[21]>>i) & 0x01 ){                     // data[21] ADCマスク
04680                                 xbee_result->ADCIN[i] =  (unsigned int)(data[(2*i+24-2*j)]);
04681                                 xbee_result->ADCIN[i] *= (unsigned int)256;
04682                                 xbee_result->ADCIN[i] += (unsigned int)(data[2*i+25-2*j]);
04683                                 xbee_result->DATA[i*2+2] = data[24+2*i-2*j];
04684                                 xbee_result->DATA[i*2+3] = data[25+2*i-2*j];
04685                             }else{                                  
04686                                 xbee_result->DATA[i*2+2] = 0xFF;
04687                                 xbee_result->DATA[i*2+3] = 0xFF;
04688                                 j++;
04689                             }
04690                         }
04691                     }else if( xbee_result->AT[0] == '%' && xbee_result->AT[1] == 'V'){  // BATTの受信
04692                         return_MODE = MODE_BATT;
04693                         xbee_result->GPI.BYTE[1] = data[18];
04694                         xbee_result->GPI.BYTE[0] = data[19];
04695                     //  xbee_result->DATA[1] = data[18];
04696                     //  xbee_result->DATA[0] = data[19];
04697                         xbee_result->ADCIN[0] = xbee_batt_acum(data[18],data[19]);
04698                     }
04699                 }
04700                 break;
04701             case MODE_GPIN: // 0x92 GPI data を受信するモード (ZigBee IO Data Sample Ex Indicator)
04702                 ret=xbee_gpi_acum( data );
04703                 for(i=0;i<8;i++) xbee_result->FROM[i] = data[4+i];      // アドレスはdata[4]から
04704                 #ifndef ARDUINO
04705                 #ifndef ARM_MBED
04706                     for(i=0;i<2;i++) xbee_result->SHORT[i] = data[12+i];// アドレスはdata[12]から
04707                 #endif
04708                 #endif
04709                 xbee_result->STATUS = data[14];                         // statusはdata[14] 0x01=Ack 0x02=broadcast
04710                 if( data[16] == 0x00 && data[17] == 0x00 ){
04711                     j = 1;                                              // デジタルデータが無いとき
04712                 }else{
04713                     j = 0;                                              // デジタルデータがある時
04714                     xbee_result->GPI.BYTE[1] = (data[16] & data[19]);   // 上位をマスクして応答
04715                     xbee_result->GPI.BYTE[0] = (data[17] & data[20]);   // 下位をマスクして応答
04716                     for( i = 0 ; i<2 ; i++) xbee_result->DATA[i] = xbee_result->GPI.BYTE[i];
04717                 }
04718                 for( i=0; i < 4 ; i++ ){                                // この中でjを使用している
04719                     if( (data[18]>>i) & 0x01 ){
04720                         xbee_result->ADCIN[i] =  (unsigned int)(data[2*i+21-2*j]);
04721                         xbee_result->ADCIN[i] *= (unsigned int)256;
04722                         xbee_result->ADCIN[i] += (unsigned int)(data[2*i+22-2*j]);
04723                         xbee_result->DATA[i*2+2] = data[21+2*i-2*j];
04724                         xbee_result->DATA[i*2+3] = data[22+2*i-2*j];
04725                     }else {
04726                         xbee_result->DATA[i*2+2] = 0xFF;
04727                         xbee_result->DATA[i*2+3] = 0xFF;
04728                         j++;
04729                     }
04730                     //printf("ADC[%d]=%d \n",i, (int)(xbee_result->ADC[i]) );
04731                 }
04732                 if( (data[18]>>7) & 0x01 ){
04733                     xbee_result->ADCIN[0] = xbee_batt_acum(data[29-2*j],data[30-2*j]);
04734                 }
04735             //  xbee_result->DATA[10]=data[2];  // 仮(受信バイト数を確認するため)
04736                 break;
04737             case MODE_UART: // 0x90 UART data を受信するモード 戻り値はlength
04738                 for(i=0;i<8;i++) xbee_result->FROM[i] = data[4+i];      // アドレスはdata[4]から
04739                 #ifndef ARDUINO
04740                 #ifndef ARM_MBED
04741                     for(i=0;i<2;i++) xbee_result->SHORT[i] = data[12+i];// アドレスはdata[12]から
04742                 #endif
04743                 #endif
04744                 xbee_result->STATUS = data[14];                         // statusはdata[14]
04745                 if( ( xbee_uart_acum( data )) > 0 ){                    // 以上の値は仕様書に記述誤り
04746                     ret = data[2]-0x0C;             // 12バイト減算
04747                     if( ret >= CALL_SIZE ) ret = CALL_SIZE -1;
04748                     for( i=0; i<ret ; i++ ) xbee_result->DATA[i] = data[15+i];
04749                     // xbee_result->DATA[i] = 0x00;
04750                     xbee_result->STATUS = data[14];
04751                 }
04752                 break;
04753             #ifndef LITE    // BeeBee Lite by 蘭
04754             case MODE_UAR2: // 0x91 UART data 2を受信するモード
04755                 for(i=0;i<8;i++) xbee_result->FROM[i] = data[4+i];      // アドレスはdata[4]から
04756                 #ifndef ARDUINO
04757                 #ifndef ARM_MBED
04758                     for(i=0;i<2;i++) xbee_result->SHORT[i] = data[12+i];// アドレスはdata[12]から
04759                     for(i=0;i<6;i++) xbee_result->ZCL[i] = data[14+i];  // ZCL情報data[14]から
04760                 #endif
04761                 #endif
04762                 xbee_result->STATUS = data[20];                         // statusはdata[20]
04763                 if( ( xbee_uart_acum( data )) > 0 ){
04764                     ret = data[2]-0x12;             // 18バイト減算
04765                     if( ret >= CALL_SIZE ) ret = CALL_SIZE -1;
04766                     for( i=0; i<ret ; i++ ) xbee_result->DATA[i] = data[21+i];
04767                     // xbee_result->DATA[i] = 0x00;
04768                 }
04769                 break;
04770             #endif // LITE
04771             #ifndef LITE    // BeeBee Lite by 蘭
04772             case MODE_SENS: // 0x94 XB Sensor(1-wire)を受信するモード(未確認)
04773                 for(i=0;i<8;i++) xbee_result->FROM[i] = data[4+i];      // アドレスはdata[4]から
04774                 #ifndef ARDUINO
04775                 #ifndef ARM_MBED
04776                     for(i=0;i<2;i++) xbee_result->SHORT[i] = data[12+i];// アドレスはdata[12]から
04777                 #endif
04778                 #endif
04779                 xbee_result->STATUS = data[14];                         // statusはdata[14]
04780                 xbee_result->ADCIN[0] = 256*(unsigned int)data[24] + (unsigned int)data[25];
04781                 for( i=1; i < 4 ; i++ )                 // ADC値を代入、ただしAIN[0]へは代入しない
04782                     xbee_result->ADCIN[i] = 256*(unsigned int)data[2*i+16] + (unsigned int)data[2*i+16];
04783                 for( i=0; i<10 ; i++ ) xbee_result->DATA[i] = data[16+i];
04784                 xbee_result->DATA[10] = data[16+i];     // sensor 01:ADC 02:Temp. 60:water present
04785                 break;
04786             #endif // LITE
04787             case MODE_IDNT: // 0x95 Node Identifyを受信するモード
04788                 for(i=0;i<8;i++) xbee_result->FROM[i] = data[4+i];      // アドレスはdata[4]から
04789                 #ifndef ARDUINO
04790                 #ifndef ARM_MBED
04791                     for(i=0;i<2;i++) xbee_result->SHORT[i] = data[12+i];    // アドレスはdata[12]から
04792                     for(i=0;i<CALL_SIZE && i<20;i++){
04793                         xbee_result->DATA[i] = data[15+i];
04794                         /*
04795                              0  15 Source 16-bit address
04796                              2  17 64-bit Network address
04797                             10  25 NI Strings
04798                             12  27 Parent address
04799                             14  29 Device Type
04800                             15  30 Source Event
04801                             16  31 Profile ID     C1 05
04802                             18  33 Manufacture ID 10 1F
04803                         */
04804                     }
04805                 #endif
04806                 #endif
04807                 xbee_result->STATUS = data[14];                         // // statusはdata[14] 0x01=Ack 0x02=broadcast
04808                 ret = data[14];
04809                 switch(data[29]){
04810                     case 0x00:  ret=ZB_TYPE_COORD; break;
04811                     case 0x01:  ret=ZB_TYPE_ROUTER; break;
04812                     case 0x02:  ret=ZB_TYPE_ENDDEV; break;
04813                 }
04814                 break;
04815             case MODE_RES:  // 0x88 ローカルATコマンドの結果を受信(モードのみ応答)
04816             //  for( i=0 ; i<2 ; i++ ) xbee_result->AT[i] = data[5+i];  // ATはdata[15]から
04817                 xbee_result->AT[0] = data[5];
04818                 xbee_result->AT[1] = data[6];
04819                 xbee_result->ID = data[4];                              // Frame ID
04820                 xbee_result->STATUS = data[7];                          // statusはdata[7]
04821                 ret = data[7];
04822                 break;
04823             case MODE_MODM: // 0x8A Modem Statusを受信
04824                 xbee_result->STATUS = data[4];                          // statusはdata[4]
04825                 ret = data[4];
04826                 break;
04827             case MODE_TXST: // 0x8B UART Transmit Status を受信
04828                 xbee_result->STATUS = data[8];                          // delivery statusはdata[8] 0x00=Success
04829                 ret = data[9];                                          // Discovery status data[9]
04830             #ifndef ARDUINO
04831             #ifndef ARM_MBED
04832             case 0x00:
04833                 break;
04834             #endif
04835             #endif
04836             default:
04837                 #ifdef LCD_H
04838                     xbee_log( 3, "CAUTION:recieved unknown pckt" , xbee_result->MODE );
04839                 #endif
04840                 ret = xbee_result->MODE;
04841                 break;
04842         }
04843         xbee_result->MODE = return_MODE;
04844     }
04845     #ifdef LCD_H
04846         // xbee_log( 1, "done:xbee_rx_call" , ret );
04847     #endif
04848     return( ret );
04849 }
04850 
04851 void xbee_clear_cache(void){
04852     #ifdef CACHE_RES
04853         CACHE_COUNTER=0;
04854     #endif
04855 }
04856 
04857 #ifdef EASY_SENSOR
04858 float xbee_sensor(const byte *address, const enum xbee_sensor_type type ){
04859 /*  XBee Sensor(XBee Sensor /L/T または /L/T/H) の測定API (1-wire Sensor Adapterではない)
04860 
04861 注意:本コマンドは応答待ちを行うので干渉によるパケット損失があります。
04862    また、センサーがスリープになっている場合はエラーになる場合が多い(タイムアウトする)
04863     
04864     これらのような場合は、xbee_forceで測定指示を出して、xbee_rx_callで受信結果を得ます。
04865     XBee Sensorはxbee_sensor_resultで受信結果を温度などに変換できます。
04866 
04867     入力:enum xbee_sensor_type {LIGHT,TEMP,HUMIDITY,WATT};    // センサタイプの型
04868     出力:float センサ読み取り値
04869 
04870 設計情報
04871     リターン信号例
04872     00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
04873     7E 00 1B 97 01 00 13 A2 00 -- -- -- -- -- -- 49 53 00 01 08 00 0E 08 00 03 E2 02 62 02 16 A1
04874       | len |mo|FI|送信元IEEEアドレス      |Short|AT(IS)  |01|GPIO |AD|GPIO |ADC1 |ADC2 |ADC3 |CS
04875       |     |de|  |                       |Adrss|        |01|MASK |MS|DATA |DATA |DATA |DATA |
04876       |     |  |  |                                               |  |     |Light|Temp |Humidity
04877       |     |  |                          ADC MASK________________|__|
04878       |     |__|__________________ MODE_RESP(0x97)= ATIS応答
04879       |_____|_____________________ Data Length
04880 */
04881     XBEE_RESULT xbee_result;
04882     byte data[API_SIZE];
04883     byte j;
04884     float ret = -1.0f;
04885 
04886     xbee_address(address);                              // 宛先のアドレスを設定
04887     if( xbee_tx_rx("RATIS", data , 0) > 0 ){
04888         if( data[3]==MODE_RESP ){                       // d[3] flame ID = 97(RAT応答)
04889             if( data[19] == 0x00 && data[20] == 0x00 ) j = 0; else j = 2;
04890             xbee_result.ADCIN[1] = (unsigned int)data[22+j] * 256 + (unsigned int)data[23+j];
04891             xbee_result.ADCIN[2] = (unsigned int)data[24+j] * 256 + (unsigned int)data[25+j];
04892             xbee_result.ADCIN[3] = (unsigned int)data[26+j] * 256 + (unsigned int)data[27+j];
04893             ret = xbee_sensor_result( &xbee_result, type );
04894         }
04895     }
04896     #ifdef LCD_H
04897         xbee_log( 1, "done:xbee_sensor" , ret );
04898     #endif
04899     return( ret );
04900 }
04901 #endif // EASY_SENSOR
04902 
04903 byte xbee_init( const byte port ){
04904 /*
04905     port:PCの場合、オープンするシリアルポート番号
04906          Arduinoの場合リトライ回数、0で永久にリトライを繰り返す
04907     戻り値:0=エラー 1=成功までのトライ回数
04908     Arduino版 portが0で無い時は、portの指定回数リトライしてエラーでもreturnする
04909 */
04910     byte i=1;   // iはリセット実行リトライ回数、0で成功するまで永久
04911     byte j;     // jは色々
04912     byte k=0;   // kはリセット成功可否フラグ,戻り値
04913     #ifndef LITE
04914         #ifndef XBEE_WIFI
04915             byte address[8];        //={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
04916         #else // XBEE_WIFI
04917             byte address[8]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
04918             // xbee_address(address);
04919         #endif
04920     #endif
04921     
04922     #ifdef LCD_H
04923         xbee_log( 1, "started:xbee_init" , port );
04924     #endif
04925     #ifdef H3694
04926         port_init();                    // 汎用入出力ポートの初期化
04927         timer_sec_init();               // 秒タイマー初期化
04928         led_green( 1 );
04929     #endif
04930     
04931     #ifdef H3694
04932         sci_init( 0 );              // シリアル初期化
04933         i=port;
04934     #elif ARDUINO
04935         sci_init( 0 );              // シリアル初期化
04936         i=port;
04937     #else
04938         #ifdef ARM_MBED
04939             sci_init( 0 );              // シリアル初期化
04940             _xbee_time_init();          // Initialize Timer
04941             i=port;
04942         #else   // PC
04943             if( port != 0 ){
04944                 j = sci_init( port );       // シリアル初期化
04945             }else{
04946                 // ポート検索
04947                 for( i=10 ; i>0; i--){
04948                     j = sci_init( i );
04949                     if( j != 0 ){
04950                         k = xbee_reset();
04951                         if( k > 0 ) i = 1; else j = 0;
04952                     }
04953                 }
04954             }
04955             if( j == 0 ){
04956                 fprintf(stderr,"EXIT:Serial Open Error\n");
04957                 exit(-1);
04958             }
04959             i=1;
04960         #endif
04961     #endif
04962     
04963     #ifdef LCD_H
04964         #ifndef ARDUINO
04965             #ifdef H3694
04966                 lcd_enable( 1 );                // 液晶の電源投入
04967                 wait_millisec(15);              // 起動待ち
04968                 lcd_init();                     // 液晶制御ICのプレ初期化
04969             #endif
04970         #endif
04971         wait_millisec(15);                      // 初期化待ち
04972         lcd_init();                         // 2回目の初期化(確実な初期化)
04973         #ifndef ARDUINO
04974             lcd_control(1,0,0);             // 液晶制御 表示ON,カーソルOFF,点滅OFF
04975         #endif
04976         #ifdef H3694
04977             lcd_cls();                      // 液晶消去
04978             lcd_goto(LCD_ROW_1);
04979         #endif
04980         lcd_putstr( NAME );
04981         lcd_putstr(" ");
04982         lcd_putstr( VERSION );
04983         #ifdef H3694
04984             lcd_goto(LCD_ROW_2);
04985         #else
04986             lcd_putch('\n');
04987         #endif
04988         #ifdef LITE
04989             lcd_putstr(COPYRIGHT);
04990             lcd_putch('\n');
04991         #else
04992             lcd_putstr(COPYRIGHT);
04993         #endif
04994         xbee_log( 1, "xbee_reset" , 0 );
04995     #endif
04996     #ifdef LITE // by 蘭
04997         k = xbee_reset();
04998         #ifndef H3694
04999         #ifndef ARDUINO
05000         #ifndef ARM_MBED    // PC
05001             if(k==0){
05002                 #ifdef LCD_H
05003                     xbee_log( 5, "EXIT:xbee_init:myaddress" , 0 );
05004                 #endif
05005                 exit(-1);
05006             }
05007         #endif
05008         #endif
05009         #endif
05010     #else // Normal mode
05011         k=1;
05012         if(i==0) while( !xbee_reset() ) wait_millisec(1000);
05013         else for(j=0;j<i;j++){
05014             k=xbee_reset(); // 0だとシリアル異常
05015             if( k ) break;
05016             wait_millisec(1000);
05017         }
05018         if(k==0){
05019             #ifndef H3694
05020             #ifndef ARDUINO
05021             #ifndef ARM_MBED    // PC
05022                 #ifdef LCD_H
05023                     xbee_log( 5, "EXIT:xbee_init:myaddress" , 0 );
05024                 #endif
05025                 exit(-1);
05026             #endif
05027             #endif
05028             #endif
05029         }else{  // k>0 すなわち reset成功時  以下、kは使用しないこと(戻り値にする)
05030             #ifdef LCD_H
05031                 #ifdef H3694
05032                     lcd_cls();
05033                     lcd_goto(LCD_ROW_1);
05034                 #else
05035                     lcd_putstr("\n--------------------\n");
05036                 #endif
05037             #endif
05038             #ifdef LCD_H
05039                 xbee_log( 1, "xbee_init:myaddress" , port );
05040             #endif
05041             xbee_myaddress( address );  // 自分自身のアドレスを取得
05042             #ifdef LCD_H
05043                 for(i=0;i<4;i++){
05044                     #ifndef XBEE_WIFI
05045                         lcd_disp_hex(address[4+i]);
05046                     #else // XBEE_WIFI
05047                         /*
05048                         printf("%d",address[i]);
05049                         if(i<3)printf(".");
05050                         */
05051                         lcd_disp_hex(address[i]);
05052                     #endif
05053                 }
05054                 switch( DEVICE_TYPE ){
05055                     #ifndef XBEE_WIFI
05056                         case ZB_TYPE_COORD:     lcd_putstr( " COORD."); break;
05057                         case ZB_TYPE_ROUTER:    lcd_putstr( " ROUTER"); break;
05058                         case ZB_TYPE_ENDDEV:    lcd_putstr( " ENDDEV"); break;
05059                     #else
05060                         case XB_TYPE_NULL:      lcd_putstr( " XBee Wi-Fi"); break;
05061                         case XB_TYPE_WIFI10:    lcd_putstr( " XBee Wi-Fi Ver 1.0"); break;
05062                         case XB_TYPE_WIFI20:    lcd_putstr( " XBee Wi-Fi Ver 2.0"); break;
05063                     #endif
05064                     default:    lcd_putstr( " UNKNWON"); break;
05065                 }
05066                 #ifdef H3694
05067                     lcd_goto(LCD_ROW_1);
05068                 #else
05069                     lcd_putstr("\n\n");
05070                 #endif
05071                 xbee_log( 1, "done:xbee_init" , 0 );
05072             #endif
05073         }
05074     #endif
05075     return(k);
05076 }
05077 
05078 
05079 byte xbee_end_device(const byte *address, byte sp, byte ir, const byte pin){
05080 /*
05081 XBee子機(エンドデバイス)をスリープモードに設定する
05082 入力:byte *address = 宛先(子機)アドレス
05083 入力:byte sp = 1~28:スリープ間隔(秒)
05084 入力:byte ir = 0:自動送信切、1~65:自動送信間隔(秒)
05085 入力:byte pin = 0:通常のスリープ、 1:SLEEP_RQ端子を有効に設定
05086 出力:戻り値 = 0x00 指示成功、 その他=エラー理由
05087         1:     対応デバイス以外に設定しようとした
05088         2:     スリープ解除しようとしたのに失敗した
05089         4:     スリープ移行待ち時間ST設定の失敗
05090         8:     スリープ間隔SP設定の失敗
05091         16: ローカル親機へのスリープ時間SP設定の失敗
05092         32: データ取得間隔IR設定の失敗
05093         64: スリープ状態設定の失敗
05094         128:   スリープオプション設定の失敗
05095 */
05096     byte ret=0x00;
05097     byte data[API_SIZE];
05098     unsigned int time;
05099     
05100     xbee_address( address );                            // 送信先を指定
05101     if( ir > 65 ) ir = 65;
05102     time = (unsigned int)ir * 1000;             // ms単位の数字に変換
05103         
05104     #ifndef XBEE_WIFI // ZigBee 
05105         /* XBee子機から自動送信する周期を設定します */
05106         data[0] = (byte)(time / 256);
05107         data[1] = (byte)(time % 256);                       // スリープ時間 sleep_time
05108         if( !xbee_tx_rx("RATIR",data,2) ) ret|=32;
05109         
05110         /* エンドデバイス以外の時に終了する */
05111         if( xbee_tx_rx("RATVR",data,0) ) if(data[18] != 0x28){
05112             return( ret );
05113         }
05114     #endif
05115 
05116     if( sp == 0x00 ){
05117         data[0] = 0x00;
05118         if( !xbee_tx_rx("RATSM",data,1) ) ret|=2;       // スリープ解除
05119     }else{
05120         #ifdef XBEE_WIFI
05121             if(DEVICE_TYPE == XB_TYPE_WIFI20){
05122                 return(1);
05123             }       
05124             data[0] = 0x01;
05125             data[1] = 0x40;                     // スリープ時間 sleep_time
05126             if( !xbee_tx_rx("RATSO",data,2) ) ret|=128;
05127         #endif
05128 
05129         #ifndef XBEE_WIFI // ZigBee
05130             /* XBee★親機★にXBee子機のデータ保持期間(28秒)を設定 */
05131             data[0] = 0x0A;
05132             data[1] = 0xF0;                     // スリープ時間 sleep_time
05133             if( !xbee_tx_rx("ATSP",data,2) ) ret|=16;               // 保持時間 sleep_time
05134         #endif
05135         
05136         /* XBee子機のスリープ移行待ち時間を設定します */
05137         data[0]=0x01; data[1]=0xF4;                         // 保持時間 500 ms
05138         if( !xbee_tx_rx("RATST",data,2) ) ret|=4;
05139         
05140         /* XBee子機のスリープ間隔を設定します */
05141         if( sp > 28 ) sp = 28;
05142         time = (unsigned int)sp * 100;              // 10ms単位の数字に変換
05143         data[0] = (byte)(time / 256);
05144         data[1] = (byte)(time % 256);                       // スリープ時間 sleep_time
05145         if( !xbee_tx_rx("RATSP",data,2) ) ret|=8;
05146 
05147         /* XBee子機をサイクリックスリープに設定します */
05148         if( pin ) data[0]=0x05; else data[0]=0x04;  // 0x00:常に動作 0x04:低消費電力動作
05149         if( !xbee_tx_rx("RATSM",data,1) ) ret|=64;  // 0x05:SLEEP_RQ有効
05150     }
05151 
05152     #ifdef LCD_H
05153         xbee_log( 1, "done:end_device" , ret );
05154     #endif
05155     return( ret );
05156 }
05157 
05158 #ifndef LITE
05159 byte _xbee_i2c(byte dio,byte level,byte *data){
05160 /*  dio     = 11:SCL    12:SDA
05161     level   = 0:L 1:Open
05162     data    ATコマンド応答用データ
05163     
05164     data[0]=0x03;   xbee_at_tx("SATP1",data,1);     // Port 11(SCL) H Imp
05165     data[0]=0x04;   xbee_at_tx("SATP1",data,1);     // Port 11(SCL) L Out
05166     data[0]=0x03;   xbee_at_tx("SATP2",data,1);     // Port 12(SDA) H Imp
05167     data[0]=0x04;   xbee_at_tx("SATP2",data,1);     // Port 12(SDA) L Out
05168 */
05169     char at[6]="SATPX";
05170     if(dio>=10) dio = dio%10;
05171     if(dio>=2) dio=2; else dio=1;
05172     at[4]='0'+dio;
05173     data[0]=level;
05174     if(level>=10) data[0]=level%10;
05175     if(level==0) data[0]=4; // Out Low
05176     if(level==1) data[0]=3; // High Imp
05177     return( xbee_at_tx(at,data,1) );    // 戻り値:0ならエラー発生
05178 }
05179 
05180 byte _xbee_i2c_start(byte *data){
05181     byte ret=1; // 戻り値:0ならエラー発生
05182     ret *= _xbee_i2c(1/*SCL*/,1,data);                  // Port 11(SCL) H Imp
05183     ret *= xbee_tx_rx("RATAC",data,0);                  // クロックHレベル固定
05184     ret *= _xbee_i2c(2/*SDA*/,1,data);                  // Port 12(SDA) H Imp
05185     ret *= _xbee_i2c(2/*SDA*/,0,data);                  // Port 12(SDA) L Out
05186     ret *= _xbee_i2c(1/*SCL*/,0,data);                  // Port 11(SCL) L Out
05187     if(ret==0) xbee_log( 5, "ERROR:Failed I2C TX Output" , ret );
05188     return(ret);
05189 }
05190 
05191 byte _xbee_i2c_tx(const byte in, byte *data){
05192     byte i;
05193     for(i=0;i<8;i++){
05194         if( (in>>(7-i))&0x01 ){
05195                 _xbee_i2c(2/*SDA*/,1,data);         // Port 12(SDA) H Imp
05196         }else   _xbee_i2c(2/*SDA*/,0,data);         // Port 12(SDA) L Out
05197         /*Clock*/
05198         _xbee_i2c(1/*SCL*/,1,data);                 // Port 11(SCL) H Imp
05199         _xbee_i2c(1/*SCL*/,0,data);                 // Port 11(SCL) L Out
05200     }
05201     /* ACK受信待ち(ACKはスレーブから) */
05202     _xbee_i2c(1/*SCL*/,1,data);                     // Port 11(SCL) H Imp
05203     _xbee_i2c(2/*SDA*/,1,data);                     // Port 12(SDA) H Imp 逆
05204 //  xbee_tx_rx("RATAC",data,0); // 本来は不要だがEnd Deviceの時にRATISを確実に受信するために入れてみた
05205     i=xbee_tx_rx("RATIS",data,0);
05206     if( i==0) xbee_log( 5, "ERROR:I2C no RAT RESP" , i );
05207     if( (data[22]>>4)&0x01 ){
05208         xbee_log( 5, "ERROR:I2C no ACK" , data[22] );
05209         i=0;
05210     }
05211 //  printf("ACK=%d ATIS=%d\n",(data[22]>>4)&0x01,i);
05212     return(i);
05213 }
05214 
05215 byte xbee_i2c_init(const byte *address){
05216 /*
05217 XBee I2Cインタフェースとして使用するための初期設定
05218 入力:byte *address リモートXBee子機のIEEEアドレス
05219 */
05220     byte data[API_SIZE];
05221     byte i;
05222     for(i=3;i>0;i--){   // リトライ3回まで
05223         xbee_address(address);
05224         _xbee_i2c(1/*SCL*/,1,data);                 // Port 11(SCL) H Imp
05225         _xbee_i2c(2/*SDA*/,1,data);                 // Port 12(SDA) H Imp
05226         if( xbee_tx_rx("RATIS",data,0) ){
05227             if( ((data[22]>>3)&0x03) == 0 ) break;
05228         }
05229     }
05230     delay(200);
05231     return(i);
05232 }
05233 
05234 byte xbee_i2c_read(const byte *address, byte adr, byte *rx, byte len){
05235 /*
05236 子機XBeeデバイス(リモート先)のI2Cから指定バイトの情報を読み取る関数
05237 入力:byte *address = リモートXBee子機のIEEEアドレス
05238 入力:byte adr = I2Cアドレス /SHT 温度測定時0x01   湿度測定時0x02
05239 出力:byte *rx = 受信データ用ポインタ
05240 入力:byte len = 受信長、0の時は Sensirion SHT用2バイト受信
05241             port=11     DIO11   XBee_pin  7     SCL
05242             port=12     DIO12   XBee_pin  4     SDA
05243 ・I2Cマスタ機能のみを実装(スレーブとしては動作しない)
05244 ・7ビットアドレスのみ対応
05245 ・1バイトの受信に5秒以上かかる(かなり遅いし、多量のXBee通信が発生する)
05246 */
05247     byte data[API_SIZE];
05248     byte ret,i,sht=0;
05249     
05250     xbee_address(address);                          // 宛先のアドレスを設定
05251     if(len){    // stop シーケンス + start シーケンス
05252         _xbee_i2c_start(data);
05253     }else{      // Sensirion SHT用  TS シーケンス
05254         _xbee_i2c(1/*SCL*/,0,data);                 // Port 11(SCL) L Out
05255         _xbee_i2c(1/*SCL*/,1,data);                 // Port 11(SCL) H Imp
05256         _xbee_i2c(2/*SDA*/,0,data);                 // Port 12(SDA) L Out
05257         _xbee_i2c(1/*SCL*/,0,data);                 // Port 11(SCL) L Out
05258         _xbee_i2c(1/*SCL*/,1,data);                 // Port 11(SCL) H Imp
05259         _xbee_i2c(2/*SDA*/,1,data);                 // Port 12(SDA) H Imp
05260         _xbee_i2c(1/*SCL*/,0,data);                 // Port 11(SCL) L Out
05261         _xbee_i2c(2/*SDA*/,0,data);                 // Port 12(SDA) L Out
05262         sht=1;  len=2;  // SHTモード
05263         xbee_tx_rx("RATAC",data,0);
05264         adr = adr<<1;
05265     }
05266     adr |= 0x01;    // RW=1 受信モード
05267     if( _xbee_i2c_tx(adr, data)==0 ) return(0); // アドレス設定
05268     if( !sht ){ // SHTセンサで無い時
05269         _xbee_i2c(2/*SDA*/,0,data);                 // Port 12(SDA) L Out
05270         _xbee_i2c(1/*SCL*/,0,data);                 // Port 11(SCL) L Out
05271     }
05272     
05273     /* スレーブ待機状態待ち */
05274     if(!sht){   // I2C
05275         /*
05276         for(i=0;i<4;i++){
05277             ret=xbee_tx_rx("RATIS",data,0);
05278             if( (((data[22]>>4)&0x01) == 1) &&      // ACKが解除された      //data[22]b4=Port 12(SDA)
05279                 (((data[22]>>3)&0x01) == 1) ) break;// スレーブがCLKホールドしていない // data[22]b3=Port 11(SCL)
05280             wait_millisec(500);
05281         }
05282                 // printf("i=%d\n",i);
05283         if(i==4){
05284             xbee_log( 5, "ERROR:I2C Clock Holded" , data[22] );
05285             return(0);
05286         }
05287         */
05288     }else{      // SHT
05289         _xbee_i2c(1/*SCL*/,0,data);                 // Port 11(SCL) L Out
05290         for(i=0;i<4;i++){
05291             ret=xbee_tx_rx("RATIS",data,0);
05292             if( ((data[22]>>4)&0x01) == 0 ) break;// 測定完了   //data[22]b4=Port 12(SDA)
05293         }   // printf("Slave Holds SDA i=%d\n",i);
05294         if(i==4){
05295             xbee_log( 5, "ERROR:I2C SDA Holded" , data[22] );
05296             return(0);
05297         }
05298     }
05299     _xbee_i2c(1/*SCL*/,0,data);                         // Port 11(SCL) L Out
05300     
05301     /* 受信データ */
05302     for(ret=0;ret<len;ret++){
05303         if(ret){    // 初回以外の時はACKを応答する
05304             _xbee_i2c(2/*SDA*/,0,data);                 // Port 12(SDA) L Out
05305             _xbee_i2c(1/*SCL*/,1,data);                 // Port 11(SCL) H Imp
05306             _xbee_i2c(1/*SCL*/,0,data);                 // Port 11(SCL) L Out
05307             _xbee_i2c(2/*SDA*/,1,data);                 // Port 12(SDA) H Imp
05308         }
05309         rx[ret]=0x00;
05310         for(i=0;i<8;i++){
05311             _xbee_i2c(1/*SCL*/,1,data);                 // Port 11(SCL) H Imp
05312         //  xbee_tx_rx("RATAC",data,0);
05313             if( xbee_tx_rx("RATIS",data,0)==0x00) break;    // error
05314             rx[ret] |= ((data[22]>>4)&0x01)<<(7-i);     //data[22] b4=Port 12(SDA)
05315             _xbee_i2c(1/*SCL*/,0,data);                 // Port 11(SCL) L Out
05316         }
05317         if(i!=8) break; // error
05318     }
05319     _xbee_i2c(1/*SCL*/,1,data);                         // Port 11(SCL) H Imp
05320     if(sht) _xbee_i2c(1/*SCL*/,0,data);                 // Port 11(SCL) L Out
05321     xbee_tx_rx("RATAC",data,0);
05322     return(ret);
05323 }
05324 
05325 byte xbee_i2c_write(const byte *address, byte adr, byte *tx, byte len){
05326 /*
05327 子機XBeeデバイス(リモート先)のI2Cから指定バイトの情報を書き込む関数
05328 入力:byte *address = リモートXBee子機のIEEEアドレス
05329 入力:byte adr = I2Cアドレス /SHT 温度測定時0x01   湿度測定時0x02
05330 入力:byte *tx = 送信データ用ポインタ
05331 入力:byte len = 送信データ長、0の時は Sensirion SHT用2バイト受信
05332             port=11     DIO11   XBee_pin  7     SCL
05333             port=12     DIO12   XBee_pin  4     SDA
05334 */
05335     byte data[API_SIZE];
05336     byte ret;
05337     
05338     xbee_address(address);                          // 宛先のアドレスを設定
05339     if(len) _xbee_i2c_start(data);
05340     else return(0);
05341     adr &= 0xFE;    // RW=0 送信モード
05342     if( _xbee_i2c_tx(adr, data)==0 ) return(0); // アドレス設定
05343     /* スレーブ待機状態待ち */
05344     /*
05345     for(i=0;i<4;i++){
05346         ret=xbee_tx_rx("RATIS",data,0);
05347         if( (((data[22]>>4)&0x01) == 1) &&      // ACKが解除された      //data[22]b4=Port 12(SDA)
05348             (((data[22]>>3)&0x01) == 1) ) break;// スレーブがCLKホールドしていない // data[22]b3=Port 11(SCL)
05349         wait_millisec(500);
05350     }
05351             // printf("i=%d\n",i);
05352     if(i==4){
05353         xbee_log( 5, "ERROR:I2C Clock Holded" , data[22] );
05354         return(0);
05355     }
05356     */
05357     _xbee_i2c(2/*SDA*/,0,data);                 // Port 12(SDA) L Out
05358     _xbee_i2c(1/*SCL*/,0,data);                 // Port 11(SCL) L Out
05359     
05360     /* 送信データ */
05361     for(ret=0;ret<len;ret++){
05362         _xbee_i2c_tx(tx[ret],data);
05363         _xbee_i2c(2/*SDA*/,0,data);                 // Port 12(SDA) L Out
05364         _xbee_i2c(1/*SCL*/,0,data);                 // Port 11(SCL) L Out
05365     }
05366     return(ret);
05367 }
05368 #endif // LITE
05369 
05370 byte xbee_delay(unsigned int ms){
05371 /*
05372 待ち時間。受信値はバッファへ保存します。
05373 入力:unsigned int(shortを想定) ms    = 時間[ms]
05374 戻り値:受信パケット数
05375 */  
05376     #ifdef LITE // BeeBee Lite by 蘭
05377         wait_millisec( ms );
05378         return 0;
05379     #else
05380         byte i,ret=0;
05381         byte data[API_SIZE];
05382         
05383         while(ms>0){
05384             #ifdef CACHE_RES
05385                 if( CACHE_COUNTER < CACHE_RES ){
05386                     if( xbee_at_rx( data ) > 0){
05387                         for( i=0 ; i < API_SIZE ; i++) CACHE_MEM[CACHE_COUNTER][i] = data[i];
05388                         CACHE_COUNTER++;
05389                         ret++;
05390                         #ifdef DEBUG
05391                             lcd_putstr("### CACHE_RES ### <- ");    // DEBUG
05392                             lcd_disp_hex( CACHE_COUNTER );
05393                             lcd_putch('\n');
05394                         #endif
05395                     }
05396                 }
05397             #endif
05398             if( ms > 100 ){
05399                 wait_millisec( 100 );
05400                 ms -= 100;
05401             }else{
05402                 wait_millisec( ms );
05403                 ms = 0;
05404             }
05405         }
05406         return(ret);
05407     #endif
05408 }