EVShield具備的功能中,除了 Servo pins 之外,都是透過 I2C 方式進行控制,包含:三個按鍵、兩個 RGB LED、四個 Motor ports 以及 四個 Sensor ports。
而對於同樣具有 I2C 通訊介面的 EV3主機 Sensor ports,應該也可以取代 Arduino 直接連接及運用 EVShield 的功能,以下即是對於這個需求所進行的測試記錄。
【EV3 接線方式】:
如下圖,將 EVShield 背面正下方的 4 pins I2C 接腳轉接成 RJ12 cable 之後,連接 EV3 的 Sensor Port。
【EV3 使用軟體】:
EV3 程式使用 RobotC 4.32 版。
至於 EV3 軟體,目前已知 Mindsensors 與 DI 的 EV3-I2C Programming Blocks,在功能方面並不適用。
EVShield I2C 架構
如下圖,EVShield 由兩個 I2C Slave 裝置所組成,分別為 Bank A ( 位址:0x34 ) 與 Bank B ( 0x36 ),其中 LED 與 按鍵 的控制功能都建立在 Bank A,詳細的 I2C 暫存器資訊需參考 "EVShield Advanced Development Guide" 文件。
EVShield共有兩組 LED,分別位於面板的正上方 ( Front LED ) 與左下方( Rear LED ),暫存器資訊如下表:
只需將顏色值分別寫入對應的暫存器中,即可以改變 LED 顯現的顏色,以下為 RobotC 範例程式:
///////////////////////////////////////////////////////////
// @EVSH_ledSetRGB: Set Front/Rear LED RGB color value
// Front LED(0xDE)
// Rear LED(0xD7)
///////////////////////////////////////////////////////////
void EVSH_ledSetRGB(ubyte ledRegAddr,
ubyte r, ubyte g, ubyte b, int delayMSec)
{
ubyte I2C_Request[6];
short errCnt=0;
while(nI2CStatus[EVSHIELD] == i2cStatusPending) {
wait1Msec(10);
}
memset(I2C_Request, 6, 0);
I2C_Request[0] = 5;
I2C_Request[1] = EVSH_BANK_A;
I2C_Request[2] = ledRegAddr;
I2C_Request[3] = r;
I2C_Request[4] = g;
I2C_Request[5] = b;
sendI2CMsg(EVSHIELD, &I2C_Request[0], 0);
wait1Msec(delayMSec);
}
2. 按鍵狀態
EVShield透過 0xDA 這個暫存器位址讀取最新的按鍵值:
RobotC 範例程式如下:
RobotC 範例程式如下:
///////////////////////////////////////////////////////////
// @EVSH_getKeyPressValue()
// Return: 1-Left, 2-Go, 4-Right
///////////////////////////////////////////////////////////
ubyte EVSH_getKeyPressValue()
{
ubyte I2C_Request[3], I2C_Reply[1];
short errCnt=0;
while(nI2CStatus[EVSHIELD] == i2cStatusPending) {
wait1Msec(10);
}
memset(I2C_Request, 3, 1);
I2C_Request[0] = 2;
I2C_Request[1] = EVSH_BANK_A;
I2C_Request[2] = EVSH_KEY_PRESS;
sendI2CMsg(EVSHIELD, &I2C_Request[0], 1);
wait1Msec(20);
memset(I2C_Reply, 1, 0);
while(nI2CStatus[EVSHIELD] == i2cStatusPending) wait1Msec(1);
readI2CReply(EVSHIELD, &I2C_Reply[0], 1);
return I2C_Reply[0];
}
3. Motor Ports控制
以EV3 透過 EVShield Motor ports 連接馬達的實務用途在於擴充 EV3 可控制的馬達數量,尤其若同時擁有 EV3 與 NXT sets,即可以單一 EV3 主機控制超過 4 顆馬達,不過此時,EVShield 即需要外接電源才能供應 Motor ports 的電力需求。
而EVShield 對於每個 Motor Port 提供三種馬達控制模式,包含:編碼值控制、Speed 控制 與 運轉時間控制等,分別有對應的暫存器,下表是 Motor 1 Port 的暫存器設定資訊:
而EVShield 對於每個 Motor Port 提供三種馬達控制模式,包含:編碼值控制、Speed 控制 與 運轉時間控制等,分別有對應的暫存器,下表是 Motor 1 Port 的暫存器設定資訊:
此外,對於馬達的運轉狀態,可透過讀取下表中的暫存器值取得:
以下是控制馬達依據 設定速度 旋轉至 指定編碼值(角度) 的範例程式:
//////////////////////////////////////////////////////////
// @EVSH_runMotorEncoderControl()
// encoderRegAddr: M1-0x42, M2-0x4A
//////////////////////////////////////////////////////////
void EVSH_runMotorEncoderControl(ubyte bankI2CAddr, ubyte encoderRegAddr,
long encoder, short motorSpeed, bool setBraked, bool setRelPos)
{
ubyte I2C_Request[11];
short errCnt=0;
while(nI2CStatus[EVSHIELD] == i2cStatusPending) {
wait1Msec(10);
}
memset(I2C_Request, 11, 0);
I2C_Request[0] = 10;
I2C_Request[1] = bankI2CAddr;
I2C_Request[2] = encoderRegAddr;
I2C_Request[3] =(encoder & 0x000000FF); // Encoder LSB
I2C_Request[4] =(encoder & 0x0000FF00) >> 8; // Encoder Byte2
I2C_Request[5] =(encoder & 0x00FF0000) >> 16; // Encoder Byte3
I2C_Request[6] =(encoder & 0xFF000000) >> 24; // Encoder MSB
I2C_Request[7] = motorSpeed; // Speed
I2C_Request[8] = 0; // Time
I2C_Request[9] = 0; // Command B
I2C_Request[10]= 0x89; // Command A 0b1000 1001
if(setBraked) I2C_Request[10] = I2C_Request[10] | CMD_STOP_WITH_BRAKE;
if(setRelPos) I2C_Request[10] = I2C_Request[10] | CMD_ENCODER_RELATIVE;
sendI2CMsg(EVSHIELD, &I2C_Request[0], 0);
wait1Msec(50);
if(setBraked)
while(!(EVSH_getMotorStatus(EVSH_BANK_B, EVSH_M2_STATUS) == 0x10)) delay(10); // Motor stop in brake mode
else
while(!(EVSH_getMotorStatus(EVSH_BANK_B, EVSH_M2_STATUS) == 0x00)) delay(10); // Motor stop in float mode
eraseDisplay();
}
4. Sensor Ports
EVShield 對於 Sensor Ports 的控制相當複雜,主要原因在於每個感應器的介面、功能與特性各異,因此,各個感應器皆需要實作專屬的 API,這可以參考 Mindsensors 為 EVShield 所提供的 Arduino 程式庫就可以瞭解(下載: EVShield-master ) 。
因此,經以 RobotC 實作幾種類型的感應器測試,發現雖可行但比較耗費的程式開發成本,實在不太切合實際,倒不如直接連接 EV3 的 Sensor port 或 以 EVShield+Arduino 再透過 EV3 以 I2C 控制還比較實用。
沒有留言:
張貼留言