1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ArduinoのI2C通信でセンサのレジスタにアクセスする。

Last updated at Posted at 2019-09-07

概要

Arduino UNO R3のI2C通信機能を使って、カラーセンサモジュール(S11059-02DT/浜松フォトニクス)

から情報を取得するためのコードを書いた。センサモジュールとArduinoの間に電圧変換のモジュールが必要だったものの、I2C通信は問題なくできた。しかし、カラーフィルターの機能確認としてはイマイチ。色味よりも輝度で値が大きく変わってしまったため、機能確認は別の機会に譲りたい。

背景

想定読者

  • 身近にあるマイコンを使ってI2Cデバイスをお手軽に制御したい人。(後に、あんまりお手軽な方法ではないことがわかる。)

目的

  • Arduinoを使ってセンサにI2C通信をすること。

実験環境

カラーセンサ > I2C電圧変換IC > Arduino

参考情報

秋月電商の販売ページ

ソースコード

コードはArduinoのI2C通信でデバイスのレジスタにアクセスする。で記載した内容を基本に、本アプリケーションに合わせて実装している。I2C通信として使い回す部分以外、つまりアプリケーション毎に異なる実装になる部分は、アプリケーション層として定義すべきだと思うが、そこまで賢い実装にはなっていない。でも、1つのセンサーに書き込む/読み込むだけであれば、この程度の実装で十分。


# include <Wire.h>

void setup() {
  Wire.begin();
  Serial.begin(9600);
}

int i=0; //initiarize
int w=119;
int r=114;
int DeviceAddress = 0x2A; // 0b0101010 42

int Address[100]={
  0x00, // Control
  0x00, // Control
  //0x01, // 
  //0x02, // 
  0x03, // Red MSB
  0x04, // Red LSB
  0x05, // Green MSB
  0x06, // Green LSB
  0x07, // Blue MSB
  0x08, // Blue LSB
  0x09,
  0x0A
  };

int Value[100]={
  0x8F, // ADC reset, awake
  0x0B, // Control initialize 0B:correct
  //0x0C, 
  //0x30, 
  0x00, // Red MSB initialize
  0x00, // Red LSB initialize
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00
  };

void loop() {
  delay(100);
  Serial.println("Please send command either w or r");
  delay(1000);
  Serial.print("Serial.available()=");
  Serial.println(Serial.available());
  if(Serial.available()>0){
    Serial.println("Serial avalable!");
    int x=0;
    x = Serial.read();
    Serial.print("x=");
    Serial.println(x,HEX);
    if(x==w){
      Serial.println("Write");
      WriteReg();
      }
    if(x==r){ 
      Serial.println("Read");
      ReadReg();
      }
    }
  }

void WriteReg(){
  for (i=0; i<10; i++) {
    Wire.beginTransmission(DeviceAddress);
    Wire.write(Address[i]);
    Wire.write(Value[i]);    
    Wire.endTransmission(false);
    Insert0x0(Address[i]);
    Serial.print(Address[i],HEX);
    Serial.print("=");
    Insert0x0(Value[i]);
    Serial.println(Value[i],HEX);
    delay(0);
  } // while(1){}//finalize
  }

void ReadReg(){
  for (i=0; i<10; i++) { 
  Wire.beginTransmission(DeviceAddress);
  Wire.write(Address[i]);
  Wire.endTransmission(false);
  Wire.requestFrom(DeviceAddress, 1,true);
  Value[i] = Wire.read();
  Insert0x0(Address[i]);
  Serial.print(Address[i],HEX);
  Serial.print("=");
  Insert0x0(Value[i]);
  Serial.println(Value[i],HEX);
  delay(0);
  } // while(1){}//finalize
  }

void Insert0x0(int num){
  Serial.print("0x");
  if (num<16){ Serial.print("0"); }
  else Serial.print("");
  }

結果1:I2C通信できた

Writeでカラーセンサーの各アドレスにデータを格納
(0x00には0x0Bを格納、0x03~0x0Aは初期化で0x00を格納)し、
Readで値を確認
(0x00を呼び出すと0x0Bが格納されていて、0x03~0x0Aにはセンサから読み込んだ値が格納されている。)

Write
0x00=0x0B
0x03=0x00
0x04=0x00
0x05=0x00
0x06=0x00
0x07=0x00
0x08=0x00
0x09=0x00
0x0A=0x00

Read
0x00=0x0B
0x03=0x0D
0x04=0x5F
0x05=0x03
0x06=0x64
0x07=0x01
0x08=0xC3
0x09=0x01
0x0A=0xD0

結果2

// 何もかざしていない時
0x03=0x11
0x04=0xB4

// 赤い下敷きをかざしたとき
0x03=0x0D
0x04=0xE7

// iPhoneのLEDで光を当てたとき
0x03=0x58
0x04=0x14

// 赤い下敷きをかざしてiPhoneのLEDで光を当てたとき
0x03=0x27
0x04=0x54

赤い下敷きをかざす方が暗くなるから、結果の値が小さくなる。。。
この程度の実験では、カラーセンサの機能が十分に果たせているかわからないため、同じ輝度で、緑、青の値も比較して見る必要がありそうだ。

考察1:ADCの初期化

ADCの初期化は自分の理解通りに動いていない。アドレス:0x00にデータ:0x0Bを書き込んで初期化しているのだが、データシートの指示通りであれば、0x0Fを書き込んでも正しく動作するはずと理解している。根本原因は不明。本検討では、センサーにI2Cアクセスすることを目的にしているので、初期化の細かい検討は不問に止めるが、今後の検討で理由を明らかにしていきたいと思っている。これでは全く考察になっていないのだが、考察できるほどの材料が揃っていないのが実際のところ。考察を揃えるためには、まず、カラーセンサーの動作検証環境を整備する必要があると考えている。今の所、カラー光源にまともなものがないため、I2通信していること以外は、センサーがどのように動いているか詳細な動きが理解できていない。まずは、環境を整えたい。しかし、初期化の検討をしているので、カラー光源なんぞなんでも関係ない、というツッコミもまた一理あり。

結論

  • カラーセンサにI2C通信できた。
  • 正確なカラー値が取得可否の確認ができなかった。

所感

  • 実験していると、往々にして本来の目的外の部分でハマる。本来の目的に立ち戻って、まずは目的達成しているかどうか確認して、一歩一歩進める方が吉。
  • 問題にぶつかったら、散歩するなり、時間を置くなりして問題と距離を置くことが有効。散歩すると足の血流が良くなり、脳の働きにも好影響を及ぼすらしい。
  • 世の中の人々は、どうやってI2Cデバイスを動かしているのだろうか。もちろん、やり方は色々あるのは知っているのだが、Aruduino使ってセンサにアクセスする方法の説明はあまりない。SoCレベルであればベンダーからのサポート資料などありそうだが、エンジニアの手元で起きることに対するソリューションとして、こういった検討を続けていきたい。

*この記事は若手もくもく会@クラウドワークスへ、台湾からのリモート参加中に実験した内容をもとに執筆しました(^^)

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?