Driver to read and control a serial (i2c) temperature sensor, The Microchip MCP9808 is the digital sensor to control, can be read it, set its resolution, shutdown and also set alarms.

Dependents:   Hotboards_temp_alarms Hotboards_temp_fahrenheit Hotboards_temp_reading_temperature LCD_Temperatura

Hotboards_temp.cpp

Committer:
Hotboards
Date:
2016-03-22
Revision:
1:f850ee1083ba
Parent:
0:83da47b7ed26

File content as of revision 1:f850ee1083ba:

/*
  Hotboards_temp.cpp - Driver to read and control a serial (i2c) temperature sensor, The Microchip
  MCP9808 is the digital sensor to control, can be read it, set its resolution, shutdown and also
  set alarms.
  Hotboards eeprom board (http://hotboards.org)
  Created by Diego Perez, March 19, 2016.
  Released into the public domain.
*/
#include "Hotboards_temp.h"

#define SENSOR_ADDR       (uint8_t)0x3E
#define REG_CONFIG        (uint8_t)0x01
#define REG_ALERT_UPPER   (uint8_t)0x02
#define REG_ALERT_LOWER   (uint8_t)0x03
#define REG_CRITICAL_TEMP (uint8_t)0x04
#define REG_TEMPERATURE   (uint8_t)0x05
#define REG_MANU_ID       (uint8_t)0x06
#define REG_DEVICE_ID     (uint8_t)0x07
#define REG_RESOLUTION    (uint8_t)0x08

Hotboards_temp::Hotboards_temp( I2C &i2c, uint8_t address, uint8_t resolution )
    : _i2c(i2c) 
{
    _address = (address<<1)|0x30;
    _resolution = resolution;
}

bool Hotboards_temp::init( void )
{
    bool flag = 0; // lets assume device is not here
    uint16_t val = readReg( REG_MANU_ID );
    if( val == 0x0054 )
    {
        // device is presence, default set resolution
        writeReg( REG_RESOLUTION, _resolution);
        // clear configuration register (alarms included)
        writeReg( REG_CONFIG, 0x00 );
        flag = 1;
    }
    return flag;
}


float Hotboards_temp::read( void )
{
    uint16_t val;
    float temp;

    // read the Ta register
    val = readReg( REG_TEMPERATURE );

    // small algorithm to calculate tmeperature in Celcius
    // borrowed from https://github.com/adafruit/Adafruit_MCP9808_Library/blob/master/Adafruit_MCP9808.cpp
    temp = val & 0x0FFF;
    
    temp /=  (float)16.0;
     //check if a negative temperature
    if( val & 0x1000 ) temp -= 256;

    return temp;
}

void Hotboards_temp::setAlarms( float lower, float upper )
{
    // set alarm values
    writeAlarm( REG_ALERT_UPPER, upper );
    writeAlarm( REG_CRITICAL_TEMP, upper );
    writeAlarm( REG_ALERT_LOWER, lower );

    uint16_t val = readReg( REG_CONFIG );
    // set alarm only in comparator mode with LAERT pin set to LOW
    writeReg( REG_CONFIG, val | 0x0008 );
}

void Hotboards_temp::disableAlarms( void )
{
    uint16_t val = readReg( REG_CONFIG );
    // just clear the Alert Output Control bit
    writeReg( REG_CONFIG, val ^ 0x0008 );
}

void Hotboards_temp::shutdown( bool state )
{
    uint16_t val = readReg( REG_CONFIG );

    if( state == HT_SENSOR_OFF )
    {// shutdown, curretn under 1uA, and disable convertions
       writeReg( REG_CONFIG, val | 0x0100 );
    }
    else
    {// power on
       writeReg( REG_CONFIG, val ^ 0x0100 );
    }
}

void Hotboards_temp::setResolution( uint8_t resolution )
{
    resolution &= 0x03;
    writeReg( REG_RESOLUTION, resolution << 8 );
}

float Hotboards_temp::CelsiusToFarenheit( float celsius )
{
    return celsius * (float)9.0 / (float)5.0 + 32;
}

float Hotboards_temp::FarenheitToCelsius( float farenheit )
{
    return ( farenheit - 32 ) * (float)5.0 / (float)9.0;
}

uint16_t Hotboards_temp::readReg( uint8_t reg )
{
    uint16_t val;
    char buffer[2];
    
    _address &= 0x3E;
    buffer[0] = reg;
    _i2c.write( _address, buffer, 1, true );
    _address |= 0x01;
    _i2c.read( _address, buffer, 2, false );
    
    val = buffer[0] << 8;
    val |= buffer[1];

    return val;
}

void Hotboards_temp::writeReg( uint8_t reg, uint16_t val )
{
    char buffer[3] = { reg, val >> 8, val & 0x00FF };
    _address &= 0x3E;
    _i2c.write( _address, buffer, 3 );
}

void Hotboards_temp::writeAlarm( uint16_t reg, float temp )
{
    uint16_t val = 0x0000;
    // check if negative temp
    if( temp < 0 )
    {
        temp += (float)256.0;
        // set sign bit
        val = 0x1000;
    }
    // convert to binary
    val |= (uint16_t)( temp *= (float)16.0 );
    writeReg( reg, val );
}