Our digital world is sometimes fed information by fuzzy-input sensors. How do we deal with those?
Digital sensors seem to make life easy for makers. Plug a DHT module in, and you rapidly receive accurate, digital-ready information about the temperature and humidity where the module is.
However, what many makers don’t realise is that digital simplicity is part of the module itself, rarely the actual sensor.
Just as a digital multimeter uses a thermocouple input to a digital readout, the sensor element doing the heavy lifting is actually analogue in its function.
Look closely at your DHT11 sensor module if you have one. Depending on the design of the module itself, you’ll usually see two other components on the PCB for the module. In addition to the plastic-enclosed sensor module, there’s a tiny Analogue to Digital converter onboard, which rapidly and consistently converts the analogue values into digital values.
Occasionally, all of these components are housed within the plastic case of a DHT and you won’t see anything at all, but rest assured it’s there!
NOT EVERYTHING IS ANALOGUE
It’s important to note that some sensors are indeed natively digital. A rotation sensor may be like a rotary encoder, providing digital pulses to provide rotational information. However, the lines between analogue and digital become blurry when what appears to be a simple sensor, may indeed be something more complex. A sensor monitoring angle of a robotic arm, for instance, could simply be a potentiometer, with a small chip doing some conversions.
Many sensors use advanced electronics along with an analogue sensor of some type (such as a thermocouple) to provide a digital output using an onboard ADC chip. This results in an apparent digital sensor as far as interfacing goes, even though the single component doing the actual measurement is analogue.
BRINGING THE ANALOGUE INTO DIGITAL
As is true in many applications, we all love to have a clean multifunction display.
One of the ideas we had for a project was to build a digital dashboard for engine monitoring, which is something we’ve pondered for some time. However, digital sensors for modern cars are obscenely expensive.
While many modern engines use digital sensors and advanced electronics, many engines for other uses do not afford the same technical inclusions. Most notably those used in boats, go karts, project cars, and similar, where the electronics tends to be less sophisticated than those found in modern vehicles.
Discrete chips are available to do our analogue to digital conversion, but an Arduino does the same job using the onboard ADC too. It keeps things neat and we can code our way into just about any solution we want.
This brings us to the overall point of this issue’s What The Tech... cleanly converting analogue sensors to a digital value with an Arduino.
MICROCONTROLLERS IN A VEHICLE’S WORLD
There’s a disparity between an engine system and a microcontroller. While most microcontrollers are happy to run between 3 and 5V, most vehicles run on ~12V (in reality more like 13.8V). This creates a few challenges for us, as we have to ensure our sensitive electronics is protected against these higher voltages.
Vehicles and engines can inherently be noisy environments when it comes to electrical noise and interference, so we want to keep things as straightforward as possible to help avoid problems with bad signals.
ADAPTING 12V SENSORS FOR 5V SYSTEMS
We’re starting our journey with what is (for all intents and purposes) a fairly standard analogue temperature sensor.
The sensors we are looking at have a common electrode that is physically screwed into the block of the engine. The other terminal is connected to the internal electronics, albeit a variable resistance of some type. In this case, they are isolated from the 12V, however, this is not the end of the story.
The way these gauges are intended to be used is as a variable current-limiter for a traditional analogue gauge. Just as you do the math to select a resistor for your favourite LED, you can change its brightness by using a different resistor. A resistor with a higher resistance value will still allow your LED to illuminate, just a little duller than if you use the one required for full brightness.
These sensors are designed to deflect an analogue gauge coil in a similar way. The lesser the resistance the higher the gauge will read, due to the greater current allowed through the windings.
Things aren’t QUITE as straightforward using an ATmega’s ADC. If it were, we could easily just connect our digital pin to one side of the sensor, ground to ground, and we’re off.
The solution is still quite straightforward however by using a voltage divider. This can actually serve two purposes for us. Creating a voltage drop across the sensor, and setting an upper limit for the voltage that can be fed to our detection pin (naturally, 5V).
To do this, we’re going to create a reliable voltage reference, then create our voltage divider.
VOLTAGE REGULATION AND DIVISION
Since a vehicle’s voltage is variable (anywhere between about 11.8V and 14.4V), we can’t reliably use it as a voltage reference. If we assume that it’s standard 12V, it’s going to be inaccurate.
Note: for simplicity, we’re ignoring that some vehicles are 24V powered. This same theory is adaptable to 24V systems, however providing numbers for both makes things quickly confusing.
A simple way for us to create a stable voltage reference is by using an LM7809 voltage regulator. This regulator will provide us with a 9V steady voltage reference, which is tolerant of the wide input range of a vehicle system.
Having a stable voltage instantly makes things easier, and we can calculate the best value for the resistor required to go inline with our sensor. While most of our sensors never fall to zero-ohms (i.e. short circuit), if we use this for our calculations we can ensure that voltage on the connection to the Arduino never rises above 5VDC.
To determine an ideal value for the resistor that will be in series with our sensor, we need to determine the maximum resistance the sensor will present. In the case of our temperature sensor, that is 2000Ω at 0°C.
Obviously, a running engine won’t be anything like this temperature, but at start-up in Winter, it may well be. Remember, we need to “keep the smoke in”. If we make our series resistor a value of 2000Ω, it ensures that a maximum of 4.5V will be presented to the Arduino’s ADC, and allows a little tolerance in the resistance value of the sensor. One sample to the next may well be different.
We have dealt with 12V in our Arduino circuits before (often when interfacing motors and such) using optocouplers (also called optisolators or optical couplers).
An optoisolator is a fantastic device for electrically isolating two different systems. We can have our 5V Arduino system, and our 12V vehicle system, and they can talk nicely between each other without any fear of the fire and destruction that can come from 12V on an ATmega.
Indeed, they’re also often used to filter noisy electrical signals, or provide a safety barrier when mains power meets USB power, for instance.
However, optocouplers are primarily for digital applications where they’re either on or off. While optocouplers can indeed be used in analogue situations, it can become complex and unreliable, especially as the electronics age. We may explore this option further down the road, but for this purpose, we’ll keep it simple.
MAPPING BASIC ANALOGUE SENSORS
The two sensors we are looking at give a variable resistance in response to change of temperature or oil pressure respectively. These are arguably the most common and fundamental sensors on an engine.
If the oil pressure drops below a certain point, or the temperature increases beyond a certain point, it’s bad news very quickly!
An Arduino can’t directly measure current or resistance, but it can measure voltage with the on-chip Analogue to Digital Converter (ADC).
Assuming we power our Arduino from +5VDC (fairly standard for an UNO or similar), the ADC can give us a digital value between 0 and 1023 for an input voltage of 0V to 5V.
CHOOSING THE SERIES RESISTOR VALUE
This now leaves the problem of how to select an appropriate series resistor, and this relies on the range of values that we can expect from the sensors. The temperature sensor has the following specifications:
- Resistance: 300Ω at 40°C to 20Ω at 120°C
- Temp accuracy +/- 3°C
- Temp response time, minimum 3 minutes after power up
- Rated voltage 6-24V
- Connects to MGG505/506 gauges
We did our own tests and found the following:
In case you were wondering how we measured the resistance at 0°C, we put the sensor on ice. 25°C is about the office temperature, and 33°C is the temperature of human skin, so for this, the sensor was held in our hand with caution to not connect our skin in parallel with the sensor. Obviously, we used very hot water to measure the resistance at 100°C.
Getting back to how to select the value of the series resistor in the voltage divider, we can see that we need to be able to handle resistance values from 2000Ω, down to something less than 70Ω. The minimum value doesn’t really matter as at that point the ADC will give us low values. If we say that 512 values are enough (that’s about 5 per °C), then we need a series resistor of about 2kΩ. Measuring the voltage at the junction of 2 × 2K resistors will give us mid voltage, hence mid-ADC value. In any case, we could divide the ADC value by 5 and have pretty much a 1° resolution.
Note: The temperature and resistance values in the chart and table above were obtained with a thermocouple and DMM.
A Thermocouple is a joint between two dissimilar metals, that acts as a thermal voltage generator, establishing a voltage across the joint non-linearly proportional to the temperature of the joint. A common type-'K' Thermocouple (Nickel-Chromium / Nickel-Alumel) can operate from -270°C to 1260°C.
INTERPRETING THE SENSOR RESISTANCE
You can see that the resistance value decreases with an increase of temperature. This is referred to as a Negative Temperature Coefficient or NTC for short. There are devices with a PTC as well.
There are a couple of interesting points from the specifications above:
- The resistance of the sensor is quoted for a minimum temperature of 40°C, but clearly, an engine is not going to be 40°C immediately.
- The accuracy is +/- 3°. This is acceptable from the point of view that 40 or 50°C is nothing to worry about, whereas pressurised coolant greater than about 109°C would indicate a big problem.
- A minimum of 3 minutes is suggested before relying on readings from the sensor. This would give the engine time to “warm up” and get over that initial non-linear 0 to 40°C section.
If you haven’t noticed, the resistance values are quite non-linear. The change of resistance from 0° to 25°C is about 3.25:1. The difference from 25° to 100°C is greater than 9:1. How do we handle this? There are two questions here, and each is handled differently.
The first question really is how would a boat or car instrumentation handle this? The simple answer is with an equally non-linear gauge. Looking at the suggested gauge, we can see the clearly non-linear scale.
The second question is how do we handle this with an electronic dashboard? There are a few ways to do this. We could come up with a mathematical equation that computes the temperature from the resistance or we could have a table of various resistance values for known temperatures.
While, the truth of the matter is, that in this particular example, we don’t really need to be concerned with 40 or 50°C. Each engine will have its own comfortable and normal temperature. What we do need to be aware of is VERY high temperatures indicating a fault.
WHERE TO FROM HERE?
This basic idea of using basic analogue sensors as part of a broader digital platform will feature in a future project in DIYODE. While we don’t have a firm publishing schedule for the project, it’s currently in development, which we’re currently work on, so keep an eye out.