Intel製のチップを載せたWi-Fi搭載型のマイコンと、Arduino風のI/Oをもたせたボードのセットです。
ソフトウェア側の余地が非常に大きなマイコンで、Arduinoとして使うだけだと高くて大きくて互換性の一部ないいいとこなしなボードになります。
このボードを活用するには、Linux側の活用がほぼ必須です。
更新履歴
- 第1版:9/22……初版
- 第2版:9/27……スケッチの自動実行を追加。自走できるようになりました。
- 第3版:10/4……スタート・ストップスイッチ増設、シャーシの組み直し、ブレッドボードの基板化を追加
- 第4版:10/7……モーター用電池の配線にスイッチを追加。右モーターの問題も解決
- 第5版(完成版):10/12……DCDCコンバーターを増設。実走行テストの動画を追加。目標は達成したと判断しました。
作りたいモノの目標
究極の目標は「Q-eyesのコピー」です。
チョロQの電動バージョンで、障害物を避けながら走るおもちゃです。
制作する前に仕様の決定
Edisonを使って、どうやって実現するか?
考えて以下のような仕様にしてみました。
- (必須)Edisonを使う
- (必須)Edison-Labのサンプルから最低3つを取り込み、活用する。
- 駆動系はタミヤのキャタピラとモーター2個で作る。
- 赤外線で障害物の検知を行う
- プログラムにはArduinoを用いる
- スタンドアロンで動作できるようにする
- Q-eyesの動作パターンは2種類あるが、片方だけを再現する
Edison LabのExamplesを使う
今回のレビューでは、製作時の条件としてEdison LabのExamplesで紹介されているサンプルを3つ以上使用することがあげられています。
現時点では、以下のサンプルを使いました。
- Blink……Edisonボードの動作確認に使用
- Analog Input……測距モジュールからの電圧を数値化するために使用
- Fading……モーター出力を可変させるために使用
- Switch Case……左右のセンサー入力からモーター動作を決定するために使用
EdisonボードでArduinoの動作確認
Arduinoでプログラムを作りますが、まずは動く環境を作る必要があります。
あらかじめ運営から提供されているEdisonを組み立ててみました。
動作テストには、Edison LabのExamplesから、Blinkというプログラムを使っています。いわゆるLチカですね。
発売直後にEdisonに触った時はインストーラーがバラバラで苦労しましたが、現在は1個のインストーラーでOKなようです。
作業中に躓いた、少しわかりにくいポイントを紹介します。
- ファームウェアの更新がGUI版のツールでできない場合は、
コマンドラインからバッチファイルを呼び出すことで更新できました。 - パソコンにJavaが入っていない場合は、途中でインストーラーをダウンロードして導入するよう指示がありました。
- Windows10を使いましたが、特に問題なく動いています。サポートOSに含まれていませんが、心配しなくて大丈夫なようです。
- USBケーブルは最低1本あれば大丈夫そうです。ボードの内側J16へ接続しました。USBケーブルを接続してからEdisonがドライブとして認識されるまでに何度か接続が切れることがありますが、正常です。少し待たないと使えません。
実際にプログラミングする場合は、以下の順序で起動するとうまく動くようです。
- パソコンでArduino IDEを起動する
- ボードのJ16側にUSBケーブルを接続
- パソコン側にUSBケーブルを接続
- 何度か抜き差しする音がするので、音がしなくなってEdisonがドライブとして認識されるまで待つ
- (初回のみ)Arduino IDEでボードの種類を選択
- (初回のみ)COMポートを選択する。デフォルトは環境に依存しますが、ウチだとCOM3でした。
この状態で、「スケッチの例」から「01.Basic」の「Blink」を開いて、マイコンへ書き込む、を実行するとEdisonにスケッチ(という名のプログラム)が送り込まれます。
正常に動作すると、Edisonボード上のLEDの1つが点滅します。
点滅を確認できれば、プログラミングの準備ができたことになります。
実際に点滅させると、以下のようになります。
赤外線センサーの動作確認
障害物の検知をするために赤外線センサーを使いました。
部品は秋月電子で買ったシャープ測距モジュール GP2Y0E03 (I2C&アナログ出力)です。
シャープ製で、ロボット掃除機にも使われているらしいです。
動作確認には、Edison LabのExamplesからAnalog Inputを使いました。
サンプルだと可変抵抗を使っていますが、かわりに測距モジュールを接続しています。
実際に動かした時の映像が以下になります。
手を近づけると点滅が遅くなります。
並列に接続したテスターの数値が徐々に大きくなっていて、電圧が上がっていることがわかります。
赤外線センサーの動作確認2
1つ前のセクションで、電圧が取得できることはわかりました。
今回は距離を測るのではなく「壁に近づいたか否か」を判定させますので、少しコードを修正します。
実際に動かしたのが以下のようになります。
手を近づけて、ある程度まで来るとLEDが点灯します。
センサーは左右を検出するため、2つ必要になります。
また、デバッグのためにセンサーと連動してLEDを点灯させるように改造します。
簡単な配線図が以下です。
ブレッドボード上に再現すると、以下のようになります。
全部律儀に配線すると電源やGNDが足りないため、ブレッドボード上でそれらをまとめています。
なのでブレッドボードからEdisonには6本まで配線を減らしました。
- 電源
- GND
- センサー1の出力
- センサー2の出力
- センサー1と連動するLED
- センサー2と連動するLED
稼働させると、以下のようになります。
この時のソースコードは、以下のようになっています。
int sensorPin_A0 = A0; // select the input pin for the potentiometer
int sensorPin_A1 = A1; // select the input pin for the potentiometer
int sensorValue_A0 = 0; // variable to store the value coming from the sensor
int sensorValue_A1 = 0; // variable to store the value coming from the sensor
int ledPin_A0 = 12; //for A0
int ledPin_A1 = 13; //for A1
int switchValue = 350;
void setup() {
// declare the ledPin as an OUTPUT:
pinMode(ledPin_A0, OUTPUT);
pinMode(ledPin_A1, OUTPUT);
}
void loop() {
// read the value from the sensor:
sensorValue_A0 = analogRead(sensorPin_A0);
sensorValue_A1 = analogRead(sensorPin_A1);
if(sensorValue_A0 > switchValue)
{
digitalWrite(ledPin_A0, HIGH);
}else{
digitalWrite(ledPin_A0, LOW);
}
if(sensorValue_A1 > switchValue)
{
digitalWrite(ledPin_A1, HIGH);
}else{
digitalWrite(ledPin_A1, LOW);
}
delay(200);
}
モーターシールドの動作確認
今回の工作では、車両を動かすのにモーターを使っています。
しかし、Edisonだけではモーターが動かせません。
そこでArduino用のモーターを制御するシールドを用意しました。
秋月電子のL298P使用 2Aモーターシールドです。
モーターを動かすための電源は、単3のニッケル水素充電池4本を使いました。
モータードライバは、EとMという2つの端子への出力で動作を決定します。
まずE端子で回転方向を決定し、次にM端子で出力を決めます。
M端子にはPWMを使って出力を連続的に可変させます。
実際に配線したのが以下のようになります。
モーター単体だと回転がわかりにくいので、ギアボックスやキャタピラを組み立てて車体の一部まで組み上げた状態にしています。
今回はEdison LabのExamplesから、Fadingを参照してPWM変調をかけました。
前方向に5秒、2秒休んで、後ろ方向に5秒、2秒休んでループという動作をさせています。
ソースコードは以下のようになっています。
//Arduino PWM Speed Control:
int E1 = 5;
int M1 = 4;
int E2 = 6;
int M2 = 7;
void setup()
{
pinMode(M1, OUTPUT);
pinMode(M2, OUTPUT);
}
void loop()
{
digitalWrite(M1,HIGH);
digitalWrite(M2,HIGH);
analogWrite(E1,150);
analogWrite(E2,150);
delay(2000);
analogWrite(E1,0);
analogWrite(E2,0);
delay(1000);
digitalWrite(M1,LOW);
digitalWrite(M2,LOW);
analogWrite(E1,150);
analogWrite(E2,150);
delay(2000);
analogWrite(E1,0);
analogWrite(E2,0);
delay(1000);
}
試作1号車の組み立て
ここまでで、壁を検出するセンサーと動作を決定するモーターの制御が可能になりました。
ハードウェアを一度カタチにして、それにあわせてプログラムもまとめあげます。
実際に組み上げたのが、以下になります。
非常にかっこ悪いですが、試作なのでこれでいきます。
センサーはブレッドボードを経由してEdisonへ接続、モーターと電池はモーターシールドへ接続しています。
モーターの配線が長すぎたため、長いところを丸めてスズメッキ線で束ねてあります。
Edisonの下にある黄色いブレッドボードは電池ボックスの配線をまとめています。
単3電池2本用のケースを前後方向に2つ並べているためです。
仮組みしたプログラムを机上で走らせると、以下のようになります。
※走りださないように下にハコを置いて、動かないようにしています。
スケッチの自動実行
さて、前回の公開時点で、未解決の問題がありました。
それがこの「スケッチの自動実行」です。
スタンドアロンで実行するには、電源をいれるだけでスケッチが動かないといけません。
ちばとどさんのコメントでいただいた情報をもとに試したところ、以下の手順を踏むことで実行できるようになりました。
- スケッチを実行するためのシェルを作成。「vi /home/root/sketch_auto.sh」
- 作成したファイルに実行権限を付与。「chmod +x /home/root/sketch_auto.sh」
- /etc/systemd/system/sketch_autorun.serviceを追加
- 実行権限を付加。「chmod 755 sketch_autorun.service」
- PCと接続して、ArduinoIDEからスケッチを転送。
- ↑で転送したスケッチの実行を確認
- サービスの存在をシステムに認識させる。「systemctl enable sketch_autorun」
- サービスを実行する設定にする。「systemctl start sketch_autorun」
- 再起動する「reboot」
これで、動くようになりました。
動画では電源を切った状態のEdisonを以下のように結線しています。
- J16(ボードの内側):USBモバイルバッテリーと接続。白いUSBケーブル
- J13(ボードの外側):PCと接続。黒いUSBケーブル。PCはTeratermでログ取得中
動きましたが、問題点が増えました。
- 電源が入るまでに時間がかかる。
→EdisonはLinuxの入ったコンピューターなのでやむなし。 - OSが起動すると同時に走り出すので、いつ走り出すか見えない。
- 走り出した後、停止する手段がない。
- 左右両方のセンサーが壁を検知した後の後退と旋回が不十分で何度も壁に接近してる。
本来のQ-eyesの動きと違う。 - Edison用のバッテリーを無理矢理おいてるので、ケーブルがはみ出して格好悪い
ほかにも改良が必要ですが、緊急停止手段は必要そうです。
9/27:試作1号車の実走行テスト
スタンドアロンで走行できるようになりましたので、部屋で走らせました。
ドアの前にハコを置いて四角い空間を作って走らせました。
途中にドアストッパーがありますが、いい具合に回避出来てるようです。
「とりあえず動いてる感」が半端ないですが、自分が作ったものが実際に動くと感動します。
これだけは間違いないです。
どんな些細なものでも、狙い通りに動くのは嬉しいものです。
コンピューターは「狙った通りに動くもの」ではなく、「書いたプログラム通りに動くもの」です。
ゆえに狙い通りに動くには、狙いとプログラムが一致しなければいけません。
今回のようにハードウェアが絡むと、ハードウェアのことも考慮したプログラムが必要です。
自分は動きの手本ができてたので、カタチになるまでコードを書き上げてからテストしました。
が、実際には「細かい機能が増えるたびに走らせる」方が達成感が湧くしテストにもなりますので、長続きします。ゆえにオススメです。
10/3:スタート・ストップのスイッチを増設
スタンドアロン動作だと、起動できたらいきなり走りだすのが問題でした。
そこで、スタート・ストップのスイッチと状態表示用にLEDを追加しました。
スケッチがスタートすると赤LEDが点滅します。
そこからスイッチを押すと、赤LEDが点灯し走行を開始します。
もう一度押すと、赤LEDは点滅になり、停止します。
この時点のソースコードは以下のようになっています。
//for SENSOR
int sensorPin_R = A0; // select the input pin for the potentiometer
int sensorPin_L = A1; // select the input pin for the potentiometer
int sensorValue_R = 0; // variable to store the value coming from the sensor
int sensorValue_L = 0; // variable to store the value coming from the sensor
int ledPin_R = 12; //for A0
int ledPin_L = 13; //for A1
int switchValue = 380;
int startSW_pin = 11;//START/STOP sw
int startSW_val = 0;
int ledPin_S = 8;
int ledPin_Sval = 0;
//for MOTOR
int E1 = 5;
int M1 = 4;
int E2 = 6;
int M2 = 7;
int valueF = 250;
int valueB = 200;
void setup() {
// declare the ledPin as an OUTPUT:
pinMode(ledPin_R, OUTPUT);
pinMode(ledPin_L, OUTPUT);
pinMode(startSW_pin, INPUT);
startSW_val = 0;
pinMode(ledPin_S, OUTPUT);
pinMode(M1, OUTPUT);
pinMode(M2, OUTPUT);
pinMode(E1, OUTPUT);
pinMode(E2, OUTPUT);
Serial.begin(9600);
}
void loop() {
//スイッチの押下を検出
int btState = 0;
btState = digitalRead(startSW_pin);
Serial.println("btState:");
Serial.println(btState);
if(btState == 0)
{
//フラグを反転
Serial.println("CHECK");
if(startSW_val == 1)
{
startSW_val = 0;//走行中→停止中
digitalWrite(ledPin_S, LOW);
Serial.println("RUN->STOP");
MotorStop();
delay(500);
}else{
startSW_val = 1;//停止中→走行中
digitalWrite(ledPin_S, HIGH);
Serial.println("STOP->RUN");
}
delay(500);
}
Serial.println("startSW_val:");
Serial.println(startSW_val);
//startSW_val = 0;
if(startSW_val == 1)
{
MovingControl();
}else{
if(ledPin_Sval == 1)
{
ledPin_Sval = 0;
digitalWrite(ledPin_S, LOW);
}else{
ledPin_Sval = 1;
digitalWrite(ledPin_S, HIGH);
}
delay(200);
//MotorStop();
}
delay(200);
}
//車両の制御
void MovingControl()
{
digitalWrite(M1,LOW);
digitalWrite(M2,LOW);
int flg_R = 0;
int flg_L = 0;
// read the value from the sensor:
sensorValue_R = analogRead(sensorPin_R);
sensorValue_L = analogRead(sensorPin_L);
if(sensorValue_R > switchValue)
{
digitalWrite(ledPin_R, HIGH);
flg_R++;
}else{
digitalWrite(ledPin_R, LOW);
}
if(sensorValue_L > switchValue)
{
digitalWrite(ledPin_L, HIGH);
flg_L++;
}else{
digitalWrite(ledPin_L, LOW);
}
int selectValue = flg_R * 10 + flg_L;
Serial.println(selectValue);
switch (selectValue) {
case 0://R=0,L=0
digitalWrite(M1,LOW);
digitalWrite(M2,LOW);
analogWrite(E1,valueF);
analogWrite(E2,valueF);
break;
case 1://R=0,L=1
digitalWrite(M1,LOW);
digitalWrite(M2,HIGH);
analogWrite(E1,valueF);
analogWrite(E2,valueB);
break;
case 10://R=1,L=0
digitalWrite(M1,HIGH);
digitalWrite(M2,LOW);
analogWrite(E1,valueB);
analogWrite(E2,valueF);
break;
case 11://R=1,L=1
digitalWrite(M1,HIGH);
digitalWrite(M2,HIGH);
analogWrite(E1,valueF);
analogWrite(E2,valueF);
delay(1000);
//force TURN
digitalWrite(M1,HIGH);
digitalWrite(M2,LOW);
analogWrite(E1,valueF);
analogWrite(E2,valueF);
delay(600);
break;
}
}
void MotorStop()
{
digitalWrite(M1, LOW);
digitalWrite(M2, LOW);
digitalWrite(E1, LOW);
digitalWrite(E2, LOW);
delay(100);
}
10/4:シャーシの組み直し
シャーシの重心低下を狙って、組み直ししてみました。
ギアボックスなどをシャーシ板の下側に配置してみました。
この状態でテストしましたが、旋回ができませんでした。
どうやら、キャタピラの接地面積が増えて摩擦が増えすぎて、モーターのパワーが足りなくなったようです。
仕方ないので、接地面積を減らすために車軸を追加しました。
そのせいで、組み直ししたのに高さは変わってません(汗
見比べて気付きましたが、たぶんこれ、シャーシ板を増やせばもっとラクに取り付けできます。
現時点では整備性が最悪で、電池交換のたびに全バラしが必要になります。
新たに調達した10mmスペーサーを多用したので、高さの微調整がきくようになりました。
今回はモーターが前側にきて、センサーやEdisonもできるだけ中央によせてます。
またEdison用の電源を置く場所がまったくなくなりました。
名刺みたいにスリムなバッテリーが必要です。
ついでに電池ボックスからの配線を、超小型のブレッドボードに交換しました。
両面テープでシャーシに貼り付けて省スペース化しています。
10/4:ブレッドボードの基板化
配線がたくさん浮いてるのは、ちょっと不安定だと思ったので、シンプルにするために基板化しました。
複数の基板を買って検討したんですが、固定位置も考えて「Arduinoのシールド」としてモータードライバに上乗せすることにしました。
ハンダ付けに慣れてない&基板化なんて初めてだったので、出来上がりが非常に汚くなりました。
このあたりは少し慣れが必要そうです。
奥の方にあるコネクタはセンサーからのケーブルを差し込むピンソケットです。
センサーからのケーブルがギリギリなので、L字型のコネクタを探してきました。
大量に取り付けてある抵抗は0Ω抵抗で、ブレッドボードでのジャンパ線代わりです。
右下にある青色の抵抗だけ、スイッチのプルアップ用で本物の抵抗です。
今回、最大のミステイクはピンヘッダの位置ですね。
右側(D0〜D13)側のピンヘッダの位置を間違えてしまい、1列ずれてて刺さりません。
スタック用に右より、左よりとずらすと思ったら、このボードは外側同士につけないとダメというシロモノでした。
センサーからの配線をあらかた終わらせてから問題が発覚したこと、換えのボードを調達してなかったこと、デジタルポートのD0〜D3が空いてることもあって、D8〜D13をD0〜D3に移設してプログラムを書き換えて対処しました。
無理やり置換えもしたので、余計に配線が増えて見苦しくなりました。
最初は片面実装で、碁盤の目のように綺麗に載せてたんですが、最終的には両面を駆使して斜め配線や立体交差やニアミスなど、シッチャカメッチャカになっています。
単純に基板化するだけなら、ブレッドボードと同じパターンのユニバーサル基板へ移設して、基板ごと両面テープで固定した方が簡単じゃないかと思います。
//for SENSOR
int sensorPin_R = A0; // select the input pin for the potentiometer
int sensorPin_L = A1; // select the input pin for the potentiometer
int sensorValue_R = 0; // variable to store the value coming from the sensor
int sensorValue_L = 0; // variable to store the value coming from the sensor
int ledPin_R = 1; //for A0
int ledPin_L = 0; //for A1
int switchValue = 380;
int startSW_pin = 2;//START/STOP sw
int startSW_val = 0;
int ledPin_S = 3;
int ledPin_Sval = 0;
//for MOTOR
int E1 = 5;
int M1 = 4;
int E2 = 6;
int M2 = 7;
int valueF = 180;
int valueB = 100;
void setup() {
// 測距センサーの近接検知LED用出力設定
pinMode(ledPin_R, OUTPUT);
pinMode(ledPin_L, OUTPUT);
// START/STOPスイッチ用入力設定
pinMode(startSW_pin, INPUT);
startSW_val = 0;
// 状態表示LED用出力設定
// ・点滅:待機中
// ・点灯:運転中
pinMode(ledPin_S, OUTPUT);
// モーター用出力設定
pinMode(M1, OUTPUT);
pinMode(M2, OUTPUT);
pinMode(E1, OUTPUT);
pinMode(E2, OUTPUT);
// デバッグ用:シリアル通信ポートの設定
Serial.begin(9600);
}
void loop() {
//スイッチの押下を検出
int btState = 0;
btState = digitalRead(startSW_pin);
Serial.println("btState:");
Serial.println(btState);
if(btState == 0)
{
//フラグを反転
Serial.println("CHECK");
if(startSW_val == 1)
{
startSW_val = 0;//走行中→停止中
digitalWrite(ledPin_S, LOW);
Serial.println("RUN->STOP");
MotorStop();
TurnLEDStop();
delay(500);
}else{
startSW_val = 1;//停止中→走行中
digitalWrite(ledPin_S, HIGH);
Serial.println("STOP->RUN");
}
delay(500);
}
Serial.println("startSW_val:");
Serial.println(startSW_val);
//startSW_val = 0;
if(startSW_val == 1)
{
MovingControl();
}else{
if(ledPin_Sval == 1)
{
ledPin_Sval = 0;
digitalWrite(ledPin_S, LOW);
}else{
ledPin_Sval = 1;
digitalWrite(ledPin_S, HIGH);
}
delay(200);
//MotorStop();
}
delay(200);
}
//車両の制御
void MovingControl()
{
digitalWrite(M1,LOW);
digitalWrite(M2,LOW);
int flg_R = 0;
int flg_L = 0;
// read the value from the sensor:
sensorValue_R = analogRead(sensorPin_R);
sensorValue_L = analogRead(sensorPin_L);
if(sensorValue_R > switchValue)
{
digitalWrite(ledPin_R, HIGH);
flg_R++;
}else{
digitalWrite(ledPin_R, LOW);
}
if(sensorValue_L > switchValue)
{
digitalWrite(ledPin_L, HIGH);
flg_L++;
}else{
digitalWrite(ledPin_L, LOW);
}
int selectValue = flg_R * 10 + flg_L;
Serial.println(selectValue);
switch (selectValue) {
case 0://R=0,L=0
digitalWrite(M1,LOW);
digitalWrite(M2,LOW);
analogWrite(E1,valueF);
analogWrite(E2,valueF);
break;
case 1://R=0,L=1
digitalWrite(M1,LOW);
digitalWrite(M2,HIGH);
analogWrite(E1,valueB);
analogWrite(E2,valueF);
break;
case 10://R=1,L=0
digitalWrite(M1,HIGH);
digitalWrite(M2,LOW);
analogWrite(E1,valueF);
analogWrite(E2,valueB);
break;
case 11://R=1,L=1
digitalWrite(M1,HIGH);
digitalWrite(M2,HIGH);
analogWrite(E1,valueF);
analogWrite(E2,valueF);
delay(800);
//force TURN
digitalWrite(M1,HIGH);
digitalWrite(M2,LOW);
analogWrite(E1,valueB);
analogWrite(E2,valueB);
delay(500);
break;
}
}
void MotorStop()
{
digitalWrite(M1, LOW);
digitalWrite(M2, LOW);
digitalWrite(E1, LOW);
digitalWrite(E2, LOW);
delay(100);
}
void TurnLEDStop()
{
digitalWrite(ledPin_R, LOW);
digitalWrite(ledPin_L, LOW);
}
10/7:モーター用の電源配線を基板化
9月末の時点でブレッドボードは2枚ありました。
センサーとモーター用電源です。
センサーは土日でやりましたので、今度はモーター用電源をやりました。
小型のトグルスイッチと、ピンソケットを万能基板につけて、それに電池ボックスからの配線をつなぎました。
トグルスイッチが小さすぎて、固定箇所がありません。これは失敗でした。
既にソフトウェア的にスタート・ストップの制御ができてるので、あまり頻繁なON/OFFはしないので大丈夫だとは思いますが。
実際に制作する場合は、ドリルでシャーシの穴を大きくして接着剤で固定するのが良いでしょう。
今回のトグルスイッチとその系列は、おおよそ6.5mmの穴があればスイッチ部分だけを表に出すようにできます。
今回の工作でも数か所に使っていますが、超薄型でハサミでカットできる万能基板があります。
ごく小さな基板が必要な場合には非常に便利です。
必要な大きさにカットできますからね。
今回は秋月電子が取り扱っている矢島製作所のものを使いましたが、ソレ以外だとサンハヤトのシール基板が同じような特性を持っています。
0.1mm厚で紙用のハサミでカットできます。
今回は穴を貫通して配線しましたが、表面に実装して配線した方が作業はしやすいです。
これは基板が薄すぎて作業中に曲がってしまい、位置決めがしづらいからです。
秋月電子では矢島製作所のハサミで切れる万能基板が、Amazonではサンハヤトのシール基板が手に入りやすいでしょう。
10/11:DCDCコンバーターの追加
これまで、この戦車は2種類の電池を使っていました。
Edisonへ給電するUSBモバイルバッテリーと、モーター用の単3ニッケル水素充電池4本です。
これを改めて、モーター用の電池からEdisonへ給電することにしました。
ですが、ニッケル水素充電池4本だと4.8Vしか出ない。
これだと電圧が足りません。
またモーターの負荷で電圧が変動するため、電圧が安定しません。
Edisonに給電する方法は「USBポートから5V」か「DCジャックかVinポートから7〜15V」の2パターンがあります。
今回は秋月電子の昇圧型DC/DCコンバータ5~25V可変出力電源モジュール組立キットを使いました。
Edisonのフルスペックを使おうと思うと、このくらいは欲しいです。
Wi-Fiがなければ、もっと安いコンバーターでもいけそうですが。
DCDCコンバーターは、Edisonの後ろに置きました。
後から改造してDCDCコンバータが不要になったら撤去できるよう、コンバーター本体との接続はピンソケットを使っています。
今回の工作で多用しているハサミで切れる万能基板を使って、ピンソケットをつけました。
同時に出力電圧を安定化するための電解コンデンサを裏面に固定しています。
DCDCコンバータの出力はドーターボードのVin端子へ接続しています。
ここの端子は7〜15Vが必要ですが、電圧を昇圧しすぎると電流が足りなくなるリスクがあるので、出力を8Vちょっとにしています。
※Arduinoボードは7〜15Vを入力すると、オンボードで5V等を生成しているようです。7Vが下限なのはおそらくレギュレータの都合です。
10/12:実走行テスト
ここまでの作業成果で、また走れるようになりました。
実際に走らせた様子を動画にとっています。
この状態の写真を以下に貼り付けます。
側面:重たい電池を前後方向にレイアウトしています。重心を前に向けるため、ギアボックスは前においています。
後ろ側:モーターの配線を短縮し、余った分をDCDC等の配線に使いました。ねじってるのはノイズ対策とバラけないようにするためです。
未解決の問題
現時点では、ここまで出来上がりました。
正直つたないですが、自分で作ったものが動くと感動しますね。
……ですが、解決しないといけない問題が残っています。
- (必須)Edisonをスタンドアロンで稼働させられるようにする。 (9/27:解決)
電圧はモバイルバッテリーで給電できるのですが、電源を入れただけだとスケッチが動きません。
どうやったら電源をいれるだけで動くようになるんでしょうか?
→Linux側の自動起動処理を追加しました。スケッチがない場合は動きません。 - 壁に寄り過ぎた時の対策ができてない。
測距センサーは壁に近寄りすぎると、距離が検出できなくなります。
ロボット掃除機のように至近距離はバンパースイッチなどでカバーする必要がありそうです。
また、今後の課題もまだまだあります。
- 動くものにブレッドボードは不安定すぎる。(10/4:解決)
→ユニバーサルシールド基板を載せました。別項で説明します。 - スタート/ストップを制御するスイッチがほしい。(10/4:解決)
→プログラム的にスタート/ストップするようにしました。 - 今のプログラムだと「Edisonらしさ」ではなく「Arduinoらしさ」になっている。
このままだと高くて大きなArduino止まりな気がしています。
これぞEdison!というのが欲しいところです。 - 動作状況を表示するためのLEDを実装できてない。(10/4:一応、解決)
→LEDを3個にしました。モーターの動作はモータードライバシールド側のLEDで代替 - 本物らしさなら、タイヤ駆動&ステアリングでは?
→タミヤの工作キットだとEdisonボードをのせるスペースが足りない……。トレーラーでの牽引にするかタテにのせないと多分ムリ。 - 10/4追加:右側モーターの駆動力が弱い。まともに走れない。(10/7:解決)
→かなり重大な問題です。
・プログラム的には左右に差はありません。
・テスターで確認しましたが、電圧は0.1Vくらい左右で違います。
・電源電圧が負荷で大きく変わる。静止時に5V、駆動時に3.4Vくらい。電池容量が足りてないんでしょうか?
→ブレッドボードを使ったことが問題だったようです。基板を介することで解決しました。 - 10/4追加:Edison用のバッテリーを載せる場所がない。(10/11:解決)
→2つの解決策があります。
① 薄型のバッテリーを買ってくる
② モーター用電池からDCDCコンバーターで昇圧して給電
→DCDCコンバーターを搭載しました。モーター駆動してもEdisonは安定していますので問題なさそうです。 - 10/4追加:整備性が悪い。電池交換のために全部バラバラにするのは面倒くさい。
→単4電池なら裏側に固定できそう……でも、電池容量が足りないかも。 - 10/4追加:モーターの配線がダサい。ノイズを拾って暴走することがある。(10/11:解決)
→ロボット用の細い多芯ケーブルとノイズキラー用のコンデンサを買い足しましたが、配線だけの問題なのかわかってません。細い配線だと余計にモーターのパワーが落ちそう。
→ブレッドボードを基板に交換した後、一度も発生していません。問題は解決したと判断しました。配線は短縮するだけにとどめました。
ちばとどさん
2015/09/22
> 電源をいれるだけで動くように
→ ターミナル(SSH)から、2ステップで出来ますよ。
① 次のファイルを作ります。
/home/root/sketch_auto.sh(ファイル名は自由です)
「
#!/bin/sh
/sketch/sketch.elf /dev/pts/0
」
②
/etc/systemd/system/sketch_auto_i2c.service を作成します。 (systemctl の制御に参加するためのファイル)
「
[Unit]
Description=sketch_auto service
[Service]
ExecStart=/home/root/sketch_auto.sh (①のファイル名と合わせます)
[Install]
WantedBy=multi-user.target
」
ファイルができたら、再起動します。いかがですか?
jakeさん
2015/09/22
今、出先なので、後で試してみますね。
そういやファームウェア更新後、一度もターミナルでログインしてないなあ(汗
ちばとどさん
2015/09/22
すみません、自分のメモをコピペしたので、ファイル名が変でした。
拡張子が、.service ならなんでもいいです。
> Edison!というのが欲しい
そりゃ、やっぱりWi-Fiの活用でしょう! ふふふ♪
jakeさん
2015/09/27
sysctlの追加が必要なのは盲点でしたが、無事に動くようになりました。