2009-08-22

Hitechnic IRLink I2C details(NXC實作範例)



LEGO Power Functions簡介


LEGO Power Functions(LPF/PF)為新一代具備IR遙控功能的動力系統, 2007年隨著LT8275 Motorized Bulldozer的上市正式引進, 目前PF系列相關產品有:



















PF馬達



XL-Motor(8882)


M-Motor(8883)



PF IR遙控器



IR-TX(8885)


IR Speed RC(8879)



PF IR接收器



IR-RX(8884)


L8183/L8184 RC Turbo車身座(bb 396c 01)



PF電池盒



PF 9V電池盒(8881)


充電電池盒/充電變壓器(8878/8887)



其他PF配件



延長線(8886/8871)


開關(8869)


LED(8870)



LPF IR的遙控功能建立於PF IR接收器的firmware, 當接收器接收到發送端(IR遙控器 或 NXT IR Sensor)傳送編碼後的控制指令(IR信號), 會由firmware解碼並執行對於output ports的控制動作(: 改變PF馬達的轉向轉速等狀態).


LEGO Power Functions RC文件說明了PF IR接收器firmware5RC模式與控制指令 (LPF RC Protocol)的詳細規格, 是程式撰寫的必要參考資料, 控制指令為2-Byte Command格式, 程式必須依據規格組合成傳送資料(Data Payload), 再透過I 2C WriteIR Sensor編碼後送出IR信號.


NXT IR sensors簡介


目前市面上共有3IR Sensor可以提供NXT傳送LPF RC ProtocolIR信號,由於功能設計上的差異, 使用I 2C 處理的方式也各不相同, 詳細規格請參考原廠文件,使用方法摘要如下:













Mindsensors NRLink-Nx



先預載PF 2-Byte commandEEPROM,再以R指令指定執行特定位址的2-Byte command Macro.


支援 PF’ RCX’ Train三種Mode



Mindsensors PFMate



主要提供PF Combo PWM Mode, 算是NRLink的改良版,但參考範例程式,事實上也提供Raw mode來傳送其他控制模式信號



Hitechnic   IRLink



傳送已轉換成IR cycles bit streamPF 2-Byte command,支援 PF ModeUART Mode.



 


NXT IR sensors 的程式開發


前面所提的3IR sensors除原廠提供的NXT-G block, 在其他開發工具也都各自有API,不過無論是NXT-G亦或其他API,即使寫得再完整,難免會封裝掉部分的特性功能,所以個人還是較喜歡使用基本的I 2C 操作(LowspeedWrite’ LowspeedRead…)來撰寫應用程式,好處是可以盡可能的測試各種功能,同時在進行一些微調時也較有彈性.


不過也因此就必須有裝置相關的技術資料可以參考,: I 2C bus address’ register layout ‘command,MindsensorsNRLink-NxPFMate都有原廠提供的User guide及範例程式,所以很容易就可以掌握裝置的功能特性與用法,HitechnicIRLink則無,這是比較特別的情形,因為其他的Hitechnic I 2C 裝置在產品網頁都會提供相關說明,唯獨IRLink沒有,推測應該是裝置的使用與處理比較複雜,不適合直接在網站上說明,所以只提供給API開發者或須要個別索取才會提供.


也因此解決方法就是解析各個開發工具現成的API source code, 這裡同時參考了NXC(NBC撰寫)’ RobotCleJOS, 以下即就解析後所瞭解的技術細節做說明,是否已是完整的原廠資料並不確定, 不過對於使用Power functions的功能應已經相當足夠了.


IRLink Registers Layout


I 2C Bus address: 0x02




































Register



Description



Remark



0x00~0x07



Version



 



0x08~0x 0F



Vendor ID



 



0x10~0x17



Device ID



 



0x40~0x 4C



待傳送資料



PF mode時為編碼後的bit stream資料,詳細參考以下說明



0x4D



待傳送資料長度(Bytes)



 



0x4E



傳輸模式(Mode)



0x00-UART mode


0x02-PF mode



0x 4F



傳送觸發(Trigger)



0x01-觸發傳送資料



IRLink Power Functions遙控功能的I 2C 操作方式


IRLinkI 2C 操作方式大致分成三個步驟:


Step.1.    依據所需的遙控功能,組合LPF RC2-Byte command.


Step.2.    2-Byte command 編碼成IR信號的bit stream.


Step.3.    初始化IRLinkI 2C buffer,將資料寫入register然後啟動傳送IR信號.


程式的撰寫即依序完成這三個步驟,然而因部分動作有點複雜且不易使用文字敘述表達,因此將以實例說明各個步驟的實作方法與程式範例,這樣應較能清楚交代完整的步驟,而本文也將能作為往後可以隨時參考的筆記.


IRLink控制功能說明實例:


Combo direct mode, Channel 1, Forward on port A, Backward on port B


Step 1: Build data Payload (2-Byte command)


參考LEGO Power Functions RC文件P6P7Binary representation組合成如下2-Byte commandData payload:


 


Nibble1                       Nibble2                      Nibble3               LRC


Bit 7  6  5  4               3  2  1                       bit7  6    5  4       3  2  1  0


   0  0  0  0                  0  0  0  1                          1  0    0  1       0  1  1  1


       Channel 0      Combo direct      B    A       b1111 ^ b0000 ^ b0001 ^ b1001


 


程式範例如下:


void Set_PF_ComboDirectMode(const byte x_channel, const byte x_out_a, const byte x_out_b)


{


     byte nibble3 = (x_out_b << 2) + x_out_a;


     byte lrc      = 0x 0F ^ x_channel ^ 0x01 ^ nibble3;


 


     ArrayInit(data_payload, 0, 2);


     data_payload[0] = (x_channel << 4) + 0x01;


     data_payload[1] = (nibble3    << 4) + lrc;


 


     EncodeIR();


}


以上程式碼中會將組合好的2-Byte command存放於陣列data_payload[],由本例所組成的data payload: data_payload[0] = 0x01(b0000 0001), data_payload[1]=0x97(b1001 0111),而於程式碼最後呼叫的EcodeIR()函數即會將陣列資料編碼成IR信號的bit stream, 編碼方式將在Step 2中說明.


補充說明:以上組合2-Byte command的程式碼亦適用於製作mindsensors NRLink-Nx sensormacro command, 但不需要呼叫EcodeIR()函數.



Step 2: Encode data payload into IR bit stream for transmitting


IRLink需要將2-Byte command編碼成IR信號才能傳送,編碼方式雖然在LEGO Power Functions RC文件P12中有說明,不過最後還是從其他開發工具API原始碼中取得bit stream的轉換規則,以下即說明轉換的步驟與方式:


           傳送的通訊協定除data payload,前後還須各加上start/stop信號以提供接收器解碼,而其編碼的bit stream都是:0x80(b1000 0000), bit長度是8.


           需將data_payload[]中各個bit依照high/low value(1/0)編碼成不同的IR信號, high bit IR信號之bit stream: b1000 0(長度5),low bitb100(長度3),請參考以下範例:



2-Byte command Encode into IR bit stream mapping table:


Data payload: StartBit-0-0-0-0-0-0-0-1-1-0-0-1-0-1-1-1-StopBit


Bit stream:   10000000-10010010-0100 1001-00100100-00100001-00100100-00100100-00100001-00001000- 00000000


  (Hex)     0x80-0x92-0x49-0x24-0x21-0x24-0x24-0x21-0x08-0x00


 


Start/stop bit: b1000 0000, High bit (1): b1000 0, Low bit (0): b100


 


Step 3: Initialize IRLink I 2C buffer then start transmitting


Step 2 將編碼後的bit stream data存放於陣列I 2C _buf[2]~[12],而其他陣列元素將依據IRLink register layoutI 2C 操作的需求填入適當的值,後續即可以透過LowspeedWrite起始IRLink的信號傳送,


           I 2C _buf[0]存放IRLinkI 2C bus address:0x02


           Bit stream data總長度為11 bytes,因此於I 2C _buf[13]填入11,同時因為IRLink data lengthregister address0x4D, 所以由0x4D反推算11bytes的位址0x42bit stream data寫入IRLink registeraddress, 因此於I 2C _buf[1]填入0x42,須特別注意此位址值的正確性,一旦起始LowspeedWrite IRLink會從此位址起傳送存放於0x4D之資料長度的資料.


           IRLink register address 0x4E為存放傳送模式,因此於I 2C _buf[14]填入0x02.


           最後於I 2C _buf[15]中填入0x01(Trigger),一旦以LowspeedWriteI 2C _buf寫入IRLink暫存器後,即會啟動IRLink傳送信號.



IRLink I2C buffer 存放內容:


Register       Buffer array          Value


 I2C_buf[0]            0x02 (IRLink I2C bus)


 I2C_buf[1]            0x42 (register address)


0x42~0x4C  I2C_buf[2]~[12]    0x80-0x92-0x49-0x24-0x21-0x24-0x24-0x21-0x08-0x00-0x00(11 bytes)


0x4D           I2C_buf[13]         11 (data length)


0x4E            I2C_buf[14]         0x02 (PF mode)


0x4F            I2C_buf[15]         0x01 (Trigger)


 


程式範例:


void EncodeIR()


{


     //0-I 2C bus, 1-I 2C register, 2~12-Encoding IR data, 13-msg len, 14-mode, 15-trigger


     ArrayInit(I 2C _buf, 0, MAX_IR_DATA_SIZE+5);


     I 2C _buf[0] = I 2C _DEVICE;


     I 2C _buf[1] = TX_BUFFER;


     int I 2C _buf_bit_idx;  //Current bit index of I 2C buffer


 


     //Add Start bit b1000 0000


     I 2C _buf[2]       = (1 << (START_STOP_BIT_LEN-1));


     I 2C _buf_bit_idx = START_STOP_BIT_LEN; //8 (bit7 of byte1)


    


     //Encode 2-Byte LPF RC protocol data payload into IR msg


     for (int xii=0; xii<16; xii++)


     {


         I 2C _buf[(I 2C _buf_bit_idx/8)+2] += (1 << (7-(I 2C _buf_bit_idx%8)));


         I 2C _buf_bit_idx += ((data_payload[xii/8] >> (7-(xii%8))) & 0x01)?


                            HIGH_BIT_LEN: LOW_BIT_LEN;  //5:3


     }


     //Add Stop bit b1000 0000


     I 2C _buf[(I 2C _buf_bit_idx/8)+2] += (1 << (7-(I 2C _buf_bit_idx%8)));


 


     //Add I 2C buffer data


     I 2C _buf[13] = MAX_IR_DATA_SIZE;  //11


     I 2C _buf[14] = MODE_PF;            //0x02


     I 2C _buf[15] = START_SEND;         //0x01


}





  • 留言者: CAVE
  • Email: zero.five@msa.hinet.net
  • 網址:
  • 日期: 2009-08-26 10:59:56
很詳細的說明, 感謝您!!
[版主回覆08/29/2009 18:10:57]

不客氣, 只不過將一些以前玩過的東西整理成筆記方便以後可以參考, 也希望能夠提供給國內NXT的同好可以分享







  • 留言者: CAVE
  • Email: zero.five@msa.hinet.net
  • 網址:
  • 日期: 2009-08-26 10:59:24
很詳細的說明, 感謝您!!

2009-08-12

NXT 2.0 8547 brick firmware V1.28 更新

Legoengineering.com 在 8/12 已經開放可以下載 NXT2.0 8547 Retail version 所搭載的 韌體 V1.28 版本, 下載點在此,


使用舊的教育版 NXT-G 更新後, NXT的版本資訊:


 





不過除了升級 Firmware 外, 應該還要使用 NXT-G 2.0 編譯程式, 才可以真正使用到新增的功能(如: 浮點運算), NXT-G 2.0 100% 要花錢買才有.



  • 留言者: robotman
  • Email: tslinb@hotmail.com
  • 網址:
  • 日期: 2009-10-22 07:56:07

若你需要nxt-g 2.0我可以免費提供正版軟體一套給您..算是"交朋友"囉!..^_^..


有興趣可以email到我信箱: tslinb@hotmail.com


以後有啥新的產品或玩意也希望您能做如此精闢的解說..


 


                                                                      創意機器人教育推廣中心 林老師


[版主回覆10/22/2009 17:57:32]

非常感謝林老師,


很樂意能夠與NXT的同好能夠一起切磋與分享, 這些文章原本是想作為筆記好讓以後能夠參考, 如果大家有興趣當然希望確實能有有參考價值囉 !