Fermion: MCP9808 I2C High Accuracy Temperature Sensor Breakout Board Wiki - DFRobot

Introduction

Compared to DS18B20, LM35 and other common temperature sensors, the MCP9808 is one of the more accurate temperature sensing options, with a typical accuracy of ±0.25°C and maximum accuracy of ±0.5°C over the sensor's -40°C to +125°C range and precision of +0.0625°C.
The MCP9808 comes with user-programmable registers that allow user-selectable settings such as Shutdown or Low-Power modes and the specification of temperature Alert window limits and critical output limits. When the temperature changes beyond the specified boundary limits, the MCP9808 outputs an Alert signal. The user has the option of setting the Alert output signal polarity as an active-low or active-high comparator output for thermostat operation, or as a temperature Alert interrupt output for microprocessor-based systems. These features make the MCP9808 ideal for sophisticated, multi-zone, temperature-monitoring applications.

Applications

Specification

Pinout

Pinout

Label Description
VCC Power Positive
GND Power Negative
SCL Clock line
SDA Data line
ALT Alert
A0 IIC Address Configuration Pin
A1 IIC Address Configuration Pin
A2 IIC Address Configuration Pin

Tutorial

Requirements


  /**
   * @fn sleepMode
   * @brief Sensor sleep mode, lower power consumption, failed to get sensor temp at this time
   * @return bool type, indicate the returned status
   * @retval true is set successfully
   * @retval false is register lock is not allowed to be modified
   */
  bool sleepMode(void);

  /**
   * @fn wakeUpMode
   * @brief Sensor waking up mode, sensor data can be obtained normally at this time
   * @return bool type, indicate the returned status
   * @retval true is set successfully
   * @retval false is register lock is not allowed to be modified
   */
  bool wakeUpMode(void);

  /**
   * @fn wakeUpMode
   * @brief Get the configured power mode
   * @return bool type, indicate the returned status
   * @retval true is waking up mode
   * @retval false is sleep mode
   */
  bool getPowerMode(void);

  /**
   * @fn setResolution
   * @brief Set resolution of the temperature sensor, the accuracy of the acquired temp is different in different resolution
   * @param resolution
   * @n     RESOLUTION_0_5     // The decimal part of the obtained temp is a multiple of 0.5     e.g. 0.5°C, 1.0°C, 1.5°C
   * @n     RESOLUTION_0_25    // The decimal part of the obtained temp is a multiple of 0.25    e.g. 0.25°C, 0.50°C, 0.75°C
   * @n     RESOLUTION_0_125   // The decimal part of the obtained temp is a multiple of 0.125   e.g. 0.125°C, 0.250°C, 0.375°C
   * @n     RESOLUTION_0_0625  // The decimal part of the obtained temp is a multiple of 0.0625  e.g. 0.0625°C, 0.1250°C, 0.1875°C
   * @return The set status
   * @retval true is set successfully
   * @retval false is set parameter error
   */
  bool setResolution(uint8_t resolution);

  /**
   * @fn getResolution
   * @brief Get resolution of the temperature sensor, the accuracy of the acquired temp is different in different resolution
   * @return resolution
   * @retval RESOLUTION_0_5     // The decimal part of the obtained temp is a multiple of 0.5     e.g. 0.5°C, 1.0°C, 1.5°C
   * @retval RESOLUTION_0_25    // The decimal part of the obtained temp is a multiple of 0.25    e.g. 0.25°C, 0.50°C, 0.75°C
   * @retval RESOLUTION_0_125   // The decimal part of the obtained temp is a multiple of 0.125   e.g. 0.125°C, 0.250°C, 0.375°C
   * @retval RESOLUTION_0_0625  // The decimal part of the obtained temp is a multiple of 0.0625  e.g. 0.0625°C, 0.1250°C, 0.1875°C
   */
  uint8_t getResolution(void);

  /**
   * @fn getTemperature
   * @brief Get the current ambient temp, note that different temp accuracy can be obtained by setting different resolution
   * @return The temp value is a floating point, default to reserve two decimal places, unit is °C
   */
  float getTemperature(void);

  /**
   * @fn getComparatorState
   * @brief Get the current comparator status and temp data, which works only in comparator mode
   * @return Struct for storing the current data
   * @n      temperate        // Current temp
   * @n      state            // Character string of the comparator status, compare the current temp with the upper threshold, lower threshold, and threshold value
   * @n      value            // Value of the comparator status, explained as follows
   * @n      TA for current temp, TCRIT for critical temp, TUPPER for maximum temp, TLOWER for minimum temp
   * @n      1 for TA ≥ TCRIT, TA > TUPPER, TA < TLOWER
   * @n      0 for TA < TCRIT, TA ≤ TUPPER, TA ≥ TLOWER
   * @n      ------------------------------------
   * @n      | bit7 ~ bit3 | bit2 | bit1 | bit0 |
   * @n      ------------------------------------
   * @n      |  reserved   |  0   |  0   |  0   |
   * @n      ------------------------------------
   */
  sComparator_t getComparatorState(void);

  /**
   * @fn setLockState
   * @brief Set lock mode or unlock, prevent wrong operations that may change upper limit, lower limit and threshold value, and unlock only by power-off reset after locking
   * @param lock
   * @n     CRIT_LOCK       // Lock threshold value, which is not allowed to be changed
   * @n     WIN_LOCK        // Lock upper and lower thresholds, which are not allowed to be changed
   * @n     CRIT_WIN_LOCK   // Lock threshold value, upper and lower limit, which are not allowed to be changed
   * @n     NO_LOCK         // No locking of threshold value, upper and lower limit
   * @return bool type return the set status
   * @retval true  is set successfully
   * @retval false is set parameter error
   */
  bool setLockState(uint8_t lock);

  /**
   * @fn getLockState
   * @brief Get locking status, to determine if upper limit, lower limit, and threshold can be changed
   * @return Locking status
   * @retval CRIT_LOCK       // Lock threshold value, which is not allowed to be changed
   * @retval WIN_LOCK        // Lock upper and lower thresholds, which are not allowed to be changed
   * @retval CRIT_WIN_LOCK   // Lock threshold and the window at the same time, upper limit, lower limit, and threshold are all not allowed to be changed
   * @retval NO_LOCK         // No locking, threshold value, upper and lower limit are all can be changed
   */
  uint8_t getLockState(void);

  /**
   * @fn setAlertHysteresis
   * @brief Set alert temp hysteresis range, add a range to the upper limit, lower limit and threshold, hysteresis function is only applicable to reduce temperature(from hot to cold),
   * @details i.e, ALE level will be restored only when the temp reaches the value obtained by subtracting hysteresis temp from the upper limit/lower limit/threshold
   * @details  For example: maximum temp is 30.0°C, hysteresis temp is +1.5°C, the current temp is 35°C and ALE level has flipped, 
   * @details  the temp must reach 30-1.5=28.5°C before restoring ALE level
   * @param mode
   * @n     HYSTERESIS_0_0        // No hysteresis, there is respond when reaching the specified temp
   * @n     HYSTERESIS_1_5        // 1.5℃ lag from hot to cold
   * @n     HYSTERESIS_3_0        // 3.0℃ lag from hot to cold
   * @n     HYSTERESIS_6_0        // 6.0℃ lag from hot to cold
   * @return uint8_t type
   * @retval 0x00 is set successfully
   * @retval 0xFE is set parameter error
   * @retval 0xFF is register lock, not allowed to be modified
   */
  uint8_t setAlertHysteresis(uint8_t mode);

  /**
   * @fn getAlertHysteresis
   * @brief Get hysteresis temp
   * @return hysteresis type
   * @retval HYSTERESIS_0_0        // Temp hysteresis range +0.0℃
   * @retval HYSTERESIS_1_5        // Temp hysteresis range +1.5℃
   * @retval HYSTERESIS_3_0        // Temp hysteresis range +3.0℃
   * @retval HYSTERESIS_6_0        // Temp hysteresis range +6.0℃
   */
  uint8_t getAlertHysteresis(void);

  /**
   * @fn setPolarity
   * @brief Set pin ALE polarity, high polarity: pin ALE is active on high, the default is low level, which turns to high when alert occurs.
   * @details                 low polarity: pin ALE is active on low, the default is high level, which turns to low when alert occurs.
   * @param polarity
   * @n     POLARITY_HIGH         // pin ALE is active on high
   * @n     POLARITY_LOW          // pin ALE is active on low
   * @return state
   * @retval 0x00 is set successfully
   * @retval 0xFE is set parameter error
   * @retval 0xFF is register lock, not allowed to be modified
   */
  uint8_t setPolarity(uint8_t polarity);

  /**
   * @fn getPolarityState
   * @brief Get pin ALE polarity, high polarity: pin ALE is active on high, the default is low level, which turns to high when alert occurs.
   * @details                     low polarity: pin ALE is active on low, the default is high level, which turns to low when alert occurs.
   * @return polarity
   * @retval POLARITY_HIGH         // pin ALE is active on high
   * @retval POLARITY_LOW          // pin ALE is active on low
   */
  uint8_t getPolarityState(void);

  /**
   * @fn setAlertOutputMode
   * @brief Set alert output mode, clearing interrupt is not required in comparator output mode, but required in interrupt mode
   * @param mode:
   * @n     COMPARATOR_OUTPUT_MODE           // clearing interrupt is not required in comparator output mode, 
   * @n         For example: set pin ALE to be active on low, when the temp exceeds the upper limit alert temp, pin ALE level turns from high to low; when it's below the upper but above the lower limit, pin ALE level turns back to high
   * @n     INTERRPUT_OUTPUT_MODE            // clearing interrupt is required in interrupt mode, when an alert occurs, the interrupt keep existing if it's not cleared, triggering interrupt mode indicates one status to another, 
   * @n         For example, set lower threshold to be 20°C, upper threshold 25°C, and threshold 30°C, no interrupt occurs when temp is below 20°C; when temp exceeds 25°C, interrupt occurs and pin ALE jump, the interrupt should be cleared at the time and pin ALE is restored; in the special case, when pin ALE is above the critical temp of 30°C, the interrupt mode and clearing interrupt are both invalid, the interrupt mode will be restored only when the temp drops below 30 degrees.
   * @n     DISABLE_OUTPUT_MODE              // After disabling output mode, no alert occurs and pin ALE is invalid
   * @return state
   * @retval 0x00 is set successfully
   * @retval 0xFE is set parameter error
   * @retval 0xFF is register lock, not allowed to be modified
   */
  uint8_t setAlertOutputMode(uint8_t mode);

  /**
   * @fn getAlertOutputMode
   * @brief Get alert output mode
   * @return mode
   * @retval COMPARATOR_OUTPUT_MODE           // Comparator output mode
   * @retval INTERRPUT_OUTPUT_MODE            // Interrupt output mode
   * @retval DISABLE_OUTPUT_MODE              // Disable output mode
   */
  uint8_t getAlertOutputMode(void);

  /**
   * @fn setAlertResponseMode
   * @brief Set alert response mode, respond to upper & lower limits and threshold; or only respond to threshold, which is inapplicable to interrupt mode
   * @param mode
   * @n     UPPER_LOWER_CRIT_RESPONSE         // respond to upper/lower limits and threshold 
   * @n     ONLY_CRIT_RESPONSE                // disable upper/lower limits response, only enable threshold response
   * @return state
   * @retval 0x00 is set successfully
   * @retval 0xFE is set parameter error
   * @retval 0xFF is register lock, not allowed to be modified
   */
  uint8_t setAlertResponseMode(uint8_t mode);

  /**
   * @fn getAlertResponseMode
   * @brief Get interrupt response mode
   * @return mode
   * @retval UPPER_LOWER_CRIT_RESPONSE         // respond to upper/lower limits and threshold
   * @retval ONLY_CRIT_RESPONSE                // disable upper/lower limits response, only enable threshold response
   */
  uint8_t getAlertResponseMode(void);

  /**
   * @fn setThreshold
   * @brief Set threshold value, the upper and lower thresholds, and respond according to the configured interrupt mode
   * @details Responding interrupt when the temp is above the upper limit, below the lower limit and above the threshold
   * @details The critical temp must be above the upper limit
   * @details the upper limit temp must be 2℃ higher than the lower limit temp 
   * @param crit  // Temp threshold, up to two decimal places, automatically processed to multiples of 0.25, range is from -40 to +125℃
   * @param upper // Upper limit temp, up to two decimal places, automatically processed to multiples of 0.25, range is from -40 to +125℃
   * @param lower // Lower limit temp, up to two decimal places, automatically processed to multiples of 0.25, range is from -40 to +125℃
   * @return state
   * @retval 0x00 is set successfully
   * @retval 0xFD  // Upper limit temp is below lower limit, or (upper limit temp - lower limit temp < 2)
   * @retval 0xFE  // Upper limit temp is below threshold
   * @retval 0xFF is register lock, not allowed to be modified
   */
  uint8_t setThreshold(float crit, float upper, float lower);

  /**
   * @fn clearInterrupt
   * @brief Clear interrupt, only used in interrupt mode, not work in other modes
   */
  void clearInterrupt(void);

protected:
  /**
   * @fn sensorInit
   * @brief Initialize sensor, comtrast sensor chip id with manufacturer id
   * @return state
   * @retval true  is init successfully
   * @retval flase is sensor chip id and manufacturer id error
   */
  bool sensorInit(void);

  /**
   * @fn setPowerMode
   * @brief Set power mode, power up mode: in this mode, the register can be accessed and the temp can be obtained normally.
   * @details            Low power mode: temp measurement stop and the register can be read or written, but bus activity will cause higher power consumption
   * @param mode
   * @n     POWER_UP_MODE         // power up mode
   * @n     LOW_POWER_MODE        // low power mode
   * @return The set status
   * @retval true  is set success
   * @retval false is register lock, not allowed to be modified
   */
  bool setPowerMode(uint8_t mode);

  /**
   * @fn setAlertEnable
   * @brief Enable or disable alert mode, after enabling it, pin ALE will jump when satisfying the alert condition; if disabling it, pin ALE has no response.
   * @param mode
   * @n     ENABLE_ALERT           // after enabling alert mode, pin ALE will jump when satisfying the alert condition
   * @n     DISABLE_ALERT          // when disabling alert mode, pin ALE has no response
   * @return state
   * @retval 0x00 is set successfully
   * @retval 0xFE is set parameter error
   * @retval 0xFF is register lock, not allowed to be modified
   */
  uint8_t setAlertEnable(uint8_t mode);

  /**
   * @fn getAlertEnableState
   * @brief Get the alert mode status, enable alert mode or disable it
   * @return mode
   * @retval ENABLE_ALERT           // enable alert mode
   * @retval DISABLE_ALERT          // disable alert mode
   */
  uint8_t getAlertEnableState(void);

  /**
   * @fn parsingDecimal
   * @brief Parse floating point, used to set the floating point of upper/lower limit and threshold
   * @return Binary floating point
   */
  uint8_t parsingDecimal(float value);

  /**
   * @fn getManufacturerID
   * @brief get manufacturer id
   * @return manufacturer id
   * @retval true               // manufacturer id is true
   * @retval false              // manufacturer id is false
   */
  bool getManufacturerID(void);

  /**
   * @fn getDeviceID
   * @brief get device id
   * @return device id
   * @retval true               // device id is true
   * @retval false              // device id is false
   */
  bool getDeviceID(void);

  /**
   * @fn dataThreshold
   * @brief Parse the integer portion of the threshold, and place it in the specified position
   * @param value The threshold data to be placed
   * @param data  The address to place
   */

Connection Diagram

Connection Diagram

Sample Code 1 - Get Temperature

The temperature is displayed on the serial port. The measured temperature changes with the ambient temperature.

/*!
 * @file getTemperature.ino
 * @brief The example of obtaining temp normally
 * @details Experimental phenomenon: display the temp on the serial port, the measured temp varies with ambient temp
 * @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @license The MIT License (MIT)
 * @author ZhixinLiu(zhixin.liu@dfrobot.com)
 * @version V1.0
 * @date 2021-04-16
 * @url https://github.com/DFRobot/DFRobot_MCP9808
 */
#include "DFRobot_MCP9808.h"

/**
 * i2c address select, default to be MCP9808_ADDRESS_7, pin A2, A1 and A0 is at high level
 *    1 for high level, 0 for low level,  | A2 | A1 | A0 |
 *    MCP9808_ADDRESS_0        | 0  | 0  | 0  |    0x18
 *    MCP9808_ADDRESS_1        | 0  | 0  | 1  |    0x19
 *    MCP9808_ADDRESS_2        | 0  | 1  | 0  |    0x1A
 *    MCP9808_ADDRESS_3        | 0  | 1  | 1  |    0x1B
 *    MCP9808_ADDRESS_4        | 1  | 0  | 0  |    0x1D
 *    MCP9808_ADDRESS_5        | 1  | 0  | 1  |    0x1D
 *    MCP9808_ADDRESS_6        | 1  | 1  | 0  |    0x1E
 *    MCP9808_ADDRESS_7        | 1  | 1  | 1  |    0x1F
 */
#define I2C_ADDRESS  MCP9808_ADDRESS_7
DFRobot_MCP9808_I2C mcp9808(&Wire, I2C_ADDRESS);

void setup()
{
  Serial.begin(115200);
  while(!Serial);
  while(!mcp9808.begin()){
    Serial.println("begin failed!");
    delay(1000);
  } Serial.println("begin success!");

  /**
   * Wake up sensor, sensor data can be obtained normally at this time
   */
  if(!mcp9808.wakeUpMode()){
    Serial.println("Register locked, Please unlock!");
  }else{
    Serial.println("Wake up sensor successfully, can read the temperature!");
  }

  /**
   * Set temp resolution
   *  RESOLUTION_0_5      The decimal part of the obtained temp is a multiple of 0.5     e.g. 0.5°C, 1.0°C, 1.5°C
   *  RESOLUTION_0_25     The decimal part of the obtained temp is a multiple of 0.25    e.g. 0.25°C, 0.50°C, 0.75°C
   *  RESOLUTION_0_125    The decimal part of the obtained temp is a multiple of 0.125   e.g. 0.125°C, 0.250°C, 0.375°C
   *  RESOLUTION_0_0625   The decimal part of the obtained temp is a multiple of 0.0625  e.g. 0.0625°C, 0.1250°C, 0.1875°C
   */
  if(mcp9808.setResolution(RESOLUTION_0_125)){
    Serial.println("Set temp resolution successfully!");
  }else{
    Serial.println("parameter error!");
  }
}

void loop()
{
  Serial.print("Temperature is ="); 
  Serial.print(mcp9808.getTemperature());
  Serial.println(" C");
  delay(1000);
}

Result

Serial print the obtained temp and humidity data.

Sample Code 2 - Interrupt Mode

Example for temperature upper limit, lower limit and critical value triggering interrupts. Connect ALE pin to pin 2.

/*!
 * @file interruptMode.ino
 * @brief The example of the upper, lower, and threshold temp triggering an interrupt
 * @details Experimental phenomenon: display the temp on the serial port, the measured temp varies with ambient temp
 * @details Experimental phenomenon: interrupt occurs at IO when the temp status changes, for example, no interrupt occurs if the temp is between the upper limit and lower limit, or has been lower than the lower or higher than the upper limit
 * @details Experimental phenomenon: when the temp status turns from being below the lower limit to above it, interrupt occurs and needs to be cleared,
 * @details Experimental phenomenon: after clearing the interrupt, pin ALE level is restored; when the temp is above the threshold, clearing interrupt is invalid(pin ALE level is not restored)
 * @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @license The MIT License (MIT)
 * @author ZhixinLiu(zhixin.liu@dfrobot.com)
 * @version V1.0
 * @date 2021-04-16
 * @url https://github.com/DFRobot/DFRobot_MCP9808
 */
#include "DFRobot_MCP9808.h"

/**
 * i2c address select, default to be MCP9808_ADDRESS_7, pin A2, A1 and A0 is at high level
 *    1 for high level, 0 for low level,  | A2 | A1 | A0 |
 *    MCP9808_ADDRESS_0        | 0  | 0  | 0  |    0x18
 *    MCP9808_ADDRESS_1        | 0  | 0  | 1  |    0x19
 *    MCP9808_ADDRESS_2        | 0  | 1  | 0  |    0x1A
 *    MCP9808_ADDRESS_3        | 0  | 1  | 1  |    0x1B
 *    MCP9808_ADDRESS_4        | 1  | 0  | 0  |    0x1D
 *    MCP9808_ADDRESS_5        | 1  | 0  | 1  |    0x1D
 *    MCP9808_ADDRESS_6        | 1  | 1  | 0  |    0x1E
 *    MCP9808_ADDRESS_7        | 1  | 1  | 1  |    0x1F
 */
#define I2C_ADDRESS  MCP9808_ADDRESS_7
DFRobot_MCP9808_I2C mcp9808(&Wire, I2C_ADDRESS);

volatile uint8_t interruptFlag = 0;
void myInterrupt(void)
{
  interruptFlag = 1;   // interrupt flag
}

void setup()
{
  Serial.begin(115200);
  while(!Serial);
  while(!mcp9808.begin()){
    Serial.println("begin failed!");
    delay(1000);
  } Serial.println("begin success!");

  /**
   * Wake up sensor, sensor data can be obtained normally at this time
   */
  if(!mcp9808.wakeUpMode()){
    Serial.println("Register locked, Please unlock!");
  }else{
    Serial.println("Wake up sensor successfully, can read the temperature!");
  }

 /**
   * Set temp resolution
   *  RESOLUTION_0_5      The decimal part of the obtained temp is a multiple of 0.5     e.g. 0.5°C, 1.0°C, 1.5°C
   *  RESOLUTION_0_25     The decimal part of the obtained temp is a multiple of 0.25    e.g. 0.25°C, 0.50°C, 0.75°C
   *  RESOLUTION_0_125    The decimal part of the obtained temp is a multiple of 0.125   e.g. 0.125°C, 0.250°C, 0.375°C
   *  RESOLUTION_0_0625   The decimal part of the obtained temp is a multiple of 0.0625  e.g. 0.0625°C, 0.1250°C, 0.1875°C
   */
  if(mcp9808.setResolution(RESOLUTION_0_25)){
    Serial.println("Set temp resolution successfully!");
  }else{
    Serial.println("parameter error!");
  }

  /**
   * Set alert output mode, clearing interrupt is not required in comparator output mode, but required in interrupt mode
   *   COMPARATOR_OUTPUT_MODE           clearing interrupt is not required in comparator output mode, 
   *     For example: set pin ALE to be active on low, when the temp exceeds the upper limit alert temp, pin ALE level turns from high to low; when it's below the upper but above the lower limit, pin ALE level turns back to high
   *   INTERRPUT_OUTPUT_MODE            clearing interrupt is required in interrupt mode, when an alert occurs, the interrupt keep existing if it's not cleared, triggering interrupt mode indicates one status to another, 
   *     For example, set lower threshold to be 20°C, upper threshold 25°C, and threshold 30°C, no interrupt occurs when temp is below 20°C; when temp exceeds 25°C, interrupt occurs and pin ALE jump, the interrupt should be cleared at the time and pin ALE is restored,
   *     In the special case, when pin ALE is above the critical temp of 30°C, the interrupt mode and clearing interrupt are both invalid, the interrupt mode will be restored only when the temp drops below 30°C.
   *   DISABLE_OUTPUT_MODE              After disabling output mode, no alert occurs and pin ALE is invalid
   */
  if(mcp9808.setAlertOutputMode(INTERRPUT_OUTPUT_MODE) == 0){
    Serial.println("Set alert output mode successfully!");
  }else{
    Serial.println("Register locked or parameter error!");
  }

  /**
   * Set pin ALE polarity, high polarity: pin ALE is active on high, the default is low level, which turns to high when alert occurs.
   *                    low polarity: pin ALE is active on low, the default is high level, which turns to low when alert occurs.
   *   POLARITY_HIGH         pin ALE is active on high
   *   POLARITY_LOW          pin ALE is active on low
   */
  if(mcp9808.setPolarity(POLARITY_LOW) == 0){
    Serial.println("Set pin ALE polarity successfully!");
  }else{
    Serial.println("Register locked or parameter error!");
  }

  /**
   * Set alert response mode, respond to upper & lower limits and threshold; or only respond to threshold, which is inapplicable to interrupt mode
   *  UPPER_LOWER_CRIT_RESPONSE          respond to upper/lower limits and threshold
   *  ONLY_CRIT_RESPONSE                 disable upper/lower limits response, only enable threshold response
   */
  if(mcp9808.setAlertResponseMode(UPPER_LOWER_CRIT_RESPONSE) == 0){
    Serial.println("Set response mode successfully!");
  }else{
    Serial.println("Register locked or parameter error!");
  }

  /**
   * Set threshold value, the upper and lower thresholds, and respond according to the configured interrupt mode
   *  crit:    Temp threshold, up to two decimal places, automatically processed to multiples of 0.25, range is from -40 to +125°C
   *  upper:   Upper limit temp, up to two decimal places, automatically processed to multiples of 0.25, range is from -40 to +125°C
   *  lower:   Lower limit temp, up to two decimal places, automatically processed to multiples of 0.25, range is from -40 to +125°C
   */
  if(mcp9808.setThreshold(35.0, 30.0, 20.0) == 0){
    Serial.println("Set temp of threshold, upper and lower limit successfully!");
  }else{
    Serial.println("Register locked or data error");
  }

  /**
   * Set alert temp hysteresis range, add a range to the upper limit, lower limit and threshold, hysteresis function is only applicable to reduce temperature(from hot to cold),
   * i.e, ALE level will be restored only when the temp reaches the value obtained by subtracting hysteresis temp from the upper limit
   * For example: maximum temp is 30.0°C, hysteresis temp is +1.5°C, the current temp is 35°C and ALE level has flipped,
   *      the temp must reach 30-1.5(28.5) degrees before restoring ALE level
   *   HYSTERESIS_0_0        No hysteresis, respond when reaching the specified temp
   *   HYSTERESIS_1_5        1.5℃ lag from hot to cold
   *   HYSTERESIS_3_0        3.0℃ lag from hot to cold
   *   HYSTERESIS_6_0        6.0℃ lag from hot to cold
   */
  if(mcp9808.setAlertHysteresis(HYSTERESIS_1_5) == 0){
    Serial.println("Set temp hysteresis successfully!");
  }else{
    Serial.println("Register locked or parameter error!");
  }

  /**
   * Set lock mode or unlock, prevent wrong operations that may change upper limit, lower limit and threshold value, and unlock only by power-off reset after locking
   * unlock only by power-off reset after locking
   *   CRIT_LOCK       Lock threshold value, which is not allowed to be changed
   *   WIN_LOCK        Lock upper and lower thresholds, which are not allowed to be changed
   *   CRIT_WIN_LOCK   Lock threshold value, upper and lower limit, which are not allowed to be changed
   *   NO_LOCK         No locking of threshold value, upper and lower limit
   */
  if(mcp9808.setLockState(NO_LOCK)){
    Serial.println("Set locking mode successfully!");
  }else{
    Serial.println("parameter error!");
  }

  mcp9808.clearInterrupt();       //The temp status is unknown at the first time, so clear the interrupt
  #if defined(ESP32) || defined(ESP8266)||defined(ARDUINO_SAM_ZERO)
  /**
   * Select according to the set pin ALE polarity
   *  INPUT_PULLUP    Set polarity to low level, set pin 2 to pull-up input
   *  INPUT_PULLDOWN  Set polarity to high level, set pin 2 to pull-down input
   * interput io
   *  All pins can be used. Pin 13 is recommended
   */
  pinMode(/*Pin */13, INPUT_PULLUP);
  attachInterrupt(/*interput io*/13, myInterrupt, FALLING);
  Serial.println("use esp type");
  #else
  /**
   * ---------------------------------------------------------------------------------------
   * |                                        |    Pin       | 2  | 3  |                   |
   * |    Uno, Nano, Mini, other 328-based    |--------------------------------------------|
   * |                                        | Interrupt No | 0  | 1  |                   |
   * |-------------------------------------------------------------------------------------|
   * |                                        |    Pin       | 2  | 3  | 21 | 20 | 19 | 18 |
   * |               Mega2560                 |--------------------------------------------|
   * |                                        | Interrupt No | 0  | 1  | 2  | 3  | 4  | 5  |
   * |-------------------------------------------------------------------------------------|
   * |                                        |    Pin       | 3  | 2  | 0  | 1  | 7  |    |
   * |    Leonardo, other 32u4-based          |--------------------------------------------|
   * |                                        | Interrupt No | 0  | 1  | 2  | 3  | 4  |    |
   * |--------------------------------------------------------------------------------------
   */
  /**
   *                       The Correspondence Table of micro:bit Interrupt Pins And Terminal Numbers
   * ---------------------------------------------------------------------------------------------------------------------------------------------
   * |             micro:bit                       | DigitalPin |P0-P20 can be used as an external interrupt                                     |
   * |  (When using as an external interrupt,      |---------------------------------------------------------------------------------------------|
   * |no need to set it to input mode with pinMode)|Interrupt No|Interrupt number is a pin digital value, such as P0 interrupt number 0, P1 is 1 |
   * |-------------------------------------------------------------------------------------------------------------------------------------------|
   */
  pinMode(/*Pin */2 ,INPUT_PULLUP);

  /**
   * Set the pin to interrupt mode
   * Open the external interrupt 0, connect INT1/2 to the digital pin of the main control:
   *  function
   *   callback function
   *  state
   *   FALLING    When the pin level goes from high to low, the interrupt occur, and enter interrupt function
   *   RISING     When the pin level goes from low to high, the interrupt occur, and enter interrupt function
   */
  attachInterrupt(/*Interrupt No*/0, /*function*/myInterrupt, /*state*/FALLING);
  #endif
}

void loop()
{
  /**
   * Clear the alert interrupt when an interrupt is generated by ALE io port
   * Clear the interrupt generated by the upper/lower limit and threshold temp, the threshold interrupt can't be cleared
   */
  if(interruptFlag == 1){
    mcp9808.clearInterrupt();
    delay(1000);
    float temperature = mcp9808.getTemperature();
    Serial.print("Temperature is =");
    Serial.print(temperature);
    Serial.print(" C ");
    Serial.println("The temperature state has changed");
    interruptFlag = 0;
  }
    float temperature = mcp9808.getTemperature();
    Serial.print("Temperature is =");
    Serial.print(temperature);
    Serial.println(" C ");
  delay(1000);
}

Result

The temperature is displayed on the serial port. The measured temperature changes with the ambient temperature and IO interface interrupt will produce when the status switches. For example, interrupts won’t produce if the temperature is between the upper and lower limits or below the lower limit or beyond the upper limit. If the temperature, below the lower limit at first, goes up and exceeds the lower limit, a interrupt will be produced and needs to be cleared at this time. ALE pin level will restore after clearing the interrupt. But, interrupt clearing will fail when the temperature is beyond the critical value, and ALED pin level remains unchanged.

Sample Code 3 - Comparator Mode

Get the status of comparing the current temperature with the upper limit, lower limit and critical value.

/*!
 * @file comparatorMode.ino
 * @brief Get the status of comparing the current temp with the upper/lower limit and threshold.
 * @details Experimental phenomenon: display temp and comparison status on the serial port
 * @details Experimental phenomenon: when the temp is above the upper limit, pin ALE level will switch,
 * @details Experimental phenomenon: when the temp is below the lower limit, pin ALE level will switch,
 * @details Experimental phenomenon: when the temp is above the critical temp, pin ALE level will switch,
 * @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @license The MIT License (MIT)
 * @author ZhixinLiu(zhixin.liu@dfrobot.com)
 * @version V1.0
 * @date 2021-04-16
 * @url https://github.com/DFRobot/DFRobot_MCP9808
 */
#include "DFRobot_MCP9808.h"

/**
 * i2c address select, default to be MCP9808_ADDRESS_7, pin A2, A1 and A0 is at high level
 *    1 for high level, 0 for low level,  | A2 | A1 | A0 |
 *    MCP9808_ADDRESS_0        | 0  | 0  | 0  |    0x18
 *    MCP9808_ADDRESS_1        | 0  | 0  | 1  |    0x19
 *    MCP9808_ADDRESS_2        | 0  | 1  | 0  |    0x1A
 *    MCP9808_ADDRESS_3        | 0  | 1  | 1  |    0x1B
 *    MCP9808_ADDRESS_4        | 1  | 0  | 0  |    0x1D
 *    MCP9808_ADDRESS_5        | 1  | 0  | 1  |    0x1D
 *    MCP9808_ADDRESS_6        | 1  | 1  | 0  |    0x1E
 *    MCP9808_ADDRESS_7        | 1  | 1  | 1  |    0x1F
 */
#define I2C_ADDRESS  MCP9808_ADDRESS_7
DFRobot_MCP9808_I2C mcp9808(&Wire, I2C_ADDRESS);

void setup()
{
  Serial.begin(115200);
  while(!Serial);
  while(!mcp9808.begin()){
    Serial.println("begin failed!");
    delay(1000);
  } Serial.println("begin success!");

  /**
   * Wake up sensor, sensor data can be obtained normally at this time
   */
  if(!mcp9808.wakeUpMode()){
    Serial.println("Register locked, Please unlock!");
  }else{
    Serial.println("Wake up sensor successfully, can read the temperature!");
  }

  /**
   * Set temp resolution
   *  RESOLUTION_0_5      The decimal part of the obtained temp is a multiple of 0.5     e.g. 0.5°C, 1.0°C, 1.5°C
   *  RESOLUTION_0_25     The decimal part of the obtained temp is a multiple of 0.25    e.g. 0.25°C, 0.50°C, 0.75°C
   *  RESOLUTION_0_125    The decimal part of the obtained temp is a multiple of 0.125   e.g. 0.125°C, 0.250°C, 0.375°C
   *  RESOLUTION_0_0625   The decimal part of the obtained temp is a multiple of 0.0625  e.g. 0.0625°C, 0.1250°C, 0.1875°C
   */
  if(mcp9808.setResolution(RESOLUTION_0_25)){
    Serial.println("Set temp resolution successfully!");
  }else{
    Serial.println("parameter error!");
  }

  /**
   * Set alert output mode, clearing interrupt is not required in comparator output mode, but required in interrupt mode
   *   COMPARATOR_OUTPUT_MODE           clearing interrupt is not required in comparator output mode, 
   *     For example: set pin ALE to be active on low, when the temp exceeds the upper limit alert temp, pin ALE level turns from high to low; when it's below the upper but above the lower limit, pin ALE level turns back to high
   *   INTERRPUT_OUTPUT_MODE            clearing interrupt is required in interrupt mode, when an alert occurs, the interrupt keep existing if it's not cleared, triggering interrupt mode indicates changing status. 
   *     For example, set lower threshold to be 20 degrees, upper threshold 25°C, and threshold 30°C, no interrupt occurs when temp is below 20°C; when temp exceeds 25°C, interrupt occurs and pin ALE jump, the interrupt should be cleared at the time and pin ALE is restored;
   *     in the special case, when current temp is above the critical temp of 30°C, the interrupt mode and clearing interrupt are both invalid, the interrupt mode will be restored only when the temp drops below 30°C.
   *   DISABLE_OUTPUT_MODE              After disabling output mode, no alert occurs and pin ALE is invalid
   */
  if(mcp9808.setAlertOutputMode(COMPARATOR_OUTPUT_MODE) == 0){
    Serial.println("Set alert output mode successfully!");
  }else{
    Serial.println("Register locked or parameter error!");
  }

  /**
   * Set pin ALE polarity, high polarity: pin ALE is active on high, the default is low level, which turns to high when alert occurs.
   *                    low polarity: pin ALE is active on low, the default is high level, which turns to low when alert occurs.
   *   POLARITY_HIGH         pin ALE is active on high
   *   POLARITY_LOW          pin ALE is active on low
   */
  if(mcp9808.setPolarity(POLARITY_LOW) == 0){
    Serial.println("Set pin ALE polarity successfully!");
  }else{
    Serial.println("Register locked or parameter error!");
  }

  /**
   * Set alert response mode, respond to upper & lower limits and threshold; or only respond to threshold, which is inapplicable to interrupt mode
   *  UPPER_LOWER_CRIT_RESPONSE          respond to upper/lower limits and threshold
   *  ONLY_CRIT_RESPONSE                 disable upper/lower limits response, only respond to threshold
   */
  if(mcp9808.setAlertResponseMode(UPPER_LOWER_CRIT_RESPONSE) == 0){
    Serial.println("Set response mode successfully!");
  }else{
    Serial.println("Register locked or parameter error!");
  }

  /**
   * Set threshold value, the upper and lower thresholds, and respond according to the configured interrupt mode, responding interruption when the temp is above the upper limit, below the lower limit and above the threshold
   *  crit:    Temp threshold, up to two decimal places, automatically processed to multiples of 0.25, range is from -40 to +125°C
   *  upper:   Upper limit temp, up to two decimal places, automatically processed to multiples of 0.25, range is from -40 to +125°C
   *  lower:   Lower limit temp, up to two decimal places, automatically processed to multiples of 0.25, range is from -40 to +125°C
   */
  if(mcp9808.setThreshold(/*crit*/35.0, /*upper*/30.0, /*lower*/20.0) == 0){
    Serial.println("Set temp of threshold, upper and lower limit successfully!");
  }else{
    Serial.println("Register locked or data error");
  }

  /**
   * Set alert temp hysteresis range, add a range to the upper limit, lower limit and threshold, hysteresis function is only applicable to reduce temperature (from hot to cold)
   * i.e, ALE level will be restored only when the temp reaches the value obtained by subtracting hysteresis temp from the upper limit.
   * For example: maximum temp is 30.0°C, hysteresis temp is +1.5°C, the current temp is 35°C and ALE level has flipped,
   *      the temp must reach 30-1.5=28.5°C before restoring ALE level
   *   HYSTERESIS_0_0        No hysteresis, respond when reaching the specified temp
   *   HYSTERESIS_1_5        1.5℃ lag from hot to cold
   *   HYSTERESIS_3_0        3.0℃ lag from hot to cold
   *   HYSTERESIS_6_0        6.0℃ lag from hot to cold
   */
  if(mcp9808.setAlertHysteresis(HYSTERESIS_1_5) == 0){
    Serial.println("Set temp hysteresis successfully!");
  }else{
    Serial.println("Register locked or parameter error!");
  }

  /**
   * Set lock mode or unlock, prevent wrong operations that may change upper limit, lower limit and threshold value,
   * and unlock only by power-off reset after locking
   *   CRIT_LOCK       Lock threshold value, which is not allowed to be changed
   *   WIN_LOCK        Lock upper and lower thresholds, which are not allowed to be changed
   *   CRIT_WIN_LOCK   Lock threshold value, upper and lower limit, which are not allowed to be changed
   *   NO_LOCK         No locking of threshold value, upper and lower limit
   */
  if(mcp9808.setLockState(NO_LOCK)){
    Serial.println("Set locking mode successfully!");
  }else{
    Serial.println("parameter error!");
  }
}

void loop()
{
  /**
   * Get the current comparator status and temp data, which works only in comparator mode
   * Struct storing the current data
   *   temperate        Current temp
   *   state            Character string of the comparator status, compare the current temp with the upper threshold, lower threshold, and threshold value
   */
  sComparator_t data = mcp9808.getComparatorState();
  Serial.print("temperature = ");
  Serial.print(data.temperature);
  Serial.println(" C");
  Serial.print("state is ");
  Serial.println(data.state);
  delay(1000);
  // if(mcp9808.sleepMode()){ Serial.println("sleep sensor success!");}  // Sensor enter sleep mode, fail to get the correct temp in sleep mode
}

Result

The temperature and the comparing status will be displayed on the serial port. When the temperature beyond the upper limit, ALE pin level will reverse; when the temperature below the lower limit, ALE pin level will reverse; when the temperature beyond the critical temperature, ALE pin level will reverse.

FAQ

For any questions, advice or cool ideas to share, please visit the DFRobot Forum.

More Documents

DFshopping_car1.png Get Fermion MCP9808 High Accuracy I2C Temperature Sensor from DFRobot Store or DFRobot Distributor.

Turn to the Top