Lucian Corduneanu
/
OneWireCRC
OneWireCRC
Fork of OneWireCRC by
Embed:
(wiki syntax)
Show/hide line numbers
OneWireThermometer.cpp
00001 /* 00002 * OneWireThermometer. Base class for Maxim One-Wire Thermometers. 00003 * Uses the OneWireCRC library. 00004 * 00005 * Copyright (C) <2010> Petras Saduikis <petras@petras.co.uk> 00006 * 00007 * This file is part of OneWireThermometer. 00008 * 00009 * OneWireThermometer is free software: you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation, either version 3 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * OneWireThermometer is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with OneWireThermometer. If not, see <http://www.gnu.org/licenses/>. 00021 */ 00022 00023 #include "OneWireThermometer.h" 00024 #include "OneWireDefs.h" 00025 #include "DebugTrace.h" 00026 00027 DebugTrace pc(ON, TO_SERIAL); 00028 00029 // constructor specifies standard speed for the 1-Wire comms 00030 OneWireThermometer::OneWireThermometer(bool crcOn, bool useAddr, bool parasitic, PinName pin, int device_id) : 00031 useCRC(crcOn), useAddress(useAddr), useParasiticPower(parasitic), 00032 oneWire(pin, STANDARD), deviceId(device_id), resolution(twelveBit) 00033 { 00034 // NOTE: the power-up resolution of a DS18B20 is 12 bits. The DS18S20's resolution is always 00035 // 9 bits + enhancement, but we treat the DS18S20 as fixed to 12 bits for calculating the 00036 // conversion time Tconv. 00037 } 00038 00039 bool OneWireThermometer::initialize() 00040 { 00041 // get the device address for use in selectROM() when reading the temperature 00042 // - not really needed except for device validation if using skipROM() 00043 if (useAddress) 00044 { 00045 pc.traceOut("\r\n"); 00046 pc.traceOut("New Scan\r\n"); 00047 00048 oneWire.resetSearch(); 00049 if (!oneWire.search(address)) // search for 1-wire device address 00050 { 00051 pc.traceOut("No more addresses.\r\n"); 00052 wait(2); 00053 return false; 00054 } 00055 00056 pc.traceOut("Address = "); 00057 for (int i = 0; i < ADDRESS_SIZE; i++) 00058 { 00059 pc.traceOut("%x ", (int)address[i]); 00060 } 00061 pc.traceOut("\r\n"); 00062 00063 if (OneWireCRC::crc8(address, ADDRESS_CRC_BYTE) != address[ADDRESS_CRC_BYTE]) // check address CRC is valid 00064 { 00065 pc.traceOut("CRC is not valid!\r\n"); 00066 wait(2); 00067 return false; 00068 } 00069 00070 if (address[0] != deviceId) 00071 { 00072 // Make sure it is a one-wire thermometer device 00073 if (DS18B20_ID == deviceId) 00074 pc.traceOut("You need to use a DS1820 or DS18S20 for correct results.\r\n"); 00075 else if (DS18S20_ID == deviceId) 00076 pc.traceOut("You need to use a DS18B20 for correct results.\r\n"); 00077 else 00078 pc.traceOut("Device is not a DS18B20/DS1820/DS18S20 device.\r\n"); 00079 00080 wait(2); 00081 return false; 00082 } 00083 else 00084 { 00085 if (DS18B20_ID == deviceId) pc.traceOut("DS18B20 present and correct.\r\n"); 00086 if (DS18S20_ID == deviceId) pc.traceOut("DS1820/DS18S20 present and correct.\r\n"); 00087 } 00088 } 00089 00090 return true; 00091 } 00092 00093 // NOTE ON USING SKIP ROM: ok to use before a Convert command to get all 00094 // devices on the bus to do simultaneous temperature conversions. BUT can 00095 // only use before a Read Scratchpad command if there is only one device on the 00096 // bus. For purpose of this library it is assumed there is only one device 00097 // on the bus. 00098 void OneWireThermometer::resetAndAddress() 00099 { 00100 oneWire.reset(); // reset device 00101 if (useAddress) 00102 { 00103 oneWire.matchROM(address); // select which device to talk to 00104 } 00105 else 00106 { 00107 oneWire.skipROM(); // broadcast 00108 } 00109 } 00110 00111 bool OneWireThermometer::readAndValidateData(BYTE* data) 00112 { 00113 bool dataOk = true; 00114 00115 resetAndAddress(); 00116 oneWire.writeByte(READSCRATCH); // read Scratchpad 00117 00118 pc.traceOut("read = "); 00119 for (int i = 0; i < THERMOM_SCRATCHPAD_SIZE; i++) 00120 { 00121 // we need all bytes which includes CRC check byte 00122 data[i] = oneWire.readByte(); 00123 pc.traceOut("%x ", (int)data[i]); 00124 } 00125 pc.traceOut("\r\n"); 00126 00127 // Check CRC is valid if you want to 00128 if (useCRC && !(OneWireCRC::crc8(data, THERMOM_CRC_BYTE) == data[THERMOM_CRC_BYTE])) 00129 { 00130 // CRC failed 00131 pc.traceOut("CRC FAILED... \r\n"); 00132 dataOk = false; 00133 } 00134 00135 return dataOk; 00136 } 00137 00138 float OneWireThermometer::readTemperature() 00139 { 00140 BYTE data[THERMOM_SCRATCHPAD_SIZE]; 00141 float realTemp = -999; 00142 00143 resetAndAddress(); 00144 oneWire.writeByte(CONVERT); // issue Convert command 00145 00146 if (useParasiticPower) 00147 { 00148 // wait while converting - Tconv (according to resolution of reading) 00149 wait_ms(CONVERSION_TIME[resolution]); 00150 } 00151 else 00152 { 00153 // TODO 00154 // after the Convert command, the device should respond by transmitting 0 00155 // while the temperature conversion is in progress and 1 when the conversion is done 00156 // - as were are not checking this (TODO), we use Tconv, as we would do for 00157 // parasitic power 00158 wait_ms(CONVERSION_TIME[resolution]); 00159 } 00160 00161 if (readAndValidateData(data)) // issue Read Scratchpad commmand and get data 00162 { 00163 realTemp = calculateTemperature(data); 00164 } 00165 00166 return realTemp; 00167 }
Generated on Sat Jul 16 2022 12:23:48 by 1.7.2