Soil to Signal logo: watercolour pea pods and tomatoes, WiFi arcs over the i, Nurtured in our greenhouse, est. 2026

A kitchen-garden build log · 15–26 September 2026

SoiltoSignal

Three pots on a shelf, one ESP32, a Raspberry Pi in the house. How a probe's voltage became a line on a screen that says when to water, and the plan for a garden bed that waters itself.

POT A POT B POT C

Every hour of the first pot week, from the deck's own log. The climb on the left is the first watering; the long slope is soil drying; the jump on the right is the watering a week later.

0NotebookBefore any wire

Two rules, then the physics

The idea fits in a sentence: a probe in the soil, a small computer that reads it, a screen in the house that says “water tomorrow”. Two rules shaped everything after it.

The control loop never leaves the garden.

Each bed gets its own ESP32 that senses, decides and, one day, waters on its own. WiFi is only a reporting path: the screen in the house asks, the node answers, and nothing arriving over that link can start a pump.

Nothing that can move water exists until the probes are proven.

Firmware, calibration, a week of watching real soil dry out. Only then a relay and a pump. So far, nothing in the build can water a plant.

Architecture diagram: three pots with probes on GPIO34, 35 and 32 feed one ESP32 node; a Pi 5 deck indoors polls it over WiFi, reporting path only; the pump box is marked not built until calibration is proven
How it connects today. Three probes on one node, a deck on a Raspberry Pi 5 in the house, and a dashed box where the pump will go. Nothing leaves the house network.

Six physical facts decided the design before any code did. Most sensor tutorials are written for a 5 V Arduino on a desk; a garden is wetter, further away and less forgiving.

ADC1 pins only

The ESP32's second ADC dies whenever WiFi is up. A probe on the wrong pin reads perfectly on the bench and returns garbage once the node joins the network.

Capacitive, never resistive

Resistive prongs electrolyse and corrode away inside a season. Capacitive probes have nothing bare in the soil.

3.3 V, not 5 V

The ESP32 is a 3.3 V part and not 5 V tolerant. Copying Arduino wiring kills boards.

Distance decides architecture

I²C dies past about a metre, and a long analog run degrades the very voltage being measured. So the computer goes to the bed, not the probe to the house.

A pump is another world

12 V, amps not milliamps, an inductive kick when it stops. Its own supply and fuse, and it reaches logic only through an opto-isolated relay.

All grounds meet

Separate supplies, one common ground. A floating ground gives readings that drift and still look plausible, which is worse than no reading.

1Notebook15–18 Sep 2026

The bench

An ESP32-WROOM-32U, five capacitive probes, a bag of jumper wires and a breadboard. Three days to get one number worth trusting.

The U in WROOM-32U means a tiny U.FL socket instead of a printed antenna. Without the pigtail it barely hears the router.

−82→−44dBm, empty socket → antenna fitted

The probes arrived on 16 September: HW-390 boards with a TLC555 timer and their own regulator. On the 17th, probe 1 on GPIO34 read 2.750 V in air and 1.566 V pushed into damp potting soil. The very first reading was 0.142 V, because two jumpers were swapped. Lesson one: read the silkscreen, not the wire colour.

Pushing the probe deeper moved the reading from 1.58 to 1.71 V. Insertion depth matters, so every probe goes in to the line printed on its board.

18 Sep · post-mortem

Two probes lost on the breadboard

A plug went in rotated and put 3.3 V straight into probe 1's output. Board and probe ran hot, and probe 1 never read again. Probe 2 never gave a reading at all. The breadboard went in a drawer for good, and three rules came out of it: USB out before any plug moves. Jumper by the silkscreen, never by position. One change, one run.

Two-jar calibration, 18 September 2026: each probe's water and air voltage. Probes 1 and 2 dead.0 V1 V2 V3 V3.3 VProbe 3GPIO34 · 3V3 supply0.977 water · 100%air 2.715 · 0%Probe 4GPIO35 · VIN (USB 5 V)1.124 water · 100%air 2.770 · 0%Probe 5GPIO32 · GPIO25 driven high1.070 water · 100%air 2.610 · 0%Probes 1 and 2lost on the breadboard, 18 SepP2 ~0.14 floatingP1 stuck at 3.145

Two jars

Calibration is two readings: the probe in air, then in a glass of water up to the line. Those voltages become 0 % and 100 %. Each probe gets its own pair, taken on the pin and supply it will live on, because the ESP32's ADC varies chip to chip. Swap the probe or the board and the numbers are void.

The board has three usable supplies (3.3 V, 5 V from USB, a GPIO driven high) and three grounds. That is the ceiling for wiring probes directly, so a node carries three probes.

Deck Pots chart to 21 September: flat until the two-jar calibration on the 18th, then three pot lines from the 19th, pot B dropping to 40 percent
The first week on screen. The spikes on the 18th are the two-jar calibration. From the 19th the probes are in pots A, B and C.
2Screen18–21 Sep 2026

A screen that stays in the house

The first plan posted readings to a hosted garden app. On 18 September that changed.

Still want to use WiFi, but it should be fully in-house.

The brief, 18 Sep

The deck is a small Python server on a Raspberry Pi 5 with a 1024 × 600 touch screen. It polls the node every 10 seconds, writes a CSV to its own disk and draws the page. Fonts ship with it, so it needs no internet at all. No cloud database, no login. Switch it off and the pots carry on.

The logo was settled on 19 September: watercolour pea pods and tomatoes, with WiFi arcs over the i. It sits in the deck's header next to the mark of Peas & Quiet, the kitchen-garden app this project will one day talk to.

Soil to Signal logoPeas & Quiet Kitchen Garden logo
Deck home view, dark theme, 21 September: Pot A 81 percent Wet leave, Pot B 40 percent Leave, Pot C 91 percent Wet leave, each card with 24 hour change, dry-line bar and seven-day sparkline
Home, 21 Sep. One card per pot: moisture as the big number, the change in 24 hours, a bar with the pot's dry line, a verdict in words, and seven days of sparkline.
Deck home view in the light theme, 21 September, same three pot cards on cream
The same screen in daylight. Press t for the light theme, r to swap percent for raw volts.

A window, not a door

On 21 September the deck got a public face at soil2signal.sloveller.com. Same pages, same live readings, and every write refused: nobody outside the house can calibrate a probe or log an event. No readings are copied anywhere. If the Pi is off, the page is off.

3Screen19–26 Sep 2026

The pot week

Probes 3, 4 and 5 went into pots A, B and C. One question for the week: does a line of numbers look like soil drying?

Pot week: hourly moisture for pots A, B and C, 19 to 26 September 2026Three lines drift down across the week, faster after Wednesday 23rd. Pot B sits lowest, near 25 percent by Saturday. Night hours are shaded. Stuck-probe flags, shown as lanes underneath, cluster in the night bands. All three jump up at the Saturday evening watering.0%25%50%75%100%SUN 20MON 21TUE 22WED 23THU 24FRI 25SAT 26DRY LINE 10%log unbroken from Sun 20, 21:39Wednesday on: 4–8 points a day,up from 1–2.5watered Sat 20:00 ▸A 54%C 53%B 24%STUCK-PROBE FLAGS PER HOUR · NIGHT SHADEDABC
POT A · PROBE 3 POT B · PROBE 4 POT C · PROBE 5 WATERED NIGHT 19:00–07:00
25,458readings logged, one a minute per probe
2gaps in the log, the longest 11 h
73 %of 462 stuck flags came at night
−57…−47dBm WiFi all week
3 of 5probes alive

It did. For the first three days the pots dried by one to two and a half points a day. From Wednesday it was four to eight. By Saturday noon Pot A had gone from 83 to 57 %, Pot B from 43 to 25 %, Pot C from 92 to 58 %. Whether the speed-up is warmer weather or the probe's curve in drier soil is still open.

Found 26 Sep

The node rebooted every 15 minutes, all week

ESPHome's API restarts a device if no Home Assistant connects within 15 minutes, and there is no Home Assistant here. The readings looked fine, so it went unnoticed for a week. One line of config fixed it: reboot_timeout: 0s.

Found 25 Sep

A still night is not a stuck probe

The deck calls a probe stuck after five identical readings, about 50 seconds. Overnight the soil barely moves, so most flags fired between 19:00 and 07:00. Real sensors fail to a plausible constant, so the check stays, but it needs a longer window.

24–25 Sep

“Water in about N days”

A forecast now fits each pot's recent dry-down and says when it will reach its dry line, with a range. A third tab, Week, rolls the log up by the hour: forecast fans, stuck-flag lanes, gaps and WiFi.

Deck Pots view, seven days to 26 September: pots A and C slide from about 90 to 55 percent, pot B from 40 to 25, then all jump at the Saturday evening watering
Pots, 7 days to Sat 26 Sep. The whole dry-down, as the deck draws it.
Deck Week tab: hourly moisture per pot with watering markers and the 10 percent dry line, stuck-flag lanes underneath, logger health panel with rows logged, gaps, stuck flags and WiFi
The Week tab. Logger health on the right: unbroken since Sun 21:39, two gaps, WiFi steady.
4NotebookDecided 18 Sep 2026

Watering, by hand, on purpose

For three pots, a pump is all cost: 12 V, a fuse, a relay, an enclosure, a shared ground. The pots get a printed gravity kit instead.

The kit is TimNooked's Modular Irrigation System from MakerWorld. A funnel feeds perforated pipe, held in the soil on spikes. Everything snaps together with no glue, and none of it is electrical, so it sits outside the rule about moving water and can start now.

The deck's only job on the watering side is to say when. The pour shows up as a step on the moisture curve, and that step against a known dose is each pot's calibration. If the step is clean and repeatable, the kit works. If not, fix the kit, not the firmware.

Status: printing next, in PETG. Sink test first (ml in against ml out), then Pot A for a week at 3 × 500 ml, then B and C.

The loop: soil, probe, node and deck are automatic and never start water; you, the funnel and the pipe are the manual half. Four reasons for a gravity kit, and three unknowns for week one
Half automatic, half you. Sensing runs on its own; only a person pouring moves water.
Cross-section of one pot: funnel at the high end, perforated pipe 5 to 8 cm down running slightly downhill to an end cap, holes up, three spikes, mesh sleeve; probe at least 5 cm from the pipe
In the pot. Pipe in the root zone, holes up, and the probe at least 5 cm away so it reads the pot, not the pipe.
Top view of pots A, B and C each with a funnel, pipes, corner and end cap; parts table of what the starterset supplies versus what three pots need; five-step maintenance cycle
One starterset, three pots. What to print extra, and how to keep it working through the season.
5Screen26 Sep – ~11 Oct 2026

Leaving it alone

Two weeks away, and nothing in the build can water a pot. So Saturday evening was hands-on checks only: probes seated, chargers on sockets nobody will switch off, and a drink for every pot.

POT A · 100 ML53→89 %the steady one
POT B · 150 ML24→66 %100 ml, then 50 more at 20:08
POT C · 100 ML53→94 %the wettest all week
Deck home, dark, 26 September 20:29: pots A 98, B 100 and C 100 percent after watering, all Wet leave, forecast in 36 hours
20:29, Saturday. All three read wet. The forecast waits 36 hours for fresh data before it names a day.
Deck home, light theme, 26 September 20:30, same three pots after watering
The last screen before leaving, in daylight colours.

A free soak test

The reboot fix went on at lunchtime, so the deck's reboot counter started at zero. For two weeks nobody touches the node or the Pi. Any reboot now is real, and points at the power supply. Any gap is real. That is half of the next phase's month on the shelf, for free.

One message out

The deck only shows alerts on its own screen, which nobody will be looking at. So one small process on the Pi checks it every 10 minutes and sends a Telegram message when a pot crosses its dry line or the node goes quiet. It only sends. Nothing it receives can act, and it will not grow into a readings feed.

6NotebookDrawn 19–21 Sep 2026 · for summer 2027

Next summer: one bed, no socket

There is no outdoor socket, decided on 20 September. So every node outside the house runs on the sun.

A bed that only senses gets the same ESP32, asleep 99 % of the time, on a 5 W panel and a small LiPo. It wakes every 30 minutes, powers the probe from a GPIO for 300 ms, reads, lets the deck poll it, and sleeps again. A bed that waters gets a 25 W, 12 V kit.

Deep sleep and a switched probe supply are preconditions, not options. And one bench test decides the solar manager: put the node to sleep and check the 5 V output is still on an hour later. Some cut out below about 50 mA, which is exactly what a sleeping node draws.

Watt-hours per day
Energy per day in watt-hours: what the node needs against what a panel makes0 Wh10 Wh20 Wh30 WhNode awake all day~12Node on a 30-min wake cycle~15 W panel, December1–25 W panel, grey September day~625 W panel, grey September day~30

A 10-litre watering costs about 0.25 Wh. Summer is not the limit; December is, and the bed is empty then anyway.

Solar-powered moisture node power chain: 6 V 5 W panel to solar manager to ESP32-WROOM-32U, LiPo cell, probe powered from GPIO25 for 300 ms, optional battery voltage divider, common ground rail, and the 30-minute wake cycle
Hardware notes 01: the sensing node. Panel, solar manager, LiPo, ESP32, probe. Solid lines carry power, dashed lines carry the reading.
First sketch of the node enclosure, top-down: solar manager and LiPo on the left, ESP32 on a half breadboard on the right, five probe leads through glands underneath
The sketch, 19 Sep. First pass at what goes where inside a 150 × 110 mm box.
Designed drawing of the pot node: solar manager and 2000 mAh LiPo, ESP32 on a printed tray, antenna on an SMA bulkhead, glands underneath with drip loops, five probes with printed caps
The drawing, 21 Sep. Printed tray, glands underneath, drip loops, antenna outside the box.
One bed, summer 2027: a 25 W panel above an IP65 box holding a PWM charge controller, 12 V LiFePO4, fuse, opto relay, buck converter and ESP32 with a stop switch; three probes in a 2 by 1 metre raised bed; a 12 V pump in a water butt feeds a drip line through a check valve; the house deck polls over WiFi
One bed, summer 2027. One box, one panel, one ground. The pump sits behind a fuse and an opto relay, a check valve stops the butt siphoning, and the drip line stays 5 cm clear of every probe. The deck reads the node and cannot start it.

Before the relay is ever wired, the firmware gets its interlocks: a hard maximum run time, a minimum gap between waterings, no watering on a stuck reading or when the cached forecast says rain, and a manual switch that can only stop. Then a week of dry runs with the relay clicking and no pump attached, a wet run into a bucket to measure litres, and only then the bed.

7ScreenDrawn 21 Sep 2026

The deck, a season on

What the screen in the house could look like once there are beds: battery and signal per node, greenhouse air, a cached forecast, the water butt, and the watering node's rules shown but never controlled. These are mockups; every reading on them is invented.

Mockup of the outdoor deck home view dated May 2027: bed cards for Tomatoes, Peas, Basil and Radish with battery, signal and moisture and a verdict each; greenhouse air from a BME280; cached forecast; water butt level; history
MockupHome, a May morning. Each bed speaks in plain words: “Fine until Thursday”, “Water tomorrow morning”, “Nothing to do”.
Mockup of the Tomatoes bed view: seven-day moisture chart with node watering runs and a feed marker, the node's watering rules with ticks and crosses, node battery, solar input, signal and firmware
MockupOne bed. The node's own watering rules, each ticked or crossed, and “Next check 17:10, will not run”.
Mockup of the deck in October 2027 with three alert cards across the top: frost tonight, water basil, radish node silent
MockupAn October night. Frost due, basil under its line, one node gone quiet.

On a phone the same page folds into one column: greenhouse, rain and butt across the top, a card per bed below, and a line at the bottom that says what the page is. Read only, served by the Pi. Nothing here waters anything.

Mockup of the outdoor deck on a phone: greenhouse 18.4 degrees, rain Saturday, butt 62 percent, then cards for Tomatoes, Peas, Basil and Radish, and a nodes list
MockupOn a phone.
8NotebookSketched 20 Sep 2026

The garden app and the soil

Peas & Quiet knows what is planted, what is due and what the weather will do. It has never seen the soil. Soil to Signal has the soil and nothing else.

Integration map: on the left the home network with the ESP32 node, the deck on the Pi 5 and a home assistant on the Mac; on the right the Peas and Quiet cloud app with snapshot, tasks, journal, a parked readings route and the copilot; tier 0, 1 and 2 links between them
Hardware notes 02: the join. Green lines only read, terracotta lines write a task, dashed lines are not planned.

The join is ordered by what crosses the house boundary. The rule: a task may leave the house; a reading never does.

Tier 0 · reads only

The deck learns the garden

  1. Tasks, crops and 7-day rain beside the moisture bars
  2. “Tomato (Sungold)” on the card instead of “Pot A”
  3. A morning brief that knows the real soil, read over the home network
  4. A feed logged in the app flags the probe to recalibrate
Tier 1 · one write

A task, not a reading

  1. A pot under its floor for hours raises one “water” task
  2. Calibrations and probe swaps become journal entries
  3. A silent node or a low battery raises a “protect” task
Tier 2 · not planned

On record, not on the roadmap

  1. An hourly digest so the copilot can tell drought from root rot
  2. Per-crop moisture floors, copied into the deck by hand

Never, in any tier: cloud → pump.

9ScreenAs of 26 Sep 2026

The plan from here

Phases keep the numbers they were given in the original plan, so they do not run in numeric order. The pots come first; the garden waits on where the greenhouse goes.

Phase 0 · Sep

Bench node + deck

Done

Node flashed and online, antenna fitted, deck running on the Pi.

Phase 1 · Sep–Oct

Pot week + calibration

Exit met

Three calibrated probes, a week that looks like drying. Left: a node-side stuck guard, a looser stuck check, two probes in one pot.

Phase 2 · Oct–Nov

The node on its own

Soak running

A month on a shelf, untouched, log unbroken. Then the printed gravity kit, pot by pot.

Phase 5a · Nov

Alerts on the deck

Nearly done

Silent node, stuck probe, dry pot and the Telegram nudge are in. Left: real dry lines for pots A and C.

Phase 3 · 18 Sep

Dashboard

Done

Home, Pots and Week tabs, forecast, read-only mirror.

Phase 2b

Probes into the beds

Parked

After a WiFi survey of each bed. Recalibrate in bed soil, not potting mix.

Phase 2c

Solar sensor nodes

Parked

Deep sleep, switched probe supply, battery gauge, a month outdoors.

Phase 4 · summer 2027

The watering node

Parked

The first thing that moves water. Interlocks, dry run, bucket, bed.

Phase 5b · 6

Beyond the deck

Later

The Peas & Quiet join, and log retention if it ever matters.

Back around 11 October
  1. Read the two weeks: reboots, gaps, the dry-down past the line.
  2. Set real dry lines for pots A and C from what the dry-down showed.
  3. Loosen the stuck check so a still night is not a fault.
  4. Work out why the drying sped up: fit on volts, or weight recent days harder.
  5. Then a stuck guard on the node itself, and print the gravity kit.
10NotebookKept alongside the build

Field log

The decisions and the reasons behind them, day by day. Most of these were written down the evening they happened.

15 Sep

First firmware, CI that compiles it on every push, and the hardware primer. Saved: two ESP32 soil-probe tutorials and a folder of DIY greenhouse plans.

16–17 Sep

Five capacitive probes arrive, labelled 1–5. First real reading on GPIO34: 2.750 V in air, 1.566 V in damp soil. A calibration log is started: one row per probe, per chip, per date.

18 Sep

The breadboard session costs two probes. Three survivors are wired direct and two-jar calibrated. Three probes per node becomes the rule.

The dashboard goes fully in-house on the Pi. The plan to post readings to a hosted app is parked, not deleted.

Watering for the pots will be a printed gravity kit. No pump, no relay, no 12 V.

19 Sep

The pot week starts: probes in pots A, B and C, a reading every minute. Logo settled. A second ESP32 and five more probes ordered as spares. Solar parked until the manager is chosen.

20 Sep

No outdoor socket, so every outdoor node is solar. Peas & Quiet becomes a joint project, joined by tiers.

21 Sep

Dry line and a verdict in words on each card. The read-only public mirror goes live. The 2027 deck is drawn, and a printable splash hood for the probe tops.

24 Sep

Watering forecast on the cards: days to each pot's dry line, with a range.

25 Sep

The Week tab. A spreadsheet mirror that never delivered a row is removed; the CSV on the Pi is the only copy.

26 Sep

The 15-minute reboots found and fixed. All pots watered at 20:00, the Telegram alert live at 20:14. Then two weeks of leaving it alone.

Learned the hard way

  • Jumper by the silkscreen.Never by wire colour or plug position. A rotated plug put 3.3 V into a probe's output and killed it.
  • USB out before any plug moves.One change, one run.
  • ADC2 lies once WiFi is up.A probe on an ADC2 pin reads perfectly on the bench and returns noise on the network.
  • Calibration is per probe, per chip.Swap either and redo both jars. A new board means new numbers for every probe on it.
  • Sensors fail quietly.A dead probe sits at a plausible constant, not an error. Reject a reading identical to the last several before acting on it.
  • Push to the line.Insertion depth moved one reading from 1.58 to 1.71 V.
  • A flat reading can be the chip.Check the probe board carries a TLC555, not an NE555.
  • A still night is not a fault.Overnight soil barely changes; a stuck check needs a window longer than a minute.
  • Readings can look fine while the node reboots.Count uptime resets, not just values.
  • Fertiliser reads wet.Soil EC makes a capacitive probe read 2–5 % wetter per dS/m, just when the plant needs water to move the feed. Recalibrate when the feeding changes.