← Build Log

Salt of the Earth

hardware firmware gardening

Round two, in which the boards behave

Last time I opened a blue box from China and found my first real circuit boards inside. The Prong, the soil sensor, was the first board I had ever designed and it did not work. The Head was the last one I designed and it worked perfectly. The Spine, the most complicated of the three, was still at the factory, and I ended the post by saying I had a guess about how it would go and refusing to tell you what it was.

My guess was that it would be a disaster. I was wrong, which is the nicest way to be wrong.

A second box came. Redesigns of all three boards, with the mistakes taken out and a summer of bench notes folded in. The Head still works. The Spine charges its battery now, which it stubbornly refused to do in the first version.

The Spine also got a less glamorous fix that I am arguably more pleased about. In version one I had invented my own pinouts, including a battery connector wired backwards from how the entire industry does it, which is how you turn a board into a small warm smell. Everything is now standard. I can plug Phoebe into off-the-shelf parts without doing arithmetic first, and nothing catches fire when I am tired. Boring. Correct.

And the Prong, my firstborn, the one that could do everything except the single job it exists for, can now feel the dirt.

Four green Prong sensor blades laid out on pink anti-static foam with the Phoebe bird logo on each, next to two larger boards, a battery, and an orange multimeter
Four Prongs, a Head, and a Spine. That squiggly maze pattern on the blade is the actual sensor. The little “Soil Line” mark is where the dirt is supposed to come up to, which turns out to matter more than I expected.

So that is the good news, and it is genuinely a lot of good news for one paragraph. But getting a working sensor forced me to confront a question I had been happily not thinking about for months.

What does a moisture sensor actually measure

Not moisture. I am sorry to report that basically none of them measure moisture.

Stick a cheap probe in the ground and what it really measures is how easily electricity moves through the soil. Wet dirt conducts better than dry dirt, so that number goes up and down with water and everyone agrees to call it a moisture reading. It mostly works, in the way that a stopped clock mostly works.

The problem is that water is not the only thing in your pot that conducts electricity. Salt does too. And “salt” here does not mean you spilled the shaker, it means fertilizer, hard tap water, and the mineral crust that builds up in any pot that has been lived in for a while.

So when you fertilize a plant, a normal moisture sensor sees the reading jump and concludes that the soil got wetter. It did not. It got saltier. The sensor then confidently tells you everything is fine while the plant slowly dries out underneath it. The failure mode is exactly backwards from what you want, and it shows up precisely in the pots that get the most attention, because those are the ones getting fed.

This bugged me for a long time before I understood it was solvable.

Three speeds instead of one

The fix is that you do not take one measurement. You take three, at three different speeds, on the same electrode.

The reason it works is almost dumb in its simplicity. Salt is slow and water is fast. Run the measurement slowly and the salt has time to join in and skew the answer. Run it a million times a second and the salt gets left behind, and what is left responding is the water. Same electrode, same instant, two different questions.

So you run both, plus one in the middle, and compare. Where they agree, that is water. Where they disagree, that is salt. The gap between them is not noise to be filtered out. The gap is the measurement.

That is the whole thesis of the board, and it is why the Prong has a maze etched into it instead of two metal spikes.

Then I fed it a sample that was both damp and salty, the exact case that breaks a normal sensor. The slow channel jumped 72 percent. The fast channel moved 6.8 percent. Two channels violently disagreeing about the same handful of dirt, which is precisely what I built them to do. The slow one is shouting about salt. The fast one is calmly reporting a little water. A single-frequency sensor would have averaged those into one confident wrong number and told you the plant just got a nice drink.

Dirt science

None of that, by the way, is how I actually spent my week. Getting the sensor working took a few days. Figuring out what it was telling me took considerably longer, and involved substantially more cat litter.

A sensor gives you a number. A number is not knowledge. To turn one into the other you have to go get a lot of dirt.

So my desk became a small, deeply unglamorous laboratory. Bone-dry soil from a houseplant I had already killed. Soil from the raised bed. That same soil after sitting in the sun. Soil at field capacity, which is the lovely term for saturated-then-drained. Waterlogged soil. Plain water in a cup. Fertilizer water in a cup, mixed at roughly one teaspoon of organic 5-4-2 in six ounces, which is a recipe I would not recommend for anything else. Walnut shell cat litter, dry, because I wanted something that looked like soil to a sensor but was not.

Each one got the probe stuck in it, four to six times, at various depths. Each one got written down. The result is a table in my notes that I am unreasonably fond of, and which no one else will ever read.

A green Prong sensor blade standing upright in a small pot of dark soil, connected by ribbon cable to a small board with a glowing red LED, powered by a blue lithium cell
One of the cups. Multiply this by a dozen, add a notebook, remove all the dignity, and you have the week.

The shell game

Then it got competitive.

The point of all those numbers is that eventually Phoebe has to interpret them without me standing there telling her what she is looking at. So I started running blind tests. Three unlabeled samples at a time, A, B and C. I would take the readings, hand over just the numbers, and ask for a verdict. What is this, how wet is it, is it salty.

I did not play fair. I threw in the cat litter. I threw in a wet paper towel. I re-tested the same sample later in the day, without saying so, to see if the drying got noticed. I salted a soil sample, let it dry out completely so the water left and the salt stayed behind, and presented it as an ordinary dry pot.

It is a genuinely stupid-looking way to spend an evening. It is also the only honest way to find out whether you have built an instrument or a random number generator, because the moment you know which cup is which, you will unconsciously grade on a curve. So: cups, no labels, and a grown man at his desk taking notes about cat litter.

It did better than I expected, and its failures were more interesting than its successes.

It caught the drying. Same sample, hours apart, correctly read as the same stuff with less water in it.

It caught the salt trap. The salted-then-dried soil was the mean one, because by every ordinary measure it is just dry dirt. It got flagged as salty anyway, on exactly the disagreement between the fast and slow channels that the whole board exists to detect. That was the moment I stopped worrying about whether the design was right.

It told cat litter from soil, both bone dry, on a gap of about twenty units I would have dismissed as noise if I had not been looking for it. Nothing else in the readings could tell them apart.

And it caught me cheating. The wet paper towel came back as very wet soil, which is wrong, but wrong in a way that gave me something. The reading was higher than pure water, which is physically impossible for actual dirt, because real soil is full of air gaps and a wet towel pressed flat against the electrode is not. So the sensor cannot identify a paper towel, but it can now say “whatever this is, it is not soil,” which is the useful half of the answer.

The other things it turned out to know

A handful of capabilities showed up that I did not design for and only noticed because I was staring at so many numbers.

It knows when it is not in the pot. Out in open air the reading falls below anything real dirt can produce. This is less trivial than it sounds, because the obvious way to detect it fails on salty soil, which is the exact case where a false “I fell out” would be worst. That took a rewrite to get right, and now Phoebe can say “I think I have been knocked over” instead of quietly reporting a drought.

It has opinions about the soil itself, not just the water in it. Loose, sandy, airy stuff reads differently from dense packed soil at the same moisture, because what the electrode really feels is the mix of water, mineral and air pressed against it. That is how it told bone-dry cat litter from bone-dry soil. Down the road it is how Phoebe might notice that a pot has gone hydrophobic, or compacted, or turned into a brick.

It can tell how sun-baked the soil is. There are two thermometers on the bird, one in the tip of the blade down in the dirt and one up on the board in the air. On the bench indoors they agree. Outside they should not, because soil holds heat differently than air does, and the gap between them is a direct read on how much sun that pot has been taking. It also doubles as a second opinion on whether the probe is actually buried, since a probe lying on the patio has both thermometers reading the same thing. That one needs a real garden and a real afternoon to prove out, so consider it a promising idea rather than a finished feature.

And warm soil lies. A sample that had been sitting in the sun read wetter than it was, because heat makes electricity move more easily and a naive sensor cannot tell that from water. That is precisely why the thermometer in the tip is not optional.

It knows how deep it is, sort of. Buried halfway, the reading is accurate. Buried a quarter of the way, moist soil reads as bone dry. That is not a firmware problem, it is a “design a collar so people cannot install it wrong” problem, which I am choosing to enjoy as a change of pace.

Why any of this matters to a plant

Phoebe’s whole premise is that she builds a little physics model of your plant and tunes it against what the sensors tell her. The model is only ever as honest as the numbers going in. If the moisture reading lies whenever you fertilize, then every conclusion downstream inherits the lie, and she becomes a very sophisticated system for being wrong in an authoritative voice.

Now she gets water and salt as two separate facts, plus a sense of what the soil is made of and how much sun it has been eating. That means fewer false “everything is fine” readings on a thirsty plant, an early warning when salt starts building up from over-fertilizing or hard water, and a probe that raises its hand when it has been knocked out of the pot.

None of this is visible in the app. Nobody will ever open Phoebe and see the cat litter. It is the boring foundation under everything I actually want to build, which is true of most of the interesting work.

Next

The numbers you just read came off a bare board on a bench. The real ones get sealed and coated before they go outside, and coating a sensor changes what it feels, so the whole characterization has to be run again on a finished unit. Then it has to survive a garden, where the sun bakes the soil in the afternoon and the temperature swings twenty degrees and nothing behaves like it does on a desk.

But the hard part is done. The thing that was just a nice theory in a design document in the spring is a number on a screen now, and the number is right.

There is always another respin

I would like to leave you with the impression that I have graduated to competence. I cannot.

Sitting in the middle of all that cleverness is one surface-mount component I laid out backwards. It is the static protection diode, the little bodyguard whose whole job is to absorb the zap when you shuffle across a rug and touch the board. I drew it facing the wrong way and sent that drawing to a factory, which built it exactly as instructed, because that is the deal.

The fix is a hot air gun and a part the size of this letter o. It is optional protection, so the board is perfectly happy without its bodyguard. It just has to live a little more dangerously until the next spin.

So the sensor can pick salt out of water, tell cat litter from dirt, and notice when it has fallen out of the pot, and I still have to go at it with tweezers because I could not get a two-terminal part the right way round. The tweezers are not the hard part. Recognizing the handwriting on the drawing is the hard part.

My firstborn works. She took two tries, a week of dirt, more cat litter than I care to explain, and she is going on the list for a third revision before the second one is even out of the bag. I am unreasonably proud of her.

— Ben