フォトリフレクタの感度をソフトで調整

こんにちは.けりです.
今回は,マイクロマウスに使っているフォトリフレクタのお話です.

フォトリフレクタの感度は悩みの種

僕自身,フォトリフレクタの感度にはかなり悩まされました.

探索で前壁を判定するにはある程度の輝度が必要

マウスを小型化すると,壁からの距離が遠くなります.特に探索走行中の前壁は結構遠く,赤外線LEDを強めに光らせないと届きません.

LEDを強く光らせると問題が発生

光を強くすると,近くで飽和してしまったり,光が散乱して異なる方向からやってきたりします.

また,LEDに大電流を流すと,電源に負担がかかり,様々な部分に影響を及ぼします.

ハーフサイズのマウスではバッテリーの持ち時間にも大きな影響を与えるでしょう.

LEDの明るさを変えるのは大変

一般的な発光回路では,抵抗や定電流回路を使うので,明るさは固定になります.しかも,ハードウェアなので,パラメータチューニングは大変です.

今回考えること

ソフトウェアで赤外線LEDの明るさを調整する方法

ハードウェアは固定でも,ソフトウェアでLEDの明るさを調整できれば,これらの問題を解決することができます.

ソリューション

森永式発光回路を使う

まずはこちらの回路図をご覧ください.

森永式発光回路

森永式発光回路

こちらは森永式と呼ばれる発光回路で,電源Vから直接LEDを光らせるのではく,少し大きめのコンデンサに充電して,その電気でLEDを発光させるというものです.

FETがオフのとき,LEDは消灯しコンデンサが充電されます.

FETがオンになると,コンデンサからLEDに一気に電流が流れ,一瞬だけLEDが明るく光ります.

ソフトウェアでの調光

森永式発光方法では,充電時間によりLEDの明るさが決まります.充電時間はソフトウェアで設定できるので,調光可能というわけです.

サンプルコード

こんな感じで充電時間を引数に取る関数で計測すればできます.

delayの部分は適宜タイマー割り込みなどを使用するとよいでしょう.

/** フォトリフレクタのサンプリング関数. 
    @param charge_time_us コンデンサへの充電時間[us]
    @return 測定データ
*/
uint16_t sampling(const int ch, const int charge_time_us = 1000) {
    digitalWrite(tx_pins[ch], LOW); //< コンデンサへの充電開始
    delayMicroseconds(charge_time_us);  //< 波形がピークになるまで待つ
    digitalWrite(tx_pins[ch], HIGH);    //< 充電終了 & 放電開始
    delayMicroseconds(10);  //< 波形がピークになるまで待つ
    return analogRead(rx_pins[ch]); //< ADC結果を返す
}

まとめ

この発光方法を考えた森永さんはすごいですね.

僕は2つのレンジを用意して,壁検出用と壁制御用に使い分けています.