2015年8月10日月曜日

AVRをI2Cスレーブとして使う

リズムマシンのシーケンス入力用のタクトスイッチの列を制御するために、AVRを使うことを考えてみました。

本体との通信はI2Cで行うとして、この制御用のAVRはI2Cのスレーブとして動作させる必要があります。

I2CはLCD等スレーブのデバイスは使っていましたが、マイコン自体をスレーブとして使ったことがないので実験してみました。

Arduinoをマスターとして使う

単体ではテストしようがないのでArduinoをマスターとして使い、スレーブ側のAVRはLEDを発光させることにしました。


Arduinoから出ている線は、

  • D2: AVRのRESET制御
  • A4: I2CのSDA
  • A5: I2CのSCL
  • 5V
  • GND

の5本です。全体を5V系で動作させています。

ArduinoのスケッチはexampleのWire/master_writeを多少変更して使いました。

#define SLAVE_RST  2
#include <Wire.h>

void setup()
{
  pinMode(SLAVE_RST, OUTPUT);
  // sleveをRESET
  //
  digitalWrite(SLAVE_RST, LOW);
  delay(100);
  digitalWrite(SLAVE_RST, HIGH);
  
  Wire.begin(); // join i2c bus (address optional for master)
}

byte x = 0;

void loop()
{
  Wire.beginTransmission(0x7f); // transmit to device Address: 0x7f
//bgnhx  Wire.write("x is ");        // sends five bytes
  Wire.write(x);              // sends one byte
  Wire.endTransmission();    // stop transmitting

  x++;
  delay(50);
}


動作としては

  • AVRのRESET PIN(1ピン)にL→Hを出力しAVRをRESET
    →RESETをかけなくても動作するようです。
  • I2Cのマスターとして、0からインクリメントしてbyteデータを送信

です。

AVRをスレーブとして使う

サンプルプログラムは「マイコン漬け」さんのプログラム(http://morokyuu.way-nifty.com/blog/2013/07/avr-489a.html)を参考にしました。参考というかほとんどそのままです。

改変点は以下のとおりです。

  • スレーブ・アドレスを「0xfe」としました。(特に意味はないです)。AVRではTWARレジスタに7bitアドレスを左詰めで設定しますが、Arduinoではbyte型に右詰めで設定するので、「0x7f」となります。いつもこれで混乱する(^q^;
  • マスターから送られたデータを連続で受信
  • エラー時に黄色のLEDを点灯させる


ソース・コード等はGithubで公開しました。
https://github.com/ryood/Arduino_master_AVR_sleve

スレーブ・ライター

マスター→スレーブのデータ送信はこれでできそうですが、タクトスイッチの入力をマスター側に送らなければいけないのでマスター受信、スレーブ送信のテストもしないとダメっぽいです。

今日はつかれたのでまた次回!