// デジタルカラーセンサー S9706をArduino Pro Mini 328 5V 16MHzに配線 
// processing にシリアルで接続 動作確認 OK
//  2009/06/21
#define RANGE 8 // 8番ピンをRange端子に設定
#define GATE  9 // 9番ピンをGate端子に設定
#define CK   10 //10番ピンをCK端子に設定
#define DOUT 11 //11番ピンをDout端子に設定

int red,green,blue;//RGB三色の変数を用意

void setup(){
  //Range,Gate,CK端子をデジタル出力に設定
  pinMode(RANGE,OUTPUT);
  pinMode(GATE,OUTPUT);
  pinMode(CK,OUTPUT);
  //Dout端子をデジタル入力に設定
  pinMode(DOUT,INPUT);
  //シリアル通信設定
  //Serial.begin(9600);
  Serial.begin(38400);
}

void loop(){
  //測光時間用の可変抵抗器の読み込み(アナログ入力:0番ピン)
  int val=analogRead(0);

  //Gate,CK端子をLowに設定
  digitalWrite(GATE,LOW);
  digitalWrite(CK,LOW);
  delayMicroseconds(2000);    //2000マイクロ秒待機

  //感度設定(HIGH:高感度に設定)  
  digitalWrite(RANGE,HIGH);

  //測光開始(光量の積算を開始) 
  digitalWrite(GATE,HIGH);
  //測光時間(valを代入し可変的に設定)
  delay(val+1);
  
  //測光終了(光量の積算を終了) 
  digitalWrite(GATE,LOW);
  delayMicroseconds(4);      //4マイクロ秒待機
  
  red  =shiftIn();           //赤の処理
  green=shiftIn();           //緑の処理
  blue=shiftIn();            //青の処理

  //Gate端子をHighに戻す  
  digitalWrite(GATE,HIGH);

  //シリアル通信でProcessingへ三色の値を文字列で送信  
  if(Serial.available()>0){
    Serial.print(red,DEC);
    Serial.print(",");
    Serial.print(green,DEC);
    Serial.print(",");
    Serial.print(blue,DEC);
    Serial.print(",");
    Serial.println(val,DEC);
    Serial.read();
  }
}

//12ビット分のパルス送信と読み込み処理
int shiftIn(){
  int result=0;                   //検出結果用の変数を用意(0:初期化)
  for(int i=0;i<12;i++){          //12ビット分の繰り返し処理
    digitalWrite(CK,HIGH);        //1ビット分のクロックパルス出力(HIGH)
    delayMicroseconds(1);         //1マイクロ秒待機
    if(digitalRead(DOUT)==HIGH){  //Dout端子からの出力がHighの場合
      result+=(1<<i);             //12ビットのi桁目に1を代入(i桁分だけ左にシフト)
    }
    digitalWrite(CK,LOW);         //1ビット分のクロックパルス出力(LOW)
    delayMicroseconds(1);         //1マイクロ秒待機
  }
  delayMicroseconds(3);           //3マイクロ秒待機
  return result;//結果を出力
}