作者:HelloGitHub-Anthony
這里是 HelloGitHub 推出的《講解開源項目》系列,本期介紹的是如何用開源硬件開發(fā)平臺 Arduino,自己動手做一個溫濕度顯示器。
書接上回,上一章我們知曉了什么是 Arduino、能用它來做什么,以及 Hello World
的實現(xiàn),內(nèi)容十分簡單和容易上手。沒看過的小伙伴可以點擊閱讀,從而做到無縫連接本章的內(nèi)容。
接下來,我們將更進一步學習 Arduino 的知識,為避免枯燥的文字教程,本文將結(jié)合實際的開發(fā)進行講解。首先會介紹 溫濕度傳感器 和 OLED 屏幕 的開發(fā),接著將這兩部分的知識進行組合,最后你將得到一個有意思的溫濕度顯示器。
不要擔心,本文所有內(nèi)容均已脫“難”,只要跟著文章一步步進行下去,肯定就能做出來!
下面,就讓我們一起開始制作你的第一個 Arduino 成品吧!
一、溫濕度傳感器
本節(jié)我們會用到名為 DHT 11
的溫濕度傳感器,DHT 11
是一款常用的溫濕度數(shù)字傳感器,它雖然精度不是很高但價格低廉,只用到三根線 VCC、GND、DATA 即可工作(簡單),是我們學習使用傳感器的不二之選!
這里我使用的是進行過二次封裝的 DHT 11
傳感器,它長這個樣子:
1.1 連接傳感器
根據(jù)購買的店鋪不同,最終實物可能會有所不同。如果你無法分辨每個引腳具體含義,一定要先咨詢賣家再進行接線,防止燒壞傳感器!
我這里的三個引腳從左到右依次為 DATA、VCC、GND,連接方式為:
1.2 讀取數(shù)據(jù)
讀取 DHT 11
傳感器的數(shù)據(jù)方式也非常簡單,我們可以根據(jù) 數(shù)據(jù)手冊
中 4、串行接口
一節(jié)提供的信息自行編寫數(shù)據(jù)解析的程序。
但我認為這已經(jīng)超出了初學者的能力范圍而且實現(xiàn)起來也會花不少功夫,所以這時候我們就需要 Arduino 的 Libraries 功能上場了!
Arduino 官方提供了一個 Library
平臺,收集了很多開發(fā)者提供的開源支持庫,靈活使用這些庫進行開發(fā),可以節(jié)省我們大量的時間以及頭發(fā)。
下面將介紹如何使用 Arduino IDE 的 Libraries 功能。
1.3 DHT 11 支持庫
在這里我們選擇 Adafruit
提供的 DHT sensor library
支持庫,它還依賴 Adafruit Unified Sensor
庫,下面我們詳細操作:
安裝
點擊左側(cè) Libraries 欄目,在搜索框中輸入 DHT11
找到 DHT sensor library by Adafruit
,點擊 INSTALL
進行安裝,然后會提示我們需要安裝一些依賴項目:
這里 Arduino IDE 自動提示我們想要使用 DHT sensor library
還需要安裝 Adafruit Unified Sensor
,我們直接點擊 Install all
讓它自動安裝,成功后可以在輸出界面看到這樣的提示:
使用
安裝好之后我們找到 Arduino IDE 上方選項卡打開:File->Examples->DHT sensor library->DHTtester
即可打開 DHT sensor library
使用例程。
這里我們只需要根據(jù)實際情況修改開頭幾行配置,就能直接編譯到開發(fā)板上進行測試啦!
上傳到開發(fā)板后打開我們的 Serial Monitor
即可看到 Arduino 正在回傳溫濕度信息:
1.4 傳感器小結(jié)
本節(jié)我們簡單學習了如何安裝 Arduino 的支持庫、如何查看支持庫提供的例程,以及 DHT11
庫的使用方法。
下一節(jié),我們將學習如何使用 LCD 屏幕顯示內(nèi)容。
二、OLED 屏幕
本節(jié)我們會用到名為 SH1106
的 1.3寸 OLED 顯示屏,我用的是 SH1106
使用 I2C
方式進行操作,只用到四根線 VCC、GND、SDA、SCL 分辨率為 128x64
,它長這個樣子:
1.1 接線
使用時接線為:
根據(jù)使用方式和屏幕不同,實際接線可能會有出入。如果不懂可以搜索關(guān)鍵詞:“Arudino+屏幕型號+通信方式”(I2C 或 SPI)
對于顯示屏如果直接進行操作使用起來非常復(fù)雜,但好在開源社區(qū)為其提供了強大的支持庫。
1.2 開源庫 U8g2
U8g2
是一個單色顯示屏的開源庫,支持市面上絕大多數(shù)單色顯示屏,能非常方便地從庫管理器進行安裝。
安裝
上一節(jié)的支持庫安裝方式相同,在 Libraries
頁面進行搜索后安裝即可。
但由于其體積較大或是網(wǎng)絡(luò)問題,可能會存在下載緩慢或者失敗等問題。如果一直無法安裝成功,可以手動下載官方版本進行安裝
使用
U8g2
同樣提供了豐富的例程供我們學習,打開 examples
文件夾可以看到如下結(jié)構(gòu):
需要注意的是 U8g2
提供了兩個版本:U8g2
本身(例程中 full_buffer
與 page_buffer
)和 u8x8
(例程中 u8x8
)。前者支持完整繪圖功能,但是速度一般且需要額外的內(nèi)存支持,后者只支持顯示字庫中圖形但是速度快不需要額外的內(nèi)存。
full_buffer
與 page_buffer
的區(qū)別在于:
full_buffer
:會在內(nèi)存中維護全部的圖形緩存會占用大量內(nèi)存。渲染速度快,但在 UNO 上只有部分例程能夠成功運行。page_buffer
:一次只維護一小部分緩存并分批次進行更新。渲染速度稍慢,在 UNO 上全部例程都可成功運行。
大家可以自行運行例程中的代碼,進行一個粗略的了解。
每段腳本只需要解除相應(yīng)屏幕的注釋就能運行,比如我用的 SH1106 128x64
使用 I2C 通信,用到的代碼片段如下:
具體規(guī)范只要有屏幕型號、分辨率、連接方式(I2C 還是 SPI)就能輕松找到
除此之外還有詳細的官方文檔。包括函數(shù)說明、屏幕類列表 等等
三、溫濕度顯示器
前面我們已經(jīng)了解了如何分別使用溫濕度傳感器和 OLED 屏幕,現(xiàn)在我們只需將它們組合起來。
下面就變得非常非常簡單了,我們只需要將傳感器數(shù)據(jù)搬運到屏幕上顯示即可。
完整的代碼如下:
#include <Arduino.h>
#include <U8g2lib.h>
#include 'DHT.h'
// DHT11 DATA 引腳連接的數(shù)字引腳編號
#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); # 符號需要啟動
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) // 每隔一段時間自動切換單位顯示
{
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īng)該已經(jīng)收獲了自己第一個 Arduino 成品,恭喜你!
其實,本文更側(cè)重的是“授人以漁”!畢竟再好的教程也做不到面面俱到,解決你所有的問題,所以解決問題的方法最重要。文中對于如何上手開源庫、查閱文檔、查看代碼示例、搜索資料等方面做了詳盡步驟的講解。相信有了這些知識,你可以打開新的世界,而不是僅限于本文所講的例子。
下面你就可以發(fā)揮想象力,結(jié)合所學到的知識和方法,自己動手做出好玩的電子產(chǎn)品啦!如果你做出了好玩的東西可以發(fā)給我,如果作品夠多的話我可以做一期 Arduino 作品秀!把你做的讓人眼前一亮的作品,讓更多的人發(fā)現(xiàn)和喜歡。
本期的內(nèi)容就是這些,這里是 HelloGitHub 分享 GitHub 上有趣、入門級的開源項目。