Arduino同士でI2C通信してもらいます。
R4がMaster、R3がSlaveでR3はI2Cメモリーとして働いてもらいます。R4のI/Oが5Vなので、R3とレベル変換なしに通信できるのがいい。さすがルネ。
I2Cの接続はとても簡単です。SCL同士、SDA同士を接続するだけ。
wire_master_study1.ino
#include <stdint.h> #include <Wire.h> uint8_t slave_address = 0x55; uint16_t slave_memadr[] = {0x0000, 0x0010, 0x0020, 0x0130}; void setup(void) { Wire.begin(); Serial.begin(115200); } uint8_t cnt = 0; void loop(void) { uint8_t txbuf[16]; uint8_t rxbuf[16]; uint8_t i; char uart_txbuf[128]; for (i = 0; i < 16; i++){ txbuf[i] = cnt + i; } Serial.println("start "); sprintf( uart_txbuf, "%04X : %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", slave_memadr[0], txbuf[0], txbuf[1], txbuf[2], txbuf[3], txbuf[4], txbuf[5], txbuf[6], txbuf[7], txbuf[8], txbuf[9], txbuf[10], txbuf[11], txbuf[12], txbuf[13], txbuf[14], txbuf[15]); Serial.println(uart_txbuf); Wire.beginTransmission(slave_address); Wire.write((uint8_t)((slave_memadr[0] >> 8) & 0x00FF)); Wire.write((uint8_t)((slave_memadr[0] >> 0) & 0x00FF)); for (i = 0; i < 16; i++){ Wire.write(txbuf[i]); } Wire.endTransmission(); delay(10); Wire.beginTransmission(slave_address); Wire.write((uint8_t)((slave_memadr[0] >> 8) & 0x00FF)); Wire.write((uint8_t)((slave_memadr[0] >> 0) & 0x00FF)); //Wire.endTransmission(); Wire.requestFrom(slave_address, 16); for (i = 0; i < 16; i++){ rxbuf[i] = Wire.read(); } Wire.endTransmission(); sprintf( uart_txbuf, " %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", rxbuf[0], rxbuf[1], rxbuf[2], rxbuf[3], rxbuf[4], rxbuf[5], rxbuf[6], rxbuf[7], rxbuf[8], rxbuf[9], rxbuf[10], rxbuf[11], rxbuf[12], rxbuf[13], rxbuf[14], rxbuf[15]); Serial.println(uart_txbuf); cnt = ((cnt + 1) & 0x3F); delay(1000); }
wire_slave_study1.ino
#include <Wire.h> uint8_t slave_address = 0x55; uint8_t slave_memory[0x0500]; uint16_t adr; uint8_t recv_flag; void requestEvent(){ uint8_t n; uint16_t i = 0; for (n = 0, i = 0; n < 64; n++, i++){ Wire.write(slave_memory[adr + i]); } } void receiveEvent(int n){ uint16_t i = 0; if (Wire.available()){ adr = (uint16_t)(Wire.read()) * 256; } if (Wire.available()){ adr = adr + (uint16_t)(Wire.read()); } while (Wire.available()){ slave_memory[adr + i] = Wire.read(); i = i + 1; } recv_flag = 1; } void setup(void) { pinMode(A5, INPUT_PULLUP); pinMode(A4, INPUT_PULLUP); Wire.begin(slave_address); Serial.begin(115200); Wire.onReceive(receiveEvent); Wire.onRequest(requestEvent); recv_flag = 0; } void loop(void) { char uart_txbuf[16]; uint16_t i; if (recv_flag == 1){ recv_flag = 0; sprintf(uart_txbuf, "%04X : ", adr); Serial.print(uart_txbuf); for (i = 0; i < 16; i++){ sprintf(uart_txbuf, "%02X", slave_memory[adr + i]); Serial.print(uart_txbuf); } Serial.println(""); } }はい。いつも通りのいきなりな感じです。
デバイスアドレスは0x55で1バイト目がメモリ(のふり)のアドレスのHighバイトで、2バイト目がLowバイトを指示する。Slave側はこれを記憶しておく。続けてデータが来れば、それを保存していき、リクエストが来ればWire.writeでデータを返送する。
通信の全体像はこんな感じ。
Masterが送っている(書き込んでいる(つもり))部分はこんな感じ。
Masterが要求してSlaveが返答している部分はこんな感じ。
いい感じです。
いやーついでといえばついでで久しぶりに更新しましたー。
ついでがなければ、冬休みまで放置するところやったわ。ここ1,2ヶ月でも世の中がどんどん混沌としてきて、どうなっちゃうんやろ。
供給を人質にして、(自らが作りこんだ)問題の対応にコストアップを要求してくるメーカーがあったり、まさに苦難の行軍。
コメントをお書きください