使用GxEPD2庫深入了解CrowPanel ePaper顯示器的功能
介紹
在上一篇文章中,我們探討了CrowPanel ePaper顯示器的主要特性,并通過一個簡單的示例學(xué)習(xí)了如何使用Elecrow庫與Arduino一起控制5.79″面板。
這一次,我們將通過使用GxEPD2庫(用于控制ePaper屏幕的流行Arduino庫)深入了解該顯示器的功能,并將我們所學(xué)到的一切應(yīng)用于具體項目:實時比特幣價格監(jiān)視器。
GxEPD2庫
GxEPD2是GxEPD的演變,是Arduino庫的第一個版本,專門用于控制帶有SPI接口的電子紙顯示器(EPD -電子紙顯示器)。GxEPD2由Jean-Marc Zingg (ZinggJM)開發(fā),擴展了其前身的功能,并為Good Display和Waveshare等領(lǐng)先制造商的各種顯示器提供支持。
GxEPD2庫依賴于另一個廣泛使用的庫Adafruit_GFX進行操作。這個庫由Adafruit開發(fā),是Arduino生態(tài)系統(tǒng)中最受歡迎的庫之一。它提供了一組功能,用于在各種顯示器上繪制文本和幾何形狀,如LCD和OLED屏幕。
這兩個庫之間的關(guān)系可以總結(jié)如下:雖然Adafruit_GFX處理圖形原語并提供渲染圖形和文本的基本工具,但GxEPD2通過專門管理ePaper顯示器(EPD)及其SPI通信接口的控制來補充它。這樣,Adafruit_GFX管理可視化表示,GxEPD2側(cè)重于epd的操作和功能。
接下來,我將解釋如何在Arduino IDE 2中安裝GxEPD2和Adafruit_GFX庫,以便與5.79″Elecrow面板一起使用它們,以及如何利用它們的功能來顯示文本,圖形和圖像。
在本教程中,我假設(shè)您已經(jīng)安裝并配置了Arduino IDE 2,以使用5.79英寸的CrowPanel。如果沒有,我建議您閱讀我之前的文章,在那里我解釋了如何設(shè)置它。
安裝
在使用這些庫之前,您需要按照標準過程將它們安裝到Arduino IDE中。
由于GxEPD2依賴于Adafruit_GFX,您只需要直接安裝GxEPD2。在安裝過程中,IDE將檢測依賴項并提示您安裝Adafruit庫。此時,只需確認并繼續(xù)安裝即可。
該過程與安裝任何其他庫相同。單擊左側(cè)工具欄中的庫管理器或從主菜單中選擇工具→管理庫。
使用任何一種方法都會打開一個搜索框。輸入GxEPD2來搜索庫,當找到它時,單擊INSTALL按鈕。
版本:確保安裝最新版本的GxEPD2,不要將其與GxEPD混淆,后者是舊版本。
在IDE中,您應(yīng)該看到如下內(nèi)容:
圖1所示。安裝GxEPD2
單擊INSTALL后,IDE將檢測與其他庫(如Adafruit_GFX)的依賴關(guān)系,并詢問您是否也想安裝它們。單擊INSTALL ALL確認
圖2所示。GxEPD2的依賴項
幾分鐘后,IDE將下載并安裝所有必要的文件。
連接
使用GxEPD2庫的第一步是配置ePaper連接,指定將哪些微控制器引腳分配給各種控制信號。在這種情況下,我們需要定義BUSY, RST(復(fù)位),DC(數(shù)據(jù)/命令),CS(芯片選擇),SCK(串行時鐘)和MOSI(主輸出,從輸入)信號。
幸運的是,Elecrow已經(jīng)在他們的存儲庫中分享了該面板的原理圖,使得檢查和識別ESP32上連接到這些信號的引腳變得容易。
圖3所示。5.79″面板電路(片段)
我們感興趣的連接是前面圖片中用紅色標記的那些:
圖4所示。電子報連接
安裝好所有庫并準備好ePaper連接細節(jié)之后,我們就可以開始使用GxEPD提供的各種特性編寫代碼了。為了使其更具吸引力,我們將朝著一個具體的目標努力:開發(fā)一個充分利用該面板的特定應(yīng)用程序。
實時比特幣監(jiān)控
接下來,我們將探索使我們能夠控制ePaper顯示的幾個GxEPD2函數(shù)。我們的目標是建立一個實時比特幣價格監(jiān)視器。該設(shè)備將從在線服務(wù)中獲取加密貨幣的當前值并將其顯示在屏幕上。我們將包括圖像、文本和數(shù)字,以一種有吸引力和視覺組織的方式呈現(xiàn)關(guān)鍵信息。
最終的結(jié)果看起來像這樣:
圖5所示。行動中的監(jiān)視器
為了開發(fā)這個應(yīng)用程序的代碼,我們將學(xué)習(xí)如何單獨控制每個元素。我們將分解并分析每一步,所以讓我們從基礎(chǔ)開始。
顯示文本
讓我們從簡單的事情開始:在屏幕上顯示文本。這不僅可以幫助我們熟悉與文本相關(guān)的函數(shù),還可以教我們?nèi)绾握_地初始化面板和庫。
GxEPD2提供了處理文本的各種功能,例如編寫消息、選擇字體、調(diào)整顏色和定義大小。
下面是一個使用不同字體和文本大小顯示經(jīng)典“Hello, World!”消息的示例:
讓我們分解代碼來理解它是如何工作的:
在代碼的第一行中,我們發(fā)現(xiàn)了幾個#include指令。第一個集成了GxEPD2庫,特別是為單色顯示設(shè)計的版本(因此添加了BW)。下面的#include指令用于加載字體定義,稍后我們將使用這些定義在屏幕上顯示文本。
可用的字體是在Adafruit_GFX庫中定義的,位于fonts文件夾中。每種字體都使用頭文件(.h)定義。
圖6所示。字體定義
每種字體的名稱表示字體、樣式和大小。例如,前面示例中使用的字體FreeSans24pt7b可以分解為以下元素:
Free:表示該字體為自由字體,沒有許可限制。
Sans:指現(xiàn)代風(fēng)格的字體,如Arial。它也可以是Mono,一種簡單的等寬字體,或Serif,一種更具裝飾性的字體,如Times New Roman。
加粗:表示字體加粗。如果沒有指定,它也可以是斜的(斜體)或正則的。
24pt:指以點為單位的字體大小。
7b:表示使用7位值定義字體。
要選擇顯示文本的字體,必須使用setFont方法,但首先需要通過包含相應(yīng)的頭文件來加載字體定義。
繼續(xù)進行代碼分析,我們找到了幾個指定ePaper連接的常量的定義,如前所述。這些值是必需的,稍后將用于創(chuàng)建表示顯示的對象。
下一步是創(chuàng)建與顯示相關(guān)聯(lián)的對象。為此,我們使用一個名為GxEPD2_BW的模板,它接受以下參數(shù):
GxEPD2_579_GDEY0579T93:類標識符,充當此顯示模型的特定驅(qū)動程序。
GxEPD2_579_GDEY0579T93::HEIGHT:一個常量,它定義了顯示的高度,并確定將使用分頁模式還是非分頁模式(不要擔心,稍后我會解釋這意味著什么)。
5.79″CrowPanel(像其他型號一樣)沒有在GxEPD2支持的顯示器中列出,因為它是除了ePaper顯示器之外集成了幾個組件的設(shè)備。根據(jù)我的測試,所包含的顯示器的特性與Good display中的GDEY0579T93型號匹配,該型號是本示例代碼中使用的型號。
最后,為顯示對象使用構(gòu)造函數(shù)(如果愿意,您可以重命名它),再次將顯示標識符作為參數(shù)與連接引腳的詳細信息一起傳遞(使用我們前面定義的常量)。
CrowPanel的另一個獨特之處在于它包含了一個控制屏幕電源的電路,從而實現(xiàn)了高效的能源管理。
該電路的控制引腳是GPIO7,因此在嘗試訪問顯示器之前,第一步是通過將該引腳設(shè)置為HIGH來打開電源。
為了實現(xiàn)這一點,我包含了displayPowerOn函數(shù),它處理這個任務(wù):
繼續(xù)編寫代碼,我們將轉(zhuǎn)向Arduino中的設(shè)置函數(shù)。
正如您所看到的,它由對屬于顯示對象的各種方法的調(diào)用組成,這就是使用語法display.method(parameters)的原因。讓我們回顧一下每個方法的作用:
init:初始化顯示對象的幾個元素。這里,我們提供值115200,它為通過串行監(jiān)視器的診斷輸出設(shè)置波特率。您可以通過將其設(shè)置為0來禁用它,但這有助于理解庫正在做什么。
setFullWindow:表示將使用整個屏幕。也可以只使用屏幕的一部分來加速刷新過程(這稱為部分刷新,我們將在后面討論)。
fillScreen:用一種顏色填充屏幕,在本例中為白色(GxEPD_WHITE),清除之前的任何內(nèi)容。您可以使用任何支持的顏色:
黑色(GxEPD_BLACK)
白色(GxEPD_WHITE)
以90度的倍數(shù)定義屏幕的方向。
setTextColor:設(shè)置文本顏色。
setTextSize:設(shè)置文本的大小。
最后,有幾個塊使用不同的字體顯示文本:setFont指定要使用的字體或字體,setCursor將光標定位在所需的位置(原點(0,0)位于左上角),print將文本輸出到屏幕上。
實際上,上面提到的方法并不直接在屏幕上顯示任何內(nèi)容。相反,所有指令都作用于緩沖區(qū)或內(nèi)存區(qū)域,然后必須將其傳輸?shù)狡聊簧弦允蛊淇梢?。實現(xiàn)這一點的一種方法是使用display方法,稍后我們將探討另一種方法。
將緩沖區(qū)的內(nèi)容傳輸?shù)狡聊坏倪^程也稱為刷新。
下面是代碼的實際效果:
圖7所示。使用不同字體的文本
圖形
GxEPD2庫還包括繪制圖形元素(如點和線)以及幾何形狀(如矩形、圓形和三角形)(空心和填充)的方法。
在下面的示例中,我使用其中一些方法來顯示條形圖。代碼如下:
如您所見,第一部分與“Hello World!”示例非常相似。這里,我們還包括必要的庫,定義引腳,并創(chuàng)建顯示對象。設(shè)置函數(shù)開始時顯示的初始化也非常相似。
接下來,我們有繪制條形圖的部分。為此,我反復(fù)使用兩種方法來繪制直線和矩形:
drawLine(x0, y0, x1, y1, color):以指定顏色繪制從點(x0, y0)到點(x1, y1)的直線。
drawRect(x, y, w, h, color):以指定的顏色繪制一個從左上角(x, y)開始的矩形,寬度為w像素,高度為h像素。注意,矩形的原點是它的左上角,它是“向下”繪制的。
fillRect(x, y, w, h, color):類似于drawRect,但是矩形被指定的顏色填充。
圖8所示。圖形使用示例
具體來說,這個例子創(chuàng)建了一個500像素寬、200像素高的畫布,然后使用水平線和垂直線對其進行細分。左側(cè)的標簽表示不同的值。由于畫布水平分為50個部分,因此定義了一個包含50個隨機值的數(shù)組,并將其顯示為黑色條。
圖片
如果上面提到的圖形元素還不夠,而您想要顯示位圖圖像,不要擔心——gxepd2也支持這一點。此外,圖像不需要占據(jù)整個屏幕;您可以顯示任何大小的位圖,并將它們放置在任何位置。
該過程與我在前一篇文章中解釋的過程相同:首先,獲取圖像(必須是單色的),并使用image2lcd程序?qū)⑵滢D(zhuǎn)換為頭文件(.h)。然后,使用#include指令將該文件包含在代碼中,并使用drawBitmap方法將其放置在屏幕上。
drawBitmap的語法如下:
drawBitmap (x, y, bitmap, w, h, color);
地點:
x, y:位圖的起始坐標(左上角)。
bitmap:圖像的標識符(在.h文件中定義)。
w, h:位圖的寬度和高度,以像素為單位。
顏色:“前景”顏色,以區(qū)別于屏幕背景。
您需要采取的唯一預(yù)防措施是在將圖像轉(zhuǎn)換為image2lcd之前對其進行水平鏡像。
圖9所示。反映圖像
在下面的示例中,我將向您展示如何加載位圖(在本例中為比特幣符號)并將其顯示在屏幕中央。
在這個例子中,width()和height()方法的使用值得注意。這些方法返回屏幕尺寸,使計算原點坐標(bitmapX和bitmapY)以正確居中位圖變得容易。
運行上述代碼后,顯示如下圖像:
圖10所示。位圖使用實例
局部刷新
在前面的示例中,我們使用了不同的方法來顯示文本、圖形和圖像。在每種情況下,使用display()方法更新整個屏幕,該方法在屏幕上呈現(xiàn)操作的結(jié)果。此外,在所有示例中,我們都使用setFullWindow()初始化屏幕。這確保了display()重新繪制整個屏幕,執(zhí)行所謂的完全刷新。
更新整個屏幕是一個相對緩慢的過程。雖然在程序開始時執(zhí)行一次通常不會出現(xiàn)問題,但是當需要頻繁更新值時,例如使用每兩秒鐘刷新一次的溫度傳感器時,這就變得不方便了。在這種情況下,延遲是不可接受的。
幸運的是,5.79″CrowPanel支持一個稱為部分刷新的功能,它允許只更新屏幕的特定部分,而無需重新繪制所有像素。這不僅明顯更快,而且還消除了與完全刷新相關(guān)的閃爍。由于部分刷新,可以在更新更快的ePaper上顯示動態(tài)值。
并非所有的ePaper顯示器都支持部分刷新。它在單色電子紙顯示器上比在多色電子紙顯示器上更常見。
下面的視頻演示了兩種刷新技術(shù)之間的比較。它顯示計數(shù)器的值,從1到10,首先使用完全刷新,然后使用部分刷新。差異是顯著的。
在本例中,我使用GxEPD中所謂的分頁模式對方法進行了略微不同的結(jié)構(gòu)。
分頁模式是為RAM有限的微控制器(如Arduino UNO)設(shè)計的。不是在內(nèi)存中存儲整個屏幕的緩沖區(qū),而是只存儲屏幕的一小部分(例如,一半)。然后分兩個步驟執(zhí)行刷新:首先,在緩沖區(qū)中生成一半屏幕的內(nèi)容并傳輸,然后重用相同的緩沖區(qū)來準備和傳輸另一半屏幕。雖然這種方法比一次刷新整個屏幕要慢,但它顯著減少了內(nèi)存使用。
要使用分頁模式,首先需要指定緩沖區(qū)僅代表全屏的一小部分。這是在創(chuàng)建顯示對象時完成的。例如,要使用一半的屏幕,您可以將緩沖區(qū)大小設(shè)置為HEIGHT/2。
接下來,訪問屏幕的方法必須遵循這個結(jié)構(gòu):
使用firstPage方法啟動分頁周期。
將修改屏幕的方法包含在do..while循環(huán)中。
在nextPage方法返回true時重復(fù)循環(huán),這表明仍有數(shù)據(jù)有待傳輸?shù)狡聊弧?
回到這個例子,雖然我將定義緩沖區(qū)以覆蓋整個屏幕(因為這個面板上的ESP32-S3有足夠的內(nèi)存),但我將以分頁模式的風(fēng)格組織代碼:
正如您所看到的,關(guān)鍵的區(qū)別在于,在第一部分中,屏幕是用setFullWindow()初始化的,而隨后是用setPartialWindow()完成的。
setPartialWindow()方法在屏幕中定義了一個“窗口”,它將被修改和更新,而屏幕的其余部分保持不變。
這個方法的語法是:
setPartialWindow (x, y, w, h);
地點:
x, y:部分刷新窗口的起始坐標。
w, h:窗口的寬度和高度。
界面按鈕
所有CrowPanel模型都在側(cè)面包含一組按鈕以支持用戶交互。它們由兩個按鈕和一個連接到ESP32-S3的旋轉(zhuǎn)開關(guān)組成,ESP32-S3的狀態(tài)可以直接從程序中讀取。
圖11所示。用戶按鈕
連接引腳如圖所示:
圖12所示。按鈕連接
這意味著MENU連接到GPIO2, EXIT連接到GPIO1,旋轉(zhuǎn)開關(guān)為GPIO6,為GPIO4,按下旋轉(zhuǎn)開關(guān)激活GPIO5。每個輸入都有一個PULL_UP電阻,所以當它們被拉低時被激活。
把它們放在一起
我們終于到達終點了!如果你已經(jīng)走到這一步,恭喜你的耐心!
讓我們把我們所學(xué)到的一切應(yīng)用到實際應(yīng)用中:比特幣價格監(jiān)視器。該監(jiān)視器將從CoinGecko(一個具有非常簡單API的網(wǎng)站)獲取比特幣的實時價格。該API允許我們在不需要注冊或API密鑰的情況下發(fā)出GET請求。
我們將每30秒發(fā)出一個請求(重要的是不要過于頻繁地發(fā)出請求,因為站點可能會返回0的值),檢索值將使用部分刷新顯示在面板上。此外,我們將實現(xiàn)按鈕控制:按MENU將顯示美元(USD)的價格,按EXIT將顯示歐元(EUR)的價格。
請求使用的端點如下:
并以JSON格式返回值:
{“比特幣”:{“美元”:101971年,“歐元”:98173}}
為了提取不同的字段(通常稱為“解析JSON”),我們將使用ArduinoJson庫。
下面是比特幣監(jiān)視器的運行情況。
存儲庫
這個項目中使用的代碼和圖像可以在這個存儲庫中找到。其余的示例可以在另一個存儲庫中獲得。
結(jié)論
在本文中,我們通過使用GxEPD2庫探索了5.79英寸CrowPanel的高級功能,GxEPD2庫是一種廣泛采用的用于控制ePaper顯示的通用工具。從最初的設(shè)置到集成文本渲染、圖形和部分刷新等功能,我們成功構(gòu)建了一個融合了設(shè)計和功能的比特幣監(jiān)視器。
在整個過程中,我們學(xué)會了:
在Arduino IDE環(huán)境中安裝和配置基本庫,如GxEPD2和Adafruit_GFX。
使用Elecrow提供的原理圖定義ePaper面板的物理連接。
使用先進的技術(shù),如部分刷新,以優(yōu)化電子紙顯示性能,減少刷新時間,消除不必要的閃爍。
合并物理控件,如CrowPanel按鈕,以提供交互式用戶界面。
通過利用CoinGecko API來獲取美元和歐元的實時價格更新,實現(xiàn)實時比特幣監(jiān)控。
構(gòu)建此監(jiān)視器不僅展示了CrowPanel和GxEPD2庫的功能,而且還提供了開發(fā)微控制器動態(tài)應(yīng)用程序的實用方法,特別是在數(shù)據(jù)可視化方面。
雖然這個例子集中在比特幣監(jiān)視器上,但所提供的工具和概念適用于使用ePaper顯示器的廣泛項目,從環(huán)境監(jiān)視器到信息面板。使用GitHub存儲庫中的示例,您可以自定義和擴展此項目以滿足您的特定需求。
本文編譯自hackster.io