2015年8月1日 星期六

Arduino 之間的 I2C 通訊 (3) 由 master 向 slave 發送資料/發出指令 [slave 延遲處理]

相關指令:

指令發出耆作用
Wire.begin([<address>]);master / slave啟動 Wire (由於 i2c 是用 Wire 的, 這就等同啟動 i2c 了)
Wire.beginTransmission(<address>);master開始對 <address> 的連線
Wire.endTransmission();master 關閉之前的連線
Wire.write(<data>);master 在連線上送出 一個 byte 的資料
Wire.onReceive(<function>)slave 設定用來接收資料的函數
Wire.available();slave檢查連線上是否有可接收的資料
Wire.read();slave讀取連線上的一個 byte 的資料


slave 延遲處理

之前的一篇, 不是已經可以由 master 向 slave 發送資料, 而 slave 亦成功收到了, 為什麼又攪個 延遲處理出來?

之前一篇, 處理 master 送來的資料, 都是在接收的函數之內.  但大家不要忘記, arduino 的主線, 是在 loop 之內執行的.  接收函數太大, 或會影響主程式進行, 而且, 有些時候, 主程式或許需要用到接收回來的資料.

延後處理就是把資料放進緩存一樣, 讓主程式去處理.
方法很簡單, 可以直接把資料放有有關變數, 又或用最通用的方式, 先放入一個 buffer 中.

以下例子, 就是用最通用的方式處理,

#include <Wire.h>

#define SLAVE_ADDRESS 0x12
#define SERIAL_BAUD 57600 

#define I2C_BUFFER_SIZE 32  
uint8_t i2cBuffer[I2C_BUFFER_SIZE];
uint8_t i2cBufferCnt = 0;
boolean dataPending = false;

void setup() {
  Wire.begin(SLAVE_ADDRESS);    // join I2C bus as a slave with address 1
  Wire.onReceive(receiveEvent); // register event

  Serial.begin(SERIAL_BAUD);
  Serial.println("I2C Slave.03 started\n");
}

void loop() {
  if (dataPending) {
    Serial.println("Receive Data:");
    for (int idx = 0; idx < i2cBufferCnt; idx++) Serial.print((char) i2cBuffer[idx]);
    Serial.println("\n");   
    dataPending = false;
  }
}

void receiveEvent(int count) {
  i2cBufferCnt = 0;
  while(Wire.available()) {
    i2cBuffer[i2cBufferCnt++] = Wire.read();
  }
  dataPending = true;
}


執行後, 跟之前的是沒分別的.
當然, 你也可以嘗試把 i2c 的 buffer 加大或收細, 看看有什麼影響.


相關程式下載 (master_03 跟 master_02 是一樣的)

沒有留言:

張貼留言