I2C通信のしくみについてはここがとてもわかりやすかったです。
用意するもの
・Arduino UNO 2個
・抵抗(4.7kΩ) 2個
・測距モジュール GP2Y0A21YK
・タクトスイッチ
今回はI2C通信を使って、スレーブのArduinoに繋いだ測距センサーで計測した値をマスター側で確認することと、同じくスレーブ側のスイッチのON/OFFをマスター側で確認するということをします。
余談ですがこの測距モジュール、GNDがオレンジでVccが黒というトラップがあるので注意。
センサーから値を得る
Analog inの4がSDA、5がSCLでそれぞれを5Vからプルアップ抵抗をはさんだところに繋ぎます。手持ちの4.7kΩを繋いだのですが、どうもここによると今回使う「Wire.h」のほうで内部プルアップ抵抗をONにする設定をしてくれているそうなので、いらないと言えばいらないです。
ちなみに上がスレーブで下がマスターです。
先述したとおり、「Wire.h」を利用するのですが、使い方はArduinoのリファレンスでWireのところを参照してください。
「スレーブ側」↓
#include <Wire.h>
#define dist_PIN 1
void setup()
{
Serial.begin(9600);
Wire.begin(8); // スレーブのアドレスを8に設定
Wire.onRequest(psd); // マスターに呼ばれたときに呼び出す関数
}
void loop()
{
delay(100);
}
void psd()
{
// 以下は距離[cm]を求める近似計算
int temp,distance;
temp = analogRead(dist_PIN);
if(temp<4) temp = 4; // 0除算を回避
distance = (6787 / (temp - 3) );
Wire.write(distance); // 1バイト送信
}「マスター側」↓#include <Wire.h>
void setup()
{
Serial.begin(9600);
Wire.begin(); // マスターに設定
}
void loop()
{
// スレーブの8番に接続されているデバイスから1バイトのデータを取得
// 送られてくる値は10進数で255以下、つまり1バイト以内であるため
Wire.requestFrom(8, 1);
// Wire.available()がfalseになるまでループ
// 要求より短いデータがくる可能性あり
while(Wire.available())
{
int c = Wire.read(); // 1バイト受信
Serial.print(c);
}
Serial.println(" cm");
delay(500);
}スイッチのON/OFF (文字列の送信)
配線例 同じく上がスレーブで下がマスターです。
「スレーブ側」↓
#include <Wire.h>
int pullup =1;
void setup()
{
Serial.begin(9600);
Wire.begin(8); // スレーブのアドレスを8に設定
Wire.onRequest(on_off); // マスターに呼ばれたときに呼び出す関数
pinMode(12,INPUT_PULLUP); //内部プルアップ抵抗を使う
}
void loop()
{
delay(100);
}
void on_off()
{
pullup = digitalRead(12);
if (pullup == 0){
Wire.write("ON "); // 3バイト送信
}
else{
Wire.write("OFF"); // 3バイト送信
}
}「マスター側」↓#include <Wire.h>
void setup()
{
Serial.begin(9600);
Wire.begin(); // マスターに設定
}
void loop()
{
// スレーブの8番に接続されているデバイスから3バイトのデータを取得
// 送られてくるのは3バイトの文字列であるため
Wire.requestFrom(8, 3);
while(Wire.available())
{
char c = Wire.read(); // 1バイト受信
Serial.print(c);
}
Serial.println("");
delay(500);
}結果
Wire.hを使って思ってたよりも簡単にI2C通信をすることができました。
今回はスレーブから値を読み取るだけでしたが、他にもマスターからスレーブへの命令を飛ばしたり、以前作った量産型Arduinoを複数台繋げたり、Raspberry Piを購入したのでそれとも繋げたりしたいです。
次回→Arduino同士でI2C通信(2)
※2015/04/16 追記
I2C通信するシリーズに記事を追加しました
→【Ruby】 Raspberry Pi とArduinoでI2C通信
参考ページ
Arduino Duemilanoveを2個I2C接続
2台のarduinoをI2Cバスで接続して通信を行う実験
参考書籍
Arduinoで電子工作をはじめよう!

0 件のコメント:
コメントを投稿