Pixel:Bit 教學(二) – ESP32 與 ATmega328P 的 UART 通訊

五、程式撰寫

1. 螢幕顯示訊息

學會顯示訊息是相當重要的功能,可以讓我們不外加其他裝置的情況下,經由螢幕將訊息顯示出來,可用來確認程式是否正確,是個除錯的好工具。

讓我們來看一下顯示訊息是怎麼運作的,請開啟「06.Uart Communication」資料夾,打開範例程式名稱為「01.LCD_Show_ESP32」,進到資料夾對裡面的程式檔案點兩下即可開啟。

Pixel:Bit 教學(二) - ESP32 與 ATmega328P 的 UART 通訊

完整程式碼如下圖所示:

Pixel:Bit 教學(二) - ESP32 與 ATmega328P 的 UART 通訊

在使用 LCD 螢幕之前需要匯入相關程式庫,並賦予物件功能,被賦予的物件名稱為「tft」,之後調用顯示功能可直接以 tft 代稱。

Pixel:Bit 教學(二) - ESP32 與 ATmega328P 的 UART 通訊

接著在 setup 區塊,我們初始化顯示螢幕,並旋轉螢幕方向以符合 Pixel:Bit 的配置,最後將螢幕顯示黑色(有點類似清空所有訊息的感覺)。

Pixel:Bit 教學(二) - ESP32 與 ATmega328P 的 UART 通訊

預設的顏色總共有 24 種,如下表所示:

Pixel:Bit 教學(二) - ESP32 與 ATmega328P 的 UART 通訊

顯示文字有幾個步驟,第一是決定位置與字型,螢幕像素大小為 240 x 240,您可以在這個範圍內決定從哪個位置開始顯示文字,程式「setCursor(0, 0, 2)」括弧內的頭兩個數字表示 x, y 座標,最後一個則是字型,共有 6 種字型(1, 2, 4, 6, 7, 8),以填入數字的方式選擇字型,每個字型支援的最大尺寸也不同。

第二步驟是決定文字顏色與背景顏色,程式「setTextColor(TFT_ORANGE, TFT_BLACK)」括弧內的第一個顏色是指文字顏色,另一個是背景顏色。

Pixel:Bit 教學(二) - ESP32 與 ATmega328P 的 UART 通訊

接著是文字大小,共有 7 種尺寸,填入數字越大,文字尺寸越大。最後則是使用程式「println(“填入要顯示的文字”)」顯示一行文字。

上圖程式是顯示一行字型為 2 大小為 2,顏色為橘色的文字,文字內容是「Hello pixel:bit.」。

2. 上傳程式到 ESP32 的方法

知道程式所要完成的功能後,我們將程式上傳到 Pixel:Bit,看一下螢幕顯示的效果。因為負責處理螢幕顯示的是 ESP32,所以首先將 Pixel:Bit 上面的 UART 切換開關,切至「ESP」模式。

Pixel:Bit 教學(二) - ESP32 與 ATmega328P 的 UART 通訊

接下來連接 Micro USB 數據線至 Pixel:Bit 與電腦,並於「工具」>「開發板」的欄位選擇「AI Thinker ESP32-CAM」這塊開發板,並選擇正確的「序列埠」,序列埠的編號會依照您自己的電腦設定而與下圖有所不同。

Pixel:Bit 教學(二) - ESP32 與 ATmega328P 的 UART 通訊

設定完成後,請按下燒錄按鈕將程式燒錄到 Pixel:Bit。燒錄過程會需要一段時間,完成後會在訊息欄內收到提示。

Pixel:Bit 教學(二) - ESP32 與 ATmega328P 的 UART 通訊

燒錄完成,即可在 Pixel:Bit 上看到剛剛撰寫的文字。

Pixel:Bit 教學(二) - ESP32 與 ATmega328P 的 UART 通訊

3. 撰寫 UART 通訊程式

接下來讓我們學習如何在 ESP32 與 ATmega328P 裡,撰寫能相互通訊的程式。

這個功能非常方便,例如我們可以讓 ATmega328P 連接感測器,並讀取環境資料,ESP32 負責顯示資訊與上傳資料到雲端。或是 ESP32 將效能全力用在影像辨識,而控制夾爪的工作就交給 ATmega328P,解決了單一控制器會遇到的多工問題。

我們以 ATmega328P 為發送訊息者,ESP32 為接收者,並負責將收到的訊息顯示在螢幕上。先來看 ESP32 這邊的程式碼,請開啟「02.UART_Read_and_Show_ESP32」。

Pixel:Bit 教學(二) - ESP32 與 ATmega328P 的 UART 通訊

完整程式碼如下圖所示:

Pixel:Bit 教學(二) - ESP32 與 ATmega328P 的 UART 通訊

與上個程式一樣匯入程式庫並賦予物件,在這裡新增一個字串類型的變數「inputString」並賦予值為"",這個變數會用來儲存從 ATmega328P 接收到的訊息。

Pixel:Bit 教學(二) - ESP32 與 ATmega328P 的 UART 通訊

在 setup 的區塊,我們啟用 UART 功能 Serial,並賦予傳輸速率為「57600」,接著初始化顯示螢幕並顯示黑色。

Pixel:Bit 教學(二) - ESP32 與 ATmega328P 的 UART 通訊

在 loop 的區塊,我們透過「Serial.available()」這個程式檢查 Serial 連線時,是否有訊息傳送過來。並新增一個字元類型的變數「inChar」來接收訊息,再使用變數「inputString」將一個個訊息組合起來。

每次接收一個訊息後都會檢查變數「inChar」,查看接收到的訊息是否等於換行訊息「’\n’」。若是收到換行訊息,表示資料傳輸完成,我們就能透過上個程式學到的顯示文字,將收到的訊息顯示到螢幕上。

Pixel:Bit 教學(二) - ESP32 與 ATmega328P 的 UART 通訊

ESP32 接收與顯示的程式就如上圖所示,現在將這個程式燒錄到 ESP32 裡。

4. ATmega328P 發送訊息的程式

接下來讓我們來看 ATmega328P 發送訊息的程式,請開啟第三個程式「03.UART_Send_ATmega328p」。

Pixel:Bit 教學(二) - ESP32 與 ATmega328P 的 UART 通訊

完整程式碼如下圖所示:

Pixel:Bit 教學(二) - ESP32 與 ATmega328P 的 UART 通訊

作為訊息發送者的 ATmega328P,程式較為簡單,只要單純的發送即可。

首先新增一個整數類型的變數「text」,並設定初始值為 1。並於 setup 區塊同樣啟用 UART 功能 Serial,並賦予傳輸速率同樣為「57600」。兩塊控制器速率需要相同,這樣才能正常收發訊息。

Pixel:Bit 教學(二) - ESP32 與 ATmega328P 的 UART 通訊

在 loop 區塊,我們透過「Serial.println」這個程式發送一行訊息,訊息內容為變數 text 儲存的數字。發送完後將變數 text 儲存的數字累加 1,接著檢查數字是否超過 100,如果超過會將 text 儲存的數字強制更改成 1。

Pixel:Bit 教學(二) - ESP32 與 ATmega328P 的 UART 通訊

經由暫停毫秒程式「delay(1000)」,會讓程式以每隔 1 秒的時間發送訊息,訊息內容為 1~100。

5. 上傳程式到 ATmega328P 的方法

首先將 Pixel:Bit 上面的 UART 切換開關,切至「PRO MINI」模式。

Pixel:Bit 教學(二) - ESP32 與 ATmega328P 的 UART 通訊

於「工具」>「開發板」的欄位選擇「Arduino Pro or Pro Mini」這塊開發板,並於處理器選項選擇「ATmega328P(3.3V, 8 MHz)」。一樣選擇正確的「序列埠」,序列埠的編號會依照您自己的電腦設定而與下圖有所不同。

Pixel:Bit 教學(二) - ESP32 與 ATmega328P 的 UART 通訊

最後按下燒錄按鈕,將程式燒錄到 ATmega328P。

Pixel:Bit 教學(二) - ESP32 與 ATmega328P 的 UART 通訊

6. 切換互連模式

當兩邊的程式都燒錄完成後,就能將 UART 模式切換開關切至互連模式「GO」,這個模式會讓 ESP32 與 ATmega328P 連接在一起。

Pixel:Bit 教學(二) - ESP32 與 ATmega328P 的 UART 通訊

切換過去後重新拔插 Micro USB,此時 ATmega328P 就會開始發送資料,ESP32 接收到資料後就會顯示在螢幕上。

Pixel:Bit 教學(二) - ESP32 與 ATmega328P 的 UART 通訊

六、進階程式撰寫

經過前面的教學,相信大家對於兩顆控制器燒錄程式的方法、收發程式的方式與互連的部份,已有了些許的概念。

接下來讓我們提高一點程式難度,改發送有意義的文字,並讓接收端除了接收訊息外,增加比對文字的步驟。依照收到的訊息,顯示對應的文字顏色。

讓我們這次先從發送者開始,請先開啟第五個程式「05.UART_Send2_ATmega328p」。

Pixel:Bit 教學(二) - ESP32 與 ATmega328P 的 UART 通訊

完整程式碼如下圖所示:

Pixel:Bit 教學(二) - ESP32 與 ATmega328P 的 UART 通訊

可以看到程式碼內 loop 的區塊,以每秒的頻率發送表示顏色的文字訊息,分別是「Red」、「Green」、「Blue」與「Gray」。

小知識

「Serial.println(“Red”)」實際上發送的訊息是「Red\r\n」,而不是單純的「Red」,\r 表示的是確認鍵或輸入鍵(鍵盤上的 Enter),\n 則是換行的意思。因為 \r\n 是表示訊息的呈現方式,所以透過序列埠監控視窗或是顯示螢幕的程式將「Red\r\n」印出來時,並不會真的顯示\r\n出來,只會顯示「Red」,但不代表它們不存在。

接著讓我們來看接收端的程式,這個程式包含接收後比對,與顯示的部份,請開啟第四個程式「04.UART_Read_and_Show2_ESP32」。

Pixel:Bit 教學(二) - ESP32 與 ATmega328P 的 UART 通訊

讓我們直接來看比對與顯示的程式,比對的部分需要將「\r\n」一併做比對,雖然顯示時看不到,但確實有傳送過來,若是忽略這兩個東西,比對是會失敗的喔。

Pixel:Bit 教學(二) - ESP32 與 ATmega328P 的 UART 通訊

在顯示的地方我們依照比對到的訊息,在設定顯示文字顏色的地方一併更改對應的顏色。例如收到「Red\r\n」,文字就呈現紅色

看完了兩邊的程式,就讓我們依照之前教過的步驟,分別燒錄程式到 ESP32 與 ATmega328P 裡。

燒錄完成後請將 UART 模式開關切換至「GO」,成功的話就能看到如下方的畫面(綠色的部分錄影顯示不是很清楚)。

Pixel:Bit 教學(二) - ESP32 與 ATmega328P 的 UART 通訊

七、結論

在這個單元,我們學習了如何透過顯示螢幕顯示資訊,並且分別在兩顆控制器燒錄對應的程式,讓它們能進行通訊。在接下來的單元,我們時常會用到互連的功能,將我們要執行的任務拆分給 ESP32 與 ATmega328P。若是之後不熟悉的話,可以再回到這個單元複習。

若您有 Pixel:Bit 研習的需求,歡迎填寫表單,日後有相關課程資訊將在第一時間通知您!