2016年5月7日土曜日

PSoC 4 Pioneer KitをスレーブにしてArduino UnoとI2C通信をしてみる

ブレッドボード図


PSoC 4 Pioneer KitのI2C SlaveのプログラムはExampleにある「SCB_EzI2cCommSlave」を使った。

これはI2Cのスレーブとして動作し、マスターからコマンドを受け取って、オンボードのRGB LEDの色を切り替えるというもの。

ExampleではPSoC 4 Pioneer Kit上のPSoC 5LP(ちょっとややこしいですが、PSoC 4 Pioneer KitではPCとの通信等はボード上のPSoC 5LPが受け持っている)がI2CマスターとなってUSB接続されたPCの「Bridge Control Panel」で・・・

説明するとめんどくさいのでドキュメントを見ながら実際にExampleをやってみるのが早いと思います(^q^;

PSoC 4 Pionner Kitの方は、ボード上のジャンパを3.3Vに設定してこのSlaveを走らせて、Arduino Unoは普通に5V駆動でマスタープログラムを書いて動作させた。

Arduinoのスケッチ

// Wire Master Writer
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Writes data to an I2C/TWI slave device
// Refer to the "Wire Slave Receiver" example for use with this

// Created 29 March 2006

// This example code is in the public domain.


#include <Wire.h>

#define SLAVE_ADDRESS  0x10

/* Start and end of packet markers */
#define PACKET_SOP      0x01
#define PACKET_EOP      0x17

/* Commands set */
#define CMD_SET_OFF     0
#define CMD_SET_RED     1
#define CMD_SET_GREEN   2
#define CMD_SET_BLUE    3

/* Base address */
#define BASE_ADDRESS_COMMAND  0x00
#define BASE_ADDRESS_STATUS   0x03

byte cmdOff[]   = { BASE_ADDRESS_COMMAND, PACKET_SOP, CMD_SET_OFF,   PACKET_EOP };
byte cmdRed[]   = { BASE_ADDRESS_COMMAND, PACKET_SOP, CMD_SET_RED,   PACKET_EOP };
byte cmdGreen[] = { BASE_ADDRESS_COMMAND, PACKET_SOP, CMD_SET_GREEN, PACKET_EOP };
byte cmdBlue[]  = { BASE_ADDRESS_COMMAND, PACKET_SOP, CMD_SET_BLUE,  PACKET_EOP };

void setup()
{
  Wire.begin(); // join i2c bus (address optional for master)
}

void loop()
{

  Wire.beginTransmission(SLAVE_ADDRESS);
  Wire.write(cmdRed, sizeof(cmdRed));
  Wire.endTransmission();
  delay(500);

  Wire.beginTransmission(SLAVE_ADDRESS);
  Wire.write(cmdGreen, sizeof(cmdGreen));
  Wire.endTransmission();
  delay(500);

  Wire.beginTransmission(SLAVE_ADDRESS);
  Wire.write(cmdBlue, sizeof(cmdBlue));
  Wire.endTransmission();
  delay(500);
}


ArduinoのExampleのWire/master_writerを改変してPSoCの「SCB_EzI2cCommSlave」のコマンドを送るようにした。

PSoCのプログラムは

  • master->slaveでLEDの色を切り替える
  • slave->masterでStatusを返す

ようになっているが、今回はslave->masterの返答の処理は端折った。

I2Cの通信状態


I2C通信にはプルアップが必要だが、プルアップしないでも動作した。


ch1:SDA ch2:SCL

波形はかなりなまっているが、通信はできている(SCLの9bit目でSDAがLになっている)し、LEDの表示色も切り替わる。

ExampleのDocumentを読むとPSoC 4 Pioneer Kit側でプルアップされてる可能性があるかも(?)

あとで調べるかも?

<追記:2016.05.10>

よく見ると無信号時にも4V付近まで電圧があがっている。↓のように3.3VでPull Upすると無信号時も3.3V~3.6Vあたりに落ち着く。

ということはPull Upというより、3.3Vに電圧を逃しているということになる?

どういう向きで電流が流れているかわかればはっきりするかな。

導通している部分に小さい値の抵抗を入れて電圧差を計れば電流はわかるか。

う~ん(^q^;;;

</追記>

3.3Vに1kΩでプルアップ

ブレッドボード図のようにPSoC側から供給した3.3Vに1kΩの抵抗でプルアップしてみると波形はかなり綺麗になる。

メモ:

前にも書いた気がしますが。

Arduino Unoは5V駆動で、ATMega328PのDATASHEETの「29.7 Two-wire Serial Interface Characteristics」を見ると、
VIH | Input High-voltage | 0.7 VCC
となっているので、仕様上ではHには最低、5V × 0.7 = 3.5V必要。

だが、1対1のI2C通信の場合は3.3VのPullUpでも殆どの場合動作する。

オープンドレインなので外部でPullUp必要があり、無信号時には信号線がプルアップする電圧になるため、高い方の電圧でプルアップすると電圧が低い方の素子を破壊する可能性がある。