RaspberryとArduinoのi2c通信(その1)


RapberryとArduinoのi2c通信は色々なところで紹介されていますので、私が改めて紹介することもありませんが、
忘備(自分のため)にまとめておきます。
最初は一番単純なRaspberry側がマスター、Arduino側がスレーブで、1文字のデータをやりとりするサンプルです。

Arduinoにはレベルシフトが不要な3.3V駆動のProMiniを使いました。
結線はRaspberryのSDAとProMiniのSDA、RaspberryのSCLとProMiniのSCLをつなぐだけですが、
ProMiniのSDA(PC4)、SCL(PC5)のピンは普通とは違う位置にあります。



Arduino側のスケッチは以下の通りです。
Raspberryからi2c経由で1バイト受け取って、値によりLEDをON/OFFしています。
//
// ATmega I2Cスレーブ sample
//

#include <Wire.h>
#define SLAVE_ADDRESS 0x08
int status = 0;

void setup() {
  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);
  digitalWrite(0, LOW); // set the LED off
  digitalWrite(1, LOW); // set the LED off

  // initialize i2c as slave
  Wire.begin(SLAVE_ADDRESS);

  // define callbacks for i2c communication
  Wire.onReceive(receiveEvent);
  Wire.onRequest(requestEvent);
}

void loop() {
  delay(100);
}

// callback for received data
void receiveEvent(int byteCount){
  int number;

  while(Wire.available()) {
    number = Wire.read();
    if (number == 1){
      digitalWrite(0, HIGH); // set the LED on
      status=HIGH;
    } else if (number == 2) {
      digitalWrite(0, LOW);  // set the LED off
      status=LOW;
    } else if (number == 3) {
      digitalWrite(1, HIGH); // set the LED off
      status=HIGH;
    } else if (number == 4) {
      digitalWrite(1, LOW);  // set the LED off
      status=LOW;
    }
  }
}

// callback for sending data
void requestEvent(){
  Wire.write(status);
}

Raspberry側のプログラムは以下の通りです。

#include <wiringPi.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

/*
cc -o test1 test1.c -lwiringPi
*/

int main (void)
{
    int fd;
    int sdata;
    int Val;

    if ((fd = wiringPiI2CSetup(0x08)) < 0)
    {
        printf("wiringPiI2CSetup failed:\n");
    }

    while(1) {
      printf("Enter i2c send data=");
      scanf("%d",&sdata);
      if (sdata < 0) break;
      wiringPiI2CWrite(fd,sdata);
      Val = wiringPiI2CRead(fd);
      printf("Val=%d\n",Val);
    }
}

i2c-toolsを使えばコマンドラインからも操作することができます。
$ sudo apt-get install i2c-tools
$ i2cset -y 1 0x08 0x01
$ i2cset -y 1 0x08 0x03
$ i2cset -y 1 0x08 0x02
$ i2cset -y 1 0x08 0x04

次回はレジスターアドレスを指定した通信を紹介します。