057836 ランダム
 HOME | DIARY | PROFILE 【フォローする】 【ログイン】

プログラミング1

プログラミング1

【毎日開催】
15記事にいいね!で1ポイント
10秒滞在
いいね! --/--
おめでとうございます!
ミッションを達成しました。
※「ポイントを獲得する」ボタンを押すと広告が表示されます。
x

PR

Keyword Search

▼キーワード検索

Rakuten Card

Profile

tanaka3n

tanaka3n

Calendar

Favorite Blog

まだ登録されていません

Comments

シャネル 財布@ hlqjdpvjxiu@gmail.com 今日は~^^またブログ覗かせていただき…
ジバンシィ 財布@ nfdijnv@gmail.com はじめまして。突然のコメント。失礼しま…
バレンシアガ バッグ@ zztmthrejg@gmail.com お世話になります。とても良い記事ですね…
ヴィトン 財布@ yasrbbw@gmail.com 匿名なのに、私には誰だか分かる・・・(^_…
バーバリー シャツ レディース@ emvklzqxd@gmail.com こんにちは、またブログ覗かせていただき…

Freepage List

Headline News

October 15, 2008
XML
カテゴリ:プログラミング
 マインドストームNXTでのSPPを通したコマンドの送受信について書きたいと思います。
マインドストームのコマンド形式はLEGO Mindstorm Bluetooth Developer Kitにある資料に書かれています。コマンドはバイナリ形式で最大64バイト長の命令になっています。
 たとえばモータの回転などの出力では0x00 0x04 0x00 0x14 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 などと13バイトで記述します。ただし、コマンドをBluetoothで送信する場合にはコマンドの先頭にメッセージの長さを表す2バイトがつき、全体では15バイトとなります。数値を表すワード長データはリトルエンディアン(Lowバイト Highバイトの順に並ぶ)ので、前述の例では0x0d 0x00が先頭につくことになります。なお、メッセージのバイト長とはバイト長を表す2バイトのデータを除いたものであることに注意が必要です。
 NXTからの応答メッセージのバイト数はコマンドにより決まっているので必要なバイト数だけを受信できるようにプログラムを作成します。なお、通信プログラムではどのタイミングでデータエラーとなっても回復が可能であるように、タイムアウト処理やエラー処理をしっかり記述しなければなりません。

 プログラムを次に示します。

#define BAUD_RATE 9600
#define BYTE_SIZE 8
#define PARITY NOPARITY
#define STOP_BIT TRUE
#define F_PARITY ONESTOPBIT

bool init(){
hCommT = ::CreateFile(
_T("COM3"),
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);

if(hCommT == INVALID_HANDLE_VALUE){

hCommT = ::CreateFile(
_T("COM5"),
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if(hCommT == INVALID_HANDLE_VALUE){
return false;
}

}
// 通信属性を設定する
DCB dcb;
GetCommState(hCommT, &dcb); /* DCB を取得 */
dcb.BaudRate = BAUD_RATE;
dcb.ByteSize = BYTE_SIZE;
dcb.Parity = PARITY;
dcb.fParity = STOP_BIT;
dcb.StopBits = F_PARITY;
SetCommState(hCommT, &dcb); /* DCB を設定 */

//タイムアウトを設定する。
_COMMTIMEOUTS CommTimeouts;
CommTimeouts.ReadIntervalTimeout=0;
CommTimeouts.ReadTotalTimeoutConstant=500;
CommTimeouts.ReadTotalTimeoutMultiplier=10;
CommTimeouts.WriteTotalTimeoutConstant=500;
CommTimeouts.WriteTotalTimeoutMultiplier=10;
SetCommTimeouts(hCommT,&CommTimeouts);

return true;
};


unsigned long readCom2(unsigned char* sBuf,int cn){
DWORD dwErrors; /* エラー情報 */
COMSTAT ComStat; /* デバイスの状態 */
DWORD dwCount; /* 受信データのバイト数 */
DWORD dwRead; /* ポートから読み出したバイト数 */

ClearCommError(hCommT, &dwErrors, &ComStat);
dwCount = ComStat.cbInQue;


ReadFile(hCommT, sBuf, cn, &dwRead, NULL);

return dwRead;
};

void writeCom(unsigned char* sBuf, int cn){
DWORD nn;

WriteFile(hCommT,sBuf,(DWORD)cn,&nn,NULL);
};

void drive_m(int portnum,int motorpower){

unsigned char tele[64];
unsigned char resu[64];
unsigned long cn;

tele[0]=13; // Length of LSB
tele[1]=0x00; // Length of MSB
tele[2]=0x00; // Direct Command,with response
tele[3]=0x04; // Command
tele[4]=portnum; // Output Port
tele[5]=(char)motorpower; // Power set point
tele[6]=0x01; // Mode byte:MotorON=0x01,Break=0x02,Reguratied=0x04
tele[7]=0x00; // Regulation Mode: IDLE=0x00,Speed=0x01,Sync=0x02
tele[8]=100; // Turn Ratio -100-100
tele[9]=0x20; // Run Stat  //Iedle=0x00,RampUp=0x10,Running=0x20,RampDown=0x40
tele[10]=0x00;// Tacho Limit 0:run forever
tele[11]=0x00;// Tacho Limit 0:run forever
tele[12]=0x00;// Tacho Limit 0:run forever
tele[13]=0x00;// Tacho Limit 0:run forever
tele[14]=0x00;// Tacho Limit 0:run forever

writeCom(tele,15);

cn = readCom2(resu,5);
};

// メイン関数の一部

if(init()){
drive_m(1,50); drive_m(2,50);
}


 上記の例ではCOM3を開いてみて開けなければCOM5を開いていますが、これは使用している環境に合わせて調整する必要があります。コマンドを送信後、応答メッセージを受信するまでには仕様上30msec以上は待機することになりますから、受信のタイムアウト時間は十分にとっておく必要があります。

追記10/29 ベタ書きが変なところに挿入されていたため読みにくくなりご迷惑をおかけしておりました。





お気に入りの記事を「いいね!」で応援しよう

Last updated  October 29, 2008 09:48:49 AM
コメント(0) | コメントを書く



© Rakuten Group, Inc.
X