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