armadillo-300のシリアルデバイス経由でプログラムにより距離センサから信号を受け取る.ここで,センサに係わる機器としては以下のものがある.
- 演習後は消すこと
- 演習用ディレクトリにて,プログラムファイルを作成し,コンパイル,実行を行うこと.
- コンパイル例:プログラムファイル:sample.c, 実行ファイル:sample
- gcc sample.c -o sample
- 実行
- ./sample
AGB65-ADCへシリアル信号で個別の命令を送ることで,その命令に合った形式で結果が返ってくる.つまり,まずarmadillo300上のプログラムがどのようなデータが欲しいかコマンド送信すると(データリクエスト),AGB65-ADCは要求されたデータを返信する(データリプライ).
AGB65-RSCと基本的な使い方は同じであるが,返ってくる値を読み取る必要がある.
大まかな流れは,センサ情報リクエストする配列をAGB65-ADCへ送信し,その後AGB65-ADCからセンサ情報を受信する.
まずデータリクエスト用配列は以下のようになる.
unsigned char command[4] = {255, 120, 1, 1};
各配列の値の意味は以下のようになる.
シンクロバイト(255) | ADCにデータの通信開始を知らせるデータで,常に「255」である. |
ID(120) | ADCに設定された固有のID(AGB65シリーズを複数接続したときの判別用.ADCの場合,出荷時のIDは「120」.) |
送信バイト数(1) | 送信される命令の(バイト)数.シンクロバイト,ID,送信バイト数は数えない. |
命令1(1) | 全ポート(16ポート)読み取り(精度8bit) |
この配列をシリアル送信する.
データリプライ用配列は以下のようになる.これはデータリクエストした後,シリアル受信するデータである.
unsigned char data[20];
data[0]:シンクロバイト(255) | ADCからデータの通信開始を知らせるデータで,常に「255」である. |
data[1]:ID(120) | リクエストされたADCのID(ID=120にリクエストした場合,120の値が入っている.) |
data[2]:データバイト数(17) | ADCからarmadillo300に向けて送信される命令のバイト数.シンクロバイト,IDは数えない. |
data[3]:命令1(1) | armadillo300からADCにリクエストされた命令を返信.command[4]の値. |
data[4]~data[19]:[ポート1の結果]~[ポート16の結果] | 各ポートにささっているセンサの取得結果 |
上記のデータを以下のように送受信すると配列dataの中にセンサの情報が格納されている.厳密には,data[0]~[3]の値を使って正常にデータを受信できているか確認する必要がある(プログラムを参照)
int main(){ ...
...
write(fd, command, sizeof(command));
read(fd, data, sizeof(data));
...
}
}
以下の特徴があるので注意すること.
下記のプログラムを作成,実行してセンサ値の取得について学ぶ.
AD-PSDセンサからのセンサ値を表示
- 100m秒(100000μ秒)毎にデータ取得,表示する.これを100回(10秒)繰り返す.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | #include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#define SERIAL_PORT "/dev/ttyAM1"
int main(){
int fd;
fd = open(SERIAL_PORT, O_RDWR | O_NOCTTY);
if(fd < 0){
printf("%s doesn't open it\n",SERIAL_PORT);
return -1;
}
struct termios oldtio, newtio;
tcgetattr(fd, &oldtio);
newtio = oldtio;
newtio.c_iflag = IGNPAR;
/* 非カノニカル入力処理 */
newtio.c_lflag = 0;
/* read関数での文字待ちうけの設定 */
newtio.c_cc[VTIME] = 0; /* 値x0.1秒待つ */
newtio.c_cc[VMIN] = 1; /* 値の文字分だけ入力されるまで待つ*/
/* バッファをクリア */
tcflush(fd, TCIFLUSH);
cfsetspeed(&newtio, B9600);
tcsetattr(fd, TCSANOW, &newtio);
/* ボードの設定 */
int id=120;
int i, j, k;
unsigned char command[4] = {255, id, 1, 1};
unsigned char data[20];
for(i=1 ; i<=100 ; i++){
printf("Getting data : %d :", i);
/* センサボードにデータ要請 */
write(fd, command, sizeof(command));
usleep(100000);
/* 1文字目データ受信 */
read(fd, &data[0], 1);
if(data[0] == 255){
read(fd, &data[1], 1);
if(data[1] == id){
read(fd, &data[2], 1);
if(data[2] == 17){
read(fd, &data[3], 1);
if(data[3] == 1){
for(k=4 ; k<20 ; k++){
/* read(fd, data2, 16);とか聞くかな */
read(fd, &data[k], 1);
}
for(k=4 ; k<7 ; k++){
/* read(fd, data2, 16);とか聞くかな */
printf("data = %d :", data[k]);
}
printf("\n");
}
}
}
}
}
tcsetattr(fd, TCSANOW, &oldtio);
close(fd);
return 0;
}
|
センサから障害物(手のひらなど)までの距離を測り,計測した距離(cm)を表示するプログラムの作成
データの基本形は次の通り.[ ]内は1バイトを表す.()内は送りえる数値の範囲.
[シンクロバイト(255)] [ID(120-123)] [送信バイト数(1-14)] [命令1] [命令2] [命令3] ..
この時の各意味は以下の表となる.
シンクロバイト | ADCにデータの通信開始を知らせるデータで,常に「255」で始まる. |
ID | ADCに設定された固有のID(AGB65シリーズを複数接続したときの判別用.ADCの場合,出荷時のIDは「3」.) |
送信バイト数 | 送信される命令の(バイト)数.シンクロバイト,ID,送信バイト数は数えない. |
命令 | ADCに動作させたい命令.詳細は以下の表. |
命令の種類は以下のものがある.
命令値 | 動作 | 方向 | フォーマット |
---|---|---|---|
1 | 全ポート読み取り(8bit) | 送信 | [255][ID(120-127)][バイト長(1)][命令(1)] |
受信 | [255][ID(120-127)][バイト長(17)][命令(1)][P1結果][P2結果]...[P16結果] | ||
2 | 1ポート読み取り(8bit) | 送信 | [255][ID(120-127)][バイト長(2)][命令(2)][ポート番号(1-16)] |
受信 | [255][ID(120-127)][バイト長(3)][命令(2)][ポート番号][結果] | ||
11 | 全ポート読み取り(12bit) | 送信 | [255][ID(120-127)][バイト長(1)][命令(11)] |
受信 | [255][ID(120-127)][バイト長(33)][命令(11)][P1_H][P1_L][P2_H][P2_L]...[P16_H][P16_L] | ||
12 | 1ポート読み取り(12bit) | 送信 | [255][ID(120-127)][バイト長(2)][命令(12)][ポート番号(1-16)] |
受信 | [255][ID(120-127)][バイト長(4)][命令(12)][P?_H][P?_L] | ||
254 | セルフチェック | 送信 | [255][ID(120-127)][長(1)][254] |
受信 | [255][ID(120-127)][長(1)][254] | ||
上以外 | 無視される |
ADCが送信フォーマットを受け取ってから返信フォーマットを返し終わって待機状態になるまでの時間
8bit,1ポート読み取り | 9600bpsの場合:約12ms | 115200bpsの場合:約1.4ms |
8bit,全16ポート読み取り | 9600bpsの場合:約25ms | 115200bpsの場合:約2.6ms |
12bit,1ポート読み取り | 9600bpsの場合:約13ms | 115200bpsの場合:約1.5ms |
12bit,全16ポート読み取り | 9600bpsの場合:約42ms | 115200bpsの場合:約4ms |