First Publish

Dependencies:   BridgeDriver2 FrontPanelButtons MAX31855 MCP23017 SDFileSystem TextLCD mbed

Committer:
mehatfie
Date:
Mon Nov 10 22:59:49 2014 +0000
Revision:
1:9954bf6d7d25
Parent:
0:20e78c9d2ea9
First Commit

Who changed what in which revision?

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