工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Manufacturing Technology >> 製造プロセス

ArduinoでI2C通信をマスターする: 実践チュートリアル

このチュートリアルでは、I2C通信プロトコルの仕組みを学び、このプロトコルを使用するセンサーとArduinoボードを使った実践例も作成します。以下の動画をご覧いただくか、書面によるチュートリアルをお読みください。

概要

I2C通信バスは、マスターと複数のスレーブデバイス、さらには複数のマスターデバイス間の通信を必要とする多くの電子設計に簡単に実装できるため、非常に人気があり広く使用されています。この簡単な実装は、7ビットアドレッシング使用時で最大約128(112)デバイス、10ビットアドレッシング使用時で最大約1024(1008)デバイス間の通信にわずか2本のワイヤーで済むという事実によるものです。

ArduinoでI2C通信をマスターする: 実践チュートリアル

I2Cの仕組み

たった2本のワイヤーでこれほど多くのデバイスと通信できるのはなぜでしょうか?各デバイスにはプリセットされた固有のデバイスアドレス(ID)があるため、マスターはどのデバイスと通信するかを選択できます。

2本のワイヤー、またはラインは、シリアルクロック(SCL)とシリアルデータ(SDA)と呼ばれます。SCLラインはI2Cバス上のデバイス間でデータ転送を同期させるクロック信号で、マスターデバイスによって生成されます。もう一方のSDAラインがデータを伝送します。

これら2本のラインは「オープンドレイン」であるため、プルアップ抵抗を接続してラインをハイに保つ必要があります。I2Cバス上のデバイスはアクティブローだからです。一般的に使用される抵抗値は、高速(約400kbps)で2kΩ、低速(約100kbps)で10kΩです。

ArduinoでI2C通信をマスターする: 実践チュートリアル

I2Cプロトコル

ArduinoでI2C通信をマスターする: 実践チュートリアル

データ信号は8ビットのシーケンスで転送されます。特別なスタートコンディションの後、最初の8ビットシーケンスがデータ送信先のスレーブアドレスを示します。各8ビットシーケンスの後にはアックノリッジビット(ACK)が続きます。最初のACKビットの後、ほとんどの場合、今度はスレーブデバイスの内部レジスタ用のアドレッシングシーケンスが続きます。アドレッシングシーケンスの後、データが完全に送信されるまでデータシーケンスが続き、特別なストップコンディションで終了します。

これらのイベントをさらに詳しく見てみましょう。スタートコンディションは、クロックラインがまだハイの状態でデータラインがローになるときに発生します。その後クロックが開始され、各クロックパルスで1ビットずつデータが転送されます。

デバイスアドレッシングシーケンスは最上位ビット(MSB)から始まり最下位ビット(LSB)で終わり、実際には7ビットで構成されます。なぜなら8ビット目は、マスターがスレーブに書き込むか(ロジックロー)、スレーブから読み取るか(ロジックハイ)を示すために使用されるからです。

ArduinoでI2C通信をマスターする: 実践チュートリアル

次のACK/NACKビットは、スレーブデバイスが前のビットシーケンスを正常に受信したかどうかを示すために使用されます。この時点でマスターデバイスはSDAラインの制御権をスレーブデバイスに渡し、スレーブが正常に受信していればSDAラインをローに引き下げてアックノリッジ(ACK)状態にします。スレーブがSDAラインをローに引き下げない場合はノットアックノリッジ(NACK)状態となり、前のシーケンスを正常に受信できなかったことを意味します。これにはいくつかの理由が考えられます。例えばスレーブがビジー状態、受信データやコマンドを理解できない、これ以上データを受信できないなどです。このような場合、マスターデバイスがどう対処するかを決定します。

ArduinoでI2C通信をマスターする: 実践チュートリアル

次は内部レジスタアドレッシングです。内部レジスタはスレーブのメモリ内のさまざまな情報やデータを含む場所です。例えばADXL345加速度計には固有のデバイスアドレスがあり、さらにX、Y、Z軸用の内部レジスタアドレスがあります。X軸のデータを読み取りたい場合、まずデバイスアドレスを送信し、次にX軸用の特定の内部レジスタアドレスを送信する必要があります。これらのアドレスはセンサーのデータシートから確認できます。

アドレッシングの後、R/Wビットで選択されたモードに応じて、マスターまたはスレーブからデータ転送シーケンスが始まります。データが完全に送信されると、SCLラインがハイの状態でSDAラインがローからハイになるストップコンディションで転送が終了します。

例

例として、5種類のセンサーを搭載したGY-80ブレイクアウトボードと、3種類のセンサーを搭載したGY-521ブレイクアウトボードを使用します。これでI2Cバスを使ってわずか2本のワイヤーで8種類のセンサーからデータを取得できます。

ArduinoでI2C通信をマスターする: 実践チュートリアル

以下のサイトから部品を入手できます:

  • ADXL345 3軸加速度計
  • 2in1: MPU6050 6軸ジャイロスコープ&加速度計
  • 3in1: GY-80 9軸磁場加速度ジャイロスコープ Amazon
  • 3in1: GY-86 10DOF MS5611 HMC5883L MPU6050モジュール Banggood / AliExpress

ボードの接続方法はこちらです。Arduinoボードのシリアルクロックピンを2つのブレイクアウトボードのシリアルクロックピンに接続し、同じようにシリアルデータピンも接続します。電源はArduinoボードのGNDと5Vピンから供給します。ここではプルアップ抵抗を使用していません。ブレイクアウトボードに既に内蔵されているためです。

ArduinoでI2C通信をマスターする: 実践チュートリアル

これらのチップやセンサーと通信するには、それぞれの固有アドレスを知る必要があります。これらはセンサーのデータシートから確認できます。GY-80ブレイクアウトボードには以下の4つのアドレスがあります:3軸加速度計センサーが16進数0x53、3軸ジャイロが0x69、3軸磁力計が0x1E、気圧計+温度計センサーが0x77です。

GY-521ブレイクアウトボードには1つのアドレスのみで、16進数0x68です。また、Arduino公式サイトで見つかるArduino I2Cスキャナースケッチを使ってアドレスを取得または確認することもできます。このスケッチをアップロードして実行すると、I2Cバスに接続されているデバイスのアドレスが表示されます。


センサー部品番号 | I2Cアドレス

3軸加速度計 Analog Devices ADXL345 0x53 データシート

3軸ジャイロ ST Microelectronics L3G4200D 0x69 データシート

3軸磁力計 Honeywell MC5883L 0x1E データシート

気圧計+温度計 Bosch BMP085 0x77 データシート


デバイスのアドレスがわかったら、それらの内部レジスタアドレスも見つける必要があります。例えば、GY-80ブレイクアウトボードの3軸加速度計センサーからX軸のデータを読み取りたい場合、X軸のデータが格納されている内部レジスタアドレスを特定する必要があります。センサーのデータシートを見ると、X軸のデータは実際には2つのレジスタに格納されており、DATAX0が16進数0x32、DATAX1が16進数0x33です。

Arduino I2Cコード

それでは、X軸のデータを取得するコードを作成しましょう。Arduino Wireライブラリを使用するため、スケッチにインクルードする必要があります。まず、センサーアドレスと先ほど見つけた2つの内部レジスタアドレスを定義します。Wire.begin()関数でWireライブラリを初期化し、シリアル通信も開始します(シリアルモニターでセンサーからのデータを表示するため)。

loop()では、Wire.beginTransmission()関数で特定のセンサー(この場合は3軸加速度計)への伝送を開始します。次にWire.write()関数でX軸の2つのレジスタから特定のデータを要求します。Wire.endTransmission()で伝送を終了し、レジスタからデータを送信します。そしてWire.requestFrom()関数で送信されたデータ、つまり2つのレジスタからの2バイトを要求します。

Wire.available()関数は取得可能なバイト数を返し、要求したバイト数(この場合2バイト)と一致する場合、Wire.read()関数でX軸の2つのレジスタからバイトを読み取ります。最後にデータをシリアルモニターに出力します。ここにデータがありますが、これは生データであり、X軸の正しい値を得るにはいくつかの数学的処理が必要です。詳細については、Arduinoで加速度計を使用する次のチュートリアルをご覧ください。このチュートリアルの主な目的はArduino I2C通信の仕組みを説明することだからです。

/*
 * I2C通信プロトコルの仕組み - Arduino I2Cチュートリアル
 *
 * by Dejan, www.HowToMechatronics.com
 */
#include <Wire.h>
int ADXLAddress = 0x53; // デバイスアドレス(8ビット目でモード選択、この場合は読み取り)
#define X_Axis_Register_DATAX0 0x32 // DATAX0内部レジスタの16進アドレス
#define X_Axis_Register_DATAX1 0x33 // DATAX1内部レジスタの16進アドレス
#define Power_Register 0x2D // 電源制御レジスタ
int X0,X1,X_out;

void setup() {
  Wire.begin(); // Wireライブラリを初期化
  Serial.begin(9600);
  delay(100);
  // 測定を有効化
  Wire.beginTransmission(ADXLAddress);
  Wire.write(Power_Register);
  // ビットD3をHighにして測定有効化 (0000 1000)
  Wire.write(8);
  Wire.endTransmission();
}

void loop() {
  Wire.beginTransmission(ADXLAddress); // センサーへの伝送開始
  // 特定のレジスタにデータを要求
  Wire.write(X_Axis_Register_DATAX0);
  Wire.write(X_Axis_Register_DATAX1);
  Wire.endTransmission(); // 伝送終了し、2つのレジスタからデータを送信
  Wire.requestFrom(ADXLAddress,2); // 2つのレジスタから送信された2バイトを要求
  if(Wire.available()<=2) {
    // X0 = Wire.read(); // レジスタからデータを読み取り
    X1 = Wire.read();
  }
  Serial.print("X0= ");
  Serial.print(X0);
  Serial.print(" X1= ");
  Serial.println(X1);
}コード言語: Arduino (arduino)

製造プロセス

  1. ArduinoとRaspberry Pi 2のI2C連携でIoTセンサープロジェクトを実現
  2. Arduinoで作る高精度エナジーモニター&データロガー – Dr. Wattsonボード活用
  3. Arduinoで温湿度ロガーを作る – DHT11とEthernetシールドでSDカード記録
  4. Python 3からArduino UNOを制御 – シリアル通信でLED点滅デモ
  5. ArduinoをNMEA-0183に接続するステップバイステップガイド
  6. Arduino Nanoで作るJARVIS v1 音声制御ホームオートメーション
  7. Arduinoプロトスレッディング入門:シングルコアで疑似マルチスレッドを実現するステップバイステップガイド
  8. nRF24L01をマスター:無線通信、Arduino連携、回路図・コード完全ガイド
  9. MPU6050 完全攻略:Arduino で加速度センサー&ジャイロを使いこなすチュートリアル
  10. Arduino と ADXL345 加速度センサーで姿勢トラッキング:ステップバイステップガイド
  11. HC-12モジュールで信頼性の高い長距離Arduinoネットワークを構築する