- 指向性を持たない
- 消費電力が少ない
- 機器間に障害物があっても通信が可能
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へ |