ここでは NXT と PC 間の Bluetooth 通信の方法を示しますが、NXT同士の Bluetooth 通信については、基礎編の10.Bluetooth通信で説明しています。
1.Bluetooth 通信プログラム
以下に前々回の説明したPD制御によるライントレースのプログラムに、Bluetooth通信機能を加えたプログラム示します。
datalogging.c
#include "kernel.h"
#include "kernel_id.h"
#include "ecrobot_interface.h"
#define PORT_LIGHT NXT_PORT_S3 /* 入出力ポートの定義 */
#define PORT_TOUCH NXT_PORT_S2
#define L_MOTOR NXT_PORT_B
#define R_MOTOR NXT_PORT_C
#define BLACK 700
#define WHITE 500
#define BT_PASS_KEY "1234" /* bluetoothパスキー */
DeclareTask(Task1); /* Task1を宣言 */
void ecrobot_device_initialize(){ /* OSEK起動時の処理 */
nxt_motor_set_speed(L_MOTOR,0,0);
nxt_motor_set_speed(R_MOTOR,0,0);
ecrobot_set_light_sensor_active(PORT_LIGHT);
//Bluetoothデバイス設定 デバイス名を新たに設定したい場合のみ、以下のコメントアウトをはずす。
//ecrobot_set_bt_device_name("NXT31");
ecrobot_init_bt_slave(BT_PASS_KEY); /* スレーブとして初期化 */
}
void ecrobot_device_terminate(){ /* OSEK終了時の処理 */
nxt_motor_set_speed(L_MOTOR,0,0);
nxt_motor_set_speed(R_MOTOR,0,0);
ecrobot_set_light_sensor_inactive(PORT_LIGHT);
}
void user_1ms_isr_type2(void){}
void sound_beep(){ /* ビープ音を鳴らすユーザ関数 */
ecrobot_sound_tone(600, 2, 50);
systick_wait_ms(20);
ecrobot_sound_tone(500, 5, 50);
systick_wait_ms(50);
}
TASK(Task1)
{
int speed=70;
float Kp, Kd;
int black,white,gray,light;
int err, err_prev ;
float turn;
float turn_p, turn_d;
//PIDゲイン
//限界感度を求める場合は Kp の値を少しづつ大きくしていく
Kp = 0.4;
Kd = 1.6;
black = BLACK;
white = WHITE;
gray = (black + white) / 2;
display_clear(0);
display_goto_xy(0, 1);
display_string("PUSH START");
display_update();
while(ecrobot_get_touch_sensor(PORT_TOUCH) == 0){ /* TSが押されたらスタート */
systick_wait_ms(10);
}
systick_wait_ms(500); /* 500msec待つ */
err_prev = ecrobot_get_light_sensor(PORT_LIGHT) - gray;
while(ecrobot_get_touch_sensor(PORT_TOUCH) == 0){ // タッチセンサが押されたらストップ
light = ecrobot_get_light_sensor(PORT_LIGHT);
err = light - gray;
//err_sum += err;
turn_p = Kp * err ;
turn_d = Kd * (err - err_prev);
turn = turn_p + turn_d ;
err_prev = err;
nxt_motor_set_speed( L_MOTOR,speed - turn, 1 );
nxt_motor_set_speed( R_MOTOR,speed + turn, 1 );
ecrobot_bt_data_logger((int)turn_p , (int)turn_d ); /* turn 値の P成分とD成分を送信*/
systick_wait_ms(10); /* 10msec待つ */
}
nxt_motor_set_speed(L_MOTOR,0,1);
nxt_motor_set_speed(R_MOTOR,0,1);
systick_wait_ms(1000); /* 1秒待つ */
TerminateTask(); /* 処理終了 */
}
|
上記のプログラムでは、デバイスの初期化 ecrobot_device_initialize で、スレーブとしての初期化を行い、Main Task 中の走行制御の無限ループの中で 10msec 周期で、ターン値とその微分成分を送信しています。
ecrobot_bt_data_logger関数でユーザが明示的に送信できる変数は2つだけですが、送信時間、バッテリ電圧、モータ回転速度、各ポートのセンサデータが送信されます。