フォト
2017年10月
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
無料ブログはココログ

« 仮想アドレスの実アドレスを調べるプログラム | トップページ | IchigoJamで使えそうな障害物センサーを使ってみる »

2015年7月 5日 (日)

2台のarduinoをI2Cバスで接続して通信を行う実験(2)

以前やった2台のArduinoをI2Cバスを使って通信する実験の続きです。

02

目的は、ちょっと前に気づいたArduinoのI2CライブラリWireのスレーブの不具合
再確認
です。
前回のデータの送信のみで問題は生じませんでしたが、
今回はコマンド送信に応じたデータを受信するような通信形態を試してみました。
Arduino IDEは1.06を利用しました。

結論を先にいうと、やはりライブラリWireに不具合がありスレーブが正常動作しません。
Arduino同士でもダメでした。
「IchigoJamとArduinoでI2Cバス通信を試してみる」で行ったライブラリ修正が必要です。

\libraries\Wire\utility\twi.cのISR(TWI_vect)のswitch文のtwi_stop()をコメントアウトすると
正常に動作します(468行あたり)。

case TW_SR_STOP: // stop or repeated start condition received
    ・・・・
      // sends ack and stops interface for clock stretching
      //twi_stop();
      // callback to user defined callback
    ・・・・

動作確認プログラム
マスター側
//
// arduino I2Cマスタ
//

#include <Wire.h>
#include <stdlib.h>
void setup() {
 Serial.begin(115200); 
 Wire.begin() ;       // I2Cの初期化、マスターとする
 delay(5000) ;        // 5秒後に開始
}

// データの送信
void data_req(uint8_t c) {
  uint8_t d;
  int i;
  Wire.beginTransmission(0x10) ;          // 通信の開始処理
  Wire.write(c) ;                         // 通信データ送信
  Wire.endTransmission(false);
  Wire.requestFrom(0x10,12);
  while (Wire.available()) {
   d = Wire.read();
    Serial.write(d);    
  }  
  Serial.println();
  Wire.endTransmission();
}

// 繰り返し実行されるメインの処理関数
void loop() {
 int i;
 for (i=0;i<3; i++) {
   data_req(i);
   delay(2000);
 }  
}

スレーブ側

#include <Wire.h>

byte d;
  
// マスターからを受信
void receiveEvent(int n) {
  Serial.println("recept data");
  for (int i=0; i < n; i++) {
    if(Wire.available()) {
        d = Wire.read();
        Serial.print(d,HEX);
        Serial.print(" ");
    }
    Serial.println();
  }
}

// マスターからのリクエストに対するデータ送信
void requestEvent() {
  Serial.println("resept request.");
  if (d == 0) {
    Wire.write("Hello,World.");
  } 
  if (d == 1) {
    Wire.write("Arduino Uno.");
  } 
  if (d == 2) {
    Wire.write("I2C Testing.");
  } 
}

//セットアップ
void setup() {
  Serial.begin(115200);
  Wire.begin(0x10) ;                 // I2Cの初期化、自アドレスを10とする
  Wire.onRequest(requestEvent) ;     // マスタからのデータ取得要求のコールバック関数登録
  Wire.onReceive(receiveEvent) ;     // マスタからのデータ送信対応のコールバック関数登録
  Serial.println("i2c slave test");
}

void loop() {
}

プログラムの概要
マスター側は0~2のコードを送信してそのコードに該当するデータを受信してます。
スレーブ側は0~2に該当するデータを送信します。

2016/05/08 追記
  このI2Cライブラリ(Wire)の不具合はArduin IDE 1.6.6で対応されています。

« 仮想アドレスの実アドレスを調べるプログラム | トップページ | IchigoJamで使えそうな障害物センサーを使ってみる »

arduino」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/571408/61842001

この記事へのトラックバック一覧です: 2台のarduinoをI2Cバスで接続して通信を行う実験(2):

« 仮想アドレスの実アドレスを調べるプログラム | トップページ | IchigoJamで使えそうな障害物センサーを使ってみる »