Intro: Fault-Tolerant Temperature Sensor Network Controller
This Instructable shows you how to convert an Arduino Uno board into a single-purpose controller for a set of DS18B20 temperature sensors capable of automated isolation of faulty sensors.
The controller can manage up to 8 sensors with Arduino Uno. (And much more with Arduino Mega or with a slight software modification.)
Step 1: Story Behind...
A couple of years ago I set up a DS18B20 temperature sensor network in my father's greenhouse for my pi-based heating controller. Unfortunately, reliability of the controller was poor mainly due to frequent sensor outages. I tried multiple setups - parasite power, direct power, connecting the network to pi as well as connecting it to Atmega-based custom board (which primary purpose was to drive valve motors).
What worse, sensor network reliability dropped mainly during winter nights while there were almost no problems in summer! What the heck is going on here?
To investigate which sensor causes the problem, there emerged a need to turn them on/off one-by-one or enable any combination of them.
Step 2: How It Works
DS18B20 (the temperature sensor) uses proprietary 1-wire protocol that allows multiple sensors to share common data link (that one wire). This common data link is connected to one of Arduino's GPIO pins and to + 5 V via a pull-up resistor – nothing uncommon, many instructables cover this setup.
The trick is that each sensor's power leads are connected to own (dedicated) GPIO pins, so that they can be switched on and off separately. For instance, if a sensor has Vcc lead connected to pin #3 and GND to pin #2, setting pin #3 to HIGH provides power for the sensor (no surprise) while setting pin #2 to LOW provides ground (a litte surprise for me). Setting both pins to input mode will (almost) completely isolate the sensor and its wiring – no matter what failure (e. g. a shortcut) happens inside it, it will not interfere with the others.
(Fair to say that connecting the data wire to something else connected somehow to Arduino will indeed cause interference, but it is almost impossible in my setup).
Notice that DS18B20 consumes up to 1,5 mA while one Arduino pin can source / sink up to 40 mA, so it is perfectly safe to power sensors by GPIO pins directly.
Step 3: Material & Tools
- 1 Arduino UNO board
- 3 female pin headers: 1×4, 1×6 and 1×6 (or longer – I cut them from one 1×40 header)
- a glue
- a piece of bare cooper wire (at least 10 cm)
- an insulation tape
- soldering consumables (wire, flux...)
- soldering equipment (iron, holders,...)
- small cutting pliers
Step 4: Fix Things Together
Glue the female pin headers to Arduino board headers:
- 1×4 header next to "analog" pin header, side-to-side with pins A0–A4
- 1×6 header next to first digital pin header, side-to-side with pins 2–7
- 1×6 header next to second digital pin header, side-to-side with pins 8–13
Notice that my headers are a bit longer... it has no cons and no pros I suppose.
Step 5: Wire Things Together
Wiring the 1-wire bus line:
- Connect all leads of glued headers on "digital" side (adjacent to pins 2–13) by soldering a piece of bare wire to them
- Solder the end of this wire to SCL pin lead (internally connected to A5)
- Connect all leads of glued header on "analog" side (pins A0–A3) by soldering a piece of bare wire to them
- Solder the end of this wire to A4 and A5 leads (I used A5 and A6 because I have a board that has A6 & A7)
- Solder a 4k7 resistor between the other end of this wire and +5 V pin lead
- Pins A0–A5, although being marked "analog", can be used as GPIO digital pins as well.
- SCL pin on "digital" side is internally connected to A5 on "analog" side; connected to the headers, this forms the 1-wire bus line
- A4 (used as analog input) measures the voltage of the bus for diagnostic purposes. That is the reason why it is directly connected to the bus.
- I used A6 instead of A4 because I have a board that has A6 & A7; originally I wanted to use A7 as the 1-wire bus master but these two pins can not be configured to be digital GPIOs.
- To prevent wrong connection of the sensor connectors you can omit / cut out the unused contact (not connected to any wire) from each male connector and insert it to the corresponding hole in the glued pin header.
Step 6: Connecting the Sensors
You just created an array of eight 2×2 sockets. You can solder and assemble 2×2 Dupont connectors to sensor cables and connect them to these sockets. The software configures the pins so that even pins are GND pins and odd pins are Vcc pins. For each sensor, Vcc pin is just GND pin + 1. One of the other two pins of the 2×2 socket (one of those two in the glued & soldered header) is for the data wire of the sensor. It does not matter which you use.
Step 7: Controller Software
The SerialThermometer sketch runs the controller. You can find it on github. Open and upload using Arduino IDE.
Step by step:
- Open your Arduino IDE and install DallasTemperature library and all its dependencies via Sketch | Include Library | Manage Libraries.
- Clone git repository. If not familiar with git, download and unpack this zip anywhere on your computer.
- Open SerialThermometer sketch in your Arduino IDE.
- Connect your modified Arduino board to your computer by USB cable (standard way)
- Upload the sketch using your Arduino IDE
- Open Serial Monitor via Tools | Serial Monitor
- You should see diagnostic output containing several physical measurements followed by temperature readings – each sensor socket on single line. If sensor count differs when turned on separately and when all turned on together), diagnostic loops until resolved. But no worry, also diagnostic provides temperature measurements!
See annotated picture for more detail about diagnostic output.
Step 8: Conclusion
I have a strong feeling that my sensor network failures were caused by high capacitance of my long wiring – around 10 m of LIYY 314 (3 × 0,14 mm²) cable for each sensor. My experiments showed that communication breaks if there is capacitance around or higher than 0.01 μF between 1-wire bus and ground, i think because 4k7 pull-up resistor is not able to pull the bus to + 5 V fast enough to comply with protocol limits.
In my setup it happens when more than 3 sensors are connected together. Then, the controller loops in diagnostic cycle, measuring temperature sensor-by-sensor (what is cool too...)
But also 5th sensor (28:ff:f2:41:51:17:04:31) looks quite ill (maybe wrong soldering), so I can investigate further!