DS18B20

Dependents:   DS1820_HelloWorld

Committer:
jack__zen
Date:
Wed Sep 06 05:35:15 2017 +0000
Revision:
0:a47e8ec71a4e
onewire

Who changed what in which revision?

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