Arduinoで遊ぶページ

Arduinoで遊んだ結果を残すページです。
garretlab
デジタルカラーセンサ

概要

S9706というデジタルカラーセンサを使った実験です。

目的

S9706というデジタルカラーセンサを使って、周囲の色を読み取ってみます。

データシート

S9706のデータシートを参照して、どのようなものかを調べました。

概要

このデジタルカラーセンサはRGBの三色を同時に測定できるセンサです。RGBそれぞれに反応する受光素子がそれぞれ27個ずつ、合計81個(9x9)並んでいます。また、感度を2段階に切り替えることができ、高感度の場合は81個すべて、低感度の場合は9個の受光素子を利用し測定を行います。

RGBそれぞれ12ビットの値(0から4095)を出力します。

ピン配置

このセンサは6ピンで、各ピンの意味は以下の通りです。

ピン番号 記号 意味
1 Dout データ出力
2 Vdd 電源
3 GND 接地
4 Range 感度選択
5 CK クロック入力
6 Gate 測定開始・終了

測定方法

測定方法は以下の通りです。

  1. GateとCKをLOWにする。
  2. Rangeで感度を選択する。測定中はRangeを変えてはいけない。
  3. GateをHIGHにして測定開始。
  4. GateをLOWにして測定終了。測定時間は任意(照度と測定時間により出力される値が変化するようです)。
  5. 4ミリ秒待つ。
  6. CKにパルスを36個入れると、そのたびに、Doutから測定結果が出力される。出力される値はRGBの順にそれぞれ12ビット、合計36ビットとなる。出力はLSBからMSBの順です。この際、12ビット読みとるごとに3ミリ秒待つ必要があります。

実験

S9706とArduinoの接続

S9760は1.27ミリピッチの表面実装用の部品なので、DIP変換基板を用いてブレッドボードに刺さるようにしました。今回は、以下の通り接続しました。基本的には同じ番号同士を接続していますが、Arduinoの1番ピンはシリアル通信に利用するため、ここだけは2番ピンに接続しています。他のピンに接続する場合は、適宜スケッチを修正してください。

S9706のピン番号 Arduinoのピン番号
1 2
2 +5V
3 GND
4 4
5 5
6 6

Arduinoプログラミング

センサから読み取った値をシリアルコンソールに出力する単純なスケッチを作成しました。測定方法で記述したとおりにスケッチを作成しています。

測定データを読み取るところだけが少し複雑なので、簡単に説明をつけておきます。

ShiftIn

データシートによると、このセンサは、赤・緑・青それぞれを12ビットずつ出力します。この際、各データはLSBから先に出力されます。つまり、最初に出力されたビットがArduino上の変数の第0ビット、12個目のビットが第11ビットになります。

Arduinoには、8ビットの値を読み取るためのshiftIn()という関数が用意されています。今回はこの関数を12ビットの値を読むように変更したshiftIn12()という関数を用意しました。

読み取ったビットの値を順に変数の第0ビットから11ビットに向かって設定していきます。最初のビットを0個目のビットと考えると、i番目のビットの値を第iビットに設定することになります。変数を0で初期化しておけば、読み取った値をiビット左にシフトした値と設定対象の変数とでビット単位のOR演算子で設定すればいいことがわかります。

スケッチ

以下にスケッチを示します。

// Arduinoのピン定義
const int doutPin = 2;   // Dout
const int rangePin = 4;  // Range
const int ckPin = 5;     // CK
const int gatePin = 6;   // Gate

void setup() {
  // put your setup code here, to run once:
  
  Serial.begin(9600);
  
  // ピンモードを設定する。doutPinは入力、それ以外は出力。
  pinMode(doutPin, INPUT);
  pinMode(rangePin, OUTPUT);
  pinMode(ckPin, OUTPUT);
  pinMode(gatePin, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly: 
  int red, green, blue;  // 測定した値を格納するための変数
  int integration = 50;  // 測定時間(ミリ秒)を格納する変数
  char s[64];            // シリアルコンソールに出力する文字列を保持する変数
  
  digitalWrite(gatePin, LOW);        // GateとCKをLOWにする。
  digitalWrite(ckPin, LOW);
  digitalWrite(rangePin, HIGH);      // RangeをHIGHにする。
  
  digitalWrite(gatePin, HIGH);       // GateをHIGHにして測定開始。
  delay(integration);                // 測定時間だけ待つ。
  digitalWrite(gatePin, LOW);        // GateをLOWにして測定終了。
  delayMicroseconds(4);              // 4ミリ秒待つ。
  red = shiftIn12(doutPin, ckPin);   // 赤色の値を読む。
  delayMicroseconds(3);              // 3ミリ秒待つ。
  green = shiftIn12(doutPin, ckPin); // 緑色の値を読む。
  delayMicroseconds(3);              // 3ミリ秒待つ。
  blue = shiftIn12(doutPin, ckPin);  // 青色の値を読む。
  
  sprintf(s, "Red = %4d, Green = %4d, Blue = %4d", red, green, blue);
  Serial.println(s);
  
  delay(2000);
}

//12ビットの値を読み込む関数(LSBから送信されるデータを想定)
int shiftIn12(int dataPin, int clockPin) {
  int value = 0;
  
  for (int i = 0; i < 12; i++) {
    digitalWrite(clockPin, HIGH);           // クロックをHIGHにする
    value |= digitalRead(dataPin) << i;     // データピンの値を読み取り、所定のビットを設定する。
    digitalWrite(clockPin, LOW);            // クロックピンをLOWにする。
  }
 
  return value;
}

スケッチ中のintegrationの値が計測時間です。この値を適切に変更する必要があります。この値があまりにも大きいとすべての出力値が4095となります。計測を行って、適切な出力値を得られるようにフィードバックして自動で変更するようなスケッチにしてもいいかもしれません。

プログラム実行結果

プログラムの実行結果(シリアルコンソールの画面)を以下に示します。手をかざしたりして光の量を適当に変えています。

バージョン

Arduino 1.5.2(Uno/AVR)



メニューを表示するためにJavaScriptを有効にしてください。

Arduinoで遊ぶページ
Copyright © 2013 garretlab all rights reserved.
inserted by FC2 system