LEGO EV3 通信开发者套件
1 MINDSTORMS EV3 可編程 brick 的硬件規格
LEGO MINDSTORMS EV3 可編程 brick 是新 LEGO MINDSTORMS 平臺內的中央處理單元。可編程 brick 由各種先進的電子設備組成,以實現其廣泛的功能。
下面的列表是 EV3 可編程 brick 硬件規格總結。
| 主處理器 | 32-bit ARM9 processor, Texas Instrument AM1808 - 300 MHz - OS: LINUX |
| 存儲器 | 64 MB DDR RAM 16 MB FLASH 256 KB EEPROM |
| Micro SD卡接口 | SDHC standard, 2 – 32 GB |
| Bluetooth 無線通信 | Bluetooth V2.1 EDR, Panasonic PAN1325 模塊 - Texas Instrument CC2550 芯片 - BlueZ Bluetooth 棧 - Primary usage, Serial Port Profile (SPP) |
| USB 2.0 通信,客戶端接口 | 高速端口 (480 MBit/s) |
| USB 1.1 通信,客戶端接口 | 全速端口 (12 MBit/s) |
| 4 個輸入端口 | 6 個接口同時支持數字和模擬接口 - 模擬輸入 0 – 5 V - 支持 Auto-ID 擴展設備 - UART 通信 * Up to 460 Kbit/s (Port 1 and 2) * Up to 230 Kbit/s (Port 3 and 4) |
| 4 個輸出端口 | 6 個有線接口,支持電機編碼器輸入 |
| 顯示 | 178x128 像素黑白點陣顯示器 - 可視區域: 29.9 x 41.1 mm |
| 擴音器 | 直徑,23 mm |
| 6 個按鈕用戶接口 | 環繞 UI 燈 |
| 電源 | 6 AA 電池 - 建議使用堿性電池 - 可充電鋰離子電池,2000 mAH |
| 鏈接器 | 6 線工業標準連接器,RJ-12右側調節 |
2 通信接口
這部分將描述不同類型 masters(主機)與 LEGO MINDSTORMS EV3 brick 通信所用的協議。EV3 支持多種通信接口 Bluetooth,USB 和 WiFi。EV3 協議對于所有 3 種傳輸技術都是相同的。
除了運行用戶程序外,VM(虛擬機)還能執行通過上述技術之一發送的直接命令。直接命令由構成常規字節碼的小程序組成,有關各字節碼的更多詳細信息,請參考 LEGO MINDSTORMS EV3 固件開發者套件。這些直接命令(代碼片段)與運行的用戶程序并行執行。
在組合這些直接命令時要特別小心。在使用危險的代碼和結構時沒有任何限制(例如,允許直接命令中出現死鎖循環)。然而 “普通的” 運行中的程序將繼續正常工作 - 只有 VM 的直接命令部分將被這樣的死鎖循環 “鎖死”。
由于頭部只為變量分配包含 2 個字節,直接命令僅限于一個 VMTHREAD - 即SUBCALLs 和 BLOCKs 當然是不可能的。
具有數據響應的直接命令可以把返回數據放在全局變量空間中。全局變量空間 “等于” 通信響應緩沖區。直接命令的組成定義了放置結果的偏移量位置(全局變量 0 放在返回緩沖區中偏移量為 0 的位置)。
響應緩沖區(全局變量)中的偏移量必須對齊(第一個對齊到 float/32 位,最后一個對齊到 8 位)。
除了直接命令,EV3 還支持系統命令,這是更通用的術語命令,它們被用于向/從嵌入式 EV3 系統下載和上傳數據。
3 系統命令
#define SYSTEM_COMMAND_REPLY 0x01 // 系統命令,需要應答 #define SYSTEM_COMMAND_NO_REPLY 0x81 // 系統命令,無需應答系統命令字節:
字節 0 - 1:命令大小,小尾端。命令大小不包含這 2 個字節
字節 2 - 3:消息計數器,小尾端。Forth running counter
字節 4:命令類型。參考上面的定義
字節 5:系統命令。參考下面的定義
字節 6 - n:依賴于字節 5 中給出的系統命令
系統命令:
#define BEGIN_DOWNLOAD 0x92 // 開始文件下載 #define CONTINUE_DOWNLOAD 0x93 // 繼續文件下載 #define BEGIN_UPLOAD 0x94 // 開始文件上傳 #define CONTINUE_UPLOAD 0x95 // 繼續文件上傳 #define BEGIN_GETFILE 0x96 // 開始從文件獲取字節(在寫入文件時) #define CONTINUE_GETFILE 0x97 // 繼續從文件獲取字節(在寫入文件時) #define CLOSE_FILEHANDLE 0x98 // 關閉文件句柄 #define LIST_FILES 0x99 // 列出文件 #define CONTINUE_LIST_FILES 0x9A // 繼續列出文件 #define CREATE_DIR 0x9B // 創建目錄 #define DELETE_FILE 0x9C // 刪除 #define LIST_OPEN_HANDLES 0x9D // 列出句柄 #define WRITEMAILBOX 0x9E // 寫郵箱 #define BLUETOOTHPIN 0x9F // 把可信的 pin 碼傳入 brick #define ENTERFWUPDATE 0xA0 // 重啟 brick 進入 Firmware 更新模式3.1 系統命令應答
#define SYSTEM_REPLY 0x03 // 系統命令應答 OK #define SYSTEM_REPLY_ERROR 0x05 // 系統命令應答 ERROR系統應答字節:
字節 0 - 1:應答大小,小尾端。應答大小不包含這 2 個字節
字節 2 - 3:消息計數器,小尾端。等于直接命令
字節 4:應答類型。參考上面的定義
字節 5:這個應答響應的系統命令
字節 6:系統應答狀態 - 錯誤,信息或成功。參考下面的定義
字節 7 - n:進一步的系統應答字節依賴于系統命令和系統應答狀態
系統命令應答狀態碼:
#define SUCCESS 0x00 #define UNKNOWN_HANDLE 0x01 #define HANDLE_NOT_READY 0x02 #define CORRUPT_FILE 0x03 #define NO_HANDLES_AVAILABLE 0x04 #define NO_PERMISSION 0x05 #define ILLEGAL_PATH 0x06 #define FILE_EXITS 0x07 #define END_OF_FILE 0x08 #define SIZE_ERROR 0x09 #define UNKNOWN_ERROR 0x0A #define ILLEGAL_FILENAME 0x0B #define ILLEGAL_CONNECTION 0x0C3.2 向 EV3 可編程 brick 下載數據
下載大文件可能非常耗時,因此文件下載可以以 2 種不同的方式完成。
以最大可能塊下載文件,即盡可能使用最大的數據包大小(總命令大小不包括在內。 Length 字節= 65534字節)。如果總消息大小可以保持在 65534 字節以下,則所有的數據可以放進 開始下載 命令,這將是下載文件最快的方式。這是最快的下載方式,但在這段時間內系統也會被鎖定。
把文件下載分為更小的部分,即一個 開始下載 后面跟著大量的 繼續下載 命令,這將增加總的下載時間,但在持續的 繼續下載 命令交錯間也將給其它命令(更高優先級的)留下空間(時間片)。
這是下載文件最慢的方式,但可以在 繼續下載 消息間交錯其他命令。
由于包中沒有停止或其它同步字節 - 一個消息一定不能被其它消息打斷。即當 brick 已經接收了命令大小(消息的頭 2 個字節)時,所有剩余的字節必須無中斷地被傳送和接收。這個特定消息的應答(來自于 brick)也應該在任何新消息被發送和由 brick 處理前被傳送和接收。
下面的例子基于想要給 P-Brick 發送一個文件的主機應用(X3 software)構建:
命令大小,命令類型,開始 D/L,文件大小,文件名 ------>
???????????????????????<------ 命令大小,命令類型,句柄
命令大小,命令類型,繼續 D/L,句柄,載荷 ------>
????????????????????<------ 命令大小,命令類型
命令大小,命令類型,繼續 D/L,句柄,載荷 ------>
????????????????????<------ 命令大小,命令類型
命令大小,命令類型,繼續 D/L,句柄,載荷 ------>
3.2.1 文件下載
- 目的文件名路徑相對于 "lms2012/sys" 定位
- 目的目錄自動從文件名路徑創建
- 第一個目錄名必須是:***“apps”***,***“prjs”*** 或 "tools" (參考 \ref UIdesign)
- 文件名路徑中的第二個文件夾名稱必須等于字節碼可執行名稱
3.2.2 文件上傳(文件讀取)
- BEGIN_UPLOAD 和 CONTINUE_UPLOAD 在文件上傳結束時自動關閉文件句柄。
- BEGIN_GETFILE 和 CONTINUE_GETFILE 當到達 EOF 時不關閉文件句柄
- CONTINUE_GETFILE 也返回完整的文件大小
3.2.3 目錄上傳
- LIST_FILES 只要列表不超過 1014 字節,就可以工作。
3.3 系統命令,通信例子
在下文中,系統命令通信示例的例子將幫助說明接口。
3.3.1 文件下載
下載文件 “…/apps/tst/tst.rbf”
???BEGIN_DOWNLOAD:
?????向 brick 發送的字節:
?????1C00xxxx0192xxxxxxxx2E2E2F617070732F7473742F7473742E72626600??(Hex)
?????bbbbmmmmttssllllllllnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
?????bbbb = 消息中的字節數
?????mm = 消息計數器
?????tt = 命令類型
?????ss = 系統命令
?????llllllll = 文件長度
?????nn… = 以 0 結束的文件名
?????從 brick 接收的字節:
?????0600xxxx03920000??(Hex)
?????bbbbmmmmttssrrhh
?????bbbb = 消息中的字節數
?????mm = 消息計數器
?????tt = 命令類型
?????ss = 系統命令
?????rr = 返回狀態
?????hh = 文件句柄
???CONTINUE_DOWNLOAD:
?????向 brick 發送的字節:
?????xxxxxxxx819300xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx??(Hex)
?????bbbbmmmmttsshhpppppppppppppppppppppppppppppppppppppppp
?????bbbb = 消息中的字節數
?????mm = 消息計數器
?????tt = 命令類型
?????ss = 系統命令
?????hh = 文件句柄(在 BEGIN_DOWNLOAD 中返回)
?????pp… = 載荷
?????從 brick 接收的字節:
?????0600xxxx03930000??(Hex)
?????bbbbmmmmttssrrhh
?????bbbb = 消息中的字節數
?????mm = 消息計數器
?????tt = 命令類型
?????ss = 系統命令
?????rr = 返回狀態
?????hh = 文件句柄
3.3.2 文件上傳
???BEGIN_UPLOAD:
?????向 brick 發送的字節:
?????xxxxxxxx0194xxxxxxx
?????bbbbmmmmttssllllnnn…
?????bbbb = 消息中的字節數
?????mmmm = 消息計數器
?????tt = 命令類型
?????ss = 系統命令
?????llll = 要讀取的字節
?????nnn… = 文件名,包含路徑
?????從 brick 接收的字節:
?????xxxxxxxx039400xxxxxxxx00xxx
?????bbbbmmmmttssrrllllllllhhppp…
?????bbbb = 消息中的字節數
?????mmmm = 消息計數器
?????tt = 命令類型
?????ss = 系統命令
?????rr = 返回狀態
?????llllllll = 文件大小
?????hh = 文件句柄
?????ppp… = 載荷
???CONTINUE_UPLOAD:
?????向 brick 發送的字節:
?????0700xxxx019500xxxx
?????bbbbmmmmttsshhllll…
?????bbbb = 消息中的字節數
?????mmmm = 消息計數器
?????tt = 命令類型
?????ss = 系統命令
?????hh = 文件句柄
?????llll = 要讀取的字節
?????向 PC 發送的字節:
?????xxxxxxxx03950000xxx
?????bbbbmmmmttssrrhhppp…
?????bbbb = 消息中的字節數
?????mmmm = 消息計數器
?????tt = 命令類型
?????ss = 系統命令
?????rr = 返回狀態
?????hh = 句柄
?????pppp… = 載荷
3.3.3 獲取文件內容
用于上傳數據記錄文件 - 文件句柄只在文件指針到達 EOF 時關閉,且文件不以寫模式打開。
???BEGIN_GETFILE:
?????向 brick 發送的字節:
?????xxxxxxxx0196xxxxxxx
?????bbbbmmmmttssllllnnn…
?????bbbb = 消息中的字節數
?????mmmm = 消息計數器
?????tt = 命令類型
?????ss = 系統命令
?????llll = 最大讀取字節數
?????nnnn… = 路徑
?????向 PC 發送的字節:
?????xxxxxxxx039600xxxxxxxx00xxx
?????bbbbmmmmttssrrllllllllhhppp…
?????bbbb = 消息中的字節數
?????mmmm = 消息計數器
?????tt = 命令類型
?????ss = 系統命令
?????rr = 返回狀態
?????llllllll = 文件大小
?????hh = 句柄
?????ppp… = 載荷
???CONTINUE_GETFILE:
?????向 brick 發送的字節:
?????0700xxxx019700xxxx
?????bbbbmmmmttsshhllll
?????bbbb = 消息中的字節數
?????mmmm = 消息計數器
?????tt = 命令類型
?????ss = 系統命令
?????hh = 句柄
?????llll = 最大讀取字節數
?????向 PC 發送的字節:
?????xxxxxxxx039700xxxxxxxx00xxx
?????bbbbmmmmttssrrllllllllhhppp…
?????bbbb = 消息中的字節數
?????mmmm = 消息計數器
?????tt = 命令類型
?????ss = 系統命令
?????rr = 返回狀態
?????llllllll = 文件大小
?????hh = 句柄
?????ppp… = 載荷
3.3.4 列出文件和目錄
???LIST_FILES:
???新行分隔列表的格式為:
???如果是文件:
???MD5SUM 的 32 chars (hex) + space + 8 chars (hex) 的文件大小 + space + 文件名 + 新行
???如果是目錄:
???目錄名 + / + 新行
?????向 brick 發送的字節:
?????xxxxxxxx0199xxxxxxx
?????bbbbmmmmttssllllnnn…
?????bbbb = 消息中的字節數
?????mmmm = 消息計數器
?????tt = 消息類型
?????ss = 系統命令
?????llll = 最大讀取字節數
?????nnn… = 路徑名
?????向 PC 發送的字節:
?????xxxxxxxx0399xxxxxxxxxxxxxxx
?????bbbbmmmmttssrrllllllllhhnnn…
?????bbbb = 消息中的字節數
?????mmmm = 消息計數器
?????tt = 消息類型
?????ss = 系統命令
?????rr = 返回狀態
?????llllllll = 列表大小
?????hh = 句柄
?????nnn… = 新行分隔列表
???CONTINUE_LIST_FILES:
?????向 brick 發送的字節:
?????0700xxxx019Axxxxxx
?????bbbbmmmmttsshhllll
?????bbbb = 消息中的字節數
?????mmmm = 消息計數器
?????tt = 命令類型
?????ss = 系統命令
?????hh = 句柄
?????llll = 最大讀取字節數
?????向 PC 發送的字節:
?????xxxxxxxx039Axxxxxxx
?????bbbbmmmmttssrrhhppp…
?????bbbb = 消息中的字節數
?????mmmm = 消息計數器
?????tt = 命令類型
?????ss = 系統命令
?????rr = 返回狀態
?????hh = 句柄
?????ppp… = 載荷
3.3.5 關閉文件句柄
???CLOSE_FILEHANDLE:
?????向 brick 發送的字節:
?????xxxxxxxx019800xxxxxxxxxxxxxxxx
?????bbbbmmmmttsshhpppppppppppppppp
?????bbbb = 消息中的字節數
?????mmmm = 消息計數器
?????tt = 消息類型
?????ss = 系統命令
?????hh = 句柄
?????ppp… = 哈希
?????向 PC 發送的字節:
?????0500xxxx039800
?????bbbbmmmmttssrr
?????bbbb = 消息中的字節數
?????mmmm = 消息計數器
?????tt = 消息類型
?????ss = 系統命令
?????rr = 返回狀態
3.3.6 創建目錄
???CREATE_DIR:
?????向 brick 發送的字節:
?????xxxxxxxx019Bxxxxxx…
?????bbbbmmmmttsspppppp…
?????bbbb = 消息中的字節數
?????mmmm = 消息計數器
?????tt = 消息類型
?????ss = 系統命令
?????pp = 以 null 結尾的字符串,其中包含了要創建的目錄的完整路徑
?????向 PC 發送的字節:
?????0500xxxx039Bxx
?????bbbbmmmmttssrr
?????bbbb = 消息中的字節數
?????mmmm = 消息計數器
?????tt = 消息類型
?????ss = 系統命令
?????rr = 返回狀態
3.3.7 刪除一個文件
???DELETE_FILE:
?????向 brick 發送的字節:
?????xxxxxxxx019Cxxxxxx…
?????bbbbmmmmttsspppppp…
?????bbbb = 消息中的字節數
?????mmmm = 消息計數器
?????tt = 消息類型
?????ss = 系統命令
?????pp = 以 null 結尾的字符串,其中包含了要刪除的文件的完整路徑
?????向 PC 發送的字節:
?????0500xxxx039Cxx
?????bbbbmmmmttssrr
?????bbbb = 消息中的字節數
?????mmmm = 消息計數器
?????tt = 消息類型
?????ss = 系統命令
?????rr = 返回狀態
3.3.8 獲取打開句柄的列表
???LIST_OPEN_HANDLES:
?????向 brick 發送的字節:
?????xxxxxxxx019D
?????bbbbmmmmttss
?????bbbb = 消息中的字節數
?????mmmm = 消息計數器
?????tt = 消息類型
?????ss = 系統命令
?????向 PC 發送的字節:
?????xxxxxxxx039Dxxxxxx…
?????bbbbmmmmttssrrpppp…
?????bbbb = 消息中的字節數
?????mmmm = 消息計數器
?????tt = 消息類型
?????ss = 系統命令
?????rr = 返回狀態
?????pppp = 用于指示句柄是否處于 busy 狀態的位
3.3.9 寫郵箱
???WRITEMAILBOX:
?????向另一個 brick 發送的字節:
?????郵箱名稱必須以 0 結尾,同時名稱長度必須是剔除結尾的 0 的字符數!
?????xxxxxxxx819Exxxxxxxxxxxxxxxxxxxx
?????bbbbmmmmttssllaaaaa…LLLLppp…
?????bbbb = 消息中的字節數
?????mmmm = 消息計數器
?????tt = 消息類型
?????ss = 系統命令
?????ll = 名稱長度
?????aaa… = 名稱
?????LLLL = 載荷長度
?????ppp… = 載荷
?????從另一個 brick 接收的應答:
?????無效
3.3.10 設置 Bluetooth PIN 碼
???BLUETOOTHPIN:
?????出于安全的原因,這個命令只能通過 USB 發送,且應該被格式化為:
??????* Bluetooth 地址一定不能包含冒號
??????* Bluetooth MAC 地址是 0 結尾的字符串類型
??????* Bluetooth pin 碼是 0 結尾的字符串類型
?????向 brick 發送的字節:
?????0E00xxxx019F06xxxxxxxxxxxx04xxxx
?????bbbbmmmmttssllaaaaaaaaaaaaLLpppp
?????bbbb = 消息中的字節數
?????mmmm = 消息計數器
?????tt = 消息類型
?????ss = 系統命令
?????ll = MAC 長度
?????aaa… = PC 的 MAC 地址
?????LL = pin 長度
?????ppp… = pin 碼
?????向 PC 發送的字節:
?????0F00xxxx039Fxx06xxxxxxxxxxxx04xxxx
?????bbbbmmmmttssrrllaaaaaaaaaaaaLLpppp
?????bbbb = 消息中的字節
?????mmmm = 消息計數器
?????tt = 消息類型
?????ss = 系統命令
?????rr = 返回狀態
?????ll = MAC 長度
?????aaa… = PC 的 MAC 地址
?????LL = pin 長度
?????ppp… = pin 碼
3.3.11 強制 EV3 可編程 brick 進入 Firmware 升級模式
這個命令用于強制 brick 進入 Firmware 升級模式。這個命令將不發送任何響應回主機。關閉(關機)Linux OS 時,不會更新文件系統。
???ENTERFWUPDATE:
?????向 brick 發送的字節:
?????0400xxxx81A0
?????bbbbmmmmttss
?????bbbb = 消息中的字節數
?????mmmm = 消息計數器
?????tt = 消息類型
?????ss = 系統命令
4. 直接命令
#define DIRECT_COMMAND_REPLY 0x00 // 直接命令,需要應答 #define DIRECT_COMMAND_NO_REPLY 0x80 // 直接命令,無需應答直接命令字節:
字節 0 - 1:命令大小,小尾端。命令大小不包含這 2 個字節
字節 2 - 3:消息計數器,小尾端。Forth running counter
字節 4:命令類型。參考上面的定義
字節 5 - 6:使用壓縮格式保留(分配)全局變量和局部變量(在字節 5 和字節 6 的 2 個 lsb 中保留全局變量,在字節 6 的高 6 位中保留本地變量) - 見下文:
字節 7 - n:單個命令或復合命令的字節代碼(即多個命令組合為一個小程序)
局部的 = “l”, 全局的 = “g”
Byte 6: Byte 5: 位號: 76543210 76543210 變量大小: llllllgg gggggggggg gggggggg 全局變量保留 0 – (2^10 – 1) 0…1023 字節
llllllxx 局部變量保留 0 – (2^6 – 1) 0…63 字節
4.1 直接應答
#define DIRECT_REPLY 0x02 // 直接命令應答 OK #define DIRECT_REPLY_ERROR 0x04 // 直接命令應答 ERROR直接應答字節:
字節 0 - 1:應答大小,小尾端。應答大小不包含這 2 個字節
字節 2 - 3:消息計數器,小尾端。與直接命令相同
字節 4:應答類型。參考上面的定義
字節 5 - n:響應緩沖區,即命令為全局變量保留的字節內容。即如果命令保留 64 字節,這些字節將被放在應答包的字節 5 到 68。
4.2 直接命令,通信示例
下面的直接命令通信的例子將幫助更詳細地說明接口。使用的高層的宏說明如下。
更高層的參數編碼:
為了使使用參數編碼更簡單,而使用了 “bytecodes.h” 中定義的一些宏(關于參數編碼也可以參考 “LEGO MINDSTORMS EV3 - Firmware Developer Kit” 文檔中第 9 頁 - 3.4 參數編碼),所示的范圍被編碼為有符號數。
| LC0(v) | Short constant(value) | single byte | +/- 31 |
| LC1(v) | Long constant(value) | one byte to follow (2 bytes) | +/- 127 |
| LC2(v) | Long constant(value) | two bytes to follow (3 bytes) | +/- 32767 |
| LC4(v) | Long constant(value) | four bytes to follow (5 bytes) | +/- 2147483647 |
| LV0(i) | Short LOCAL variable(adr) | single byte at adr | +/- 31 |
| LV1(i) | Long LOCAL variable(adr) | one byte to follow at adr (2 bytes) | +/- 127 |
| LV2(i) | Long LOCAL variable(adr) | two bytes to follow at adr (3 bytes) | +/- 32767 |
| LV4(i) | Long LOCAL variable(adr) | four bytes to follow at adr (5 bytes) | +/- 2147483647 |
| GV0(i) | Short GLOBAL variable(adr) | single byte at adr | +/- 31 |
| GV0(i) | Long GLOBAL variable(adr) | one byte to follow at adr (2 bytes) | +/- 127 |
| GV0(i) | Long GLOBAL variable(adr) | two bytes to follow at adr (3 bytes) | +/- 32767 |
| GV0(i) | Long GLOBAL variable(adr) | four bytes to follow at adr (5 bytes) | +/- 2147483647 |
4.2.1 在 EV3 brick 上啟動程序 “Demo”
加載并運行一個應用字節碼文件。這個示例也展示了復合的直接命令 - 即在一個單獨的包中的兩個或更多直接命令。這里我們加載字節碼鏡像:“…/prjs/BrkProg_SAVE/Demo.rpf”*** 進 slot 1 - 用戶 slot。后面緊接著是啟動slot 1 中的程序的命令。記住這是一個組合命令,且不能交錯。備注: 文件擴展名是 “rpf” 而不是* “rbf”。文件是內建的 “on-brick program file”。
向 brick 發送的字節:
opFILE,LC0(LOAD_IMAGE),LC2(USER_SLOT),LCS,’.’,’.’,’/’,‘p’,‘r’,‘j’,‘s’,’/’,
‘B’,‘r’,‘k’,‘P’,‘r’,‘o’,‘g’,
’_’,‘S’,‘A’,‘V’,‘E’/’,‘D’,‘e’,‘m’,‘o’,’.’,‘r’,‘p’,‘f’,0,GV0(0),GV0(4),opPROGRAM_START,
LC0(USER_SLOT),GV0(0),GV0(4),LC0(0)
| opFILE | 文件有關的操作碼 |
| LC0(LOAD_IMAGE) | 命令被編碼為單字節常數 |
| LC2(USER_SLOT) | 用戶 slot(1 = 程序 slot)被編碼為單個常量字節 |
| LCS | 編碼:后面是字符串(以 0 結尾) |
| “…/prjs/BrkProg_SAVE/Demo.rpf” | 文件路徑和名稱。“…” 是 “從當前目錄移到上一級目錄” |
| 0x00 | 上面的字符串的結尾 0 |
| GV0(0) | 在全局變量偏移 0 處返回鏡像大小。偏移量被編碼為單個字節。 |
| GV0(4) | 在全局變量偏移 4 處返回鏡像地址。偏移量被編碼為單個字節。 |
| opPROGRAM_START | 操作碼 |
| LC0(USER_SLOT) | 用戶 slot(1 = 程序 slot)被編碼為單個字節常量 |
| GV0(0) | 鏡像大小位于全局變量偏移 0 處。 |
| GV0(4) | 鏡像地址位于全局變量偏移 4 處。 |
| LC0(0) | 調試模式(0 = 普通)被編碼為單個字節常量 |
30000000800800C008820100842E2E2F70726A732F42726B50726F675F534156452F44656D6F2E7270660060640301606400
bbbbmmmmtthhhhccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccCCCCCCCCCC
bbbb = 消息中的字節數為 48,不包含包長度字節
mmmm = 消息計數器
tt = 命令類型 - 直接命令無需應答
hhhh = 頭部 – 變量分配。
cc/CC = 字節碼
hhhh = 10 個最低有效位是全局變量的個數,6 個最高有效位是局部變量的
4.2.2 以電源 50 向前啟動電動機 B&C 3 轉,并在目的地制動
這個例子使用了特殊的 OUTPUT_STEP_SPEED 電動機命令。這個命令在電動機列表中為電動機設置了速度((setpoint))。命令包含加速和減速部分。特別是減速對于更精確地到達最終目的地非常有用。電動機在 3 轉(3 * 360 度)結束后制動。
opOUTPUT_STEP_SPEED,LC0(LAYER_0),LC0(MOTOR_A + MOTOR_B),LC1(SPEED_50),LC0(0),LC2(900),LC2(180),LC0(BRAKE)
| opOUTPUT_STEP_SPEED | 操作碼 |
| LC0(0) | Layer 0 - 被編碼為單個字節常量 |
| LC0(MOTOR_A + MOTOR_B) | 電動機 B & C (電動機列表)被編碼為單個字節常量 |
| LC1(SPEED_50) | 速度 50% 被編碼為單個字節常量 |
| LC0(0) | 沒有 STEP1,即從開始全速 - 編碼為單個字節常量 |
| LC2(900) | 2.5 周(900 度) STEP2 - 被編碼為兩個字節 |
| LC2(180) | 0.5 周(180 度) STEP3 為了更精確的到達目的地 - 被編碼為兩個字節 |
| LC0(BRAKE) | 制動(1)- 被編碼為單個字節常量 |
向 brick 發送的字節:
1200xxxx800000AE000681320082840382B40001
Bbbbmmmmtthhhhcccccccccccccccccccccccccc
bbbb = 消息中的字節數為 21,不包含包長度字節
mmmm = 消息計數器
tt = 命令類型 - 直接命令無需應答
hhhh = 頭部 – 變量分配。
cc/CC = 字節碼
hhhh = 10 個最低有效位是全局變量的個數,6 個最高有效位是局部變量的
4.2.3 讀取傳感器端口 3 上的光傳感器值
這個直接命令將讀取連接在 brick 的輸入端口 3 上的光傳感器。模式被顯式地設為模式 0(零)即光傳感器(0 – 100 pct.)的本地模式 0。返回值是一個32 位 float,編碼為 SI 0-100 pct。
默認的 32 位浮點數(SI 0-100 pct)。
opINPUT_DEVICE,LC0(READY_SI),LC0(LAYER_0),LC0(SENSOR_PORT_3),LC0(DO_NOT_CHANGE_TYPE),LC0(MODE_0),LC0(ONE_DATA_SET),LCO(GLOBAL_VAR_INDEX0)
| opINPUT_DEVICE | 輸入相關的操作碼 |
| LC0(READY_SI) | 命令(READY_SI)被編碼為單個字節常量 |
| LC0(LAYER_0) | Layer number (0 = 這個特定 brick) 被編碼為單個字節常量 |
| LC0(SENSOR_PORT_3) | 連接到端口 3 ((1-4 / 0-3 內部的)上的傳感器被編碼為單個字節常量 |
| LC0(DO_NOT_CHANGE_TYPE) | 如果設置為 0 (零) - 不改變類型 - 被編碼為單個字節常量 |
| LC0(MODE_0) | 模式 0 - 被編碼為單個字節常量 |
| LC0(ONE_DATA _SET) | 數據集的個數(模式 0 只有 1 個(pct))- 被編碼為單個字節常量 |
| LC0(GLOBAL_VAR_INDEX0) | 把返回值放在全局變量的索引 0 (零)處 - 被編碼為單個字節常量 |
向 brick 發送的字節:
0D00xxxx000400991D000200000160
BbbbmmmmtthhhhCCCCCCCCCCCCCCCC
bbbb = 消息中的字節數為 13,不包含包長度字節
mmmm = 消息計數器
tt = 命令類型 - 直接命令需要應答
hhhh = 頭部 – 變量分配。這 4 個字節在全局變量中保留
CC/cc/CC/cc = 字節碼
hhhh = 10 個最低有效位是全局變量的個數,6 個最高有效位是局部變量的
4.2.4 讀取連接到端口 1 的光傳感器為 COLOR
這個直接命令將讀取連接在 brick 的輸入端口 1 上的光傳感器。模式被顯式地設為模式 2 “COLOR 模式”。傳感器將返回一個 0 - 8(包含)之間的值,即傳感器前的物體的顏色。返回值是 32 位浮點數,編碼為 0-8。
opINPUT_DEVICE,LC0(READY_SI),LC0(LAYER_0),LC0(SENSOR_PORT_1),LC0(DO_NOT_CHANGE_TYPE),LC0(MODE_2),LC0(ONE_DATA_SET),LCO(GLOBAL_VAR_INDEX0)
| opINPUT_DEVICE | 輸入相關的操作碼 |
| LC0(READY_SI) | 命令(READY_SI)被編碼為單個字節常量 |
| LC0(LAYER_0) | Layer number (0 = 這個特定 brick) 被編碼為單個字節常量 |
| LC0(SENSOR_PORT_1) | 連接到端口 1 ((1-4 / 0-3 內部的)上的傳感器被編碼為單個字節常量 |
| LC0(DO_NOT_CHANGE_TYPE) | 如果設置為 0 (零) - 不改變類型 - 被編碼為單個字節常量 |
| LC0(MODE_2) | 模式 2 - 被編碼為單個字節常量 |
| LC0(ONE_DATA _SET) | 數據集的個數(模式 0 只有 1 個(pct))- 被編碼為單個字節常量 |
| LC0(GLOBAL_VAR_INDEX0) | 把返回值放在全局變量的索引 0 (零)處 - 被編碼為單個字節常量 |
向 brick 發送的字節:
0D00xxxx000400991D000000020160
BbbbmmmmtthhhhCCCCCCCCCCCCCCCC
bbbb = 消息中的字節數為 13,不包含包長度字節
mmmm = 消息計數器
tt = 命令類型 - 直接命令需要應答
hhhh = 頭部 – 變量分配。這 1 個字節在全局變量中保留
CC/cc/CC/cc = 字節碼
hhhh = 10 個最低有效位是全局變量的個數,6 個最高有效位是局部變量的
4.2.5 在 level 2 播放 1 Kz 音調 1 秒
opSOUND,LC0(TONE),LC1(2),LC2(1000),LC2(1000)
| opSOUND | 聲音相關的操作碼 |
| LC0(TONE) | 命令(TONE)被編碼為單個字節常量 |
| LC1(2) | 聲音 leve2 被編碼為 1 個常量字節 |
| LC2(1000) | 頻率 1000 Hz 被編碼為 2 個常量字節 |
| LC2(1000) | 持續時長 1000 ms 被編碼為 2 個常量字節 |
向 brick 發送的字節:
0F00xxxx8000009401810282E80382E803
Bbbbmmmmtthhhhcccccccccccccccccccc
bbbb = 消息中的字節數為 15,不包含包長度字節
mmmm = 消息計數器
tt = 命令類型 - 直接命令無需應答
hhhh = 頭部 – 變量分配。
cc/CC = 字節碼
hhhh = 10 個最低有效位是全局變量的個數,6 個最高有效位是局部變量的
4.2.6 在屏幕上展示一幅圖片
清除屏幕,并在屏幕上的坐標 (x = 0, y= 50) 處繪制 bmp 圖片 “mindstorms.rgf”。首先屏幕由 FILLWINDOW 子命令清除,然后 bmp 圖片文件由子命令 BMPFILE 加載。在 UPDATE 子命令發出之前屏幕上什么都不會發送。
opUI_DRAW,LC0(FILLWINDOW),LC0(BG_COLOR),LC2(0),LC2(0),opUI_DRAW,LC0(BMPFILE),LCO(FG_COLOR),LC2(0),LC2(50),LCS,‘u’,‘i’,’/’,‘m’,‘i’,‘n’,‘d’, ‘s’,‘t’,‘o’,‘r’,‘m’,‘s’,’.’,‘r’,‘g’,‘f’,0,opUI_DRAW,LC0(UPDATE)
| opUI_DRAW | 繪制相關的操作碼 |
| LC0(FILLWINDOW) | 命令(FILLWINDOW)被編碼為單個字節常量 |
| LC0(BG_COLOR) | 顏色設置背景顏色 - 即清除屏幕被編碼為單個字節常量 |
| LC2(0) | 起始 y(0 表示整個屏幕)被編碼為單個字節常量 |
| LC2(0) | 結束 y(0 表示整個屏幕)被編碼為單個字節常量 |
| opUI_DRAW | 繪制相關的操作碼 |
| LC0(BMPFILE) | 命令(BMPFILE)被編碼為單個字節常量 |
| LC0(FG_COLOR) | 顏色設置前景顏色被編碼為單個字節常量 |
| LC2(50) | 起始 y 坐標 50 被編碼為 2 個字節 |
| LC2(0) | 起始 x 坐標 0 被編碼為 2 個字節 |
| LCS | 編碼:字符串(以 0 結尾) |
| “ui/mindstorms.rgf” | 文件路徑和名稱 |
| 0 | 字符串的 0 結尾 |
| opUI_DRAW | 繪制相關的操作碼 |
| LC0(UPDATE) | 命令(UPDATE)“執行所有的圖形操作” 被編碼為單個字節常量 |
向 brick 發送的字節:
2C000000800000841300820000820000841C018200008232008475692F6D696E6473746F726D732E726766008400
BbbbmmmmtthhhhCCCCCCCCCCCCCCCCCCccccccccccccccccccccccccccccccccccccccccccccccccccccccccCCCC
bbbb = 消息中的字節數為 44,不包含包長度字節
mmmm = 消息計數器
tt = 命令類型 - 直接命令無需應答
hhhh = 頭部 – 變量分配。
CC/cc/CC/cc = 字節碼
hhhh = 10 個最低有效位是全局變量的個數,6 個最高有效位是局部變量的
原文
總結
以上是生活随笔為你收集整理的LEGO EV3 通信开发者套件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 搭建 LEGO EV3 的 PyChar
- 下一篇: LEGO EV3 中执行 VSCode