Now supports DS18B20 and DS18S20 Maxim/Dallas one-wire thermometer devices. Also supports DS18S20 in 9, 10, 11, and 12 bit resolution modes. 'Use Address' mode now checks if the correct device type is present, and informs the user which device to use. Correct temperature conversion times now used in non-parasitic mode. The device should be placed at least 6 inches (15 cm) from the mbed board in order to accurately read ambient temperature.

Dependencies:   mbed

Fork of OneWireCRC by Petras Saduikis

Committer:
lagish
Date:
Mon Jul 13 17:22:49 2015 +0000
Revision:
1:ade3fad22621
Parent:
0:01a6a40578c9
Draft1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
snatch59 0:01a6a40578c9 1 /*
snatch59 0:01a6a40578c9 2 * OneWireThermometer. Base class for Maxim One-Wire Thermometers.
snatch59 0:01a6a40578c9 3 * Uses the OneWireCRC library.
snatch59 0:01a6a40578c9 4 *
snatch59 0:01a6a40578c9 5 * Copyright (C) <2010> Petras Saduikis <petras@petras.co.uk>
snatch59 0:01a6a40578c9 6 *
snatch59 0:01a6a40578c9 7 * This file is part of OneWireThermometer.
snatch59 0:01a6a40578c9 8 *
snatch59 0:01a6a40578c9 9 * OneWireThermometer is free software: you can redistribute it and/or modify
snatch59 0:01a6a40578c9 10 * it under the terms of the GNU General Public License as published by
snatch59 0:01a6a40578c9 11 * the Free Software Foundation, either version 3 of the License, or
snatch59 0:01a6a40578c9 12 * (at your option) any later version.
snatch59 0:01a6a40578c9 13 *
snatch59 0:01a6a40578c9 14 * OneWireThermometer is distributed in the hope that it will be useful,
snatch59 0:01a6a40578c9 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
snatch59 0:01a6a40578c9 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
snatch59 0:01a6a40578c9 17 * GNU General Public License for more details.
snatch59 0:01a6a40578c9 18 *
snatch59 0:01a6a40578c9 19 * You should have received a copy of the GNU General Public License
snatch59 0:01a6a40578c9 20 * along with OneWireThermometer. If not, see <http://www.gnu.org/licenses/>.
snatch59 0:01a6a40578c9 21 */
snatch59 0:01a6a40578c9 22
snatch59 0:01a6a40578c9 23 #include "OneWireThermometer.h"
snatch59 0:01a6a40578c9 24 #include "OneWireDefs.h"
snatch59 0:01a6a40578c9 25 #include "DebugTrace.h"
snatch59 0:01a6a40578c9 26
snatch59 0:01a6a40578c9 27 DebugTrace pc(ON, TO_SERIAL);
snatch59 0:01a6a40578c9 28
snatch59 0:01a6a40578c9 29 // constructor specifies standard speed for the 1-Wire comms
snatch59 0:01a6a40578c9 30 OneWireThermometer::OneWireThermometer(bool crcOn, bool useAddr, bool parasitic, PinName pin, int device_id) :
snatch59 0:01a6a40578c9 31 useCRC(crcOn), useAddress(useAddr), useParasiticPower(parasitic),
snatch59 0:01a6a40578c9 32 oneWire(pin, STANDARD), deviceId(device_id), resolution(twelveBit)
snatch59 0:01a6a40578c9 33 {
snatch59 0:01a6a40578c9 34 // NOTE: the power-up resolution of a DS18B20 is 12 bits. The DS18S20's resolution is always
snatch59 0:01a6a40578c9 35 // 9 bits + enhancement, but we treat the DS18S20 as fixed to 12 bits for calculating the
snatch59 0:01a6a40578c9 36 // conversion time Tconv.
snatch59 0:01a6a40578c9 37 }
snatch59 0:01a6a40578c9 38
snatch59 0:01a6a40578c9 39 bool OneWireThermometer::initialize()
snatch59 0:01a6a40578c9 40 {
snatch59 0:01a6a40578c9 41 // get the device address for use in selectROM() when reading the temperature
snatch59 0:01a6a40578c9 42 // - not really needed except for device validation if using skipROM()
snatch59 0:01a6a40578c9 43 if (useAddress)
snatch59 0:01a6a40578c9 44 {
snatch59 0:01a6a40578c9 45 pc.traceOut("\r\n");
snatch59 0:01a6a40578c9 46 pc.traceOut("New Scan\r\n");
snatch59 0:01a6a40578c9 47
snatch59 0:01a6a40578c9 48 oneWire.resetSearch();
snatch59 0:01a6a40578c9 49 if (!oneWire.search(address)) // search for 1-wire device address
snatch59 0:01a6a40578c9 50 {
snatch59 0:01a6a40578c9 51 pc.traceOut("No more addresses.\r\n");
snatch59 0:01a6a40578c9 52 wait(2);
snatch59 0:01a6a40578c9 53 return false;
snatch59 0:01a6a40578c9 54 }
snatch59 0:01a6a40578c9 55
snatch59 0:01a6a40578c9 56 pc.traceOut("Address = ");
snatch59 0:01a6a40578c9 57 for (int i = 0; i < ADDRESS_SIZE; i++)
snatch59 0:01a6a40578c9 58 {
snatch59 0:01a6a40578c9 59 pc.traceOut("%x ", (int)address[i]);
snatch59 0:01a6a40578c9 60 }
snatch59 0:01a6a40578c9 61 pc.traceOut("\r\n");
snatch59 0:01a6a40578c9 62
snatch59 0:01a6a40578c9 63 if (OneWireCRC::crc8(address, ADDRESS_CRC_BYTE) != address[ADDRESS_CRC_BYTE]) // check address CRC is valid
snatch59 0:01a6a40578c9 64 {
snatch59 0:01a6a40578c9 65 pc.traceOut("CRC is not valid!\r\n");
snatch59 0:01a6a40578c9 66 wait(2);
snatch59 0:01a6a40578c9 67 return false;
snatch59 0:01a6a40578c9 68 }
snatch59 0:01a6a40578c9 69
snatch59 0:01a6a40578c9 70 if (address[0] != deviceId)
snatch59 0:01a6a40578c9 71 {
snatch59 0:01a6a40578c9 72 // Make sure it is a one-wire thermometer device
snatch59 0:01a6a40578c9 73 if (DS18B20_ID == deviceId)
snatch59 0:01a6a40578c9 74 pc.traceOut("You need to use a DS1820 or DS18S20 for correct results.\r\n");
snatch59 0:01a6a40578c9 75 else if (DS18S20_ID == deviceId)
snatch59 0:01a6a40578c9 76 pc.traceOut("You need to use a DS18B20 for correct results.\r\n");
snatch59 0:01a6a40578c9 77 else
snatch59 0:01a6a40578c9 78 pc.traceOut("Device is not a DS18B20/DS1820/DS18S20 device.\r\n");
snatch59 0:01a6a40578c9 79
snatch59 0:01a6a40578c9 80 wait(2);
snatch59 0:01a6a40578c9 81 return false;
snatch59 0:01a6a40578c9 82 }
snatch59 0:01a6a40578c9 83 else
snatch59 0:01a6a40578c9 84 {
snatch59 0:01a6a40578c9 85 if (DS18B20_ID == deviceId) pc.traceOut("DS18B20 present and correct.\r\n");
snatch59 0:01a6a40578c9 86 if (DS18S20_ID == deviceId) pc.traceOut("DS1820/DS18S20 present and correct.\r\n");
snatch59 0:01a6a40578c9 87 }
snatch59 0:01a6a40578c9 88 }
snatch59 0:01a6a40578c9 89
snatch59 0:01a6a40578c9 90 return true;
snatch59 0:01a6a40578c9 91 }
snatch59 0:01a6a40578c9 92
snatch59 0:01a6a40578c9 93 // NOTE ON USING SKIP ROM: ok to use before a Convert command to get all
snatch59 0:01a6a40578c9 94 // devices on the bus to do simultaneous temperature conversions. BUT can
snatch59 0:01a6a40578c9 95 // only use before a Read Scratchpad command if there is only one device on the
snatch59 0:01a6a40578c9 96 // bus. For purpose of this library it is assumed there is only one device
snatch59 0:01a6a40578c9 97 // on the bus.
snatch59 0:01a6a40578c9 98 void OneWireThermometer::resetAndAddress()
snatch59 0:01a6a40578c9 99 {
snatch59 0:01a6a40578c9 100 oneWire.reset(); // reset device
snatch59 0:01a6a40578c9 101 if (useAddress)
snatch59 0:01a6a40578c9 102 {
snatch59 0:01a6a40578c9 103 oneWire.matchROM(address); // select which device to talk to
snatch59 0:01a6a40578c9 104 }
snatch59 0:01a6a40578c9 105 else
snatch59 0:01a6a40578c9 106 {
snatch59 0:01a6a40578c9 107 oneWire.skipROM(); // broadcast
snatch59 0:01a6a40578c9 108 }
snatch59 0:01a6a40578c9 109 }
snatch59 0:01a6a40578c9 110
snatch59 0:01a6a40578c9 111 bool OneWireThermometer::readAndValidateData(BYTE* data)
snatch59 0:01a6a40578c9 112 {
snatch59 0:01a6a40578c9 113 bool dataOk = true;
snatch59 0:01a6a40578c9 114
snatch59 0:01a6a40578c9 115 resetAndAddress();
snatch59 0:01a6a40578c9 116 oneWire.writeByte(READSCRATCH); // read Scratchpad
snatch59 0:01a6a40578c9 117
snatch59 0:01a6a40578c9 118 pc.traceOut("read = ");
snatch59 0:01a6a40578c9 119 for (int i = 0; i < THERMOM_SCRATCHPAD_SIZE; i++)
snatch59 0:01a6a40578c9 120 {
snatch59 0:01a6a40578c9 121 // we need all bytes which includes CRC check byte
snatch59 0:01a6a40578c9 122 data[i] = oneWire.readByte();
snatch59 0:01a6a40578c9 123 pc.traceOut("%x ", (int)data[i]);
snatch59 0:01a6a40578c9 124 }
snatch59 0:01a6a40578c9 125 pc.traceOut("\r\n");
snatch59 0:01a6a40578c9 126
snatch59 0:01a6a40578c9 127 // Check CRC is valid if you want to
snatch59 0:01a6a40578c9 128 if (useCRC && !(OneWireCRC::crc8(data, THERMOM_CRC_BYTE) == data[THERMOM_CRC_BYTE]))
snatch59 0:01a6a40578c9 129 {
snatch59 0:01a6a40578c9 130 // CRC failed
snatch59 0:01a6a40578c9 131 pc.traceOut("CRC FAILED... \r\n");
snatch59 0:01a6a40578c9 132 dataOk = false;
snatch59 0:01a6a40578c9 133 }
snatch59 0:01a6a40578c9 134
snatch59 0:01a6a40578c9 135 return dataOk;
snatch59 0:01a6a40578c9 136 }
snatch59 0:01a6a40578c9 137
snatch59 0:01a6a40578c9 138 float OneWireThermometer::readTemperature()
snatch59 0:01a6a40578c9 139 {
snatch59 0:01a6a40578c9 140 BYTE data[THERMOM_SCRATCHPAD_SIZE];
snatch59 0:01a6a40578c9 141 float realTemp = -999;
snatch59 0:01a6a40578c9 142
snatch59 0:01a6a40578c9 143 resetAndAddress();
snatch59 0:01a6a40578c9 144 oneWire.writeByte(CONVERT); // issue Convert command
snatch59 0:01a6a40578c9 145
snatch59 0:01a6a40578c9 146 if (useParasiticPower)
snatch59 0:01a6a40578c9 147 {
snatch59 0:01a6a40578c9 148 // wait while converting - Tconv (according to resolution of reading)
snatch59 0:01a6a40578c9 149 wait_ms(CONVERSION_TIME[resolution]);
snatch59 0:01a6a40578c9 150 }
snatch59 0:01a6a40578c9 151 else
snatch59 0:01a6a40578c9 152 {
snatch59 0:01a6a40578c9 153 // TODO
snatch59 0:01a6a40578c9 154 // after the Convert command, the device should respond by transmitting 0
snatch59 0:01a6a40578c9 155 // while the temperature conversion is in progress and 1 when the conversion is done
snatch59 0:01a6a40578c9 156 // - as were are not checking this (TODO), we use Tconv, as we would do for
snatch59 0:01a6a40578c9 157 // parasitic power
snatch59 0:01a6a40578c9 158 wait_ms(CONVERSION_TIME[resolution]);
snatch59 0:01a6a40578c9 159 }
snatch59 0:01a6a40578c9 160
snatch59 0:01a6a40578c9 161 if (readAndValidateData(data)) // issue Read Scratchpad commmand and get data
snatch59 0:01a6a40578c9 162 {
snatch59 0:01a6a40578c9 163 realTemp = calculateTemperature(data);
snatch59 0:01a6a40578c9 164 }
snatch59 0:01a6a40578c9 165
snatch59 0:01a6a40578c9 166 return realTemp;
snatch59 0:01a6a40578c9 167 }