Sim's blog

電子工作はじめてみました

カラーセンサ・モジュールを使ってみた?

2008-10-07 23:51:47 | AVR
ストロベリーリナックスさんで販売しているカラーセンサ・モジュール ADJD-S371-QR999を使ってみました。AVRでI2Cが使えるようになったので、何か他のものも使ってみたくなりました。

カラーセンサ・モジュールです。

動作電圧は2.5~3.6Vで測定値はデジタル値としてI2Cを使って読み取れます。ストロベリーリナックスさんでは、このモジュールを使ったキットも販売しています(ADJDカラーセンサ評価キット)。

実験の様子です。


読み取った値です。

上からR, G, B, クリア(?)の値です。0~1023なので000から3ffまでの値をとります。蛍光灯の下の値を表示しています。Nokia5110のバックライトをつけてみました。暗くしても値が読み取れるようにです。

カラーセンサー・モジュールのおおざっぱな使い方です。
(1) 初期化する
(2) CTRLに0x01を書き込む(変換開始)
(3) CTRLが0になるまで待つ(変換終了待ち)
(4) 値を読み取る
初期化はR, G, Bとクリアの4つについてgain(増幅度?)とintegration time(積分時間?)を設定します。クリアはR, G, Bのフィルターのかかってない素の光センサーの読み取り値みたいです。gain(0~15)は大きいほどセンサーの読み取り値が小さくなります。integration time(0~4095)は大きいほどセンサーの値が大きくなります。

ソースです。
#include <avr/io.h>
#include <util/twi.h>
#include <util/delay.h>
#include "i2c.h"
#include "lcd.h"

// S371の定数
#define S371 (0x74 << 1) // S371のスレーブアドレス

#define CTRL 0
#define CAP_RED   6
#define CAP_GREEN 7
#define CAP_BLUE  8
#define CAP_CLEAR 9
#define INT_RED_LO 10
#define INT_RED_HI 11
#define INT_GREEN_LO 12
#define INT_GREEN_HI 13
#define INT_BLUE_LO 14
#define INT_BLUE_HI 15
#define INT_CLEAR_LO 16
#define INT_CLEAR_HI 17
#define DATA_RED_LO 64
#define DATA_RED_HI 65
#define DATA_GREEN_LO 66
#define DATA_GREEN_HI 67
#define DATA_BLUE_LO 68
#define DATA_BLUE_HI 69
#define DATA_CLEAR_LO 70
#define DATA_CLEAR_HI 71

// 指定したアドレスにデータを書く
void write(byte address, byte data)
{
    i2c_start(S371 | TW_WRITE); // アドレスとデータを送る
    i2c_write(address);
    i2c_write(data);
    i2c_stop();
}   

// 指定したアドレスのデータを読む
byte read(byte address)
{
    byte x;

    i2c_start(S371 | TW_WRITE); // アドレスを送る
    i2c_write(address);
    i2c_stop();
    i2c_start(S371 | TW_READ);  // データを読む
    x = i2c_read_nak();
    i2c_stop();
    return x;
}

int main()
{
    uint16_t x;
    lcd_init(); // Noki5110初期化
    i2c_init(); // I2C初期化

    // S371初期化
    write(CAP_RED,   10);   // 0~15
    write(CAP_GREEN, 10);   // 0~15
    write(CAP_BLUE,  10);   // 0~15
    write(CAP_CLEAR, 10);   // 0~15
    write(INT_RED_LO, 2500 & 255);
    write(INT_RED_HI, 2500 >> 8);
    write(INT_GREEN_LO, 2500 & 255);
    write(INT_GREEN_HI, 2500 >> 8);
    write(INT_BLUE_LO, 2500 & 255);
    write(INT_BLUE_HI, 2500 >> 8);
    write(INT_CLEAR_LO, 2500 & 255);
    write(INT_CLEAR_HI, 25000 >> 8);

    while(1){
        write(CTRL, 0x01);  // 測定開始
        while(read(CTRL)) ; // 測定完了待ち
        // RED読み取り
        x = read(DATA_RED_HI) << 8 | read(DATA_RED_LO);
        lcd_locate(0, 0);
        lcd_hex4(x);        // 16進4桁出力
        // GREEN読み取り
        x = read(DATA_GREEN_HI) << 8 | read(DATA_GREEN_LO);
        lcd_locate(0, 1);
        lcd_hex4(x);        // 16進4桁出力
        // BLUE読み取り
        x = read(DATA_BLUE_HI) << 8 | read(DATA_BLUE_LO);
        lcd_locate(0, 2);
        lcd_hex4(x);        // 16進4桁出力
        // CLEAR読み取り
        x = read(DATA_CLEAR_HI) << 8 | read(DATA_CLEAR_LO);
        lcd_locate(0, 3);
        lcd_hex4(x);        // 16進4桁出力
        _delay_ms(500);     // 0.5秒待つ
    }
}

とりあえず何か動いているものはできました。
明るい所で測定すると、周囲の光のせいで測定値が飽和してしまいます。フードか何か遮光するものがいります。LEDの光を直接当てると暗闇の中でも飽和してしまいます。測定の方法としては、モジュールの白色LEDをつけて反射光で測るのもあるみたいです。その際は2.5mmくらいに近づけないといけないみたいです。回路をつなげることより、測定環境を整える方がたいへんかもしれません。あくまで絶対的な値を測定するのではなく、相対的な値の測定に使用するものです。
内部でプルアップもされているのでつなぐだけで測定できるのは気楽です。
I2Cさえできれば気軽に使えるのでフィジカルコンピューティングなんかにいいんじゃないでしょうか。

最新の画像もっと見る

4 コメント

コメント日が  古い順  |   新しい順
R=$369 G=$32C B=$0E9 (のりたん)
2008-10-08 09:48:09
黄色い蛍光灯?
返信する
re:R=$369 G=$32C B=$0E9 (Sim)
2008-10-09 00:02:14
こんばんは、のりたんさん
ううっ、黄ばんでるんでしょうか。というか、ちょっと青の感度が悪いみたいです。蛍光灯だとかなり数値が上下します。
作り方より測り方が難しいですね。どうすればいいのかさっぱりです。
返信する
蛍光灯の測定 (のりたん)
2008-10-09 09:09:18
以前、フォトトランジスタで自宅の蛍光灯の光を測定したときに、測定値がばらつくことに気がつきました。そのときは、「ずいぶんノイズっぽいのね。」ぐらいしか思わなかったのですが、同じセットをオフィスの蛍光灯で試したところ、ばらつきが無くなりました。あれ?




自宅の蛍光灯はグロー管付きの古いタイプ。オフィスの蛍光灯はインバータ式。どうやら、蛍光灯の100Hz(50Hz?)の点滅を検出していたらしいと判明しました。

蛍光灯の点灯方式によって結果が変わってきますので、色々と試してみてください。

で、普通の蛍光灯にも対応した測定方法ですが、20ミリ秒間(50Hzの一周期分)に多くの測定を行って、その平均を取るとそれらしい値が出ると思います。
返信する
re:蛍光灯の測定 (Sim)
2008-10-09 23:03:30
こんばんは、のりたんさん
50Hzとか100Hzですか、どおりで測定値が変動するわけです。うちのもグローランプのでした。
このモジュールは白色LEDが点いていて、反射光で測るものみたいなんですが、LEDなんかも測れるというこど直接光を当てていました。
もうちょっと調べてみようと思います。ありがとうございました。
返信する

コメントを投稿