OneWire Temperature library for interfacing DS18B20

Dependents:   DallasTemperature project1

Committer:
Wimpie
Date:
Sun Apr 17 17:27:20 2011 +0000
Revision:
0:ad90c2e86a63
improved 1W search function

Who changed what in which revision?

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