Cold-chain temperature monitoring with ESP32 and DS18B20

By , Founder · 12 min read · Published

A fridge full of stock fails quietly. The compressor stops on a Friday evening, the door seal lets go, or a breaker trips, and nobody notices until the morning, when everything inside has to be thrown away. Cold-chain monitoring exists for that moment. A chart of yesterday's temperatures is useful, but it isn't the point. The point is a message to the right person while there's still time to move the stock. This guide covers building that with an ESP32 and DS18B20 probes: the temperature ranges to design around, what the probe can and can't measure, where to put it, how to set alerts that don't fire every time someone opens the door, and what records are worth keeping.

The ranges to design around

Every cold-chain setup starts with the range the stock has to stay inside. These are the common ones:

What's stored Must stay Source
Refrigerated vaccines 2 °C to 8 °C (36–46 °F) CDC Vaccine Storage and Handling Toolkit
Frozen vaccines −50 °C to −15 °C (−58 to +5 °F) CDC toolkit
Chilled food in shops and restaurants 5 °C (41 °F) or below US FDA Food Code
Frozen food −18 °C (0 °F) or below USDA

These are US figures, checked October 2026. Other countries set their own, and some products print a narrower range on the label, so use the rule that applies to you. Two design decisions follow from the range:

What a DS18B20 can and can't tell you

The DS18B20 is the usual probe for a DIY cold-chain monitor, for good reasons. The waterproof stainless-steel versions on a few metres of cable are cheap. Each chip carries a unique 64-bit code, so many probes can share one data wire. And it sends a digital reading, so a long cable doesn't add analogue noise or need its own calibration.

Read its datasheet before you trust it in a freezer, though:

Datasheet figure Value What it means here
Accuracy ±0.5 °C from −10 °C to +85 °C Fine for a fridge at 2–8 °C
Accuracy over the full range ±2 °C from −55 °C to +125 °C A freezer at −20 °C is outside the ±0.5 °C band, so leave a wider margin
Resolution 12-bit (0.0625 °C) by default Much finer than the accuracy: the extra digits aren't extra truth
Conversion time at 12-bit 750 ms at most Irrelevant at cold-chain sample rates
Value at power-up +85 °C A reading of exactly 85.0 means a conversion didn't run, not that the fridge is hot

Two more things decide whether the numbers on your screen mean anything:

Wiring DS18B20 probes to an ESP32

1-Wire lets many probes share one GPIO pin, which is the usual way to wire several cabinets to one board. A few rules keep the bus reliable:

Then work out which probe is which. A 1-Wire bus doesn't number probes by their position on the cable. It finds them in the order of their 64-bit codes, and most software numbers them in that order, so "sensor 1" isn't necessarily the one nearest the board. Warm each probe in your hand in turn, note which reading rises, and label both ends of the cable. Do it again whenever you replace a probe, because the new chip's code can land anywhere in the order and shuffle the numbering. Giving each probe its own pin avoids the problem entirely, and an ESP32 has more free GPIOs than most rows of cabinets need. The Synacl setup below does exactly that.

Where to put the probe

Where the probe sits matters as much as the probe itself:

Alerts that fire for the right reasons

The usual failure of a temperature alarm isn't a missed excursion. It's an alarm on raw air temperature that fires every lunchtime, until someone mutes it, and then misses the real failure. These rules keep alerts worth reading:

  1. Use two bands. A warning at the edge of normal, for example 7 °C, goes to a dashboard or an email. A critical alarm at the limit, 8 °C, goes to a phone. Someone glances at the first and acts on the second.
  2. Let the buffer absorb door openings. With a buffered probe, a door left open for a minute barely moves the reading, so the alarm doesn't need a delay. Without a buffer, the alarm needs a condition that has to last, such as "above 8 °C for 15 minutes", or a higher limit for short spikes.
  3. Alarm on silence. The failure that spoils the most stock is a power cut, and a power cut takes the monitor and often the Wi-Fi router down with it. A monitor that only alarms on temperature says nothing at all. "No data from this unit for a few minutes" has to be an alarm in its own right, raised by the server rather than by the device that just lost power.
  4. Send the all-clear too. "Back in range after 23 minutes, warmest 9.4 °C" is what you need to decide whether the stock is still usable. Without the end of an excursion, you only know it started.
  5. Make someone own it. An alarm at 3 a.m. goes to whoever is on call that night, with a second person if the first doesn't respond.

Records worth keeping

When something goes wrong, the questions are always the same: when did it start, how long did it last, how warm did it get, and what did you do. A good log answers them without anyone having to reconstruct it:

Setting it up on Synacl

The Synacl gateway firmware reads DS18B20 probes over 1-Wire, and the DS18B20 catalog entry fills in the connection settings. Flash an ESP32 from the web flasher, pair it with your account, and then build the monitor like this.

One probe per pin, one device per probe. Add each probe as its own 1-Wire device on its own GPIO, each pin with its own 4.7 kΩ pull-up. The firmware can read several probes on one pin, but it matches them to tags by their position in the bus search, and it searches again on every read. If one probe on a shared pin dies, the probes after it move up a place, so their readings land on the wrong tags, and the last tag keeps showing its old value. With one probe per pin, a dead or unplugged probe turns that device amber and raises a device/offline event marked as a fault, which is something you can alarm on. The app refuses a pin that another device on the same gateway already uses, so you can't double-book one by mistake. See connecting a 1-Wire device for the fields.

Name the tags after what they guard. Call every fridge tag fridge_temp and every freezer tag freezer_temp. A rule can watch one device or every device with a given tag name, so one rule then covers every fridge. Its cooldown runs separately for each device, so one failing fridge doesn't silence an alert from another.

Read once a minute. A sample interval of 60 seconds (sampleIntervalMs: 60000) is plenty for a cabinet. The gateway sends its own heartbeat about every 10 seconds, so slow readings don't make a device look offline. Your plan sets the fastest interval allowed, and the pricing page lists it.

Two rules for the two bands. A threshold rule compares one tag with one number:

Rule Condition Action Severity
Fridge warning fridge_temp > 7 Email warning
Fridge critical fridge_temp > 8 Push to the mobile app critical
Fridge too cold fridge_temp < 2 Push to the mobile app critical
Freezer critical freezer_temp > -15 Push to the mobile app critical

Rules run in the cloud on every reading, and while the condition holds they fire again each time the cooldown runs out, so a warm fridge keeps reminding you instead of alerting once. Push goes to the account owner and every team member with the Synacl app. Quiet hours in the app mute everything except critical, which is why the rules that should wake someone are set to critical.

Two more rules for silence. Add event rules on gateway/offline and device/offline, with email or a webhook to whatever pages your on-call person. A gateway that loses power is marked offline within a few minutes, from its MQTT last will or, if that never arrives, from missed heartbeats. Its devices go offline with it, but they share the gateway's cooldown, so a dead site sends one alert per rule, not one per probe. The online status article explains every state.

Tag limits as a second line. On paid plans you can also set an alarm band on the tag itself, for example 2 °C to 8 °C. The gateway then checks each reading on the board and logs one alert when the reading leaves the band and another when it comes back, which puts the start and end of each excursion in the event feed. Rules don't send an all-clear, so this is where the end of an excursion is recorded. Use the rules above as the alarm, though. A limit alert raised while the gateway is offline is lost, while a rule re-checks the first reading after the gateway reconnects. See alert thresholds.

For the screen on the wall, a value card and a trend chart per unit plus an uptime strip cover it (build a dashboard).

What Synacl doesn't do, so you can plan around it:

If you haven't wired anything to an ESP32 yet, flash an ESP32 from your browser gets the gateway running in a few minutes, and IoT device uptime monitoring goes deeper into offline windows and alerts on silence.

Try it on your own hardware

Synacl is free for five devices — no card, no sales call. Flash a gateway from the browser, add your first device, and see live data in a few minutes.