Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: DallasTemperature project1
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(PinName pin, bool crcOn, bool useAddr, bool parasitic, int device_id, unsigned char *ROMaddress) 00031 :oneWire(pin, STANDARD) { 00032 _useCRC=crcOn; 00033 _useAddress=useAddr; 00034 _useParasiticPower=parasitic; 00035 _deviceId= device_id; 00036 _resolution=twelveBit; 00037 00038 if (_useAddress) { 00039 for (int i = 0; i < ADDRESS_SIZE; i++) 00040 _ROMCode[i]=ROMaddress[i]; 00041 } else { 00042 for (int i = 0; i < ADDRESS_SIZE; i++) 00043 _ROMCode[i]=0; 00044 } 00045 00046 // NOTE: the power-up resolution of a DS18B20 is 12 bits. The DS18S20's resolution is always 00047 // 9 bits + enhancement, but we treat the DS18S20 as fixed to 12 bits for calculating the 00048 // conversion time Tconv. 00049 00050 } 00051 00052 bool OneWireThermometer::initialize() { 00053 00054 int OneWireFound; 00055 int OneWireSameAddress; 00056 int i; 00057 BYTE _dummyaddress[8]; 00058 00059 00060 if (_useAddress) { 00061 pc.traceOut("Scan for device with address "); 00062 for (i = 0; i < ADDRESS_SIZE; i++) { 00063 pc.traceOut("%x ", (int)_ROMCode[i]); 00064 } 00065 pc.traceOut("\r\n"); 00066 } 00067 OneWireSameAddress=0; 00068 00069 oneWire.resetSearch(); 00070 do { 00071 OneWireFound=(oneWire.search(_dummyaddress)); 00072 if (OneWireFound) { 00073 00074 if (!_useAddress) { 00075 pc.traceOut("Device found with Address = "); 00076 for (i = 0; i < ADDRESS_SIZE; i++) { 00077 pc.traceOut("%x ", (int)_dummyaddress[i]); 00078 } 00079 } 00080 OneWireSameAddress=1; 00081 00082 if (_useAddress) { 00083 for (i = 0; i < ADDRESS_SIZE; i++) { 00084 if (!((OneWireSameAddress) && (_ROMCode[i] ==_dummyaddress[i]))) 00085 OneWireSameAddress=0; 00086 } 00087 } else { 00088 for (i = 0; i < ADDRESS_SIZE; i++) { 00089 _ROMCode[i] =_dummyaddress[i]; 00090 } 00091 } 00092 00093 /* if (OneWireSameAddress) { 00094 pc.traceOut("-> Address valid!\r\n"); 00095 00096 } else { 00097 pc.traceOut("-> Address NOT valid.\r\n"); 00098 }*/ 00099 00100 } else { 00101 00102 pc.traceOut("No more addresses.\r\n"); 00103 oneWire.resetSearch(); 00104 wait_ms(250); //500 00105 } 00106 } while (OneWireFound && !OneWireSameAddress); 00107 00108 if (!OneWireSameAddress) { 00109 pc.traceOut("-> No Valid ROM Code found.\r\n"); 00110 return false; 00111 } 00112 00113 if (OneWireCRC::crc8(_ROMCode, ADDRESS_CRC_BYTE) != _ROMCode[ADDRESS_CRC_BYTE]) { // check address CRC is valid 00114 pc.traceOut("CRC is not valid!\r\n"); 00115 // wait_ms(500); 00116 return false; 00117 } 00118 00119 if (_ROMCode[0] != _deviceId) { 00120 // Make sure it is a one-wire thermometer device 00121 if (DS18B20_ID == _deviceId) 00122 pc.traceOut("You need to use a DS1820 or DS18S20 for correct results.\r\n"); 00123 else if (DS18S20_ID == _deviceId) 00124 pc.traceOut("You need to use a DS18B20 for correct results.\r\n"); 00125 else 00126 pc.traceOut("Device is not a DS18B20/DS1820/DS18S20 device.\r\n"); 00127 00128 // wait_ms(500); 00129 return false; 00130 } else { 00131 if (DS18B20_ID == _deviceId) pc.traceOut("DS18B20 present and correct.\r\n"); 00132 if (DS18S20_ID == _deviceId) pc.traceOut("DS1820/DS18S20 present and correct.\r\n"); 00133 } 00134 00135 00136 return true; 00137 } 00138 00139 // NOTE ON USING SKIP ROM: ok to use before a Convert command to get all 00140 // devices on the bus to do simultaneous temperature conversions. BUT can 00141 // only use before a Read Scratchpad command if there is only one device on the 00142 // bus. For purpose of this library it is assumed there is only one device 00143 // on the bus. 00144 00145 void OneWireThermometer::resetAndAddress() { 00146 oneWire.reset(); // reset device 00147 if (_useAddress) { 00148 oneWire.matchROM(_ROMCode); // select which device to talk to 00149 } else { 00150 oneWire.skipROM(); // broadcast 00151 } 00152 } 00153 00154 bool OneWireThermometer::readAndValidateData(BYTE* data) { 00155 bool dataOk = true; 00156 00157 resetAndAddress(); 00158 oneWire.writeByte(DS18X20_READSCRATCH); // read Scratchpad 00159 00160 // pc.traceOut("read = "); 00161 for (int i = 0; i < THERMOM_SCRATCHPAD_SIZE; i++) { 00162 // we need all bytes which includes CRC check byte 00163 data[i] = oneWire.readByte(); 00164 // pc.traceOut("%x ", (int)data[i]); 00165 } 00166 //pc.traceOut("\r\n"); 00167 00168 // Check CRC is valid if you want to 00169 if (_useCRC && !(OneWireCRC::crc8(data, THERMOM_CRC_BYTE) == data[THERMOM_CRC_BYTE])) { 00170 // CRC failed 00171 pc.traceOut("CRC FAILED... \r\n"); 00172 dataOk = false; 00173 } 00174 00175 return dataOk; 00176 } 00177 00178 float OneWireThermometer::readTemperature() { 00179 BYTE data[THERMOM_SCRATCHPAD_SIZE]; 00180 float realTemp = -999; 00181 int i = 0; 00182 00183 do { 00184 00185 resetAndAddress(); 00186 oneWire.writeByte(CONVERT); // issue Convert command 00187 00188 if (_useParasiticPower) { 00189 // wait while converting - Tconv (according to resolution of reading) 00190 wait_ms(CONVERSION_TIME[_resolution]); 00191 } else { 00192 // TODO 00193 // after the Convert command, the device should respond by transmitting 0 00194 // while the temperature conversion is in progress and 1 when the conversion is done 00195 // - as were are not checking this (TODO), we use Tconv, as we would do for 00196 // parasitic power 00197 wait_ms(CONVERSION_TIME[_resolution]); 00198 } 00199 00200 if (readAndValidateData(data)) { // issue Read Scratchpad commmand and get data 00201 realTemp = calculateTemperature(data); 00202 i++; 00203 } 00204 } while ((realTemp==-999) && (i<5)); 00205 00206 return realTemp; 00207 }
Generated on Fri Jul 22 2022 03:20:41 by
1.7.2