DesignSpark Electrical Logolinkedin
Menu 検索
フォーラムで質問

Arduinoを使った色選別マシーン

この動画は、カラフルキャンディー 「Skittles」の色を認識し選別するマシンです。Arduinoを使って作ってみました。今回の製作のおかげで、ステッピングモータ・サーボモータの制御方法、それから色を識別し分類するプログラムを学ぶことができました。これらの経験は、今後のロボット開発のための基礎力になったと実感しています。   

もしご興味ある方は、プロジェクトのファイルをこちらのGitHubから入手できます⇒ GitHub

開発のフェーズ分け

この色選別マシーンでは、物質(ここではSkittlesキャンディー)をその色毎に5つの異なる器に分類します。このマシーンは、サーボモータで回転するガイドアームにホッパーからカウンタを投入することで機能します。アームには丸い保持穴があり、カウンタをRGBカラーセンサの下に移動させます。センサによって色が判定されたら、ステッピングモータで回転するプラッターがその色の正しい位置(収集ポイントの下)に移動します。その後、アームがカウンタを放出孔の上に移動させ、コンテナに落とします。この時点でアームは最初の位置に戻り、同じサイクルを繰り返します。Arduino Uno (715-4081) マイクロコントローラボードは、さまざまな部品の機能を連係させます。

このようなマシンを作るには、乗り越えなければならない設計上の課題がいくつもあります。そこで、プロジェクトを3つの独立した部品に分割し、個別に組み立て、テストすることで問題に対処しました。こうすることにより、各ソリューションを組み合わせてマシンを完成させる前に、より小さな部分の設計に集中することができました。

サーボモーターの制御

まず、回転プラッターを設計、作成し、コードを記述しました。RS Proステッピングモータ(535-0489) を使用しました。この汎用モータはバイポーラの4線式モータで、1回転につき200ステップを実行できます。このプロジェクトには十分過ぎるトルクが備わり、今後考え得るさまざまな用途のマシンで使用できます。

バイポーラステッピングモータには2個のコイルがあります。電源を入れると、モータをいずれかの方向に回転させ、非常に正確に、一度に1ステップずつ実行します。1回転ごとに実行できるステップの数は、モータの仕様で決まります。Arduinoを使ってモータを制御するにはHブリッジ回路が必要ですが、問題を単純化するためにEasyDriverボードを使用しました。このボードはオープンソース設計で質の高いドキュメントが提供されています。

EasyDriverは、制御するのにArduinoのデジタルI/Oピンを3本しか必要としません。1本のピンで、モータがステップを実行する1ミリ秒間隔のパルスを送信します。もう1本のピンで回転方向を決め、3本目のピンでモータを有効にします。これにより、モータが停止しているときの電流を減らすことができます。EasyDriverのデフォルトの設定では、⅛ステップというマイクロステップで、よりスムーズな回転を実現します。

StepTest.inoには配列が含まれています。配列のインデックスはそれぞれ、ソートする5つの色のいずれかを表します。配列の値は、プラッターが戻る必要がある最初の位置又は収集ポイントを、ゼロベースのポジションで示します。

int indexArray[] = {0, 4, 3, 2, 1};

配列の値は、プラッターが1ポジション移動するたびに更新されます。そのため、特定のインデックスを最初のポジションに戻すには、最適な方向とポジションの数を計算します。setPosition()関数でこの処理を行います。

move()関数は、プラッターが移動するポジションの数と方向を受け取ります。1ポジション移動するには、モータは1回転で200ステップ(1ステップは8マイクロステップ)進み、5ポジション移動するため、320 (200 * 8 / 5)ステップが必要となります。以下は、この処理を行っている重要なコード部分です。

for (int i = 0; i < steps; i++)   // Move the number of micro-steps
 {
   digitalWrite(stp, HIGH); //Trigger one step forward
   delay(1);
   digitalWrite(stp, LOW); // Pull step pin low so it can be triggered again
   delay(1);
 }

これは、あらゆる種類のステッピングモータプロジェクトで使用できるシンプルなテクニックです。

駆動部分を制作

次に行うのは、組み立てとコーディングです。着色されたカウンタを色識別マシーンの土台とアームが動かせるようにします。これは扱いやすい3mmのハードボードを使って組み立てました。アームの制御には、Parallax標準サーボモータ(781-3058) を土台の下に取り付けて使用しました。サーボモータは、スタート位置に自動的に戻るため、アームの制御に最適です。Arduinoサーボライブラリでは、1本の制御ピンを使って、サーボが元のポジションから回転する角度を設定します。

ServoTest.inoには、独立した関数のmoveToOrigin()・moveToSensor()・moveToEjector()が含まれています。これらの関数は、サーボに必要な3つのポジションをカプセル化します。

次のコードは、指定された角度で移動します。ループをインクリメントすることで、スムーズさは失われますが移動を高速化できます。個々のポジションに到達するまで、少し待つ必要があります。

for (pos = 0; pos <= 30; pos += 1) { // goes from 0 degrees to 30 degrees in steps of 1 degree
   myservo.write(pos);              // tell servo to go to position in variable 'pos'
   delay(15);                       // waits 15ms for the servo to reach the position
 }

繰り返しますが、このテクニックはほとんどのサーボ駆動プロジェクトで使用できます。

色を認識

パズルの最後の部品はカラーセンサでした。これには、AdafruitのTCS34725ベースのボードを使用しました。色の感知は難しい課題です。このボードには、色温度を算出できる高度なライブラリが付属しています。カウンタごとの色の判断には、この色温度を使用しました。

SensorTest.inoでは、個々の色の較正値を取得し、センサをテストします。センサは照明の変化の影響を受けやすいため、この処理は周囲の照明の状況を同じにして行うようにしてください。特定の色に対し信頼性の高い色温度マップを作成することが、このプロジェクトの最も難しい部分です。色覚異常を持つ人が苦しむ理由がわかります。

テストコードは、各色の色温度の最小値と最大値をArduinoのシリアルモニタに出力します。最後のコードでこのマップを使用して、プラッターの正しいポジションのインデックスを示します。

ひとつにまとめる

プロジェクトの個々の部品を開発したので、テストしたすべてのものをColourSorter.inoでまとめます。

7Vに設定されたベンチ電源を使用しました。これはサーボにはややオーバースペックですが、問題ありませんでした。つまり、回路の追加は不要でした。

getIndex()関数の追加が重要です。この関数には、センサの較正で取得した色温度ごとに境界を設定する一連のif文が含まれています。この関数の戻り値は、その色に対するプラッターのインデックスポジションです。これを使用してステッピングモータを駆動させます。

if (colour > 3878 && colour <= 4183) {
   Serial.println("Yellow");
   return index = 1;
 }

バックトゥザフューチャー

このプロジェクトの作成は、ステッピングモータとサーボモータの操作だけでなく、着色された物体の分類についてもとても楽しく学ぶことができます。他の電子機械プロジェクトやロボットプロジェクトに欠かせない、本当に優れた要素です。

このプロジェクトで最も難しい課題は、正確かつ一貫した色の読み取りです。さらに手を加えるなら、「拒否」されたものを集めるプラッターポジションを追加したかもしれません。そうすれば、色温度マップ内に空白部分を作成し、より厳密に色の許容範囲を設定できるでしょう。その後、分類されなかったカウンタを拒否して返却します。

そうは言っても、Arduino 色識別マシン は98~99%の精度を達成しています。色を分類する代わりの方法についていい案があれば、以下にコメントしてください。

それから、これを作りながらSkittlesを食べ過ぎないようにしてくださいね!

I'm a big Open Source fan and Linux aficionado with a penchant for Italian motorbikes

9 May 2019, 15:35