lmt01.cpp 3.71 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
/* Copyright (c) 2017 Philippe Kalaf, MIT License
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
 * and associated documentation files (the "Software"), to deal in the Software without restriction, 
 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or 
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 
 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

/* LMT01 temperature sensor driver */
#include "lmt01.h"

/* Taken from datasheet */
const int LMT01::_pulse_temp_table[20][2] = {
                 {-40, 181}, {-30, 338}, {-20, 494}, {-10, 651}, {0, 808}, 
                 {10, 966}, {20, 1125}, {30, 1284}, {40, 1443}, {50, 1603},
                 {60, 1762}, {70, 1923}, {80, 2084}, {90, 2245}, {100, 2407},
                 {110, 2569}, {120, 2731}, {130, 2894}, {140, 3058}, {150, 3220}
                 };

30 31 32 33 34 35 36
LMT01::LMT01(PinName pin) : _interrupt(pin), _worker_thread(osPriorityNormal, 1024) {        // create the InterruptIn on the pin specified to LMT01

    _interrupt.mode(PullUp); // an internal pull up is used, otherwise disable here
    _interrupt.fall(callback(this, &LMT01::_increment)); // attach increment function of this counter instance

    // Start worker thread for counting pulses and calculating temp
    _worker_thread.start(callback(this, &LMT01::_worker));
37 38
}

39
void LMT01::_worker()
40 41
{
    uint16_t i;
42

43
    while(true)
44
    {
45 46
        _interrupt.enable_irq();
        ThisThread::sleep_for(250);
47
        _pulse_count = 0;
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
        _last_pulse_count = 0;

        // Let's skip the first potentially partial pulse train
        while (_pulse_count != _last_pulse_count || _pulse_count == 0 || _last_pulse_count == 0)
        {
            _last_pulse_count = _pulse_count;
            ThisThread::sleep_for(1);
        }

        // OK let's now count the next pulse train from the start
        _pulse_count = 0;
        _last_pulse_count = 0;

        while (_pulse_count != _last_pulse_count || _pulse_count == 0 || _last_pulse_count == 0)
        {
            _last_pulse_count = _pulse_count;
            ThisThread::sleep_for(1);
        }

        // Find pulse/temp range from table
        for (i = 0; i < sizeof(_pulse_temp_table); i++)
            if (_last_pulse_count < _pulse_temp_table[i][1])
                break;

        // Read/convert/store count as temperature
        _temperature = 
            (
             (
              ((_last_pulse_count - _pulse_temp_table[i-1][1]) * 1000) / 
              (_pulse_temp_table[i][1] - _pulse_temp_table[i-1][1])
             ) * 10 // at this point unit is 10^3 Celsius
            ) 
            + _pulse_temp_table[i-1][0] * 1000;

        _interrupt.disable_irq();

        ThisThread::sleep_for(250);
85
    }
86 87 88 89
}

void LMT01::_increment()
{
90 91 92 93 94 95 96 97 98 99 100 101 102 103
        _pulse_count++;
}

// returns temperature in 10^3 Celsius
int LMT01::read_int()
{
    return _temperature;
}

// return temperature in Celsius
float LMT01::read()
{
    return float(_temperature)/1000;
}
104 105 106 107 108

uint16_t LMT01::get_last_pulse_count()
{
    return _last_pulse_count;
}