Coffeemaker controller

Dependencies:   mbed OneWire

Committer:
jvfausto
Date:
Sat Sep 26 00:30:09 2020 +0000
Revision:
0:17c5e4f9a805
Coffeemaker code

Who changed what in which revision?

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