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:
- one ESP32 and its USB data cable;
- the credential slip from the kit box;
- your charter page, open in a tab, for your zone and device type.
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
Connect the board. Plug the ESP32 into your laptop. Pick your board under and the port that appeared under . Unplug and replug to see which port changes.
done when: Arduino IDE shows a serial port for the board.
Open the example and save your own copy. Go to , then 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.
Add a
config.htab. Click the small arrow button at the right end of the tab bar, choose New Tab, and name itconfig.h. Fill it in as shown below.done when: no square brackets remain in
config.h.Upload, then open at 115200 baud. Press the board’s reset button once if the monitor stays blank.
done when: the monitor prints the expected output below.
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:
SPINE_DEVICE_IDSPINE_MQTT_USERNAMEBoth get the same device ID. The example shows gm-01.
SPINE_MQTT_PASSWORDThe only value you cannot guess. Case-sensitive.
SPINE_ZONESPINE_DEVICE_TYPEThe 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.
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:
“temperature”22.5“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.
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 celsiusThe number of dots varies. The last line is the one that matters.
The developer view should show:
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")
published temperature = 22.5 celsiusIf it did not work
- No serial port: use a USB data cable, not a charge-only cable.
GardenSpine.h: No such file or directory: the library is not installed. Redo setup step 04.- Wi-Fi never connects: confirm the SSID is exactly
panouluand the password is empty. - Clock never becomes ready: the helper needs network time before it can validate the TLS certificate.
- MQTT never connects: copy the username and password again. They are case-sensitive.
- Certificate error: reinstall the library from setup step 04, which carries the certificate. Never disable certificate checking.
- Connected, but no green device: confirm
SPINE_DEVICE_IDinconfig.hmatches the ID on your credential slip. - A rejected message appears: read the bold hint. It names the field to change.
Continue with the troubleshooting guide, or open When it breaks to learn the reject feed.