ゼミのお話/アルマジロゼミ/Linux組み込みボードでのセンサの取り扱い

2018-04-16 (月) 15:53:00 (840d)

概要

  • Linux組み込みボードのシリアルデバイス経由でプログラムにより距離センサから信号を受け取る.「Linux組み込みボードでのサーボの取り扱い」の項で接続した機器に追加して接続する.
    • AGB65-ADC
      • シリアルポート経由で受けた指令を元にセンサからの信号を数値化・整形して返す機器である.この機器が扱うシリアルデバイスはTTLレベル信号であり,論理0が0V,論理1が5Vである.
    • 距離センサ
      • 物体との距離を電圧で表すデバイスである.測定できる距離はデバイスによって異なる.

準備

接続

  1. AGB65-RSCにAGB65-ADCを接続する.(接続ケーブル:付属の4ピンケーブル・電源ケーブル)
  2. AGB65-ADCにセンサを接続する.
connection_adcconverter.png
  • 図 センサ接続図
DSC_0283.jpg
  • 図 部品配置
DSC_0282.jpg
  • 図 部品接続

プログラム1

AGB65-ADC の簡単な使い方

  • AGB65-ADCへシリアル信号で個別の命令を送ることで,その命令に合った形式で結果が返ってくる.
  • AGB65-RSCと基本的な使い方は同じであるが,返ってくる値を読み取る必要がある.

AGB65-ADCからのセンサ値と実際の距離の関係について

  • 電源投入後、約40mS後から信号線に距離に応じて出力される.
  • この出力は28〜48mS毎にアップデートされる.
  • 出力電圧と距離の関係は次のようになる.
AS-PSD-3.jpg
  • 図 出力電圧と距離の関係図

センサ値読み取りプログラムの作成

  • 下記のプログラムを入力
    • センサの値を読み取り,画面に出力
    • センサの値は,デバイスに特化した値
01:#include <sys/types.h>
02:#include <sys/stat.h>
03:#include <sys/ioctl.h>
04:#include <fcntl.h>
05:#include <termios.h>
06:#include <unistd.h>
07:#include <stdio.h>
08:#include <stdlib.h>
09:#include <string.h>
10:#include <sys/time.h>
11:
12:#define SERIAL_PORT     "/dev/ttyAM1"
13:
14:int main(){
15:  int fd;
16:  fd = open(SERIAL_PORT, O_RDWR | O_NOCTTY);
17:  if(fd < 0){
18:    printf("%s doesn't open it\n",SERIAL_PORT);
19:    return -1;
20:  }
21:
22:  struct termios oldtio, newtio;
23:  tcgetattr(fd, &oldtio);
24:  newtio = oldtio;
25:
26:  newtio.c_iflag = IGNPAR;
27:  /* 非カノニカル入力処理 */
28:  newtio.c_lflag = 0;
29:
30:  /* read関数での文字待ちうけの設定 */
31:  newtio.c_cc[VTIME] = 0; /* 値x0.1秒待つ */
32:  newtio.c_cc[VMIN] = 1; /* 値の文字分だけ入力されるまで待つ*/
33:
34:  /* バッファをクリア */
35:  tcflush(fd, TCIFLUSH);
36:  
37:  cfsetspeed(&newtio, B9600);
38:  tcsetattr(fd, TCSANOW, &newtio);
39:
40:  /* ボードの設定 */
41:  int id=120;
42:
43:  int i, j, k;
44:  unsigned char command[4] = {255, id, 1, 1};
45:  unsigned char data[20];
46:  
47:  for(i=1 ; i<=10 ; i++){
48:    printf("Getting data : %d\n", i);
49:
50:    /* センサボードにデータ要請 */
51:    write(fd, command, sizeof(command));
52:    /* 1文字目データ受信 */
53:    read(fd, &data[0], 1);
54:    if(data[0] == 255){
55:      read(fd, &data[1], 1);
56:      if(data[1] == id){
57:        read(fd, &data[2], 1);
58:        if(data[2] == 17){
59:          read(fd, &data[3], 1);
60:          if(data[3] == 1){
61:            for(k=4 ; k<20 ; k++){
62:              /* read(fd, data2, 16);とか聞くかな */
63:              read(fd, &data[k], 1);
64:              printf("port %2d : data = %d\n", k-3, data[k]);
65:            }
66:          }
67:        }
68:      }
69:    }
70:  }
71:
72:  for(i=1 ; i<=100 ; i++){
73:    printf("Getting data : %d :", i);
74:
75:    /* センサボードにデータ要請 */
76:    write(fd, command, sizeof(command));
77:    usleep(100000);
78:    /* 1文字目データ受信 */
79:    read(fd, &data[0], 1);
80:    if(data[0] == 255){
81:      read(fd, &data[1], 1);
82:      if(data[1] == id){
83:        read(fd, &data[2], 1);
84:        if(data[2] == 17){
85:          read(fd, &data[3], 1);
86:          if(data[3] == 1){
87:            for(k=4 ; k<20 ; k++){
88:              /* read(fd, data2, 16);とか聞くかな */
89:              read(fd, &data[k], 1);
90:            }
91:
92:            for(k=4 ; k<7 ; k++){
93:              /* read(fd, data2, 16);とか聞くかな */
94:              printf("data = %d :", data[k]);
95:            }
96:            printf("\n");
97:          }
98:        }
99:      }
100:    }
101:  }
102:
103:  tcsetattr(fd, TCSANOW, &oldtio);
104:  close(fd);
105:  return 0;
106:}

プログラム2

お題

  • センサから障害物(手のひらなど)までの距離を測る.サーボモータによって,計測した距離(cm)をメータで示すプログラムの作成

参考

AGB65-ADC 命令・返値仕様

  • マスタ(Armadillo-300)からADCへの指示は,4〜17バイトの数値データで送る.
  • バイトサイズ(8ビット)なので,表される数値は0〜255の256種類.
  • 数値は10進数.
  • 注)データは文字データではなく,数値(バイナリ)データで送る.

基本形

  • データの基本形は次の通り.[ ]内は1バイトを表す.()内は送りえる数値の範囲.
[シンクロバイト(255)] [ID(0-3)] [送信バイト数(1-14)] [命令1] [命令2] [命令3] ...
シンクロバイトRSCにデータの通信開始を知らせるデータで,常に「255」で始まる.
IDRSCに設定された固有のID(AGB65シリーズを複数接続したときの判別用.ADCの場合,出荷時のIDは「120」.)
送信バイト数送信される命令の(バイト)数.シンクロバイト,ID,送信バイト数は数えない.
命令ADCに動作させたい命令.詳細は以下の表.

命令の説明

命令値動作方向フォーマット
全ポート読み取り(8bit)送信[255][ID(120-127)][バイト長(1)][命令(1)]
  受信[255][ID(120-127)][バイト長(17)][命令(1)][P1結果][P2結果]...[P16結果]
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]
121ポート読み取り(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