Try   HackMD

期末模組與函式庫

tags: 物聯網實境遊戲應用課程

期末戰提供資源

模組

  • KSM111_ESP8266 WiFi module
  • MF-RC522 RFID reader

函式庫

  • 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):模擬中控台運作,供測試用的 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
  • 第三戰的地圖資訊檔

第三戰相關 RFID 的寶藏內容與 server 行為

  • 當 APP 讀完地圖後,會列出所有寶藏的 serial number
  • 只要 BRCClient request 寶藏 serial number,就會視為找到
  • 按 Start Round 可以將所有寶藏設為未找到,當所有寶藏 serial number 都被找到後,Server 自動發送 MSG_ROUND_END

模組使用教學

WiFi module

  • 供電:5V/3.3V
  • 通訊:UART 配合 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
  • 接線:
    • 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
      1
    • MEGA

BRCClient

與中控台連線並能夠與所有其他連線的 BRCClient 傳遞訊息的 API。

由於 BRCClient 是 public 繼承自 KSM111_ESP8266,所以可以直接透過 BRCClient 的物件直接使用 KSM111_ESP8266 的成員函式。

這個函式庫使用 SoftwareSerial 做為與 WiFi 模組溝通的介面,注意 SoftwareSerial 做為 RX 腳位的限制,Arduino Uno 只有 pin 2, 3 可以做為 RX。

常用 API 說明

  • 使用函式庫:#include <BRCClient.h>

  • 建構子:BRCClient(int Rx, int Tx, int resetPin = -1)

    • 建立 BRCClient 物件並初始化 SoftwareSerial
    • RxSoftwareSerial 的 RX pin,與模組的 TXD pin 相接
    • TxSoftwareSerial 的 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 之間主要的通訊資料結構,所有通訊資料都會以此資料結構打包傳送。

#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

    • 發送資料格式
      • typeMSG_REGISTER
      • ID:要註冊的 ID (1 byte)
      • buffer:無
    • 中控台會紀錄該 IP 對應的 ID,之後透過中控台與其他通訊裝置只需指定 ID
    • 中控台回應
      • typeMSG_REGISTER
      • ID:剛剛註冊的 ID
      • buffer:"OK"/"FAIL"
        • "FAIL":代表 ID 重覆或無效 ID
    • 被保留的 ID
      • 0xFF:尚未有有效 ID
      • 0x01~0x0F:特殊用途
        • 0x01:BRC server
  • MSG_REQUSET_RFID:0x10,詢問 RFID SN 對應的座標

    • 發送資料格式
      • typeMSG_REQUEST_RFID
      • ID:無
      • buffer:4 bytes 的 RFID serial number
    • 中控台回應
      • typeMSG_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 停止計時
    • 發送資料格式
      • typeMSG_ROUND_COMPLETE
      • ID:無
      • buffer:無
    • 當中控台收到所有回合完成後,會發送 MSG_ROUND_END 給所有通訊裝置 (包含最後發送回合完成的裝置)
  • MSG_ROUND_START:0x20,回合開始

    • 只能由中控台發送
    • 中控台發送格式
      • typeMSG_ROUND_START
      • ID0x01
      • buffer:無
  • MSG_ROUND_END:0x21,回合結束

    • 只能由中控台發送
    • 中控台發送格式
      • typeMSG_ROUND_END
      • ID0x01
      • buffer:無
  • MSG_CUSTOM:0x70,發送自訂訊息給其他連線的裝置

    • 發送資料格式
      • typeMSG_CUSTOM
      • ID:接收訊息的裝置 ID
      • buffer:自定訊息,長度不能超過 COMM_MSG_BUF_LEN - 1
    • 發送者收到中控台回應
      • typeMSG_CUSTOM
      • ID:發送者的 ID,以區分來自其他 client 的訊息
      • buffer:"OK"/"FAIL"
        • "FAIL":代表目標 ID 不存在或已經斷線
    • 接收者會收到
      • typeMSG_CUSTOM
      • ID:發送者的 ID
      • buffer:自定訊息,長度不能超過 COMM_MSG_BUF_LEN - 1
  • MSG_CUSTOM_BROADCAST0x71,廣播自訂訊息給所有連線裝置

    • 發送資料格式
      • typeMSG_CUSTOM_BROADCAST
      • ID:無
      • buffer:自定訊息,長度不能超過 COMM_MSG_BUF_LEN - 1
    • 發送者收到中控台回應
      • typeMSG_CUSTOM
      • ID:發送者的 ID,以區分來自其他 client 的訊息
      • buffer:"OK"
    • 接收者會收到
      • typeMSG_CUSTOM
      • ID:發送者的 ID
      • buffer:自定訊息,長度不能超過 COMM_MSG_BUF_LEN - 1

KSM111_ESP8266

與 WiFi 模組溝通的基本 API,使用 AT command 操作。

常用 API 說明

  • 啟用 SoftwareSerialbool begin(long baudrate)

    • 啟用 SoftwareSerial 並測試模組有無正確啟動
    • baudrate:設定 SoftwareSerial 的 baudrate
    • 回傳:true 模組整確啟動
  • 重設與重啟模組:bool softreset()

    • 透過指令讓 WiFi 模組重啟,需等待 5 秒
    • 回傳:true 成功重啟
  • 設定預設 baudrate:bool setBaudrate(long baudrate)

    • 指定 WiFi 的預設 baudrate 並且更新 SoftwareSerial 的 baudrate
    • 注意:重啟並不會重設 baudrate
    • 由於 baudrate 更換時可能會收到一些亂碼而造成函式判斷錯誤,所以可以呼叫兩次確認有沒有設定成功
    ​​​​// 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