- 指向性を持たない
- 消費電力が少ない
- 機器間に障害物があっても通信が可能
Bluetoothには様々なバージョンや規格があり、NXTのBluetoothはVer.2.0でシリアル通信機能を有しています。 また、Bluetoothの通信距離・電波強度を定める規格をクラスと呼んでおり、NXTに実装されている Bluetooth は10mまでの通信を保障する Class2 です。NXT はは PC との間で Bluetooth 通信することも可能ですが、ここではNXT同士でBluetooth通信を行うプログラムについて学習します。なお、NXTのマスター機は1台のスレーブ機としか通信できません。
なお、以下のプログラムでは、スレーブ機を受信側、マスター機を送信側としていますが、スレーブとマスターの送受信の関係を反対にすることも可能ですし、送受信の両方を行うことも可能です。
1.マスター側のプログラム
以下に、1から10までの整数を1秒おきに送信するマスター側のプログラムについて説明します。
次のプログラムを blue_master.c として作成し、ビルドしたものをマスター側のNXTへダウンロードしてください。
blue_master.c で用いた Bluetooth 通信の API について説明します。
※スレーブ側NXTのアドレスの調べ方
次のプログラムを blue_master.c として作成し、ビルドしたものをマスター側のNXTへダウンロードしてください。
blue_master.c
#include "kernel.h" #include "kernel_id.h" #include "ecrobot_interface.h" // NXT Bluetooth 設定 // bluetoothパスキー #define BT_PASS_KEY "1234" // bluetooth送信パケットの大きさ #define BT_SNV_BUF_SIZE 32 // 送信データのリセット値 #define COUNT 10 // スレーブNXTのデバイスアドレス const U8 BT_ADDR[7] = {0x00,0x16,0x53,0x01,0x85,0x83,0x00}; // bluetooth送信パケットァの宣言、 U8 は unsinged char (1バイト) U8 bt_send_buf[BT_SNV_BUF_SIZE]; DeclareCounter(SysTimerCnt); DeclareTask(Task1); void ecrobot_device_initialize(){ //Bluetoothデバイス設定 デバイス名を新たに設定したい場合のみ、以下のコメントアウトをはずす。 //ecrobot_set_bt_device_name("NXT51"); //スレーブのアドレスを指定して、マスターとして初期化 ecrobot_init_bt_master(BT_ADDR, BT_PASS_KEY); } void ecrobot_device_terminate(){ // bluetooth通信終了 ecrobot_term_bt_connection(); } void user_1ms_isr_type2(void){} TASK(Task1) { int i=0; unsigned int send_len; while(1){ if( i < COUNT ){ bt_send_buf[0] = i; // bt_send_buf[0] には i(int 型)の下位1バイトが代入さえる send_len = ecrobot_send_bt_packet(bt_send_buf, BT_SNV_BUF_SIZE);//buf のデータを送信 display_goto_xy(0,1); display_string("Sending "); display_goto_xy(8,1); display_int(i, 2); display_update(); i++; }else{ i = 0; } systick_wait_ms(1000); // 1秒待つ } TerminateTask(); } |
blue_master.c で用いた Bluetooth 通信の API について説明します。
ecrobot_init_bt_master(BT_ADDR, BT_PASS_KEY);
ecrobot_term_bt_connection();
ecrobot_send_bt_packet(bt_send_buf, BT_SNV_BUF_SIZE);
NXTをマスターとして初期化します。
第一の引数は、スレーブ側のNXTのアドレスです。アドレスを調べる方法については下の※で示します。
第二の引数は、通信を確立するためのパスキーです。(マスター側とスレーブ側で同じ値を保持する必要があります。)
この関数は、NXT起動時の処理を記述するフック関数内に記述します。
第一の引数は、スレーブ側のNXTのアドレスです。アドレスを調べる方法については下の※で示します。
第二の引数は、通信を確立するためのパスキーです。(マスター側とスレーブ側で同じ値を保持する必要があります。)
この関数は、NXT起動時の処理を記述するフック関数内に記述します。
ecrobot_term_bt_connection();
bluetooth通信を終了するAPIです。
この関数は、NXT終了時の処理を記述するフック関数内に記述します。
この関数は、NXT終了時の処理を記述するフック関数内に記述します。
ecrobot_send_bt_packet(bt_send_buf, BT_SNV_BUF_SIZE);
データを送信するAPIです。戻り値は送信したデータのバイト数となります。
第一の引数は、送信バッファの名前(配列名)を指定します。
第二の引数は、送信バッファのサイズ(バイト数)を指定します。最大値は256[byte]です。
第一の引数は、送信バッファの名前(配列名)を指定します。
第二の引数は、送信バッファのサイズ(バイト数)を指定します。最大値は256[byte]です。
※スレーブ側NXTのアドレスの調べ方
- スレーブ側NXTにスレーブ用プログラムをダウンロードします。
- スレーブ側プログラムを起動し、OSEKの画面にします。
- 画面上の BT_ADDR: の下に表示されている14桁の数字がbluetooth通信用のアドレスですので、この文字を控えます。
- たとえば、スレーブのBT_ADDRが「00165304F1B300」と表示された場合、マスター用のプログラム中の BT_ADDR に {0x00,0x16,0x53,0x04,0xF1,0xB3,0x00}を代入します。
2.スレーブ側のプログラム
スレーブ機の設定を行って、受信したデータを画面に表示するプログラムについて説明します。
次のプログラム blue_slave.c として作成します。
blue_slave.c で新たに用いたAPIについて解説します。
このプログラムでは受信処理を 10msec 周期で行っていますが、受信したデータはハード的に受信バッファに取り込まれているため、バッファがいっぱいにならない限り受信データを取りこぼすことはありません。
送信データを受信側が取りこぼさないためには、一般に送信側の動作周期(systeick_wait_ms(10))より、 受信側の動作周期を短くする(同じでもよい)しておく必要があります。
次のプログラム blue_slave.c として作成します。
blue_slave.c
#include "kernel.h" #include "kernel_id.h" #include "ecrobot_interface.h" // NXT Bluetooth 設定 // bluetoothパスキー #define BT_PASS_KEY "1234" // bluetooth受信パケットの大きさ #define BT_RCV_BUF_SIZE 32 #define COUNT 10 // bluetooth受信パケットの宣言 U8 は unsigned 8bit(1バイト) U8 bt_receive_buf[BT_RCV_BUF_SIZE]; DeclareTask(Task1); void ecrobot_device_initialize(){ //Bluetoothデバイス設定 デバイス名を新たに設定したい場合のみ、以下のコメントアウトをはずす。 //ecrobot_set_bt_device_name("NXT51"); // スレーブとして初期化 ecrobot_init_bt_slave(BT_PASS_KEY); } void ecrobot_device_terminate(){ // bluetooth通信終了 ecrobot_term_bt_connection(); } void user_1ms_isr_type2(void){} TASK(Task1) { int i=0; unsigned int read_len; while(1){ // 受信データを buf に代入 read_len = ecrobot_read_bt_packet(bt_receive_buf, BT_RCV_BUF_SIZE); if( read_len != 0){ //データ更新されたときの実行 i = bt_receive_buf[0]; display_clear(0); display_goto_xy(0,1); display_string("Receive "); display_goto_xy(8,1); display_int(i, 2); display_update(); } i = 0; systick_wait_ms(10); } TerminateTask(); } |
blue_slave.c で新たに用いたAPIについて解説します。
ecrobot_init_bt_slave(BT_PASS_KEY);
ecrobot_read_bt_packet(bt_receive_buf, BT_RCV_BUF_SIZE);
NXTをスレーブデバイスとして初期化します
引数には、パスキーを指定します。パスキーとは、通信する双方で有する合言葉のようなものです。4桁以上の文字を自由に指定してください。"1234"がディフォルト値です。
この関数は、NXT起動時の処理を記述するフック関数(デバイス初期化関数)内に記述します。
引数には、パスキーを指定します。パスキーとは、通信する双方で有する合言葉のようなものです。4桁以上の文字を自由に指定してください。"1234"がディフォルト値です。
この関数は、NXT起動時の処理を記述するフック関数(デバイス初期化関数)内に記述します。
ecrobot_read_bt_packet(bt_receive_buf, BT_RCV_BUF_SIZE);
データを受信するAPIです。戻り値は受信したデータのバイト数です。
第一の引数は、受信バッファの名前を指定します。
第二の引数は、受信バッファのサイズ(バイト数)を指定します。最大値は256byteです。
第一の引数は、受信バッファの名前を指定します。
第二の引数は、受信バッファのサイズ(バイト数)を指定します。最大値は256byteです。
このプログラムでは受信処理を 10msec 周期で行っていますが、受信したデータはハード的に受信バッファに取り込まれているため、バッファがいっぱいにならない限り受信データを取りこぼすことはありません。
送信データを受信側が取りこぼさないためには、一般に送信側の動作周期(systeick_wait_ms(10))より、 受信側の動作周期を短くする(同じでもよい)しておく必要があります。
3.動作のさせ方
Bluetooth通信プログラムを動作させるときは、必ずスレーブ側NXTを先に起動させOSEK画面が立ち上がった後に、マスター側のプログラムを起動させ、両方のNXTのOSEKメニュー画面で[R]の右横に[BT]と表示されるまで待ちます。通常、4~5秒で通信が確立します。
[BT]の表示を確認出来たら、両方のプログラムを走らせます。
ここではマスターからスレーブにデータを送信しましたが、逆にスレーブでパケットを受信しマスターで受信することも可能です。マスター・スレーブの双方で送受信を行うことにより、双方向通信が可能になります。
[BT]の表示を確認出来たら、両方のプログラムを走らせます。
ここではマスターからスレーブにデータを送信しましたが、逆にスレーブでパケットを受信しマスターで受信することも可能です。マスター・スレーブの双方で送受信を行うことにより、双方向通信が可能になります。
4.補足
今回は通信用の API に ecrobot_read_bt_packet(), ecrobot_send_bt_packet() を用いましたが、nxtOSEK ver2.15以降は、
これと別に ecrobot_read_bt(), ecrobot_send_bt()というAPIが用意されています。
このAPIの詳細は、ECRobot C APIレファレンスのBluetooth 通信API を参照して下さい。
Bluetooth通信でパソコンとデータの送受信を行う場合は、こちらの(_packetの無い)APIを使う必要があります。
read_len = ecrobot_read_bt(buf, 0, BT_RCV_BUF_SIZE); //戻り値は受信したデータのバイト数 send_len = ecrobot_send_bt(buf, 0, BT_SND_BUF_SIZE); //戻り値は送信したデータのバイト数
このAPIの詳細は、ECRobot C APIレファレンスのBluetooth 通信API を参照して下さい。
Bluetooth通信でパソコンとデータの送受信を行う場合は、こちらの(_packetの無い)APIを使う必要があります。
5.課題
- スレーブ側のアドレスを確認し、サンプルプログラムの動作を確認せよ。
- それぞれのNXTにスレーブ側のプログラムをアップロードし、OSEK画面で Bluetooth の通信アドレス(BTアドレス)を確認する。
- マスター側のプログラムにスレーブ側(相手側)のBTアドレスを入れて、マスター側プログラムをアップロードする。
- NXTの一方でスレーブのプログラムを、他方でマスター側のプログラムを起動し、BT通信の確立・データの送受信ができることを確認する。
- 3.をマスター機とスレーブ機を入れ替えて実施する。
- マスター側のタッチセンサが押されているときスレーブ側の走行体が前進、押されていないとき停止するプログラムを作成せよ。
このとき送信側の周期(待ち時間)が大きいとその分反応が遅れるで、待ち時間は適切な値とすること。
6. チャレンジ課題
超音波センサの課題で実現した動作をマスター側に実装し、スレーブ側の走行体がそれに同調して前後するようにせよ。
ヒント:マスター機の送信バッファ(bt_send_buf[])に、左右の指定速度値または、命令(前進・後退・停止)に対応する数値を入れてスレーブ機に送り、スレーブ機はそのデータに従って動作するようにする。
9.その他のセンサーの使用 | TOPへ |