カラーセンサモジュールを入手したので、使って見たいと思います。
今回購入したのは、以下図の様なモジュールです。
このモジュールに搭載されているのは、AVAGO社のAPDS9960と言うチップでした。まずは、データシートを検索しておきましょう。
APDS9960データシートを検索(別ウインドウが開きます)
データシートより、以下の様な特長を持つチップだと解りました。
特長:
主たる機能としては、ジェスチャセンサ👋らしいです。赤外線LEDを発光させ、反射して戻ってきた赤外線強度を上下/左右の4方向へ向けたフォトトランジスタで受け、「ジェスチャ(手の動き等)」を検出するセンサです。
同時に、環境光センサと、カラーセンサを内蔵しています。何を隠そうカラーセンサを使いたくて、このモジュールを購入しました。ので、ジェスチャセンサは、さておき、カラーセンサとして使って見たいと思います。
今回のお買い物は以下の通りです。
AmazonのEasyWordMallと言う中華ショップで、中国から発送される商品でした。配送料150円でした。配送料込みで充分安かったので、このショップに決めました。前から何度か使ってきたショップなので、安心感もありました(個人の感想です。今までトラブルには見舞われていないので)。
データシートを参照して、APDS9960のカラーセンサ使用手順を以下にまとめます。
カラーセンサ使用手順:
ENABLEレジスタのAENビットとPONビットをクリアしない限り、カラーセンサが動作し続けるので、繰り返し連続して変換結果を読み出すことが可能です。
Blocklyを使ったプログラミングは楽しいです。
けど、M5StickC PlusのUIFlow(Blockly)はバグも多いし、Python処理系によるインタープリタ方式の開発環境なため、ESP32 @240MHzの能力を全く活かせないことが不満です。処理能力不足が原因で上手く制御し切れなかったこともしばしば在りました。その度に、UIFlowをあきらめてArduinoを使った開発環境に戻るのが煩わしいのでした。
今回の様な、カラーセンサから計測値を読み出してTFT画面に表示するだけの応用であれば、手軽に使えるし、バグに阻害される可能性も低いので、こんな時こそUIFlow一番の使い所だと思われます。UIFlowの環境立ち上げ等については、こちらを参照してください。
※本格的なプログラムを作成する場合、UIFlow開発環境は推奨しません。恐らく、UIFlowのバグに悩まされることになるからです。Arduino(C言語)を使いましょう。
M5StickC Plus+UIFlowで作成したプログラムを以下にリンクしておきます。
完成プログラム:chameleon.m5f
M5StickC PlusのUIFlowで読み込んでご覧ください。
完成プログラムをリンクした後で何ですが、実はAPDS9960モジュールからカラーデータレジスタを読み出すだけでは、それが何色なのかを知ることはできません。次節で解説しましょう。
APDS9960には、カラーセンサ用として4個のフォトトランジスタと4種類の光学フィルタが搭載されています。
光学フィルタ:
フォトトランジスタで各色の強度を検知、AD変換してデジタルデータとして読み出すことができます。AD変換器の解像度は10ビットです。これを何回かサンプリングして加算する事で、最大16ビット解像度のデータを取得することができます。
読み出したRGB値をそのまま色として使えるか?と言うと、それは否です。
光学カラーフィルタ等の特性、フォトトランジスタの個体差、そもそも、RGB各色の光の強度等により、取得できるカラーデータの最大/最小値が変動するためです。
例)RGB=(255,128,0)が読めたからと言って、「橙色」とは限らない
次の実験で、取り得る値の最大値を計測し、APDS9960のカラーセンサを校正して使って見ようと思います。
UIFlow環境を立ち上げたM5StickC PlusをUSBケーブルでPCと接続します。シリアルモニタを使って計測データを吸い上げるため、PCとのUSB接続が必要です。次に、APDS9960モジュールとM5StickC Plusを以下表の通りに接続してください。
M5StickC Plus | 接続 | APDS9960モジュール |
3V3 | → | VCC |
GND | ⇔ | GND |
D0(SCL) | ⇔ | SCL |
D26(SDA) | ⇔ | SDA |
× | INT(未使用) | |
× | VL |
※IR LEDは使わないので、APDS9960のVL端子は、接続しなくて良いと思われます。
こちらのプログラムをUIFlowで実行してください。
以下図に実験中の様子を示します。
この先、PCのTFTディスプレイを使ってAPDS9960モジュールのカラーセンサを校正しますので、カラーモードにsRGBを選択できるディスプレイが望ましいです。
ディスプレイの設定メニューを開いて、sRGBに設定して使ってください。
上図はご参考です。ディスプレイによって設定方法が異なるので、各自、取扱説明書などで確認してください。ユーザ設定で、お好みのカラーモードに設定して使っている場合、そのカラー座標系で校正されることに留意してください。
以下のスクリプトをダウンロードして準備完了です。
校正スクリプト:apds9960_calib.olv
※スクリプト(.olv)を実行するには拙作Olive+をWindowsにインストールしてください。
引き続き、以下に示す手順で実験を進めて行きましょう。
実験サンプル:
校正データファイルのテキストをExcel等に貼り付けて処理したグラフを以下図に示します。
横軸には、TFTディスプレイ(sRGB)の各色の強度(0〜255[LSB])、縦軸には、APDS9960モジュールから読み出したカラーデータ値をそのまま打点しました。
綺麗な二次多項式の関係が観測できました。あまりに綺麗なので、単にディスプレイのガンマ補正(sRGBのγ=2.2)が見えているだけかもしれません。
前節に示したグラフから二次多項式(近似式)の各係数を読み取って、以下図の様にプログラムに埋め込んだら、もう一度M5StickC Plusにプログラムを転送しましょう。
これで校正完了です。
近似式は二次多項式なので、APDS9960から読み取ったカラーデータを実際の色に変換するには二次方程式解の公式を使います。
これをRGB成分毎に計算して色(R,G,B)を求め、TFTディスプレイの表示に反映しています。
なお、APDS9960のAD変換設定やゲイン設定等を変更した場合、校正データを取得し直す必要があるので、APDS9960の設定を確定してから校正する様にしてください。
APDS9960をかざすと、近くの色を読み取って、その色をM5StickC PlusのTFTディスプレイに表示する様になっています。カメレオンみたいでしょう?それが応用プログラムにつけた名前の由来です。
APDS9960には、ヘッドライトの様な照明が付いていない(※)ので、自己発光しない物体の色を調べようと、あまり近づけすぎてしまうと影ができて暗くなってしまいます。と言って、あまり離し過ぎると周囲環境光が入射して、物体の色が薄まってしまう事になります。と言う板挟みです。
※APDS9960には、ジェスチャセンサ用にLEDが付いているのですが、こちらは赤外線IR LEDなので可視光ではありません。ここに白色LEDが搭載されていれば、ヘッドライトとして使えたのですが……。
TFTディスプレイにカラーグラデーションを表示して、同じ色がM5StickC PlusのTFTディスプレイに表示されるか実験で確認してみました(以下動画)。
結果は、なんだか違和感があります……。
赤色、緑色、青色をかざすと、全て、白っぽいパステル調の色が表示される様です(下図、想像図)。
これは?
校正スクリプトでは以下図の様に、赤色のグラデーションを描画しながら、赤色フォトトランジスタを校正しました。
緑色、青色も同様です。
こちらで取得した校正データでは、赤色フォトトランジスタの校正時であっても、緑色および青色フォトトランジスタ測定値も取得しています。そのデータを精査し直してみたところ、以下図の通りでした。
例えば、赤色のグラデーション(Red gradation)で計測したグラフでは、本来、緑色および青色の成分は検出されないはずなのに、検出されています。他の色も同様な状況だと判りました。
これが、白っぽく(パステル調に)見えてしまった原因でした。
上のグラフから推測するに:
実験で感じた違和感と矛盾しません。
校正にはTFTディスプレイを使ったので、液晶で遮断しきれなかったバックライト(白色)が透過してきているだろうし、APDS9960の光学フィルタ特性にも、理想的なフィルタからの偏差があると推察します。これらの影響を排除する事は困難と考えられます。
純粋な赤色の光線源に対して、緑色や青色のフォトトランジスタが値を返してくるとは盲点でした。パステル調に見えてしまって少し違和感は残りますが回避不可能、止む無しです。
概ねカラーセンサとしての機能は確認できたと思います。周りの風景に溶け込んで姿を隠すカメレオンとは名ばかりで、周囲に溶け込み切れずに悪目立ちするカメレオンになってしまったのは残念でした。