Temperature is a fundamental physical parameter which can be used to track how water moves and interacts with the rest of the environment. Most waterways in the world are multi use, and temperature sensors are a simple way to monitor rivers and streams, to see how they are being affected by urban pollution, agricultural runoff, solar heating, groundwater exchange, etc. In larger water bodies, we also want to track the cycles of temperature stratification. Sometimes we deliberately disrupt thermoclines with aeration to preserve game fish, but at other times we depend on metalimnion stability to provide a barrier between the E. coli we dump in, and the water we take out for drinking. Monitoring hydrothermal plumes can even shed light on geological activity under the ocean floor.
Temperature is also a key metric of ecological integrity because it exerts a profound influence on aquatic creatures. Many species time their reproduction and migration according to seasonal water temperatures and, as temperature increases, the capacity of water to hold dissolved oxygen is reduced. In coastal environments, temperature and salinity are very strongly associated so you can use it as a reliable proxy to record tidal cycles, and saline intrusion into fresh water habitats.
All of these applications require simultaneous sampling at different depths and locations, so arrays of temperature sensors are a standard tool for addressing water quality issues. Today, many researchers are looking to the open source movement to help make these large installations more affordable. One obvious candidate is the inexpensive DS18b20 temperature sensor because it’s one wire protocol makes it possible to string them together in a daisy-chain configuration. Electronics hobbyists have taken note, and are putting them all over the place with Cat5 network cables. Reading those pages convinced me to take a closer look at the DB’s from the perspective of the Cave Pearl Project: Would it be possible to turn these humble band-gap temperature sensors into something like a research quality thermistor string?
A review of typical commercial options gives you a sense of how much it actually costs to build a network of temperature sensors:
|0.10°C ±0.70||Thermochrons have made a new class of low resolution networks possible, with large #’s of sensors (Note: You need to coat these guys in PlastiDip if you are deploying them outside, as they are not really waterproof)|
|Hobo Water Temperature Pro v2||$129.00
|0.02°C ±0.21||Here is an interesting USDA study using TidbiTs which have identical cost & spec.|
|NexSens T-Node FR||$250/node + $150/cable||0.01°C ±0.075||Typical of high end sensors used in large well funded projects at NOAA, etc.|
The iButtons are basically disposable, and I don’t think it would be worth anyone’s time to make them from scratch if all you need is 0.10±0.7°C. But if you need more precise information, a simple 10 node string puts you around $1500 in the mid range, and $4000+ at the geotechnical high end. Factory calibration of 0.0625 ±0.5°C puts the DS18B20s somewhere between the Hobo loggers and the low end Themochrons. But with each sensor on the same chain, you would be able to keep all the sensors synchronized better than stand alone units. After seeing the elegant pro-level system, I knew I also wanted something that could be assembled from interchangeable segments, to customize the chain for each installation.
I googled and grazed my way through various YouTube videos, instructables, etc. looking at how others had water-proofed these sensors. After digesting that, I produced a some prototypes using a modified version of my underwater connector idea that have the DS18b20 potted in an irrigation pipe coupling:
The 1-Wire Address Finder and the library from Miles Burton work well with this changeable configuration. I preferred the code over at Paul Stoffregen’s site, as it gives you the raw integer reading, the ROM address, and the temp in °C as soon as you connect a new sensor. But like most of the scripts that uses address arrays, it will read them in numerical, rather than physical order. So you will eventually end up hard coding the Rom addresses unless you switch over to something like the DS28EA00 that supports sequence detection through a chain mode function. This allows you to discover the registration numbers according to the physical device location in a chain, and if the DS28 also had better resolution/accuracy than the dirt cheap DS18’s, I’d be converted.
The one-wire guide at the Arduino playground has a most valuable tip for driving a string of sensors like this:
“The master can address all devices on the bus simultaneously without sending any ROM code information. For example, the master can make all DS18B20s on the bus perform simultaneous temperature conversions by issuing a Skip ROM [CCh] command followed by a Convert T [44h] command.”
This means that I can minimize the number of times the Arduino has to wake-up for each set of readings. But these sensors are still going to pull about 1.5 mA each during the 750ms 12-bit conversions, so there is going to be a substantial power demand during each set of sensor readings even if I put the μC to sleep while it waits for the data. (and you can only sleep if you are not using parasite power) Thirty or more sensors on the bus will also generate allot of communication and data buffering. I have no idea yet how much juice all that is going to take so I built some larger housings, with room for twelve AA batteries, to drive these long daisy-chains:
Maxim has guidelines for reliable long line 1-wire networks which suggests that longer networks need 100 Ω resistors at each node for distributed impedance matching or you could run into timing/reflection issues. As I am working in reasonably restricted cave environments where the floor to ceiling distances rarely exceed 20m, I did not add these resistors. If I start seeing the dreaded 85°C error after I load the bus, I will try a lower value pullup resistor, or perhaps a barrier diode. There is even an I2C to one wire bridge out there that can adjust the strength of the pull-up dynamically as your network grows, although since the one-wire bus is so easy to get running, I would only cobble the two networks together if I had an unusual situation.
The sharp eyed will note that there are four conductors on that interconnect. I used four conductor cable for added strength because silicone jacket cables are so soft and floppy that the sheath really provides no support at all. And this offers the potential for a second one-wire network that is separate from the first if communication errors start to appear. Alternatively, I could add other one wire devices to that second line for more functionality. I have not figured out what this might be yet, but perhaps I could include some kind of leak detector to make the system more robust. I am also keeping an eye on the one-wire weather station crowd to see if an interesting sensor pops up there. And finally, I wanted a four wire connector that could also be used with I2C breakouts, as most of my other builds use sensors with that protocol.
I have replaced the cable that came with the “waterproof” DS18B20 sensors, as the insulation was far too thin for the rough handling I expect to see and the 28awg wires would add significant resistance over a long run. But silicone jacket cable is expensive and I am still searching for an affordable 24awg, 4-conductor option. (If you have a suggestion, please pop it in the comments!) The PVC and Poly-urethane jacket cables I have tried so far are just too stiff to “hang right” under water without a weight on the line, and this would put strain the data connections. The standard solution is to run a suspension wire alongside the thermistor string with the data lines connected to this armored stiffener. While this works great off a boat or a buoy, I would prefer not to have to deal with those extra components on a cave dive.
After addressing the issues with the physical build, I still have an elephant standing in the corner. While an accuracy of ±0.5°C might be good enough to track the refrigerator in the garage, ±0.1 °C is about as coarse as you want to go for research applications. So a lot of the burden of making this thing really functional will be the calibration. If you replace the Arduino’s 10-bit ADC, then there are thermistors that give you ±0.1°C right out of the box, and I would like to get these DS18b20’s into that ball park before I say the newest addition to the Cave Pearl family is ready to deploy.
Maxim has a document describing how to curve fit the error of a band-gap based digital temperature sensor with 2nd order polynomials to achieve accuracies in the 0.02-0.04°C range, but they make the assumption that you already have a NIST traceable platinum RTD to determine what the errors actually are. But what if you don’t have that $5-600 piece of kit just lying around? (+another $150/year for the required annual re-calibration) Is there any other way to calibrate temperature sensors like this to improve their accuracy?
Actually, there are verification procedures that use the ice and steam points of water, and I will detail my attempts to use these “old-school” calibration methods in the next post. In theory at least, these intrinsic standards can bring our DS18b20’s well within a mid-range accuracy target of ±0.2°C. At the end of it all I will try to borrow a certified pt100 to see how close I actually got.
After handling that long chain for a few days of calibration, I realized that I needed to mount those sensors with a much smaller physical profile or they were going to be a pain the backside under water. So I came up with a simple combination of heat shrink tubing and epoxy that keeps the sensor much closer to the cable than a hard-sided mould:
The trick is to seal one end of the clear tubing first, and then inject the epoxy into that from the open end. Once the tube is about 2/3 full 0f epoxy, shrink the upper open end of the tubing down to it’s minimum diameter. Very gently heat several spots along the tube – as those areas contract it pushes the epoxy up toward the open end. Then wipe away any excess so the meniscus is level, and seal the upper end of the outer tube to the cable with a short section of adhesive lined heat shrink tubing, making sure that you trap as few bubbles as possible. I usually use adhesive lined heat shrink for those two end tubes, and I let the upper ring completely cool so that if forms a good seal before heating the rest of the clear heat shrink tube. I usually use Loctite E-30CL epoxy as this sets much more quickly after the reheating process, often becoming hard in about 30-45 minutes. This approach to mounting the sensors would also work with ‘naked’ Ds18b20’s, but having the sensors already mounted in the stainless steel sleeve makes it much easier to do the ice & steam point calibrations before you commit to actually using a particular sensor. At only $1.50 each, you should expect to triage at least some of them for being out of spec.
Completely encasing the sensor like this will induce some thermal lag, if you are really worried about that you could make the tubing shorter and not seal the upper end, leaving the metal sleeve exposed. If field handling indicates that the hard epoxy is too brittle, I will hunt around for a flexible amine curing silicone, or a low durometer clear urethane, to fill the nodes (typical hardware store silicone gives off acetic acid while curing which is bad for electronics)
With more handling, those epoxy filled tubes did end up feeling a little fragile at the thin ends, so I reinforced them with a few more wraps of adhesive lined 3:1 heat shrink tubing:
In addition, I decided to make the chain in 2m segments, with sensors at fixed distances along each segment. This reduces the total number of joins in the cable, while still allowing for custom configurations. In the photo (below) you can see that I used a longer piece of pipe in the segment connectors than was necessary. My hope is that if I distribute some buoyancy throughout the chain there will be less strain on the segment nearest to the datalogger. Those segments will be bearing the weight of the whole sensor string because the logger will most likely be mounted on the ceiling of the cave passages. The real test will be when we actually install them, as there is always some unforeseen factor that comes into play under water.
I just came across a great write up by someone using DS18b20 sensors to track ocean temperatures over in New Zealand. (I knew I couldn’t be the only one…) Interestingly, he uses a star configuration for the sensor connections. While this is much faster to connect than the daisy-chain approach I have taken, it looks like he ran into some problems with his long cable runs and had to use a very strong 480Ω pullup resistor. There are plenty of photos, and a good explanation of how he used normalization to smooth out between-sensor variations. While this is helpful for tracking relative changes in temperature, it does not necessarily improve the accuracy of these sensors.
I have been putting more segments together for a second prototype. For the newer nodes I used Loctite U-09FL urethane. This stuff is less brittle than the epoxy after curing, however it sets almost immediately when you apply the heat to the shrinkable tubing. The result is that the nodes didn’t “smooth out” like they did with the epoxy, and so they ended up looking like clear Jello raisins. You can’t be too aggressive with the heat gun or the outer sheath splits, making a bit of a mess.
Once I had enough segments ready I did some tests to see how far the chain could be extended before the coms failed. Line capacitance appears to be the controlling factor on these kinds of networks and most try to keep it low for maximum distances, or better performance. But I am packing quite a few DS18’s close together, so the sensors themselves are more likely to limit my system. With 15 minute sample intervals being typical for an environmental monitoring application, I could even look into slowing down the bus, rather than speeding it up.
With a standard 4.7 kΩ pullup, I was able to get to 30 sensors responding well on 12m of 4x 26awg silicone jacket cable. Changing the pullup to 3k3, allowed me to add 15 more sensors on an extra 8m of cabling. And taking the bus to a fairly aggressive 2k2 let me add 19 more sensors and an additional 7m of cable. So my add-hock test reached a total of 63 daisy chained nodes on 27 m of cable before the readings became unstable. I did not see 85°C errors, but when the network approached the R-C rise time limit, the readings started looking like this: (in a room at 20°C)
Probe 0 Temp Raw: 268 Temp C: 16.238
Probe 1 Temp Raw: 288 Temp C: 18.0
Probe 2 Temp Raw: 16 Temp C: 1.0
Probe 3 Temp Raw: 322 Temp C: 20.125
Probe 4 Temp Raw: 332 Temp C: 20.238
Probe 5 Temp Raw: 113 Temp C: 7.62
Probe 6 Temp Raw: 323 Temp C: 20.187
Probe 7 Temp Raw: 280 Temp C: 17.244
Probe 8 Temp Raw: 324 Temp C: 20.250
Probe 9 Temp Raw: 17 Temp C: 1.62
Probe 10 Temp Raw: 256 Temp C: 16.0
Probe 11 Temp Raw: 320 Temp C: 20.0
Probe 12 Temp Raw: 66 Temp C: 4.125
Probe 13 Temp Raw: 24 Temp C: 1.244
Probe 14 Temp Raw: 32 Temp C: 2.0
Probe 15 Temp Raw: 268 Temp C: 16.238
Probe 16 Temp Raw: 320 Temp C: 20.0
Adding a couple more nodes after that caused the reads to completely fail. The numbers then become zeros because I use memset(rawTemps,0,sizeof(rawTemps)); to clear the temperature reading array after the data has been transferred to the eeprom buffer. Doing this between readings makes it much easier to spot when sensors drop out.
Thirty sensors is a bit tight for my application, so I will remove the 4.7K resistors I have on the loggers now and make an in-line adapter that lets me change the pull-up on the fly if a particular installation starts giving me grief. But going much larger than 10m & 30 nodes might be putting too much data at risk if we have a point failure. Another limitation on the practical side is that my FTDI USB adapter can only source about 50 mA, so I can’t use the skip ROM command to trigger temperature conversions on more that about 33 sensors before I risk hurting the chip during tethered test runs.
We recently had a chance to test the first prototype (with the separate individual nodes) out in open water. To make sure the connections were up to the challenges of “normal” fieldwork, I let students handle & install the unit, with no specific instructions other than letting the last sensor just rest on the bottom. (yes, I cringed a few times…) The lowest sensor was at 6.5m depth, and the unit gathered temperature data in a saline water outflow for about 7 hours with no leaks or problems. On the same trip we also deployed two “clear epoxy tube” chains in a different cave system spanning depths from 7 to 14m. I don’t have any photos as that deployment was significantly deeper, and beyond the reach of our little point & shoot. Both of those carried 12 x AA batteries, and the plan is to leave them running in-situ till mid year, at which point I should have a pretty good record of power consumption of these long sensor strings.
I mentioned using E00CL epoxy earlier, but have since gotten back some cave deployed RH sensors that all failed due to moisture permeability on the E05CL epoxy I used to build them. And those humidity sensors were not even under water! So for future builds, I will stick with E30CL. It’s gooey to work with, but I have several units that have been under water for more than a year using that epoxy.
The single sensor chain in the photo above ended up coming home after the field trip, and since it was just sitting there, I set it up on the bookshelf for a power drain test:
Because the DS18’s run on fumes when they are not doing a conversion, this logger slept at 0.11 mA. The units currently in the field have more sensors and longer cables, but seeing that less than half of a three cell battery’s capacity was used on this two month run gives me confidence that the 12 cell loggers we deployed had far more power than they needed. So the only real question is how long they remained water tight* with the crummy epoxy used on some of the nodes. If I am lucky, the marine heat shrink tubing I used for physical re-enforcement will have provided a water tight seal on those ends.
P.S. * Those deployed units survived their first underwater test and worked brilliantly. For more details click HERE
Just an update to that 20-node DS18B20 sensor chain’s power test:
So we have already done five months on 3xAA battteries, confirming that those DS18B20s are very nicely behaved sensors in terms of their overall power consumption. But that P.S. curve is bumpier than I am used to seeing from alkaline batteries read with a 2x 4.7M ohm divider, so I might go digging on what causes that to happen. It could just be that simultaneous temperature conversons ( 20 sensors x 1.5 mA x 750ms ) is enough of a load that the batteries feel that hit.
Just an update regarding a problem we ran into on some deeper deployments of 24m x 24 node DS18b20 chains. I’d been running those with 3k3 pullups and they passed all run tests at the surface – but those strings suffered a slow progressive read failure after about five months between 20-50m depth. This was a slow bus failure, and the tidal cycle showed up clearly as the sensors fell off, and then rejoined the set. My best guess is that the soft silicone jacket on the cable became progressively more compressed over time, and this raised the bus capacitance just enough to push the timing out of spec. Adding a second pull-up to the end of the bus brought all the sensors back on line, so my recommendation is to stick with ~2K pullups if you build longer chains like this. Harder PUR insulation cable jackets might also have prevented this very tricky problem.