名称介绍

简介

DS18B20、LM35是否已经不能满足您对测温的需求?为什么不试试MCP9808高精度数字温度传感器。 MCP9808 数字温度传感器可检测-40°C和+125°C之间的温度,提供±0.25°C/±0.5°C(典型值 / 最大值)高级精度的数据检测,以及最高+0.0625℃的用户可选择数据精度。 MCP9808具有用户可编程寄存器,可以实现关断或低功耗模式,以及温度报警窗口限制的规范和临界输出限制。 当温度变化超出规定的边界限制时,MCP9808会输出报警信号。用户可以设置比较器输出或温度报警中断输出。 这些特性使MCP9808成为精密的多区域温度监控应用的理想选择。

应用场景

技术规格

引脚说明

名称 功能描述
VCC 电源正极
GND 电源负极
SCL 时钟线
SDA 数据线
ALT 报警
A0 IIC地址配置引脚
A1 IIC地址配置引脚
A2 IIC地址配置引脚

使用教程

准备

关于如何安装库文件,点击链接

   /**
   * @brief 睡眠传感器模式, 功耗降低, 此时获取传感器温度错误
   * @return true is set successfully
             false is register lock is not allowed to be modified
   */
  bool sleepMode(void);

  /**
   * @brief 唤醒传感器模式, 此时可以正常获取传感器数据
   * @return true is set successfully
             false is register lock is not allowed to be modified
   */
  bool wakeUpMode(void);

  /**
   * @brief 获取电源的配置模式
   * @return  true     // 唤醒模式
              false    // 睡眠模式
   */
  bool getPowerMode(void);

  /**
   * @brief 设置温度传感器的分辨率, 不同的分辨率, 获取的温度的精度不同
   * @param resolution
                RESOLUTION_0_5     // 获取温度的小数部分为0.5的倍数     如0.5℃ 、1.0℃、1.5℃
                RESOLUTION_0_25    // 获取温度的小数部分为0.25的倍数    如0.25℃、0.50℃、0.75℃
                RESOLUTION_0_125   // 获取温度的小数部分为0.125的倍数   如0.125℃、0.250℃、0.375℃
                RESOLUTION_0_0625  // 获取温度的小数部分为0.0625的倍数  如0.0625℃、0.1250℃、0.1875℃
     @return true is set successfully
             false is set parameter error
   */
  bool setResolution(uint8_t resolution);

  /**
   * @brief 获取温度传感器的分辨率 ,不同的分辨率, 获取的温度的精度不同
   * @return resolution
                RESOLUTION_0_5     // 获取温度的小数部分为0.5的倍数     如0.5℃ 、1.0℃、1.5℃
                RESOLUTION_0_25    // 获取温度的小数部分为0.25的倍数    如0.25℃、0.50℃、0.75℃
                RESOLUTION_0_125   // 获取温度的小数部分为0.125的倍数   如0.125℃、0.250℃、0.375℃
                RESOLUTION_0_0625  // 获取温度的小数部分为0.0625的倍数  如0.0625℃、0.1250℃、0.1875℃
   */
  uint8_t getResolution(void);

  /**
   * @brief 获取当前的环境温度, 注意设置不同分辨率能够得到的温度精度不同
   * @return 温度值为浮点数, 默认保留两位小数, 单位为 ℃
   */
  float getTemperature(void);

  /**
   * @brief  获取当前比较器的状态和温度数据, 只有在比较器模式下有效
   * @return 存放当前数据的结构体
               temperate        // 当前温度
               state            // 比较器状态的字符串,比较当前温度和上限阈值,下限阈,和临界值的关系
               value            // 比较器的状态的值,解释如下
               TA 代表当前温度, TCRIT代表临界温度, TUPPER代表上限温度, TLOWER代表下限温度
               1 代表 TA ≥ TCRIT, TA > TUPPER, TA < TLOWER
               0 代表 TA < TCRIT, TA ≤ TUPPER, TA ≥ TLOWER
               ------------------------------------
               | bit7 ~ bit3 | bit2 | bit1 | bit0 |
               ------------------------------------
               |  reserved   |  0   |  0   |  0   |
               ------------------------------------
   */
  struct comparatorData getComparatorState(void);

  /**
   * @brief 设置锁定模式或解锁, 防止错误操作更改上限、下限、临界值的大小, 锁定后只能通过断电复位解除锁定
   * @param lock
                CRIT_LOCK       // 锁定临界值, 临界值的阈值不允许被修改
                WIN_LOCK        // 锁定上限下限, 上限下限的阈值不允许被修改
                CRIT_WIN_LOCK   // 锁定临界值和上限下限, 上限下限和临界值的数据都不允许被修改
                NO_LOCK         // 不锁定上限下限和临界值
     @return state
                true  is set successfully
                false is set parameter error
   */
  bool setLockState(uint8_t lock);

  /**
   * @brief 获取锁定的状态, 来判断是否可以修改上限下限和临界值的阈值
   * @return state
                CRIT_LOCK       // 临界值锁定, 临界值的阈值不允许被修改
                WIN_LOCK        // 上限下限锁定, 上限下限的阈值不允许被修改
                CRIT_WIN_LOCK   // 临界值和窗口同时锁定, 上限下限和临界值的数据都不允许被修改
                NO_LOCK         // 没有锁定, 上限下限和临界值的阈值都可以被修改
   */
  uint8_t getLockState(void);

  /**
   * @brief 设置报警温度滞后的范围, 在上限下限和临界值的阈值上增加一个范围,滞后功能仅适用于降温(从热至冷)
            ,也就是说(上限/下限/临界值)减去滞后温度, ALE电平才恢复
            例如:温度上限为30.0度, 滞后温度为+1.5度, 当前是35度ALE已经产生电平翻转, 
            要想ALE恢复电平, 必须达到30-1.5(28.5)度, ALE引脚才能恢复电平
   * @param mode
                HYSTERESIS_0_0        // 没有滞后, 就是到达指定温度就响应
                HYSTERESIS_1_5        // 从热至冷要滞后1.5℃
                HYSTERESIS_3_0        // 从热至冷要滞后3.0℃
                HYSTERESIS_6_0        // 从热至冷要滞后6.0℃
     @return state
                0x00 is set successfully
                0xFE is set parameter error
                0xFF is register lock is not allowed to be modified
   */
  uint8_t setAlertHysteresis(uint8_t mode);

  /**
   * @brief 获取滞后的温度
   * @return hysteresis
                HYSTERESIS_0_0        // 温度滞后范围为 +0.0℃
                HYSTERESIS_1_5        // 温度滞后范围为 +1.5℃
                HYSTERESIS_3_0        // 温度滞后范围为 +3.0℃
                HYSTERESIS_6_0        // 温度滞后范围为 +6.0℃
   */
  uint8_t getAlertHysteresis(void);

  /**
   * @brief 设置ALE引脚的极性, 引脚极性为高:ALE引脚高电平为活动电平, 默认为低电平, 产生报警后ALE为高电平
                               引脚极性为低:ALE引脚低极性为活动电平, 默认为高电平, 产生报警后ALE为低电平
   * @param polarity
                POLARITY_HIGH         // ALE引脚高电平为活动电平
                POLARITY_LOW          // ALE引脚低极性为活动电平
     @return state
                0x00 is set successfully
                0xFE is set parameter error
                0xFF is register lock is not allowed to be modified
   */
  uint8_t setPolarity(uint8_t polarity);

  /**
   * @brief 获取ALE引脚的极性状态, 引脚极性为高:ALE引脚高电平为活动电平, 默认为低电平, 产生报警后ALE为高电平
                                   引脚极性为低:ALE引脚低极性为活动电平, 默认为高电平, 产生报警后ALE为低电平
   * @return polarity
                POLARITY_HIGH         // ALE引脚高电平为活动电平
                POLARITY_LOW          // ALE引脚低极性为活动电平
   */
  uint8_t getPolarityState(void);

  /**
   * @brief 设置警报输出的模式, 比较器输出模式不需要清除中断, 中断模式需要清除中断
   * @param mode:
              COMPARATOR_OUTPUT_MODE           // 比较器输出模式不需要清除中断, 
                例如:设置ALE引脚为低电平活动,当超过上限警报的温度时, ALE引脚从高电平到低电平, 当温度低于上限但高于下限时, ALE引脚恢复高电平
              INTERRPUT_OUTPUT_MODE            // 中断输出模式需要清除中断, 当产生警报时, 如果不清除中断中断一直存在, 中断模式的触发, 是从一种状态变为另一种状态, 
                例如:设置了下限阈值20度, 上限阈值25度, 临界阈值30度, 当温度一直低于20度时不产生中断, 当温度超过25度时才产生中断, ALE引脚跳变, 此时应该清空中断, ALE引脚恢复, 特殊情况, 当ALE引脚大于临界温度30度时, 中断模式失效, 清空中断也失效, 必须等温度降到30度以下, 才恢复中断模式
              DISABLE_OUTPUT_MODE              // 禁止输出模式后不产生警报,ALE引脚失效
     @return state
                0x00 is set successfully
                0xFE is set parameter error
                0xFF is register lock is not allowed to be modified
   */
  uint8_t setAlertOutputMode(uint8_t mode);

  /**
   * @brief 获取警报输出的模式
   * @return mode
                COMPARATOR_OUTPUT_MODE           // 比较器输出模式
                INTERRPUT_OUTPUT_MODE            // 中断输出模式
                DISABLE_OUTPUT_MODE              // 禁止输出模式
   */
  uint8_t getAlertOutputMode(void);

  /**
   * @brief 设置响应模式, 响应上限下限和临界值, 或者只响应临界值, 只响应临界值不适用于中断模式
   * @param mode
                UPPER_LOWER_CRIT_RESPONSE         // 上限/下线和临界值 都响应, 
                ONLY_CRIT_RESPONSE                // 禁止上限下限响应, 只有临界值响应
     @return state
                0x00 is set successfully
                0xFE is set parameter error
                0xFF is register lock is not allowed to be modified
   */
  uint8_t setAlertResponseMode(uint8_t mode);

  /**
   * @brief 获取中断响应的模式
   * @return mode
                UPPER_LOWER_CRIT_RESPONSE         // 上限/下线和临界值 都响应
                ONLY_CRIT_RESPONSE                // 禁止上限下限响应, 只有临界值响应
   */
  uint8_t getAlertResponseMode(void);

  /**
   * @brief 设置临界值和上限和下限阈值,根据配置的中断模式响应
            高于上限温度和低于下限温度和高于临界值响应中断
            临界值温度必须大于上限温度
            上限温度必须大于下限温度 2摄氏度
   * @param crit
              // 温度临界值, 最多两位小数, 自动处理成0.25的倍数, 范围为-40 到 +125度
   * @param upper
              // 温度上限, 最多两位小数, 自动处理成0.25的倍数, 范围为-40 到 +125度
   * @param lower
              // 温度下限, 最多两位小数, 自动处理成0.25的倍数, 范围为-40 到 +125度
   * @return state
                0x00 is set successfully
                0xFD  // 温度上限小于下限, 或者(上限温度-下限温度 < 2 )
                0xFE  // 温度上限小于临界值
                0xFF is register lock is not allowed to be modified
   */
  uint8_t setThreshold(float crit, float upper, float lower);

  /**
   * @brief 清空中断, 只使用于中断模式下, 其余模式没有效果
   */
  void clearInterrupt(void);

protected:
  /**
   * @brief 初始化传感器, 对比传感器的芯片id 和 厂商 id
     @return state
                true  is init successfully
                flase is 芯片id或者厂商id错误
   */
  bool sensorInit(void);

  /**
   * @brief 设置电源模式, 上电模式:该模式下, 可以正常访问寄存器, 能够得到正常的温度;
                          低功耗模式:温度测量停止, 可以读取或写入寄存器, 但是总线活动会使耗电升高
   * @param mode
                POWER_UP_MODE         // 上电模式
                LOW_POWER_MODE        // 低功耗模式
   * @return true  is set success
             false is register lock is not allowed to be modified
   */
  bool setPowerMode(uint8_t mode);

  /**
   * @brief 使能或者禁止报警模式, 使能报警模式后, ALE引脚到达报警条件后会产生跳变, 禁止报警模式ALE引脚没有响应
   * @param mode
                ENABLE_ALERT           // 使能报警模式, ALE引脚到达报警条件后会产生跳变
                DISABLE_ALERT          // 禁止报警模式, 禁止报警模式ALE引脚没有响应
     @return state
                0x00 is set successfully
                0xFE is set parameter error
                0xFF is register lock is not allowed to be modified
   */
  uint8_t setAlertEnable(uint8_t mode);

  /**
   * @brief 获取报警模式状态, 得到时报警模式或者非报警模式
   * @return mode
                ENABLE_ALERT           // 报警模式
                DISABLE_ALERT          // 非报警模式
   */
  uint8_t getAlertEnableState(void);

  /**
   * @brief 解析浮点数, 用于设置上限下限临界值的浮点数部分
   * @return 二进制的浮点数
   */
  uint8_t parsingDecimal(float value);

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

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

  /**
   * @brief 解析阈值的整数部分, 放到指定位置
   * @param value 要放的阈值数据
   * @param data  要放到的地址
   */

接线图

样例代码1 - getTemperature

温度在串口显示,测量温度随环境温度改变而改变。

/*!
  * @file  getTemperature.ino
  * @brief 普通获取温度的例子
  * @n 实验现象:温度在串口显示,测量温度随环境温度改变而改变
  * @n i2c 地址选择,默认i2c地址为0x1F,A2、A1、A0引脚为高电平
  * @n 1代表高电平,0代表低电平,8种组合为
  *               | A2 | A1 | A0 |
  *               | 0  | 0  | 0  |    0x18
  *               | 0  | 0  | 1  |    0x19
  *               | 0  | 1  | 0  |    0x1A
  *               | 0  | 1  | 1  |    0x1B
  *               | 1  | 0  | 0  |    0x1D
  *               | 1  | 0  | 1  |    0x1D
  *               | 1  | 1  | 0  |    0x1E
  *               | 1  | 1  | 1  |    0x1F   default i2c address
  *
  * @copyright   Copyright (c) 2010 DFRobot Co.Ltd (https://www.dfrobot.com)
  * @licence     The MIT License (MIT)
  * @author      ZhixinLiu(zhixin.liu@dfrobot.com)
  * @version     V0.3
  * @date        2021-04-16
  * @get         from https://www.dfrobot.com
  * @url         https://www.dfrobot.com
  */
#include "DFRobot_MCP9808.h"

/**
  i2c 地址的选择
    I2C_ADDRESS
      I2C_ADDRESS_0   0x18
      I2C_ADDRESS_1   0x19
      I2C_ADDRESS_2   0x1a
      I2C_ADDRESS_3   0x1b
      I2C_ADDRESS_4   0x1c
      I2C_ADDRESS_5   0x1d
      I2C_ADDRESS_6   0x1e
      I2C_ADDRESS_7   0x1f   default i2c address
*/
#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!");

  /**
   * 唤醒传感器,此时可以正常获取传感器数据
   */
  if(!mcp9808.wakeUpMode()){
    Serial.println("Register locked, Please unlock!");
  }else{
    Serial.println("Wake up sensor successfully, can read the temperature!");
  }

  /**
    设置温度的分辨率
      RESOLUTION_0_5     // 获取温度的小数部分为0.5的倍数     如0.5℃ 、1.0℃、1.5℃
      RESOLUTION_0_25    // 获取温度的小数部分为0.25的倍数    如0.25℃、0.50℃、0.75℃
      RESOLUTION_0_125   // 获取温度的小数部分为0.125的倍数   如0.125℃、0.250℃、0.375℃
      RESOLUTION_0_0625  // 获取温度的小数部分为0.0625的倍数  如0.0625℃、0.1250℃、0.1875℃
  */
  if(mcp9808.setResolution(RESOLUTION_0_125)){
    Serial.println("设置温度的分辨率成功!");
  }else{
    Serial.println("parameter error!");
  }
}

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

结果

串口打印出获取到的温湿度数据

MCP9808结果1

样例代码2 - interruptMode

温度上限下限临界值触发中断的例子,将ALE引脚连接pin 2

/*!
  * @file  interruptMode.ino
  * @brief 温度上限下限临界值触发中断的例子,将ALE引脚连接如下
  * @n 实验现象:温度在串口显示,测量温度随环境温度改变而改变
  * @n 实验现象:中断io口在状态转换时产生,例如温度在上限和下限中间或者在一直低于下限或者一直高于上限,此时不会发生中断
  * @n 实验现象:当温度状态在低于下限的状态时改变,高于了下限此时产生了中断需要清除中断,
  * @n 实验现象:清除中断后,ALE引脚电平恢复,高于临界值时清除中断失效(ALE引脚电平不恢复)
  * @n i2c 地址选择,默认i2c地址为0x1F,A2、A1、A0引脚为高电平,
  * @n 其8中组合为,1代表高电平,0代表低电平
  *               | A2 | A1 | A0 |
  *               | 0  | 0  | 0  |    0x18
  *               | 0  | 0  | 1  |    0x19
  *               | 0  | 1  | 0  |    0x1A
  *               | 0  | 1  | 1  |    0x1B
  *               | 1  | 0  | 0  |    0x1D
  *               | 1  | 0  | 1  |    0x1D
  *               | 1  | 1  | 0  |    0x1E
  *               | 1  | 1  | 1  |    0x1F   default i2c address
  *
  * @copyright   Copyright (c) 2010 DFRobot Co.Ltd (https://www.dfrobot.com)
  * @licence     The MIT License (MIT)
  * @author      ZhixinLiu(zhixin.liu@dfrobot.com)
  * @version     V0.3
  * @date        2021-04-16
  * @get         from https://www.dfrobot.com
  * @url         https://www.dfrobot.com
  */
#include "DFRobot_MCP9808.h"

/**
  i2c 地址的选择
    I2C_ADDRESS
      I2C_ADDRESS_0   0x18
      I2C_ADDRESS_1   0x19
      I2C_ADDRESS_2   0x1a
      I2C_ADDRESS_3   0x1b
      I2C_ADDRESS_4   0x1c
      I2C_ADDRESS_5   0x1d
      I2C_ADDRESS_6   0x1e
      I2C_ADDRESS_7   0x1f   default i2c address
*/
#define I2C_ADDRESS  I2C_ADDRESS_7
DFRobot_MCP9808_I2C mcp9808(&Wire, I2C_ADDRESS);

volatile uint8_t interruptFlag = 0;
void myInterrupt(void)
{
  interruptFlag = 1;   // 中断标志
}

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

  /**
   * 唤醒传感器,此时可以正常获取传感器数据
   */
  if(!mcp9808.wakeUpMode()){
    Serial.println("Register locked, Please unlock!");
  }else{
    Serial.println("Wake up sensor successfully, can read the temperature!");
  }

  /**
    设置温度的分辨率
      RESOLUTION_0_5     // 获取温度的小数部分为0.5的倍数     如0.5℃ 、1.0℃、1.5℃
      RESOLUTION_0_25    // 获取温度的小数部分为0.25的倍数    如0.25℃、0.50℃、0.75℃
      RESOLUTION_0_125   // 获取温度的小数部分为0.125的倍数   如0.125℃、0.250℃、0.375℃
      RESOLUTION_0_0625  // 获取温度的小数部分为0.0625的倍数  如0.0625℃、0.1250℃、0.1875℃
  */
  if(mcp9808.setResolution(RESOLUTION_0_25)){
    Serial.println("设置温度的分辨率成功!");
  }else{
    Serial.println("parameter error!");
  }

  /**
    设置警报输出的模式, 比较器输出模式不需要清除中断, 中断模式需要清除中断
      COMPARATOR_OUTPUT_MODE           // 比较器输出模式不需要清除中断, 
        例如:设置ALE引脚为低电平活动,当超过上限警报的温度时, ALE引脚从高电平到低电平, 当温度低于上限但高于下限时, ALE引脚恢复高电平
      INTERRPUT_OUTPUT_MODE            // 中断输出模式需要清除中断, 当产生警报时, 如果不清除中断中断一直存在, 中断模式的触发, 是从一种状态变为另一种状态, 
        例如:设置了下限阈值20度, 上限阈值25度, 临界阈值30度, 当温度一直低于20度时不产生中断, 当温度超过25度时才产生中断, ALE引脚跳变, 此时应该清空中断, ALE引脚恢复,
        特殊情况, 当ALE引脚大于临界温度30度时, 中断模式失效, 清空中断也失效, 必须等温度降到30度以下, 才恢复中断模式
      DISABLE_OUTPUT_MODE              // 禁止输出模式后不产生警报,ALE引脚失效
  */
  if(mcp9808.setAlertOutputMode(INTERRPUT_OUTPUT_MODE) == 0){
    Serial.println("设置报警输出模式成功!");
  }else{
    Serial.println("Register locked or parameter error!");
  }

  /**
    设置ALE引脚的极性,引脚极性为高:ALE引脚高电平为活动电平,默认为低电平,产生报警后ALE为高电平
                       引脚极性为低:ALE引脚低极性为活动电平,默认为高电平,产生报警后ALE为低电平
      POLARITY_HIGH         // ALE引脚高电平为活动电平
      POLARITY_LOW          // ALE引脚低极性为活动电平
  */
  if(mcp9808.setPolarity(POLARITY_LOW) == 0){
    Serial.println("设置ALE引脚极性成功!");
  }else{
    Serial.println("Register locked or parameter error!");
  }

  /**
    设置响应模式,响应上限下限和临界值,或者只响应临界值,只响应临界值不适用于中断模式
      UPPER_LOWER_CRIT_RESPONSE         // 上限/下线和临界值 都响应
      ONLY_CRIT_RESPONSE                // 禁止上限下限响应,只有临界值响应
  */
  if(mcp9808.setAlertResponseMode(UPPER_LOWER_CRIT_RESPONSE) == 0){
    Serial.println("设置响应模式成功!");
  }else{
    Serial.println("Register locked or parameter error!");
  }

  /**
    设置临界值和上限和下限阈值,根据配置的中断模式响应, 高于上限温度和低于下限温度和高于临界值响应中断
      crit:   // 温度临界值, 最多两位小数, 自动处理成0.25的倍数, 范围为-40 到 +125度
      upper:  // 温度上限, 最多两位小数, 自动处理成0.25的倍数, 范围为-40 到 +125度
      lower:  // 温度下限, 最多两位小数, 自动处理成0.25的倍数, 范围为-40 到 +125度
   */
  if(mcp9808.setThreshold(35.0, 30.0, 20.0) == 0){
    Serial.println("设置临界值上限下限的温度成功!");
  }else{
    Serial.println("Register locked or data error");
  }

  /**
    设置报警温度滞后的范围,在上限下限和临界值的阈值上增加一个范围,滞后功能仅适用于降温(从热至冷),
    也就是说上限减去滞后温度,ALE电平才恢复
    例如:温度上限为30.0度,滞后温度为+1.5度,当前是35度ALE已经产生电平翻转,
         要想ALE恢复电平,必须达到30-1.5(28.5)度,ALE引脚才能恢复电平
      HYSTERESIS_0_0        // 没有滞后,就是到达指定温度就响应
      HYSTERESIS_1_5        // 从热至冷要滞后1.5℃
      HYSTERESIS_3_0        // 从热至冷要滞后3.0℃
      HYSTERESIS_6_0        // 从热至冷要滞后6.0℃
  */
  if(mcp9808.setAlertHysteresis(HYSTERESIS_1_5) == 0){
    Serial.println("设置温度滞后成功!");
  }else{
    Serial.println("Register locked or parameter error!");
  }

  /**
    设置锁定模式或解锁,防止错误操作更改上限、下限、临界值的大小
    锁定后只能通过断电复位解除锁定
      CRIT_LOCK       // 锁定临界值,临界值的阈值不允许被修改
      WIN_LOCK        // 锁定上限下限,上限下限的阈值不允许被修改
      CRIT_WIN_LOCK   // 锁定临界值和上限下限,上限下限和临界值的数据都不允许被修改
      NO_LOCK         // 不锁定上限下限和临界值
  */
  if(mcp9808.setLockState(NO_LOCK)){
    Serial.println("设置锁定模式成功!");
  }else{
    Serial.println("parameter error!");
  }

  mcp9808.clearInterrupt();       //第一次温度状态未知,所以清除中断
  #if defined(ESP32) || defined(ESP8266)||defined(ARDUINO_SAM_ZERO)
  /**
    根据设置ALE引脚极性选择
      INPUT_PULLUP    // 设置极性为低电平,设置2号引脚为上拉输入
      INPUT_PULLDOWN  // 设置极性为高电平,设置2号引脚为下拉输入
    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
  /*    The Correspondence Table of AVR Series Arduino Interrupt Pins And Terminal Numbers
   * ---------------------------------------------------------------------------------------
   * |                                        |    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);

  /**
    设置引脚为中断模式
    // Open the external interrupt 0, connect INT1/2 to the digital pin of the main control:
      function
        callback function
      state
        FALLING         // 当引脚由高电平到低电平后产生中断,进入interrupt函数
        RISING          // 当引脚由低电平到高电平后产生中断,进入interrupt函数
  */
  attachInterrupt(/*Interrupt No*/0, /*function*/myInterrupt, /*state*/FALLING);
  #endif
}
void loop()
{
  /**
    当ALE io口产生了中断,清除报警中断
    清空上限下限阈值温度所产生的中断,临界值中断不能清除
  */
  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);
}

结果

温度在串口显示,测量温度随环境温度改变而改变 中断io口在状态转换时产生,例如温度在上限和下限中间或者在一直低于下限或者一直高于上限,此时不会发生中断 当温度状态在低于下限的状态时改变,高于了下限此时产生了中断需要清除中断, 清除中断后,ALE引脚电平恢复,高于临界值时清除中断失效(ALE引脚电平不恢复)

MCP9808结果2

MCP9808结果2

样例代码3 - comparatorMode

获取当前温度和上限下限临界值比较的状态

 /*!
  * @file  comparatorMode.ino
  * @brief 获取当前温度和上限下限临界值比较的状态
  * @n 实验现象:温度和比较状态在串口显示
  * @n 实验现象:当温度大于上限温度时,ALE引脚电平会翻转,
  * @n 实验现象:当温度小于下限温度时,ALE引脚电平会翻转,
  * @n 实验现象:当温度大于临界温度时,ALE引脚电平会翻转,
  * @n i2c 地址选择,默认i2c地址为0x1F,A2、A1、A0引脚为高电平
  * @n 1代表高电平,0代表低电平,8种组合为
  *               | A2 | A1 | A0 |
  *               | 0  | 0  | 0  |    0x18
  *               | 0  | 0  | 1  |    0x19
  *               | 0  | 1  | 0  |    0x1A
  *               | 0  | 1  | 1  |    0x1B
  *               | 1  | 0  | 0  |    0x1D
  *               | 1  | 0  | 1  |    0x1D
  *               | 1  | 1  | 0  |    0x1E
  *               | 1  | 1  | 1  |    0x1F   default i2c address
  *
  * @copyright   Copyright (c) 2010 DFRobot Co.Ltd (https://www.dfrobot.com)
  * @licence     The MIT License (MIT)
  * @author      ZhixinLiu(zhixin.liu@dfrobot.com)
  * @version     V0.3
  * @date        2021-04-16
  * @get         from https://www.dfrobot.com
  * @url         https://www.dfrobot.com
  */
#include "DFRobot_MCP9808.h"

/**
  i2c 地址的选择
    I2C_ADDRESS
      I2C_ADDRESS_0   0x18
      I2C_ADDRESS_1   0x19
      I2C_ADDRESS_2   0x1a
      I2C_ADDRESS_3   0x1b
      I2C_ADDRESS_4   0x1c
      I2C_ADDRESS_5   0x1d
      I2C_ADDRESS_6   0x1e
      I2C_ADDRESS_7   0x1f   default i2c address
*/
#define I2C_ADDRESS  I2C_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!");

  /**
   * 唤醒传感器,此时可以正常获取传感器数据
   */
  if(!mcp9808.wakeUpMode()){
    Serial.println("Register locked, Please unlock!");
  }else{
    Serial.println("Wake up sensor successfully, can read the temperature!");
  }

  /**
    设置温度的分辨率
      RESOLUTION_0_5     // 获取温度的小数部分为0.5的倍数     如0.5℃ 、1.0℃、1.5℃
      RESOLUTION_0_25    // 获取温度的小数部分为0.25的倍数    如0.25℃、0.50℃、0.75℃
      RESOLUTION_0_125   // 获取温度的小数部分为0.125的倍数   如0.125℃、0.250℃、0.375℃
      RESOLUTION_0_0625  // 获取温度的小数部分为0.0625的倍数  如0.0625℃、0.1250℃、0.1875℃
  */
  if(mcp9808.setResolution(RESOLUTION_0_25)){
    Serial.println("设置温度的分辨率成功!");
  }else{
    Serial.println("parameter error!");
  }

  /**
    设置警报输出的模式, 比较器输出模式不需要清除中断, 中断模式需要清除中断
      COMPARATOR_OUTPUT_MODE           // 比较器输出模式不需要清除中断, 
        例如:设置ALE引脚为低电平活动,当超过上限警报的温度时, ALE引脚从高电平到低电平, 当温度低于上限但高于下限时, ALE引脚恢复高电平
      INTERRPUT_OUTPUT_MODE            // 中断输出模式需要清除中断, 当产生警报时, 如果不清除中断中断一直存在, 中断模式的触发, 是从一种状态变为另一种状态, 
        例如:设置了下限阈值20度, 上限阈值25度, 临界阈值30度, 当温度一直低于20度时不产生中断, 当温度超过25度时才产生中断, ALE引脚跳变, 此时应该清空中断, ALE引脚恢复,
        特殊情况, 当ALE引脚大于临界温度30度时, 中断模式失效, 清空中断也失效, 必须等温度降到30度以下, 才恢复中断模式
      DISABLE_OUTPUT_MODE              // 禁止输出模式后不产生警报,ALE引脚失效
  */
  if(mcp9808.setAlertOutputMode(COMPARATOR_OUTPUT_MODE) == 0){
    Serial.println("设置报警输出模式成功!");
  }else{
    Serial.println("Register locked or parameter error!");
  }

  /**
    设置ALE引脚的极性,引脚极性为高:ALE引脚高电平为活动电平,默认为低电平,产生报警后ALE为高电平
                       引脚极性为低:ALE引脚低极性为活动电平,默认为高电平,产生报警后ALE为低电平
      POLARITY_HIGH         // ALE引脚高电平为活动电平
      POLARITY_LOW          // ALE引脚低极性为活动电平
  */
  if(mcp9808.setPolarity(POLARITY_LOW) == 0){
    Serial.println("设置ALE引脚极性成功!");
  }else{
    Serial.println("Register locked or parameter error!");
  }

  /**
    设置响应模式,响应上限下限和临界值,或者只响应临界值,只响应临界值不适用于中断模式
      UPPER_LOWER_CRIT_RESPONSE         // 上限/下线和临界值 都响应
      ONLY_CRIT_RESPONSE                // 禁止上限下限响应,只有临界值响应
  */
  if(mcp9808.setAlertResponseMode(UPPER_LOWER_CRIT_RESPONSE) == 0){
    Serial.println("设置响应模式成功!");
  }else{
    Serial.println("Register locked or parameter error!");
  }

  /**
    设置临界值和上限和下限阈值,根据配置的中断模式响应, 高于上限温度和低于下限温度和高于临界值响应中断
      crit:   // 温度临界值, 最多两位小数, 自动处理成0.25的倍数, 范围为-40 到 +125度
      upper:  // 温度上限, 最多两位小数, 自动处理成0.25的倍数, 范围为-40 到 +125度
      lower:  // 温度下限, 最多两位小数, 自动处理成0.25的倍数, 范围为-40 到 +125度
   */
  if(mcp9808.setThreshold(35.0, 30.0, 20.0) == 0){
    Serial.println("设置临界值上限下限的温度成功!");
  }else{
    Serial.println("Register locked or data error");
  }

  /**
    设置报警温度滞后的范围,在上限下限和临界值的阈值上增加一个范围,滞后功能仅适用于降温(从热至冷),
    也就是说上限减去滞后温度,ALE电平才恢复
    例如:温度上限为30.0度,滞后温度为+1.5度,当前是35度ALE已经产生电平翻转,
         要想ALE恢复电平,必须达到30-1.5(28.5)度,ALE引脚才能恢复电平
      HYSTERESIS_0_0        // 没有滞后,就是到达指定温度就响应
      HYSTERESIS_1_5        // 从热至冷要滞后1.5℃
      HYSTERESIS_3_0        // 从热至冷要滞后3.0℃
      HYSTERESIS_6_0        // 从热至冷要滞后6.0℃
  */
  if(mcp9808.setAlertHysteresis(HYSTERESIS_1_5) == 0){
    Serial.println("设置温度滞后成功!");
  }else{
    Serial.println("Register locked or parameter error!");
  }

  /**
    设置锁定模式或解锁,防止错误操作更改上限、下限、临界值的大小
    锁定后只能通过断电复位解除锁定
      CRIT_LOCK       // 锁定临界值,临界值的阈值不允许被修改
      WIN_LOCK        // 锁定上限下限,上限下限的阈值不允许被修改
      CRIT_WIN_LOCK   // 锁定临界值和上限下限,上限下限和临界值的数据都不允许被修改
      NO_LOCK         // 不锁定上限下限和临界值
  */
  if(mcp9808.setLockState(NO_LOCK)){
    Serial.println("设置锁定模式成功!");
  }else{
    Serial.println("parameter error!");
  }
}

void loop()
{
  /**
    获取当前比较器的状态和温度数据, 只有在比较器模式下有效
    存放当前数据的结构体
      temperate        // 当前温度
      state            // 比较器状态的字符串,比较当前温度和上限阈值,下限阈,和临界值的关系
   */
  struct comparatorData data = mcp9808.getComparatorState();
  Serial.print("temperature = "); Serial.print(data.temperature); Serial.println(" C");
  Serial.print("state is "); Serial.println(data.state);
  delay(1000);
}

结果

温度和比较状态在串口显示 当温度大于上限温度时,ALE引脚电平会翻转, 当温度小于下限温度时,ALE引脚电平会翻转, 当温度大于临界温度时,ALE引脚电平会翻转,

MCP9808结果3

MCP9808结果3

常见问题

还没有客户对此产品有任何问题,欢迎通过qq或者论坛联系我们!

更多问题及有趣的应用,可以 访问论坛 进行查阅或发帖。

更多

DFshopping_car1.png DFRobot商城购买链接