I2C通信Part1–Arduino to Arduino

はじめに

i2C通信は、マイクロコントローラ、マイクロコンピュータ、さまざまな集積回路やセンサ間の通信の事実上の方法となっています。 それは1982年以来の周りされており、もともとテレビ受信機で使用するために開発されました。

以前の記事では多くのI2Cセンサーとディスプレイを使用してきましたが、I2Cがどのように機能し、マイクロコントローラ間の通信にどのようまた、2つのArduinos間で情報を交換するためにどのように使用できるか、1つのArduinoが別のArduinoを制御できるようにするためにどのように使用できるかも

I2Cパート1-2Arduinosを使用して

これは、I2Cに関する四つの記事の最初になります.将来の記事では、私たちは私たち自身のI2Cデバ

始めましょう!

始めましょう!

I2C通信

I2Cは、低速2線式インターフェイスで使用されるシリアルプロトコルです。 もともとは1982年にフィリップスによって開発され、テレビ受信機内の集積回路が互いに通信できるようになりました。

時代が変わった、フィリップスは今NXPであり、I2Cは、事実上すべての主要な半導体メーカーによってサポートされている通信標準となっています。I2Cは「Inter-Integrated Circuit」の略です。 また、”IIC”または”I squared C”とも呼ばれます。

使用法と制限

I2Cは、ArduinoのようなマイクロコントローラやRaspberry Piのようなマイクロコンピュータで使用されます。 多くのディスプレイとセンサーは、I2Cを使用してホストコントローラにインターフェイスします。

I2Cにはいくつかの制限があります。 その意図された用途のほとんどのために、それは十分に高速ですが、それは、特に高速ではありません。

I2Cは短距離でしか使用できませんが、もともとは同じプリント回路基板上の集積回路間で通信することを意図していました。 信頼性の高い伝送の最大距離は、速度が増加するにつれて減少し、最も遅い速度(100Kbaudまたは100KHzのクロックレート)では、最大距離は約1メートルです。

i2C速度

元のI2Cバスの最大速度は100KHzでした。 ほとんどの一般的なアプリケーションでは、センサーやシンプルなディスプレイにデータを転送するのに十分なので、この速度を使用しています。

I2Cといくつかのより高い速度モードを持っています。 すべてのI2Cデバイスがこれらのモードをサポートしているわけではありません。

  • 高速モード–これは最大クロック速度が400KHzです。
  • ハイスピードモード-最大クロック周波数fo3.4MHz
  • 超高速モード–最大クロック周波数5MHz

i2Cバス上では、クロック速度を決定するのはマスターです。.こんにちは、クロック速度を決定するマスターです。

I2Cの仕組み

I2Cバスには、電源とグランド接続とともに二つの信号があります。P>

I2Cバス通信

二つの信号線は次のとおりです。

  • SDA–これは双方向データ線です。
  • SCL–これはクロック信号です。

各信号ラインには2つのプルアップ抵抗が接続されており、非アクティブなときにバスを電源電圧までプルアップします。電源電圧は標準ではなく、3.3ボルトまたは5ボルトのいずれかになります。

電源電圧は標準ではないことに注意してください。 また、一部の高速I2C実装では、より低い電圧にすることもできます。

この電源電圧の違いは、異なるロジックレベルを使用するI2Cデバイスをインタフェースするときに問題を引き起こす可能性があります。 私はラズベリーパイをインターフェイスする方法をお見せするとき、我々は、将来の記事では、より多くのこれを議論します(3.Arduino Uno(5ボルトの論理)との3ボルトの論理)。I2Cバスにインタフェースできるデバイスには、マスタとスレーブの二つのタイプがあります。

マスターデバイスはバスを制御し、クロック信号を供給します。 スレーブからのデータを個別に要求します。 バス上には複数のマスターデバイスが存在する可能性がありますが、任意の時点でアクティブなマスターになることができるのは1つだけです。

マスターデバイスにはアドレスが割り当てられていません。

スレーブデバイスにはアドレスがあり、このアドレスはバス上で一意である必要があります。 これらは7ビットのアドレッシング方式を使用するため、1つのI2Cバス上に最大128個のスレーブを配置できます。 実生活では、この大規模なデバイスのコレクションは決して使用されず、1つのバス上に1ダース以上のI2Cデバイスを見ることはまれです。

新しい10ビットのアドレッシング方式が実装され、既存の7ビットのアドレッシング方式と下位互換性があります。

商用I2Cデバイスは、バス仕様を維持するNXPによってI2Cアドレスが割り当てられます。 I2Cは2006年以来オープンソースであったが、nxpからスレーブアドレスを取得するための料金が請求されている。 マスターデバイス、または商用製造用ではないデバイスについては、料金は必要ありません。

一部のI2Cデバイスには複数のアドレスが割り当てられており、通常は下位アドレスビットの分散が割り当てられています。 これらのデバイスは、異なるアドレスに対して手動で構成することができ、同じタイプの複数のデバイスを単一のI2Cバス上で使用できます。

その他のI2C派生物

I2Cバスから派生した他のバスがあり、多くの点でI2Cと互換性があります。

  • TWI–ツインワイヤインターフェイスは、I2Cバスと実質的に同一です。 これは実際にArduinoが使用するバスであり、TWIはI2Cバスがオープンソースではなく、Atmelが商号違反の危険を冒したくなかったときに開発されました。 TWIとI2Cの唯一の大きな違いは、TWIが”クロックストレッチ”と呼ばれる高度な技術をサポートしていないことです。 SMBusは、Intelによって開発された別のI2C同等のバスです。 TWIと同様に、ほとんどのI2C機能をサポートしています。

今後の記事では、I2Cバス上のデータがどのように構造化されているかを説明します。 しかし、今、私たちは実験を開始するのに十分ないくつかの基本的なI2C情報を持っています。Arduinoには、Wireライブラリと呼ばれるI2Cを操作するためのライブラリが組み込まれています。 これにより、I2Cバス上での通信が非常に簡単になり、arduinoをマスターまたはスレーブのいずれかになるように構成できます。Wireライブラリには、I2Cを操作するためのいくつかの便利な機能があります。

  • begin()–これは、ライブラリを開始し、マスターまたはスレーブのいずれかになるようにArduinoを設定します。
  • requestFrom()–この関数は、スレーブからデータを要求するためにマスターによって使用されます。
  • beginTransmission()–この関数は、指定されたスレーブにデータを送信するためにマスターによって使用されます。
  • endTransmission()–この関数は、beginTransmission関数で開始された送信を終了するためにマスターによって使用されます。
  • write()–i2Cバス上でデータを送信するためにマスターとスレーブの両方で使用されます。
  • available()–マスターとスレーブの両方で、受信しているデータのバイト数を決定するために使用されます。
  • read()–i2Cバスからデータのバイトを読み込みます。
  • SetClock()–特定のクロック周波数を設定するためにマスターによって使用されます。
  • onReceive()–マスターからデータを受信したときに呼び出される関数を指定するためにスレーブによって使用されます。
  • onRequest()–マスターがデータを要求したときに呼び出される関数を指定するためにスレーブによって使用されます。

スケッチではこれらの関数のいくつかを使用します。

Arduino I2C接続

I2CのSDA接続とSCL接続は、Arduinoモデル間で異なります。 私があなたに見せようとしている実験は2つのArduino Unoを使って行われましたが、それに応じてピンを変更すれば、Arduinoの他のモデルを使うことができま私はあなたがそれを理解するのを助けるためにチャートをまとめました。

これには、いくつかの一般的なArduinoボードと、いくつかの個別のチップが含まれています。 私がリストするチップ(ATTinyとAtmega328P)のピン配置は、表面実装のものではなく、DIPパッケージにあります。

Arduino Board or Chip SDA SCL
Uno A4 A5
Mega2560 20 21
Nano A4 A5
Pro Mini A4 A5
Leonardo 2 3
Due (has two I2C) 20 + SDA1 20 + SCL1
ATTiny85 & ATTiny45 5 7
ATmega328P 27 28

いくつかのArduino Unoクローンは、別々のSDAピンとSCLピンを持っており、必要に応じて二つのアナログピンの代わ それらは同じ場所に内部的に接続されています。Arduino Dueには実際には2つのI2Cポートがあることに注意してください。また、プロミニのためのインターネット上のいくつかの誤ったフックアップ図があることに注意してください。

また、プロミニのためのインターネッ 上の表に示すように、2つのアナログピンA4とA5を使用します。私たちの最初の実験では、2つのArduinosを一緒にhooし、それらの間でデータを交換します。 一つのArduinoはマスターになり、もう一つはスレーブになります。私は2つのArduino Unoを使用していますが、2つのUnoがない場合は、他のArduinoを置き換えることができます。

私は2つのArduino Unoを使用していますが、2つの 接続には前のグラフを使用します。

2つのArduinoをフックする

ここで私は2つのArduino Unosを一緒に接続した方法です:P>

I2C ArduinoからArduino

それは非常に単純なフックアップです。注意すべきことの1つは、私の図にプルアップ抵抗の使用が示されていないことです。 ただし、特にエラーや断続的な操作が発生した場合は、それらを含めることができます。

いくつかのプルアップ抵抗を接続するには、SDAとSCLラインに数10kの抵抗を接続します。 もう一方の端をArduinoの1つの5v出力に接続します。ここでは、マスターとして指定したArduinoで使用されるスケッチです。

Master Demo Sketch

マスターとして指定したArduinoで使用されるスケッチを示します。

Master Demo Sketch

I2Cマスターデモ

iv id
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
19
19
19
19
19
19
19

25

26

>

41
42
43
44
45
46
47
48
49
50
51
52
53
53
53
54
55
56
57
58
59
50
51
52
54
55
td>

/*
i2cマスターデモ
i2c-master-demo。ino
Demonstrate use of I2C bus
Master sends character and gets reply from Slave
DroneBot Workshop 2019
https://dronebotworkshop.com
*/
// Include Arduino Wire library for I2C
#include <Wire.h>
// Define Slave I2C Address
#define SLAVE_ADDR 9
// Define Slave answer size
#define ANSWERSIZE 5
void setup() {
// Initialize I2C communications as Master
Wire.begin();
//シリアルモニタをセットアップします。
シリアル。begin(9600);
シリアル。println(“I2Cマスターデモ”);
}
void loop(){
delay(50);
シリアル。println(“Write data to slave”);
//Charatreをスレーブに書き込みます
ワイヤー。beginTransmission(SLAVE_ADDR);
ワイヤ。write(0);
ワイヤ。endTransmission();
シリアル。println(“Receive data”);
//スレーブから応答を読み取ります
//5文字を読み戻します
ワイヤー。requestFrom(SLAVE_ADDR,ANSWERSIZE);
//文字列に文字を追加する
文字列response=””;
while(ワイヤー。available()){
char b=ワイヤ。read();
response+=b;
}
//シリアルモニタに出力
シリアル。println(response);
}

すべてのI2Cスケッチと同様に、ワイヤライブラリを含めることから始めます。

次に、スレーブのI2Cアドレスと、スレーブから取得する予定のデータのバイト数を表すいくつかの定数を定義します。

セットアップでは、i2C通信をマスターとして初期化します。 Begin関数にはaddressパラメータがないため、マスターであることがわかります。 私達はまた連続モニターをセットアップし、それにテキストの行を印刷します。

今すぐループに。

私たちは、主に我々はシリアルモニタ上のディスプレイを読み取ることができるように、十分に物事を遅くするために、小さな時間遅延で始ま

次に、beginTransmission関数を使用してスレーブにデータを送信します。 この場合、送信するデータは単なる数値ゼロです。 EndTransmission関数の呼び出しで送信を終了します。

次に、requestFrom関数を使用してスレーブからいくつかのデータを要求します。

その後、スレーブから一度に1バイトずつデータを読み取ることによって応答文字列を定式化します。

私たちは、私たちが何をしているのか、私たちが受け取ったデータの詳細をシリアルモニターに印刷します。 そして、我々はループを終了し、すべての上に再びそれを行います。

Slave Demo Sketch

スレーブが使用するスケッチになりました。/div>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
19
19
19
19
19
19
19

25

26

>

41
42
43
44
45
46
47
48
49

50

51
52
53
54
55
56
57
58
59
50
51
52
54
55
56
57
58
59

69

70
/*
I2C Slave Demo
i2c-slave-demo.ino
Demonstrate use of I2C bus
Slave receives character from Master and responds
DroneBot Workshop 2019
https://dronebotworkshop.com
*/
// Include Arduino Wire library for I2C
#include <Wire.h>
//定スレーブI2Cアドレス
#define SLAVE_ADDR9
//定スレーブサイズに答え
#define ANSWERSIZE5
//定義文字列との対応マスター
文字列の回答=”こんにちは”;
void setup(){
//初期化I2Cのコミュニケーションをスレーブ
す。begin(SLAVE_ADDR);
//マスターからデータが要求されたときに実行する関数
ワイヤー。onRequest(requestEvent);
//マスターからデータを受信したときに実行する関数
ワイヤー。onReceive(receiveEvent);
//シリアルモニタをセットアップします。
シリアル。begin(9600);
シリアル。println(“I2Cスレーブデモ”);
}
void receiveEvent(){
//データが受信された間に読み取り
while(0<ワイヤ。available()){
バイトx=ワイヤ。read();
}
//シリアルモニタに出力
シリアル。println(“Receive event”);
}
void requestEvent(){
//正しいサイズでバイト変数を設定
バイト応答; 答えを配列としてフォーマットするfor(byte i=0;i<ANSWERSIZE;i++){
response=(byte)answer。charAt(i);
}
//マスターに応答を送り返します
ワイヤー。write(response,sizeof(response));
//シリアルモニタに出力
シリアル。println(“Request event”);
}
void loop(){
//ループ内の時間遅延
delay(50);
}

もう一度、ワイヤライブラリを含めることから始めます。 前のスケッチと同様に、スレーブのI2Cアドレスと、マスターに送り返す予定のバイト数も定義します。

次にこの文字列を送り、マスター、この場合にだけ、”Hello”とします。 これを変更する場合は、両方のスケッチのANSWERSIZE定数を正しいように調整してください。

セットアップでは、begin関数を使用してI2Cバスへの接続を初期化します。 これは使用するI2Cアドレスを指定するスレーブであるため、これを行う別の方法に注意してください。 これにより、ワイヤライブラリはスレーブモードで動作したいことを知っています。ここで、マスターから受信したデータ要求とマスターから受信したデータという2つのイベントが発生したときに呼び出す関数の名前を定義する必要が 私達はまた連続モニターにセットアップし、印刷します。

関数receiveEventは、マスターからデータを受信するときに呼び出されます。 この関数では、データが利用可能である間にデータを読み取り、それをバイトに割り当てます(データは一度に1バイトずつ受信されます)。

requestevent関数は、マスターからデータの要求を取得するたびに呼び出されます。 “今”を当社の文字列”こんにちは”に戻ります。 している必要がありまを送信するデータを上位バイト時についての文字”こんにちは”の各項目の配列で送信します。

両方の機能の進捗状況をすべてシリアルモニターに報告します。

このスケッチのループは、マスタースケッチで使用されているものと一致する時間遅延を追加するだけです。

デモスケッチの実行

これらのスケッチを実行するには、各Arduinoのシリアルモニタを表示できるようにする必要があります。 Arduino IDEがインストールされている2台のコンピュータがある場合、それはそれをはるかに簡単にします。

Microsoft Windowsでは、Arduino IDEの2つのインスタンスを開くことができます。 それが行われている場合は、同じ画面上に並んで両方のシリアルモニタを表示することができます。代わりに、1台のコンピュータを使用して、2台目のArduinoに独自の電源を供給することもできます。 あなたは2つのArduinoの間でコンピュータと電源を切り替える必要があります.これを行うことによって、あなたは両方の画面を1つずつ監視することができます。

I2Cを使用したArduinoのリモート

次のデモでは、マスター Arduinoにポテンショメータをフックし、スレーブにLEDをフックします。 私達はLEDのまばたき率を制御するのに電位差計を使用します。これは別の簡単なデモです、あなたはより実用的な何かを作成するためにそれの上に構築することができます。

リモートデモフックアップ

ここでは、この実験が一緒に置かれている方法です。

I2C Arduino Control

これは、マスターにポテンショメータを追加し、スレーブにLEDを追加して、基本的に前の実験と同じフックアップです。

スレーブのLEDがピン13に接続されていることに注意してください。 Arduino Unoにはピン13にLEDが内蔵されているため、必要に応じてLEDとその落下抵抗を排除することができます。

プルアップ抵抗に関する注意事項もこの接続に適用されます。

Remote Demo Master Sketch

この実験のマスター側のスケッチは非常に簡単で、いくつかの点でI2C側は最初のデモで使用されたものよりもさらに簡単です。 これは、スレーブにデータを送信しているだけで、戻ってくることを期待していないためです。P>

ポテンショメータ付きI2Cマスター

2
3
4
5
6
8
9
10
11
12
13
14
15
16
17
18
19
19
19
19
19
19
19
19
19
19
19
19
19>
25

>

40
/*
i2cマスターコントロールデモ
i2c-master-demo-control。ino
Demonstrate use of I2C bus
Master sends potentimeter position data
DroneBot Workshop 2019
https://dronebotworkshop.com
*/
// Include Arduino Wire library for I2C
#include <Wire.h>
// Define Slave I2C Address
#define SLAVE_ADDR 9
// Analog pin for potentiometer
int analogPin = 0;
// Integer to hold potentiometer value
int val = 0;
void setup(){
//I2C通信をマスターとして初期化します
ワイヤ。begin();
}
void loop(){
delay(50);
//pot値を読み取る
//フラッシュレートの1-255の範囲にマップ
val=map(analogRead(analogPin))val=map(analogRead(analogPin))val=map(analogRead(analogPin))val=map(analogRead(analogPin))val=map(analogRead(analogPin)val=map(analogpin), 0, 1023, 255, 1);
//スレーブにcharatreを書き込みます
ワイヤー。beginTransmission(SLAVE_ADDR);
ワイヤ。書き込み(val);
ワイヤ。endTransmission();
}

いつものように、スケッチの先頭にワイヤライブラリを含める必要があります。 また、スレーブアドレスを保持する定数も定義します。

ポテンショメータを使用しているので、接続されているピンとその値を保持する変数の両方を定義する必要があります。

セットアップで行うことは、i2C接続をマスターとして初期化することだけです。

ループでは、ポテンショメータ値を読み取り、01-255の範囲にマップします。 私たちは1バイトの情報を送信しており、この多くの値を1バイトでしか保持できないので、これを行う必要があります。これは、システムが期待どおりに動作するように行われます–ポテンショメータを右に回すとフラッシュレートが増加します。 “フラッシュレート”は時間遅延によって指定されるので、送信されるより大きな数はより長いフラッシュレートに相当します。

また、LEDを1つの状態に保持する値0を送信しないことにも注意してください。 代わりに範囲を1で終了するように設定します。これで、バイトをスレーブに送信し、ループを再度繰り返すだけです。

リモートデモ受信スケッチ

スレーブ側は、マスターからデータを受信し、LEDを点滅させるためにそれを使用する必要があります。/div>1

2
3
4
5
6
7
8
9
10

111213141516171819191919191919191919191919191919191919191919

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
29
29
29
29
29
29
29
29
2925
26

>

41
42
43
44
45
46
47
48
49

50

51
52
53
54
55
56
57
58
59
50
51
52
54
55
56
57
58
59
55
56
57
58
59

60

/*
i2cスレーブ制御デモ
i2c-slave-demo-control。ino
Demonstrate use of I2C bus
Receives potentimeter position data
Controls LED blink rate
DroneBot Workshop 2019
https://dronebotworkshop.com
*/
// Include Arduino Wire library for I2C
#include <Wire.h>
// Define Slave I2C Address
#define SLAVE_ADDR 9
// Define LED Pin
int LED = 13;
// Variable for received data
int rd;
// Variable for blink rate
int br;
void setup(){
pinMode(LED,OUTPUT);
//I2C通信をスレーブとして初期化します
ワイヤ。begin(SLAVE_ADDR);
//マスターからデータを受信したときに実行する関数
ワイヤー。onReceive(receiveEvent);
//シリアルモニタを設定します。
シリアル。begin(9600);
シリアル。println(“I2Cスレーブデモ”);
}
void receiveEvent(){
//I2C
rd=ワイヤから一文字を読み取ります。read();
//受信データの値を出力します
シリアル。println(rd);
void loop(){
delay(50);
//点滅値を計算します
br=map(rd, 1, 255, 100, 2000);
digitalWrite(LED,HIGH);
delay(br);
digitalWrite(LED,LOW);
delay(br);
}

私たちは、ワイヤライブラリの通常の包含だけでなく、スレーブアドレスの定義。 また、LED用のピンも定義します。

いくつかの追加の変数が定義され、一方は受信したデータを保持し、他方は点滅レートの時間遅延値を保持します。

セットアップでは、LEDのI/Oピンを出力として設定し、I2Cバスを初期化します。 Begin関数でスレーブアドレスを使用すると、Wireライブラリはスレーブとして機能していることを認識します。

最後のデモとは異なり、マスターからの要求を期待していないonReceive関数を定義するだけです。 私達はまたセットアップし、連続モニターに印刷します、入って来るデータを見るのにモニターを使用します。

receiveEvent関数は、受信データを読み取り、それをI変数に割り当てます。 また、シリアルモニタに値を出力します。

最後に、ループでは、着信データを使用してLEDを点滅させます。 もう一度、Map関数を使用してこれを達成し、1-255の入力値をより広い範囲に変更します。 この範囲を変更して、必要に応じてLEDをより速くまたは遅く点滅させることができます。

最後のいくつかの文は、本質的に変装してArduinoの点滅スケッチです! 最後のステップで決定した期間、LEDをオンとオフにします。

そして、ループを繰り返します。

リモートデモを実行する

コードをロードし、両方のArduinoの電源を入れます。

I2C実験2

ポテンショメータを回すと、スレーブのLED点滅レートが変化するはずです。

結論

これで、I2Cの最初の詳細な外観は終わりです。次の割賦では、交換されているデータの構造についての詳細を学びます。 また、通常のセンサーを使用してI2Cセンサーに変換します。

幸せなコミュニケーション!

リソース

Sketches–この記事で使用されているすべてのI2Cスケッチ。p>

I2C情報–I2Cプロトコルに関する情報

I2C通信パート1–ArduinoからArduino
概要
I2C通信パート1-ArduinoからArduino

I2C通信パート1-ArduinoからArduinoI2C通信パート1-ArduinoからArduinodiv>

記事名
I2c通信パート1-arduinoからarduino
説明
i2cに関する一連の記事のこの最初の部分では、i2cが何であるかを学びます。 また、Arduino WireライブラリがI2C経由の通信を非常に簡単にする方法についても説明します。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です