A copy of very incomplete program for forum

Dependencies:   mbed SDFileSystem

Committer:
roselea
Date:
Sat Mar 17 14:34:23 2012 +0000
Revision:
1:d1c29c7b7ab3
Parent:
0:bfcb5b67b1d6

        

Who changed what in which revision?

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