Quellcode durchsuchen

max31855: add sensor and documentation on creation of a UPM sensor

Signed-off-by: Brendan Le Foll <brendan.le.foll@intel.com>
Brendan Le Foll vor 10 Jahren
Ursprung
Commit
2c1baf66b5

+ 2
- 1
Doxyfile.in Datei anzeigen

@@ -865,7 +865,8 @@ EXCLUDE_SYMBOLS        =
865 865
 # command).
866 866
 
867 867
 EXAMPLE_PATH           = @CMAKE_CURRENT_SOURCE_DIR@/examples/ \
868
-                         @CMAKE_CURRENT_SOURCE_DIR@/docs/
868
+                         @CMAKE_CURRENT_SOURCE_DIR@/docs/ \
869
+			 @CMAKE_CURRENT_SOURCE_DIR@/src/max31855/
869 870
 
870 871
 # If the value of the EXAMPLE_PATH tag contains directories, you can use the
871 872
 # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and

+ 96
- 0
docs/max31855.md Datei anzeigen

@@ -0,0 +1,96 @@
1
+Making a UPM module for MAX31855                         {#max31855}
2
+================================
3
+
4
+The Maxim Integrated MAX31855 is a thermocouple amplifier allowing you to read
5
+from a K type themocouple. My board comes from the Pmod kit form Maxim
6
+(MAX31855PMB1) but you can get this from many different sources. The adafruit
7
+people made arduino code already so we'll use that as a
8
+[reference](https://github.com/adafruit/Adafruit-MAX31855-library/blob/master/Adafruit_MAX31855.cpp).
9
+
10
+### Basics
11
+
12
+This is a spi module so we will use the maa spi functions to build our module.
13
+First thing to do is to create a tree structure like this in upm/src/max31855:
14
+
15
+* max31855.cxx
16
+* max31855.h
17
+* jsupm_max31855.i
18
+* pyupm_max31855.i
19
+* CMakeLists.txt
20
+
21
+And then an example file to use & test our lib with in upm/examples/max31855.cxx.
22
+
23
+### Swig
24
+
25
+The .i files are used by swig, there is one for each python & javascript. They
26
+contain essentially the same thing and are very simple. The only thing to
27
+change between the javascript & node.js one is the argument to %module.
28
+
29
+@snippet jsupm_max31855.i Interesting
30
+
31
+The %include parameter defines which functions will be available to the
32
+node/python module created, Whilst the headers inside %{} will be explicitly
33
+required during compilation. Typically only the top level header is required in
34
+either of those args.
35
+
36
+### API
37
+
38
+Then we create the header (max31855.h) , a very simple header in our case we
39
+will have only a very basic api. We provide a getTemp() function which will
40
+return the same type as in the arduino library, a double.
41
+
42
+@snippet max31855.h Interesting
43
+
44
+Note that the header contains both the io that we will use, the gpio is in this
45
+case used as the chip select pin.
46
+
47
+### Implementing our API
48
+
49
+In the adafruit library the read function (our chip is a 3pin SPI so only read
50
+is possible), the spiread32() does all the work. It starts by setting up the io
51
+so we will do the same in our constructor.
52
+
53
+Note unlike on Arduino, we'll just set a 2Mhz clock and let the chip do the
54
+work.
55
+
56
+@snippet src/max31855/max31855.cxx Constructor
57
+
58
+Then we also need to implement a nice cleanup in our destructor.
59
+
60
+@snippet src/max31855/max31855.cxx Destructor
61
+
62
+Then to read data, we will use spi_write_buf which will allow us to write a
63
+whole uint32_t in order to get one back, which is what the arduino code does in
64
+spiread32. Obviously we set our chip select to low first. Here is the start of
65
+the implementation of MAX31855::getTemp()
66
+
67
+@snippet src/max31855/max31855.cxx spi
68
+
69
+Then using the arduino code as reference we simply reconstruct form the 4
70
+uint8_t values a 32bit int value and select only the valuable parts of
71
+information from that. The MAX31855 datahseet explains exactly which bits are
72
+useful, we will just do the same as the adafruit code, first checking the error
73
+bit and then scrapping everything but the 14bit of thermocouple data that are
74
+useful to us and converting it to a double.
75
+
76
+@snippet src/max31855/max31855.cxx conversion
77
+
78
+### Finalizing
79
+
80
+Our final example, very easy to use api!
81
+
82
+@snippet examples/max31855.cxx Interesting
83
+
84
+### Building
85
+
86
+The we need to add it to the examples/CMakeLists.txt. Only three lines are required
87
+
88
+~~~~~~~~~~~
89
+add_executable (max31855-example max31855.cxx)
90
+include_directories (${PROJECT_SOURCE_DIR}/src/max31855)
91
+target_link_libraries (max31855-example max31855 ${CMAKE_THREAD_LIBS_INIT})
92
+~~~~~~~~~~~
93
+
94
+Note you dont have to rebuild everything, cmake keeps target lists so if you
95
+named your example target <modulename>-example you can simply do make
96
+max31855-example and both the library & example will build.

+ 2
- 1
docs/porting.md Datei anzeigen

@@ -3,7 +3,8 @@ Porting a module from Arduino                         {#porting}
3 3
 
4 4
 Porting arduino libraries to libmaa as UPM libraries is usually fairly easy.
5 5
 The issues typically come from misunderstanding of how a non real time OS deals
6
-with interupts and timers. It also highly depends on the sensor.
6
+with interupts and timers. It also highly depends on the sensor. A concrete
7
+example is explained in detail on @ref max31855
7 8
 
8 9
 ### Adding a new module to UPM
9 10
 

+ 3
- 0
examples/CMakeLists.txt Datei anzeigen

@@ -15,6 +15,7 @@ add_executable (oled-1327 oled-1327.cxx)
15 15
 add_executable (proximity max44000.cxx)
16 16
 add_executable (accelerometer mma7455.cxx)
17 17
 add_executable (lcd st7735.cxx)
18
+add_executable (max31855-example max31855.cxx)
18 19
 
19 20
 include_directories (${PROJECT_SOURCE_DIR}/src/hmc5883l)
20 21
 include_directories (${PROJECT_SOURCE_DIR}/src/grove)
@@ -28,6 +29,7 @@ include_directories (${PROJECT_SOURCE_DIR}/src/hcsr04)
28 29
 include_directories (${PROJECT_SOURCE_DIR}/src/max44000)
29 30
 include_directories (${PROJECT_SOURCE_DIR}/src/mma7455)
30 31
 include_directories (${PROJECT_SOURCE_DIR}/src/st7735)
32
+include_directories (${PROJECT_SOURCE_DIR}/src/max31855)
31 33
 
32 34
 target_link_libraries (compass hmc5883l ${CMAKE_THREAD_LIBS_INIT})
33 35
 target_link_libraries (groveled grove ${CMAKE_THREAD_LIBS_INIT})
@@ -46,3 +48,4 @@ target_link_libraries (oled-1327 i2clcd ${CMAKE_THREAD_LIBS_INIT})
46 48
 target_link_libraries (proximity max44000 ${CMAKE_THREAD_LIBS_INIT})
47 49
 target_link_libraries (accelerometer mma7455 ${CMAKE_THREAD_LIBS_INIT})
48 50
 target_link_libraries (lcd st7735 ${CMAKE_THREAD_LIBS_INIT})
51
+target_link_libraries (max31855-example max31855 ${CMAKE_THREAD_LIBS_INIT})

+ 41
- 0
examples/max31855.cxx Datei anzeigen

@@ -0,0 +1,41 @@
1
+/*
2
+ * Author: Brendan Le Foll <brendan.le.foll@intel.com>
3
+ * Copyright (c) 2014 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
+//! [Interesting]
30
+#include "max31855.h"
31
+
32
+int
33
+main(int argc, char **argv)
34
+{
35
+    upm::MAX31855 *temp = new upm::MAX31855(0, 8);
36
+
37
+    std::cout << temp->getTemp() << std::endl;
38
+
39
+    return 0;
40
+}
41
+//! [Interesting]

+ 5
- 0
src/max31855/CMakeLists.txt Datei anzeigen

@@ -0,0 +1,5 @@
1
+set (libname "max31855")
2
+set (libdescription "K type thermistor amplifier")
3
+set (module_src ${libname}.cxx)
4
+set (module_h ${libname}.h)
5
+upm_module_init()

+ 9
- 0
src/max31855/jsupm_max31855.i Datei anzeigen

@@ -0,0 +1,9 @@
1
+//! [Interesting]
2
+%module jsupm_max31855
3
+
4
+%{
5
+    #include "max31855.h"
6
+%}
7
+
8
+%include "max31855.h"
9
+//! [Interesting]

+ 103
- 0
src/max31855/max31855.cxx Datei anzeigen

@@ -0,0 +1,103 @@
1
+/*
2
+ * Author: Brendan Le Foll <brendan.le.foll@intel.com>
3
+ * Copyright (c) 2014 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 <unistd.h>
27
+#include <stdlib.h>
28
+#include <functional>
29
+#include <string.h>
30
+
31
+#include "max31855.h"
32
+
33
+using namespace upm;
34
+
35
+//! [Constructor]
36
+MAX31855::MAX31855(int bus, int cs)
37
+{
38
+    // initialise chip select as a normal gpio
39
+    m_gpio = maa_gpio_init(cs);
40
+    maa_gpio_dir(m_gpio, MAA_GPIO_OUT);
41
+
42
+    // initialise the spi bus with a 2Mhz clock
43
+    m_sensor = maa_spi_init(bus);
44
+    maa_spi_frequency(m_sensor, 2000000);
45
+}
46
+//! [Constructor]
47
+
48
+//! [Destructor]
49
+MAX31855::~MAX31855()
50
+{
51
+    // close both m_sensor & m_gpio cleanly
52
+    maa_result_t error;
53
+    error = maa_spi_stop(m_sensor);
54
+    if (error != MAA_SUCCESS) {
55
+        maa_result_print(error);
56
+    }
57
+    error = maa_gpio_close(m_gpio);
58
+    if (error != MAA_SUCCESS) {
59
+        maa_result_print(error);
60
+    }
61
+}
62
+//! [Destructor]
63
+
64
+double
65
+MAX31855::getTemp()
66
+{
67
+//! [spi]
68
+    // set chip select low
69
+    maa_gpio_write(m_gpio, 0);
70
+
71
+    uint8_t buf[4];
72
+
73
+    // set our input buffer to 0, this is clean but not required
74
+    memset(buf, 0, sizeof(uint8_t)*4);
75
+
76
+    // Write buffer to the spi slave
77
+    uint8_t* x = maa_spi_write_buf(m_sensor, buf, 4);
78
+//! [spi]
79
+
80
+//! [conversion]
81
+    // Endian correct way of making our char array into an 32bit int
82
+    int32_t temp = (x[0] << 24) | (x[1] << 16) | (x[2] << 8) | x[3];;
83
+
84
+    // maa_spi_write_buf does not free the return buffer
85
+    free(x);
86
+
87
+    if (temp & 0x7) {
88
+        std::cerr << "Something went very wrong!" << std::endl;
89
+    }
90
+
91
+    // scrap all the data we dont care about
92
+    temp >>= 18;
93
+
94
+    // LSB = 0.25 degrees C
95
+    double c = (double) temp;
96
+    c *= 0.25;
97
+//! [conversion]
98
+
99
+    // set chip select high
100
+    maa_gpio_write(m_gpio, 1);
101
+
102
+    return c;
103
+}

+ 69
- 0
src/max31855/max31855.h Datei anzeigen

@@ -0,0 +1,69 @@
1
+/*
2
+ * Author: Brendan Le Foll <brendan.le.foll@intel.com>
3
+ * Copyright (c) 2014 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 <maa/spi.h>
28
+#include <maa/gpio.h>
29
+
30
+namespace upm {
31
+
32
+/**
33
+ * @brief C++ API for MAX31855
34
+ *
35
+ * This file defines the max31855 SPI sensor
36
+ *
37
+ * @snippet examples/max31855.cxx Interesting
38
+ *
39
+ */
40
+ //! [Interesting]
41
+class MAX31855 {
42
+    public:
43
+        /**
44
+         * Instanciates a MAX31855 object
45
+         *
46
+         * @param bus The spi bus to use
47
+         * @param cs The chip select pin
48
+         */
49
+        MAX31855(int bus, int cs);
50
+
51
+        /**
52
+         * MAX31855 object destructor
53
+         */
54
+        ~MAX31855();
55
+
56
+        /**
57
+         * Get the distance from the sensor
58
+         *
59
+         * @return value in degrees celcius
60
+         */
61
+        double getTemp();
62
+
63
+    private:
64
+        maa_spi_context m_sensor;
65
+        maa_gpio_context m_gpio;
66
+};
67
+//! [Interesting]
68
+
69
+}

+ 10
- 0
src/max31855/pyupm_max31855.i Datei anzeigen

@@ -0,0 +1,10 @@
1
+%module pyupm_max31855
2
+
3
+%include "stdint.i"
4
+
5
+%feature("autodoc", "3");
6
+
7
+%include "max31855.h"
8
+%{
9
+    #include "max31855.h"
10
+%}