ESP32 相對於 Raspberry Pi 來說,最大的差異點之一是擁有類比輸出輸入(DAC, ADC)!可以讓我們把現實生活中的訊號(類比)與電路世界的訊號(數位)做一個橋樑。就讓我們為 如何用 ESP32 快速做溫溼度監測? 使用 DHT sensor 來達成智慧家居! 中一起做的溫濕度偵測器增加一個 80 年代的指針輸出吧!
這個專案有趣的地方在於,先透過 DHT sensor 把類比溫濕度轉換成數位後進入 ESP32 中處理,再將數值轉換成類比電壓大小輸出,並掛上負載電阻,透過指針電流計測量電流大小顯示溫濕度。因為轉換兩次可能會損失一些精准度,但卻是一個有趣的概念性專案,就讓我們一起來實作吧!
為了方便講解,以下我們以一個類比輸出來顯示濕度作為範例。
Step 1:準備硬體元件
這次製作需要準備的材料為:
- ESP32 (這邊以 NodeMCU-ESP32 為例)
- 3.3k 電阻
- 電流錶頭,最大值為 1mA
註:先前偵測溫濕度的元件就不再註明了,詳細可以參考 如何用 ESP32 快速做溫溼度監測? 使用 DHT sensor 來達成智慧家居!
Step 2:硬體線路
線路非常簡單
- 將 VIN 拉到 Vcc,方便起見我們可以直接用 USB 供電
- 以 GPIO 25 作為類比輸出 pin,拉到 3.3k 電阻的一端
- 電流計串連電阻,再拉到地
為什麼我們要選用 3.3k 電阻呢?有以下原因
- ESP32 analog output 最大電壓是 3.3V
- 我希望最大輸出電流 1mA
- 簡單計算一下 V = IR,可以得到電阻應該選用 3.3k
- 因此電流錶頭用最大值為 1mA 的規格
Step 3:如何寫 DAC 程式
首先我們學習如何使用 analog output (DAC)。
在 ESP32 arduino framework 中,使用 dacWrite()
這個函數做輸出。第一個參數給定 pin,第二個參數給定要輸出的電壓的值。其中:
- 對應的 pin 不用特別宣告他的型態,也就是說不需要透過
pinMode()
函數在setup
階段做宣告,直接使用dacWrite()
函數即可 - 給定輸出的值範圍是 0~255,可以得知他將 3.3V 分成 255 份。255 時輸出 3.3V,3.3 * 128 / 255 的話約為 1.65V
#include <Arduino.h>
#define OUTPUT_PIN 25
void setup() {}
void loop() {
int value = 128;
dacWrite(OUTPUT_PIN, value);
}
拿一片尚未接線的 ESP32 跑起來後可以用三用電錶點一下看看是不是 1.65V 左右,如果是表示成功!
Step 4:開始寫程式
我們接續 如何用 ESP32 快速做溫溼度監測? 使用 DHT sensor 來達成智慧家居! 的程式範例繼續寫:
- 增加 define 三個常數,
HUMIDITY_PIN
,MAX_HUMIDITY
以及DAC_MAX_VALUE
- 增加
displayHumidity()
函數,傳入目前濕度值,轉換 0 ~ 100 的濕度範圍為 0 ~ 255 後寫入 DAC - 在
loop()
函數中,成功從 DHT22 取得溫濕度,呼叫displayHumidity()
函數將數值送出
#include <Arduino.h>
#include "DHTesp.h"
// 新增 define
#define HUMIDITY_PIN 25
#define MAX_HUMIDITY 100.0
#define DAC_MAX_VALUE 255
DHTesp dht;
// 新增顯示濕度函數
void displayHumidity(float humidity) {
int value = (int)(humidity / MAX_HUMIDITY * DAC_MAX_VALUE);
dacWrite(HUMIDITY_PIN, value);
}
void setup() [
dht.setup(27, DHTesp::AM2302);
}
void loop() {
TempAndHumidity data = dht.getTempAndHumidity();
if (dht.getStatus() != 0) {
Serial.println("DHT sensor error status: " + String(dht.getStatusString()));
} else if (isnan(data.humidity) || isnan(data.temperature)) {
Serial.println("Data is NaN!");
} else {
Serial.print("Humidity: ");
Serial.print(data.humidity);
Serial.print("% Temperature: ");
Serial.println(data.temperature);
// 呼叫顯示濕度函數,將濕度傳入
displayHumidity(data.humidity);
}
delay(2000);
}
溫度的部分就留給大家自行嘗試看看囉!
Step 5:上電測試
成功的話會看到電流表指針移動到對應電流值,可以簡單回推一下電壓是否正確,就能驗證程式是否有寫錯。
電流表頭裡面的刻度可以自行重新印一張正確的覆蓋上去,以後讀取就不用再腦中計算電壓反推拉!
延伸閱讀:如何用 ESP32 快速做溫溼度監測? 使用 DHT sensor 來達成智慧家居!