スポンサーリンク

LEDを光センサとして利用したり光らせたりと「光る光センサ」にする実験をしてみた

スポンサーリンク

先日は、基本的な半導体の構造が同じなことを利用して、LEDを太陽電池として利用する実験をしてみました。

今回は、LEDを、光センサとしても、LEDとして光らせることもできる「光る光センサ」の実験をしてみたいと思います。

スポンサーリンク

発電を利用した光センサ

LEDに光を当てると、発電することがわかったので、上記のような光センサとしての回路を試してみました。

回路図左側のLEDに光を当てると、LEDが発電して電圧が上がり、その電圧がNOTゲートのスレッショルド電圧を超えると、NOTゲートが反転します。もう一つNOTゲートがあるのでさらに反転します。そのため結果的には、左側のLEDに光が当たると、右側のLEDが光るという回路になっています。

今回は、光源のLEDは白色LEDとして、受光側のLEDには白色LEDに反応しやすかった黄色のLEDにしました。NOTゲートには74HC04を使っています。

実験した結果、受光側のLEDの発電電圧が低く、なかなかNOTゲートのスレッショルドを超える電圧になりません。光源のLEDと受光のLEDをピッタリとくっつけてやっと反応する程度です。

光センサとして利用するには、かなり感度が低い結果となりました。

スポンサーリンク

LEDを逆バイアスにしてみる

今度はLEDを逆バイアスにして、センサとして利用できるか実験してみます。逆バイアスとは、上記の回路の左側のLEDのように、LEDのマイナス極(カソード)を電源に接続して、プラス極(アノード)から信号を得ます。

通常ですと、LEDのマイナス極(カソード)の電圧が高く、プラス極(アノード)の電圧が低いため、ダイオードの特性によって電流は流れず、アノードには電気が流れてきません。この状態ではもちろん右側のLEDは光りません。

この回路で、左側の受光側のLEDに光を当てると…

青いLEDが光りました。受光側のLEDが光センサとして機能しています。発電の回路よりも、逆バイアスの回路の方が、光に対して感度が良い感じです。

LEDに光が当たることで、ダイオードとして特性が弱まることで、逆バイアスの電流が若干流れ出してくるようです。

NOTゲートの入力には、10MΩの抵抗でプルダウンしました。かなりの高抵抗ですが、ないと安定して動作しません。というのも、光に反応した後、光源を離しても反応した状態が続いてしまいます。電気がたまってしまうようなので、その電気を逃す抵抗が必要でした。ただし、抵抗値が2MΩより低いと光センサとして動作しなくなってしまいます。そこで、10MΩとしました。

スポンサーリンク

LEDを「光る光センサ」にするには

LEDに逆バイアスをかけることで、光センサとして利用できることがわかりました。続いて、光ることもできるし、光センサとしても利用できる回路を考えます。

上記がその回路になります。ロジックICが3Vなので、マイコンにはarduinoではなく、3V程度で動作するLPC1114を利用しました。LPC1114はmbedを利用して簡単にプログラミングができます。

ブレッドボードに部品を刺したり抜いたり、mbedでマイコンの実験をするのに最適なDIP型のマイコンLPC1114の便利な実験セットを販売しています。マイコンの入門にも最適です。
mbedねこちゃん

光センサとして利用する時

光センサとして利用する場合、マイコンのledKのピンをHに、ledAのピンをLにします。こうすることでLEDが逆バイアスの状態になり、LEDが光センサとして機能します。

NOTゲートの結果をマイコンのledSensorピンに入力して、Lだったら光に反応していると判断し、Hだったら光に反応していないと判断します。(NOTゲートが1つだけなので、先ほどの実験と結果が反転しています)

LEDを光らせる時

LEDを光らせる場合は、ledAのピンをHの状態にします。この状態で、ledKのピンをLにするとLEDに電流が流れLEDが点灯します。ledKピンをHにすると電流が流れないのでLEDが消灯します。

プログラムを作って実験してみる

仕組みが決まったので、プログラムにしてみます。0.5秒ごとにONとOFFを繰り返すLED(黄色)を、0.1秒ごとに一瞬だけ光センサとして動作させて、測定した結果を別のLED(青)へ出力してみます。

#include "mbed.h"

DigitalOut ledK(dp13);
DigitalOut ledA(dp14);
DigitalIn ledSensor(dp1);

DigitalOut led(dp15);

bool lightDetect();

int main() {
    while(1) {
        
        for( int i=0 ; i<5 ; i ++ )
        { 
            ledA = 1;   //光センサ点灯
            ledK = 0;
            wait(0.1);
            led = lightDetect();    //センサ状態をLEDへ出力
        }
        
        for( int i=0 ; i<5 ; i ++ )
        { 
            ledA = 1;   //光センサ消灯
            ledK = 1;
            wait(0.1);
            led = lightDetect();    //センサ状態をLEDへ出力
        }
    }
}

//光センサとして光を検知する
bool lightDetect()
{
    ledA = 0;   //光センサのモードにする
    ledK = 1;
    wait(0.001);    //1ms光センサのモード
    bool sense = ledSensor; //センサの状態を読み込む
    
    ledA = 1;   //発光モードにする
    return sense;
}

こちらが、プログラムです。dp13,dp14につながったLEDが光センサとしても利用するLED。dp15につながったLEDが出力のLEDです。

実際に動作させてみましょう。

左側の黄色の点滅しているLEDが、光センサにもなるLEDです。光源の白色LEDを近づけると、反応して右側の青いLEDが点灯していますね。

LEDが、光センサとしても、発光デバイスとしても利用できるようになりました。「光る光センサ」ができました。

ちなみに、NOTゲートを省略してLPC1114の入力ピンに光センサのLEDを直接つないだところ、LPC1114の入力インピーダンスが低いため、光センサとして動作しませんでした。

スポンサーリンク

たくさんのLEDを「光る光センサ」にする

完成した「光る光センサ」にはLED1つあたり3つのポートが必要です。たくさんの「光る光センサ」をマイコンで利用しようとすると、ポートがすぐに不足してしまいます。

そこで、なるべく少ないポート数で、「光る光センサ」をたくさん利用するための回路を考えました。

光センサとして利用する時

光センサとして利用する場合には、これまで同様ledAのピンをLにします。そして調べたいLEDのledKのピンだけをHにします。これで特定のLEDだけ逆バイアスになり、光センサになります。

例えば、上記の図のようにledK1だけをHにすると、D1のLEDが光センサとして機能するので、ledSensorの出力を読み取ってD1のLEDが光に反応しているかを判断します。

次にledK2だけをHにして、ledSensorの出力を読み取ります。次にledK3だけHにして…と、LEDの数だけスキャンしていきます。

上記の図では、これまで10MΩだった抵抗のところがトランジスタに変更になり、そのトランジスタを制御する「flash」という新しいピンが増えています。これは、スキャンの方式に変更したところ、10MΩの抵抗では光に反応した時の電気の放電が間に合わず、1カ所のLEDが反応すると電気が抜けるのが遅いために、他のLEDも反応したかのような現象が起きてしまいました。そこで、強制放電させる回路にしました。

具体的には、

  • ledK1をH
  • ledSensorの結果を読み込み
  • ledK1をL
  • flashを一瞬H

とします。これを全てのLED ledK1〜ledKnまでスキャンしていきます。

LEDを光らせる場合

LEDを光らせる場合には、ledAをHにします。そして、光らせたいLEDのみLにして、光らせたくないLEDはHにします。こうすることで、LにしたLEDにのみ電流が流れLEDが光ります。上記の例の場合、ledK1のみLなので、D1のLEDだけが光ります。

実際にやってみた

「光る光センサ」8個にしてみました。ledK1からledK8までの8本と、ledA、ledSensor、flashの3本、合計11本のポート数で実現できます。

プログラムはこうなりました。

#include "mbed.h"

DigitalOut ledK[8] = { dp1, dp2, dp4, dp6, dp9, dp10, dp13, dp14};
DigitalOut ledA(dp11);

DigitalIn ledSensor(dp15);

bool sensorArray[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
bool ledArray[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };

DigitalOut led(dp17);
DigitalOut flash(dp5);

void lightDetect();

int main() {
    
    for( int i=0 ; i<8 ; i++ )
        ledK[i] = 1;
    flash = 1;
        
    while(1) {
        
        lightDetect();    //センサ状態を取得
        
        ledA = 0;   //光センサ点灯
        for( int i=0 ; i< 8 ; i++ )
        {
            if( sensorArray[i] == 1 )
                ledArray[i] = 1;
            
            if( ledArray[i] == 0 )
                ledK[i] = 1;
            else
                ledK[i] = 0;
        }
        wait(0.01);           
    }
}

//光センサとして光を検知する
void lightDetect()
{
    ledA = 1;   //光センサのモードにする
    for( int j=0 ; j<8 ; j++ )  //全てのセンサをOFFにする
    {
        ledK[j] = 0;
        sensorArray[j] = 0;
    }   
    for( int i=0 ; i< 8 ; i++ )
    {        
        flash = 0;
        wait(0.0001);
        flash = 1;
        
        ledK[i] = 1;    //特定のセンサのみONにする
        wait(0.0001);
        bool res = ledSensor; //センサの状態を読み込む
        if( res == 0 )
            sensorArray[i] = 1;
        else
            sensorArray[i] = 0;
        if( i== 3 )
            led = sensorArray[i]; 
        //wait(3);    //1ms光センサのモード
        ledK[i] = 0;    //特定のセンサをOFFにする
    }
    return;
}

実際に動作させるとこうなります。

光源の光に反応して、「光る光センサ」が点灯していく様子がわかりますね。

LEDを使った「光る光センサ」ができたので、これでちょっと遊んでみたいと思います。

2020.8.31 追加 つづきはこちら

追加終わり

今回実験した原理を使った「キャンドルパニック」ゲームキットができました。こちら👇👇で販売しています。

 

LPC1114とmbedを使った、便利な実験セット販売しています。ブレッドボードに部品を刺したり抜いたり、マイコンの実験をするのに最適なDIP型のマイコンLPC1114です。マイコンの入門にも最適!
mbedねこちゃん

コメント