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.
Fork of DS1820 by
DS1820.cpp@2:b7ad1da7331a, 2015-03-16 (annotated)
- Committer:
- hudakz
- Date:
- Mon Mar 16 08:52:33 2015 +0000
- Revision:
- 2:b7ad1da7331a
- Parent:
- 1:e4689408d617
- Child:
- 3:a250babd0a9f
Bug fix
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
hudakz | 0:433af64321d5 | 1 | #include "DS1820.h" |
hudakz | 0:433af64321d5 | 2 | |
hudakz | 1:e4689408d617 | 3 | #define DEBUG 0 |
hudakz | 0:433af64321d5 | 4 | |
hudakz | 0:433af64321d5 | 5 | #if DEBUG |
hudakz | 0:433af64321d5 | 6 | extern Serial serial; |
hudakz | 0:433af64321d5 | 7 | #endif |
hudakz | 0:433af64321d5 | 8 | |
hudakz | 0:433af64321d5 | 9 | /** |
hudakz | 0:433af64321d5 | 10 | * @brief Constructs a generic DS1820 sensor |
hudakz | 0:433af64321d5 | 11 | * @note begin() must be called to detect and initialize the actual model |
hudakz | 0:433af64321d5 | 12 | * @param Name of data pin |
hudakz | 0:433af64321d5 | 13 | * @retval |
hudakz | 0:433af64321d5 | 14 | */ |
hudakz | 0:433af64321d5 | 15 | DS1820::DS1820(PinName pin) : |
hudakz | 0:433af64321d5 | 16 | oneWire(pin) { |
hudakz | 0:433af64321d5 | 17 | present = 0; |
hudakz | 0:433af64321d5 | 18 | type_s = 0; |
hudakz | 0:433af64321d5 | 19 | } |
hudakz | 0:433af64321d5 | 20 | |
hudakz | 0:433af64321d5 | 21 | /** |
hudakz | 0:433af64321d5 | 22 | * @brief Constructs a specific model |
hudakz | 0:433af64321d5 | 23 | * @note No need to call begin() to detect and initialize the model |
hudakz | 0:433af64321d5 | 24 | * @param One character model name: 'S', 's', 'B' or 'b' |
hudakz | 0:433af64321d5 | 25 | * Name of data pin |
hudakz | 0:433af64321d5 | 26 | * @retval |
hudakz | 0:433af64321d5 | 27 | */ |
hudakz | 0:433af64321d5 | 28 | DS1820::DS1820(char model, PinName pin) : |
hudakz | 0:433af64321d5 | 29 | oneWire(pin) { |
hudakz | 0:433af64321d5 | 30 | if((model == 'S') or (model == 's')) { |
hudakz | 0:433af64321d5 | 31 | present = 1; |
hudakz | 0:433af64321d5 | 32 | type_s = 1; |
hudakz | 0:433af64321d5 | 33 | } |
hudakz | 0:433af64321d5 | 34 | else if((model == 'B') or (model == 'b')) { |
hudakz | 0:433af64321d5 | 35 | present = 1; |
hudakz | 0:433af64321d5 | 36 | type_s = 0; |
hudakz | 0:433af64321d5 | 37 | } |
hudakz | 0:433af64321d5 | 38 | else |
hudakz | 0:433af64321d5 | 39 | present = 0; |
hudakz | 0:433af64321d5 | 40 | } |
hudakz | 0:433af64321d5 | 41 | |
hudakz | 0:433af64321d5 | 42 | /** |
hudakz | 0:433af64321d5 | 43 | * @brief Detects and initializes the actual DS1820 model |
hudakz | 0:433af64321d5 | 44 | * @note |
hudakz | 0:433af64321d5 | 45 | * @param |
hudakz | 0:433af64321d5 | 46 | * @retval true: if a DS1820 family sensor was detected and initialized |
hudakz | 0:433af64321d5 | 47 | false: otherwise |
hudakz | 0:433af64321d5 | 48 | */ |
hudakz | 0:433af64321d5 | 49 | bool DS1820::begin(void) { |
hudakz | 0:433af64321d5 | 50 | oneWire.reset_search(); |
hudakz | 0:433af64321d5 | 51 | wait_ms(250); |
hudakz | 0:433af64321d5 | 52 | if(!oneWire.search(addr)) { |
hudakz | 0:433af64321d5 | 53 | #if DEBUG |
hudakz | 0:433af64321d5 | 54 | serial.printf("No addresses.\r\n"); |
hudakz | 0:433af64321d5 | 55 | #endif |
hudakz | 0:433af64321d5 | 56 | oneWire.reset_search(); |
hudakz | 0:433af64321d5 | 57 | wait_ms(250); |
hudakz | 0:433af64321d5 | 58 | return false; |
hudakz | 0:433af64321d5 | 59 | } |
hudakz | 0:433af64321d5 | 60 | |
hudakz | 0:433af64321d5 | 61 | #if DEBUG |
hudakz | 0:433af64321d5 | 62 | serial.printf("ROM ="); |
hudakz | 0:433af64321d5 | 63 | for(uint8_t i = 0; i < 8; i++) { |
hudakz | 0:433af64321d5 | 64 | serial.printf(" %x", addr[i]); |
hudakz | 0:433af64321d5 | 65 | } |
hudakz | 0:433af64321d5 | 66 | serial.printf("\r\n"); |
hudakz | 0:433af64321d5 | 67 | #endif |
hudakz | 0:433af64321d5 | 68 | |
hudakz | 0:433af64321d5 | 69 | if(OneWire::crc8(addr, 7) == addr[7]) { |
hudakz | 0:433af64321d5 | 70 | present = 1; |
hudakz | 0:433af64321d5 | 71 | |
hudakz | 0:433af64321d5 | 72 | // the first ROM byte indicates which chip |
hudakz | 0:433af64321d5 | 73 | switch(addr[0]) { |
hudakz | 0:433af64321d5 | 74 | case 0x10: |
hudakz | 0:433af64321d5 | 75 | type_s = 1; |
hudakz | 0:433af64321d5 | 76 | #if DEBUG |
hudakz | 0:433af64321d5 | 77 | serial.printf("DS18S20 or old DS1820\r\n"); |
hudakz | 0:433af64321d5 | 78 | #endif |
hudakz | 0:433af64321d5 | 79 | break; |
hudakz | 0:433af64321d5 | 80 | |
hudakz | 0:433af64321d5 | 81 | case 0x28: |
hudakz | 0:433af64321d5 | 82 | type_s = 0; |
hudakz | 0:433af64321d5 | 83 | #if DEBUG |
hudakz | 0:433af64321d5 | 84 | serial.printf("DS18B20\r\n"); |
hudakz | 0:433af64321d5 | 85 | #endif |
hudakz | 0:433af64321d5 | 86 | break; |
hudakz | 0:433af64321d5 | 87 | |
hudakz | 0:433af64321d5 | 88 | case 0x22: |
hudakz | 0:433af64321d5 | 89 | type_s = 0; |
hudakz | 0:433af64321d5 | 90 | #if DEBUG |
hudakz | 0:433af64321d5 | 91 | serial.printf("DS1822\r\n"); |
hudakz | 0:433af64321d5 | 92 | #endif |
hudakz | 0:433af64321d5 | 93 | break; |
hudakz | 0:433af64321d5 | 94 | |
hudakz | 0:433af64321d5 | 95 | default: |
hudakz | 0:433af64321d5 | 96 | present = 0; |
hudakz | 0:433af64321d5 | 97 | #if DEBUG |
hudakz | 0:433af64321d5 | 98 | serial.printf("Device doesn't belong to the DS1820 family\r\n"); |
hudakz | 2:b7ad1da7331a | 99 | #endif |
hudakz | 0:433af64321d5 | 100 | return false; |
hudakz | 0:433af64321d5 | 101 | } |
hudakz | 0:433af64321d5 | 102 | return true; |
hudakz | 0:433af64321d5 | 103 | } |
hudakz | 2:b7ad1da7331a | 104 | else { |
hudakz | 0:433af64321d5 | 105 | #if DEBUG |
hudakz | 0:433af64321d5 | 106 | serial.printf("Invalid CRC!\r\n"); |
hudakz | 2:b7ad1da7331a | 107 | #endif |
hudakz | 0:433af64321d5 | 108 | return false; |
hudakz | 0:433af64321d5 | 109 | } |
hudakz | 0:433af64321d5 | 110 | } |
hudakz | 0:433af64321d5 | 111 | |
hudakz | 0:433af64321d5 | 112 | /** |
hudakz | 0:433af64321d5 | 113 | * @brief Starts temperature conversion |
hudakz | 0:433af64321d5 | 114 | * @note The time to complete the converion depends on the selected resolusion |
hudakz | 0:433af64321d5 | 115 | * @param |
hudakz | 0:433af64321d5 | 116 | * @retval |
hudakz | 0:433af64321d5 | 117 | */ |
hudakz | 0:433af64321d5 | 118 | void DS1820::startConversion(void) { |
hudakz | 0:433af64321d5 | 119 | if(present) { |
hudakz | 0:433af64321d5 | 120 | oneWire.reset(); |
hudakz | 0:433af64321d5 | 121 | |
hudakz | 0:433af64321d5 | 122 | //oneWire.select(addr); |
hudakz | 0:433af64321d5 | 123 | oneWire.skip(); |
hudakz | 0:433af64321d5 | 124 | oneWire.write(0x44); //start conversion |
hudakz | 0:433af64321d5 | 125 | } |
hudakz | 0:433af64321d5 | 126 | } |
hudakz | 0:433af64321d5 | 127 | |
hudakz | 0:433af64321d5 | 128 | /** |
hudakz | 0:433af64321d5 | 129 | * @brief Reads temperature from the chip's scratchpad |
hudakz | 0:433af64321d5 | 130 | * @note |
hudakz | 0:433af64321d5 | 131 | * @param |
hudakz | 0:433af64321d5 | 132 | * @retval Floating point temperature value |
hudakz | 0:433af64321d5 | 133 | */ |
hudakz | 0:433af64321d5 | 134 | float DS1820::read(void) { |
hudakz | 0:433af64321d5 | 135 | if(present) { |
hudakz | 0:433af64321d5 | 136 | oneWire.reset(); |
hudakz | 0:433af64321d5 | 137 | oneWire.skip(); |
hudakz | 0:433af64321d5 | 138 | oneWire.write(0xBE); // to read Scratchpad |
hudakz | 0:433af64321d5 | 139 | for(uint8_t i = 0; i < 9; i++) |
hudakz | 0:433af64321d5 | 140 | data[i] = oneWire.read(); |
hudakz | 0:433af64321d5 | 141 | |
hudakz | 0:433af64321d5 | 142 | // Convert the raw bytes to a 16bit signed fixed point value : |
hudakz | 0:433af64321d5 | 143 | // 1 sign bit, 7 integer bits, 8 fractional bits (two’s compliment |
hudakz | 0:433af64321d5 | 144 | // ie. the LSB of the 16bit binary number represents 1/256th of a unit). |
hudakz | 0:433af64321d5 | 145 | |
hudakz | 0:433af64321d5 | 146 | uint16_t* p_word = reinterpret_cast < uint16_t * > (&data[0]); |
hudakz | 0:433af64321d5 | 147 | |
hudakz | 0:433af64321d5 | 148 | #if DEBUG |
hudakz | 0:433af64321d5 | 149 | serial.printf("raw = %#x\r\n", *p_word); |
hudakz | 0:433af64321d5 | 150 | #endif |
hudakz | 0:433af64321d5 | 151 | |
hudakz | 0:433af64321d5 | 152 | |
hudakz | 0:433af64321d5 | 153 | if(type_s) { |
hudakz | 0:433af64321d5 | 154 | *p_word = *p_word << 3; // default 9 bit resolution |
hudakz | 0:433af64321d5 | 155 | if(data[7] == 0x10) { |
hudakz | 0:433af64321d5 | 156 | |
hudakz | 0:433af64321d5 | 157 | // "count remain" gives full 12 bit resolution |
hudakz | 0:433af64321d5 | 158 | *p_word = (*p_word & 0xFFF0) + 12 - data[6]; |
hudakz | 0:433af64321d5 | 159 | } |
hudakz | 0:433af64321d5 | 160 | |
hudakz | 0:433af64321d5 | 161 | *p_word = *p_word << 4; |
hudakz | 0:433af64321d5 | 162 | return(toFloat(*p_word)); |
hudakz | 0:433af64321d5 | 163 | } |
hudakz | 0:433af64321d5 | 164 | else { |
hudakz | 0:433af64321d5 | 165 | uint8_t cfg = (data[4] & 0x60); |
hudakz | 0:433af64321d5 | 166 | // at lower res, the low bits are undefined, so let's zero them |
hudakz | 0:433af64321d5 | 167 | |
hudakz | 0:433af64321d5 | 168 | if(cfg == 0x00) |
hudakz | 0:433af64321d5 | 169 | *p_word = *p_word &~7; // 9 bit resolution, 93.75 ms |
hudakz | 0:433af64321d5 | 170 | else |
hudakz | 0:433af64321d5 | 171 | if(cfg == 0x20) |
hudakz | 0:433af64321d5 | 172 | *p_word = *p_word &~3; // 10 bit res, 187.5 ms |
hudakz | 0:433af64321d5 | 173 | else |
hudakz | 0:433af64321d5 | 174 | if(cfg == 0x40) |
hudakz | 0:433af64321d5 | 175 | *p_word = *p_word &~1; // 11 bit res, 375 ms |
hudakz | 0:433af64321d5 | 176 | *p_word = *p_word << 4; // default is 12 bit resolution |
hudakz | 0:433af64321d5 | 177 | return(toFloat(*p_word)); |
hudakz | 0:433af64321d5 | 178 | } |
hudakz | 0:433af64321d5 | 179 | } |
hudakz | 0:433af64321d5 | 180 | else |
hudakz | 0:433af64321d5 | 181 | return 0; |
hudakz | 0:433af64321d5 | 182 | } |
hudakz | 0:433af64321d5 | 183 | |
hudakz | 0:433af64321d5 | 184 | /** |
hudakz | 0:433af64321d5 | 185 | * @brief Converts a 16bit signed fixed point value to float |
hudakz | 0:433af64321d5 | 186 | * @note The 16bit unsigned integer represnts actually |
hudakz | 0:433af64321d5 | 187 | * a 16bit signed fixed point value: |
hudakz | 0:433af64321d5 | 188 | * 1 sign bit, 7 integer bits, 8 fractional bits |
hudakz | 0:433af64321d5 | 189 | * (two’s compliment ie. the LSB of the 16bit binary number |
hudakz | 0:433af64321d5 | 190 | * represents 1/256th of a unit). |
hudakz | 0:433af64321d5 | 191 | * @param 16bit unsigned integer |
hudakz | 0:433af64321d5 | 192 | * @retval Floating point temperature value |
hudakz | 0:433af64321d5 | 193 | */ |
hudakz | 0:433af64321d5 | 194 | float DS1820::toFloat(uint16_t word) { |
hudakz | 0:433af64321d5 | 195 | //word = word << 4; |
hudakz | 0:433af64321d5 | 196 | if(word & 0x8000) |
hudakz | 0:433af64321d5 | 197 | return (-float(uint16_t(~word + 1)) / 256.0f); |
hudakz | 0:433af64321d5 | 198 | else |
hudakz | 0:433af64321d5 | 199 | return (float(word) / 256.0f); |
hudakz | 0:433af64321d5 | 200 | } |
hudakz | 0:433af64321d5 | 201 |