Home | History | Annotate | Download | only in docs
      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 thermocouple. 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 mraa 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. The upm.i is just a shortcut to include some commonly
     35 used swig wrappers for UPM sensors, it's not obligatory but recommended.
     36 
     37 ### API
     38 
     39 Then we create the header (max31855.h) , a very simple header in our case we
     40 will have only a very basic api. We provide a getTemp() function which will
     41 return the same type as in the arduino library, a double.
     42 
     43 @snippet max31855.h Interesting
     44 
     45 Note that the header contains both the io that we will use, the gpio is in this
     46 case used as the chip select pin.
     47 
     48 ### Implementing our API
     49 
     50 In the adafruit library the read function (our chip is a 3pin SPI so only read
     51 is possible), the spiread32() does all the work. It starts by setting up the io
     52 so we will do the same in our constructor.
     53 
     54 Note unlike on Arduino, we'll just set a 2Mhz clock and let the chip do the
     55 work.
     56 
     57 @snippet src/max31855/max31855.cxx Constructor
     58 
     59 Then we also need to implement a nice cleanup in our destructor.
     60 
     61 @snippet src/max31855/max31855.cxx Destructor
     62 
     63 Then to read data, we will use spi_write_buf which will allow us to write a
     64 whole uint32_t in order to get one back, which is what the arduino code does in
     65 spiread32. Obviously we set our chip select to low first. Here is the start of
     66 the implementation of MAX31855::getTemp()
     67 
     68 @snippet src/max31855/max31855.cxx spi
     69 
     70 Then using the arduino code as reference we simply reconstruct form the 4
     71 uint8_t values a 32bit int value and select only the valuable parts of
     72 information from that. The MAX31855 datasheet explains exactly which bits are
     73 useful, we will just do the same as the adafruit code, first checking the error
     74 bit and then scrapping everything but the 14bit of thermocouple data that are
     75 useful to us and converting it to a double.
     76 
     77 @snippet src/max31855/max31855.cxx conversion
     78 
     79 ### Finalizing
     80 
     81 Our final example, very easy to use API!
     82 
     83 @snippet examples/c++/max31855.cxx Interesting
     84 
     85 ### Building
     86 
     87 The we need to add it to the examples/CMakeLists.txt. Only three lines are required
     88 
     89 ~~~~~~~~~~~
     90 add_executable (max31855-example max31855.cxx)
     91 include_directories (${PROJECT_SOURCE_DIR}/src/max31855)
     92 target_link_libraries (max31855-example max31855 ${CMAKE_THREAD_LIBS_INIT})
     93 ~~~~~~~~~~~
     94 
     95 Note you don't have to rebuild everything, cmake keeps target lists so if you
     96 named your example target modulename-example you can simply do make
     97 max31855-example and both the library & example will build.
     98