Tutorial 02 of 05

Publish a real reading.

Wire one sensor and publish a number that changes when you breathe on it.

Success looks likeA live sensor value changes in the developer view.

You will replace the fixed number from Hello, spine with temperature and humidity from a DHT11. Keep the network code that already produced a green device.

Reference starting point. This sketch uses GPIO 4 for sensor data. If your confirmed board reserves that pin, change SENSOR_PIN once. Do not scatter pin numbers through the code.

Your file contains the project decisions. GardenSpine.h still handles Wi-Fi, security, topics, and message formatting. You decide which sensor to read and how often to read it.

Wire one sensor

Disconnect USB power before moving wires.

DHT11 pin ESP32 connection Wire role
VCC or + 3V3 sensor power
DATA or S GPIO 4 digital reading
GND or - GND shared ground

Some DHT11 modules have three pins and some bare sensors have four. Read the labels on your part. Do not identify a pin by color alone.

  1. Install the DHT library. In Arduino IDE, install the DHT sensor library and its required unified sensor dependency.

    done when: #include <DHT.h> verifies without an error.

  2. Add the sensor constants and setup. Put the declarations at the top of the sketch, above setup(). Call dht.begin() once inside setup().

    done when: Serial Monitor prints two finite values.

  3. Publish two separate messages. Temperature and humidity use different measurements and units. The helper supplies ts: null.

    done when: both measurements appear beneath your device card.

  4. Prove the value is live. Breathe gently toward the sensor vents, without touching them. Watch humidity over the next readings.

    done when: the humidity number changes in Serial Monitor and on the developer view.

Download 02_ClimateNode.ino, or replace the first-message sketch with this complete climate sketch:

#include <DHT.h>          // the sensor tool
#include <GardenSpine.h>  // connection, topic, and message format

const int SENSOR_PIN = 4;

// YOUR CALL: choose how often to measure.
const unsigned long SAMPLE_MS = 60000;

DHT dht(SENSOR_PIN, DHT11);
GardenSpine spine;
unsigned long lastReading = 0;

void setup() {
  Serial.begin(115200);
  dht.begin();
  spine.begin();
}

void loop() {
  spine.loop();

  bool timeToPublish =
    millis() - lastReading > SAMPLE_MS;

  if (timeToPublish) {
    lastReading = millis();

    spine.publish(
      "temperature",
      dht.readTemperature(),
      "celsius"
    );
    spine.publish(
      "humidity",
      dht.readHumidity(),
      "percent-rh"
    );
  }
}

GardenSpine.h includes config.h for you. You never include it yourself.

Only the two spine.publish() calls describe your data. The header checks that the sensor returned a real number, builds the canonical payload in a fixed memory buffer, and sends it.

Expected Serial Monitor output
published temperature = 23.00 celsius
published humidity = 61.00 percent-rh
Expected browser result

Your device stays alive. It shows separate temperature and humidity rows. Both sparklines begin filling from the same API used by the real dashboard.

If it did not work

Next: read the neighbouring visitor counter.