想學嵌入式?要不一起玩 Arduino 吧

削微寒發表於2022-06-17

作者:HelloGitHub-Anthony

這裡是 HelloGitHub 推出的《講解開源專案》系列,本期介紹的是如何用開源硬體開發平臺 Arduino,自己動手做一個溫溼度顯示器。

書接上回,上一章我們知曉了什麼是 Arduino、能用它來做什麼,以及 Hello World 的實現,內容十分簡單和容易上手。沒看過的小夥伴可以點選閱讀,從而做到無縫連線本章的內容。

接下來,我們將更進一步學習 Arduino 的知識,為避免枯燥的文字教程,本文將結合實際的開發進行講解。首先會介紹 溫溼度感測器OLED 螢幕 的開發,接著將這兩部分的知識進行組合,最後你將得到一個有意思的溫溼度顯示器。

不要擔心,本文所有內容均已脫“難”,只要跟著文章一步步進行下去,肯定就能做出來!

下面,就讓我們一起開始製作你的第一個 Arduino 成品吧!

一、溫溼度感測器

本節我們會用到名為 DHT 11 的溫溼度感測器,DHT 11 是一款常用的溫溼度數字感測器,它雖然精度不是很高但價格低廉,只用到三根線 VCC、GND、DATA 即可工作(簡單),是我們學習使用感測器的不二之選!

這裡我使用的是進行過二次封裝的 DHT 11 感測器,它長這個樣子:

1.1 連線感測器

根據購買的店鋪不同,最終實物可能會有所不同。如果你無法分辨每個引腳具體含義,一定要先諮詢賣家再進行接線,防止燒壞感測器

我這裡的三個引腳從左到右依次為 DATA、VCC、GND,連線方式為:

  • GND -- GND
  • VCC -- 5V
  • DATA -- Digital 8

1.2 讀取資料

讀取 DHT 11 感測器的資料方式也非常簡單,我們可以根據 資料手冊4、序列介面 一節提供的資訊自行編寫資料解析的程式。

但我認為這已經超出了初學者的能力範圍而且實現起來也會花不少功夫,所以這時候我們就需要 Arduino 的 Libraries 功能上場了

Arduino 官方提供了一個 Library 平臺,收集了很多開發者提供的開源支援庫,靈活使用這些庫進行開發,可以節省我們大量的時間以及頭髮。

下面將介紹如何使用 Arduino IDE 的 Libraries 功能。

1.3 DHT 11 支援庫

在這裡我們選擇 Adafruit 提供的 DHT sensor library 支援庫,它還依賴 Adafruit Unified Sensor 庫,下面我們詳細操作:

安裝

點選左側 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 使用例程。

這裡我們只需要根據實際情況修改開頭幾行配置,就能直接編譯到開發板上進行測試啦!

上傳到開發板後開啟我們的 Serial Monitor 即可看到 Arduino 正在回傳溫溼度資訊:

1.4 感測器小結

本節我們簡單學習了如何安裝 Arduino 的支援庫如何檢視支援庫提供的例程,以及 DHT11 庫的使用方法。

下一節,我們將學習如何使用 LCD 螢幕顯示內容

二、OLED 螢幕

本節我們會用到名為 SH1106 的 1.3寸 OLED 螢幕,我用的是 SH1106 使用 I2C 方式進行操作,只用到四根線 VCC、GND、SDA、SCL 解析度為 128x64 ,它長這個樣子:

1.1 接線

使用時接線為:

  • GND -- GND
  • VCC -- 5V
  • SDA -- A4
  • SCL -- A5

根據使用方式和螢幕不同,實際接線可能會有出入。如果不懂可以搜尋關鍵詞:“Arudino+螢幕型號+通訊方式”(I2C 或 SPI)

對於螢幕如果直接進行操作使用起來非常複雜,但好在開源社群為其提供了強大的支援庫。

1.2 開源庫 U8g2

U8g2 是一個單色螢幕的開源庫,支援市面上絕大多數單色螢幕,能非常方便地從庫管理器進行安裝。

安裝

上一節的支援庫安裝方式相同,在 Libraries 頁面進行搜尋後安裝即可。

但由於其體積較大或是網路問題,可能會存在下載緩慢或者失敗等問題。如果一直無法安裝成功,可以手動下載官方版本進行安裝

使用

U8g2 同樣提供了豐富的例程供我們學習,開啟 examples 資料夾可以看到如下結構:

需要注意的是 U8g2 提供了兩個版本:U8g2 本身(例程中 full_bufferpage_buffer)和 u8x8(例程中 u8x8)。前者支援完整繪圖功能,但是速度一般且需要額外的記憶體支援,後者只支援顯示字型檔中圖形但是速度快不需要額外的記憶體。

full_bufferpage_buffer 的區別在於:

  • full_buffer:會在記憶體中維護全部的圖形快取會佔用大量記憶體。渲染速度快,但在 UNO 上只有部分例程能夠成功執行。
  • page_buffer:一次只維護一小部分快取並分批次進行更新。渲染速度稍慢,在 UNO 上全部例程都可成功執行。

大家可以自行執行例程中的程式碼,進行一個粗略的瞭解。

每段指令碼只需要解除相應螢幕的註釋就能執行,比如我用的 SH1106 128x64 使用 I2C 通訊,用到的程式碼片段如下:

具體規範只要有螢幕型號、解析度、連線方式(I2C 還是 SPI)就能輕鬆找到

除此之外還有詳細的官方文件。包括函式說明螢幕類列表 等等

三、溫溼度顯示器

前面我們已經瞭解瞭如何分別使用溫溼度感測器OLED 螢幕,現在我們只需將它們組合起來。

下面就變得非常非常簡單了,我們只需要將感測器資料搬運到螢幕上顯示即可。

完整的程式碼如下:

#include <Arduino.h>
#include <U8g2lib.h>
#include "DHT.h"

// DHT11 DATA 引腳連線的數字引腳編號
#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;
}

最終效果如下:

結語

如果你跟著本文一步步走下來,到這裡應該已經收穫了自己第一個 Arduino 成品,恭喜你!

其實,本文更側重的是“授人以漁”!畢竟再好的教程也做不到面面俱到,解決你所有的問題,所以解決問題的方法最重要。文中對於如何上手開源庫、查閱文件、檢視程式碼示例、搜尋資料等方面做了詳盡步驟的講解。相信有了這些知識,你可以開啟新的世界,而不是僅限於本文所講的例子。

下面你就可以發揮想象力,結合所學到的知識和方法,自己動手做出好玩的電子產品啦!如果你做出了好玩的東西可以發給我,如果作品夠多的話我可以做一期 Arduino 作品秀!把你做的讓人眼前一亮的作品,讓更多的人發現和喜歡。

本期的內容就是這些,這裡是 HelloGitHub 分享 GitHub 上有趣、入門級的開源專案。

感謝您的閱讀!您的每個點贊、留言、分享,都是對我們最大的鼓勵~我們下期再見!

相關文章