在上一篇文章【Maker 電子學】GPS 接收器的原理與應用—PART6 中,我們將 u-blox NEO-7M GPS 接收器模組透過 USB 接到 PC 上,用 terminal 程式直接觀察在真實環境中收到的訊號、解出來的資料,我們也說明了 $GPGSA、$GPGGA、$GPGLL、$GPRMC 等幾個最重要的定位訊息。
這一回我們要試著將 GPS 接收器透過 UART 連接到像 Arduino 這樣的小系統上,來使用 GPS 的訊號。
連接 ESP8266
我們選用 ESP8266 來當作這次實驗的主控晶片。除了 Arduino 原生的 ATmega328p 之外,ESP8266 可能是 Arduino 平台上數一數二流行的晶片,它有 Wi-Fi 的功能,又有足夠大的 flash 和 RAM,處理器的速度也夠快,可以做很多 ATmega328p 做不到或做起來很吃力的事。
不過 ESP8266 最大的缺點就是 I/O 接腳太少,雖然晶片本身提供了 17 支的 GPIO,但 GPIO 0、GPIO 2、GPIO 15 用來控制啟動狀態,使用上有一些限制,而 GPIO 6-11 則用來連接存放程式碼的 SPI flash memory,其中 GPIO 7-10 是 data bits;如果你讓 SPI flash 跑在 4-bit 模式下,這四支腳都要用到;如果你把 SPI flash 設成 1-bit 模式,就可以空出 GPIO 8-10 三支腳出來當 GPIO 使用。
ESP8266 晶片本人有兩組硬體的 UART,但嚴格來說只有一組半。UART 0 有完整的 RxD/TxD 接腳,甚至還有硬體 flow control 用的 RTS/CTS 接腳,但 UART 1 只有一支 TxD 接腳,也就是說 UART 1 只能發不能收。
UART0 的 RxD/TxD 分別在 GPIO 3 和 GPIO 1 上,而 UART 1 的 TxD 則是 GPIO 2。在很多 ESP8266 的開發板上,會把 GPIO13 和 GPIO15 標示成 UART2,這裡其實有點小小的誤會。GPIO13 和 GPIO15 其實是 UART0 的另一組可以設定的接腳,也就是說當你用了 GPIO13/15,GPIO1/GPIO3 就不能當 UART 用了。
(圖片來源:Bird 提供)
當我們在 Arduino 裡面使用 Serial.begin() 來起始 serial 物件時,使用的就是預設在 GPIO1/3 上面的 serial port。如果要用第二組接腳 GPIO13/15,只要呼叫 Serial.swap(),就可以把 UART0 的接腳換到 GPIO13/15 上,但這時 GPIO1/3 上就沒有 UART 訊號了,而一般的 ESP8266 開發板像 NodeMCU 或是 WeMos D1,都是將 UART-USB 橋接晶片接在 GPIO1/3 上,以便透過 USB 可以燒錄 firmware,因此如果將 UART0 的接腳移走,我們雖然可以在別的接腳上使用 UART,但就失去了透過 USB 來觀察 UART0 輸出的方便。
我們想要將 GPS 模組的輸出連接到 ESP8266 上,又希望可以繼續用 Serial.print() 等方便的工具來觀察 ESP8266 的工作狀態,但 UART1 又只有 TxD,無法接收 GPS 的資料。
該怎麼辦呢?
軟體 Serial 界面
Arduino 裡有一個叫做 SoftwareSerial 的函式庫,可以在任意的 GPIO 接腳上用軟體方式模擬 serial 界面。原來的這個函式庫只能給 AVR 架構的 Arduino 硬體使用,在 ESP8266 上直接使用 SoftwareSerial 會遭遇一些奇奇怪怪的問題。幸好後來有一個叫做 EspSoftwareSerial 的函式庫,是專門移植給 ESP8266/ESP32 使用的 SoftwareSerial。
我們可以將 SoftwareSerial 出來的 UART 界面拿來連接 GPS 接收器,而將原來的硬體 UART 保留給 debug 界面。
SoftwareSerial 用起來很簡單:
#include <SoftwareSerial.h> // 帶入 library 的 header file
SoftwareSerial SWSerial (rxPin, txPin); // 初始化 SoftwareSerial 物件
SoftwareSerial 物件繼承了 Serial 物件大部分的 property 跟 method,因此用起來的方法就跟 SErial 物件一樣。
我們先來寫個小程式:
#include int serialChar; SoftwareSerial SWSerial(13,15); // RxD - 13, TxD - 15 for GPS receiver void setup() { SWSerial.begin(9600); // Neo-7m module defualt UART baudrate Serial.begin(115200); // original defualt UART } void loop() { if(SWSerial.available()>0) // check if there is data to be read { serialChar = SWSerial.read(); // read 1 character from SWSerial Serial.print((char)serialChar); // put it to Serial } }
這個程式很簡單,它不斷地從 SoftwareSerial 模擬的 UART 界面上將資料讀進來,然後送到硬體的 UART 0 上。我們在程式中宣告的軟體 UART 接腳是 RxD 用 GPIO 13,TxD 用 GPIO 15。
我們以 ESP8266 的開發板 NodeMCU 爲例,用四根線將 NodeMCU 跟 Neo-7m GPS 接收器模組連接起來:
只需不到短短一分鐘...
輸入您的信箱與ID註冊即可享有一切福利!
會員福利
免費電子報
會員搶先看
主題訂閱
好文收藏