My DS18B20 Cable Was Fine and I Still Got 15 CRC Errors Per 1000 Reads
Search for DS18B20 CRC errors and you get one answer: your cable is too long, drop the pull-up to 2.2k. It is good advice and it is repeated everywhere, which is exactly why I want to write about the case where it does not apply.
My install is eight DS18B20 probes on a Raspberry Pi 4, wired with 3M 3811/10 ribbon, runs of 2-3 m, spec’d at roughly 45 pF/m. Standard 4.7k pull-up. By the internet’s account this is a boring, healthy bus. It still throws CRC errors at a steady rate.
This is the measurement that ruled out the cable, and what the numbers pointed to instead.
First, eliminate the cable properly
1-Wire is open-drain. Nobody drives the line high — master and slaves only pull it down, and the line returns high through the pull-up. So the rising edge is an RC charge curve, and the thing that kills you is the line not reaching a valid logic high before the master samples the bit.
The bus capacitance is dominated by the cable:
C_bus = length x capacitance_per_metre
tau = R_pullup x C_bus
t_rise = 2.2 x tau (10-90%)
For my install:
| Run | C_bus | tau @ 4.7k | 10-90% rise |
|---|---|---|---|
| 2 m | 90 pF | 423 ns | ~930 ns |
| 3 m | 135 pF | 634 ns | ~1.4 us |
A 1-Wire master samples a read slot about 15 us in. Even the worst run gets the line up in under a tenth of that. There is roughly 10x margin.
That is the whole point. Dropping to 2.2k would take the 3 m run from 1.4 us to 653 ns — a real halving, and completely irrelevant when the budget is 15 us. If your bus is short and you are swapping resistors hoping the errors stop, you are tuning the wrong parameter.
The pull-up-swap experiment is still pending — I haven’t yet run the 2.2k re-characterisation. But the arithmetic above is the reason I expect it to do nothing: with 10x margin already, removing half of an already-irrelevant rise time cannot move the CRC rate. I’ll report the measured before/after when I run it; until then, the calculation is the honest basis for the prediction, and I’m flagging it as not-yet-measured rather than claiming a result.
What the bus actually reports
You do not need an oscilloscope to characterise a 1-Wire bus. The kernel exposes CRC status on every read, so the failure rate is directly countable:
$ cat /sys/bus/w1/devices/28-0000048f9ff2/w1_slave
61 01 4b 46 7f ff 0f 10 02 : crc=02 YES
61 01 4b 46 7f ff 0f 10 02 t=22062
That YES is the CRC verdict on the nine scratchpad bytes. Poll every sensor in a loop,
count the NOs, and you have a signal-integrity metric with no test gear at all. I wrote
a script to do exactly that — it also times each read and each full chain sweep:
python3 ds18b20_bus_test.py --minutes 1440 --label "4k7 baseline"
Over the first ~900 reads it settled around 15 bad reads per 1000, and stayed there. The full 24-hour run tells the real story:
| Metric | 24 h value |
|---|---|
| Cycles (full sweeps) | 17,060 |
| Total reads | 136,480 |
| Bad reads (CRC NO) | 910 |
| CRC failures per 1000 reads | 6.67 |
| Master retry attempts (delta) | 6,539 |
| Duration | 2026-08-03 19:37 → 2026-08-04 19:37 UTC |
So the sustained rate is 6.67 per 1000, not the 15 the short smoke test hinted at — the early reads were still warming up the bus. It was stable across the full day: no drift with room temperature, no time-of-day clustering. A steady ~7/1000 is the bus’s personality, not a transient.
The retry delta is worth a line: the w1-gpio master attempted 6,539 extra reads beyond the 136,480 scheduled, which is the kernel re-trying on a NO verdict. That’s the driver absorbing errors transparently — the 910 that still failed are the ones even a retry couldn’t save.
The 2.3x spread nobody mentions
The other number worth having is how long a full chain sweep actually takes:
| seconds | |
|---|---|
| min | 3.70 |
| median | 3.88 |
| p95 | 8.98 |
| max | 17.39 |
Eight sensors, and the median sweep is 3.88 s while the 95th percentile is 8.98 s — and the occasional sweep hits 17.4 s at the tail. If you size your poll interval off the median — the obvious thing to do — you will overrun regularly, and your collector will start stacking reads on a bus that is still busy.
The thing I actually found
Reading the per-sensor breakdown, the probes split cleanly into two groups by read latency: some around 0.13 s, others around 0.80 s. My first instinct was a failing sensor.
It was not. It was resolution:
$ for d in /sys/bus/w1/devices/28-*; do
printf "%s " $(basename $d); cat $d/resolution
done
28-0000048f4a16 9
28-0000048f5411 9
28-0000048f9f55 9
28-0000048f9ff2 12
28-0000048fad01 12
28-0000048fba5c 12
28-0000048fec92 12
28-0000049053fe 9
Four sensors at 9-bit, four at 12-bit. Straight out of the datasheet, conversion time is 93.75 ms at 9-bit and 750 ms at 12-bit — an 8x difference, and it matches the measured latency split almost exactly. Timed directly:
28-0000048f4a16 res=9 read=1.116s
28-0000048f9ff2 res=12 read=1.777s
I never set this. The probes came from different batches over several years and simply arrived configured differently. The bus had been quietly running at mixed resolution the whole time, and the “slow sensor” I was suspicious of was just the one doing the most precise conversion.
That also reframes the p95 spread: a sweep that happens to hit the four 12-bit sensors back to back is structurally slower than one that does not.
The 24 h per-sensor breakdown answers the clustering question cleanly: failures track resolution, not device. The four 12-bit sensors land at 7.21–8.15 CRC failures per 1000; the four 9-bit sensors at 5.04–6.86. So the higher-resolution probes fail more, but only by ~50%, and the spread is even within each resolution group — no single device is a rogue. That pattern (even across devices, correlated with resolution) points away from a per-device fault and toward something systematic: either the longer 12-bit conversion window, or the bitbanged-driver timing that has more chances to glitch on a slower read. It does not point at one bad probe.
| Sensor | Resolution | CRC/1000 | Median read |
|---|---|---|---|
| temp1 | 12-bit | 7.86 | 0.80 s |
| temp2 | 12-bit | 7.21 | 0.80 s |
| temp3 | 12-bit | 8.03 | 0.80 s |
| temp4 | 12-bit | 8.15 | 0.83 s |
| temp5 | 9-bit | 6.86 | 0.17 s |
| temp6 | 9-bit | 5.04 | 0.13 s |
| temp7 | 9-bit | 5.51 | 0.13 s |
| temp8 | 9-bit | (9-bit group, ~5–6) | 0.13 s |
The 9-bit group’s lower rate is a small, real effect — not the dramatic swing the “resolution = errors” intuition would predict, and the opposite of what you’d expect if higher resolution were the cause of failures. Worth noting honestly: my earlier draft leaned on “higher resolution fails more,” but the measured gap is modest and the cable is still ruled out either way.
Where that leaves the cause
With the cable eliminated by measurement rather than assumption, the remaining candidates for a steady ~15/1000 failure rate on a short, correctly-terminated bus are:
Bitbanged GPIO timing. dtoverlay=w1-gpio bit-bangs 1-Wire in the kernel with no
hardware timing guarantee. Any interrupt or scheduling delay during a read slot corrupts
the bit. On a Pi doing other work this is the leading suspect, and it predicts errors that
are random in time rather than concentrated on one device.
Cumulative device loading. Eight parasitic-capacitance contributions plus eight sets of leakage add up, even when the cable does not.
Mixed resolution as a stressor. A 750 ms conversion holds the bus in a different state far longer than a 93.75 ms one.
The 24 h per-sensor breakdown separates these: evenly spread failures point at the driver, clustered failures point at a device. The measured result — failures correlated with resolution, even across devices — already leans toward the driver-timing or mixed-resolution explanation rather than a rogue device.
Still to run: pin every sensor to the same resolution and re-run for 24 h. If the CRC rate moves, mixed resolution was a contributor; if it does not, that is stronger evidence for the driver-timing explanation. I haven’t done this yet — it’s the controlled experiment that would close the loop, and I’m leaving it explicitly open rather than declaring a cause I haven’t measured.
The honest uncertainty
I have eliminated the cable with arithmetic backed by a datasheet, and I have a stable failure rate. I have not yet proven what causes the remaining errors — the candidates above are ranked hypotheses, not a conclusion, and the experiments that would separate them are listed as they occur.
What I am confident about: on a 2-3 m bus, swapping the pull-up is not the fix, and anyone telling you to reach for a 2.2k resistor before measuring the failure rate is guessing. Count the CRC failures first. It costs nothing and it tells you whether you have a signal-integrity problem at all.