OrangePi-PCを使ってみる

Debian Jessieでのi2c通信

Debian Jessieでのi2c通信を紹介します。
Raspberry Pi の場合、raspi-configを使ってi2cモジュールを有効にする必要がありますが、
OrangePi-PC のFAQに よると、

A19:The I²C driver is included in the kernel - you do not need load any drivers. The I²C on the CON3 is I²C-2.

だそうです。

それらしいデバイスファイルもあります。


そこで、i2c-toolsをインストールした後、mcp23017をPin#3/#5につないで、i2cdetect してみました。


mcp23017のi2cアドレスは20ですが、どちらも認識しません。
また、i2c-bus0の48番に見慣れないデバイスが現れます。
調べてみましたが、Debian Jessieではpcf8591とbmp085のi2cデバイスがカーネルに組み込まれていて、
これが悪さをすることが分かりました。


そこで、これらのデバイスをロードしないように「/etc/modprobe.d/fbdev-blacklist.conf」に以下の2行を追 加します。


再起動すると、無事mcp23017を認識できました。
その後の調べで、pcf8591だけ無効にすればいことが分かりました。


次に、以下のような回路でmcp23017の動作を確認しました。




以下のプログラムをRaspberryPiで実行すると、LEDが順番に点滅します。
Debian Jessieでも、全く同じコード、同じワイヤリングで正常に動作しました。
RpiのPin#3/#5は /dev/i2c-1  OpiのPin#3/#5は/dev/ic2-0 の違いが有りますが、
WiringPiライブラリの中でこの違いを吸収しています。
//
// test program for MCP23017 with wiringPi
// cc -o mcp23017Led mcp23017Led.c -l wiringPi
//
#include <stdio.h>
#include <time.h>
#include <wiringPi.h>
#include <wiringPiI2C.h>

#define IODIRA          0x00            // MCP23017 address of I/O direction
#define IODIRB          0x01            // MCP23017 address of I/O direction
#define GPIOA           0x12            // MCP23017 address of GP Value
#define GPIOB           0x13            // MCP23017 address of GP Value
#define ADDRESS         0x20            // MCP23017 I2C address

int main(int argc, char **argv) {
  int i;
  int fd;
  int byte;

  if ((fd=wiringPiI2CSetup(ADDRESS)) == -1){
    printf("wiringPiI2CSetup Error\n");
    return 1;
  }

  wiringPiI2CWriteReg16(fd,IODIRA,0x00);
  wiringPiI2CWriteReg16(fd,IODIRB,0x00);
  wiringPiI2CWriteReg16(fd,GPIOA,0x00);
  wiringPiI2CWriteReg16(fd,GPIOB,0x00);

  byte=0;
  for(i=0;i<8;i++) {
    byte=(byte<<1) + 1;
    wiringPiI2CWriteReg16(fd,GPIOA,byte);
    delay(1000);
  }
  delay(2000);

  for(i=0;i<10;i++) {
    byte=0;
    wiringPiI2CWriteReg16(fd,GPIOA,byte);
    delay(100);
    byte=0xff;
    wiringPiI2CWriteReg16(fd,GPIOA,byte);
    delay(100);
  }
  delay(2000);

  byte=0xff;
  for(i=0;i<8;i++) {
    byte=(byte>>1);
    wiringPiI2CWriteReg16(fd,GPIOA,byte);
    delay(1000);
  }
}

mcp23017Setup を使った digitalWrite も正常に動きました。
//
// test program for MPC23017 with wiringPi
// cc -o mcp23017Setup mcp23017Setup.c -l wiringPi
//
#include <stdio.h>
#include <stdlib.h>
#include <wiringPi.h>
#include <mcp23017.h>

#define ADDRESS         0x20            // MCP23017 I2C address
#define PINBASE 100

int main(int argc, char **argv) {
 int i;

  if (mcp23017Setup(PINBASE,ADDRESS) == -1){
    printf("mcp23017Setup Fail\n");
    return 1;
  }

  for(i=0;i<8;i++) {
    pinMode(PINBASE+i,OUTPUT);
    digitalWrite(PINBASE+i,0);
  }

  for(i=0;i<8;i++) {
    digitalWrite(PINBASE+i,1);
    delay(1000);
  }
  delay(2000);

  for(i=0;i<8;i++) {
    digitalWrite(PINBASE+7-i,0);
    delay(1000);
  }
}

こちらで紹介しているプログラムでパラレルI/Oのパ フォーマンスを計ってみました。
$ sudo ./mcp23017w
time:114.0Sec

CPUパワーの差が出るのか、RaspberryPI(209秒)よりも早いです。
30000回のパラレルI/Oの時間比較。

wiringPiライブラリ bcm2835ライブラリ
RPi(Raspbian)+MCP23017 209秒 145秒
OPi(Armbian)+MCP23017 114秒 サポートしていない

次回は 2つのi2cポートを使ったi2c通信を紹介します。