瀏覽代碼

ds18b20: Initial implementation

This driver supports, and was tested with, a DS18B20 1-wire
Temperature Sensor using external power.

This device requires the use of a UART to provide access to a Dallas
1-wire bus, via a new facility supported by MRAA (once the relevant PR
is accepted), using the UartOW access class.  It is important to
realize that the UART is only being used to access and control a
Dallas 1-wire compliant bus, it is not actually a UART device.

Multiple DS18B20 devices can be connected to this bus.  This module
will identify all such devices connected, and allow you to access them
using an index starting at 0.

Parasitic power is not currently supported due to the very tight 10us
limit on switching a GPIO properly to supply power during certain
operations.  For this reason, you should use external power for your
sensors.

Setting the alarm values (Tl, Th) is also not supported, since this is
only useful when doing a 1-wire device search looking for devices in
an alarm state, a capability not yet supported in MRAA.  In reality,
this is trivial to handle yourself in your application.

Signed-off-by: Jon Trulson <jtrulson@ics.com>
Signed-off-by: Noel Eck <noel.eck@intel.com>
Jon Trulson 9 年之前
父節點
當前提交
e679d40d44

+ 1
- 0
examples/c++/CMakeLists.txt 查看文件

@@ -266,6 +266,7 @@ if (BACNET_FOUND)
266 266
 endif()
267 267
 add_example (vcap)
268 268
 add_example (ds2413)
269
+add_example (ds18b20)
269 270
 
270 271
 # These are special cases where you specify example binary, source file and module(s)
271 272
 include_directories (${PROJECT_SOURCE_DIR}/src)

+ 81
- 0
examples/c++/ds18b20.cxx 查看文件

@@ -0,0 +1,81 @@
1
+/*
2
+ * Author: Jon Trulson <jtrulson@ics.com>
3
+ * Copyright (c) 2016 Intel Corporation.
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining
6
+ * a copy of this software and associated documentation files (the
7
+ * "Software"), to deal in the Software without restriction, including
8
+ * without limitation the rights to use, copy, modify, merge, publish,
9
+ * distribute, sublicense, and/or sell copies of the Software, and to
10
+ * permit persons to whom the Software is furnished to do so, subject to
11
+ * the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ */
24
+
25
+#include <unistd.h>
26
+#include <iostream>
27
+#include <signal.h>
28
+
29
+#include "ds18b20.h"
30
+
31
+using namespace std;
32
+
33
+bool shouldRun = true;
34
+
35
+void sig_handler(int signo)
36
+{
37
+  if (signo == SIGINT)
38
+    shouldRun = false;
39
+}
40
+
41
+int main(int argc, char **argv)
42
+{
43
+  signal(SIGINT, sig_handler);
44
+
45
+//! [Interesting]
46
+
47
+  cout << "Initializing..." << endl;
48
+
49
+  // Instantiate an DS18B20 instance using the default values (uart 0)
50
+  upm::DS18B20 sensor;
51
+
52
+  // locate and setup our devices
53
+  sensor.init();
54
+
55
+  cout << "Found " << sensor.devicesFound() << " device(s)" << endl;
56
+  cout << endl;
57
+
58
+  // bail if we didn't find anything
59
+  if (!sensor.devicesFound())
60
+    return 1;
61
+
62
+  // update and print available values every second
63
+  while (shouldRun)
64
+    {
65
+      // update our values for the first sensor
66
+      sensor.update(0);
67
+
68
+      // we show both C and F for temperature for the first sensor
69
+      cout << "Temperature: " << sensor.getTemperature(0)
70
+           << " C / " << sensor.getTemperature(0, true) << " F"
71
+           << endl;
72
+
73
+      sleep(1);
74
+    }
75
+
76
+  cout << "Exiting..." << endl;
77
+
78
+//! [Interesting]
79
+
80
+  return 0;
81
+}

+ 70
- 0
examples/javascript/ds18b20.js 查看文件

@@ -0,0 +1,70 @@
1
+/*jslint node:true, vars:true, bitwise:true, unparam:true */
2
+/*jshint unused:true */
3
+
4
+/*
5
+ * Author: Jon Trulson <jtrulson@ics.com>
6
+ * Copyright (c) 2016 Intel Corporation.
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining
9
+ * a copy of this software and associated documentation files (the
10
+ * "Software"), to deal in the Software without restriction, including
11
+ * without limitation the rights to use, copy, modify, merge, publish,
12
+ * distribute, sublicense, and/or sell copies of the Software, and to
13
+ * permit persons to whom the Software is furnished to do so, subject to
14
+ * the following conditions:
15
+ *
16
+ * The above copyright notice and this permission notice shall be
17
+ * included in all copies or substantial portions of the Software.
18
+ *
19
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+
29
+var sensorObj = require('jsupm_ds18b20');
30
+
31
+
32
+/************** Main code **************/
33
+
34
+console.log("Initializing...");
35
+
36
+// Instantiate an DS18B20 instance using the default values (uart 0)
37
+var sensor = new sensorObj.DS18B20(0);
38
+
39
+// locate and setup our devices
40
+sensor.init();
41
+
42
+console.log("Found", sensor.devicesFound(), "device(s)");
43
+console.log("");
44
+
45
+if (!sensor.devicesFound())
46
+{
47
+    process.exit(1);
48
+}
49
+
50
+// update and print available values every second
51
+setInterval(function()
52
+{
53
+    // update our values for the first sensor
54
+    sensor.update(0);
55
+
56
+    // we show both C and F for temperature for the first sensor
57
+    console.log("Temperature:", sensor.getTemperature(0),
58
+                "C /", sensor.getTemperature(0, true), "F");
59
+
60
+}, 1000);
61
+
62
+
63
+process.on('SIGINT', function()
64
+{
65
+    sensor = null;
66
+    sensorObj.cleanUp();
67
+    sensorObj = null;
68
+    console.log("Exiting...");
69
+    process.exit(0);
70
+});

+ 64
- 0
examples/python/ds18b20.py 查看文件

@@ -0,0 +1,64 @@
1
+#!/usr/bin/python
2
+# Author: Jon Trulson <jtrulson@ics.com>
3
+# Copyright (c) 2016 Intel Corporation.
4
+#
5
+# Permission is hereby granted, free of charge, to any person obtaining
6
+# a copy of this software and associated documentation files (the
7
+# "Software"), to deal in the Software without restriction, including
8
+# without limitation the rights to use, copy, modify, merge, publish,
9
+# distribute, sublicense, and/or sell copies of the Software, and to
10
+# permit persons to whom the Software is furnished to do so, subject to
11
+# the following conditions:
12
+#
13
+# The above copyright notice and this permission notice shall be
14
+# included in all copies or substantial portions of the Software.
15
+#
16
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+import time, sys, signal, atexit
25
+import pyupm_ds18b20 as sensorObj
26
+
27
+## Exit handlers ##
28
+# This function stops python from printing a stacktrace when you hit control-C
29
+def SIGINTHandler(signum, frame):
30
+	raise SystemExit
31
+
32
+# This function lets you run code on exit
33
+def exitHandler():
34
+	print "Exiting..."
35
+	sys.exit(0)
36
+
37
+# Register exit handlers
38
+atexit.register(exitHandler)
39
+signal.signal(signal.SIGINT, SIGINTHandler)
40
+
41
+print "Initializing..."
42
+
43
+# Instantiate an DS18B20 instance using the default values (uart 0)
44
+sensor = sensorObj.DS18B20(0)
45
+
46
+# locate and setup our devices
47
+sensor.init()
48
+
49
+print "Found", sensor.devicesFound(), "device(s)"
50
+print
51
+
52
+if (not sensor.devicesFound()):
53
+        sys.exit(1);
54
+
55
+# update and print available values every second
56
+while (1):
57
+        # update our values for the first sensor
58
+        sensor.update(0)
59
+
60
+        # we show both C and F for temperature for the first sensor
61
+        print "Temperature:", sensor.getTemperature(0), "C /",
62
+        print sensor.getTemperature(0, True), "F"
63
+
64
+	time.sleep(1)

+ 5
- 0
src/ds18b20/CMakeLists.txt 查看文件

@@ -0,0 +1,5 @@
1
+set (libname "ds18b20")
2
+set (libdescription "upm DS18B20 1-wire Temperature sensor")
3
+set (module_src ${libname}.cxx)
4
+set (module_h ${libname}.h)
5
+upm_module_init()

+ 298
- 0
src/ds18b20/ds18b20.cxx 查看文件

@@ -0,0 +1,298 @@
1
+/*
2
+ * Author: Jon Trulson <jtrulson@ics.com>
3
+ * Copyright (c) 2016 Intel Corporation.
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining
6
+ * a copy of this software and associated documentation files (the
7
+ * "Software"), to deal in the Software without restriction, including
8
+ * without limitation the rights to use, copy, modify, merge, publish,
9
+ * distribute, sublicense, and/or sell copies of the Software, and to
10
+ * permit persons to whom the Software is furnished to do so, subject to
11
+ * the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ */
24
+
25
+#include <iostream>
26
+#include <time.h>
27
+#include <stdexcept>
28
+
29
+#include "ds18b20.h"
30
+
31
+using namespace upm;
32
+using namespace std;
33
+
34
+// conversion from celcius to fahrenheit
35
+static float c2f(float c)
36
+{
37
+  return (c * (9.0 / 5.0) + 32.0);
38
+}
39
+
40
+DS18B20::DS18B20(int uart) :
41
+  m_uart(uart)
42
+{
43
+  m_devicesFound = 0;
44
+
45
+  // check basic access to the 1-wire bus (presence detect)
46
+  mraa::Result rv;
47
+
48
+  if ((rv = m_uart.reset()) != mraa::SUCCESS)
49
+    {
50
+      throw std::runtime_error(std::string(__FUNCTION__) +
51
+                               ": reset() failed, no devices on bus?");
52
+    }
53
+}
54
+
55
+DS18B20::~DS18B20()
56
+{
57
+}
58
+
59
+void DS18B20::init()
60
+{
61
+  // iterate through the bus and build up a list of detected DS18B20
62
+  // devices (only)
63
+
64
+  // empty the map, in case this method has already been run once
65
+  // before
66
+  m_devicesFound = 0;
67
+  m_deviceMap.clear();
68
+
69
+  sensor_info_t sinfo;
70
+
71
+  // defaults
72
+  sinfo.temperature = 0.0;
73
+  sinfo.resolution = RESOLUTION_12BITS;
74
+
75
+  // start the search from scratch
76
+  string id = m_uart.search(true);
77
+  if (id.empty())
78
+    {
79
+      throw std::runtime_error(std::string(__FUNCTION__) +
80
+                               ": no devices detected on bus");
81
+    }
82
+
83
+  while (!id.empty())
84
+    {
85
+      // The first byte (id[0]]) is the device type (family) code.  We
86
+      // are only interested in the family code for these devices.
87
+
88
+      if ((uint8_t)id[0] == DS18B20_FAMILY_CODE)
89
+        {
90
+          // we have a winner, add it to our map and continue searching
91
+
92
+          sinfo.id = id;
93
+          m_deviceMap[m_devicesFound] = sinfo;
94
+
95
+          m_devicesFound++;
96
+        }
97
+
98
+      // continue search
99
+      id = m_uart.search(false);
100
+    }
101
+
102
+  if (!m_devicesFound)
103
+    {
104
+      throw std::runtime_error(std::string(__FUNCTION__) +
105
+                               ": no DS18B20 devices found on bus");
106
+    }
107
+
108
+  // iterate through the found devices and query their resolutions
109
+  for (int i=0; i<m_devicesFound; i++)
110
+    {
111
+      // read only the first 5 bytes of the scratchpad
112
+      static const int numScratch = 5;
113
+      uint8_t scratch[numScratch];
114
+
115
+      m_uart.command(CMD_READ_SCRATCHPAD, m_deviceMap[i].id);
116
+      for (int j=0; j<numScratch; j++)
117
+        scratch[j] = m_uart.readByte();
118
+
119
+      // config byte, shift the resolution to bit 0
120
+      scratch[4] >>= _CFG_RESOLUTION_SHIFT;
121
+
122
+      switch (scratch[4] & _CFG_RESOLUTION_MASK)
123
+        {
124
+        case 0: m_deviceMap[i].resolution = RESOLUTION_9BITS; break;
125
+        case 1: m_deviceMap[i].resolution = RESOLUTION_10BITS; break;
126
+        case 2: m_deviceMap[i].resolution = RESOLUTION_11BITS; break;
127
+        case 3: m_deviceMap[i].resolution = RESOLUTION_12BITS; break;
128
+        }
129
+
130
+      // reset the bus
131
+      m_uart.reset();
132
+    }
133
+}
134
+
135
+void DS18B20::update(int index)
136
+{
137
+  if (index >= m_devicesFound)
138
+    {
139
+      throw std::out_of_range(std::string(__FUNCTION__) +
140
+                              ": device index out of range");
141
+    }
142
+
143
+  // should we update all of them?
144
+  bool doAll = (index < 0) ? true : false;
145
+
146
+  if (doAll)
147
+    {
148
+      // if we want to update all of them, we will first send the
149
+      // convert command to all of them, then wait.  This will be
150
+      // faster, timey-wimey wise, then converting, sleeping, and
151
+      // reading each individual sensor.
152
+
153
+      for (int i=0; i<m_devicesFound; i++)
154
+        m_uart.command(CMD_CONVERT, m_deviceMap[i].id);
155
+    }
156
+  else
157
+    m_uart.command(CMD_CONVERT, m_deviceMap[index].id);
158
+
159
+  // wait for conversion(s) to finish
160
+  usleep(750000); // 750ms max
161
+
162
+  if (doAll)
163
+    {
164
+      for (int i=0; i<m_devicesFound; i++)
165
+        m_deviceMap[i].temperature = readSingleTemp(i);
166
+    }
167
+  else
168
+    m_deviceMap[index].temperature = readSingleTemp(index);
169
+}
170
+
171
+// utility function to read temp data from a single sensor
172
+float DS18B20::readSingleTemp(int index)
173
+{
174
+  if (index < 0 || index >= m_devicesFound)
175
+    {
176
+      throw std::out_of_range(std::string(__FUNCTION__) +
177
+                              ": device index out of range");
178
+    }
179
+
180
+  static const int numScratch = 9;
181
+  uint8_t scratch[numScratch];
182
+
183
+  // read the 9-byte scratchpad
184
+  m_uart.command(CMD_READ_SCRATCHPAD, m_deviceMap[index].id);
185
+  for (int i=0; i<numScratch; i++)
186
+    scratch[i] = m_uart.readByte();
187
+
188
+  // validate cksum -- if we get an error, we will warn and simply
189
+  // return the current (previously read) temperature
190
+  uint8_t crc = m_uart.crc8(scratch, 8);
191
+
192
+  if (crc != scratch[8])
193
+    {
194
+      cerr << __FUNCTION__ << ": crc check failed for device "
195
+           << index << ", returning previously measured temperature" << endl;
196
+      return m_deviceMap[index].temperature;
197
+    }
198
+
199
+  // check the sign bit(s)
200
+  bool negative = (scratch[1] & 0x80) ? true : false;
201
+
202
+  // shift everything into position
203
+  int16_t temp = (scratch[1] << 8) | scratch[0];
204
+
205
+  // grab the fractional
206
+  uint8_t frac = temp & 0x0f;
207
+
208
+  // depending on the resolution, some frac bits should be ignored, so
209
+  // we mask them off.  For 12bits, all bits are valid so we leve them
210
+  // alone.
211
+
212
+  switch (m_deviceMap[index].resolution)
213
+    {
214
+    case RESOLUTION_9BITS: frac &= 0x08; break;
215
+    case RESOLUTION_10BITS: frac &= 0x0c; break;
216
+    case RESOLUTION_11BITS: frac &= 0x0e; break;
217
+    }
218
+
219
+  // remove the fractional with extreme prejudice
220
+  temp >>= 4;
221
+
222
+  // compensate for sign
223
+  if (negative)
224
+    temp -= 65536; // 2^^16
225
+
226
+  // convert
227
+  return ( float(temp) + (float(frac) * 0.0625) );
228
+}
229
+
230
+float DS18B20::getTemperature(int index, bool fahrenheit)
231
+{
232
+  if (index < 0 || index >= m_devicesFound)
233
+    {
234
+      throw std::out_of_range(std::string(__FUNCTION__) +
235
+                              ": device index out of range");
236
+    }
237
+
238
+  if (fahrenheit)
239
+    return c2f(m_deviceMap[index].temperature);
240
+  else
241
+    return m_deviceMap[index].temperature;
242
+}
243
+
244
+void DS18B20::setResolution(int index, RESOLUTIONS_T res)
245
+{
246
+  if (index < 0 || index >= m_devicesFound)
247
+    {
248
+      throw std::out_of_range(std::string(__FUNCTION__) +
249
+                              ": device index out of range");
250
+    }
251
+
252
+  static const int numScratch = 9;
253
+  uint8_t scratch[numScratch];
254
+
255
+  // read the 9-byte scratchpad
256
+  m_uart.command(CMD_READ_SCRATCHPAD, m_deviceMap[index].id);
257
+  for (int i=0; i<numScratch; i++)
258
+    scratch[i] = m_uart.readByte();
259
+
260
+  // resolution is stored in byte 4
261
+  scratch[4] = ((scratch[4] & ~(_CFG_RESOLUTION_MASK << _CFG_RESOLUTION_SHIFT))
262
+                | (res << _CFG_RESOLUTION_SHIFT));
263
+
264
+  // now, write back, we only write 3 bytes (2-4), no cksum.
265
+  m_uart.command(CMD_WRITE_SCRATCHPAD, m_deviceMap[index].id);
266
+  for (int i=0; i<3; i++)
267
+    m_uart.writeByte(scratch[i+2]);
268
+}
269
+
270
+void DS18B20::copyScratchPad(int index)
271
+{
272
+  if (index < 0 || index >= m_devicesFound)
273
+    {
274
+      throw std::out_of_range(std::string(__FUNCTION__) +
275
+                              ": device index out of range");
276
+    }
277
+
278
+  // issue the command
279
+  m_uart.command(CMD_COPY_SCRATCHPAD, m_deviceMap[index].id);
280
+
281
+  sleep(1); // to be safe...
282
+}
283
+
284
+void DS18B20::recallEEPROM(int index)
285
+{
286
+  if (index < 0 || index >= m_devicesFound)
287
+    {
288
+      throw std::out_of_range(std::string(__FUNCTION__) +
289
+                              ": device index out of range");
290
+    }
291
+
292
+  // issue the command
293
+  m_uart.command(CMD_RECALL_EEPROM, m_deviceMap[index].id);
294
+
295
+  // issue read timeslots until a '1' is read back, indicating completion
296
+  while (!m_uart.writeBit(1))
297
+    usleep(100);
298
+}

+ 242
- 0
src/ds18b20/ds18b20.h 查看文件

@@ -0,0 +1,242 @@
1
+/*
2
+ * Author: Jon Trulson <jtrulson@ics.com>
3
+ * Copyright (c) 2016 Intel Corporation.
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining
6
+ * a copy of this software and associated documentation files (the
7
+ * "Software"), to deal in the Software without restriction, including
8
+ * without limitation the rights to use, copy, modify, merge, publish,
9
+ * distribute, sublicense, and/or sell copies of the Software, and to
10
+ * permit persons to whom the Software is furnished to do so, subject to
11
+ * the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ */
24
+#pragma once
25
+
26
+#include <string>
27
+#include <iostream>
28
+#include <map>
29
+
30
+#include <stdlib.h>
31
+#include <unistd.h>
32
+#include <string.h>
33
+
34
+#include <mraa/common.hpp>
35
+#include <mraa/uart_ow.hpp>
36
+
37
+#define DS18B20_DEFAULT_UART 0
38
+
39
+namespace upm {
40
+    /**
41
+     * @brief DS18B20 1-Wire Temperature Sensor
42
+     * @defgroup ds18b20 libupm-ds18b20
43
+     * @ingroup maxim uart
44
+     */
45
+
46
+    /**
47
+     * @library ds18b20
48
+     * @sensor ds18b20
49
+     * @comname DS18B20 1-Wire Temperature Sensor
50
+     * @type uart
51
+     * @man maxim
52
+     * @con uart
53
+     * @web https://www.sparkfun.com/products/11050
54
+     *
55
+     * @brief API for the DS18B20 1-Wire Temperature Sensor
56
+     *
57
+     * This driver supports, and was tested with, a DS18B20 with
58
+     * external power.
59
+     *
60
+     * Multiple DS18B20 devices can be connected to this bus.  This
61
+     * module will identify all such devices connected, and allow you
62
+     * to access them using an index starting at 0.
63
+     *
64
+     * Parasitic power is not currently supported due
65
+     * to the very tight 10us limit on switching a GPIO properly to
66
+     * supply power during certain operations.  For this reason, you
67
+     * should use external power for your sensors.
68
+     *
69
+     * Setting the alarm values (Tl, Th) is also not supported, since
70
+     * this is only useful when doing a 1-wire device search looking
71
+     * for devices in an alarm state, a capability not yet supported
72
+     * in MRAA.  In reality, this is trivial to handle yourself in
73
+     * your application.
74
+     *
75
+     * This device requires the use of a UART to provide access to a
76
+     * Dallas 1-wire bus, via a new facility supported by MRAA (once
77
+     * the relevant PR is accepted), using the UartOW access class.
78
+     * It is important to realize that the UART is only being used to
79
+     * access and control a Dallas 1-wire compliant bus, it is not
80
+     * actually a UART device.
81
+     *
82
+     * @snippet ds18b20.cxx Interesting
83
+     */
84
+
85
+  class DS18B20 {
86
+  public:
87
+
88
+    // The family code for these devices.  We handle all of them that
89
+    // are found on the bus.
90
+    static const uint8_t DS18B20_FAMILY_CODE = 0x28;
91
+
92
+    // commands
93
+    typedef enum {
94
+      CMD_CONVERT                         = 0x44, // start a temp conversion
95
+      CMD_WRITE_SCRATCHPAD                = 0x4e,
96
+      CMD_READ_SCRATCHPAD                 = 0xbe,
97
+      CMD_COPY_SCRATCHPAD                 = 0x48, // copy scratchpad to EEPROM
98
+      CMD_RECALL_EEPROM                   = 0xb8, // copy EEPROM to scratchpad
99
+      CMD_READ_POWER_SUPPLY               = 0xb4  // parasitically powered?
100
+    } CMD_T;
101
+
102
+    // config register (scratchpad[4])
103
+    typedef enum {
104
+      CFG_RESOLUTION_R0                   = 0x20,
105
+      CFG_RESOLUTION_R1                   = 0x40,
106
+      _CFG_RESOLUTION_MASK                = 3,
107
+      _CFG_RESOLUTION_SHIFT               = 5
108
+
109
+      // all other bits reserved and non-writable
110
+    } CFG_BITS_T;
111
+
112
+    typedef enum {
113
+      RESOLUTION_9BITS                    = 0, // 93.75ms (tconv/8)
114
+      RESOLUTION_10BITS                   = 1, // 187.5 (tconv/4)
115
+      RESOLUTION_11BITS                   = 2, // 375ms (tconv/2)
116
+      RESOLUTION_12BITS                   = 3  // 750ms (tconv)
117
+    } RESOLUTIONS_T;
118
+
119
+    /**
120
+     * DS18B20 object constructor
121
+     *
122
+     * @param uart Default UART to use (0 or 1). Default is 0.
123
+     */
124
+    DS18B20(int uart=DS18B20_DEFAULT_UART);
125
+
126
+    /**
127
+     * DS18B20 object destructor
128
+     */
129
+    ~DS18B20();
130
+
131
+    /**
132
+     * This method will search the 1-wire bus and store information on
133
+     * each device detected on the bus.  If no devices are found, an
134
+     * exception is thrown.  Once this function completes
135
+     * successfully, you can use devicesFound() to determine how many
136
+     * devices were detected.  This method must be executed first
137
+     * before any others below.
138
+     */
139
+    void init();
140
+
141
+    /**
142
+     * Update our stored temperature for a device.  This method must
143
+     * be called prior to getTemperature().
144
+     *
145
+     * @param index The device index to access (starts at 0).  Specify
146
+     * -1 to query all detected devices.  Default: -1
147
+     */
148
+    void update(int index=-1);
149
+
150
+    /**
151
+     * Get the current temperature.  update() must have been called
152
+     * prior to calling this method.
153
+     *
154
+     * @param index The device index to access (starts at 0).
155
+     * @param fahrenheit true to return the temperature in degrees
156
+     * fahrenheit, false to return the temperature in degrees celcius.
157
+     * The default is false (degrees Celcius).
158
+     * @return The last temperature reading in Celcius or Fahrenheit
159
+     */
160
+    float getTemperature(int index, bool fahrenheit=false);
161
+
162
+    /**
163
+     * Set the device resolution for a device.  These devices support
164
+     * 9, 10, 11, and 12 bits of resolution, with the default from the
165
+     * factory at 12 bits.
166
+     *
167
+     * @param index The device index to access (starts at 0).
168
+     * @param res One of the RESOLUTIONS_T values
169
+     */
170
+    void setResolution(int index, RESOLUTIONS_T res);
171
+
172
+    /**
173
+     * Copy the device's scratchpad memory to the EEPROM.  This
174
+     * includes the configuration byte (resolution).
175
+     *
176
+     * @param index The device index to access (starts at 0).
177
+     */
178
+    void copyScratchPad(int index);
179
+
180
+    /**
181
+     * Copy the device's EEPROM memory to the scratchpad.  This method
182
+     * will return when the copy completes.  This operation is
183
+     * performed by the device automatically on power up, so it is
184
+     * rarely needed.
185
+     *
186
+     * @param index The device index to access (starts at 0).
187
+     */
188
+    void recallEEPROM(int index);
189
+
190
+    /**
191
+     * This method will return the number of DS18B20 devices that were
192
+     * found on the bus by init().
193
+     *
194
+     * @return number of DS18B20's that were found on the bus
195
+     */
196
+    int devicesFound()
197
+    {
198
+      return m_devicesFound;
199
+    }
200
+
201
+    /**
202
+     * Return an 8 byte string representing the unique device ID
203
+     * (1-wire romcode) for a given device index.
204
+     *
205
+     * @param index The device index to access (starts at 0).
206
+     * @return 8 byte string representing the 1-wire device's unique
207
+     * romcode.
208
+     */
209
+    std::string getId(int index)
210
+    {
211
+      if (index < 0 || index >= m_devicesFound)
212
+        {
213
+          throw std::out_of_range(std::string(__FUNCTION__) +
214
+                                  ": device index out of range");
215
+        }
216
+      return m_deviceMap[index].id;
217
+    }
218
+
219
+  protected:
220
+    mraa::UartOW m_uart;
221
+
222
+    // the total number of devices found
223
+    int m_devicesFound;
224
+
225
+    // this struct will generate SWIG warnings on build, but as it's not
226
+    // exposed outside the class, they can be safely ignored
227
+
228
+    // data we need to store for each sensor we are dealing with
229
+    typedef struct {
230
+      std::string id;           // 8-byte romcode id
231
+      float temperature;
232
+      RESOLUTIONS_T resolution;
233
+    } sensor_info_t;
234
+
235
+    std::map<int, sensor_info_t> m_deviceMap;
236
+
237
+  private:
238
+    // internal utility function to read temperature from a single
239
+    // device
240
+    float readSingleTemp(int index);
241
+  };
242
+}

+ 22
- 0
src/ds18b20/javaupm_ds18b20.i 查看文件

@@ -0,0 +1,22 @@
1
+%module javaupm_ds18b20
2
+%include "../upm.i"
3
+%include "carrays.i"
4
+%include "std_string.i"
5
+
6
+%{
7
+    #include "ds18b20.h"
8
+%}
9
+
10
+%include "ds18b20.h"
11
+%array_class(char, charArray);
12
+
13
+%pragma(java) jniclasscode=%{
14
+    static {
15
+        try {
16
+            System.loadLibrary("javaupm_ds18b20");
17
+        } catch (UnsatisfiedLinkError e) {
18
+            System.err.println("Native code library failed to load. \n" + e);
19
+            System.exit(1);
20
+        }
21
+    }
22
+%}

+ 11
- 0
src/ds18b20/jsupm_ds18b20.i 查看文件

@@ -0,0 +1,11 @@
1
+%module jsupm_ds18b20
2
+%include "../upm.i"
3
+%include "carrays.i"
4
+%include "std_string.i"
5
+
6
+%{
7
+    #include "ds18b20.h"
8
+%}
9
+
10
+%include "ds18b20.h"
11
+%array_class(char, charArray);

+ 12
- 0
src/ds18b20/pyupm_ds18b20.i 查看文件

@@ -0,0 +1,12 @@
1
+%module pyupm_ds18b20
2
+%include "../upm.i"
3
+%include "carrays.i"
4
+%include "std_string.i"
5
+
6
+%feature("autodoc", "3");
7
+
8
+%{
9
+    #include "ds18b20.h"
10
+%}
11
+%include "ds18b20.h"
12
+%array_class(char, charArray);