Interface for Dallas DS18B20 digital thermometer device.

Dependents:   WIZ550io_Xively_Demo ESP8266-WEB-Mbed-Controller BrewCtrl Brew_Keg ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DS18B20.cpp Source File

DS18B20.cpp

00001 #include "DS18B20.h"
00002 
00003 DS18B20::DS18B20(PinName pin, unsigned resolution) :
00004     _pin(pin) {
00005     SetResolution(resolution);
00006 }
00007 
00008 DS18B20::~DS18B20() {
00009 }
00010 
00011 // Reset 1-wire interface.
00012 unsigned DS18B20::Reset() {
00013     _pin.output();
00014     _pin = 0;    // drive bus low
00015     wait_us(H);
00016     _pin.input(); // release bus
00017     wait_us(I);
00018     unsigned result = _pin;  // read bus value
00019     wait_us(J);
00020     return result;
00021 }
00022 
00023 // Write bit to 1-wire.
00024 void DS18B20::WriteBit(unsigned bit) {
00025     _pin.output();
00026     if (bit) {
00027         _pin = 0;        // drive bus low
00028         wait_us(A);        // delay A
00029         _pin.input();      // release bus
00030         wait_us(B);        // delay B
00031     } else {
00032         _pin = 0;    // drive bus low
00033         wait_us(C);    // delay C
00034         _pin.input();  // release bus
00035         wait_us(D);    // delay D
00036     }
00037 }
00038 
00039 // Read bit from 1-wire.
00040 unsigned DS18B20::ReadBit() {
00041     unsigned bit_value;
00042     _pin.output();
00043     _pin = 0;        // drive bus low
00044     wait_us(A);        // delay A
00045     _pin.input();      // release bus
00046     wait_us(E);        // delay E
00047     bit_value = _pin;    // master sample bus
00048     wait_us(F);
00049     return bit_value;
00050 }
00051 
00052 // Write byte to 1-wire.
00053 void DS18B20::WriteByte(unsigned byte) {
00054     for (unsigned bit = 0; bit < 8; ++bit) {
00055         WriteBit(byte & 0x01); // lsb to msb
00056         byte >>= 1;    // right shift by 1-bit
00057     }
00058 }
00059 
00060 // Read byte from 1-wire.
00061 unsigned DS18B20::ReadByte() {
00062     unsigned byte = 0;
00063     for (unsigned bit = 0; bit < 8; ++bit) {
00064         byte |= (ReadBit() << bit);    // Reads lsb to msb
00065     }
00066     return byte;
00067 }
00068 
00069 // Set number of bits in the conversion.
00070 unsigned DS18B20::SetResolution(unsigned resolution) {
00071     if (Reset() != 0)
00072         return 1;
00073     else {
00074         WriteByte(SKIP_ROM);            // Skip ROM
00075         WriteByte(WRITE_SCRATCHPAD);    // WRITE_SCRATCHPAD
00076         WriteByte(0x7f);                // Alarm TH
00077         WriteByte(0x80);                // Alarm TL
00078         WriteByte(resolution);          // 0xx11111 xx=resolution (9-12 bits)
00079     }
00080     return 0;
00081 }
00082 
00083 // Trigger a temperature conversion but don't read the temperature.
00084 unsigned DS18B20::DoConversion() {
00085     if (Reset() != 0)
00086         return 1;
00087     else {
00088         WriteByte(SKIP_ROM);            // Skip ROM
00089         WriteByte(CONVERT);             // Convert
00090         while (ReadBit() == 0)
00091             ; // wait for conversion to complete
00092     }
00093     return 0;
00094 }
00095 
00096 // Do Conversion and get temperature as s8.4 sign-extended to 16-bits.
00097 int DS18B20::RawTemperature() {
00098     // Perform the temperature conversion.
00099     if (DoConversion() != 0)
00100         return INVALID_TEMPERATURE;
00101     // Read the temperature back.
00102     if (Reset() != 0)
00103         return INVALID_TEMPERATURE;
00104     else {
00105         WriteByte(SKIP_ROM);    // Skip ROM
00106         WriteByte(READ_SCRATCHPAD);    // Read Scrachpad
00107         unsigned LSB = ReadByte();
00108         unsigned MSB = ReadByte();
00109         // Terminate read as we only want temperature
00110         Reset();
00111         // Ensure correct sign-extension.
00112         return (int)((int16_t)((MSB << 8) | LSB));
00113     }
00114 }
00115 
00116 // Read temperature in floating point format.
00117 float DS18B20::GetTemperature() {
00118     int temperature = RawTemperature();
00119     return ((float)temperature) / 16.0;
00120 }
00121 
00122 // Read back DS18B20 ROM.
00123 int DS18B20::ReadROM(DS18B20::ROM_Code_t *ROM_Code) {
00124     if (Reset() != 0)
00125         return 1;
00126     else {
00127         WriteByte(READ_ROM);    // Read ROM
00128         for (unsigned i = 0; i < 8; ++i) {
00129             ROM_Code->rom[i] = ReadByte();
00130         }
00131     }
00132     return 0;
00133 }