今回は、Arduino互換ボード(Adafruit Feather 32u4 Bluefruit LE)とフォトリフレクタ(QRE1113)を使用して、床に貼った黒テープに沿って走る車(ライントレースカー)を作成する方法を紹介します。
使用する部品一覧
使用する電子部品は以下のとおりです。全てスイッチサイエンスで購入しました。
| 商品名 | 単価 | 個数 | 金額 |
| Adafruit Feather 32u4 Bluefruit LE (2723: ADA-2829) | 3,949 円 | 1 | 3,949 円 |
| デュアルモータードライバDRV8835 (1637: POLOLU-2135) | 594 円 | 1 | 594 円 |
| リチウムイオンポリマー電池400mAh (3118: DPTL-DTP502535) | 770 円 | 1 | 770 円 |
| QRE1113 フォトリフレクタ・モジュール (408: SFE-ROB-09453) | 375 円 | 3 | 1,125 円 |
| Feather用足の長いピンソケットのセット (2754: ADA-2830) | 176 円 | 1 | 176 円 |
| SparkFun 超小型ブレッドボード(赤) (1520: SFE-PRT-12044) | 501 円 | 2 | 1,002 円 |
車体の部品は以下のとおりです。これ以外に、フォトリフレクタモジュールを取り付けるために、タミヤミニ四駆のスタビローラーセット(?)の棒を使用しています。これは、家の中にあったものなので、今も販売しているかどうかはわかりません。長いネジをホームセンターで購入して代用できると思います。
| 商品名 | 単価 | 個数 | 金額 |
| タミヤ 楽しい工作シリーズ No.144 ボールキャスター 2セット入 (70144) | 253円 | 1 | 253円 |
| タミヤ 楽しい工作シリーズ No.193 スリムタイヤセット (36・55mm径) 70193 | 354円 | 1 | 354円 |
| タミヤ 楽しい工作シリーズ No.157 ユニバーサルプレート 2枚セット (70157) | 469円 | 1 | 469円 |
| タミヤ 楽しい工作シリーズ No.168 ダブルギヤボックス 左右独立4速タイプ (70168) | 632円 | 1 | 632円 |
| 電池ケース 単3×2 スイッチ・カバー付 KIT-UM32S | 198円 | 1 | 198円 |
※記載している金額は購入時のものです。
Adafruit Feather 32u4 Bluefruit LEの特徴や使い方
「Adafruit Feather 32u4 Bluefruit LE」は、Adafruit IndustriesのArduino互換機で、ArduinoUnoの約1/3の大きさです。この小型を活かせるように、電源はリチウムイオンバッテリー(3.7V)を接続できる端子があります。さらに、Bluetoothのモジュールが搭載されており、技適取得済みなので日本国内でも使用できます。また、Adafruitが公開しているiOSやAndroidのアプリを使用することで、スマートフォンから制御することもできます。製品ドキュメントは公式サイト( https://learn.adafruit.com/adafruit-feather-32u4-bluefruit-le/downloads )にまとめられています。主な特徴は下記のとおりです。
- サイズ 2.0″ x 0.9″ x 0.28″ (51mm x 23mm x 8mm)
- ATmega32u4 @ 8MHz with 3.3V logic/power
- 3.3V レギュレータ 、最大電流ピーク500mA
- GPIO 20本
- 通信(シリアル、I2C、SPI)
- PWM 7本
- アナログ入力 10本
- リチウムポリマー電池の充電機能有り
デュアルモータドライバDRV8835の特徴や使い方
「デュアルモータドライバDRV8835」は、1つで2つのDCモータを駆動することができます。よく使用されるモータドライバとして、TA7291Pがありますが、ロジック電源の動作範囲が4.5~20Vなので、今回使用するArduino互換機の電源3.3Vでは動作させることができません。電流は最大1.5Aまで流せるので、電子工作でよく使用される、マブチのFA-130RA-18100の最大効率時の消費電流0.56Aに対しては十分です。障害物にあたって、モータがロックされた場合は2.1A流れるようですが、DRV8835の過電流防止機能があるため、壊れてしまう可能性は低いと判断して使用します。詳細は製品ページ( https://www.pololu.com/product/2135/ )を参照してください。モータ制御は下記のとおりです。PWM反転制御もできるようですが、今回は不要なので下記だけで十分です。
| xIN1 | xIN2 | xOUT1 | xOUT2 | 制御 |
|---|---|---|---|---|
| 0 | 0 | OPEN | OPEN | 停止(惰性) |
| PWM | 0 | PWM | L | 順方向回転 PWM % |
| 0 | PWM | L | PWM | 逆方向回転 PWM % |
| 1 | 1 | L | L | 停止(ブレーキ) |
QRE1113フォトリフレクタモジュールの特徴や使い方
QRE1113フォトリフレクタモジュールは、3.3Vで動作可能なモジュールです。端子は電源・GND・OUTの3端子のみで、OUTはアナログ出力なので、Arduinoのアナログ入力端子に接続して使用します。最適検出距離は3mmと記載されており、特性グラフを見ると、0.8mmぐらいが一番感度が高いようです。とはいえ、あまり床に近づけすぎると、ちょっとした障害物でもぶつかってしまうため、ある程度の距離が必要です。これは、床と黒線とのコントラストがどれくらいかにもよるので、各々の環境で調整が必要となります。特性の詳細は製品ページ( https://www.sparkfun.com/products/9453 )を参照してください。
回路図
電源は単三電池×2本(3.0V)とリチウムポリマー電池(3.7V)の2つにしました。電源を1つにした場合、モータ制御によるノイズが電源に乗り、Arduino制御回路の誤動作に繋がる恐れがあります。ノイズによる電源変動をアルミ電解コンデンサで吸収するという方法もありますが、アルミ電解コンデンサは極性を間違うと破裂する恐れがあり危険です。
配線図
ブレッドボードを使用した配線は図のとおりになります。
組立完成写真
実際に組み立てた写真です。配線長さは調整していないので、少し不格好ですが、部品はコンパクトに纏められたと思います。
プログラム
モータは2個使用しますが、制御方法は同じなので、ライブラリ化しました(Motor.h)。ダブルギヤボックスを使う場合、タイヤを同じ方向に回転させたい場合、左右のモータ回転方向を反対にする必要があります。ライブラリを使うため、制御は同じになるので、モータの接続極性を反対にしておく必要があります。説明がわかり難いかもしれませんが、はんだ付けする前に一度試してみてください。
次に、メインのプログラムの内容ですが、ライントレースのアルゴリズムは以前の記事(「ELEGOO UNO R3スマートロボットカーV3.0+」でライントレース(自動運転)をやってみた)で紹介していますので参照してください。黒線の判定しきい値「thresholdLine」は、フォトリフレクタのアナログ取得値をシリアル通信で見ながら決めます。床と黒線で値の変化が少ない場合は、センサと床の距離を縮めてみたり、黒線ではなく白線を使うなど工夫してみてください。また、ラインから脱線してしまうことがあると思います。その場合は、車の速度「carSpeed」を遅くしたり、loop時間を短くするなどして調整してください。
//www.stemship.com
//2019.11.10
class Motor {
private:
int _IN1;
int _IN2;
void motorCtrl(int val1, int val2) {
analogWrite(_IN1, val1);
analogWrite(_IN2, val2);
}
public:
//モータの制御ピン設定
Motor(int IN1, int IN2) {
_IN1 = IN1;
_IN2 = IN2;
pinMode(_IN1, OUTPUT);
pinMode(_IN2, OUTPUT);
}
//モータを順方向に回転
void forward(int val) {
motorCtrl(val, 0);
}
//モータを逆方向に回転
void reverse(int val) {
motorCtrl(0, val);
}
//モータ回転を停止(ブレーキ有/無)
void stop(boolean withBrake) {
if(withBrake) {
motorCtrl(HIGH, HIGH);
}
else {
motorCtrl(LOW, LOW);
}
}
};
//www.stemship.com
//2019.11.10
#include "Motor.h"
//右と左のモータ
Motor motorR = Motor(11, 10);
Motor motorL = Motor(6, 5);
//トラッキング用センサのピン番号(Analog Input)
const int pinSensorR = 1; //右側
const int pinSensorL = 5; //左側
const int pinSensorC = 3; //真ん中
//車線の判定しきい値
const int thresholdLine = 980;
//車の速度
const int carSpeed = 192;
//車の動作関数
void runForward();
void runRight();
void runLeft();
void runBack();
void setup() {
// put your setup code here, to run once:
pinMode(pinSensorR, INPUT);
pinMode(pinSensorL, INPUT);
pinMode(pinSensorC, INPUT);
//シリアル通信
Serial.begin(9600);
}
void loop() {
unsigned long now = millis();
int valSensorR = analogRead(pinSensorR);
int valSensorL = analogRead(pinSensorL);
int valSensorC = analogRead(pinSensorC);
Serial.print("Sensor Right: ");
Serial.print(valSensorR);
Serial.print("\n");
Serial.print("Sensor Left: ");
Serial.print(valSensorL);
Serial.print("\n");
Serial.print("Sensor Center: ");
Serial.print(valSensorC);
Serial.print("\n");
if(valSensorC > thresholdLine) {
runForward(carSpeed);
}
else if(valSensorL > thresholdLine) {
runRight(carSpeed);
}
else if(valSensorR > thresholdLine) {
runLeft(carSpeed);
}
//ループ時間[ms]
delay(50);
}
//前進
void runForward(int val) {
motorR.forward(val);
motorL.forward(val);
}
//後退
void runBack(int val) {
motorR.reverse(val);
motorL.reverse(val);
}
//右旋回
void runRight(int val) {
motorR.stop(false);
motorL.forward(val);
}
//左旋回
void runLeft(int val) {
motorR.forward(val);
motorL.stop(false);
}
動かしてみよう
プログラムを書き込んで、実際に動かしてみてください。










Arduino初心者です。同じようなライントレースカーを作りたいと思い、とりあえず真似させて頂こうという所存です。数点質問がありご回答いただけると幸いです。
1,手元にあるELEGOD UNO R3を使う予定なのですが、問題ありませんか?
2,購入欄にデュアルモータードライブが3つと書かれているのですが、3つ購入した方がいいのでしょうか?
3,初心者にはリチウムイオン電池が危険と聞いたので、モータードライブに繋がれている電池だけでArduinoにも供給したいのですが可能でしょうか?また繋ぎ方のアドバイスもあれば頂きたいです。
コメントありがとうございます。
>1,手元にあるELEGOD UNO R3を使う予定なのですが、問題ありませんか?
UNO R3は5Vなので、ドライバとフォトリフレクタも5Vで動作するか確認が必要です。
DRV8835は2~7VなのでOKです。QRE1113は3.3Vでも5Vでも使用できます。
したがって、ELEGOD UNO R3でも問題ないと思います。
>2,購入欄にデュアルモータードライブが3つと書かれているのですが、3つ購入した方がいいのでしょうか?
1つで良いです。ご指摘ありがとうございます。修正しておきます。
>3,初心者にはリチウムイオン電池が危険と聞いたので、モータードライブに繋がれている電池だけでArduinoにも供給したいのですが可能でしょうか?また繋ぎ方のアドバイスもあれば頂きたいです。
Arduinoとモータドライブの電源を共用すると、モータに電流が流れた時に電池の電圧変動がArduinoに影響するため、
Arduino電源が一瞬落ちたり、過電圧で故障する可能性があるためお勧めできません。
リチウムイオン電池は、過充電や発熱を検知して保護するモジュールが内蔵されているのですが、
製造元のよくわからない安いリチウムイオン電池は、そのような保護機能が省かれている可能性があるため、やめておいたほうが良いと思います。
Motor.hのライブラリの内容を教えていただきたいです。
“class Motor{…}”がMotor.hの内容です。
わかりにくくてすみません(Wordpressのアップデートにプラグインが対応しておらず、表示が簡素化されてしまっているようです)。