Land research-grade SDI-12 instruments — soil, water, weather probes — straight in your own data lake.
| Status | Source release — build & flash it yourself |
| Interface | SDI-12 digital bus (one data wire, addressable) |
| Delivers | Webhook (HTTP POST) · MQTT — oat-ods/0.3 |
| Site page | openagriculturetechnology.com/build/sketches/sdi12-reader/ |
| License | Apache-2.0 |
Professional soil, water, and weather instruments speak SDI-12, the open
digital bus that usually needs a costly datalogger. This node reads them directly
— Apogee SQ-521, soil/water probes, weather sensors — and pushes each value to
your endpoint, no proprietary logger required. Reuses the shared
oat_ods encoder.
SDI-12 returns bare numbers — it doesn't say what they mean. So you tell the node, on its setup page, one line per sensor:
<addr> <stream_id> <measure1>:<unit1>,<measure2>:<unit2>,...
Examples:
0 gh2-soil moisture:%,temperature:Cel,ec:dS/m
1 canopy-par par:umol/m2/s
The node polls each address (aM! then aD0!…) and maps the returned values, in
order, to your labels. Each value becomes one oat-ods message: stream = your
stream_id, physical_id = sdi12:<addr>, measurement/unit = your labels.
Don't know the addresses? The setup page has a Scan the bus helper that
queries aI! on addresses 0–9 and shows what answers.
SDI-12 is one data wire (plus power + ground). The data line is 5 V logic (it idles low; signals swing to 5 V) and the ESP32 is 3.3 V, so put a level interface on the data line for reliable reads: one channel of a common BSS138 logic-level converter board works. Many sensors also want 12 V on their power line — separate from the ESP32's supply. Set the data GPIO on the setup page (default 16).
pio run -t upload.OAT-SDI12-xxxx Wi-Fi, open the setup page (admin / oatsetup).pipx install platformio # or: pip install --user platformio
cd oat-sdi12-reader
./build.sh # builds all chip families, assembles the web-installer payload
This is a source release: it compiles against the pinned deps but hasn't
earned the bench-verified badge the live sketches carry — build it, flash it, and
prove it on your bench before you trust it in the field. Deps (pinned in
platformio.ini): EnviroDIY/SDI-12, knolleary/PubSubClient,
bblanchon/ArduinoJson, and the local oat_ods module.
{
"stream": "gh2-soil",
"measurement": "soil_moisture",
"value": 34.2,
"unit": "%",
"source": { "physical_id": "sdi12:0" }
}
The endpoint can't tell a $600 SDI-12 instrument from a $20 sensor — it's all one stream of owned data.
aM! stated seconds) is a blocking delay, capped at 30 s;
typical sensors answer in 1–3 s. A future rev can watch for the service-request
line instead of waiting.sdi12:<addr>; a future rev can enrich it from aI!
(vendor/model/serial).How do I read an SDI-12 sensor without a datalogger? An ESP32 with an SDI-12 library can act as the SDI-12 recorder itself: it addresses each sensor, issues a measure command, and reads back the values. Because SDI-12 signals swing to 5 V, a small level interface protects the 3.3 V microcontroller.
What sensors use SDI-12? It's the digital bus common on research-grade environmental instruments: soil moisture and water-content probes, water-quality sensors, and some weather and radiation sensors such as the Apogee SQ-521. Several sensors share one data wire, each at its own address.
Can I use an RS-485 or RS-232 converter board instead of a level shifter? No. An RS-485 board (MAX485) puts a differential pair on the wire, and SDI-12 is a single-ended one-wire bus, so the sensor never hears it — keep that board for the Modbus / RS-485 Reader. An RS-232 board is closer in spirit but drives negative voltage onto the bus and can't release the shared wire for the sensor to answer. The board that works is the common BSS138 logic-level converter: one channel on the data line shifts 3.3 V to 5 V both ways.
oat-modbus-reader/ — the other industrial-bus bridge (RS-485 / Modbus RTU).../lib/oat_ods/ — the shared oat-ods encoder + measurand vocabulary.Shared core: this sketch carries its own copy of the config / Wi-Fi / delivery scaffolding; as the shared
oat-node-corelibrary is adopted, only the acquisition layer stays sketch-specific.
Code: Apache-2.0 · Docs: CC BY 4.0 · An OAT sketch — an OpenCDC initiative.