Dependencies:   mbed

Committer:
gbeardall
Date:
Mon Oct 17 10:42:00 2011 +0000
Revision:
0:2f78e3dca55d

        

Who changed what in which revision?

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