2009-12-29

NXC I2C HowTo:(2)NXT I2C通訊的操作方式與步驟

 


一般的I 2C裝置, 若是使用原廠提供的NXT-G Block, 只需要對於Input/Output plug的用法瞭解清楚, 通常很快就能夠上手使用.
而使用NXC, 則必須透過NXTI 2C通訊程序與裝置進行溝通, 實作上多了一些步驟, 不過這些步驟都是標準程序, 不會因不同的裝置而有所差異, 同時如前一篇的說明, 使用NXC可以對於裝置的用法更具彈性, 也更能發揮裝置的功能, 所以即使麻煩一些都是值得的.


NXT Firmware Digital Communication功能


I 2C通訊屬非同步通訊並使用Master/Slave架構, NXTMaster, 負責啟使I 2C通訊的程序(包含: 初始化及存取請求), Slave端裝置則等候接收NXT的請求(request)並回應(Response)對應的動作, 這些請求主要就是進行存取Slave裝置的Register, 至於請求存取的目的則依裝置具備的功能而定, 例如, 可能是NXT要求讀取裝置所偵測到的值 或者 要求裝置執行特定的功能等.
此外, NXT firmware 會維護每個input ports所擁有的Internal Write bufferRead Buffer, 做為待傳送資料 接收資料的暫存空間.
同時, NXT Firmware提供了以下3Digital I/O Communication Methods能夠讓使用者可以存取Internal Write / Read Buffer, 以進行I 2C通訊的處理過程.
NXT Firmware Digital I/O Communication Methods
功能摘要:


l   NXTCommLSWrite: 起始I 2C通訊, Internal Write buffer資料傳送至裝置, 要求裝置回應指定長度的資料, 讀取資料並存放至Internal Read buffer.


l   NXTCommLSCheckStatus: 檢查I 2C通訊的進行狀態以及裝置實際回應的資料長度.


l   NXTCommLSRead: Internal Read buffer資料複製到使用者的Buffer.


NXT I 2C通訊的步驟與方式


NXT與裝置間的溝通需要按照特定的步驟進行, 這些過程屬於標準的I 2C通訊協定, 與裝置的類型無關, 雖然每個裝置具備的功能不同, 存取的需求可能不同, 然而對於這些差異性, 只需要在I 2C處理的過程中稍微調整就能符合應用上需求. 總之, 只要瞭解標準I 2C通訊的進行步驟, 則任何裝置, 都可以很容易的上手使用, 以下即對於NXT I 2C進行的步驟以及各個階段 NXC API的用法作一個整理與說明:


1.      初始化


要對於input port進行I 2C通訊前首先須將Input port type設成LOWSPEEDLOWSPEED_9V, 差別在於是否需要NXT9V供電, NXCAPI: SetSensorLowspeed(port)則會將type設成LOWSPEED_9V.
此外依據文件說明, 在設定input port type, 須先對port的狀態屬性InvalidData設成TRUE, 再以迴路(loop)等候直到firmware完成對input port的初始化同時更新狀態值為FALSE之後, 才可以繼續後續的處理.
初始化過程NXC的程式碼為:


SetSensor(port, InvalidData, TRUE);  //先將port狀態屬性設成TRUE


SetSensorLowspeed(port);           //設定port type


while (SensorInvalid(port));          //等候port完成初始化


2.    啟始I 2C通訊
NXT Firmware使用NXTCommLSWrite system call來啟始對裝置的I 2C通訊, NXC對應的APILowspeedWrite(port, returnlen, buffer), 函數使用的3個參數分別為:


l   port裝置所連接的Input port.


l   returnlen要求裝置回傳的資料長度(Bytes), 最多為16 Bytes, 若不需要讀取裝置資料則設為0.


l   buffer byte型態的陣列, 存放NXT啟始的通訊對象(裝置)位址資訊以及 準備要寫入的資料(若有的話).


在啟始每一次的通訊處理前, 必須先檢查port的狀態, 確定前一次的處理已經執行結束, 而可以接受新的處理請求, 檢查的方式是使用迴路(loop)等候直到LowspeedCheckStatus(port)函數的回傳值不等於32(STAT_COMM_PENDING).


讀取I 2C裝置資料範例


Hitechnic IRReceiver Sensor為例, 參考它的Register Layout:


Address       Type        Contents
=======   ======   ====================

42H          byte         Motor 1A control
43H          byte         Motor 1B control
44H          byte         Motor 2A control
45H          byte         Motor 2B control
46H          byte         Motor 3A control
47H          byte         Motor 3B control
48H          byte         Motor 4A control
49H          byte         Motor 4B control


若要讀取裝置所偵測到的所有PFIR信號, 可以透過I 2C通訊, 要求IRReceiver裝置從register 0x42的位址起回傳8 Bytes資料, NXC的程式範例如下:



byte I 2C _request_buf[];  //宣告byte陣列

//
1個元素: 裝置的Device address(0x02)
//
2個元素: 本次讀取之裝置register資料的起始位址(0x42)
ArrayBuild(I2C_request_buf,  0x02,  0x42);

//
檢查input port 1的狀態, 等候直到可以啟始下一次的通訊作業
while(LowspeedCheckStatus(IN_1) == STAT_COMM_PENDING);

//
啟始通訊作業, 並要求IRReceiverregister 0x42的位址回傳8 Bytes資料
LowspeedWrite(IN_1,  8,  I 2C _request_buf);


寫入I 2C 裝置資料範例


至於寫入資料至I 2C裝置的方式, 可以參考以下的NXTHID使用範例:


NXTHID Register layout:


Address       Type        Contents
=======   ======   ====================

41H          byte         Command,
42H          byte         Modifier
43H          byte         Keyboard Data


NXTHID的主要功能在於可以模擬成為鍵盤而將資料輸入到PC, 它提供3種指令作為控制傳送的動作與資料的型態, 以下範例為傳送指令至NXTHID以啟動指令的執行

/* ********************************************************
 *
寫入CommandNXTHID0x41位址以啟動指令的執行
 * Command:
T-Transmit data to PC
 *         
A
-Setup device for Ascii mode
 *         
D
-Setup device for Direct data mode
 * ******************************************************** */
 
void NXTHID_RunCmd (byte hid_cmd)
 {
      byte I 2C _buf[];
  //
宣告byte陣列
     
      //
1個元素: NXTHID Device address(0x02)
      //
2個元素: NXTHID command register(0x41)
      //
3個元素: 要寫入NXTHIDcommand(hid_cmd)
     
ArrayBuild(I 2C _buf,  0x02,  0x41,  hid_cmd);
 
      //
檢查input port 1的狀態, 等候直到可以啟始下一次的通訊作業
     
while(LowspeedCheckStatus(IN_1) == STAT_COMM_PENDING);

      //
啟始通訊作業, 並傳送hid_cmd指令至NXTHID,要求執行該指令
     
LowspeedWrite(IN_1,  0,  I 2C _buf);
 
}


3.      檢查執行狀態
當使用LowspeedWrite(port,  returnlen,  buffer)啟始通訊作業之後, 如果是對裝置請求讀取資料, 則資料將會被存入至Internal Read Buffer, 此時, 可以使用NXTCommLSCheckStatus system call來檢查執行狀態, 一方面確認通訊作業是否正常完成, 同時也可以取得存入Internal Read Buffer中資料的實際長度(Bytes).
如果要進行以上的兩個檢查, 可以使用LowspeedStatus(port, BytesReady) NXC API, 其中BytesReady並非作為函數的傳入參數, 而是存放由函數回應Internal Read buffer資料長度的變數, 稍後可參考後面的使用範例.


4.      讀取資料
讀取Internal Read Buffer資料的system callNXTCommLSRead, NXC APILowspeedRead(port, buflen, buffer), 3個參數說明如下:


l   port裝置所連接的Input port.


l   buflen讀取自Internal Read buffer資料的長度(Bytes), 最多為16 Bytes.


l   buffer byte型態的陣列, 存放自Internal Read buffer所讀取的資料.


就如同啟始通訊作業時一樣, 必須先檢查port的狀態, 確定前一次處理已經執行結束, 而可以接受新的處理請求,
檢查的方式是使用迴路(loop)等候直到LowspeedCheckStatus(port) LowspeedStatus(port, BytesReady)函數的回傳值等於32(STAT_COMM_PENDING),而我是比較習慣使用第2個函數做檢查.


2009-12-22

Xander對於John Hansen"Power Programming"再版新書的介紹



John Hansen 在11月才上市的新書 "Power Programming - ROBOTICS IN C" 第2版, 雖然已經收到將近一個月還沒時間詳細閱讀, 今天發現Xander已經在他的網站摘要介紹了這本書的內容, 有興趣的人可以去參考, 基本上Xander的介紹文雖然簡單扼要, 但相當有條理的說明每一章節的重點內容.
本文中也有John Hansen 回應有人所提問之再版內容與第一版之間差異的說明, 就如同我之前走馬看花翻過一遍之後的感覺一樣, 表面上似乎編排內容差異不大, 事實上補充了不少該有的更新內容, 尤其是NXT 2.0 firmware所新增的功能, 如: 浮點運算類型'  全彩感應器等, 還有相當多新增的API, 不過部分功能還是需要John Hansen所提供的 enhanced firmware才有支援, 如使用LCD螢幕之橢圓形與多邊形的繪圖功能,  總之, 這本書對於發掘NXT firmware所具備深一層功能的瞭解來說, 是相當值得擁有的


 啊 ! 我只是推薦好書, 絕對沒有勸Buy意思 ...


還有, 昨天又收到從 Amazon 寄來的兩本書, 分別是 這一本這一本, 其中第二本雖然也是再版, 但內容更新的相當多, 至於第一本書, 光知道作者, 它的內容 就值得讓人期待, 總之這下子元旦假期有料可以好好研究了  !!



  • 留言者: CAVE Hsieh
  • Email:
  • 網址:
  • 日期: 2009-12-25 01:10:01
對阿 我之前翻了一下也是蠻失望的 他好像就是讓你裝出來 下載現成程式然後可以動 這樣 連原始碼都沒有還是rxe檔,有點沒誠意 之前還期待這本書很久說..

不過我是還沒有仔細看啦~也有可能還有什麼東西
[版主回覆12/25/2009 21:25:28]

其實這本書所介紹的兩個機器人本來就是相當高階的設計, 不只機構, 程式本身更是精髓所在, 會買的人難免會有相當期待, 失望也在所難免, 不過Danny其實在機構設計也有他獨到之處, 看他出的第一本書就可以知道, 也許真的還是可以發掘與學習到一些東西, 何況是已經花錢買了阿


不過我還是會試著向他索取source code看看







  • 留言者: CAVE Hsieh
  • Email:
  • 網址:
  • 日期: 2009-12-24 16:36:46
哈哈 話說我最近也上亞馬遜買了這三本書 不到一個禮拜就收到了

比國內的網路書局快速便宜多了。
[版主回覆12/24/2009 17:13:38]

昨晚稍微翻一下Daniele Benedettelli的"LEGO MINDSTORMS NXT THINKING ROBOTS", 發覺完全沒有任何原始程式碼, 上官網也只下載到執行檔(rxe), 是怎樣了 ! 難道只是要讀者看圖組裝嗎 ?


2009-12-13

NXC I2C HowTo : (1).NXT I2C裝置的特性





開發3rd Party NXT周邊裝置RobotC APIXander日前發表了 ROBOTC I2C How To, Step by step的方式教導如何撰寫RobotC程式來控制NXT I 2C周邊, 這使我回想起2007年第一次嘗試使用NXC來撰寫NXTCam程式時的摸索過程, 雖然當時John HansenNXC Programmer’s Guide中已經有Low speed communication API的介紹, 然而NXTI 2C功能對於我而言仍是全新的探索領域, 而在當時也很難找到實際使用這些APINXC範例, 最後好不容易參考到了Mindsensors MTRMX-NxRobotC sample code, 將程式的寫法套用到NXC之後再加上一些摸索與測試, 終於才弄清楚了實作以及API的用法, 從此藉由對NXC使用的逐漸熟悉, 也同時對於NXT I 2C裝置特性的掌握始有了一個豁然開朗的認識.


NXT具備的I 2C處理能力相較於前一代的RCX算是相當程度的功能升級, 這也促使自NXT上市以來各式有趣又好玩的I 2C周邊不斷的推陳出新, 無論MindsensorsHiTechnic常會有意想不到的新產品推出, 使用方面雖然原廠都會有NXT-G block可供下載, 不過對於一些較複雜的進階產品, 這些NXT-G block往往只有提供到部分特定的功能而未能充分的發揮產品的特性. 所以惟有使用能夠對於裝置直接進行I 2C操作的程式軟體才能有機會突破這一層的限制, 也因此 具有完整的I 2C API呼叫函數同時免費又容易上手的NXC就成為一窺NXT的這個強大功能的最佳入門工具了!


提到NXC不免要對開發的John Hansen致敬與感激, 除了提供好用的IDE, 而他所著的Lego Mindstorms NXT power programming應該是目前對於NXTofficial firmware解說最詳細完整的書, 而這本書的2nd版在上個月也收到了, 主要增加了NXT 2.0新功能(float資料類型’Lego new color sensor…)以及第一版之後上市的幾個新I 2C裝置API的介紹,以後會找機會整理,在此先回到本文討論的主題.



本文主要將對於過去在NXT I 2C操作方式以及NXC AP I用法等的使用經驗作一個整理, 一方面除了可以提供作為筆記參考之外, 亦方便後續若有新資料補充時能有一個現成的架構可以利用, 內容方面則預計將分成3個部分:


(1)               首先對於NXT I 2C裝置的特性與用途先建立基本的認識.


(2)               接下來以NXT firmwareLowspeed Module3System call methods來說明NXT如何進行I 2C操作的方式與步驟.


(3)               最後說明NXC I 2C API的實作用法.


 



NXT I 2C裝置簡介


雖然NXTI 2C裝置都是連接在input port, 不過以裝置所實際具備的功能而言, 則未必僅作為NXT讀取資訊的輸入來源, 事實上部分裝置還可以由NXT寫入控制指令以執行特定的功能, 反而應該界定成為output device. 這是由於NXT4input ports具備I 2C的通訊處理能力, 因此可以對於具備同樣介面的周邊裝置進行讀取以及寫入資料的動作, 所以只要是使用標準的I 2C通訊協定也就能發展出各式各樣NXT可以運用的周邊裝置, 以下幾個之前的測試文可以用來說明部分NXT I 2C週邊的應用實例:.


l   讀取I 2C裝置資料的應用:
測試Hitechnic IR Receiver的回傳狀態及行為


l   寫入控制指令資料到I 2C裝置的應用:
mindsensors NXTHID 人性化介面裝置測試( Lego mindstorms NXT based HID)
Hitechnic IRLink I2C details(NXC實作範)
Mindsensors MagicWand 組裝測試


l   有些I 2C裝置則同時兼具回饋資訊以及輸出控制的功能, MindsensorsNXTServo,除了可以控制RC Servo的動作外, 還可以回饋它的位置資訊.


NXT I 2C通訊的特性


I 2C通訊是產業標準, LEGO在導入到NXT時再加上部分規範並對外公開, 提供3rd party廠商能夠開發適用於NXTI 2C裝置, 這裡先摘要說明NXT處理I 2C通訊的一些特性, 以對於後續的討論先有一個初步的了解:


1.          I 2C通訊在NXT也稱之為Digital I/O CommunicationLowspeed Communication, 為運用NXT firmwareLowspeed Module功能來進行相關操作.


2.          I 2C 通訊是Master-Slave架構, Lego界定NXT必為Master, I 2C裝置則為Slave, 因此會由NXT來主控雙邊間的資料通訊(包含:初始化寫等動作), 而裝置則被動的回應來自NXT的相關要求.


3.          NXT I 2C通訊每一次操作時最大的資料傳輸量為16 Bytes, 對於存取擁有大量資訊的周邊裝置時, 必須留意這個限制.(:Mindsensors NXTCamNXTServo)


4.          每一個I 2C裝置都具有一個特定位址, 稱為Device address (I 2C bus address), 會在出廠時由廠商預設, NXTSlave裝置進行I 2C讀寫操作時, 它的通訊標的即為:Slave裝置所接的input port + 裝置的Device address.


l   每一種裝置的Device address設定值通常可以由廠商的產品文件/網頁中取得, 不過, 有些I 2C裝置因為功能複雜, 原廠可能會因為支援能力問題只提供NXT-G block而不提供NXC API 所需的Device address資訊.


l   Lego定義的I 2C Device address7-bits編碼, 所以最多可以有127組編碼, 而在I 2C通訊時傳送的data payload會放在bit 1-bit 7, bit 0則作為R/W動作指示, 因此, 原廠所公佈的Device address事實上已經是left shift 1之後的值(也就是乘以2), NXC為採用原廠值, LeJOS若需要自行撰寫I 2C Device Class, 必須將原廠值除以2還原成真正的Device address.


5.          每一個I 2C裝置事實上都是具體而微可以執行特訂功能的微型設備, 因此會有內部記憶體用來存放所需的資料稱為Internal register(register), 而裝置對於記憶體中資料存放的布置方式稱為Register Layout, 至於每一個特定資訊在記憶體的參照位置則稱之為register address, 因此, NXT需要對於裝置存取特定的資訊時, 也就是對通訊標的(Port + Device address)內資訊所在的register address參照位置進行存取.


l  Lego對於register layout有特定的memory model, 亦即會規範特定的資訊應存放的register address, : 0x00-0x07 存放裝置的軟體版本(Sensor version number), 0x08-0x 0F 存放廠商ID(Manufacturer), 0x10-0x17 存放裝置ID(Sensor type).


l  參考Hitechnic IRReceiver Sensorregister layout, 表格中的每一列代表存放於裝置記憶體內的特定資訊, 舉例: IRReceiver若偵測到Channel 1’ Output AIR控制信號時, 會將之轉換成對應值後存放至0x42register address(Motor 1A control), 所以, 我們就可以透過I 2C Read讀取這個位置的值來得知IRReceiver偵測到的結果

     IRReceiver Register Layout


     Address       Type        Contents
=======   ======   ====================
00 – 07H    chars      Sensor version number
08 – 0FH    chars      Manufacturer
10 – 17H    chars      Sensor Type
18 – 3DH    bytes      Not used
3E – 41H    chars      Reserved
42H           byte       Motor 1A control
43H           byte       Motor 1B control
44H           byte       Motor 2A control
45H           byte       Motor 2B control
46H           byte       Motor 3A control
47H           byte       Motor 3B control
48H           byte       Motor 4A control
49H           byte       Motor 4B control



  • 留言者: CAVE
  • Email: zero.five@msa.hinet.net
  • 網址:
  • 日期: 2009-12-15 17:53:07
受教了, 說明很詳細又不會太難懂.
[版主回覆12/15/2009 22:01:06]

謝謝!
整理這些文章的目的, 主要是夠將過去玩過的心得能夠保存下來, 如果不嫌棄, 還望多多指教
您是CAVE的阿吉嗎? 對於NXC的推廣也相當用心ㄛ, 加油!