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
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 }
Generated on Thu Jul 14 2022 01:23:34 by 1.7.2