何かのジャンクにSharpのフォトダイオード(BS120)が一個だけ紛れていて、ずっとこれを使って何か作って見たいと考えていました。
Sharpのフォトダイオードは後継(?)のBS520という製品もあったようですが、現在は作ってないようです。
これまで気温などのセンサーは使ったことがありましたが、照度を計れるセンサーを試したことはありませんでした。
簡易の測定で、正確なルクスは必要なく、ある程度の傾向を見えるようにすることを目標にします。
照度センサーはBH1750FVIやTSL2561やMAX44009を使ったモジュールになってるものもありますが、昨今の情勢で中国発送の激安モジュールは入手困難と思われ、自作することにしました。
自作する場合、フォトダイオードやフォトトランジスタをセンサーとして使い、それをオペアンプで増幅してマイコンのAD変換で数値化するのが一般的です。
いろいろ検索したらこちらのページが見つかりました。
実際作った回路はこちらです。
この回路は電流電圧変換を行います。室内での測定を考えていて、それほど強い光が入らないため、帰還抵抗は1MΩにしました。直射が入る場合などは100KΩなどに小さくしたほうが良いです。
オペアンプは手持ちの単電源のNECのuPC358Cを使いました。電源は3.3Vなのですが、uPC358Cは3Vから使えるので大丈夫です。
マイコンでADCしてI2Cで蟹さんにデータを送ることにします。I2Cのslaveは以前ATTiny85で作っていたのですが、このモジュールは蟹さんで認識できません。プルアップ抵抗の調整なども試してみたのですが、ダメでした。
いろいろ思案した結果、他のマイコンでI2C Slaveを試してみることにしました。
マイコン箱を見たところATTiny85と同じ8ピンのPIC12F1822が目にとまりました。このチップでI2C Slaveを試してみます。
PIC12はPlatformioでは開発できないので、メーカー製のMPLAB X使う必要があります。MPLAB Xは以前MBA Originalにインストールしていたのですが、それより早いWin7機があるので、こちらにインストールして開発環境を作りました。PICのコンパイラーは古くはHI-TECH Cでその後XC Ver1になり、現在はXC Ver2になっています。
PIC12F1822のI2C Slaveはこちらのページに詳しく説明がありました。
コメントに残してありますが、こちらのコードはXC Ver1の頃のコードで2018/5/27 にリリースされたXC Ver2にはinterruptが__interruptと変更されています。MICROCHIPのよくわからないところは2019/5/9付のこちらのデモはXC Ver1で作られたようです。
これにADCのコードを埋め込みます。ADCについてはこちらに詳しく説明がありました。
以前Aitendoの処分品で購入したら書き込みアダプタを使って書き込みしてみました。
このアダプタは使い方によっては問題があるようですが、PIC12F1822は10KΩの抵抗を1ピンと4ピンに挟めば問題なく使えました。
直射が入ると2V位なのでADCの2024mVを参照電圧にするモードで試してみることにします。
PIC12F1822の回路はこんな感じです。
自分で作ってなんですが、蟹さんのI2Cは微妙に変な動きがあり、ちょっと苦戦しましたが、PIC12F1822 I2C Slaveから2バイトのAD値が拾えるようになりました。
ところが安定しません。
MacにつないだMCP2221ではちゃんと読めます。
いろいろ試していたところ、最初の回路図で帰還抵抗と並列の0.1uFのコンデンサーを入れたところ安定しました。
mrubyでスクリプトを書いてThingSpeakに投げてIoT(Internet of Test)してみました。
さほど明るくない1階の東向きの曇りガラスの窓際に置いてみました。フォトダイオードはブレッドボードに挿した状態で横向きです。正しく計るには水平にするのが良いようです。
国立天文台のデータでは日の入りは18:24で日の出は4:54だったので大きな間違いはなさそうです。
一番下は10mVくらいなのですが、10mVくらいになってもまだ文字を読めるくらい明るく、それ以降は数値化できていません。
また時々I2Cで読み取る値にエラーがあるので、mrubyのスクリプトで2048以上の数値は省いています。
いろいろ調整が必要と思われます。
最初に参考にしたページではアナログスイッチICでゲインを変えて細かく値を取り込むような方法をとってるいるようです。似たような方法でマイコンのIOでゲインを変える試みもありました。
晴天時の日中の直射が100000ルクスに対して、文字が読めるぎりぎりの明るさが10ルクスまでを計るのは難しい。
改良その壱
オペアンプを二段にしてゲインを上げフォトダイオードをレアチーズケーキの白いカップで覆いゲインを下げてみました。
あわせて、FVRCONを2024でADCして1000以下の場合は1012でADCするようにしてみました。FVRCON変えて直ぐにGOすると正しく動かなかったので__delay_us(200)を入れました。
改良その弐
最初にVCCの3.3Vを基準電圧でADCして、その値が990mV以下の時はx1で1990mV以下の時はFVRCON x2でもう一度ADCして値とするようにしました。あたりまえですがVCCが3.3VのときはFVRCON x4(4.096V)は使えません。
CRCを計算して3バイト目をCRCとした。割込みハンドラ内でCRCを計算したところ蟹さんのI2Cで転送が失敗するようになったので、mainで計算するようにした。
帰還抵抗を3MΩにしてみましが、大きな改善は見られませんでした。
VCCを基準電圧にしてADCするとADCが飽和する前にオペアンプが飽和します。
夕方ノイズレベルまで下がった時点で照度が計れるテスターで見たところ35Luxでした。日の入りの1時間前でした。
改善その参
フォトダイオードを水平に置いてみました。
白いカップの文字を消しました。
改善その四
ブレットボードからユニバーサル基板に移しました。帰還抵抗をスペースの関係で、2.2MΩにしました。
フォトダイオードを固定しました。
改善その五
動作が不安定になり、半田付けを確認して補修しました。半田ごてがボロくて、いも半田になりやすいです。
朝は東側の窓からの光が入り、昼は壁に遮られますが、昼過ぎはピークは南側の窓からの光と思われます。考えれば至極当たり前ですが、グラフにするとより状況が把握しやすいと思います。
14時前に急激に降下してなだらかな降下に変わるのは我が家が南中に対して東へ25度角度があり、太陽の方位が245度を越えると直接の光は入らなくなるためと思われます。
太陽の方位と時間の関係は日々変わっていきます。
いろいろ試してみて、どこにセンサーを置くかが重要な気がします。
BH1750が手に入ったので、並べて比較してみたのですが、この仕組みで測定できるのは20Luxから1000Lux弱くらいのようです。
おまけ
PICの書き込みアダプタに空いていたRJ11のパターンを使って10Kの抵抗のソケットをつけてみました。