ASensor
 All Classes Functions Pages
DS18B20Sensor.h
1 #pragma once
2 /*
3  ASensor - Sensor library. Can be used standalone or in conjunction with AWind library
4  Copyright (C)2015 Andrei Degtiarev. All right reserved
5 
6  You can always find the latest version of the library at
7  https://github.com/AndreiDegtiarev/ASensor
8 
9  This library is free software; you can redistribute it and/or
10  modify it under the terms of the MIT license.
11  Please see the included documents for further information.
12 */
14 class DS18B20Sensor : public ISensor
15 {
16 #ifndef DEMO_SENSORS
17  OneWire *ds;
18 #endif
19  int _wire_index;
20 public:
21  DS18B20Sensor(int port,int wire_index)
22 
23  {
24 #ifndef DEMO_SENSORS
25  ds=new OneWire(port);
26 #endif
27  _wire_index=wire_index;
28  }
29  virtual const __FlashStringHelper* Name()
30  {
31  return F("DS18B20");
32  }
33  virtual float LowMeasurementLimit()
34  {
35  return -50;
36  }
37  virtual float HighMeasurementLimit()
38  {
39  return 50;
40  }
41  virtual int Precission()
42  {
43  return 1;
44  }
45  virtual bool Measure(float & ret_data)
46  {
47 
48 #ifdef DEMO_SENSORS
49  ret_data=(float)rand()/RAND_MAX*5+15;
50  return true;
51 #else
52  byte i;
53  byte present = 0;
54  byte type_s=0;
55  byte data[12];
56  byte addr[8];
57  //byte addr[] = {0x28,0xB2,0x6F,0xA4,0x5,0x0,0x0,0x9B};
58  float celsius, fahrenheit;
59 
60  bool isError=true;
61  for(int i=0;i<_wire_index;i++)
62  {
63  for(int j=0;j<3;j++)
64  {
65  isError=!ds->search(addr);
66  if(isError)
67  {
68  Serial.print(F("No more addresses:"));
69  Serial.println(j);
70  delay(250);
71  }
72  else
73  {
74  /*Serial.print("found ");
75  Serial.print(i);
76  Serial.println(_wire_index);*/
77  break;
78  }
79  }
80  if(isError)
81  break;
82  }
83  if(isError)
84  {
85  ds->reset_search();
86  return false;
87  }
88  /*Serial.print("ROM =");
89  for( i = 0; i < 8; i++) {
90  Serial.write(' ');
91  Serial.print(addr[i], HEX);
92  }
93  Serial.println("");*/
94 
95  if (OneWire::crc8(addr, 7) != addr[7]) {
96  Serial.println(F("CRC is not valid!"));
97  return false;
98  }
99  //Serial.println();
100 
101  // the first ROM byte indicates which chip
102  switch (addr[0]) {
103  case 0x10:
104  Serial.println(F(" Chip = DS18S20")); // or old DS1820
105  type_s = 1;
106  break;
107  case 0x28:
108  //Serial.println(" Chip = DS18B20");
109  type_s = 0;
110  break;
111  case 0x22:
112  Serial.println(F(" Chip = DS1822"));
113  type_s = 0;
114  break;
115  default:
116  Serial.println(F("Device is not a DS18x20 family device."));
117  return false;
118  }
119 
120  ds->reset();
121  ds->select(addr);
122  ds->write(0x44, 1); // start conversion, with parasite power on at the end
123 
124  //delay(1000); // maybe 750ms is enough, maybe not
125  // we might do a ds.depower() here, but the reset will take care of it.
126 
127  present = ds->reset();
128  ds->select(addr);
129  ds->write(0xBE); // Read Scratchpad
130 
131  /*Serial.print(" Data = ");
132  Serial.print(present, HEX);
133  Serial.print(" ");*/
134  for ( i = 0; i < 9; i++) { // we need 9 bytes
135  data[i] = ds->read();
136  //Serial.print(data[i], HEX);
137  //Serial.print(" ");
138  }
139  /*Serial.print(" CRC=");
140  Serial.print(OneWire::crc8(data, 8), HEX);
141  Serial.println();*/
142 
143  // Convert the data to actual temperature
144  // because the result is a 16 bit signed integer, it should
145  // be stored to an "int16_t" type, which is always 16 bits
146  // even when compiled on a 32 bit processor.
147  int16_t raw = (data[1] << 8) | data[0];
148  if (type_s) {
149  raw = raw << 3; // 9 bit resolution default
150  if (data[7] == 0x10) {
151  // "count remain" gives full 12 bit resolution
152  raw = (raw & 0xFFF0) + 12 - data[6];
153  }
154  } else {
155  byte cfg = (data[4] & 0x60);
156  // at lower res, the low bits are undefined, so let's zero them
157  if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms
158  else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
159  else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
161  }
162  celsius = (float)raw / 16.0;
163  fahrenheit = celsius * 1.8 + 32.0;
164  /*Serial.print(" Temperature = ");
165  Serial.print(celsius);
166  Serial.print(" Celsius, ");
167  Serial.print(fahrenheit);
168  Serial.println(" Fahrenheit");*/
169  ds->reset_search();
170  if(!isnan(celsius))
171  {
172  ret_data=celsius;
173 #ifdef DEBUG_AWIND
174  out<<F("DS18B20: ")<<ret_data<<endln;
175 #endif
176  return true;
177  }
178 #endif
179  return false;
180  }
181 };
DS18B20-Temperature sensor. To use this sensor OneWire library has to be installed from http://www...
Definition: DS18B20Sensor.h:14