Arduino を I2C Slave デバイスにするための Sketch です。自作アプリの動作確認用に作成しました。
主な仕様
- SDA = A4
- SCL = A5
- 7-bit Slave Address = 0x24 (8-bit表記では 0x48/0x49)
- SCL/SDA 内蔵 Pull-up 有り (内蔵 Pull-up 無しの Sketch もあり)
- 16-byte Register (Address: 0x00 to 0x0F)
- Burst mode 対応
- Register Address = 0x00 に値を書き込むと、値の回数だけ Arduino上の LED が点滅する
Register Map
Address (Hex) | R/W | 初期値 (Hex) |
00 | R/W | 00 |
01 | R/W | 10 |
02 | R/W | 02 |
03 | R/W | 30 |
04 | R/W | 04 |
05 | R/W | 50 |
06 | R/W | 06 |
07 | R/W | 70 |
08 | R/W | 08 |
09 | R/W | 90 |
0A | R/W | 0A |
0B | R/W | B0 |
0C | R/W | 0C |
0D | R/W | D0 |
0E | R/W | 0E |
0F | R/W | F0 |
Sketch
#include <Wire.h> byte byteSlaveADR = 0x24; // 7-bit Slave Address byte byteADR; byte byteDAT[32]; byte byteREG[] = {0x00, 0x10, 0x02, 0x30, 0x04, 0x50, 0x06, 0x70, 0x08, 0x90, 0x0a, 0xb0, 0x0c, 0xd0, 0x0e, 0xf0}; bool trig; int led=13; void setup() { pinMode(led, OUTPUT); Wire.begin(byteSlaveADR); Wire.onReceive(receiveEvent); Wire.onRequest(sendEvent); trig = false; } void loop() { if(trig){ blink_led(byteREG[0]); } delay(1000); } void blink_led(byte byteCNT){ int i; for(i=0;i<byteCNT;i++){ digitalWrite(led, HIGH); delay(100); digitalWrite(led,LOW); delay(500); } trig = false; } void receiveEvent(){ int i = 0; int j; byte byteTMP; while(Wire.available()){ if(i < 32){ byteDAT[i] = Wire.read(); } else{ Wire.read(); } i = i + 1; } byteADR = byteDAT[0]; if(i > 1){ for(j=0;j<(i-1);j++){ byteTMP = byteADR + j; if(byteTMP < 32){ byteREG[byteTMP] = byteDAT[j+1]; if(byteTMP == 0){ trig = true; } } } } } void sendEvent(){ int i; for(i=byteADR;i<16;i++){ Wire.write(byteREG[i]); } }
Sketch (SCL/SDA 内蔵Pull-up 無効)
上の Sketch に SCL/SDA の内蔵Pull-up を無効にする記述を追加したものです。
#include <Wire.h> byte byteSlaveADR = 0x24; // 7-bit Slave Address byte byteADR; byte byteDAT[32]; byte byteREG[] = {0x00, 0x10, 0x02, 0x30, 0x04, 0x50, 0x06, 0x70, 0x08, 0x90, 0x0a, 0xb0, 0x0c, 0xd0, 0x0e, 0xf0}; bool trig; int led=13; void setup() { pinMode(led, OUTPUT); Wire.begin(byteSlaveADR); Wire.onReceive(receiveEvent); Wire.onRequest(sendEvent); pinMode(SDA, INPUT); // disable internal pull-up pinMode(SCL, INPUT); // disable internal pull-up trig = false; } void loop() { if(trig){ blink_led(byteREG[0]); } delay(1000); } void blink_led(byte byteCNT){ int i; for(i=0;i<byteCNT;i++){ digitalWrite(led, HIGH); delay(100); digitalWrite(led,LOW); delay(500); } trig = false; } void receiveEvent(){ int i = 0; int j; byte byteTMP; while(Wire.available()){ if(i < 32){ byteDAT[i] = Wire.read(); } else{ Wire.read(); } i = i + 1; } byteADR = byteDAT[0]; if(i > 1){ for(j=0;j<(i-1);j++){ byteTMP = byteADR + j; if(byteTMP < 32){ byteREG[byteTMP] = byteDAT[j+1]; if(byteTMP == 0){ trig = true; } } } } } void sendEvent(){ int i; for(i=byteADR;i<16;i++){ Wire.write(byteREG[i]); } }