// フォトリフレクタ入力インターフェース
// 製作者：中口　製作日：2022/7/24
// (Arduino)Seeeduino XIAO M0+ https://www.switch-science.com/catalog/6335/
// (Sensor)S11059 https://akizukidenshi.com/download/ds/akizuki/S11059_module_manual.pdf
//         S11059接続 GND  黒, SCL 白, SDA 灰, +V  紫
// カラーセンサ値（B, R, G, IR）とスイッチ入力(0/1)をシリアルポートへ出力

#include <Wire.h>

//アドレス指定
#define S11059_ADDR 0x2A
#define CONTROL_MSB 0x00
#define CONTROL_1_LSB 0x89 // 固定時間モード,Highゲイン,Tint=01(1.4ms),積分時間1.4ms/ch
#define CONTROL_2_LSB 0x09 // 固定時間モード,Highゲイン,Tint=01(1.4ms),積分時間1.4ms/ch
#define SENSOR_REGISTER 0x03
#define SW_PIN 7  // スイッチ入力ピン
#define SYNC_OUT_PIN 8  // 同期出力ピン

// 初期化
void setup()
{
  Serial.begin(115200);//シリアル通信を115200bpsで初期化
  Wire.begin();//I2Cを初期化
  pinMode(SW_PIN, INPUT_PULLUP); // デジタル入力初期化
  pinMode(SYNC_OUT_PIN, OUTPUT); // 同期出力初期化

  Wire.beginTransmission(S11059_ADDR);//I2Cスレーブ データ送信開始
  Wire.write(CONTROL_MSB);//コントロールバイトを指定
  Wire.write(CONTROL_1_LSB);//ADCリセット、スリープ解除
  Wire.endTransmission();//I2Cスレーブ データ送信終了
  
  Wire.beginTransmission(S11059_ADDR);//I2Cスレーブ データ送信開始
  Wire.write(CONTROL_MSB);//コントロールバイトを指定
  Wire.write(CONTROL_2_LSB);//ADCリセット解除、バスリリース
  Wire.endTransmission();//I2Cスレーブ データ送信終了
}

// ループ
void loop() {
  //変数宣言
  int high_byte, low_byte, red, green, blue, IR, sw;

  delay(50);//50msec待機

  Wire.beginTransmission(S11059_ADDR);//I2Cスレーブ データ送信開始
  Wire.write(SENSOR_REGISTER);//出力データバイトを指定
  Wire.endTransmission();//I2Cスレーブ データ送信終了

  Wire.requestFrom(S11059_ADDR, 8);//I2Cデバイス「S11059_ADDR」に8Byteのデータ要求
  if(Wire.available()){
    high_byte = Wire.read();//high_byteに「赤(上位バイト)」のデータ読み込み
    low_byte = Wire.read();//high_byteに「赤(下位バイト)」のデータ読み込み
    red = high_byte << 8|low_byte;//1Byte目のデータを8bit左にシフト、OR演算子で2Byte目のデータを結合して、redに代入

    high_byte = Wire.read();//high_byteに「緑(上位バイト)」のデータ読み込み
    low_byte = Wire.read();//high_byteに「緑(下位バイト)」のデータ読み込み
    green = high_byte << 8|low_byte;//1Byte目のデータを8bit左にシフト、OR演算子で2Byte目のデータを結合して、greenに代入

    high_byte = Wire.read();//high_byteに「青(上位バイト)」のデータ読み込み
    low_byte = Wire.read();//high_byteに「青(下位バイト)」のデータ読み込み
    blue = high_byte << 8|low_byte;//1Byte目のデータを8bit左にシフト、OR演算子で2Byte目のデータを結合して、blueに代入

    high_byte = Wire.read();//high_byteに「赤外(上位バイト)」のデータ読み込み
    low_byte = Wire.read();//high_byteに「赤外(下位バイト)」のデータ読み込み
    IR = high_byte << 8|low_byte;//1Byte目のデータを8bit左にシフト、OR演算子で2Byte目のデータを結合して、IRに代入
  }
  Wire.endTransmission();//I2Cスレーブ データ送信終了

  sw = digitalRead(SW_PIN);
  while (Serial.available() > 0) {
    char c = Serial.read();
    if (c == '0') digitalWrite(SYNC_OUT_PIN, 0);
    if (c == '1') digitalWrite(SYNC_OUT_PIN, 1);
  }
  // digitalWrite(SYNC_OUT_PIN, 1 - sw);

  Serial.print(blue);//「blue」をシリアルモニタに送信
  Serial.print(",");//文字列「,」をシリアルモニタに送信
  Serial.print(red);//「red」をシリアルモニタに送信
  Serial.print(",");//文字列「,」をシリアルモニタに送信
  Serial.print(green);//「green」をシリアルモニタに送信
  Serial.print(",");//文字列「,」をシリアルモニタに送信
  Serial.print(IR);//「IR」をシリアルモニタに送信
  Serial.print(",");//文字列「,」をシリアルモニタに送信
  Serial.print(sw);//「Switch」をシリアルモニタに送信
  Serial.println("");//改行
}
