Lazurite 920Jを立ち上げてみる 其の11 #LAZURITE920J #ラピスセミコンダクタ [Lazurite]
めちゃくちゃ久しぶりの更新
PRO MINI相当に変換する基板の資料を置いておきますね。
プログラムの書き換えは以下のリンク先を読んでみてください。
http://hamayan.blog.so-net.ne.jp/2016-10-21
これが有ると便利です。
スルホール用テストワイヤ TP-200
http://akizukidenshi.com/catalog/g/gC-09830/
使用コネクタ関しては以下のリンク先を読んでみてください。
http://hamayan.blog.so-net.ne.jp/2016-10-17
PRO MINI相当に変換する基板の資料を置いておきますね。
プログラムの書き換えは以下のリンク先を読んでみてください。
http://hamayan.blog.so-net.ne.jp/2016-10-21
これが有ると便利です。
スルホール用テストワイヤ TP-200
http://akizukidenshi.com/catalog/g/gC-09830/
使用コネクタ関しては以下のリンク先を読んでみてください。
http://hamayan.blog.so-net.ne.jp/2016-10-17
Lazurite 920Jを立ち上げてみる 其の10 #LAZURITE920J #ラピスセミコンダクタ [Lazurite]
変換基板の配布をしようと思っています。数量は20~30セットくらい。
いやぁ、某店舗での委託販売で交渉をしていましたが、「常時在庫を持つ!」「1年間の継続販売必須!」と言う事で売り切りができず、個人ではもっとも辛いところの在庫を持つ!必要があり、いまのところ断念しています。
セット内容は、基板と1.27mmピッチのコネクタ、2mmピッチ、2.54mmピッチのコネクタになります。
価格ですが、委託販売を行わない事から某店への手数料などが無くなるので、1000円ポッキリを考えています。※送料は別です!
どうでしょうかね?
※勿論サポートもここで行います。
※好評?だったら別タイプの変換基板も企画を進めます。
コメントに書いていただくか、以下から連絡先のファイルを入手してください。
https://dl.dropboxusercontent.com/u/60463387/contact/contact.txt
※変換基板と言えば、ESP8266をXBeeのピン配置に変換する基板も用意しているんですよ。でも半田付け、結構大変です。こちらも良かったら要望を送ってください。
Lazurite 920Jを立ち上げてみる 其の9 #LAZURITE920J #ラピスセミコンダクタ [Lazurite]
マルチタスクで行こう!
例によってマルチタスク化。例によってノンプリエンプティブ。
〇ドキュメントの在処
ネットを検索しても見つからないなぁ、、、と思っていたら、東大元暮らしでした!
ついついネット上に有ると思い込んでしまいますね。
▼FJUL-U16-100-INST-02.pdf
アーキテクチャの解説とアセンブラ命令コードの解説
▼FJXTCCU8_UM-08.pdf
コンパイラ・ユーザーズマニュアル
▼FJXTCCU8_PG-03.pdf
コンパイラ・プログラミングガイド
▼FJXTCCU8_LR-03.pdf
コンパイラ・ランゲージリファレンス
〇CPUについてまとめると
▼16bit RISCマイコン、記述が見つからなかったけれどハーバードアーキテクチャかもしれない。
一応1命令1クロック。
▼3段パイプライン。パイプラインストールを頻発しなければ結構速いかもしれない。
▼メモリ空間に関してsmallモデルとLargeモデルが有るが、今回はsmallモデルを対象としている。
ROM 64kbyte、RAM 6kbyte
〇ディスパッチャーを作る
どうでもイイことを勘違いして一日悩んだが、smallモデルであればわりと簡単だと思う。
/****************************************************************************/ /* dispatcher */ /****************************************************************************/ void sta_ctx( void *exe ) /*exe=ER0*/ { __asm( "L ER2,[ER0]\n" ); /**/ __asm( "MOV SP,ER2\n" ); /**/ __asm( "POP QR8\n" ); /*R8-R15 8bytes*/ __asm( "POP XR4\n" ); /*R4-R7 4bytes*/ __asm( "POP LR\n" ); /*link register 2bytes*/ } void swi_ctx( void *pre, void *post ) /*pre=ER0,post=ER2*/ { __asm( "PUSH LR\n" ); /*link register*/ __asm( "PUSH XR4\n" ); /*R4-R7*/ __asm( "PUSH QR8\n" ); /*R8-R15*/ __asm( "MOV ER4,SP\n" ); /**/ __asm( "ST ER4,[ER0]\n" ); /**/ __asm( "L ER0,[ER2]\n" ); /**/ __asm( "MOV SP,ER0\n" ); /**/ __asm( "POP QR8\n" ); /*R8-R15*/ __asm( "POP XR4\n" ); /*R4-R7*/ __asm( "POP LR\n" ); /*link register*/ }
〇サンプルプログラム
黄色タスクが250ms周期、青タスクが500ms周期、赤タスクが1000ms周期でLEDを点滅させているだけのプログラム
#include "multiTaskDemo_ide.h" // Additional Header #include <mul_tsk.h> #include "delivertive.h" #define BLUE_LED 26 #define RED_LED 20 #define YELLO_LED 25 void led_yello( void ); void led_blue( void ); void led_red( void ); char tsk1_stk[ 256 ]; char tsk2_stk[ 256 ]; char tsk3_stk[ 256 ]; void tsk_ini( void ) { reg_tsk( ID_led_yello,led_yello, tsk1_stk, sizeof(tsk1_stk), (VP_INT)0,(VP_INT)0,(VP_INT)0,(VP_INT)0 ); reg_tsk( ID_led_blue, led_blue, tsk2_stk, sizeof(tsk2_stk), (VP_INT)0,(VP_INT)0,(VP_INT)0,(VP_INT)0 ); reg_tsk( ID_led_red, led_red, tsk3_stk, sizeof(tsk3_stk), (VP_INT)0,(VP_INT)0,(VP_INT)0,(VP_INT)0 ); sta_tsk( ID_led_yello ); sta_tsk( ID_led_blue ); sta_tsk( ID_led_red ); } void setup(void) { Serial.begin( 115022UL ); tsk_ini(); //タスクの初期化 sta_rdq( ID_led_yello ); /*ラウンドロビン開始*/ } // Arduino loop sequence void loop(void) { } void led_yello( void ) { pinMode( YELLO_LED, OUTPUT ); digitalWrite( YELLO_LED, LOW ); while( 1 ) { digitalWrite( YELLO_LED, HIGH ); dly_tsk( 125UL ); digitalWrite( YELLO_LED, LOW ); dly_tsk( 125UL ); Serial.print( "task1 time=" ); Serial.print_long( millis(), DEC ); Serial.println( "ms" ); } } void led_blue( void ) { pinMode( BLUE_LED, OUTPUT ); digitalWrite( BLUE_LED, LOW ); while( 1 ) { digitalWrite( BLUE_LED, HIGH ); dly_tsk( 250UL ); digitalWrite( BLUE_LED, LOW ); dly_tsk( 250UL ); Serial.print( "task2 time=" ); Serial.print_long( millis(), DEC ); Serial.println( "ms" ); } } void led_red( void ) { pinMode( RED_LED, OUTPUT ); digitalWrite( RED_LED, LOW ); while( 1 ) { digitalWrite( RED_LED, HIGH ); dly_tsk( 500UL ); digitalWrite( RED_LED, LOW ); dly_tsk( 500UL ); Serial.print( "task3 time=" ); Serial.print_long( millis(), DEC ); Serial.println( "ms" ); } }
※IDEにプロジェクトの設定ファイルってのがあるんだけれど、ここに書きこんだからと言ってコンパイルオプションに展開されるわけではなく、悲しかった。
※ライブラリのデバックをしたくてSerial.printって書いても、「何それ?美味しいの?」ってコンパイラに言われて、悲しかった。
Lazurite 920Jを立ち上げてみる 其の7 #LAZURITE920J #ラピスセミコンダクタ [Lazurite]
まず言って置きます。LazuriteのI2Cの標準の速度は400kHzだぁ。つまずく事間違いなし。勿論私もつまづいた!
※setupの中で100kHzに落としてねー!
さて今日のお題はArudinoとかGR-KURUMIとか用に作成したライブラリの移植の話。
LazuriteはC++をサポートしていないので、ライブラリは全てCソースで記述しなければならない。
この辺を参照して欲しい。
http://hamayan.blog.so-net.ne.jp/2016-10-17
つまりArduinoのライブラリを持って来てもコンパイルすら通らないので、地道にコツコツCソースへの置き換えが必要となる。きっとここでめげる人多数、、、
とは言え買っちゃったのでなんとか使いこなす必要性から、なんとかしてみたいと思う。
今回移植するライブラリはGR-KURUMI用に作成したOLED表示器のライブラリです。
※ArduinoのライブラリをGR-KURUMIに持ってきた場合、かなりの確率でそのまま動く。修正が必要となったとしても、それ程手間ではない。
以下にGR-KURUMI用のソースを掲載します。
US2066.cpp ※<とか>などhtmlに変換した時に正しく変換されていない可能性が有るので、使わない事。
/*********************************************************************************/ /* US2066を使用したOLED SO1602AWGBの初期化と表示 */ /* designed by hamayan since 2015/04/21 */ /*********************************************************************************/ #include <RLduino78.h> #include <iodefine.h> #include <iodefine_ext.h> #include <US2066.h> extern "C" { #include <mul_tsk.h> } #if !defined( _MULTITASK_H_ ) #define dly_tsk(tim) delay(tim) #define rot_rdq() #define loc_cpu() interrupts() #define unl_cpu() noInterrupts() #endif /*_MULTITASK_H_ */ US2066::US2066() { } /****************************************************************************/ /* I2C block Write */ /****************************************************************************/ int US2066::blkWrite(unsigned char addr, const unsigned char *dat, unsigned int len) { Wire.beginTransmission(addr); Wire.write(dat,len); return Wire.endTransmission(); } /*************************************************************************/ /* write command */ /*************************************************************************/ int US2066::writeCommand(unsigned char t_command) { unsigned char cmd[2]; cmd[0] = 0x00; cmd[1] = t_command; return blkWrite( i2cAddress, cmd, sizeof(cmd) ); } /*************************************************************************/ /* write data */ /*************************************************************************/ int US2066::writeData(unsigned char t_data) { unsigned char dat[2]; dat[0] = 0x40; dat[1] = t_data; return blkWrite( i2cAddress, dat, sizeof(dat) ); } /*************************************************************************/ /* US2066初期化 */ /*************************************************************************/ void US2066::init( unsigned char adr ) { i2cAddress = adr; /*I2C address set*/ dly_tsk(100); writeCommand( 0x01 ); //clear display dly_tsk(20); writeCommand( 0x02 ); //return home dly_tsk(2); writeCommand( 0x0f ); //send display on command dly_tsk(2); writeCommand( 0x01 ); //clear display dly_tsk(20); } /*************************************************************************/ /* clear display */ /*************************************************************************/ void US2066::clear( void ) { dly_tsk(100); writeCommand( 0x01 ); //clear display dly_tsk(20); } /*************************************************************************/ /* display on/off */ /*************************************************************************/ void US2066::OnOff( unsigned char onoff ) { writeCommand( onoff | 0x08 ); //display on/off,cursor on/off,blink on/off dly_tsk(20); } /*************************************************************************/ /* locate */ /*************************************************************************/ void US2066::locate( int x, int y ) { int temp = x + (y * 20); if(temp >= 20) temp = (temp - 20) + 0x20; writeCommand( (unsigned char)temp | 0x80 ); //set ddram address dly_tsk(20); } /*************************************************************************/ /* set contrast */ /*************************************************************************/ void US2066::contrast( unsigned char cnt ) { //コントラスト調整 writeCommand( 0x2a ); //RE=1 writeCommand( 0x79 ); //SD=1 writeCommand( 0x81 ); //contrast set writeCommand( cnt ); //contrast max writeCommand( 0x78 ); //SD=0 writeCommand( 0x28 ); //set character size is normal. dly_tsk(100); } /*************************************************************************/ /* write strings */ /*************************************************************************/ int US2066::writeString( const char *str ) { unsigned char dat[1 * SO2002A_COLUMN + 1]; int len = strlen(str); dat[0] = 0x40; len = (len > sizeof(dat) - 1) ? sizeof(dat) - 1 : len; memcpy( &dat[1], str, len ); return blkWrite( i2cAddress, dat, len + 1 ); } /*************************************************************************/ /* write strings */ /*************************************************************************/ int US2066::writeString( const char *str, unsigned int len ) { unsigned char dat[1 * SO2002A_COLUMN + 1]; dat[0] = 0x40; len = (len > sizeof(dat) - 1) ? sizeof(dat) - 1 : len; memcpy( &dat[1], str, len ); return blkWrite( i2cAddress, dat, len + 1 ); } /*************************************************************************/ /* write strings */ /*************************************************************************/ int US2066::writeString( String str ) { return writeString( (const char *)&str[0], str.length() ); } /*********************************************************************************/ /* end of file */ /*********************************************************************************/
US2066.h ※<とか>などhtmlに変換した時に正しく変換されていない可能性が有るので、使わない事。
/****************************************************************************/ /* ssd1305 header */ /* Copyright (C) 2014 hamayan All Rights Reserved. */ /****************************************************************************/ #ifndef US2066_h #define US2066_h #include <wire.h> extern "C" { } //#define US2066_0_ADR 0x3C #define SO2002A_LINES 2 #define SO2002A_COLUMN 16 #define SO2002A_DISPLAY_ON 0x04 #define SO2002A_DISPLAY_OFF 0x00 #define SO2002A_CURSOR_ON 0x02 #define SO2002A_CURSOR_OFF 0x00 #define SO2002A_BLINK_ON 0x01 #define SO2002A_BLINK_OFF 0x00 class US2066 { private: unsigned char i2cAddress; int blkWrite(unsigned char addr, const unsigned char *dat, unsigned int len); int writeCommand(unsigned char t_command); int writeData(unsigned char t_data); public: US2066(); void init( unsigned char adr ); void clear( void ); void OnOff( unsigned char onoff ); void locate( int x, int y ); void contrast( unsigned char cnt ); int writeString( const char *str ); int writeString( const char *str, unsigned int len ); int writeString( String str ); }; #endif /*US2066_H*/ /****************************************************************************/ /* Copyright (C) 2014 hamayan All Rights Reserved. */ /****************************************************************************/
さてこれを移植するのですが、まずC++の記述スタイルはCには適用できない事が多い!
例えば関数のオーバーライド
int writeString( const char *str ); int writeString( const char *str, unsigned int len ); int writeString( String str );
なんてもろにダメですね!
Wire.endTransmission();
こう言った省略もダメです。
まぁ実際にコンパイル掛けてみると色々エラーや警告出ますんで、一つ一つ潰していくしかない。
クラスのメッソッドっぽく記述し直す必要があります。例えば
US2066 oled; oled.init( 10 );
みたいに書きたいとすれば、関数名のリストを作った構造体を用意して、それで呼び出す事になります。
結局以下の様になりました。
US2066.c ※<とか>などhtmlに変換した時に正しく変換されていない可能性が有るので、使わない事。
/*********************************************************************************/ /* US2066を使用したOLED SO1602AWGBの初期化と表示 */ /* designed by hamayan since 2015/04/21 */ /*********************************************************************************/ #include <US2066.h> #if !defined( _MULTITASK_H_ ) #define dly_tsk(tim) delay(tim) #define rot_rdq() #define loc_cpu() interrupts() #define unl_cpu() noInterrupts() #endif /*_MULTITASK_H_ */ static unsigned char i2cAddress; static int blkWrite(unsigned char addr, const unsigned char *dat, unsigned int len); static int writeCommand(unsigned char t_command); static int writeData(unsigned char t_data); /****************************************************************************/ /* I2C block Write */ /****************************************************************************/ static int blkWrite(unsigned char addr, const unsigned char *dat, unsigned int len) { Wire.beginTransmission(addr); Wire.write(dat,len); return Wire.endTransmission( true ); } /*************************************************************************/ /* write command */ /*************************************************************************/ static int writeCommand(unsigned char t_command) { unsigned char cmd[2]; cmd[0] = 0x00; cmd[1] = t_command; return blkWrite( i2cAddress, cmd, sizeof(cmd) ); } /*************************************************************************/ /* write data */ /*************************************************************************/ static int writeData(unsigned char t_data) { unsigned char dat[2]; dat[0] = 0x40; dat[1] = t_data; return blkWrite( i2cAddress, dat, sizeof(dat) ); } /*************************************************************************/ /* US2066初期化 */ /*************************************************************************/ static void init( unsigned char adr ) { i2cAddress = adr; /*I2C address set*/ dly_tsk(100); writeCommand( 0x01 ); //clear display dly_tsk(20); writeCommand( 0x02 ); //return home dly_tsk(2); writeCommand( 0x0f ); //send display on command dly_tsk(2); writeCommand( 0x01 ); //clear display dly_tsk(20); } /*************************************************************************/ /* clear display */ /*************************************************************************/ static void clear( void ) { dly_tsk(100); writeCommand( 0x01 ); //clear display dly_tsk(20); } /*************************************************************************/ /* display on/off */ /*************************************************************************/ static void OnOff( unsigned char onoff ) { writeCommand( onoff | (unsigned char)0x08 ); //display on/off,cursor on/off,blink on/off dly_tsk(20); } /*************************************************************************/ /* locate */ /*************************************************************************/ static void locate( int x, int y ) { int temp = x + (y * 20); if(temp >= 20) temp = (temp - 20) + 0x20; writeCommand( (unsigned char)temp | (unsigned char)0x80 ); //set ddram address dly_tsk(20); } /*************************************************************************/ /* set contrast */ /*************************************************************************/ static void contrast( unsigned char cnt ) { //コントラスト調整 writeCommand( 0x2a ); //RE=1 writeCommand( 0x79 ); //SD=1 writeCommand( 0x81 ); //contrast set writeCommand( cnt ); //contrast max writeCommand( 0x78 ); //SD=0 writeCommand( 0x28 ); //set character size is normal. dly_tsk(100); } /*************************************************************************/ /* write strings */ /*************************************************************************/ static int writeString( const char *str ) { unsigned char dat[1 * SO2002A_COLUMN + 1]; int len = strlen(str); dat[0] = 0x40; len = (len > sizeof(dat) - 1) ? sizeof(dat) - 1 : len; memcpy( &dat[1], str, len ); return blkWrite( i2cAddress, dat, len + 1 ); } /*************************************************************************/ /* メンバー関数のリスト */ /*************************************************************************/ const t_US2066_I2C oled = { init, clear, OnOff, locate, contrast, writeString, }; /*********************************************************************************/ /* end of file */ /*********************************************************************************/
US2066.h ※<とか>などhtmlに変換した時に正しく変換されていない可能性が有るので、使わない事。
/****************************************************************************/ /* ssd1305 header */ /* Copyright (C) 2014 hamayan All Rights Reserved. */ /****************************************************************************/ #ifndef US2066_h #define US2066_h #include <Wire.h> //#define US2066_0_ADR 0x3C #define SO2002A_LINES 2 #define SO2002A_COLUMN 16 #define SO2002A_DISPLAY_ON 0x04 #define SO2002A_DISPLAY_OFF 0x00 #define SO2002A_CURSOR_ON 0x02 #define SO2002A_CURSOR_OFF 0x00 #define SO2002A_BLINK_ON 0x01 #define SO2002A_BLINK_OFF 0x00 #if 0 class US2066 { private: unsigned char i2cAddress; int blkWrite(unsigned char addr, const unsigned char *dat, unsigned int len); int writeCommand(unsigned char t_command); int writeData(unsigned char t_data); public: US2066(); void init( unsigned char adr ); void clear( void ); void OnOff( unsigned char onoff ); void locate( int x, int y ); void contrast( unsigned char cnt ); int writeString( const char *str ); int writeString( const char *str, unsigned int len ); int writeString( String str ); }; #else typedef struct { void (*init)( unsigned char adr ); void (*clear)( void ); void (*OnOff)( unsigned char onoff ); void (*locate)( int x, int y ); void (*contrast)( unsigned char cnt ); int (*writeString)( const char *str ); } t_US2066_I2C; extern const t_US2066_I2C oled; #endif #endif /*US2066_H*/ /****************************************************************************/ /* Copyright (C) 2014 hamayan All Rights Reserved. */ /****************************************************************************/
※関数のオーバーライドの代替関数はめんどうくさいので止めちゃいました!
※BME280の移植をしていて気付いたのですが、long long型が使えない、、、
上記ソースを、Lazurite IDEが入っているフォルダーの中のlibraries以下に、ソースと同じ名前にしたフォルダーを生成し、そこに収納します。
この状態でIDEを起動するとこのライブラリが左端のライブラリリストに表示されますので、チェックします。
※I2CなのでWireにもチェックを入れます。
で、冒頭の表示プログラムが以下になります。
blue_led.c ※<とか>などhtmlに変換した時に正しく変換されていない可能性が有るので、使わない事。
#include "blue_led_ide.h" // Additional Header #include "mcu.h" #define BLUE_LED 26 #define US2066_ADDRESS (0x3C << 0) void setup(void) { digitalWrite(BLUE_LED,HIGH); pinMode(BLUE_LED,OUTPUT); Wire.begin(); I21MD=0; /*100khz setup*/ oled.init( US2066_ADDRESS ); oled.contrast( 0xff ); oled.clear(); oled.OnOff( SO2002A_DISPLAY_ON | SO2002A_CURSOR_OFF | SO2002A_BLINK_OFF ); oled.writeString( "Lazurite 920J" ); oled.locate( 0, 1 ); oled.writeString( " with OLED" ); } void loop(void) { digitalWrite(BLUE_LED,HIGH); delay(1000); digitalWrite(BLUE_LED,LOW); delay(1000); }
冒頭でmcu.hをインクルードしていますが、I2Cの速度を落とす為に必要です。
またsetupの先頭の
Wire.begin(); I21MD=0; /*100khz setup*/
も必要です。
※まぁこれくらいのコード量なら移植はそれほどでもですが、もっと複雑なコードだと厳しいですね。BME280の移植はそれなりに手間でしたよ。
※IDEのライブラリにBME280は登録されていますが、、、SPIで動かした時のライブラリで、I2Cではありませんでしたorz。
※いや、最大の問題はこんなライブラリの移植ではなく、フォーラムのレスポンスの悪さだったりして。
Lazurite 920Jを立ち上げてみる 其の6 #LAZURITE920J #ラピスセミコンダクタ [Lazurite]
外部から低消費電力状態を解除したい!
sleep関数は時間が来ると低消費電力状態から解除されますが、それ以外に外部からこの低消費電力状態を解除したい時も多いかと思います。
この様な場合、wait_event関数を使う様です。
以下にサンプルを上げておきます。
Arduino同様外部割り込み端子として2番と3番が使用できますが、今回は2番に押しボタンスイッチを接続しています。
#define BLUE_LED 26 #define RED_LED 20 #define YELLO_LED 25 bool eventFlag = false; void pin2Int( void ) { eventFlag = true; } void setup(void) { pinMode( BLUE_LED, OUTPUT ); pinMode( 2, INPUT_PULLUP ); attachInterrupt( 0, pin2Int, FALLING ); } void loop(void) { digitalWrite(BLUE_LED, LOW); delay( 500 ); digitalWrite(BLUE_LED, HIGH); eventFlag = false; wait_event( &eventFlag ); }
端子割り込みの中でbool型のフラグをtrueにしているだけの簡単なプログラムですね。
※低消費電力状態に入るとPower LEDは消灯されるが、青LEDは直前の端子の状態を維持している模様。
※では時間と外部割り込みの併用はできるのか?
先ほどのコードの wait_event( &eventFlag ); を sleep( 10 * 1000UL ); に変更してみましたが、外部割り込みでは起きない様です。うーん、、、一応sleepのマニュアルでは外部割り込みは有効と書いてあるので、低消費電力状態の解除方法が提供されていれば良いのですけれどね。
Lazurite 920Jを立ち上げてみる 其の5 #LAZURITE920J #ラピスセミコンダクタ [Lazurite]
どんくらい転送できるんだろう?
気になるのは「らずらいと姫」の解説ページに、送信時間は1時間当たり360秒(10%)に制限されるって書いてある点。
http://www.lapis-semi.com/lazurite-jp/lazurite/2473.html
そこで写真の様に2つのLazurite 920Jを並べています。ラベルを見て判るように、左が送信、右が受信ですね!
ええっと、送信データサイズが839543byte、送信時間合計が1452933ms、1048回エラー、送信数40279回。
受信データ数が8586536byte、受信数40124回。
あ、合わない、、、
1回のペイロードサイズが214byte、ヘッダーの11byteを考慮すると839543byteの全体サイズは882697byte。
ビットに直して1秒辺りのレートに換算すると、約4860bps。
無線の設定では100kbpsなので10%にも達していない結果。
※流れる時はやけに流れる(50kbpsとか60kbps)、流れない時はまったく流れない!ムラっけのある通信。
※あれぇ?これ、アンテナの向きとか距離(近過ぎる)とか影響されている感じがする。マルチパスとかも!
SubGHz.sendのマニュアルを読む限り、
http://www.lapis-semi.com/lazurite-jp/contents/reference/subghz_send.html
標準で250-11=239byteがデータのペイロードサイズに思えるが、実際にそのサイズを送信すると受信側は214byteしか受けていない。
なんで???
※試験やり直し
無線モジュール同士の距離とか、アンテナの向きを調整して比較的安定している状態にして再度約1時間の転送レートを求めてみた。
約50kbps以上は出ている計算になった。じゃあ「らずらいと姫」のあの解説は一体なんだったんだろう?
送信のデータ数と受信のデータ数とかカウントが一致しないのは、もう無線だからとしか言いようがないなぁ。
なので、過信せずに自分で上位プロトコルを実装した方がいいでしょう。少なくともシーケンス番号のチェックは必要に思える。
送信側プログラム
#define SUBGHZ_CH 36 #define SUBGHZ_PANID 0xABCD #define CLIENT_ID 0x405D #define SERVER_ID 0x406A #define BLUE_LED 26 #define TEST_PERIOD (60UL * 60UL * 1000UL) //#define TEST_PERIOD (10UL * 60UL * 1000UL) uint8_t tx_data[ 200 ]; unsigned long totalTime = 0; unsigned long startTime = 0; unsigned long totalBytes = 0; unsigned long totalCount = 0; unsigned long totalError = 0; void setup(void) { int i; SUBGHZ_MSG msg; Serial.begin(115200); msg = SubGHz.init(); if(msg != SUBGHZ_OK) { SubGHz.msgOut(msg); while(1) {} } msg = SubGHz.begin( SUBGHZ_CH, SUBGHZ_PANID, SUBGHZ_100KBPS, SUBGHZ_PWR_20MW ); if(msg != SUBGHZ_OK) { SubGHz.msgOut(msg); while(1) {} } msg = SubGHz.rxEnable(NULL); if(msg != SUBGHZ_OK) { SubGHz.msgOut(msg); while(1){ } } //dummy data for( i = 0; i < sizeof(tx_data); i++ ) { tx_data[ i ] = (uint8_t)i; } Serial.println("transmit rate test SEME!"); delay( 10000UL ); startTime = millis(); pinMode( BLUE_LED, OUTPUT ); digitalWrite( BLUE_LED, HIGH ); } void loop(void) { unsigned long baseTim,diffTime; SUBGHZ_MSG msg; if( (millis() - startTime) >= TEST_PERIOD ) { Serial.print( "transmit end:" ); Serial.print_long( totalBytes, DEC ); Serial.print( "bytes / " ); Serial.print_long( totalTime / 1000UL, DEC ); Serial.print( "ms " ); Serial.print_long( totalError, DEC ); Serial.print( "errors / " ); Serial.print_long( totalCount, DEC ); Serial.println( "counts" ); while( 1 ) {} } //transmit message digitalWrite( BLUE_LED, LOW ); baseTim = micros(); msg = SubGHz.send( SUBGHZ_PANID, SERVER_ID, tx_data, sizeof(tx_data), NULL ); // send data diffTime = micros() - baseTim; digitalWrite( BLUE_LED, HIGH ); if( msg == SUBGHZ_OK ) { totalTime += diffTime; totalBytes += sizeof(tx_data); } else { totalError++; SubGHz.msgOut(msg); } totalCount++; }
受信側プログラム
#define SUBGHZ_CH 36 #define SUBGHZ_PANID 0xABCD #define CLIENT_ID 0x405D #define SERVER_ID 0x406A #define BLUE_LED 26 uint8_t rx_data[ 512 ]; uint32_t last_recv_time = 0; unsigned long startTime = 0; unsigned long totalCount = 0; SUBGHZ_STATUS rx; void setup(void) { SUBGHZ_MSG msg; Serial.begin(115200); msg = SubGHz.init(); if(msg != SUBGHZ_OK) { SubGHz.msgOut(msg); while(1) {} } msg = SubGHz.begin(SUBGHZ_CH, SUBGHZ_PANID, SUBGHZ_100KBPS, SUBGHZ_PWR_20MW); if(msg != SUBGHZ_OK) { SubGHz.msgOut(msg); while(1) {} } msg = SubGHz.rxEnable(NULL); if(msg != SUBGHZ_OK) { SubGHz.msgOut(msg); while(1){ } } pinMode(BLUE_LED,OUTPUT); digitalWrite(BLUE_LED,HIGH); Serial.println("transmit rate test UKE!"); } void loop(void) { static unsigned long tolatLength = 0; short rx_len; rx_len = SubGHz.readData(rx_data,sizeof(rx_data)); if( rx_len > 0 ) { totalCount++; digitalWrite( BLUE_LED, LOW ); tolatLength += rx_len - 9; Serial.print( "recieve size:" ); Serial.print_long( tolatLength, DEC ); Serial.print( " count:" ); Serial.println_long( totalCount, DEC ); digitalWrite( BLUE_LED, HIGH ); } }
Lazurite 920Jを立ち上げてみる 其の4 #LAZURITE920J #ラピスセミコンダクタ [Lazurite]
Lazurite 920Jを立ち上げてみる 其の3 #LAZURITE920J #ラピスセミコンダクタ [Lazurite]
今日のお題は、Writerをなんとかできないのか?って話です。
できるか、できないのか?と言う話なら、こうやってネタにしているのだから出来ます。
やっていいのか、悪いのかは判りません。自己責任でお願いします。
わりとお得に実現できるので、複数台の対向でデバックとかの時に役に立つでしょう。
※と言うか、対向でデバックする時は2つ以上無いと効率悪くて仕方がないよね。
さて、普通にWriterを買うと、高いですよね。一個くらいは仕方ないとしても、それ以上はどうかと思います。
しかも接続がハーフピッチの10pinコネクタと、使い辛い。
Lazurite Mini writer Type B(Lazurite Miniシリーズ)
https://www.switch-science.com/catalog/2956/
しかしこのWriterに使用しているICはおなじみのFT232RLですんで、2000円以下のFT232RLを使ったUSB/シリアル変換基板は、マルツとか秋月とか、まぁ色々なショップに並んでいます。
マルツ
http://www.marutsu.co.jp/pc/i/52777/
秋月
http://akizukidenshi.com/catalog/g/gK-01977/
さて、ハードウエアから見ると、Writerで使用している接続は電源を除けば4本です。
TXD、RXD、TEST0、TEST1N
です。
それぞれFT232RLのどこに接続する?ですが、以下になります。
わりと簡単ですね。
ただ、配線だけなんとかすれば使える!と言う訳ではありません。FT232RLの設定をいくつか変更します。
FT232RLの設定はFTDIから無償で配布されているユーティリティで変更可能です。FT_Progを使用します。
http://www.ftdichip.com/Support/Utilities.htm#FT_PROG
FT232RLを使ったUSB/シリアル変換基板をPCに接続し、FT_Progを起動してデバイスのスキャンを行います。
ディスクリプション(USB String Descriptorをクリック)を以下の赤枠の様に変更します。
FT232RLのGPIO(Hardware SpecificからIO Controlsをクリック) を以下の赤枠の様に変更します。
変更したらデバイスにプログラムして、その後一旦USB/シリアル変換基板をPCから抜き挿しします。
この時、COMポート番号が変更されてしまうので注意してね。
あとはLazurite IDEから書き込みが出来るようになります。
現状、Lazurite 920Jの2.54mmピッチのDIP変換基板等が出ていないのであれですが、XBee ShieldとXBeeのDIP変換基板を使用する事でできますね。
できるか、できないのか?と言う話なら、こうやってネタにしているのだから出来ます。
やっていいのか、悪いのかは判りません。自己責任でお願いします。
わりとお得に実現できるので、複数台の対向でデバックとかの時に役に立つでしょう。
※と言うか、対向でデバックする時は2つ以上無いと効率悪くて仕方がないよね。
さて、普通にWriterを買うと、高いですよね。一個くらいは仕方ないとしても、それ以上はどうかと思います。
しかも接続がハーフピッチの10pinコネクタと、使い辛い。
Lazurite Mini writer Type B(Lazurite Miniシリーズ)
https://www.switch-science.com/catalog/2956/
しかしこのWriterに使用しているICはおなじみのFT232RLですんで、2000円以下のFT232RLを使ったUSB/シリアル変換基板は、マルツとか秋月とか、まぁ色々なショップに並んでいます。
マルツ
http://www.marutsu.co.jp/pc/i/52777/
秋月
http://akizukidenshi.com/catalog/g/gK-01977/
さて、ハードウエアから見ると、Writerで使用している接続は電源を除けば4本です。
TXD、RXD、TEST0、TEST1N
です。
それぞれFT232RLのどこに接続する?ですが、以下になります。
Lazurite Mini | FT232RL |
---|---|
VCC5V | 5Vまたは3.3V出力 |
GND | GND |
TXD(1) | RXD |
RXD(0) | TXD |
TEST0 | CBUS0 |
TEST1N | CBUS1 |
わりと簡単ですね。
ただ、配線だけなんとかすれば使える!と言う訳ではありません。FT232RLの設定をいくつか変更します。
FT232RLの設定はFTDIから無償で配布されているユーティリティで変更可能です。FT_Progを使用します。
http://www.ftdichip.com/Support/Utilities.htm#FT_PROG
FT232RLを使ったUSB/シリアル変換基板をPCに接続し、FT_Progを起動してデバイスのスキャンを行います。
ディスクリプション(USB String Descriptorをクリック)を以下の赤枠の様に変更します。
FT232RLのGPIO(Hardware SpecificからIO Controlsをクリック) を以下の赤枠の様に変更します。
変更したらデバイスにプログラムして、その後一旦USB/シリアル変換基板をPCから抜き挿しします。
この時、COMポート番号が変更されてしまうので注意してね。
あとはLazurite IDEから書き込みが出来るようになります。
現状、Lazurite 920Jの2.54mmピッチのDIP変換基板等が出ていないのであれですが、XBee ShieldとXBeeのDIP変換基板を使用する事でできますね。
Lazurite 920Jを立ち上げてみる 其の2 #LAZURITE920J #ラピスセミコンダクタ [Lazurite]
あれを動かしてみる。
「展示会で大活躍!920MHz無線お手軽電波ポリス★」
http://www.lapis-semi.com/lazurite-jp/lazurite/359.html
スイッチ等は実装が面倒なので、3秒くらいで自動的にチャネルが切り替わる様にした。
もちろん電波が出ていないと上手く行っているのか、いないんだか判らんので、もう一つのLazurite 920Jには参考例の送信のプログラムを書き込んである。
※リンク先のページでは、配線はI2Cとスイッチの読み込み以外にLCDのRESETへの接続が行われているが、実際にはRESETの操作をしていない。だからLCDのRESETはVCCに固定してしまった。
※SPIは要らないだろう!
※よくよく見たらMsTimer2も要らないじゃん。ラズライトひめぇ~
「展示会で大活躍!920MHz無線お手軽電波ポリス★」
http://www.lapis-semi.com/lazurite-jp/lazurite/359.html
スイッチ等は実装が面倒なので、3秒くらいで自動的にチャネルが切り替わる様にした。
もちろん電波が出ていないと上手く行っているのか、いないんだか判らんので、もう一つのLazurite 920Jには参考例の送信のプログラムを書き込んである。
※リンク先のページでは、配線はI2Cとスイッチの読み込み以外にLCDのRESETへの接続が行われているが、実際にはRESETの操作をしていない。だからLCDのRESETはVCCに固定してしまった。
※SPIは要らないだろう!
※よくよく見たらMsTimer2も要らないじゃん。ラズライトひめぇ~
Lazurite 920Jを立ち上げてみる 其の1 #LAZURITE920J #ラピスセミコンダクタ [Lazurite]
なんか、其の一しか書かない予感、、、
Lazurite FAQ
新掲示板
http://www.lapis-semi.com/lazurite-jp/forums/forum/lazurite-basicsub-ghz%e3%81%ae%e3%82%bd%e3%83%95%e3%83%88%e3%82%a6%e3%82%a8%e3%82%a2%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a62
すげぃリンクだなぁ、、
旧掲示板(こっちも読む必要有り!)
http://www.lapis-semi.com/lazurite-jp/forums/forum/lazurite-basicsub-ghz%e3%81%ae%e3%82%bd%e3%83%95%e3%83%88%e3%82%a6%e3%82%a8%e3%82%a2%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a6
Lazurite IDEの掲示板
http://www.lapis-semi.com/lazurite-jp/forums/forum/lazurite-ide%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a6
何気に重要な事が書いてあるんじゃないかい?
「らずらいと姫の挑戦日記」
http://www.lapis-semi.com/lazurite-jp/%E3%82%89%E3%81%9A%E3%82%89%E3%81%84%E3%81%A8%E5%A7%AB%E3%81%AE%E6%8C%91%E6%88%A6%E6%97%A5%E8%A8%98/9912.html
〇ハーフピッチコネクタの選択
シングルライン10pinレセプタクルならこれでいいかな?最安。ただし、ヘッダー部の高さが3.4mmで、ここが他のコネクタと一致しない。@30円
http://akizukidenshi.com/catalog/g/gC-08695/
Digi-Keyならこれになるが、ややお高め@170円
http://www.digikey.jp/product-search/ja?keywords=S9008E-10-ND
デュアルライン2×5極のピンソケットならこれ。@98円
http://www.digikey.jp/product-detail/ja/sullins-connector-solutions/GRPB052VWVN-RC/S9015E-05-ND/1786455
デュアルライン2×5極のレセプタクルならこれ。@89円
http://www.digikey.jp/product-search/ja?keywords=609-3754-nd
※廣杉にも有った!高さが3.4mmなので秋月の物に合わせられる。
http://hirosugi.co.jp/products/N/FSS-70.html#bx2
モノタロウで買える
https://www.monotaro.com/p/1129/5357/ @56円
https://www.monotaro.com/p/1129/5305/ @54円
https://www.monotaro.com/p/1155/5513/ ちがう!
https://www.monotaro.com/g/01213751/ こっち!@28円
〇純正開発ツール(ハードウエア)
Lazurite 920J
http://www.lapis-semi.com/lazurite-jp/products/lazurite-920j
基板上のLDO(BH33PB1WHFV)は3.3V/150mA、入力最大5.5V、最低1.7V
端子配置図
表にしてみるか!
U4
U3
920Mhz用の外付けアンテナがリストされているが、これらを組み合わせた場合の技適はどうなんだろう?
XBeeシールド
http://www.lapis-semi.com/lazurite-jp/products/lazurite-920j-xbee-shield
XBeeシールド上でWriterからの5V電源がXBeeのVCC(3.3V電源)端子に接続されてしまっているが、実際にUSBからの5VがVCC5Vに出てしまっているので、なんと嫌らしい、、、
「3.3V以下で使用すると無線の電波強度は弱くなります。」だそうだ、、、
Writer
http://www.lapis-semi.com/lazurite-jp/products/lazurite-mini-writer-type-b
WriterのVID、PIDはFTDIのそれから変更はされていない。
Lazurite Basic(参考用)
http://www.lapis-semi.com/lazurite-jp/products/lazurite-basic
Lazurite 920JとXBeeシールドを組み合わせるとこんな(-ω-;)ウーンな感じ。
〇Lazureite IDEの入手とインストール
http://www.lapis-semi.com/lazurite-jp/contents/InstallGuide.html
説明の通りに進めばOK!
〇Lazureite IDEの使用方法
※最大の問題は、このIDEがC++をサポートしていない事。
http://www.lapis-semi.com/lazurite-jp/contents/IDE/How_to_use.html
このBasic用のページの説明で基本的には構わないが、ときおり出る脅し文句は一体何だろう?無視しているが。
また、ツール→オプション→LAZURITE mini seriasもクリックが必要。
書き込みが終わると、青いLEDが1秒で点灯、1秒で消灯を繰り返す。
書き込み中は黄色LEDのみ点灯から青LEDがチラチラ点灯。多分書き込みが終了すると電源LEDらしい赤LEDが点灯する。
シリアルモニターは、改行コードを受信しないと表示しないみたいだ。トホホ
〇コンパイラ使用上の注意点
〇標準ライブラリについて
標準ライブラリリファレンス
http://www.lapis-semi.com/lazurite-jp/contents/reference/Lazurite_Reference.html
▼C言語でArduinoのライブラリっぽく作っていいるので、大分無理が有る感じ。
例えば
Serial.print( 100,DEC );
は記述できず、同じ事は以下になる。
Serial.print_long( (long)100,DEC );
ようするにオーバーライドができない。だってC言語だから。
▼C99に部分対応で基本的にC89なので、コードの途中に変数の宣言ができない。つらい、、、
▼「Serial.print」とかクラスメソッドの様に見えているが、実際は静的に生成された構造体の関数ポインタを呼び出しているとの事。
〇スタック領域
RAM領域は全体で6kbyte有る!。
標準で512byteの領域をスタックに割り当てている。そこで大域変数に約2kbyteの領域を確保したmap出力を見てみる。
スタック領域はRAMの底に配置されるのではなく、先頭に持ってこられているが、それ以外のデータ領域はスタック領域の後に配置される。
キャプチャのグレーのところにSTACKと書かれており、サイズが512になっている。その上のGAPが事実上のRAM領域の余りになっており、なんで1244.0と小数点が付くのか判らないが1244byteは余っているらしい。
なのでスタックの伸長による暴走の懸念は、まずこのmap出力を見ると良いかも。
〇通信
▼ブロードキャストする為にはPANID=0xFFFF、相手先アドレス=0xFFFFでいいのか?
▼自機16bitアドレスは、モジュールの半田面に手書き(笑)で記載されている。本来は64bitアドレスも在るのだと思う。
▼モジュールに中継機能は、無いんだろうなぁ、、、
▼ZigBeeと異なり無線チャネルは自力でどうぞ!なので、実運用を想定するなら事前に周囲の無線環境を調べる何かが必要。だからこんなの作ったのか(笑)。
http://www.lapis-semi.com/lazurite-jp/lazurite/359.html
▼チャネルと周波数とビットレートの関係
http://www.lapis-semi.com/lazurite-jp/contents/IEEE802154/about_frequency.html
XBee Shieldの回路図が見難くて辛いので、清書してみた。
Lazurite FAQ
新掲示板
http://www.lapis-semi.com/lazurite-jp/forums/forum/lazurite-basicsub-ghz%e3%81%ae%e3%82%bd%e3%83%95%e3%83%88%e3%82%a6%e3%82%a8%e3%82%a2%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a62
すげぃリンクだなぁ、、
旧掲示板(こっちも読む必要有り!)
http://www.lapis-semi.com/lazurite-jp/forums/forum/lazurite-basicsub-ghz%e3%81%ae%e3%82%bd%e3%83%95%e3%83%88%e3%82%a6%e3%82%a8%e3%82%a2%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a6
Lazurite IDEの掲示板
http://www.lapis-semi.com/lazurite-jp/forums/forum/lazurite-ide%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a6
何気に重要な事が書いてあるんじゃないかい?
「らずらいと姫の挑戦日記」
http://www.lapis-semi.com/lazurite-jp/%E3%82%89%E3%81%9A%E3%82%89%E3%81%84%E3%81%A8%E5%A7%AB%E3%81%AE%E6%8C%91%E6%88%A6%E6%97%A5%E8%A8%98/9912.html
〇ハーフピッチコネクタの選択
シングルライン10pinレセプタクルならこれでいいかな?最安。ただし、ヘッダー部の高さが3.4mmで、ここが他のコネクタと一致しない。@30円
http://akizukidenshi.com/catalog/g/gC-08695/
Digi-Keyならこれになるが、ややお高め@170円
http://www.digikey.jp/product-search/ja?keywords=S9008E-10-ND
デュアルライン2×5極のピンソケットならこれ。@98円
http://www.digikey.jp/product-detail/ja/sullins-connector-solutions/GRPB052VWVN-RC/S9015E-05-ND/1786455
デュアルライン2×5極のレセプタクルならこれ。@89円
http://www.digikey.jp/product-search/ja?keywords=609-3754-nd
※廣杉にも有った!高さが3.4mmなので秋月の物に合わせられる。
http://hirosugi.co.jp/products/N/FSS-70.html#bx2
モノタロウで買える
https://www.monotaro.com/p/1129/5357/ @56円
https://www.monotaro.com/p/1129/5305/ @54円
https://www.monotaro.com/g/01213751/ こっち!@28円
〇純正開発ツール(ハードウエア)
Lazurite 920J
http://www.lapis-semi.com/lazurite-jp/products/lazurite-920j
基板上のLDO(BH33PB1WHFV)は3.3V/150mA、入力最大5.5V、最低1.7V
端子配置図
表にしてみるか!
U4
Pin number | Pin name | Arduino number |
---|---|---|
1 | LDO3V | LDO3V |
2 | GND | GND |
3 | P20/A4 | 14 |
4 | P21/A5 | 15 |
5 | P22/A6 | 16 |
6 | P03/A11 | 17 |
7 | P34/A0/SDA | 18 |
8 | P35/A1/SCL | 19 |
9 | P53 | 3 |
10 | P50 | 2 |
U3
Pin number | Pin name | Arduino number |
---|---|---|
1 | P42 | 4 |
2 | P43 | 5 |
3 | P32 | 6 |
4 | P33 | 7 |
5 | P57 | 8 |
6 | P52 | 9 |
7 | P37/SS | 10 |
8 | P44/MOSI | 11 |
9 | P45/MISO | 12 |
10 | P36/SCK | 13 |
920Mhz用の外付けアンテナがリストされているが、これらを組み合わせた場合の技適はどうなんだろう?
XBeeシールド
http://www.lapis-semi.com/lazurite-jp/products/lazurite-920j-xbee-shield
XBeeシールド上でWriterからの5V電源がXBeeのVCC(3.3V電源)端子に接続されてしまっているが、実際にUSBからの5VがVCC5Vに出てしまっているので、なんと嫌らしい、、、
「3.3V以下で使用すると無線の電波強度は弱くなります。」だそうだ、、、
Writer
http://www.lapis-semi.com/lazurite-jp/products/lazurite-mini-writer-type-b
WriterのVID、PIDはFTDIのそれから変更はされていない。
Lazurite Basic(参考用)
http://www.lapis-semi.com/lazurite-jp/products/lazurite-basic
Lazurite 920JとXBeeシールドを組み合わせるとこんな(-ω-;)ウーンな感じ。
〇Lazureite IDEの入手とインストール
http://www.lapis-semi.com/lazurite-jp/contents/InstallGuide.html
説明の通りに進めばOK!
〇Lazureite IDEの使用方法
※最大の問題は、このIDEがC++をサポートしていない事。
http://www.lapis-semi.com/lazurite-jp/contents/IDE/How_to_use.html
このBasic用のページの説明で基本的には構わないが、ときおり出る脅し文句は一体何だろう?無視しているが。
また、ツール→オプション→LAZURITE mini seriasもクリックが必要。
書き込みが終わると、青いLEDが1秒で点灯、1秒で消灯を繰り返す。
書き込み中は黄色LEDのみ点灯から青LEDがチラチラ点灯。多分書き込みが終了すると電源LEDらしい赤LEDが点灯する。
シリアルモニターは、改行コードを受信しないと表示しないみたいだ。トホホ
〇コンパイラ使用上の注意点
〇標準ライブラリについて
標準ライブラリリファレンス
http://www.lapis-semi.com/lazurite-jp/contents/reference/Lazurite_Reference.html
▼C言語でArduinoのライブラリっぽく作っていいるので、大分無理が有る感じ。
例えば
Serial.print( 100,DEC );
は記述できず、同じ事は以下になる。
Serial.print_long( (long)100,DEC );
ようするにオーバーライドができない。だってC言語だから。
▼C99に部分対応で基本的にC89なので、コードの途中に変数の宣言ができない。つらい、、、
▼「Serial.print」とかクラスメソッドの様に見えているが、実際は静的に生成された構造体の関数ポインタを呼び出しているとの事。
〇スタック領域
RAM領域は全体で6kbyte有る!。
標準で512byteの領域をスタックに割り当てている。そこで大域変数に約2kbyteの領域を確保したmap出力を見てみる。
スタック領域はRAMの底に配置されるのではなく、先頭に持ってこられているが、それ以外のデータ領域はスタック領域の後に配置される。
キャプチャのグレーのところにSTACKと書かれており、サイズが512になっている。その上のGAPが事実上のRAM領域の余りになっており、なんで1244.0と小数点が付くのか判らないが1244byteは余っているらしい。
なのでスタックの伸長による暴走の懸念は、まずこのmap出力を見ると良いかも。
〇通信
▼ブロードキャストする為にはPANID=0xFFFF、相手先アドレス=0xFFFFでいいのか?
▼自機16bitアドレスは、モジュールの半田面に手書き(笑)で記載されている。本来は64bitアドレスも在るのだと思う。
▼モジュールに中継機能は、無いんだろうなぁ、、、
▼ZigBeeと異なり無線チャネルは自力でどうぞ!なので、実運用を想定するなら事前に周囲の無線環境を調べる何かが必要。だからこんなの作ったのか(笑)。
http://www.lapis-semi.com/lazurite-jp/lazurite/359.html
▼チャネルと周波数とビットレートの関係
http://www.lapis-semi.com/lazurite-jp/contents/IEEE802154/about_frequency.html
XBee Shieldの回路図が見難くて辛いので、清書してみた。