
作者:HelloGitHub-Anthony
這里是 HelloGitHub 推出的《講解開(kāi)源項(xiàng)目》系列,本期介紹的是如何用開(kāi)源硬件開(kāi)發(fā)平臺(tái) Arduino,自己動(dòng)手做一個(gè)溫濕度顯示器。
書(shū)接上回,上一章我們知曉了什么是 Arduino、能用它來(lái)做什么,以及 Hello World
的實(shí)現(xiàn),內(nèi)容十分簡(jiǎn)單和容易上手。沒(méi)看過(guò)的小伙伴可以點(diǎn)擊閱讀,從而做到無(wú)縫連接本章的內(nèi)容。
接下來(lái),我們將更進(jìn)一步學(xué)習(xí) Arduino 的知識(shí),為避免枯燥的文字教程,本文將結(jié)合實(shí)際的開(kāi)發(fā)進(jìn)行講解。首先會(huì)介紹 溫濕度傳感器 和 OLED 屏幕 的開(kāi)發(fā),接著將這兩部分的知識(shí)進(jìn)行組合,最后你將得到一個(gè)有意思的溫濕度顯示器。
不要擔(dān)心,本文所有內(nèi)容均已脫“難”,只要跟著文章一步步進(jìn)行下去,肯定就能做出來(lái)!
下面,就讓我們一起開(kāi)始制作你的第一個(gè) Arduino 成品吧!
一、溫濕度傳感器
本節(jié)我們會(huì)用到名為 DHT 11
的溫濕度傳感器,DHT 11
是一款常用的溫濕度數(shù)字傳感器,它雖然精度不是很高但價(jià)格低廉,只用到三根線 VCC、GND、DATA 即可工作(簡(jiǎn)單),是我們學(xué)習(xí)使用傳感器的不二之選!
這里我使用的是進(jìn)行過(guò)二次封裝的 DHT 11
傳感器,它長(zhǎng)這個(gè)樣子:

1.1 連接傳感器
根據(jù)購(gòu)買的店鋪不同,最終實(shí)物可能會(huì)有所不同。如果你無(wú)法分辨每個(gè)引腳具體含義,一定要先咨詢賣家再進(jìn)行接線,防止燒壞傳感器!
我這里的三個(gè)引腳從左到右依次為 DATA、VCC、GND,連接方式為:
1.2 讀取數(shù)據(jù)
讀取 DHT 11
傳感器的數(shù)據(jù)方式也非常簡(jiǎn)單,我們可以根據(jù) 數(shù)據(jù)手冊(cè)
中 4、串行接口
一節(jié)提供的信息自行編寫(xiě)數(shù)據(jù)解析的程序。
但我認(rèn)為這已經(jīng)超出了初學(xué)者的能力范圍而且實(shí)現(xiàn)起來(lái)也會(huì)花不少功夫,所以這時(shí)候我們就需要 Arduino 的 Libraries 功能上場(chǎng)了!
Arduino 官方提供了一個(gè) Library
平臺(tái),收集了很多開(kāi)發(fā)者提供的開(kāi)源支持庫(kù),靈活使用這些庫(kù)進(jìn)行開(kāi)發(fā),可以節(jié)省我們大量的時(shí)間以及頭發(fā)。
下面將介紹如何使用 Arduino IDE 的 Libraries 功能。
1.3 DHT 11 支持庫(kù)
在這里我們選擇 Adafruit
提供的 DHT sensor library
支持庫(kù),它還依賴 Adafruit Unified Sensor
庫(kù),下面我們?cè)敿?xì)操作:
安裝
點(diǎn)擊左側(cè) Libraries 欄目,在搜索框中輸入 DHT11
找到 DHT sensor library by Adafruit
,點(diǎn)擊 INSTALL
進(jìn)行安裝,然后會(huì)提示我們需要安裝一些依賴項(xiàng)目:


這里 Arduino IDE 自動(dòng)提示我們想要使用 DHT sensor library
還需要安裝 Adafruit Unified Sensor
,我們直接點(diǎn)擊 Install all
讓它自動(dòng)安裝,成功后可以在輸出界面看到這樣的提示:

使用
安裝好之后我們找到 Arduino IDE 上方選項(xiàng)卡打開(kāi):File->Examples->DHT sensor library->DHTtester
即可打開(kāi) DHT sensor library
使用例程。

這里我們只需要根據(jù)實(shí)際情況修改開(kāi)頭幾行配置,就能直接編譯到開(kāi)發(fā)板上進(jìn)行測(cè)試?yán)玻?/p>
上傳到開(kāi)發(fā)板后打開(kāi)我們的 Serial Monitor
即可看到 Arduino 正在回傳溫濕度信息:

1.4 傳感器小結(jié)
本節(jié)我們簡(jiǎn)單學(xué)習(xí)了如何安裝 Arduino 的支持庫(kù)、如何查看支持庫(kù)提供的例程,以及 DHT11
庫(kù)的使用方法。
下一節(jié),我們將學(xué)習(xí)如何使用 LCD 屏幕顯示內(nèi)容。
二、OLED 屏幕
本節(jié)我們會(huì)用到名為 SH1106
的 1.3寸 OLED 顯示屏,我用的是 SH1106
使用 I2C
方式進(jìn)行操作,只用到四根線 VCC、GND、SDA、SCL 分辨率為 128x64
,它長(zhǎng)這個(gè)樣子:

1.1 接線
使用時(shí)接線為:
根據(jù)使用方式和屏幕不同,實(shí)際接線可能會(huì)有出入。如果不懂可以搜索關(guān)鍵詞:“Arudino+屏幕型號(hào)+通信方式”(I2C 或 SPI)
對(duì)于顯示屏如果直接進(jìn)行操作使用起來(lái)非常復(fù)雜,但好在開(kāi)源社區(qū)為其提供了強(qiáng)大的支持庫(kù)。
1.2 開(kāi)源庫(kù) U8g2
U8g2
是一個(gè)單色顯示屏的開(kāi)源庫(kù),支持市面上絕大多數(shù)單色顯示屏,能非常方便地從庫(kù)管理器進(jìn)行安裝。
安裝
上一節(jié)的支持庫(kù)安裝方式相同,在 Libraries
頁(yè)面進(jìn)行搜索后安裝即可。
但由于其體積較大或是網(wǎng)絡(luò)問(wèn)題,可能會(huì)存在下載緩慢或者失敗等問(wèn)題。如果一直無(wú)法安裝成功,可以手動(dòng)下載官方版本進(jìn)行安裝
使用
U8g2
同樣提供了豐富的例程供我們學(xué)習(xí),打開(kāi) examples
文件夾可以看到如下結(jié)構(gòu):

需要注意的是 U8g2
提供了兩個(gè)版本:U8g2
本身(例程中 full_buffer
與 page_buffer
)和 u8x8
(例程中 u8x8
)。前者支持完整繪圖功能,但是速度一般且需要額外的內(nèi)存支持,后者只支持顯示字庫(kù)中圖形但是速度快不需要額外的內(nèi)存。
full_buffer
與 page_buffer
的區(qū)別在于:
full_buffer
:會(huì)在內(nèi)存中維護(hù)全部的圖形緩存會(huì)占用大量?jī)?nèi)存。渲染速度快,但在 UNO 上只有部分例程能夠成功運(yùn)行。page_buffer
:一次只維護(hù)一小部分緩存并分批次進(jìn)行更新。渲染速度稍慢,在 UNO 上全部例程都可成功運(yùn)行。
大家可以自行運(yùn)行例程中的代碼,進(jìn)行一個(gè)粗略的了解。
每段腳本只需要解除相應(yīng)屏幕的注釋就能運(yùn)行,比如我用的 SH1106 128x64
使用 I2C 通信,用到的代碼片段如下:

具體規(guī)范只要有屏幕型號(hào)、分辨率、連接方式(I2C 還是 SPI)就能輕松找到
除此之外還有詳細(xì)的官方文檔。包括函數(shù)說(shuō)明、屏幕類列表 等等
三、溫濕度顯示器
前面我們已經(jīng)了解了如何分別使用溫濕度傳感器和 OLED 屏幕,現(xiàn)在我們只需將它們組合起來(lái)。
下面就變得非常非常簡(jiǎn)單了,我們只需要將傳感器數(shù)據(jù)搬運(yùn)到屏幕上顯示即可。
完整的代碼如下:
#include <Arduino.h>
#include <U8g2lib.h>
#include 'DHT.h'
// DHT11 DATA 引腳連接的數(shù)字引腳編號(hào)
#define DHT_DATA_PIN 8
DHT dht11(DHT_DATA_PIN, DHT11, 1);
U8G2_SH1106_128X64_NONAME_1_HW_I2C oled(U8G2_R0, U8X8_PIN_NONE);
float t, f, h;
float head_index;
const char URL[] = 'http://www.HelloGitHub.com';
int url_width = 0;
bool Fahrenheit = false;
void update_data()
{
h = dht11.readHumidity();
t = dht11.readTemperature();
f = dht11.readTemperature(true);
head_index = dht11.computeHeatIndex(t, h, false);
}
void setup()
{
t = f = h = 0;
dht11.begin();
oled.begin();
oled.enableUTF8Print();
oled.setFontMode(0);
url_width = oled.getUTF8Width(URL); # 符號(hào)需要啟動(dòng)
update_data();
}
void loop()
{
static int url_x_pos = -url_width;
oled.firstPage();
do
{
if (millis() % 200 == 0) // 每 200ms 更新一次
update_data();
oled.setFont(u8g2_font_t0_11_mr);
oled.drawBox(0, 0, 128, 17);
oled.setDrawColor(0);
oled.setCursor(url_x_pos, 14);
oled.print(URL);
oled.setDrawColor(1);
oled.setCursor(0, 32);
oled.setFont(u8g2_font_7x13_mf);
oled.print('Temp: ');
if (Fahrenheit) // 每隔一段時(shí)間自動(dòng)切換單位顯示
{
oled.print(f);
oled.print('°F');
}
else
{
oled.print(t);
oled.print('°C');
}
oled.setCursor(0, 47);
oled.print('Humi: ');
oled.print(h);
oled.print(' %');
oled.setCursor(0, 62);
oled.print('HeadIndex: ');
oled.print(head_index);
oled.print('°C');
} while (oled.nextPage());
Fahrenheit = (millis() % 4000 == 0) ? (!Fahrenheit) : Fahrenheit; // 每 4s 更換一次單位
url_x_pos += 3;
if (url_x_pos > 128)
url_x_pos = -url_width;
}
最終效果如下:

結(jié)語(yǔ)
如果你跟著本文一步步走下來(lái),到這里應(yīng)該已經(jīng)收獲了自己第一個(gè) Arduino 成品,恭喜你!
其實(shí),本文更側(cè)重的是“授人以漁”!畢竟再好的教程也做不到面面俱到,解決你所有的問(wèn)題,所以解決問(wèn)題的方法最重要。文中對(duì)于如何上手開(kāi)源庫(kù)、查閱文檔、查看代碼示例、搜索資料等方面做了詳盡步驟的講解。相信有了這些知識(shí),你可以打開(kāi)新的世界,而不是僅限于本文所講的例子。
下面你就可以發(fā)揮想象力,結(jié)合所學(xué)到的知識(shí)和方法,自己動(dòng)手做出好玩的電子產(chǎn)品啦!如果你做出了好玩的東西可以發(fā)給我,如果作品夠多的話我可以做一期 Arduino 作品秀!把你做的讓人眼前一亮的作品,讓更多的人發(fā)現(xiàn)和喜歡。
本期的內(nèi)容就是這些,這里是 HelloGitHub 分享 GitHub 上有趣、入門級(jí)的開(kāi)源項(xiàng)目。