Temperature Sensing using DS18B20 Digital Sensors
Hardware
Multiple sensors can be connected to the same data bus. Each sensor identifies itself by a unique serial number.
The sensor can operate in normal or parasite mode. In normal mode, a 3-wire connection is needed. In parasite mode the sensor derives its power from the data line. Only two wires, data and ground, are required.
Note: The Arduino positive supply rail is referred to as Vcc and the positive supply for the DS18B20 as Vdd. In this context, the two are the same.
Normal Mode
In normal mode, each sensor is connected between a power line (Vdd pin 3) and ground (GND pin 1), and the data output (DQ pin 2) connects to a third, data, line. The data output is a 3-state or open-drain port (DQ pin 2) and requires a 4k7 pull-up resistor. The data line is connected to an available Arduino digital input or Arduino digital pin 4 in the case of the emonTx.
Normal mode is recommended when many devices and/or long distances are involved.
Parasite Mode
Parasite power mode requires both DS18B20 GND (pin 1) and Vdd (pin 3) to be connected to ground. The DQ pin (pin 2 - the middle pin) is the data/parasite power line. The data line requires a pull-up resistor of 4k7 connected to + 5 V. The data line is connected to an available Arduino digital input or Arduino digital pin 4 in the case of the emonTx.
Parasite mode should be used only with a small number of devices, over relatively short distances.
Figure 1: Normal Power Connection Diagram |
Figure 2: Parasite Power Connection Diagram |
Figure 3: Three DS18B20's in normal power mode |
Figure 4: Three DS18B20's in parasite power mode |
Connecting multiple sensors
If the sensors are located relatively close to the Arduino/emonTx, then satisfactory operation should be achieved by making a parallel connection of the sensors at the connection to the Arduino or emonTx . This is called a radial or 'star' arrangement.
If long cable runs are required, consideration should be given to connecting in 'daisy-chain' fashion where one cable runs from the furthest sensor, connecting to each sensor in turn, before ending at the Arduino or emonTx.
There is more about this in the note below.
For short cable runs, unscreened two or three-core cable, or single-core (parasite mode) or twin-core (normal mode) screened audio cable should be suitable. For longer cable runs, low capacitance cable such as RF aerial downlead (parasite mode) has been successfully used over a distance of 10 m. CAT 5 network cable has also been used with success over a distance of 30m, with data & ground using one twisted pair and power & ground using a second twisted pair.
Cable Length
Up to 20m cable length has been successfully reported with a lower pull-up resistor value of 2K. Adding multiple sensors will reduce the practical length, as will non consistent / nonlinear cable runs, see app note
Temperature Sensing with the emonTx
Update: For emonTx V3 and emonPi see Wiki:
https://wiki.openenergymonitor.org/index.php/EmonPi#DS18B20_Temperature
https://wiki.openenergymonitor.org/index.php/EmonTx_V3.4#RJ45_Connection
The emonTx supports direct connection of DS18B20 temperature sensors, however, there are significant differences between emonTx V2 and emonTx V3.
The emonTx V2
The PCB includes the option to solder a DS18B20 sensor directly onto the PCB for monitoring the temperature where the emonTx is located. A more useful option is to connect DS18B20 temperature sensors to the 3.5mm temperature jack port for monitoring remote temperatures e.g. outside temperature, living room temperature and boiler temperature.
The sensors can be connected either in normal or parasite power mode. We recommend normal power mode for increased reliability. 3-core 22AWG wire is perfect for wiring up sensors. Encapsulated sensors can be purchased. and connected. The 4k7 pull-up resistor is provided on the pcb.
Wire up the sensor(s) to a male 3.5mm jack as follows:
Connection | Normal Mode | Parasite Mode | Voltage |
Tip | DQ (data line) | DQ (data line) | 3.9 V approx |
Ring | Vdd | no connection | + 5 V |
Sleeve | GND | GND + Vdd | 0 V |
(Voltages are for V2.2 boards powered at 5 V)
Note: If you purchased the Waterproof DS18B20 temperature sensing kit from the shop, it is pre-wired:
Data: White wire
Vcc: Red wire
GND: Black wire
The one-wire temperature data line is hardwired to Arduino Dig I/O 4 on the emonTx PCB. See the emonTx reference page for schematic and PCB layout.
The emonTx runs internally at 3.3V. On emonTx PCB version 2.0 and 2.1 the DS18B20 also runs at 3.3V.
On emonTx V2.2 the temperature sensors are connected to the PWR rail which is 5V when the emonTx is powered via the 5V mini-USB connector. Note: ignore the solder jumper. If you look carefully, it is already connected to PWR. Running the sensors at 5V gives increased reliability and enables for more sensors and longer cable runs to be used.
GitHub emonTx temperature example also includes a sketch to extract the serial number from the DS18B20. (N.B. You must change "#define ONE_WIRE_BUS 4" to "#define ONE_WIRE_BUS 5" for the emonTx V3.4)
Software
Each sensor has a unique serial number assigned by the manufacturer, and your sketch (unless it is the "low-power" sketch that expects a single sensor) must be programmed with these serial numbers so it can identify and interrogate each sensor. Download the examples from GitHub emonTx V2 temperature example. There you will find the temperature search test sketch. You need run the sketch only once to extract and list the serial number from each DS18B20. Then you manually copy the serial numbers into your monitoring sketch.
See Part 2 for a description of how the order in which the sensors are discovered is decided.
The power-on value in the scratchpad memory is 85 °C. If the scratchpad memory is read before the temperature conversion has completed, then the erroneous temperature value of 85 °C might be returned. Depending on your application, it might not be possible to distinguish this from a genuine reading. This error value might be caused by an intermittent or absent connection of either the power wire (normal mode) or the GND wire.
If the data being read from the scratchpad memory is corrupted in transit, then the checksum will fail and the Dallas library will return a value of -127 °C. This is outside the operating temperature range of the sensor, so can easily be detected in software. This error value might be caused by an intermittent or absent connection of either the data wire (normal mode) or the GND wire, or indeed an absent sensor.
The emonTx V3
The emonTx V3 has a connection for the temperature sensors on a screw terminal block. Full details can be found on the Wiki page. The pre-loaded sketch will sense a single temperature sensor at start-up and requires no further configuration. Note: The examples for the emonTx V2 and the temperature search sketch will not work without modification. You will need to edit the sketch due to changed I/O usage in the emonTx V3: You must change "#define ONE_WIRE_BUS 4" to "#define ONE_WIRE_BUS 5".
Notes and further reading
For large numbers of sensors and longer cable runs, use the DS2480B 1-wire driver chip.
[N.B. Some very helpful information from Chris Shucksmith appears to have been removed.]
"If you intend to have a large 1-wire network, it is important that you design the network correctly, otherwise you will have problems with timing/reflection issues and loss of data. For very small networks, it is possible to connect each sensor in a star or radial arrangement. This means that each sensor is connected via its own cable back to a central point and then connected to the 1-wire to serial adapter. However, it is strongly recommend that you connect each sensor to a single continuous cable which loops from sensor to sensor in turn (daisy chain). This will reduce potential misreads due to reflections in the cable. Each sensor should have a maximum of 50mm (2") of cable connected off the main highway. Even using this method, connecting more than 10-15 sensors will still cause problems due to loading of the data bus. To minimise this effect, always place a 100-120 ohm resistor in the data leg of each sensor before connecting to the network."
quoted from: http://www.jon00.me.uk/onewireintro.shtml
Re: DS18B20 temperature sensing
I have tried replacing the code in the Simple example
sensors.requestTemperatures();
Serial.print(sensors.getTempCByIndex(0));
with
sensors.requestTemperatures();
if(sensors.getAddress(0x28, 0xC0, 0x5E, 0x9C, 0x03, 0x00, 0x00, 0xA1, 0))
temp0=(sensors.getTempC(0x28, 0xC0, 0x5E, 0x9C, 0x03, 0x00, 0x00, 0xA1,));
if(sensors.getAddress(0x28, 0xC0, 0x5A, 0x9C, 0x09, 0x00, 0x00, 0xB1, 1))
temp1=(sensors.getTempC(0x28, 0xC0, 0x5A, 0x9C, 0x09, 0x00, 0x00, 0xB1,));
but I get a zillion error messages when I try and compile it. Have I done it wrong? (again!)
Re: DS18B20 temperature sensing
Re: DS18B20 temperature sensing
Glyn, do you have the rest of the sketch please, the first part is missing, variable declarations etc.
Thanks
Re: DS18B20 temperature sensing
Sure, here's all the code from my home monitor setup: http://openenergymonitor.org/emon/sites/default/files/HomeMonitorV4.zip.
Its a bit outdated, its been running for a few years now. The emonTx was only a pipedream at this stage!
Re: DS18B20 temperature sensing
Thanks Glyn for your sketch, it has been time well spent working through your code. I have learnt a lot from you!
Re: DS18B20 temperature sensing
Glyn, I have used extracts from your sketch for a few months now, and occassionally get a rogue reading posted to Pachube, usually a large negative number (it's averaged over 3 or 4 readings), the last one was -25.4 degC.
I wondered if the error catching code should be;
if (temp0 == -127) { ...reset sensors
instead of
if (temp0 == DEVICE_DISCONNECTED) { ...reset sensors
Re: DS18B20 temperature sensing
Good observation. Why not have both. Anything less than -40 higher than about 50 (for ambient temperaure monitoring in the UK) could be considered a rouge value.
Re: DS18B20 temperature sensing
Thanks, I'll mod the code to:
sensors.requestTemperatures(); // Send the command to get temperatures
if(sensors.getAddress(tempDeviceAddress, 0))
tmpSenseP = (sensors.getTempC(tempDeviceAddress));
//---Error rejection---//
if ((tmpSenseP < -50) || (tmpSense > 50)) {
sensors.begin();
for(int i=0;i<numberOfDevices; i++)
sensors.getAddress(tempDeviceAddress, i); }
else tmpSense = tmpSenseP; //If no error, then copy provisional data to temp variable
Re: DS18B20 temperature sensing
Looks great. Thanks
Re: DS18B20 temperature sensing
I have built the '2 channel Mains AC: non-invasive 3.0' with a LCD display, and wondered if the addition of a few DS18B20 temperature sensors could be added to the sketch without spoiling the functions of energy monitoring?