# 期末模組與函式庫 ###### tags: `物聯網實境遊戲應用課程` ## 期末戰提供資源 ### 模組 * KSM111_ESP8266 WiFi module * MF-RC522 RFID reader ### [函式庫](https://github.com/LanKuDot/iot_brc) * KSM111_ESP8266:與 KSM111_ESP8266 WiFi 模組直接溝通的基本 API * BRCClient:建構在 KSM111_ESP8266 之上,用來與中控台溝通的 API * RFID:與 MF-RC522 模組溝通的 API #### 將函式庫匯入 Arduino IDE 1. 找到 Arduino IDE 存放使用者專案的地方 (eg. C:/My Documents/Arduino/),進入 `libraries` 資料夾 2. 將上述三個函式庫的資料夾直接放到這個資料夾中 3. 重新開啟 Arduino IDE,檢查選單中的 library 有無剛剛放入的函式庫名稱 4. 在程式碼中使用函式庫:`#include <library_name.h>` 5. 每個函式庫都有附範例,可以在 IDE 的 Example -> Custom Libraries 中打開 * 範例可以直接修改與編譯,但 IDE 不允許範例直接存檔,必須需要另存新檔 ### App * BRC Server ([Android](https://drive.google.com/file/d/0B8l9tuYB4QokR25yTnd4U1VhTFU/view?usp=sharing)):模擬中控台運作,供測試用的 APP #### 匯入 RFID 地圖資訊檔 (v1.3 之後) * 檔名:`map.dat` * 放置路徑:[內部 或 SD卡 或 `storage/emulated/0`] `/Android/data/com.LanKuDot.iotBRC/files` * 第一次啟用會自動建立對應的資料夾,如果找不到對應資料夾可以先啟動一次 APP * 當 APP 找不到檔案時會提示檔案放置的路徑 * [已知 Bug] 然而提示的檔案路徑不一定正確,像助教的手機測試提示 `storage/emulated/0/`,但實際位置為內存,因此助教列出三個可能的檔案路徑,正確的檔案路徑會有上述路徑的資料夾 * 地圖資訊檔格式 * 一行一個地圖資訊 * `8 字元 16 進制 RFID SN (大寫)` `空格` `2 字元 x 座標` `空格` `2 字元 y 座標` `空格` `4 字元地圖類型 0xNN` * 例如:`C5B538D5 01 02 0x22` * [第三戰的地圖資訊檔](https://drive.google.com/open?id=0B8l9tuYB4QokNGZOQVNUcklQMnM) #### 第三戰相關 RFID 的寶藏內容與 server 行為 * 當 APP 讀完地圖後,會列出所有寶藏的 serial number * 只要 BRCClient request 寶藏 serial number,就會視為找到 * 按 Start Round 可以將所有寶藏設為未找到,當所有寶藏 serial number 都被找到後,Server 自動發送 `MSG_ROUND_END` ## 模組使用教學 ### WiFi module * 供電:5V/3.3V * 通訊:UART 配合 [SoftwareSerial](https://www.arduino.cc/en/Reference/SoftwareSerial) * 接線: * VCC:5V/3.3V * GND:接地 * TXD:接 SoftwareSerial 的 RX * RXD:接 SoftwareSerial 的 TX * RST:可不接,與接地短路一下可以重啟模組 (Hard reset) * 由於 WiFi 模組在收送訊息時需要較多的耗電量,所以需要獨立供電。以下提供一些隊伍的解決方案: * 電源為電池,利用 L298N 的穩壓 IC 讓 +5V 可以**當 5V 輸出**用 * L298N 使用的穩壓 IC 為 78M05,輸出電壓為 5V,最大輸出電流為 500mA (瞬間為 750 mA)。輸入輸出的壓差 (dropdown voltage) 要有 2V 以上才會有穩定的 5V 輸出 * ESP8266 發訊息時最大耗電流為 215 mA * 接法一:+5V 只供應 WiFi 模組  * 接法二:+5V 同時供應 Arduino 與 WiFi 模組  * 利用三用電表確認 Arduino 運作時的電流量,以確認接法二是否適合使用  ### RFID Reader * **供電:3.3V** * 通訊:[SPI](https://www.arduino.cc/en/Reference/SPI) * 接線: * VCC:3.3V * GND:接地 * MOSI:SPI 的 MOSI * MISO:SPI 的 MISO * SCL:SPI 的 SCK * SDA:SPI 的 SS (SPI 的 Slave Select 是 Low active) * RST:Reset and Power down pin,用來讓模組重設的 pin 腳 * 接線圖 (右鍵檢視圖片都可以看原始大小圖片) * 由於 Arduino 的 SPI 是以 master mode 運行,所以模組的 SDA (SPI 的 SS) 腳位可以自由選擇,不一定要接到 Arduino 的 SS 腳位 * 模組的 RST 腳位接線也可以自由選擇 * UNO  * MEGA  ## BRCClient 與中控台連線並能夠與所有其他連線的 BRCClient 傳遞訊息的 API。 由於 `BRCClient` 是 public 繼承自 `KSM111_ESP8266`,所以可以直接透過 `BRCClient` 的物件直接使用 `KSM111_ESP8266` 的成員函式。 這個函式庫使用 `SoftwareSerial` 做為與 WiFi 模組溝通的介面,注意 `SoftwareSerial` 做為 `RX` [腳位的限制](https://www.arduino.cc/en/Reference/SoftwareSerial),Arduino Uno 只有 pin 2, 3 可以做為 RX。 ### 常用 API 說明 * 使用函式庫:`#include <BRCClient.h>` * 建構子:`BRCClient(int Rx, int Tx, int resetPin = -1)` * 建立 `BRCClient` 物件並初始化 `SoftwareSerial` * `Rx`:`SoftwareSerial` 的 RX pin,與模組的 TXD pin 相接 * `Tx`:`SoftwareSerial` 的 TX pin,與模組的 RXD pin 相接 * `resetPin`:可不指定,與模組的 RST pin 相接 * 連線到 BRC Server:`bool beginBRCClient(const char *ssid, const char *passwd, const char *serverIP, const int port)` * 與 server 所在的 AP 連線,並連到 server 上 * 注意本函式不會開啟 `SoftwareSerial`,需要呼叫 `KSM111_ESP8266::begin()` 來啟用 * `ssid`:AP 的名稱 * `passwd`:AP 的密碼,`""` 代表為無密碼 * `serverIP`:server 的 IP * `port`:server 的 port * 回傳:`true` 成功連線到 server * 離開 BRC Server:`bool endBRCClient()` * 離開 server 並退出連線的 AP * 發訊息:`bool sendMessage(CommMsg *msg)` * 傳送訊息給 BRC Server 交由 Server 處理訊息 * 回傳:`true` 傳送成功 * 收訊息:`bool receiveMessage(CommMsg *msg)` * 從 BRC Server 收取訊息,並存放到 `msg` 中 * 回傳:`true` 有訊息傳入 ### 範例 * RegisterID:如何註冊到 Server 中 * DataReceiver:顯示從 Server 收到的 raw data * DataSender:週期性的傳遞自訂訊息給其他裝置 * RoundTimer:示範回合開始與結束的功能 ### 訊息資料結構:`CommMsg` BRCServer 與 BRCClient 之間主要的通訊資料結構,所有通訊資料都會以此資料結構打包傳送。 ```c #define COMM_MSG_BUF_LEN 30 typedef struct COMM_MESSAGE { char type; // 記錄資料類型 char ID; // 記錄發送/接收者 ID char buffer[COMM_MSG_BUF_LEN]; // 額外資料區,至少要保留 1 byte 給 null character } CommMsg; ``` * 注意收發訊息遇到 `0x00` (`\0`, null terminated character) 會視為訊息結束 #### 資料類型說明 * 資料 ID 有對應的 macro 定義在 `CommMsg.h` 中 * **MSG_REGISTER**:0x01,註冊通訊裝置的代表 ID * 發送資料格式 * `type`:`MSG_REGISTER` * `ID`:要註冊的 ID (1 byte) * `buffer`:無 * 中控台會紀錄該 IP 對應的 ID,之後透過中控台與其他通訊裝置只需指定 ID * 中控台回應 * `type`:`MSG_REGISTER` * `ID`:剛剛註冊的 ID * `buffer`:"OK"/"FAIL" * "FAIL":代表 ID 重覆或無效 ID * 被保留的 ID * `0xFF`:尚未有有效 ID * `0x01~0x0F`:特殊用途 * `0x01`:BRC server * **MSG_REQUSET_RFID**:0x10,詢問 RFID SN 對應的座標 * 發送資料格式 * `type`:`MSG_REQUEST_RFID` * `ID`:無 * `buffer`:4 bytes 的 RFID serial number * 中控台回應 * `type`:`MSG_REQUEST_RFID` * `ID`:0x01 * `buffer`:4 bytes RFID serial number + 1 byte x 座標 + 1 byte y 座標 + 1 byte 類型 * 如果收到座標為 0xFF, 0xFF 代表請求的 RFID 是無效的。而且只有發送者才會收到 0xFF, 0xFF * 地圖類型定義 * header file:`MapMsg.h` * MAP_NORMAL = 0x01 MAP_TREASURE = 0x02 MAP_PARK_1 = 0x21 MAP_PARK_2 = 0x22 MAP_PARK_3 = 0x23 MAP_PARK_4 = 0x24 MAP_INVAILD = 0xFF * App Server 對於 RFID 管理的應對見「期末戰提供資源 → APP」 * **MSG_ROUND_COMPLETE**:0x11,回傳回合完成 * 用於認為自走車完成任務後傳送,讓 Server 停止計時 * 發送資料格式 * `type`:`MSG_ROUND_COMPLETE` * `ID`:無 * `buffer`:無 * 當中控台收到所有回合完成後,會發送 `MSG_ROUND_END` 給所有通訊裝置 (包含最後發送回合完成的裝置) * **MSG_ROUND_START**:0x20,回合開始 * 只能由中控台發送 * 中控台發送格式 * `type`:`MSG_ROUND_START` * `ID`:`0x01` * `buffer`:無 * **MSG_ROUND_END**:0x21,回合結束 * 只能由中控台發送 * 中控台發送格式 * `type`:`MSG_ROUND_END` * `ID`:`0x01` * `buffer`:無 * **MSG_CUSTOM**:0x70,發送自訂訊息給其他連線的裝置 * 發送資料格式 * `type`:`MSG_CUSTOM` * `ID`:接收訊息的裝置 ID * `buffer`:自定訊息,長度不能超過 `COMM_MSG_BUF_LEN - 1` * 發送者收到中控台回應 * `type`:`MSG_CUSTOM` * `ID`:發送者的 ID,以區分來自其他 client 的訊息 * `buffer`:"OK"/"FAIL" * "FAIL":代表目標 ID 不存在或已經斷線 * 接收者會收到 * `type`:`MSG_CUSTOM` * `ID`:發送者的 ID * `buffer`:自定訊息,長度不能超過 `COMM_MSG_BUF_LEN - 1` * **MSG_CUSTOM_BROADCAST**:`0x71`,廣播自訂訊息給所有連線裝置 * 發送資料格式 * `type`:`MSG_CUSTOM_BROADCAST` * `ID`:無 * `buffer`:自定訊息,長度不能超過 `COMM_MSG_BUF_LEN - 1` * 發送者收到中控台回應 * `type`:`MSG_CUSTOM` * `ID`:發送者的 ID,以區分來自其他 client 的訊息 * `buffer`:"OK" * 接收者會收到 * `type`:`MSG_CUSTOM` * `ID`:發送者的 ID * `buffer`:自定訊息,長度不能超過 `COMM_MSG_BUF_LEN - 1` ## KSM111_ESP8266 與 WiFi 模組溝通的基本 API,使用 AT command 操作。 ### 常用 API 說明 * 啟用 `SoftwareSerial`:`bool begin(long baudrate)` * 啟用 `SoftwareSerial` 並測試模組有無正確啟動 * `baudrate`:設定 `SoftwareSerial` 的 baudrate * 回傳:`true` 模組整確啟動 * 重設與重啟模組:`bool softreset()` * 透過指令讓 WiFi 模組重啟,需等待 5 秒 * 回傳:`true` 成功重啟 * 設定預設 baudrate:`bool setBaudrate(long baudrate)` * 指定 WiFi 的預設 baudrate 並且更新 `SoftwareSerial` 的 baudrate * 注意:重啟並不會重設 baudrate * 由於 baudrate 更換時可能會收到一些亂碼而造成函式判斷錯誤,所以可以呼叫兩次確認有沒有設定成功 ```c // Change baudrate from 115200 to 9600 setBaudrate(9600); // May return false becasue of changing to new baudrate. serBaudrate(9600); // It will return true. ``` * 回傳:`true` 成功設定 ### 範例 * SetBaudrate:設定 WiFi module 的預設 baudrate ## RFID `MFRC522` 是與 MF-RC522 模組溝通的基本 API,而 `RFID` 則是以 public 繼承自 `MFRC522` ### 常用 API 說明 * 建構子:`RFID(int selectPin, int resetPowerDownPin)` * 初始化 pin 腳 * `selectPin`:與模組的 SDA pin 相接 * `resetPowerDownPin`:與模組的 RTPD pin 相接 * 初始化並啟用模組:`void begin()` * 該函式會呼叫 `pcdReset()`、`pcdInit()`、`pcdAntennaOn()` 來重設與啟用模組 * 模組天線:`void pcdAntennaOn()`, `void pcdAntennaOff()` * 啟用/關閉模組天線,要啟用才能讀取 RFID tag * 偵測有無 RFID tag:`uint8_t find_tag(uint16_t *card_type)` * `card_type`:輸出記錄 16-bit 的卡片類型資訊 * 回傳: * `STATUS_OK`:有偵測到 tag * `STATUS_TIMEOUT`:沒有偵測到 tag * `STATUS_ERROR`:tag 資訊讀取出錯 * `STATUS_COLLISION`:有多組 tag 出現 * `STATUS_PCD_NO_RESPONSE`:模組出錯 * 讀取 tag serial number:`uint8_t readTagSN(uint8_t *sn, uint8_t *snBytes)` * `sn`:存放讀取到的 serial number 的 buffer,至少 4 bytes,至多 10 bytes * `snBytes`:記錄在 `sn` 中有多少 bytes 是有效的 * 回傳:`STATUS_OK`,正確讀出 serial number ### 範例 * readTagSN:讀取 tag 的 serial number
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.