I'm trying to build a thermometer for my car and I need some help with ideas on how to detect errors when reading the DS18b20.
Here is the situation:
The circuit is used in a harsh automotive environment
I'm using an Arduino Uno with a 16x2 LCD
It works fine and shows the temperature, no problems here
Since the circuit is used in a car, once in a while I get errors when reading the sensor.
What I'm trying to accomplish:
I want this thermometer to look "professional" and so I'd like to be able to detect those errors.
When I simply disconnect the DS (or its data line) I get a -127C reading and that results in an error message being displayed. Instead of the -127 I get a "Sensor error!" on the display. Works great
BUT
When I only lose power to the sensor (positive or negative) the Arduino gets crazy readings and I don't know how to identify this as an error condition. I use long wires, going through to the engine compartment and power to the sensor is supplied from the car's OEM wires. So, losing just the power supply is very possible (chafing, corrosion, blown fuse, etc)
I get values like -127, 85, 0 and some random numbers in between.
My idea was to read the temperature and compare that reading to two previous readings and signal an error if the difference was larger than 15 degrees. Unfortunately I can't get that to work and I either get "Sensor error" all the time or no error and just crazy values.
Please post your ideas on how to detect an error condition when Arduino gets crazy readings like that.
I appreciate any and all help on the subject.
Ideas with some code that I can use are even more appreciated. "More better" is always better
If you are getting consistent correct readings and only occasional errors, can't you simply ignore them?
The sensor can be read every second or so. This time should not effect what you want. What you can do is read the sensor and average over the previous 5 readings, ignoring readings that are more than say 20% out of range with the average.
The occasional errors are not really my concern. What I'd like to do is have the LCD say "Sensor error" when the readings are wrong. Lets say that the DS loses its power supply because the wire broke. I'd like to be able to detect an error state. Right now I just get a bunch of wild readings.
Ignoring bad readings is one thing, detecting them and displaying "error" is what I'm trying to do. What type of detection would you suggest? I would greatly appreciate some sample code... if you don't mind
Thanks!
weedpharma:
If you are getting consistent correct readings and only occasional errors, can't you simply ignore them?
The sensor can be read every second or so. This time should not effect what you want. What you can do is read the sensor and average over the previous 5 readings, ignoring readings that are more than say 20% out of range with the average.
Weedpharma
yeah but to compare a reading to calculate the average you need the average. There is some snake biting its own tail.
But weedpharma has the right direction. You could use the previous temperature as reference to see if a new measurement is valid. And the good thing is that one read should be sufficient, no need to average them.
Alternative do 5 (odd nr) readings and use the median ( the middle value when sorted).
robtillaart:
yeah but to compare a reading to calculate the average you need the average. There is some snake biting its own tail
Using a running average in a system that has mainly good data would not take long to have a reliable average.
The program simply has a setup loop of say 10 reads while taking the running average of 5 reads. The main loop then keeps taking a running average to compare with new readings. If the reading is outside the specified range from the average, it is an error and not included in the average calculation.
The running average would allow the temperature to vary with the temperature being read.
Thank you guys for your suggestions.
Averaging is not needed and actually unwanted in my application. I need to rely on single readings. Then, when the reading is wrong (broken sensor, broken wire, etc) I need to report an error.
I am taking readings once every second.
I will try the approach suggested by Weedpharma of counting errors that are outside of allowed limit. I recon that 10 degrees C is wide enough margin to prevent false triggering.
One sensor is reading my engine temperature and I don't believe that it can rise more than 10 degrees in one second. Well, if it does, the readout is going to be the least of my problems
But there is still one issue I can't figure out...
Quite often I get a reading of 85C which is an error but it falls within the limits of normal engine temperature. Lets say that my engine is at 94C and suddenly the sensor gives me a false reading of 85C. It is within the set limit of 10C so the error condition will not be detected. I'd like to control my cooling fan with this circuit and this will leave a very small margin of error - the fan comes on at 96 and switches off at 93.
Any suggestions? Are there any "secret" methods for detecting wrong readings? I've spent hours googling but could not find any good solutions.
For several reasons (one of which you have discovered), the DS18xxx is a very poor choice of sensors for an automobile. A ruggedly constructed thermistor is what most people use.
The automotive electrical environment is extremely harsh, with occasional voltage spikes of several hundred volts, easily destroying unprotected circuitry. Proper shielding and spike protection is required on all signal leads and adequate power conditioning for the main circuitry is essential.
I couldn't agree more. But, there's always that "but"
On one hand the DS sensor is a very poor choice because data transmission can be fairly unreliable due to noise and voltage spikes. On the other hand this is a much better choice than thermistors because resistance in transmission lines (wires, connectors, poor and corroded contacts) will make that analog reading very unreliable. There might be fewer (or no) errors but I will never know if the temperature I see is real or not. I need to be sure.
There's another sensor I thought about using - LM134. It is a current source, analog, that varies the current depending on the temperature. The problem is that those things are pretty darn expensive and hard to get.
If you guys have any suggestions, please don't be afraid to speak up
Jamesik:
. . . data transmission can be fairly unreliable due to noise and voltage spikes. . .
If this is the root cause of your problem, perhaps it would be better to try to suppress the presumed noise and voltage spikes rather than clean up the resultant mess in software.
What does your wiring look like (harness length, are you using parasitic mode or a 3-wire interface, is the harness twisted pair for signal and ground, . . .)?
Automotive 12 Volts is pretty noisy, but if there is significant noise on the regulated Arduino 5 V or your signal line, it got there via coupling in the wiring.
I'd recommend using the 3-wire configuration over parasitic mode, have the harness wires twisted or use a two twisted pair cable (telephone wire) with signal/gnd and +5 V/gnd, and using the lowest value pullup resistor allowed by the component specs (1.5 k ohm or so).
A thermistor can still be used with a 4 wire system.
You use one pair to from a constant current source.
The other pair, you run to your measurement system.
It is also easier to detect a broken or shorted wire.
Dwight