第 1.0 版 '12/03/07 - 三鷹ハードウェアエンジニアカフェ メニューの Tools →...
Transcript of 第 1.0 版 '12/03/07 - 三鷹ハードウェアエンジニアカフェ メニューの Tools →...
© Xstech Inc.
第 1.0 版 '12/03/07
第 1.1 版 '12/04/02
三鷹ハードウエアエンジニアカフェ
タイヤロボット
( Arduino )
講習会資料
© Xstech Inc.
目次
1. はじめに........................................................................................................................................... 1
2. 準備.................................................................................................................................................. 2
2.1. Arduino ボードの購入.............................................................................................................. 2
2.2. PC での準備 .............................................................................................................................. 4
3. スケッチ(プログラム)の作成........................................................................................................ 6
3.1. LEDチカチカ ........................................................................................................................... 8
3.2. スケッチ(プログラム)の書き込み........................................................................................ 10
3.3. Photodiode 入力 ..................................................................................................................... 11
3.4. タイヤの駆動........................................................................................................................... 16
4. ライントレース .............................................................................................................................. 18
1
© Xstech Inc.
1. はじめに
Arduino(アルデュイーノ)はイタリア製
Atmel 社製の CPUが載っていいます。(ROM, RAM 内臓)
Arduino はソフト、ハードがオープンソースで公開されています。
(http://www.arduino.cc/)
Arduino が動作するタイヤロボットを制御しライントレーススケッチを書き込み動作させます。
2
© Xstech Inc.
2. 準備
2.1. Arduino ボードの購入
タイヤロボットのボードには Arduino を実行できる準備がされています。
タイヤロボットに USBシリアル変換基板を追加すれば Arduino ボードと同じになります。
USBモジュール
取り付け
新型はジャンパーピンでは
無くスイッチに変更されて
います。
3
© Xstech Inc.
タイヤロボットでは一旦 Arduino 化するとオリジナルに戻せません。
(もどすには ROM を書き直す必要があります。)
4
© Xstech Inc.
2.2. PCでの準備
http://arduino.cc/ にアクセスし Download ページより Windows 用をダウンロードします。
arduino-1.0-windows.zip を適当なフォルダーにコピーし解凍するだけです。
クリックするとダウン
ロードが始まります。
5
© Xstech Inc.
USBドライバーのインストール
解凍した arduino-1.0-windows内の arduino-1.0¥drivers¥FTDI USB Drivers にドライバーがあ
ります。
初めて USB を接続した時にドライバーが存在するフォルダが聞かれますので上記のフォルダー
を指定します。
1. ジャンパー設定する。
2. 電源 ON
3. USBケーブルを接続する。
ドライバーの確認は「コントロールパネル」→「システムとセキュリティ」→システム欄の「デバイス
マネージャー」と辿りポート(COMと LPT)にデバイスが追加されていると OKです。
(Windows7 の場合)
COMxx が追加さ
れていれば OK
6
© Xstech Inc.
3. スケッチ(プログラム)の作成
ボードと Serial Port の設定
タイヤロボットでは
LilyPad Arduino w/ ATmeag168
を指定します。
7
© Xstech Inc.
Serial Port は先ほどインストールしたドライバーで追加されて COMポートを指定します。
おまけ
Tools の反応が遅い時は
arduino-1.0 フォルダーの rxtxSerial.dll を下記のものと入れ替えると反応が早くなります。
http://servicios.ried.cl/arduino/temp/rxtxSerial-2.2_fixed_2009-03-17.rar をダウンロードし解凍
します。解凍すると rxtxSerial.dll が現れますので置き換えてください。
8
© Xstech Inc.
3.1. LEDチカチカ
スケッチ(プログラム)は setup と loop の中に書き込みます。
setup はスケッチが動き出した時、最初に一回だけ動作します。
loop は電池が無くなるまで(電源スイッチを OFFにするまで)永遠に繰り返します。
setup 例
#define LED1 5 // LED 1 はデジタルピン 5 に接続されている。PD5
#define LED2 4 // LED 2 はデジタルピン 4 に接続されている。PD4
#define LED3 3 // LED 3 はデジタルピン 3 に接続されている。PD3
#define LED4 2 // LED 4 はデジタルピン 2 に接続されている。PD2
//------------------------------------------------------------------
// 初めに1回だけ動作する。
//------------------------------------------------------------------
void setup()
{
// デジタルピンは入出力を設定する。(初期値は入力)
pinMode( LED1, OUTPUT ) ; // LED 1 (デジタルピン 5 ) を出力に設定する。
pinMode( LED2, OUTPUT ) ; // LED 2 (デジタルピン 4 ) を出力に設定する。
pinMode( LED3, OUTPUT ) ; // LED 3 (デジタルピン 3 ) を出力に設定する。
pinMode( LED4, OUTPUT ) ; // LED 4 (デジタルピン 2 ) を出力に設定する。
// LED すべて消灯する。
digitalWrite( LED1, HIGH ) ; // LED 1 消灯
digitalWrite( LED2, HIGH ) ; // LED 2 消灯
digitalWrite( LED3, HIGH ) ; // LED 3 消灯
digitalWrite( LED4, HIGH ) ; // LED 4 消灯
}
9
© Xstech Inc.
loop例
上記例では LED1から LED4までが順次点滅します。
//------------------------------------------------------------------
// 繰り返し動作する。
//------------------------------------------------------------------
void loop()
{
digitalWrite( LED1, LOW) ; // LED 1 点灯
delay(500); // 0.5 秒待つ ( LED 1 は点灯したまま )
digitalWrite( LED1, HIGH ) ; // LED 1 消灯
delay(500); // 0.5 秒待つ ( LED 1 は消えたま )
digitalWrite( LED2, LOW) ; // LED 2 点灯
delay(500); // 0.5 秒待つ ( LED 2 は点灯したまま )
digitalWrite( LED2, HIGH ) ; // LED 2 消灯
delay(500); // 0.5 秒待つ ( LED 2 は消えたま )
digitalWrite( LED3, LOW) ; // LED 3 点灯
delay(500); // 0.5 秒待つ ( LED 3 は点灯したまま )
digitalWrite( LED3, HIGH ) ; // LED 3 消灯
delay(500); // 0.5 秒待つ ( LED 3 は消えたま )
digitalWrite( LED4, LOW) ; // LED 4 点灯
delay(500); // 0.5 秒待つ ( LED 4 は点灯したまま )
digitalWrite( LED4, HIGH ) ; // LED 4 消灯
delay(500); // 0.5 秒待つ ( LED 4 は消えたま )
delay(500) ;
}
10
© Xstech Inc.
3.2. スケッチ(プログラム)の書き込み
USBケーブルを使いスケッチをロボットに書き込みます。
画面下側に
Compilling scktch..
Uploading...
Done uploading. と表示されます(これが表示されれば 書き込み成功です。)
コンパイル後、正常ならば
Download されます。
11
© Xstech Inc.
動作開始
1. 電源 OFF
2. ジャンパーを外す。
(新型:切換え SW を B 側に設定する。)
3. 電源 ONで動作を開始します。
3.3. Photodiode 入力
Photodiode 入力をシリアルモニターに出力し確認します。
タイヤロボットを紙の上に描いた線(黒)の上に沿って動かしますが、タイヤロボットの先端に
赤外線を利用したレフレクターセンサーが付います、黒線の上か、白の上かを調べながら走行しま
す。この反射光がどの程度入力されるかを調べます。
Photodiode の入力が AD 変換に入力されているのでその電圧を調べてライン(黒)の上か、ライ
ン外(白)の上かを判定します。ATmega168 の AD変換機能は 10bit で行われ、0~1023 までの値
をとります。
Arduino では analogRead(ピン番号)で読み込むことができます。(約 100μ秒)
赤外線 Diode
紙
Photo diode
ATmega168
AD変換
12
© Xstech Inc.
setup例
アナログピン(SENSOR_PHOTO_1 ~ 4 )はデフォルトが入力です。pinMode で設定する必要はあ
りません。
// センサーチェック
#define SENSOR_MAX 4 // センサーの数
#define SENSOR_LED 8
#define SENSOR_PHOTO_1 3 // 位置 LED 1 (PC3)
#define SENSOR_PHOTO_2 2 // 位置 LED 2 (PC2)
#define SENSOR_PHOTO_3 1 // 位置 LED 3 (PC1)
#define SENSOR_PHOTO_4 0 // 位置 LED 4 (PC0)
// 変数
int SensorPhoto[4] ; // センサー値の保存エリア
int iCount = 0 ;
void setup()
{
Serial.begin(9600) ; // シリアル出力の設定
pinMode( SENSOR_LED, OUTPUT ) ; // センサー用 LED を出力に設定する。
digitalWrite( SENSOR_LED, HIGH ) ; // センサー LED を ON とする。
// 変数クリアー
for ( int i = 0 ; i < SENSOR_MAX ; i++ ) {
SensorPhoto[ i ] = 0 ;
}
}
13
© Xstech Inc.
loop例
0.01秒ごとにセンサー値を読み込み、シリアルで送る。
void loop()
{
int i ;
char strSensor[32] ;
char strSData[6] ;
// センサー値を読み込む
SensorPhoto[0] = analogRead( SENSOR_PHOTO_1 ) ;
SensorPhoto[1] = analogRead( SENSOR_PHOTO_2 ) ;
SensorPhoto[2] = analogRead( SENSOR_PHOTO_3 ) ;
SensorPhoto[3] = analogRead( SENSOR_PHOTO_4 ) ;
// 読み込んだセンサー値を文字列に変換しシリアルに出力する。
sprintf( strSensor, "%3d -", iCount ) ;
for ( i = 0 ; i < SENSOR_MAX ; i++ ) {
sprintf( strSData, "%4d", SensorPhoto[i]) ;
strcat( strSensor, strSData ) ;
}
strcat( strSensor, "\r\n" ) ;
Serial.print( strSensor ) ;
if ( ++iCount >= 1000 ) {
iCount = 0 ;
}
delay( 10 ) ;
}
14
© Xstech Inc.
Arduino メニューの Tools → Serial Monitor をクリックするとArduino基板のシリアルよりセ
ンサー値が出力されますのでデータを確認できます。
シリアルモニターは Arduino 付属のものでなくても可能です。(TeraTerm でも可能です。)
失敗談
インクジェットプリンターで印刷したライン(黒)ではかなり反射光がありラインを判別できず
ライントレースできませんでした。その為、ラインを油性インクでなぞると反射光が半減しライン
をトレースすることができました。
光が反射し、A/D 変換値が大
きくなっている。
15
© Xstech Inc.
Photo diode の入力波型を見てみる
0
200
400
600
800
1000
1200
1
32
63
94
12
5
15
6
18
7
21
8
24
9
28
0
31
1
34
2
37
3
40
4
43
5
46
6
49
7
52
8
55
9
59
0
62
1
65
2
68
3
71
4
74
5
77
6
80
7
83
8
86
9
90
0
93
1
96
2
0
200
400
600
800
1000
1200
1
32
63
94
12
5
15
6
18
7
21
8
24
9
28
0
31
1
34
2
37
3
40
4
43
5
46
6
49
7
52
8
55
9
59
0
62
1
65
2
68
3
71
4
74
5
77
6
80
7
83
8
86
9
90
0
93
1
96
2
インクジェットプリンターで
黒線を印刷した場合。
黒線を認識しません。
中央部の黒線を油性インキ
で上書きした場合。
黒線をはっきり認識します。
16
© Xstech Inc.
3.4. タイヤの駆動
タイヤの左右にはそれぞれモーターが接続されており、このモーターをアナログ出力により制御
します。
アナログ出力は
analogWrite( ピン番号、値)
とします。
左モータは9番ピンに、右モータは10番ピンに接続されています。9番、10番を制御してタ
イヤロボットを動かします。
値に設定できる範囲は0~255の間です。0は0%、255を100%として制御します
P の値はタイヤロボットでは4ミリ秒(250Hz)固定です。
ONにする時間 Aをアナログ出力で指定します。
analogWrite
A
P
// アナログ出力のチェック
#define AOUT9 9
#define AOUT10 10
#define MIN 50
#define MAX 200
void setup()
{
}
void loop()
{
analogWrite( AOUT9, MIN );
analogWrite( AOUT10, MAX );
}
ON
OFF
17
© Xstech Inc.
モータ制御では一定周期内での ON/OFF 時間を変化させ回転速度を制御します。PWM ( Pulse
Width Modulation ) と言いよく利用されています。モータ以外でも温度制御でも利用されます。(ヒ
ータに与える電流を PWM で変調して制御します。)
補足
Arduino ではアナログ出力の周波数は 490Hz となっています。
18
© Xstech Inc.
4. ライントレース
右のセンサーが黒色を感知した時、右モーターの回転を下げれればロボットは右に曲がります。
モータの回転はギアで減速されています。また、前進、後退は別の設定で行います。今回は前進
のみのスケッチを作成します。
L R
19
© Xstech Inc.
ライントレース スケッチの定数を定義します。
6://#define FULL_POWER はデバッグ用でコメントアウトしています。
1:// Line trace
2:
3:#define SENSOR_MAX 4 // センサーの数
4:#define SENSOR_LED 8 // センサー用 LED 番号
5:#define AVR_COUNT 4 // 集計数 ( 4データを集計し、平均する。)
6://#define FULL_POWER
7:
8:#define SENSOR_PHOTO_1 3 // 位置 LED 1 (PC3)
9:#define SENSOR_PHOTO_2 2 // 位置 LED 2 (PC2)
10:#define SENSOR_PHOTO_3 1 // 位置 LED 3 (PC1)
11:#define SENSOR_PHOTO_4 0 // 位置 LED 4 (PC0)
12:
13:#define LED1 5 // LED 1 はデジタルピン 5 に接続されている。(PD5)
14:#define LED2 4 // LED 2 はデジタルピン 4 に接続されている。(PD4)
15:#define LED3 3 // LED 3 はデジタルピン 3 に接続されている。(PD3)
16:#define LED4 2 // LED 4 はデジタルピン 2 に接続されている。(PD2)
17:
18:#define MOTOR_LEFT 9 // PB1
19:#define MOTOR_RIGHT 10 // PB2
20:
21:#define SENSOR_BLACK (600) //
22:#define SENSOR_LOW_LIMIT (200) // センサー下限
23:
24:// 変数
25:int SensorPhoto[ SENSOR_MAX ] ;
26:int Sensor[ SENSOR_MAX ][ AVR_COUNT ] ;
27:int SensorAvr[ SENSOR_MAX ] ;
28:int AvrNo = 0 ;
29:int Motor_L, Motor_R ;
20
© Xstech Inc.
初期設定
34:void setup()
35:{
36: int i, j ;
37:
38: pinMode( SENSOR_LED, OUTPUT ) ; // センサー(発光) LED を ON/OFF する。
39: digitalWrite( SENSOR_LED, HIGH ) ; // センサー LED を ON とする。
40:
41: // アナログピンは入力が初期値なので通常は設定する必要はありません。
42: // モータ設定
43: pinMode( MOTOR_LEFT, OUTPUT ) ; // 左モータ アナログ(PWM) 出力用
44: pinMode( MOTOR_RIGHT, OUTPUT ) ; // 右モータ アナログ(PWM) 出力用
45:
46: // 左モータ方向制御用
47: // +----------------- PB7 出力に設定
48: // |+---------------- PB6
49: // ||
50: DDRB = DDRB | 0b11000000 ;
51:
52: // 右モータ方向制御用
53: // +--------------- PC5 出力に設定
54: // |+-------------- PC4
55: // ||
56: DDRC = DDRC | 0b00110000 ;
57:
58: // 変数クリアー
59: for ( i = 0 ; i < SENSOR_MAX ; i++ ) {
60: SensorPhoto[ i ] = 0 ;
61: for ( j = 0 ; j < AVR_COUNT ; j++ ) {
62: Sensor[ i ][ j ] = 0 ;
63: }
64: }
65:
66: // テスト用
67: pinMode( LED1, OUTPUT ) ; // LED 1 (デジタルピン 5 ) を出力に設定する。
68: pinMode( LED2, OUTPUT ) ; // LED 2 (デジタルピン 4 ) を出力に設定する。
69: pinMode( LED3, OUTPUT ) ; // LED 3 (デジタルピン 3 ) を出力に設定する。
70: pinMode( LED4, OUTPUT ) ; // LED 4 (デジタルピン 2 ) を出力に設定する。
71:
72: // LED すべて消灯する。
73: digitalWrite( LED1, HIGH ) ; // LED 1 消灯
74: digitalWrite( LED2, HIGH ) ; // LED 2 消灯
75: digitalWrite( LED3, HIGH ) ; // LED 3 消灯
76: digitalWrite( LED4, HIGH ) ; // LED 4 消灯
77: // 動作確認用
78: digitalWrite( LED1, LOW ) ; // LED 1 点灯
79:}
21
© Xstech Inc.
メインループ
84:void loop()
85:{
86: int i ;
87: int c ;
88:
89: GetSensor() ;
90: // 平均値を求める。集計値 ÷ 4 (小数点以下は切り捨て)
91: Motor_R = SensorAvr[1] / AVR_COUNT ;
92: Motor_L = SensorAvr[2] / AVR_COUNT ;
93:
94: if ( Motor_L <= SENSOR_LOW_LIMIT || Motor_R <= SENSOR_LOW_LIMIT ) {
95: StopMotor() ;
96: digitalWrite( LED2, HIGH ) ; // LED 2 消灯
97: digitalWrite( LED3, HIGH ) ; // LED 3 消灯
98: } else {
99: // 両方紙の上(前進)
100: c = AvrNo - 1 ;
101: if ( c < 0 ) c = AVR_COUNT - 1 ; // 最新データ位置
102:
103: if ( Sensor[ 1 ][ c ] <= SENSOR_BLACK ) {
104: Motor_R = Sensor[ 1 ][ c ] / 4 ; // 右カーブ対策
105: }
106: if ( Sensor[ 2 ][ c ] <= SENSOR_BLACK ) {
107: Motor_L = Sensor[ 2 ][ c ] / 4 ; // 左カーブ対策
108: }
109:
110:#ifdef FULL_POWER
111: Motor_L = Motor_L * 2 / 3 ;
112: Motor_R = Motor_R * 2 / 3 ;
113:#endif
114: Motor_L >>= 2 ; // アナログ出力は 0~255 までなのでセンサー値を 1/4にする。
115: Motor_R >>= 2 ;
116:
117: ForwardMotor() ;
118: analogWrite( MOTOR_RIGHT, Motor_R ) ;
119: analogWrite( MOTOR_LEFT, Motor_L ) ;
120: digitalWrite( LED2, LOW ) ; // LED 2 点灯
121: digitalWrite( LED3, LOW ) ; // LED 3 点灯
122: }
123: delay( 2 ) ;
124:}
22
© Xstech Inc.
メインループでは2ミリ秒ごとにセンサーを読み込み、平均値を求めアナログ出力用に加工(1/4)
します。その値をモータに設定して制御します。なお、センサー値が紙上で無い場合はモータを停
止します。
100~108行までは移動平均値だけでモータを制御してると緩いカーブではOKですが急カーブを
曲がることができません。そのため黒判定を行った時、減速を加速します。
114: Motor_L >>= 2 ; は値を右に 2ビットシフトしていますが、これは
Motor_L /= 4 と同じです。
23
© Xstech Inc.
センサーの読み込み
センサーの読み込みは誤差(ゴミ)を抑えるため 4 個読み込み、メインループで移動平均を算出
します。
0 1 2 3 4 5 6 7 8 9 10 11
129:void GetSensor( void )
130:{
131: int i ;
132:
133: // センサー値を読み込む
134: SensorPhoto[0] = analogRead( SENSOR_PHOTO_1 ) ;
135: SensorPhoto[1] = analogRead( SENSOR_PHOTO_2 ) ; // 右センサー
136: SensorPhoto[2] = analogRead( SENSOR_PHOTO_3 ) ; // 左センサー
137: SensorPhoto[3] = analogRead( SENSOR_PHOTO_4 ) ;
138:
139: // 移動平均用にデータを保存する。
140: for ( i = 0 ; i < SENSOR_MAX ; i++ ) {
141: SensorAvr[ i ] -= Sensor[ i ][ AvrNo ] ; // 前回の値を減算する。
142: Sensor[ i ][ AvrNo ] = SensorPhoto[ i ] ; // 今回の値を保存する。(次、減算用)
143: SensorAvr[ i ] += Sensor[ i ][ AvrNo ] ; // 今回の値を加算する。
144: }
145: if ( ++AvrNo >= AVR_COUNT ) {
146: AvrNo = 0 ;
147: }
148:}
24
© Xstech Inc.
モータ制御
モータの制御は TB6552経由でおこなれます。TB6552を設定します。
162:void StopMotor( void )
163:{
164: // 左モータを停止する。
165: // +----------------- PB7
166: // |+---------------- PB6
167: // ||
168: PORTB = PORTB & 0b00111111 ;
169:
170: // 右モータを停止する。
171: // +--------------- PC5
172: // |+-------------- PC4
173: // ||
174: PORTC = PORTC & 0b11001111 ;
175:}
176:
177://---------------------------------------------------------------
178:// Motor 前進
179://---------------------------------------------------------------
180:void ForwardMotor( void )
181:{
182: // 左モータ前進。
183: // +------------------ PB7 --> 0
184: // |+----------------- PB6 --> 0
185: // || +-- PB6 --> 1
186: // || |
187: PORTB = ( PORTB & 0b00111111 ) | 0b01000000 ;
188:
189: // 右モータ前進。
190: // +------------------ PC5 --> 0
191: // |+----------------- PC4 --> 0
192: // || +-- PC4 --> 1
193: // || |
194: PORTC = ( PORTC & 0b11001111 ) | 0b00010000 ;
195:}
25
© Xstech Inc.
本資料は株式会社 ジェイエス・ロボティクス社製タイヤロボットを対象に解説しておりますが、
株式会社 ジェイエス・ロボティクス社へ直接の問い合わせは控えて下さい。
サンプルソース等が原因による損害・問題に対し三鷹ハードウエアエンジニアカフェ、有限会社
キィーズ・テックは一切の責任を負いません。ご使用者の責任の範囲内でお使いください。
【タイヤロボット講習会資料】の著作権は有限会社キィーズ・テック、三鷹ハードウエアエンジニアカ
フェに帰属しクリエイティブコモンズ(Creative Commons)のライセンスに従います。
表示 - 非営利 2.1 日本(CC BY-NC 2.1)
再配布される場合は以下を約束して下さい。
1. 表示:作者(有限会社キィーズ・テック、三鷹ハードウエアエンジニアカフェ)を明記してください。
2. 非営利:作品を営利目的で利用してはなりません。
上記以外で利用される場合は作者に連絡してください。