Custom

Dependencies:   mbed

Fork of OneWireCRC by Petras Saduikis

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers OneWireThermometer.cpp Source File

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 }