2014-06-13 16:44:48 +01:00
|
|
|
Making a UPM module for MAX31855 {#max31855}
|
|
|
|
================================
|
|
|
|
|
|
|
|
The Maxim Integrated MAX31855 is a thermocouple amplifier allowing you to read
|
2015-03-04 11:22:56 -08:00
|
|
|
from a K type thermocouple. My board comes from the Pmod kit form Maxim
|
2014-06-13 16:44:48 +01:00
|
|
|
(MAX31855PMB1) but you can get this from many different sources. The adafruit
|
|
|
|
people made arduino code already so we'll use that as a
|
|
|
|
[reference](https://github.com/adafruit/Adafruit-MAX31855-library/blob/master/Adafruit_MAX31855.cpp).
|
|
|
|
|
|
|
|
### Basics
|
|
|
|
|
2014-06-25 10:05:27 +01:00
|
|
|
This is a spi module so we will use the mraa spi functions to build our module.
|
2014-06-13 16:44:48 +01:00
|
|
|
First thing to do is to create a tree structure like this in upm/src/max31855:
|
|
|
|
|
|
|
|
* max31855.cxx
|
2016-04-25 14:27:51 -07:00
|
|
|
* max31855.hpp
|
2018-01-26 11:52:34 -08:00
|
|
|
* max31855.i
|
2014-06-13 16:44:48 +01:00
|
|
|
* CMakeLists.txt
|
|
|
|
|
|
|
|
And then an example file to use & test our lib with in upm/examples/max31855.cxx.
|
|
|
|
|
|
|
|
### Swig
|
|
|
|
|
|
|
|
The .i files are used by swig, there is one for each python & javascript. They
|
|
|
|
contain essentially the same thing and are very simple. The only thing to
|
|
|
|
change between the javascript & node.js one is the argument to %module.
|
|
|
|
|
|
|
|
@snippet jsupm_max31855.i Interesting
|
|
|
|
|
|
|
|
The %include parameter defines which functions will be available to the
|
|
|
|
node/python module created, Whilst the headers inside %{} will be explicitly
|
|
|
|
required during compilation. Typically only the top level header is required in
|
2014-06-25 14:02:12 +01:00
|
|
|
either of those args. The upm.i is just a shortcut to include some commonly
|
|
|
|
used swig wrappers for UPM sensors, it's not obligatory but recommended.
|
2014-06-13 16:44:48 +01:00
|
|
|
|
|
|
|
### API
|
|
|
|
|
2016-04-25 14:27:51 -07:00
|
|
|
Then we create the header (max31855.hpp) , a very simple header in our case we
|
2014-06-13 16:44:48 +01:00
|
|
|
will have only a very basic api. We provide a getTemp() function which will
|
|
|
|
return the same type as in the arduino library, a double.
|
|
|
|
|
2016-04-25 14:27:51 -07:00
|
|
|
@snippet max31855.hpp Interesting
|
2014-06-13 16:44:48 +01:00
|
|
|
|
|
|
|
Note that the header contains both the io that we will use, the gpio is in this
|
|
|
|
case used as the chip select pin.
|
|
|
|
|
|
|
|
### Implementing our API
|
|
|
|
|
|
|
|
In the adafruit library the read function (our chip is a 3pin SPI so only read
|
|
|
|
is possible), the spiread32() does all the work. It starts by setting up the io
|
|
|
|
so we will do the same in our constructor.
|
|
|
|
|
|
|
|
Note unlike on Arduino, we'll just set a 2Mhz clock and let the chip do the
|
|
|
|
work.
|
|
|
|
|
|
|
|
@snippet src/max31855/max31855.cxx Constructor
|
|
|
|
|
|
|
|
Then we also need to implement a nice cleanup in our destructor.
|
|
|
|
|
|
|
|
@snippet src/max31855/max31855.cxx Destructor
|
|
|
|
|
|
|
|
Then to read data, we will use spi_write_buf which will allow us to write a
|
|
|
|
whole uint32_t in order to get one back, which is what the arduino code does in
|
|
|
|
spiread32. Obviously we set our chip select to low first. Here is the start of
|
|
|
|
the implementation of MAX31855::getTemp()
|
|
|
|
|
|
|
|
@snippet src/max31855/max31855.cxx spi
|
|
|
|
|
|
|
|
Then using the arduino code as reference we simply reconstruct form the 4
|
|
|
|
uint8_t values a 32bit int value and select only the valuable parts of
|
2015-03-04 11:22:56 -08:00
|
|
|
information from that. The MAX31855 datasheet explains exactly which bits are
|
2014-06-13 16:44:48 +01:00
|
|
|
useful, we will just do the same as the adafruit code, first checking the error
|
|
|
|
bit and then scrapping everything but the 14bit of thermocouple data that are
|
|
|
|
useful to us and converting it to a double.
|
|
|
|
|
|
|
|
@snippet src/max31855/max31855.cxx conversion
|
|
|
|
|
|
|
|
### Finalizing
|
|
|
|
|
2015-03-04 11:22:56 -08:00
|
|
|
Our final example, very easy to use API!
|
2014-06-13 16:44:48 +01:00
|
|
|
|
2015-06-03 10:33:46 -07:00
|
|
|
@snippet examples/c++/max31855.cxx Interesting
|
2014-06-13 16:44:48 +01:00
|
|
|
|
|
|
|
### Building
|
|
|
|
|
|
|
|
The we need to add it to the examples/CMakeLists.txt. Only three lines are required
|
|
|
|
|
|
|
|
~~~~~~~~~~~
|
|
|
|
add_executable (max31855-example max31855.cxx)
|
|
|
|
include_directories (${PROJECT_SOURCE_DIR}/src/max31855)
|
|
|
|
target_link_libraries (max31855-example max31855 ${CMAKE_THREAD_LIBS_INIT})
|
|
|
|
~~~~~~~~~~~
|
|
|
|
|
2015-03-04 11:22:56 -08:00
|
|
|
Note you don't have to rebuild everything, cmake keeps target lists so if you
|
2014-08-28 17:59:21 +01:00
|
|
|
named your example target modulename-example you can simply do make
|
2014-06-13 16:44:48 +01:00
|
|
|
max31855-example and both the library & example will build.
|