指令 | 發出耆 | 作用 |
---|---|---|
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 的資料 |
通訊也有不同程度的, 先做一個最簡單的單向通訊.
由於只有 master 可以主動發出通訊要求, 最簡單的就是由 master 向 slave 發送資料了.
這個例子是針對一些操控裝置, 例如你做了一個 i2C 的舵機, 由 arduino 發出指令, 要它轉到指定的角度, 而舵機是不會回傳任何資料的
程式同樣分開 mater 及 slave 的部份, master 發送, slave 接收.
master 發送資料
在 master 發送資料, 只有幾個簡單步驟就可以了:
- 執行 beginTransmission 並指定接收資料地址
- 以 Wire.write 把資料送出去
- 執行 endTransmission 作結束
以下是一個簡單的例子, master 把 串口收到的資料, 發送給 slave.
#include <Wire.h> #define SLAVE_ADDRESS 0x12 #define SERIAL_BAUD 57600 void setup() { Wire.begin(); Serial.begin(SERIAL_BAUD); Serial.println("I2C Master.02 started"); Serial.println(); } void loop() { if (Serial.available()) { Wire.beginTransmission(SLAVE_ADDRESS); while(Serial.available()) { Wire.write(Serial.read()); delay(1); } Wire.endTransmission(); } }
slave 接收資料
而 slave 接收, 是有點像 interrupt driven 的形式去做, 簡單的做法如下.
- 執行 Wire.onReceive 去設定接收資料的函數
- 在接收資料的函數中, 不斷以 Wire.available 檢查是否有資源, 並以 Wire.read 把一個 byute 資料提出, 直到所有資料提出後, Wire.available 為 false
注意, 因為 Wire 庫的 buffer 只有 32 個 byte, 每次發送的資料應限制在 32 個 byte 之內.
由於 master 進行 write 是沒有限制的, 如果發送超過 32 bytes, 之後的資料就會流失.
以下例子, 是在 接收的函數中, 直接處理接收回來的資料.
#include <Wire.h> #define SLAVE_ADDRESS 0x12 #define SERIAL_BAUD 57600 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.02 started\n"); } void loop() { } void receiveEvent(int count) { Serial.println("Receive Data:"); while(Wire.available()) { Serial.print((char) Wire.read()); } Serial.println("\n"); }
注意:
這個例子中在 receiveEvent 中用到 Serial.print, 只是為了簡單展示結果, 雖然這裡沒有問題, 但其實是絕不應該的.
在正常的程式中, 應該盡量避免在 receiveEvent 中放入複雜的程序, 在下一章中會提及正確的做法.
執行程式後, 在 master 板子連線的 serial monitor 輸入資料, 就會發送到 slave 板子, 再在相關的 serial monitor 顯示出來.
你好 請問關於mpu6050的data sheet有提到它有一個FIFO BUFFER有1024Bytes 請問跟WIRE庫的32-Byte buffer有相關性嗎?
回覆刪除會因為wire的buffer大小限制了FIFO的BUFFER嗎?
0
回覆刪除