DCDevicecamp
メニュー

ESP32 + DS18B20を数分で可視化。

DS18B20向けの完全なArduino MQTT/TLSレシピです。認証情報を生成し、Wi-Fiを設定して基板へ書き込みます。

1. ライブラリをインストール

Arduino IDEで「esp32 by Espressif Systems」「PubSubClient by Nick O’Leary」「DallasTemperature」をインストールし、表示される依存関係も追加します。

2. センサーを接続

1-Wireデータ線はGPIO 4を使用します。必要に応じてONE_WIRE_PINを変更し、センサーと基板に適したプルアップを接続してください。

送信メトリクス: temperature

3. 実際の認証情報を生成

Devicecampでデバイスを作成し、ESP32 Arduinoを選びます。コピーまたはダウンロード前にこのセンサーを選ぶと、正しいMQTT IDとトピックがスケッチへ入ります。

4. 公開テンプレートを確認

この公開ページのMQTT_CLIENT_ID、MQTT_USERNAME、MQTT_PASSWORDはプレースホルダーです。

// Devicecamp ESP32 MQTT/TLS starter
// Install "esp32 by Espressif Systems" and "PubSubClient by Nick O'Leary".
// Also install "DallasTemperature" and "OneWire".
// This file contains a live device credential. Do not commit or share it.

#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <time.h>
#include <math.h>
#include <OneWire.h>
#include <DallasTemperature.h>

const char WIFI_SSID[] = "YOUR_WIFI_SSID";
const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD";

const char MQTT_HOST[] = "mqtt.devicecamp.app";
const uint16_t MQTT_PORT = 8883;
const char MQTT_CLIENT_ID[] = "MQTT_CLIENT_ID";
const char MQTT_USERNAME[] = "MQTT_USERNAME";
const char MQTT_PASSWORD[] = "MQTT_PASSWORD";
const char TELEMETRY_TOPIC[] = "v1/devices/DEVICE_ID/telemetry";
const char STATUS_TOPIC[] = "v1/devices/DEVICE_ID/status";

const char DEVICECAMP_CA[] PROGMEM = R"EOF(
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAwTzELMAkGA1UE
BhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2VhcmNoIEdyb3VwMRUwEwYDVQQD
EwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQG
EwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMT
DElTUkcgUm9vdCBYMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54r
Vygch77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+0TM8ukj1
3Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6UA5/TR5d8mUgjU+g4rk8K
b4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sWT8KOEUt+zwvo/7V3LvSye0rgTBIlDHCN
Aymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyHB5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ
4Q7e2RCOFvu396j3x+UCB5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf
1b0SHzUvKBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWnOlFu
hjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTnjh8BCNAw1FtxNrQH
usEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbwqHyGO0aoSCqI3Haadr8faqU9GY/r
OPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CIrU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4G
A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY
9umbbjANBgkqhkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ3BebYhtF8GaV
0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KKNFtY2PwByVS5uCbMiogziUwt
hDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJw
TdwJx4nLCgdNbOhdjsnvzqvHu7UrTkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nx
e5AW0wdeRlN8NwdCjNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZA
JzVcoyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq4RgqsahD
YVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPAmRGunUHBcnWEvgJBQl9n
JEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57demyPxgcYxn/eR44/KJ4EBs+lVDR3veyJ
m+kXQ99b21/+jh5Xos1AnX5iItreGCc=
-----END CERTIFICATE-----
)EOF";

WiFiClientSecure tls;
PubSubClient mqtt(tls);
const uint8_t ONE_WIRE_PIN = 4;  // Change this to the GPIO used by your board.
OneWire oneWire(ONE_WIRE_PIN);
DallasTemperature ds18b20(&oneWire);

unsigned long lastPublishAt = 0;
unsigned long nextReconnectAt = 0;
unsigned long reconnectDelayMs = 1000;
const unsigned long PUBLISH_INTERVAL_MS = 60000;

void connectWiFi() {
  WiFi.mode(WIFI_STA);
  WiFi.setAutoReconnect(true);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("Connecting to Wi-Fi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" connected");
}

void syncClock() {
  // Certificate validation needs a reasonably correct clock.
  configTime(0, 0, "pool.ntp.org", "time.nist.gov");
  Serial.print("Synchronizing clock");
  time_t now = time(nullptr);
  while (now < 1700000000) {
    delay(500);
    Serial.print(".");
    now = time(nullptr);
  }
  Serial.println(" ready");
}

void connectMQTT() {
  if (mqtt.connected() || millis() < nextReconnectAt) return;

  const bool connected = mqtt.connect(
    MQTT_CLIENT_ID,
    MQTT_USERNAME,
    MQTT_PASSWORD,
    STATUS_TOPIC,
    1,
    true,
    "{\"status\":\"offline\"}"
  );

  if (connected) {
    Serial.println("MQTT connected");
    mqtt.publish(STATUS_TOPIC, "{\"status\":\"online\"}", true);
    reconnectDelayMs = 1000;
    return;
  }

  Serial.printf("MQTT failed, state=%d; retry in %lu ms\n",
    mqtt.state(), reconnectDelayMs);
  nextReconnectAt = millis() + reconnectDelayMs;
  reconnectDelayMs = min(reconnectDelayMs * 2, 60000UL);
}

void publishReading() {
  ds18b20.requestTemperatures();
  const float temperature = ds18b20.getTempCByIndex(0);
  if (temperature == DEVICE_DISCONNECTED_C) {
    Serial.println("DS18B20 read failed");
    return;
  }
  const String localIP = WiFi.localIP().toString();
  char payload[160];
  snprintf(payload, sizeof(payload),
    "{\"metrics\":{\"temperature\":%.2f},\"metadata\":{\"local_ip\":\"%s\"}}",
    temperature, localIP.c_str());

  if (mqtt.publish(TELEMETRY_TOPIC, payload)) {
    Serial.printf("Published: %s\n", payload);
  } else {
    Serial.println("Publish failed");
  }
}

void setup() {
  Serial.begin(115200);
  ds18b20.begin();
  connectWiFi();
  syncClock();
  tls.setCACert(DEVICECAMP_CA);
  mqtt.setServer(MQTT_HOST, MQTT_PORT);
  mqtt.setBufferSize(512);
  mqtt.setKeepAlive(30);
  mqtt.setSocketTimeout(10);
}

void loop() {
  if (WiFi.status() != WL_CONNECTED) {
    WiFi.reconnect();
    delay(100);
    return;
  }

  connectMQTT();
  mqtt.loop();

  const unsigned long now = millis();
  if (mqtt.connected() &&
      (lastPublishAt == 0 || now - lastPublishAt >= PUBLISH_INTERVAL_MS)) {
    publishReading();
    lastPublishAt = now;
  }
}

5. 書き込んで確認

WIFI_SSIDとWIFI_PASSWORDを設定してアップロードし、115200 baudでシリアルモニターを開きます。「Published」が送信成功の目印で、最初のpayload受信後にworkbenchへメトリクスが表示されます。