目次

ライントレーサスケッチ

 ライントレーサは、床面に引いたラインに追従して
 移動するロボットです。
 写真は、無限軌道を利用したライントレーサです。



 能開大のG棟の教室にあるコースは、以下。



 Arduinoを利用して、次のメカをライントレーサに
 仕立てます。



 メカにはハイスピードギアが接続されていますが
 ドライブ回路とセンサーを載せなければ、ロボット
 になりません。

 ドライブ回路は、次のものを利用します。



 回路は、モータを回転させるためのPWM波形を
 入力し絶縁して伝達するフォトカプラとMOSFET
 で構成します。また、ラインセンサーのモニタ
 用LEDをつけてあります。

 回路図は、以下。



 センサーは、密着タイプを利用します。



 回路図は、以下。



 ライントレーサを動かす前に、次のテストをして
 回路が正しく動くことを確認しておきます。

 各項目ごとにスケッチを作成して
 テストしていきます。

 ただし、テスト数は少ない方がよいので
 スタートトリガースイッチとモータドライバの
 テストは、合体させます。
 また、方向設定スイッチとセンサーの出力値の
 確認も合体させます。

モータ回転テストスケッチ

 モータを回転させるには、PWM波形をMOSFETに  与えればよいので、analogWriteを使います。  モータ回転テストの仕様を決めます。  スイッチを押している間、モータを回転させる。  モータの回転は、DUTY比を50%とする。  プッシュスイッチになっているのは、回路図から  スタートトリガーです。また、負論理であること  に注意します。  ピンアサインを決めます。  50%のDUTY比は、analogWriteが0〜255の値を  とるので、128とします。  スイッチには、チャタリングがあるので  1秒ごとに状態を入力し、PWM波を出力  するか否かを指定します。  テストなので、単純に仕様を決め、スケッチは  次のように定義しました。 #define INTERV 1000 #define PWMV 128 // define data types typedef unsigned char UBYTE ; typedef unsigned short UWORD ; // pin assign #define ENABLE 9 #define MOTOR_R 10 #define MOTOR_L 11 // variables UBYTE flag ; UWORD xinterval ; void setup() { // enable pin pinMode(ENABLE,INPUT); // PWM pin pinMode(MOTOR_R,OUTPUT); pinMode(MOTOR_L,OUTPUT); // set interval xinterval = INTERV ; } // the loop() method runs over and over again, // as long as the Arduino has power void loop() { // get switch state flag = digitalRead(ENABLE); // judge if ( flag == LOW ) { analogWrite(MOTOR_R,PWMV); analogWrite(MOTOR_L,PWMV); } else { analogWrite(MOTOR_R,0); analogWrite(MOTOR_L,0); } // delay delay(xinterval); }

密着タイプセンサーテストスケッチ

 密着タイプセンサーの出力は、8ビットありますが  ArduinoのポートB、C、Dのピンは6ビットだけです。  両端のセンサー出力とは接続しないことにします。  センサー出力は、時々刻々変化するとして  1秒周期で読み取ることにします。  センサー出力値は、ArduinoIDEに端末エミュレータが  あるので、シリアルでPersonalComputerに転送します。  方向設定スイッチの状態も知りたいので、こちらも  シリアルで転送します。  シリアルでPersonalComputerに、ASCIIコードを転送  するときは、Serial.printかSerial.printlnを利用  します。  センサー出力値は6ビットなので、1ビットごとに  数値から数字に変換して対応します。  次のように1ビットごとに取出し、変換します。  *(msg+0) = '0' ; if ( sensor & 0x20 ) { *(msg+0) = '1' ; }  デフォルト値を入力しておき、その値と異なる  場合だけ、変更します。  センサー値とスイッチの状態には、スペースを  入れて見やすくしておきます。  おおよその仕様が確定したので、スケッチを作成します。 #define INTERV 1000 // define data types typedef unsigned char UBYTE ; typedef unsigned int UWORD ; // pin assign #define DIRSW 2 // variables UBYTE flag ; UBYTE sensor ; UWORD xinterval ; UBYTE msg[7] ; void setup() { // enable pin pinMode(DIRSW,INPUT); // PORT_C inputs DDRC = 0x00 ; // Serial.begin(9600); // set interval xinterval = INTERV ; // set initial values *(msg+0) = '0' ; *(msg+1) = '0' ; *(msg+2) = '0' ; *(msg+3) = '0' ; *(msg+4) = '0' ; *(msg+5) = '0' ; *(msg+6) = '\0' ; } // the loop() method runs over and over again, // as long as the Arduino has power void loop() { UBYTE i ; // default for ( i = 0 ; i < 6 ; i++ ) { *(msg+i) = '0' ; } // get sensor state sensor = PINC ; // separate if ( sensor & 0x20 ) { *(msg+0) = '1' ; } if ( sensor & 0x10 ) { *(msg+1) = '1' ; } if ( sensor & 0x08 ) { *(msg+2) = '1' ; } if ( sensor & 0x04 ) { *(msg+3) = '1' ; } if ( sensor & 0x02 ) { *(msg+4) = '1' ; } if ( sensor & 0x01 ) { *(msg+5) = '1' ; } // get switch state flag = digitalRead(DIRSW); flag += '0' ; // show for ( i = 0 ; i < 6 ; i++ ) { Serial.print(*(msg+i)); } Serial.print(" "); Serial.println(flag); // delay delay(xinterval); }

動作シーケンス処理

 各ブロックのテストが終わったなら、動作  シーケンスを考えます。  一般に、次のようなシーケンスを利用します。
  1. スタートトリガー待ち
  2. センサーから情報入力
  3. センサー情報からモータ回転数計算
  4. モータ回転数設定
  5. ディレイ
  6. スタートトリガーをチェックし、2にもどるか7に進む
  7. モータ回転数をゼロに設定
  8. モータ回転数設定
  9. 1に戻る
 loop関数の中に、シーケンスを記述します。  状態変数stateを用意して、ステートマシンを  構成します。 #define OFF 0 #define ON OFF+1 #define RIGHT 0 #define LEFT RIGHT+1 UBYTE state ; UBYTE sensor ; UBYTE rmotor ; UBYTE lmotor ; switch (state) { // wait start trigger case 0 : state = 0 ; if ( strg == ON ) { strg = OFF ; state = 1 ; } break ; // get sensor state case 1 : sensor = PINC ; state = 2 ; break ; // calcualte both motor PWM case 2 : rmotor = calculate(RIGHT,sensor) ; lmotor = calculate(LEFT ,sensor) ; state = 3 ; break ; // set motor PWM duty case 3 : analogWrite(MOTOR_R,rmotor); analogWrite(MOTOR_L,lmotor); state = 4 ; break ; // delay case 4 : delay(xinterval); state = 5 ; break ; // judge case 5 : state = 1 ; if ( strg == ON ) { strg = OFF ; state = 6 ; } break ; // clear motor PWM case 6 : rmotor = 0 ; lmotor = 0 ; state = 7 ; break ; // stop both motor case 7 : analogWrite(MOTOR_R,rmotor); analogWrite(MOTOR_L,lmotor); state = 0 ; break ; // others default : state = 0 ; break ; }  ステートマシンが出来ればセンサー値で  モータの回転数に、いくらにするのかを  計算する関数calculateを定義します。  センサー値から、モータの回転数を求めるには  テーブルルックアップで対応します。  センサー値は6ビットで入力されるので  左右それぞれに対応する値は、最大64に  なります。  64サイズの8ビット配列を2つ用意するか  センサー値から、右モータの回転数だけを  64サイズの8ビット配列に入れて、左モータ  の回転数は、右モータの回転数を若干補正  した値にします。 (under construction)

目次

inserted by FC2 system