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接收器firmware的5種RC模式與控制指令 (LPF RC Protocol)的詳細規格, 是程式撰寫的必要參考資料, 控制指令為2-Byte Command格式, 程式必須依據規格組合成傳送資料(Data Payload), 再透過I 2C Write由IR Sensor編碼後送出IR信號.
NXT IR sensors簡介
目前市面上共有3種IR Sensor可以提供NXT傳送LPF RC Protocol的IR信號,由於功能設計上的差異, 使用I 2C 處理的方式也各不相同, 詳細規格請參考原廠文件,使用方法摘要如下:
Mindsensors NRLink-Nx | 先預載PF 2-Byte command至EEPROM中,再以R指令指定執行特定位址的2-Byte command Macro. 支援 PF’ RCX’ Train三種Mode |
Mindsensors PFMate | 主要提供PF Combo PWM Mode, 算是NRLink的改良版,但參考範例程式,事實上也提供Raw mode來傳送其他控制模式信號 |
Hitechnic IRLink | 傳送已轉換成IR cycles bit stream的PF 2-Byte command,支援 PF Mode及UART Mode. |
NXT IR sensors 的程式開發
前面所提的3種IR sensors除原廠提供的NXT-G block外, 在其他開發工具也都各自有API,不過無論是NXT-G亦或其他API,即使寫得再完整,難免會封裝掉部分的特性功能,所以個人還是較喜歡使用基本的I 2C 操作(LowspeedWrite’ LowspeedRead…)來撰寫應用程式,好處是可以盡可能的測試各種功能,同時在進行一些微調時也較有彈性.
不過也因此就必須有裝置相關的技術資料可以參考,如: I 2C bus address’ register layout ‘command等,而Mindsensors的NRLink-Nx及PFMate都有原廠提供的User guide及範例程式,所以很容易就可以掌握裝置的功能特性與用法,而Hitechnic的IRLink則無,這是比較特別的情形,因為其他的Hitechnic I 2C 裝置在產品網頁都會提供相關說明,唯獨IRLink沒有,推測應該是裝置的使用與處理比較複雜,不適合直接在網站上說明,所以只提供給API開發者或須要個別索取才會提供.
也因此解決方法就是解析各個開發工具現成的API source code, 這裡同時參考了NXC(以NBC撰寫)’ RobotC及leJOS等, 以下即就解析後所瞭解的技術細節做說明,是否已是完整的原廠資料並不確定, 不過對於使用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 操作方式
IRLink的I 2C 操作方式大致分成三個步驟:
Step.1. 依據所需的遙控功能,組合LPF RC的2-Byte command.
Step.2. 將2-Byte command 編碼成IR信號的bit stream.
Step.3. 初始化IRLink的I 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文件P6及P7的Binary representation組合成如下2-Byte command的Data payload:
Nibble1 Nibble2 Nibble3 LRC
Bit 7 6 5 4 3 2 1 0 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 sensor的macro 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 bit為b100(長度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 layout及I 2C 操作的需求填入適當的值,後續即可以透過LowspeedWrite起始IRLink的信號傳送,
● I 2C _buf[0]存放IRLink的I 2C bus address:0x02
● Bit stream data總長度為11 bytes,因此於I 2C _buf[13]填入11,同時因為IRLink data length的register address為0x4D, 所以由0x4D反推算11bytes的位址0x42為bit stream data寫入IRLink register的address, 因此於I 2C _buf[1]填入0x42,須特別注意此位址值的正確性,一旦起始LowspeedWrite IRLink會從此位址起傳送存放於0x4D之資料長度的資料.
● IRLink register address 0x4E為存放傳送模式,因此於I 2C _buf[14]填入0x02.
● 最後於I 2C _buf[15]中填入0x01(Trigger),一旦以LowspeedWrite將I 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