2014-07-18

EV3與Arduino之間的I2C通訊(測試Dexter的EV3_I2C Block) - (I) 功能摘要

五月底,由The NXT得知:DI在他們官網部落格中分享了以自行開發的EV3程式區塊(EV3_I2C)能夠透過I2C連接Arduino的方式,除了有How-To教學之外,也提供EV3 block與Arduino sample code的下載。
這確實是一個好消息,因為EV3除了官方軟體外,不像NXT還有功能彈性高而且簡單容易上手的NXC可以使用,雖然陸續有其他開發工具發展中,終究有些技術門檻,所以目前EV3若要連接外部裝置,唯有依賴第三方開發的程式區塊,而終於Dexter造福Arduino users,提供了可以Import的EV3_I2C block。

下載與匯入

可以到這個網頁的右側找到Download ZIP這個按鍵下載壓縮檔,解壓縮之後再使用EV3軟體匯入Dexter.ev3b這個檔案,就可以在Sensor Blocks裏找到Dexter所有提供的感應器區塊包含EV3_I2C Block。



EV3_I2C程式區塊

共有七種功能模式可以選擇,很顯然就是為了EV3能透過I2C連接Arduino而設計,不過應該也可以測試連接其他I2C介面的裝置。

對於每一種模式的功用望文生義,很容易就能夠理解,
不過第5項:「Read 8 bytes ASCII」,似乎功能已經移除,
在編譯時會出現以下的錯誤訊息,有待釐清。


實體接線方式

EV3 Sensor port向下相容於NXT的感應器,
所以EV3 Cable連接Arduino I2C通訊的腳位與NXT相同,
以下圖片來自於Dexter的教學文章:


至於本次測試則是使用端子座轉換EV3 Cable與Arduino UNO的接線方式:

Arduino處理方式

Arduino的I2C程式庫為 Wire.h,因為EV3為I2C Master,Arduino為Slave,所以在I2C bus初始化時需要指定Slave位址,以作為EV3(Master)傳送與接收資料的對象,而在測試案例中Slave address為:0x04:

#include <Wire.h>
#define I2C_SLAVE_ADDRESS      0x04

Wire.begin(I2C_SLAVE_ADDRESS);

接下來Arduino需要註冊處理來自Master寫入與請求資料傳送的Handler程序,分別是:

Wire.onReceive(receiveEvent);    //  註冊處理來自Master寫入資料的Handler
Wire.onRequest(requestEvent);
   //   註冊處理來自Master請求傳送資料的Handler

void receiveEvent(int howMany)
{  
   requestRegister = Wire.read();   
   while(Wire.available() > 0 && bytesRead < MAX_DATA_BUF_SIZE) {
     rcvData[bytesRead]=Wire.read();
     bytesRead++;
   }
   executeCommand(requestRegister);  
}

void requestEvent() 
  if(requestRegister == COMMAND_GET_VERSION) {
      Wire.write(softwareVersion, 8);
   }
   else if(requestRegister == COMMAND_GET_VENDOR) {
           Wire.write(vendorID, 8);
   }
   else if(requestRegister == COMMAND_GET_DEVICE_ID) {
           Wire.write(deviceID, 8);
   } 

所以,當使用EV3_I2C 程式區塊,
(1)  執行「Write 1 byte」、「Write 8 bytes」或
     「DigitalWrite」三種模式時,
      即會觸發Arduino sketch中的 receiveEvent 程序。

(2) 執行「Read 1 byte」、「Read 8 bytes」或
    「Read 8 bytes ASCII」三種模式時,
      即會觸發Arduino sketch中的 requestEvent 程序。

(3) 執行「AnalogRead」模式時,
     則因為EV3會傳送所要讀取的Arduino Analog腳位,
     再接收讀取結果,
所以Arduino sketch的兩個程序都會
     被觸發,執行的順序是:

      receiveEvent() --> loop() --> requestEvent() 

以上幾種模式的用法,在下載自Dexter壓縮檔中的 EV3_arduino 資料夾,有相關的arduino 範例程式可以參考。

※ 對於EV3與Arduino程式的運作方式,
   另於測試案例中說明

6 則留言:

  1. 作者已經移除這則留言。

    回覆刪除
    回覆
    1. 如果有甚麼問題, 歡迎提出來討論, 我會盡可能協助

      刪除
    2. 作者已經移除這則留言。

      刪除
    3. 那我要怎麼將在Arduino的上輸出數字給EV3讀

      刪除
    4. 即使用 i2C 的標準通訊方式, 其中EV3 是 master, Arduino是slave, 所以要由EV3 主動向 Arduino請求資料, Arduino 收到 EV3 的request之後再傳送資料回EV3.
      可參考這一篇文章的範例說明:
      https://chlego.blogspot.com/2014/07/ev3arduinoi2cdexterev3i2c-block-ii.html

      刪除
    5. 作者已經移除這則留言。

      刪除