首頁 技術服務 智能顯示器 Smart Display RS485 進階實例

Smart Display RS485 進階實例

一、前言

前一篇關於 SmartDispaly RS485的技術文章『SmartDisplay RS485入門』已經對RS485與 Modbus協定進行初步介紹,本篇將進一步以多頁面的實例來介紹幾個常用的技巧,同時說明相關的SmartDisplay規格與技術,包括:

  • 如何利用按鈕widget進行換頁。
  • 換頁後的widget資料更新。
  • 以蜂鳴器發出不同長短的聲音。
  • Graph widget的使用方法。

二、 準備材料

  • 具備RS485介面的SmartDisplay 。此處使用的是3.5” SmartDisplay。
  • Arduino (Uno 或Mega2560)。
  • Arduino 的RS485 擴充板 (Link to DFRobot)。
  • 可變電阻。

三、 接線方式

  • 可變電阻:Vcc接5V, GND 接GND, 輸出接到 Arduino A0。
  • RS485擴充板的A接到SmartDisplay RS485+。
  • RS485擴充板的B接到SmartDisplay RS485-。

四、 範例內容

這個專案包含三個頁面,各頁面可以利用按鈕物件進行切換。各頁面的內容與功能如下:

第一頁:
右方有一個到下一頁的按鈕,下方則有一個調整螢幕亮度的Horizontal Slider。預視圖如下:

範例內容 - 第一頁

第二頁:
左邊按鈕回前一頁,右邊按鈕到下一頁,以及下方三個按鈕可以分別發出短、中、長三種不同長度的蜂鳴聲。

範例內容 - 第二頁

第三頁:
左邊按鈕回前一頁,同時以可變電阻模擬類比輸入,將結果顯示在Graph widget上:

範例內容 - 第三頁

由於本範例中使用了RS485擴充板,在開始進行編程前請透過函式庫管理員進行下載函式庫:

由於本範例中使用了RS485擴充板,在開始進行編程前請透過函式庫管理員進行下載函式庫

五、 建立頁面內容

首先以GUI Builder建立頁面內容。其中各頁面的 Text widget可以直接填入文字,就不必在程式中寫入:

建立頁面內容 - 1

詳細的 widget 內容如下表所示:

建立頁面內容 - 2

您可以根據現有材料選擇SmartDisplay型號,並使用不同widget製作不同的外觀,唯一要注意的是每一頁的 widget ID與Type必須和程式中的寫法一致,所以為了避免複雜化,建議還是根據此表的 widget ID和type 建立您的頁面內容。

接下來就要進入程式部分。

六、 範例解說

1. Include 檔

下載 ModebusMaster 函式庫後,記得要加入 #include:

範例解說 - Include 檔 - 1

另外我們也把一些 SmartDisplay 相關的常數放在 SmartDisplayModbus.h 中以方便管理,也要包含進來。

2. Widget ID與暫存器的轉換

在前一篇的介紹文章中曾說明 widget ID 的暫存器位址換算方式如下:

範例解說 - Widget ID與暫存器的轉換 - 1

但這個表格是針對早期每頁最多只有10個widgets的情況下制定。現在每一頁的 widget 已經可以增加到最多 64 個。這個表格在前10個 widget 仍然適用,但超過10個以後就必須調整到新的暫存器區塊,因此我們定義了下列巨集:

範例解說 - Widget ID與暫存器的轉換 - 2

為了方便使用,我們定義了根據 widget ID 來進行讀寫的函式,在函式中進行轉換:

範例解說 - Widget ID與暫存器的轉換 - 3Explanation - (2) Widget ID to Register Conversion - 3

3. Widget ID 與 GUI 設計

在前面使用 GUI Builder 設計頁面內容時曾提到 widget ID 必須保持一致,因此程式中定義了 widget ID常數如下:

範例解說 - Widget ID 與 GUI 設計 - 1

利用這些常數定義可以幫助我們記憶widget的類別,同時便於對照到實際的頁面設計。日後若GUI設計上有進行修改,也記得要對這些數值進行比對,以免產生錯誤。

4. 蜂鳴器

韌體實現蜂鳴器發聲方式是以計數器延遲一段時間後送出0/1訊號給蜂鳴器發出聲音,並以其他計數器來控制聲音啟動與關閉的時間。為了發出聲音,我們必須寫入四個暫存器,包括:

範例解說 - 蜂鳴器 - 1

為了調整聲音長度,我們製作一個傳入SMARTDISPLAY_BUZZER_HIGH參數的函式進行發音:

範例解說 - 蜂鳴器 - 2

SMARTDISPLAY_BUZZER_ACTIVE 必須與前一次寫入的值不一樣時才會進行發聲,所以在此函式內以 static 式存在,並且在每次呼叫前進行反向處理。

最後在頁面處理函式中就可以根據按鈕狀態發出不同長度的聲音了:

範例解說 - 蜂鳴器 - 3

5. 換頁機制

換頁前必須先進入 CONFIG_MODE。設定到新頁面後,再設為 DISPLAY_MODE。在切換頁面後,SmartDisplay會重新載入新頁面所有的 widgets。為了避免在SmartDisplay載入動作完成前進行讀寫,我們通常會增加一個延遲時間稍作等待。這個延遲長度與頁面複雜度有關,若實際操作時發現換頁後有異常現象,可以試著延長時間看看。

範例解說 - 換頁機制 - 1

換頁之後新頁面的 widgets的內容都是預設值,因此我們建立一個流程來進行換頁、記錄 widgets及回復 widgets的數值。

首先定義頁面處理的函式指標,方便我們建立頁面表格,並且為每一頁指定一個處理函式:

範例解說 - 換頁機制 - 2

並且建立頁面表格:

範例解說 - 換頁機制 - 3

常數MAX_WIDGETS_PER_PAGE 定義了每一頁要記錄數值的 widgets數量。若日後增加了widget數,記得同步更新些值。

最後在 loop() 進行處理:

範例解說 - 換頁機制 - 4

當發現目前頁面_curPage不等於下個頁面_nextPage時,就將換頁旗標 newPage 設為 true,這樣在頁面處理函式知道需要進行初始化。以 Page0 為例:

範例解說 - 換頁機制 - 5

若傳入的 init 為 true 表示剛進入頁面,我們就將 WIDGET_P0_BUTTON_NEXT 的值設為0,這是因為剛換到新頁的按鈕預設值為 0,我們希望只有在剛按下時(此時讀到的值為由0變1)才會執行特定指令(這裡為換到PAGE_1),因此要重新設定(因為先前可能已經按下變成1了)。

Slider 剛載入時的初值也是0,但是先前可能已經修改過亮度,因此要恢復成目前的亮度值 _brightness。

其他時候(init 為 false)則根據 widget 的是否有變化進行相對的處置,最後再把所有 widget的值都存起來,供下次處理時參考。

至於下一頁_nextPage的設定,是利用下列函式:

範例解說 - 換頁機制 - 6

頁面處理函式除了第一次外每次都會檢查 widgets內容。當檢查到按鈕由0變1時就呼叫此函式提出換頁需求:

範例解說 - 換頁機制 - 7

6. 繪圖物件(Graph Widget)

Graph widget可以將寫入的數值以繪圖的方式呈現。這裡使用一個可變電阻接到 A0 模擬成類比輸入,以Graphic widget顯示資料的變化。由於 Arduino 的類比輸入範圍為 0-1023,而 Graph widget 的接受範圍則為 0-100,因此要使用 map() 進行範圍調整。

Graph widget被設計成當數值改變時才會更新畫面,若想要呈現定時更新的效果,就得使用一些小技巧:定時更新檢查數值,若發現新的值與上次讀取的值相同時,就稍微加以變化(加1或減1),這樣就可以產生定時更新的動態效果。

範例解說 - 繪圖物件(Graph Widget) - 1

七、 結語

以上就是對這次範例程式的說明,希望能讓讀者有進一步的認識。此範例也可以做為日後專案的初始框架,縮短一些開發時間。完整的程式可以在下列網址下載: Modbus-MultiPageOperation on GitHub.

若對 RS485 / Modbus 比較不熟悉的話,也可以參考前一篇的說明: SmartDisplay RS485 Introduction.

回分類頁
go top
close