Interface for Dallas DS18B20 digital thermometer device.

Dependents:   mDot_TTN_DHT11_Boston16_CAM

Fork of DS18B20_1wire by Richard Lane

Committer:
merckeng
Date:
Sat Dec 03 22:04:36 2016 +0000
Revision:
2:7a9581fe3e8b
Parent:
0:769f9b2b30d5
water sensor library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
richardlane 0:769f9b2b30d5 1 #include "DS18B20.h"
richardlane 0:769f9b2b30d5 2
richardlane 0:769f9b2b30d5 3 DS18B20::DS18B20(PinName pin, unsigned resolution) :
richardlane 0:769f9b2b30d5 4 _pin(pin) {
richardlane 0:769f9b2b30d5 5 SetResolution(resolution);
richardlane 0:769f9b2b30d5 6 }
richardlane 0:769f9b2b30d5 7
richardlane 0:769f9b2b30d5 8 DS18B20::~DS18B20() {
richardlane 0:769f9b2b30d5 9 }
richardlane 0:769f9b2b30d5 10
richardlane 0:769f9b2b30d5 11 // Reset 1-wire interface.
richardlane 0:769f9b2b30d5 12 unsigned DS18B20::Reset() {
richardlane 0:769f9b2b30d5 13 _pin.output();
richardlane 0:769f9b2b30d5 14 _pin = 0; // drive bus low
richardlane 0:769f9b2b30d5 15 wait_us(H);
richardlane 0:769f9b2b30d5 16 _pin.input(); // release bus
richardlane 0:769f9b2b30d5 17 wait_us(I);
richardlane 0:769f9b2b30d5 18 unsigned result = _pin; // read bus value
richardlane 0:769f9b2b30d5 19 wait_us(J);
richardlane 0:769f9b2b30d5 20 return result;
richardlane 0:769f9b2b30d5 21 }
richardlane 0:769f9b2b30d5 22
richardlane 0:769f9b2b30d5 23 // Write bit to 1-wire.
richardlane 0:769f9b2b30d5 24 void DS18B20::WriteBit(unsigned bit) {
richardlane 0:769f9b2b30d5 25 _pin.output();
richardlane 0:769f9b2b30d5 26 if (bit) {
richardlane 0:769f9b2b30d5 27 _pin = 0; // drive bus low
richardlane 0:769f9b2b30d5 28 wait_us(A); // delay A
richardlane 0:769f9b2b30d5 29 _pin.input(); // release bus
richardlane 0:769f9b2b30d5 30 wait_us(B); // delay B
richardlane 0:769f9b2b30d5 31 } else {
richardlane 0:769f9b2b30d5 32 _pin = 0; // drive bus low
richardlane 0:769f9b2b30d5 33 wait_us(C); // delay C
richardlane 0:769f9b2b30d5 34 _pin.input(); // release bus
richardlane 0:769f9b2b30d5 35 wait_us(D); // delay D
richardlane 0:769f9b2b30d5 36 }
richardlane 0:769f9b2b30d5 37 }
richardlane 0:769f9b2b30d5 38
richardlane 0:769f9b2b30d5 39 // Read bit from 1-wire.
richardlane 0:769f9b2b30d5 40 unsigned DS18B20::ReadBit() {
richardlane 0:769f9b2b30d5 41 unsigned bit_value;
richardlane 0:769f9b2b30d5 42 _pin.output();
richardlane 0:769f9b2b30d5 43 _pin = 0; // drive bus low
richardlane 0:769f9b2b30d5 44 wait_us(A); // delay A
richardlane 0:769f9b2b30d5 45 _pin.input(); // release bus
richardlane 0:769f9b2b30d5 46 wait_us(E); // delay E
richardlane 0:769f9b2b30d5 47 bit_value = _pin; // master sample bus
richardlane 0:769f9b2b30d5 48 wait_us(F);
richardlane 0:769f9b2b30d5 49 return bit_value;
richardlane 0:769f9b2b30d5 50 }
richardlane 0:769f9b2b30d5 51
richardlane 0:769f9b2b30d5 52 // Write byte to 1-wire.
richardlane 0:769f9b2b30d5 53 void DS18B20::WriteByte(unsigned byte) {
richardlane 0:769f9b2b30d5 54 for (unsigned bit = 0; bit < 8; ++bit) {
richardlane 0:769f9b2b30d5 55 WriteBit(byte & 0x01); // lsb to msb
richardlane 0:769f9b2b30d5 56 byte >>= 1; // right shift by 1-bit
richardlane 0:769f9b2b30d5 57 }
richardlane 0:769f9b2b30d5 58 }
richardlane 0:769f9b2b30d5 59
richardlane 0:769f9b2b30d5 60 // Read byte from 1-wire.
richardlane 0:769f9b2b30d5 61 unsigned DS18B20::ReadByte() {
richardlane 0:769f9b2b30d5 62 unsigned byte = 0;
richardlane 0:769f9b2b30d5 63 for (unsigned bit = 0; bit < 8; ++bit) {
richardlane 0:769f9b2b30d5 64 byte |= (ReadBit() << bit); // Reads lsb to msb
richardlane 0:769f9b2b30d5 65 }
richardlane 0:769f9b2b30d5 66 return byte;
richardlane 0:769f9b2b30d5 67 }
richardlane 0:769f9b2b30d5 68
richardlane 0:769f9b2b30d5 69 // Set number of bits in the conversion.
richardlane 0:769f9b2b30d5 70 unsigned DS18B20::SetResolution(unsigned resolution) {
richardlane 0:769f9b2b30d5 71 if (Reset() != 0)
richardlane 0:769f9b2b30d5 72 return 1;
richardlane 0:769f9b2b30d5 73 else {
richardlane 0:769f9b2b30d5 74 WriteByte(SKIP_ROM); // Skip ROM
richardlane 0:769f9b2b30d5 75 WriteByte(WRITE_SCRATCHPAD); // WRITE_SCRATCHPAD
richardlane 0:769f9b2b30d5 76 WriteByte(0x7f); // Alarm TH
richardlane 0:769f9b2b30d5 77 WriteByte(0x80); // Alarm TL
richardlane 0:769f9b2b30d5 78 WriteByte(resolution); // 0xx11111 xx=resolution (9-12 bits)
richardlane 0:769f9b2b30d5 79 }
richardlane 0:769f9b2b30d5 80 return 0;
richardlane 0:769f9b2b30d5 81 }
richardlane 0:769f9b2b30d5 82
richardlane 0:769f9b2b30d5 83 // Trigger a temperature conversion but don't read the temperature.
richardlane 0:769f9b2b30d5 84 unsigned DS18B20::DoConversion() {
richardlane 0:769f9b2b30d5 85 if (Reset() != 0)
richardlane 0:769f9b2b30d5 86 return 1;
richardlane 0:769f9b2b30d5 87 else {
richardlane 0:769f9b2b30d5 88 WriteByte(SKIP_ROM); // Skip ROM
richardlane 0:769f9b2b30d5 89 WriteByte(CONVERT); // Convert
richardlane 0:769f9b2b30d5 90 while (ReadBit() == 0)
richardlane 0:769f9b2b30d5 91 ; // wait for conversion to complete
richardlane 0:769f9b2b30d5 92 }
richardlane 0:769f9b2b30d5 93 return 0;
richardlane 0:769f9b2b30d5 94 }
richardlane 0:769f9b2b30d5 95
richardlane 0:769f9b2b30d5 96 // Do Conversion and get temperature as s8.4 sign-extended to 16-bits.
richardlane 0:769f9b2b30d5 97 int DS18B20::RawTemperature() {
richardlane 0:769f9b2b30d5 98 // Perform the temperature conversion.
richardlane 0:769f9b2b30d5 99 if (DoConversion() != 0)
richardlane 0:769f9b2b30d5 100 return INVALID_TEMPERATURE;
richardlane 0:769f9b2b30d5 101 // Read the temperature back.
richardlane 0:769f9b2b30d5 102 if (Reset() != 0)
richardlane 0:769f9b2b30d5 103 return INVALID_TEMPERATURE;
richardlane 0:769f9b2b30d5 104 else {
richardlane 0:769f9b2b30d5 105 WriteByte(SKIP_ROM); // Skip ROM
richardlane 0:769f9b2b30d5 106 WriteByte(READ_SCRATCHPAD); // Read Scrachpad
richardlane 0:769f9b2b30d5 107 unsigned LSB = ReadByte();
richardlane 0:769f9b2b30d5 108 unsigned MSB = ReadByte();
richardlane 0:769f9b2b30d5 109 // Terminate read as we only want temperature
richardlane 0:769f9b2b30d5 110 Reset();
richardlane 0:769f9b2b30d5 111 // Ensure correct sign-extension.
richardlane 0:769f9b2b30d5 112 return (int)((int16_t)((MSB << 8) | LSB));
richardlane 0:769f9b2b30d5 113 }
richardlane 0:769f9b2b30d5 114 }
richardlane 0:769f9b2b30d5 115
richardlane 0:769f9b2b30d5 116 // Read temperature in floating point format.
richardlane 0:769f9b2b30d5 117 float DS18B20::GetTemperature() {
richardlane 0:769f9b2b30d5 118 int temperature = RawTemperature();
richardlane 0:769f9b2b30d5 119 return ((float)temperature) / 16.0;
richardlane 0:769f9b2b30d5 120 }
richardlane 0:769f9b2b30d5 121
richardlane 0:769f9b2b30d5 122 // Read back DS18B20 ROM.
richardlane 0:769f9b2b30d5 123 int DS18B20::ReadROM(DS18B20::ROM_Code_t *ROM_Code) {
richardlane 0:769f9b2b30d5 124 if (Reset() != 0)
richardlane 0:769f9b2b30d5 125 return 1;
richardlane 0:769f9b2b30d5 126 else {
richardlane 0:769f9b2b30d5 127 WriteByte(READ_ROM); // Read ROM
richardlane 0:769f9b2b30d5 128 for (unsigned i = 0; i < 8; ++i) {
richardlane 0:769f9b2b30d5 129 ROM_Code->rom[i] = ReadByte();
richardlane 0:769f9b2b30d5 130 }
richardlane 0:769f9b2b30d5 131 }
richardlane 0:769f9b2b30d5 132 return 0;
richardlane 0:769f9b2b30d5 133 }