2010年2月12日金曜日

小型で安価な回転角を検出する装置

ホビーでロボット系の工作をする際に,モーターの回転角や回転速度の検出が良く問題になると思います.RCサーボがこの手の工作で頻繁に使われている理由として,角度の検出部を自分で工作することが困難なことがあげられると思うのですがどうでしょう?

アナログ型光学式ロータリーエンコーダ


そこでここでは,アナログ型の光学式ロータリーエンコーダによって角度を検出する方法を提案してみます.通常光学式のロータリーエンコーダにおいては下の図のようなスリットを持った回転円板を用います.
このような円板は手作りすることが困難であり,高精度の物は高価になります.また,絶対値型のエンコーダはスリットやセンサーの数が多く,自作は非常に困難で大型になってしまいます.そこで,ここでは以下のようなグレースケールを持つ円板
を用いて,以下の図のように配置されたセンサーを用いることを考えます.


グレースケールを持つ円板はプリンタで簡単に作成できますし,センサの組み付け精度などもそれほど必要とされないのでこのような装置は比較的簡単に作成することが出来ます.

試作機

次に実際に試作品を作ってみた結果を示します.
円板はプリンタで印刷したもので,後ろの田宮の小型ギアボックスは回転軸の固定&テスト用です.


センサー部は適当に買ってきた反射型のフォトインタラプタを2個,回転軸について90度対称な位置に配置しただけです.


組み合わせると下の写真のような感じになります.


動作テストの様子です.


動画で使っている円板は黒い部分の半径を変化させてグラデーション円板の代用とした物です.透過型のフォトインタラプタを用いる場合やグレーが使えない場合に有用なのではないかと思います.
いい加減な工作ですが,それらしい波形が出ていることが確認できます.もう少し真面目に作れば,実用的な角度センサになるのではないでしょうか.

9 件のコメント:

Unknown さんのコメント...

初めまして.
動画のモノクロの回転板(黒円の半径を変化)の方は,回転速度に対してコントラストの円周長の比が1:1になる様に,速度毎にセンシング位置を変えているのでしょうか…(多分違うのだとは思いますが)

後,MouseoverDictionaryは,FireFox3.6以降は対応のご予定はないのでしょうか.

丸田 一郎 (Ichiro Maruta) さんのコメント...

センシング位置は常に一定ですので,
おっしゃるような複雑なことはしていないと思います.

MouseoverDictionaryに関しては,
今使ってるPCに入れる英辞郎のライセンスを持っておらず,古いPCを引っ張り出さないと開発できないためにちょっととまっています.
新しい版を購入したら対応するかもしれません.

匿名 さんのコメント...

ブログ投稿をありがとうございます。
このプロジェクトを続けてきた?
今まで円板をグレースケール試してみましたか?

(私の悪い日本語を許してください。アメリカ人です。)

丸田 一郎 (Ichiro Maruta) さんのコメント...

Thank you for your comment!
I also tried the disk with grey-scale (not used in the movie, but appears in above photos) and it works well.

匿名 さんのコメント...

Thank you! This is a great technique. I have blogged about it here:

http://botscene.net/2012/10/18/make-a-low-cost-absolute-encoder/

Tobias さんのコメント...

This looks very interesting. How fine was the resolution you were able to achieve with this approach? Would you care to elaborate what kind of sensors you used specifically?

匿名 さんのコメント...

Thank you for sharing your brilliant design a combination of Tesla polyphase and art.
A couple of quick suggestions that may improve accuracy adding a pot on the side of your photoresistor and another pot on the diode to get them as close as possible to a perfect sine wave at 90 degrees out. Was able to get just better than 5 degree resolution on slow rpms with a sketchy diy build. Someone should be manufacturing this because it really is an amazing idea. Here is the arduino source used, hope it helps you in your future builds. Thanks Again

void calibrate_encoder()
{
// Add Motor Turn On & Start Motor
for (int i = 0; i < 30000; i++)
{
encoder_a = analogRead(0);
encoder_b = analogRead(1);

if (encoder_a < encoder_min_a)
{
encoder_min_a = encoder_a;
}
if (encoder_a > encoder_max_a)
{
encoder_max_a = encoder_a;
}
if (encoder_b < encoder_min_b)
{
encoder_min_b = encoder_b;
}
if (encoder_b > encoder_max_b)
{
encoder_max_b = encoder_b;
}
delay(1);
}
encoder_spread_a = encoder_max_a - encoder_min_a;
encoder_spread_b = encoder_max_b - encoder_min_b;

encoder_a_last = encoder_a;
encoder_b_last = encoder_b;
// Turn Off Motor & Reset Timer
}

void encoder_update()
{
encoder_a = analogRead(0);
encoder_b = analogRead(1);
if (encoder_a < encoder_min_a)
{
encoder_a = encoder_min_a;
}
if (encoder_a > encoder_max_a)
{
encoder_a = encoder_max_a;
}
if (encoder_b < encoder_min_b)
{
encoder_b = encoder_min_b;
}
if (encoder_b > encoder_max_b)
{
encoder_b = encoder_max_b;
}
encoder_position_a = encoder_a - encoder_min_a;
encoder_position_b = encoder_b - encoder_min_b;

encoder_angle_a = (float) encoder_position_a / encoder_spread_a;
encoder_angle_b = (float) encoder_position_b / encoder_spread_b;

// Angle A
if (encoder_angle_b <= 0.5)
{
encoder_angle_aa = encoder_angle_a / 2.0;
}
else
{
encoder_angle_aa = ((1.0 - encoder_angle_a) + 1.0) / 2.0;
}
encoder_angle_aa -= 0.125;
if (encoder_angle_aa < 0.0)
{
encoder_angle_aa += 1.0;
}
if (encoder_angle_aa >= 1.0)
{
encoder_angle_aa -= 1.0;
}


// Angle B
if (encoder_angle_a >= 0.5)
{
encoder_angle_bb = encoder_angle_b / 2.0;
}
else
{
encoder_angle_bb = ((1.0 - encoder_angle_b) + 1.0) / 2.0;
}
encoder_angle_bb += 0.125;
if (encoder_angle_aa < 0.0)
{
encoder_angle_aa += 1.0;
}
if (encoder_angle_bb >= 1.0)
{
encoder_angle_bb -= 1.0;
}

if (encoder_angle_aa < .25 && encoder_angle_bb > .75)
{
encoder_angle = (1.0 + encoder_angle_aa + encoder_angle_bb) / 2.0;
}
else if (encoder_angle_bb < .25 && encoder_angle_aa > .75)
{
encoder_angle = (1.0 + encoder_angle_aa + encoder_angle_bb) / 2.0;
}
else
{
encoder_angle = (encoder_angle_aa + encoder_angle_bb) / 2.0;
}
if (encoder_angle < 0.0)
{
encoder_angle = 1.0 - encoder_angle;
}
if (encoder_angle >= 1.0)
{
encoder_angle = encoder_angle - 1.0;
}

encoder_angle = encoder_angle * 359.0;
encoder_angle_int = (int) encoder_angle;

/*
Serial.println("X1 X2");

Serial.println(angle_a);

Serial.println(angle_b);

Serial.println(angle_aa);
Serial.println(angle_bb);
Serial.println(angle);

Serial.println(angle_int);
*/
}

匿名 さんのコメント...


Jenis terjemahan
Terjemahan teks
INDONESIA
JEPANG
Teks sumber
Semalam saya mendesain dan mencetak disk skala abu-abu untuk proyek sensor sudut saya. Saya mencari ide serupa di internet namun tidak menemukannya, saya pikir ini ide yang buruk hingga tidak ada orang lain yang mencobanya. Namun pagi harinya secara tidak sengaja saya menemukan postingan ini dan menunjukkan hasil pengujian yg sesuai dengan yang saya pikirkan. Jadi saya bisa melanjutkan proyek impian saya. Terima kasih telah berbagi ide yang menarik dan secara kebetulan mempunyai pemikiran yang sama.

Maaf bahasa jepang saya yang buruk karena menggunakan google translate.
Semalam saya mendesain dan mencetak disk skala abu-abu untuk proyek sensor sudut saya. Saya mencari ide serupa di internet namun tidak menemukannya, saya pikir ini ide yang buruk hingga tidak ada orang lain yang mencobanya. Namun pagi harinya secara tidak sengaja saya menemukan postingan ini dan menunjukkan hasil pengujian yg sesuai dengan yang saya pikirkan. Jadi saya bisa melanjutkan proyek impian saya. Terima kasih telah berbagi ide yang menarik dan secara kebetulan mempunyai pemikiran yang sama.

Maaf bahasa jepang saya yang buruk karena menggunakan google translate.
577 / 5.000
Hasil terjemahan
昨夜、角度センサー プロジェクト用にグレースケール ディスクをデザインして印刷しました。 私はインターネットで同様のアイデアを探しましたが、それを見つけることができませんでした. しかし、翌朝、偶然この投稿を見つけて、思っていたものと一致するテスト結果を示してくれました。 だから私は夢のプロジェクトを続けることができます。 興味深いアイデアを共有してくれて、偶然にも同じ考えを持ってくれてありがとう.

グーグル翻訳を使って下手な日本語でごめんなさい。

tsu さんのコメント...

Very interesting idea. What do you think about one that uses rgb colour sensors so that hopefully it will be more accurate when lighting conditions are changing.