使用ESP32製做水溫計並透過MQTT整合至Home Assistant來監測水溫

要看魚缸的水溫,拐杖型的溫度計是最簡單且便宜的產品,從一開始玩水草缸時就有在使用。後來跳入海水缸後用上了Neptune Apex 2016當魚缸的主控系統,對一個有資料狂熱症的我來說,有了各種即時監控的資料就再也回不去那個用眼睛看資料的古早時代了。

從海水缸撤缸後,本以為「水族」這個標籤在這個網站上不會再有新文章了,現在莫名的一句「爸爸我想養魚」,一回過神已經有一金魚缸擺在客廳裡養水了。因為家裡有架Home Assistant的伺服器在做智慧家居,要寫寫程式搞個魚缸控制也不難,其中水溫這一項可以靠ESP32來達成,需要的材料有

  • ESP32開發板一片(我買的是DOIT ESP32 Devkit V1開發板)
  • MicroUSB線一條
  • 4.7KΩ電阻一根
  • 水溫線一條(DS18B20或DS1820B)
  • 杜邦線三條(紅黃黑最好)

先接線,DS18B20有三條線,紅色是VCC、黑色是GND而黃色是DATA。

  • VCC跟紅色杜邦線接起來,透過接頭接到ESP32開發板的3.3V腳位。
  • GND跟黑色杜邦線接起來,透過接頭接到ESP32開發板的GND腳位。
  • DATA跟黃色杜邦線接起來,透過接頭接到ESP32開發板的GPIO15腳位,GPIO的腳位可以任意選擇,在後面程式中綁定即可,選GPIO15是因為就在GND旁邊。
  • 在GND與DATA之間接上一根4.7KΩ的電阻。

完工後的樣子,ESP32開發板一端是USB線,一端是水溫計。

接上電腦後開始寫程式並上傳到ESP32。如果首次使用,需要安裝ESP32的USB-to-Serial轉換器驅動程式,否則Windows會認不到裝置,比較常見的是Silicon LABS的CP210x和WCH的CH340二種。

這個程式會用到的四個Arduino套件要預先到Manage Libaries裡安裝

  • Wi-Fi:提供與ESP32的Wi-Fi模組進行通信的功能
  • DallasTemperature:用於與Dallas半導體公司的DS18B20溫度感應器通信的套件,這些感應器使用OneWire協議來傳輸數據。
  • OneWire:使ESP32可以通過一根數據線與DS18B20感應器進行通訊。
  • PubSubClient:透過MQTT協議將資料上傳到指定的MQTT Broker。

程式碼如下

// 引入需要使用的套件
#include <WiFi.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <PubSubClient.h>

// 設定Wi-Fi
const char* ssid = "SSID"; // 自行更改
const char* password = "PASSWORD"; // 自行更改

// 設定MQTT Broker
const char* mqtt_server = "IP"; // 自行更改
const char* mqtt_user = "USER"; // 自行更改
const char* mqtt_password = "PASSWORD"; // 自行更改
const char* topic = "aquarium/tank/water_temperature"; // 自行更改

// 設定DS18B20
#define ONE_WIRE_BUS 15 // GPIO腳位可自行更改
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

// 設定MQTT客戶端
WiFiClient espClient;
PubSubClient client(espClient);

void setup() {
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  sensors.begin();
}

void setup_wifi() {
  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void reconnect() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    if (client.connect("ESP32Client", mqtt_user, mqtt_password)) {
      Serial.println("connected");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);
    }
  }
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  sensors.requestTemperatures();
  float temperatureC = sensors.getTempCByIndex(0);
  Serial.print("Temperature: ");
  Serial.println(temperatureC);

  char tempString[8];
  dtostrf(temperatureC, 1, 2, tempString);
  client.publish(topic, tempString);

  delay(30000); 
}

寫完後就可以上傳至ESP32

如果硬體連線與程式都沒有問題,這時從MQTT Explorer應該就要可以看到ESP32上傳的資料。

到Home Assistant中新增MQTT sensor

sensor:
  - name: Aquarium_Tank_WaterTemperature
    state_topic: "aquarium/tank/water_temperature"
    value_template: "{{ value }}"
    unit_of_measurement: "°C"

初始化MQTT實體後就可以看到水溫的資料,這是測試了大約六小時的資料,水溫每10秒鐘上傳一次,但後來認為不需要這麼頻繁,改成每30秒鐘上傳一次,減少資料的儲存量。

左邊埋入水裡的是水溫感應器,跟右邊的實體溫度計比對,大概差個0.2度左右而已。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

返回頂端