Tutorial 01 of 05

Hello, spine.

Flash the reference publisher and make one device appear.

Success looks likeYour device appears on the developer view with a green alive badge.

You will connect one ESP32 to Wi-Fi, give it its printed device credentials, and publish a known-good temperature message. Do not wire a sensor yet. Use the fixed value in the reference firmware.

Stop when the dot turns green. This tutorial proves the network path. Sensor work comes next.

You are not expected to understand the code yet. Treat it like a recipe. Copy it exactly. The only file you edit is config.h. Leave every quote, comma, bracket, and semicolon in place.

Before you start

Your laptop needs setting up once. If you have not installed the Arduino IDE, ESP32 support, and the Garden Spine library yet, do the 30-minute setup first. This page assumes it is done.

Set these beside your laptop:

The programme uses the open Wi-Fi network panoulu. It has no password. The live MQTT hostname is gardenspine.ikapo.fi; publishing still uses authenticated TLS on port 8883.

Flash the first message

  1. Connect the board. Plug the ESP32 into your laptop. Pick your board under ToolsBoardesp32 and the port that appeared under ToolsPort. Unplug and replug to see which port changes.

    done when: Arduino IDE shows a serial port for the board.

  2. Open the example and save your own copy. Go to FileExamplesGardenSpine01_FirstMessage, then FileSave As… into your documents. The menu copy is read-only; the saved one is yours.

    done when: the tab name no longer has a lock or “read-only” marker.

  3. Add a config.h tab. Click the small arrow button at the right end of the tab bar, choose New Tab, and name it config.h. Fill it in as shown below.

    done when: no square brackets remain in config.h.

  4. Upload, then open ToolsSerial Monitor at 115200 baud. Press the board’s reset button once if the monitor stays blank.

    done when: the monitor prints the expected output below.

  5. Open your team view. Visit the developer view, select your team prefix, and find the device ID printed on your slip.

    done when: the badge reads alive and the message count increases.

Fill in config.h

Copy this whole block into your empty config.h tab. Do not leave any line out — the file has to compile as it stands.

// Copy this file into your sketch folder as config.h, then fill in your own values.
// config.h is the only file holding your credentials. Never commit it.
// When you are done, search this file for "[" — no placeholder should remain.

#pragma once

// Leave these four as they are. The programme network is open, so the password is empty.
const char* SPINE_WIFI_SSID = "panoulu";
const char* SPINE_WIFI_PASSWORD = "";
const char* SPINE_MQTT_HOST = "gardenspine.ikapo.fi";
const int SPINE_MQTT_PORT = 8883;

// From your credential slip. The MQTT username is the same as the device ID.
const char* SPINE_DEVICE_ID = "gm-01";
const char* SPINE_MQTT_USERNAME = "gm-01";
const char* SPINE_MQTT_PASSWORD = "[DEVICE_PASSWORD]";

// From your charter page. These must match the registry exactly.
const char* SPINE_ZONE = "greenhouse-1";
const char* SPINE_DEVICE_TYPE = "climate-node";

// Your own version string. Bump it so you can tell which build is running.
const char* SPINE_FIRMWARE_VERSION = "0.1.0";

Now change three things, and nothing else:

From your credential slipSPINE_DEVICE_IDSPINE_MQTT_USERNAME

Both get the same device ID. The example shows gm-01.

From your credential slipSPINE_MQTT_PASSWORD

The only value you cannot guess. Case-sensitive.

From your charter pageSPINE_ZONESPINE_DEVICE_TYPE

The example shows Charter 01. Yours are in your charter’s header.

Every value is in quotation marks except the port. SPINE_MQTT_PORT is a number, so it has no quotes and uses int rather than const char*. If you retype that line and add quotes, the sketch will not compile.

There is no certificate to paste. The programme’s security certificate ships inside the library, and your connection is still fully verified.

Check before uploading

Search config.h for [. The password is the only placeholder, and it should be gone.

What the sketch does

You already have this open in the other tab. Nothing here needs changing.

#include <GardenSpine.h>

GardenSpine spine;
bool firstMessageSent = false;

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

void loop() {
  spine.loop();
  if (spine.connected() && !firstMessageSent) {
    firstMessageSent =
      spine.publish("temperature", 22.5, "celsius");
  }
}

One line carries your data, and it takes three things:

what you measured“temperature”
the value22.5
the registered unit“celsius”

The library fills in everything else — device ID, timestamp, firmware version, the topic, TLS, MQTT, and the JSON. Open GardenSpine.h if you are curious. You never need to edit it.

Expected Serial Monitor output
Garden Spine: starting
Wi-Fi: connecting to panoulu
….
Wi-Fi: connected, IP 10.x.x.x
Clock: synchronizing.. ready
MQTT: connecting to gardenspine.ikapo.fi
MQTT: connected
published temperature = 22.50 celsius

The number of dots varies. The last line is the one that matters.

The developer view should show:

Expected browser result

gm-01 alive temperature 22.5 celsius

No board yet: publish from a laptop

No hardware yet, or waiting for a kit? Publish from Python instead and reach the same green dot. Get GardenSpineLaptop.py, config.py.example, and first_message.py from the downloads page, then rename the config file to config.py and fill in the bracketed values.

Python reads the certificate from disk rather than from the library, so download the CA certificate too and save it beside config.py.

python -m pip install paho-mqtt
import config
from GardenSpineLaptop import GardenSpineLaptop

spine = GardenSpineLaptop(config)
spine.begin()
spine.publish("temperature", 22.5, "celsius").wait_for_publish()
print("published temperature = 22.5 celsius")
Expected terminal output
published temperature = 22.5 celsius

If it did not work

Continue with the troubleshooting guide, or open When it breaks to learn the reject feed.