ze

Dependencies:   mbed WakeUp OneWire

Committer:
mangalho_eanes
Date:
Sun Nov 22 20:11:11 2020 +0000
Revision:
2:15f2d7d650bb
Commit message (required)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mangalho_eanes 2:15f2d7d650bb 1 /*
mangalho_eanes 2:15f2d7d650bb 2 * Dallas' DS1820 family temperature sensor.
mangalho_eanes 2:15f2d7d650bb 3 * This library depends on the OneWire library (Dallas' 1-Wire bus protocol implementation)
mangalho_eanes 2:15f2d7d650bb 4 * available at <http://developer.mbed.org/users/hudakz/code/OneWire/>
mangalho_eanes 2:15f2d7d650bb 5 *
mangalho_eanes 2:15f2d7d650bb 6 * Example of use:
mangalho_eanes 2:15f2d7d650bb 7 *
mangalho_eanes 2:15f2d7d650bb 8 * Single sensor.
mangalho_eanes 2:15f2d7d650bb 9 *
mangalho_eanes 2:15f2d7d650bb 10 * #include "mbed.h"
mangalho_eanes 2:15f2d7d650bb 11 * #include "DS1820.h"
mangalho_eanes 2:15f2d7d650bb 12 *
mangalho_eanes 2:15f2d7d650bb 13 * Serial pc(USBTX, USBRX);
mangalho_eanes 2:15f2d7d650bb 14 * DigitalOut led(LED1);
mangalho_eanes 2:15f2d7d650bb 15 * OneWire oneWire(D8); // substitute D8 with actual mbed pin name connected 1-wire bus
mangalho_eanes 2:15f2d7d650bb 16 * float temp = 0;
mangalho_eanes 2:15f2d7d650bb 17 * int result = 0;
mangalho_eanes 2:15f2d7d650bb 18 *
mangalho_eanes 2:15f2d7d650bb 19 * int main()
mangalho_eanes 2:15f2d7d650bb 20 * {
mangalho_eanes 2:15f2d7d650bb 21 * pc.printf("\r\n--Starting--\r\n");
mangalho_eanes 2:15f2d7d650bb 22 * if (ds1820.begin()) {
mangalho_eanes 2:15f2d7d650bb 23 * while (1) {
mangalho_eanes 2:15f2d7d650bb 24 * ds1820.startConversion(); // start temperature conversion from analog to digital
mangalho_eanes 2:15f2d7d650bb 25 * ThisThread::sleep_for(1000);// let DS1820 complete the temperature conversion
mangalho_eanes 2:15f2d7d650bb 26 * result = ds1820.read(temp); // read temperature from DS1820 and perform cyclic redundancy check (CRC)
mangalho_eanes 2:15f2d7d650bb 27 * switch (result) {
mangalho_eanes 2:15f2d7d650bb 28 * case 0: // no errors -> 'temp' contains the value of measured temperature
mangalho_eanes 2:15f2d7d650bb 29 * pc.printf("temp = %3.1f%cC\r\n", temp, 176);
mangalho_eanes 2:15f2d7d650bb 30 * break;
mangalho_eanes 2:15f2d7d650bb 31 *
mangalho_eanes 2:15f2d7d650bb 32 * case 1: // no sensor present -> 'temp' is not updated
mangalho_eanes 2:15f2d7d650bb 33 * pc.printf("no sensor present\n\r");
mangalho_eanes 2:15f2d7d650bb 34 * break;
mangalho_eanes 2:15f2d7d650bb 35 *
mangalho_eanes 2:15f2d7d650bb 36 * case 2: // CRC error -> 'temp' is not updated
mangalho_eanes 2:15f2d7d650bb 37 * pc.printf("CRC error\r\n");
mangalho_eanes 2:15f2d7d650bb 38 * }
mangalho_eanes 2:15f2d7d650bb 39 *
mangalho_eanes 2:15f2d7d650bb 40 * led = !led;
mangalho_eanes 2:15f2d7d650bb 41 * }
mangalho_eanes 2:15f2d7d650bb 42 * }
mangalho_eanes 2:15f2d7d650bb 43 * else
mangalho_eanes 2:15f2d7d650bb 44 * pc.printf("No DS1820 sensor found!\r\n");
mangalho_eanes 2:15f2d7d650bb 45 * }
mangalho_eanes 2:15f2d7d650bb 46 *
mangalho_eanes 2:15f2d7d650bb 47 *
mangalho_eanes 2:15f2d7d650bb 48 * More sensors connected to the same 1-wire bus.
mangalho_eanes 2:15f2d7d650bb 49 *
mangalho_eanes 2:15f2d7d650bb 50 * #include "mbed.h"
mangalho_eanes 2:15f2d7d650bb 51 * #include "DS1820.h"
mangalho_eanes 2:15f2d7d650bb 52 *
mangalho_eanes 2:15f2d7d650bb 53 * #define SENSORS_COUNT 64 // number of DS1820 sensors to be connected to the 1-wire bus (max 256)
mangalho_eanes 2:15f2d7d650bb 54 *
mangalho_eanes 2:15f2d7d650bb 55 * Serial pc(USBTX, USBRX);
mangalho_eanes 2:15f2d7d650bb 56 * DigitalOut led(LED1);
mangalho_eanes 2:15f2d7d650bb 57 * OneWire oneWire(D8); // substitute D8 with actual mbed pin name connected to the DS1820 data pin
mangalho_eanes 2:15f2d7d650bb 58 * DS1820* ds1820[SENSORS_COUNT];
mangalho_eanes 2:15f2d7d650bb 59 * int sensors_found = 0; // counts the actually found DS1820 sensors
mangalho_eanes 2:15f2d7d650bb 60 * float temp = 0;
mangalho_eanes 2:15f2d7d650bb 61 * int result = 0;
mangalho_eanes 2:15f2d7d650bb 62 *
mangalho_eanes 2:15f2d7d650bb 63 * int main() {
mangalho_eanes 2:15f2d7d650bb 64 * int i = 0;
mangalho_eanes 2:15f2d7d650bb 65 *
mangalho_eanes 2:15f2d7d650bb 66 * pc.printf("\r\n Starting \r\n");
mangalho_eanes 2:15f2d7d650bb 67 * //Enumerate (i.e. detect) DS1820 sensors on the 1-wire bus
mangalho_eanes 2:15f2d7d650bb 68 * for(i = 0; i < SENSORS_COUNT; i++) {
mangalho_eanes 2:15f2d7d650bb 69 * ds1820[i] = new DS1820(&oneWire);
mangalho_eanes 2:15f2d7d650bb 70 * if(!ds1820[i]->begin()) {
mangalho_eanes 2:15f2d7d650bb 71 * delete ds1820[i];
mangalho_eanes 2:15f2d7d650bb 72 * break;
mangalho_eanes 2:15f2d7d650bb 73 * }
mangalho_eanes 2:15f2d7d650bb 74 * }
mangalho_eanes 2:15f2d7d650bb 75 *
mangalho_eanes 2:15f2d7d650bb 76 * sensors_found = i;
mangalho_eanes 2:15f2d7d650bb 77 *
mangalho_eanes 2:15f2d7d650bb 78 * if (sensors_found == 0) {
mangalho_eanes 2:15f2d7d650bb 79 * pc.printf("No DS1820 sensor found!\r\n");
mangalho_eanes 2:15f2d7d650bb 80 * return -1;
mangalho_eanes 2:15f2d7d650bb 81 * }
mangalho_eanes 2:15f2d7d650bb 82 * else
mangalho_eanes 2:15f2d7d650bb 83 * pc.printf("Found %d sensors.\r\n", sensors_found);
mangalho_eanes 2:15f2d7d650bb 84 *
mangalho_eanes 2:15f2d7d650bb 85 * while(1) {
mangalho_eanes 2:15f2d7d650bb 86 * pc.printf("-------------------\r\n");
mangalho_eanes 2:15f2d7d650bb 87 * for(i = 0; i < sensors_found; i++)
mangalho_eanes 2:15f2d7d650bb 88 * ds1820[i]->startConversion(); // start temperature conversion from analog to digital
mangalho_eanes 2:15f2d7d650bb 89 * ThisThread::sleep_for(1000); // let DS1820s complete the temperature conversion
mangalho_eanes 2:15f2d7d650bb 90 * for(int i = 0; i < sensors_found; i++) {
mangalho_eanes 2:15f2d7d650bb 91 * if(ds1820[i]->isPresent())
mangalho_eanes 2:15f2d7d650bb 92 * pc.printf("temp[%d] = %3.1f%cC\r\n", i, ds1820[i]->read(), 176); // read temperature
mangalho_eanes 2:15f2d7d650bb 93 * }
mangalho_eanes 2:15f2d7d650bb 94 * }
mangalho_eanes 2:15f2d7d650bb 95 * }
mangalho_eanes 2:15f2d7d650bb 96 *
mangalho_eanes 2:15f2d7d650bb 97 */
mangalho_eanes 2:15f2d7d650bb 98
mangalho_eanes 2:15f2d7d650bb 99 #include "DS1820.h"
mangalho_eanes 2:15f2d7d650bb 100
mangalho_eanes 2:15f2d7d650bb 101 #define DEBUG 0
mangalho_eanes 2:15f2d7d650bb 102
mangalho_eanes 2:15f2d7d650bb 103 //* Initializing static members
mangalho_eanes 2:15f2d7d650bb 104 uint8_t DS1820::lastAddr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
mangalho_eanes 2:15f2d7d650bb 105 /**
mangalho_eanes 2:15f2d7d650bb 106 * @brief Constructs a generic DS1820 sensor
mangalho_eanes 2:15f2d7d650bb 107 * @note begin() must be called to detect and initialize the actual model
mangalho_eanes 2:15f2d7d650bb 108 * @param pin: Name of data pin
mangalho_eanes 2:15f2d7d650bb 109 * @retval
mangalho_eanes 2:15f2d7d650bb 110 */
mangalho_eanes 2:15f2d7d650bb 111 DS1820::DS1820(PinName pin, int sample_point_us /* = 13 */) {
mangalho_eanes 2:15f2d7d650bb 112 oneWire = new OneWire(pin, sample_point_us);
mangalho_eanes 2:15f2d7d650bb 113 present = false;
mangalho_eanes 2:15f2d7d650bb 114 model_s = false;
mangalho_eanes 2:15f2d7d650bb 115 }
mangalho_eanes 2:15f2d7d650bb 116
mangalho_eanes 2:15f2d7d650bb 117 /**
mangalho_eanes 2:15f2d7d650bb 118 * @brief Constructs a generic DS1820 sensor
mangalho_eanes 2:15f2d7d650bb 119 * @note begin() must be called to detect and initialize the actual model
mangalho_eanes 2:15f2d7d650bb 120 * @param pin: Name of data pin
mangalho_eanes 2:15f2d7d650bb 121 * @retval
mangalho_eanes 2:15f2d7d650bb 122 */
mangalho_eanes 2:15f2d7d650bb 123 DS1820::DS1820(OneWire* wire) :
mangalho_eanes 2:15f2d7d650bb 124 oneWire(wire) {
mangalho_eanes 2:15f2d7d650bb 125 present = false;
mangalho_eanes 2:15f2d7d650bb 126 model_s = false;
mangalho_eanes 2:15f2d7d650bb 127 }
mangalho_eanes 2:15f2d7d650bb 128
mangalho_eanes 2:15f2d7d650bb 129 /**
mangalho_eanes 2:15f2d7d650bb 130 * @brief Detects and initializes the actual DS1820 model
mangalho_eanes 2:15f2d7d650bb 131 * @note
mangalho_eanes 2:15f2d7d650bb 132 * @param
mangalho_eanes 2:15f2d7d650bb 133 * @retval true: if a DS1820 family sensor was detected and initialized
mangalho_eanes 2:15f2d7d650bb 134 false: otherwise
mangalho_eanes 2:15f2d7d650bb 135 */
mangalho_eanes 2:15f2d7d650bb 136 bool DS1820::begin(void) {
mangalho_eanes 2:15f2d7d650bb 137 #if DEBUG
mangalho_eanes 2:15f2d7d650bb 138 printf("lastAddr =");
mangalho_eanes 2:15f2d7d650bb 139 for(uint8_t i = 0; i < 8; i++) {
mangalho_eanes 2:15f2d7d650bb 140 printf(" %x", lastAddr[i]);
mangalho_eanes 2:15f2d7d650bb 141 }
mangalho_eanes 2:15f2d7d650bb 142 printf("\r\n");
mangalho_eanes 2:15f2d7d650bb 143 #endif
mangalho_eanes 2:15f2d7d650bb 144 if(!oneWire->search(lastAddr)) {
mangalho_eanes 2:15f2d7d650bb 145 #if DEBUG
mangalho_eanes 2:15f2d7d650bb 146 printf("No addresses.\r\n");
mangalho_eanes 2:15f2d7d650bb 147 #endif
mangalho_eanes 2:15f2d7d650bb 148 oneWire->reset_search();
mangalho_eanes 2:15f2d7d650bb 149 //ThisThread::sleep_for(250);
mangalho_eanes 2:15f2d7d650bb 150 return false;
mangalho_eanes 2:15f2d7d650bb 151 }
mangalho_eanes 2:15f2d7d650bb 152
mangalho_eanes 2:15f2d7d650bb 153 for (int i = 0; i < 8; i++)
mangalho_eanes 2:15f2d7d650bb 154 addr[i] = lastAddr[i];
mangalho_eanes 2:15f2d7d650bb 155
mangalho_eanes 2:15f2d7d650bb 156 #if DEBUG
mangalho_eanes 2:15f2d7d650bb 157 printf("ROM =");
mangalho_eanes 2:15f2d7d650bb 158 for(uint8_t i = 0; i < 8; i++) {
mangalho_eanes 2:15f2d7d650bb 159 printf(" %x", addr[i]);
mangalho_eanes 2:15f2d7d650bb 160 }
mangalho_eanes 2:15f2d7d650bb 161 printf("\r\n");
mangalho_eanes 2:15f2d7d650bb 162 #endif
mangalho_eanes 2:15f2d7d650bb 163
mangalho_eanes 2:15f2d7d650bb 164 if(OneWire::crc8(addr, 7) == addr[7]) {
mangalho_eanes 2:15f2d7d650bb 165 present = true;
mangalho_eanes 2:15f2d7d650bb 166
mangalho_eanes 2:15f2d7d650bb 167 // the first ROM byte indicates which chip
mangalho_eanes 2:15f2d7d650bb 168 switch(addr[0]) {
mangalho_eanes 2:15f2d7d650bb 169 case 0x10:
mangalho_eanes 2:15f2d7d650bb 170 model_s = true;
mangalho_eanes 2:15f2d7d650bb 171 #if DEBUG
mangalho_eanes 2:15f2d7d650bb 172 printf("DS18S20 or old DS1820\r\n");
mangalho_eanes 2:15f2d7d650bb 173 #endif
mangalho_eanes 2:15f2d7d650bb 174 break;
mangalho_eanes 2:15f2d7d650bb 175
mangalho_eanes 2:15f2d7d650bb 176 case 0x28:
mangalho_eanes 2:15f2d7d650bb 177 model_s = false;
mangalho_eanes 2:15f2d7d650bb 178 #if DEBUG
mangalho_eanes 2:15f2d7d650bb 179 printf("DS18B20\r\n");
mangalho_eanes 2:15f2d7d650bb 180 #endif
mangalho_eanes 2:15f2d7d650bb 181 break;
mangalho_eanes 2:15f2d7d650bb 182
mangalho_eanes 2:15f2d7d650bb 183 case 0x22:
mangalho_eanes 2:15f2d7d650bb 184 model_s = false;
mangalho_eanes 2:15f2d7d650bb 185 #if DEBUG
mangalho_eanes 2:15f2d7d650bb 186 printf("DS1822\r\n");
mangalho_eanes 2:15f2d7d650bb 187 #endif
mangalho_eanes 2:15f2d7d650bb 188 break;
mangalho_eanes 2:15f2d7d650bb 189
mangalho_eanes 2:15f2d7d650bb 190 default:
mangalho_eanes 2:15f2d7d650bb 191 present = false;
mangalho_eanes 2:15f2d7d650bb 192 #if DEBUG
mangalho_eanes 2:15f2d7d650bb 193 printf("Device doesn't belong to the DS1820 family\r\n");
mangalho_eanes 2:15f2d7d650bb 194 #endif
mangalho_eanes 2:15f2d7d650bb 195 return false;
mangalho_eanes 2:15f2d7d650bb 196 }
mangalho_eanes 2:15f2d7d650bb 197 return true;
mangalho_eanes 2:15f2d7d650bb 198 }
mangalho_eanes 2:15f2d7d650bb 199 else {
mangalho_eanes 2:15f2d7d650bb 200 #if DEBUG
mangalho_eanes 2:15f2d7d650bb 201 printf("Invalid CRC!\r\n");
mangalho_eanes 2:15f2d7d650bb 202 #endif
mangalho_eanes 2:15f2d7d650bb 203 return false;
mangalho_eanes 2:15f2d7d650bb 204 }
mangalho_eanes 2:15f2d7d650bb 205 }
mangalho_eanes 2:15f2d7d650bb 206
mangalho_eanes 2:15f2d7d650bb 207 /**
mangalho_eanes 2:15f2d7d650bb 208 * @brief Informs about presence of a DS1820 sensor.
mangalho_eanes 2:15f2d7d650bb 209 * @note begin() shall be called before using this function
mangalho_eanes 2:15f2d7d650bb 210 * if a generic DS1820 instance was created by the user.
mangalho_eanes 2:15f2d7d650bb 211 * No need to call begin() for a specific DS1820 instance.
mangalho_eanes 2:15f2d7d650bb 212 * @param
mangalho_eanes 2:15f2d7d650bb 213 * @retval true: when a DS1820 sensor is present
mangalho_eanes 2:15f2d7d650bb 214 * false: otherwise
mangalho_eanes 2:15f2d7d650bb 215 */
mangalho_eanes 2:15f2d7d650bb 216 bool DS1820::isPresent(void) {
mangalho_eanes 2:15f2d7d650bb 217 return present;
mangalho_eanes 2:15f2d7d650bb 218 }
mangalho_eanes 2:15f2d7d650bb 219
mangalho_eanes 2:15f2d7d650bb 220 /**
mangalho_eanes 2:15f2d7d650bb 221 * @brief Sets temperature-to-digital conversion resolution.
mangalho_eanes 2:15f2d7d650bb 222 * @note The configuration register allows the user to set the resolution
mangalho_eanes 2:15f2d7d650bb 223 * of the temperature-to-digital conversion to 9, 10, 11, or 12 bits.
mangalho_eanes 2:15f2d7d650bb 224 * Defaults to 12-bit resolution for DS18B20.
mangalho_eanes 2:15f2d7d650bb 225 * DS18S20 allows only 9-bit resolution.
mangalho_eanes 2:15f2d7d650bb 226 * @param res: Resolution of the temperature-to-digital conversion in bits.
mangalho_eanes 2:15f2d7d650bb 227 * @retval
mangalho_eanes 2:15f2d7d650bb 228 */
mangalho_eanes 2:15f2d7d650bb 229 void DS1820::setResolution(uint8_t res) {
mangalho_eanes 2:15f2d7d650bb 230 // keep resolution within limits
mangalho_eanes 2:15f2d7d650bb 231 if(res > 12)
mangalho_eanes 2:15f2d7d650bb 232 res = 12;
mangalho_eanes 2:15f2d7d650bb 233 if(res < 9)
mangalho_eanes 2:15f2d7d650bb 234 res = 9;
mangalho_eanes 2:15f2d7d650bb 235 if(model_s)
mangalho_eanes 2:15f2d7d650bb 236 res = 9;
mangalho_eanes 2:15f2d7d650bb 237
mangalho_eanes 2:15f2d7d650bb 238 oneWire->reset();
mangalho_eanes 2:15f2d7d650bb 239 oneWire->select(addr);
mangalho_eanes 2:15f2d7d650bb 240 oneWire->write_byte(0xBE); // to read Scratchpad
mangalho_eanes 2:15f2d7d650bb 241 for(uint8_t i = 0; i < 9; i++) // read Scratchpad bytes
mangalho_eanes 2:15f2d7d650bb 242 data[i] = oneWire->read_byte();
mangalho_eanes 2:15f2d7d650bb 243
mangalho_eanes 2:15f2d7d650bb 244 data[4] |= (res - 9) << 5; // update configuration byte (set resolution)
mangalho_eanes 2:15f2d7d650bb 245 oneWire->reset();
mangalho_eanes 2:15f2d7d650bb 246 oneWire->select(addr);
mangalho_eanes 2:15f2d7d650bb 247 oneWire->write_byte(0x4E); // to write into Scratchpad
mangalho_eanes 2:15f2d7d650bb 248 for(uint8_t i = 2; i < 5; i++) // write three bytes (2nd, 3rd, 4th) into Scratchpad
mangalho_eanes 2:15f2d7d650bb 249 oneWire->write_byte(data[i]);
mangalho_eanes 2:15f2d7d650bb 250 }
mangalho_eanes 2:15f2d7d650bb 251
mangalho_eanes 2:15f2d7d650bb 252 /**
mangalho_eanes 2:15f2d7d650bb 253 * @brief Starts temperature conversion
mangalho_eanes 2:15f2d7d650bb 254 * @note The time to complete the converion depends on the selected resolution:
mangalho_eanes 2:15f2d7d650bb 255 * 9-bit resolution -> max conversion time = 93.75ms
mangalho_eanes 2:15f2d7d650bb 256 * 10-bit resolution -> max conversion time = 187.5ms
mangalho_eanes 2:15f2d7d650bb 257 * 11-bit resolution -> max conversion time = 375ms
mangalho_eanes 2:15f2d7d650bb 258 * 12-bit resolution -> max conversion time = 750ms
mangalho_eanes 2:15f2d7d650bb 259 * @param
mangalho_eanes 2:15f2d7d650bb 260 * @retval
mangalho_eanes 2:15f2d7d650bb 261 */
mangalho_eanes 2:15f2d7d650bb 262 void DS1820::startConversion(void) {
mangalho_eanes 2:15f2d7d650bb 263 if(present) {
mangalho_eanes 2:15f2d7d650bb 264 oneWire->reset();
mangalho_eanes 2:15f2d7d650bb 265 oneWire->select(addr);
mangalho_eanes 2:15f2d7d650bb 266 oneWire->write_byte(0x44); //start temperature conversion
mangalho_eanes 2:15f2d7d650bb 267 }
mangalho_eanes 2:15f2d7d650bb 268 }
mangalho_eanes 2:15f2d7d650bb 269
mangalho_eanes 2:15f2d7d650bb 270 /**
mangalho_eanes 2:15f2d7d650bb 271 * @brief Reads temperature from the chip's Scratchpad
mangalho_eanes 2:15f2d7d650bb 272 * @note
mangalho_eanes 2:15f2d7d650bb 273 * @param
mangalho_eanes 2:15f2d7d650bb 274 * @retval Floating point temperature value
mangalho_eanes 2:15f2d7d650bb 275 */
mangalho_eanes 2:15f2d7d650bb 276 float DS1820::read(void) {
mangalho_eanes 2:15f2d7d650bb 277 if(present) {
mangalho_eanes 2:15f2d7d650bb 278 oneWire->reset();
mangalho_eanes 2:15f2d7d650bb 279 oneWire->select(addr);
mangalho_eanes 2:15f2d7d650bb 280 oneWire->write_byte(0xBE); // to read Scratchpad
mangalho_eanes 2:15f2d7d650bb 281 for(uint8_t i = 0; i < 9; i++) // reading scratchpad registers
mangalho_eanes 2:15f2d7d650bb 282 data[i] = oneWire->read_byte();
mangalho_eanes 2:15f2d7d650bb 283
mangalho_eanes 2:15f2d7d650bb 284 // Convert the raw bytes to a 16-bit unsigned value
mangalho_eanes 2:15f2d7d650bb 285 uint16_t* p_word = reinterpret_cast < uint16_t * > (&data[0]);
mangalho_eanes 2:15f2d7d650bb 286
mangalho_eanes 2:15f2d7d650bb 287 #if DEBUG
mangalho_eanes 2:15f2d7d650bb 288 printf("raw = %#x\r\n", *p_word);
mangalho_eanes 2:15f2d7d650bb 289 #endif
mangalho_eanes 2:15f2d7d650bb 290
mangalho_eanes 2:15f2d7d650bb 291 if(model_s) {
mangalho_eanes 2:15f2d7d650bb 292 *p_word = *p_word << 3; // 9-bit resolution
mangalho_eanes 2:15f2d7d650bb 293 if(data[7] == 0x10) {
mangalho_eanes 2:15f2d7d650bb 294
mangalho_eanes 2:15f2d7d650bb 295 // "count remain" gives full 12-bit resolution
mangalho_eanes 2:15f2d7d650bb 296 *p_word = (*p_word & 0xFFF0) + 12 - data[6];
mangalho_eanes 2:15f2d7d650bb 297 }
mangalho_eanes 2:15f2d7d650bb 298 }
mangalho_eanes 2:15f2d7d650bb 299 else {
mangalho_eanes 2:15f2d7d650bb 300 uint8_t cfg = (data[4] & 0x60); // default 12-bit resolution
mangalho_eanes 2:15f2d7d650bb 301
mangalho_eanes 2:15f2d7d650bb 302 // at lower resolution, the low bits are undefined, so let's clear them
mangalho_eanes 2:15f2d7d650bb 303 if(cfg == 0x00)
mangalho_eanes 2:15f2d7d650bb 304 *p_word = *p_word &~7; // 9-bit resolution
mangalho_eanes 2:15f2d7d650bb 305 else
mangalho_eanes 2:15f2d7d650bb 306 if(cfg == 0x20)
mangalho_eanes 2:15f2d7d650bb 307 *p_word = *p_word &~3; // 10-bit resolution
mangalho_eanes 2:15f2d7d650bb 308 else
mangalho_eanes 2:15f2d7d650bb 309 if(cfg == 0x40)
mangalho_eanes 2:15f2d7d650bb 310 *p_word = *p_word &~1; // 11-bit resolution
mangalho_eanes 2:15f2d7d650bb 311
mangalho_eanes 2:15f2d7d650bb 312 }
mangalho_eanes 2:15f2d7d650bb 313
mangalho_eanes 2:15f2d7d650bb 314 // Convert the raw bytes to a 16-bit signed fixed point value :
mangalho_eanes 2:15f2d7d650bb 315 // 1 sign bit, 7 integer bits, 8 fractional bits (two’s compliment
mangalho_eanes 2:15f2d7d650bb 316 // and the LSB of the 16-bit binary number represents 1/256th of a unit).
mangalho_eanes 2:15f2d7d650bb 317 *p_word = *p_word << 4;
mangalho_eanes 2:15f2d7d650bb 318
mangalho_eanes 2:15f2d7d650bb 319 // Convert to floating point value
mangalho_eanes 2:15f2d7d650bb 320 return(toFloat(*p_word));
mangalho_eanes 2:15f2d7d650bb 321 }
mangalho_eanes 2:15f2d7d650bb 322 else
mangalho_eanes 2:15f2d7d650bb 323 return 0;
mangalho_eanes 2:15f2d7d650bb 324 }
mangalho_eanes 2:15f2d7d650bb 325
mangalho_eanes 2:15f2d7d650bb 326 /**
mangalho_eanes 2:15f2d7d650bb 327 * @brief Reads temperature from chip's scratchpad.
mangalho_eanes 2:15f2d7d650bb 328 * @note Verifies data integrity by calculating cyclic redundancy check (CRC).
mangalho_eanes 2:15f2d7d650bb 329 * If the calculated CRC dosn't match the one stored in chip's scratchpad register
mangalho_eanes 2:15f2d7d650bb 330 * the temperature variable is not updated and CRC error code is returned.
mangalho_eanes 2:15f2d7d650bb 331 * @param temp: The temperature variable to be updated by this routine.
mangalho_eanes 2:15f2d7d650bb 332 * (It's passed as reference to floating point.)
mangalho_eanes 2:15f2d7d650bb 333 * @retval error code:
mangalho_eanes 2:15f2d7d650bb 334 * 0 - no errors ('temp' contains the temperature measured)
mangalho_eanes 2:15f2d7d650bb 335 * 1 - sensor not present ('temp' is not updated)
mangalho_eanes 2:15f2d7d650bb 336 * 2 - CRC error ('temp' is not updated)
mangalho_eanes 2:15f2d7d650bb 337 */
mangalho_eanes 2:15f2d7d650bb 338 uint8_t DS1820::read(float& temp) {
mangalho_eanes 2:15f2d7d650bb 339 if(present) {
mangalho_eanes 2:15f2d7d650bb 340 oneWire->reset();
mangalho_eanes 2:15f2d7d650bb 341 oneWire->select(addr);
mangalho_eanes 2:15f2d7d650bb 342 oneWire->write_byte(0xBE); // to read Scratchpad
mangalho_eanes 2:15f2d7d650bb 343 for(uint8_t i = 0; i < 9; i++) // reading scratchpad registers
mangalho_eanes 2:15f2d7d650bb 344 data[i] = oneWire->read_byte();
mangalho_eanes 2:15f2d7d650bb 345
mangalho_eanes 2:15f2d7d650bb 346 if(oneWire->crc8(data, 8) != data[8]) // if calculated CRC does not match the stored one
mangalho_eanes 2:15f2d7d650bb 347 {
mangalho_eanes 2:15f2d7d650bb 348 #if DEBUG
mangalho_eanes 2:15f2d7d650bb 349 for(uint8_t i = 0; i < 9; i++)
mangalho_eanes 2:15f2d7d650bb 350 printf("data[%d]=0x%.2x\r\n", i, data[i]);
mangalho_eanes 2:15f2d7d650bb 351 #endif
mangalho_eanes 2:15f2d7d650bb 352 return 2; // return with CRC error
mangalho_eanes 2:15f2d7d650bb 353 }
mangalho_eanes 2:15f2d7d650bb 354
mangalho_eanes 2:15f2d7d650bb 355 // Convert the raw bytes to a 16bit unsigned value
mangalho_eanes 2:15f2d7d650bb 356 uint16_t* p_word = reinterpret_cast < uint16_t * > (&data[0]);
mangalho_eanes 2:15f2d7d650bb 357
mangalho_eanes 2:15f2d7d650bb 358 #if DEBUG
mangalho_eanes 2:15f2d7d650bb 359 printf("raw = %#x\r\n", *p_word);
mangalho_eanes 2:15f2d7d650bb 360 #endif
mangalho_eanes 2:15f2d7d650bb 361
mangalho_eanes 2:15f2d7d650bb 362 if(model_s) {
mangalho_eanes 2:15f2d7d650bb 363 *p_word = *p_word << 3; // 9 bit resolution, max conversion time = 750ms
mangalho_eanes 2:15f2d7d650bb 364 if(data[7] == 0x10) {
mangalho_eanes 2:15f2d7d650bb 365
mangalho_eanes 2:15f2d7d650bb 366 // "count remain" gives full 12 bit resolution
mangalho_eanes 2:15f2d7d650bb 367 *p_word = (*p_word & 0xFFF0) + 12 - data[6];
mangalho_eanes 2:15f2d7d650bb 368 }
mangalho_eanes 2:15f2d7d650bb 369
mangalho_eanes 2:15f2d7d650bb 370 // Convert the raw bytes to a 16bit signed fixed point value :
mangalho_eanes 2:15f2d7d650bb 371 // 1 sign bit, 7 integer bits, 8 fractional bits (two's compliment
mangalho_eanes 2:15f2d7d650bb 372 // and the LSB of the 16bit binary number represents 1/256th of a unit).
mangalho_eanes 2:15f2d7d650bb 373 *p_word = *p_word << 4;
mangalho_eanes 2:15f2d7d650bb 374 // Convert to floating point value
mangalho_eanes 2:15f2d7d650bb 375 temp = toFloat(*p_word);
mangalho_eanes 2:15f2d7d650bb 376 return 0; // return with no errors
mangalho_eanes 2:15f2d7d650bb 377 }
mangalho_eanes 2:15f2d7d650bb 378 else {
mangalho_eanes 2:15f2d7d650bb 379 uint8_t cfg = (data[4] & 0x60); // default 12bit resolution, max conversion time = 750ms
mangalho_eanes 2:15f2d7d650bb 380
mangalho_eanes 2:15f2d7d650bb 381 // at lower resolution, the low bits are undefined, so let's clear them
mangalho_eanes 2:15f2d7d650bb 382 if(cfg == 0x00)
mangalho_eanes 2:15f2d7d650bb 383 *p_word = *p_word &~7; // 9bit resolution, max conversion time = 93.75ms
mangalho_eanes 2:15f2d7d650bb 384 else
mangalho_eanes 2:15f2d7d650bb 385 if(cfg == 0x20)
mangalho_eanes 2:15f2d7d650bb 386 *p_word = *p_word &~3; // 10bit resolution, max conversion time = 187.5ms
mangalho_eanes 2:15f2d7d650bb 387 else
mangalho_eanes 2:15f2d7d650bb 388 if(cfg == 0x40)
mangalho_eanes 2:15f2d7d650bb 389 *p_word = *p_word &~1; // 11bit resolution, max conversion time = 375ms
mangalho_eanes 2:15f2d7d650bb 390
mangalho_eanes 2:15f2d7d650bb 391 // Convert the raw bytes to a 16bit signed fixed point value :
mangalho_eanes 2:15f2d7d650bb 392 // 1 sign bit, 7 integer bits, 8 fractional bits (two's complement
mangalho_eanes 2:15f2d7d650bb 393 // and the LSB of the 16bit binary number represents 1/256th of a unit).
mangalho_eanes 2:15f2d7d650bb 394 *p_word = *p_word << 4;
mangalho_eanes 2:15f2d7d650bb 395 // Convert to floating point value
mangalho_eanes 2:15f2d7d650bb 396 temp = toFloat(*p_word);
mangalho_eanes 2:15f2d7d650bb 397 return 0; // return with no errors
mangalho_eanes 2:15f2d7d650bb 398 }
mangalho_eanes 2:15f2d7d650bb 399 }
mangalho_eanes 2:15f2d7d650bb 400 else
mangalho_eanes 2:15f2d7d650bb 401 return 1; // error, sensor is not present
mangalho_eanes 2:15f2d7d650bb 402 }
mangalho_eanes 2:15f2d7d650bb 403
mangalho_eanes 2:15f2d7d650bb 404 /**
mangalho_eanes 2:15f2d7d650bb 405 * @brief Converts a 16-bit signed fixed point value to floating point value
mangalho_eanes 2:15f2d7d650bb 406 * @note The 16-bit unsigned integer represnts actually
mangalho_eanes 2:15f2d7d650bb 407 * a 16-bit signed fixed point value:
mangalho_eanes 2:15f2d7d650bb 408 * 1 sign bit, 7 integer bits, 8 fractional bits (two’s complement
mangalho_eanes 2:15f2d7d650bb 409 * and the LSB of the 16-bit binary number represents 1/256th of a unit).
mangalho_eanes 2:15f2d7d650bb 410 * @param 16-bit unsigned integer
mangalho_eanes 2:15f2d7d650bb 411 * @retval Floating point value
mangalho_eanes 2:15f2d7d650bb 412 */
mangalho_eanes 2:15f2d7d650bb 413 float DS1820::toFloat(uint16_t word) {
mangalho_eanes 2:15f2d7d650bb 414 if(word & 0x8000)
mangalho_eanes 2:15f2d7d650bb 415 return (-float(uint16_t(~word + 1)) / 256.0f);
mangalho_eanes 2:15f2d7d650bb 416 else
mangalho_eanes 2:15f2d7d650bb 417 return (float(word) / 256.0f);
mangalho_eanes 2:15f2d7d650bb 418 }
mangalho_eanes 2:15f2d7d650bb 419
mangalho_eanes 2:15f2d7d650bb 420