简介
DS18B20、LM35是否已经不能满足您对测温的需求?为什么不试试MCP9808高精度数字温度传感器。
MCP9808 数字温度传感器可检测-40°C和+125°C之间的温度,提供±0.25°C/±0.5°C(典型值 / 最大值)高级精度的数据检测,以及最高+0.0625℃的用户可选择数据精度。
MCP9808具有用户可编程寄存器,可以实现关断或低功耗模式,以及温度报警窗口限制的规范和临界输出限制。
当温度变化超出规定的边界限制时,MCP9808会输出报警信号。用户可以设置比较器输出或温度报警中断输出。
这些特性使MCP9808成为精密的多区域温度监控应用的理想选择。
应用场景
- 工业冰柜和冰箱
- 食品加工
- 个人计算机和服务器
- PC外设
- 消费类电子产品
- 笔记本/便携设备
技术规格
- 工作电压:2.7~5.5V
- 工作电流:200μA典型值
- 精度:
- 40°C 至 +125°C 时为 ±0.25°C (典型值)
- -20°C 至 100°C 时为 ±0.5°C (最大值)
- -40°C 至 +125°C 时为 ±1°C (最大值)
- 用户可选测量分辨率: +0.5°C、 +0.25°C、 +0.125°C 和 +0.0625°C
- 用户可编程温度报警: 温度阈值报警、临界温度报警
- 通信接口:I2C(2.54mm Breakout)
- 外形尺寸:18.5*23mm
- 安装孔尺寸:2mm
- 安装孔间距:18mm
引脚说明
名称 | 功能描述 |
---|---|
VCC | 电源正极 |
GND | 电源负极 |
SCL | 时钟线 |
SDA | 数据线 |
ALT | 报警 |
A0 | IIC地址配置引脚 |
A1 | IIC地址配置引脚 |
A2 | IIC地址配置引脚 |
使用教程
准备
- 硬件
- 1 x Arduino UNO控制板
- 1 x MCP9808 高精度数字温度传感器
- 若干 杜邦线
- 软件
- Arduino IDE, 点击下载Arduino IDE
- MCP9808库文件和示例程序
关于如何安装库文件,点击链接
- 主要API接口函数列表
/**
* @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);
}
结果
串口打印出获取到的温湿度数据
样例代码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引脚电平不恢复)
样例代码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引脚电平会翻转,
常见问题
还没有客户对此产品有任何问题,欢迎通过qq或者论坛联系我们!
更多问题及有趣的应用,可以 访问论坛 进行查阅或发帖。