本产品是采用高稳定性电容式感湿元件作为传感元件,经过微处理器采集处理转化成数字信号输出。每一个传感器都经过标定校准和测试。具有长期稳定、可靠性高、 精度高、低功耗等特点。
单位:mm(±0.5)
三、产品特点
DHT22数字温湿度模块具有以下特点:
1、数字输出,IIC协议;
2、超低功耗;
3、0-100%相对湿度测量范围;
4、全标定、温漂校准。
5、使用独立感湿元器件,稳定性好,抗污染能力强
相对湿度
参数 | 条件 | 最小 | 典型 | 最大 | 单位 |
分辨率 | 0.1 | %RH | |||
量程范围 | 0 | 99.9 | %RH | ||
精度 | 25℃ | ±3 | %RH | ||
重复性 | ±0.1 | ||||
响应时间 | 1/e(63%) | <8 | S | ||
迟滞 | ±0.5 | ||||
漂移 | 典型值 | < 3 | %RH/r |
温度
参数 | 条件 | 最小 | 典型 | 最大 | 单位 |
分辨率 | 0.1 | ℃ | |||
工作范围 | -40 | 80 | ℃ | ||
精度 | ±0.5 | ℃ | |||
重复性 | ±0.2 | ℃ | |||
响应时间 | 1/e(63%) | 1 | S | ||
迟滞 | ±0.1 | ||||
漂移 | 典型值 | < 0.2 | ℃/r |
参数 | 条件 | 最小 | 典型 | 最大 | 单位 |
供电电压VDD | 2.8 | 3.3 | 5.5 | V | |
供电电流 | 休眠模式 | 0.2 | uA | ||
测量模式 | 500 | uA | |||
采样周期 | 2.0 | S | |||
低电平输出电压 | Io<4mA | 0 | 250 | mV | |
高电平输出电压 | Rp<25kΩ | 80% | 100% | VDD | |
低电平输入电压 | 下降沿 | 0% | 20% | VDD | |
高电平输入电压 | 上升沿 | 80% | 100% | VDD | |
输出电流 | On | 4 | mA | ||
三态门(Off) | 10 | 20 | μA |
表3 Io表示低电平输出电流 Rp代表上拉电阻
引脚 | 名称 | 描述 |
1 | VDD | 电源 2.8~5.5V |
2 | SDA | 串行数据,双向口 |
3 | GND | 地 |
4 | SCK | 时钟线 |
表4 引脚分配
本产品的供电电压为2.8~5.5V,建议供电电压为3.3V。
SDA为数据口,三态结构,SDA在SCK时钟下降沿之后改变状态,并仅在SCK上升沿有效
SCK 用于微处理器与 DHT22之间的通讯同步。注意频率范围。
DHT22为了精确测量气体的湿度,减少温度对测量的影响,DHT22传感器在非工作期间,自动转为休眠模式,以降低传感器自身的发热对周围气体湿度的影响。DHT22采用被动式工作模式,即主机通过指令唤醒传感器后,传感器才开始测量、应答等动作。通讯结束后,传感器进入休眠状态。
注:上拉电阻一般建议采用10KΩ电阻,传感器与主机传输距离超过10米,建议用5.1KΩ
电气特性,如功耗、输入和输出的高、低电平电压等,依赖于电源供电电压。表3详细解释了DHT22的电气特性。若想与传感器获得最佳的通讯效果,请设计时严格遵照表4与图5的条件。
参数 | 最小 | 典型 | 最大 | 单位 | |
FSCK | SCK频率 | 100 | KHZ | ||
TSCKx | SCK高/低时间 | 5 | us | ||
TR/TF | SCK升/降时间 | 1 | us | ||
TFO | SDA下降时间 | 800 | ns | ||
TRO | SDA上升时间 | 1000 | ns | ||
TV | SDA有效时间 | 400 | ns | ||
TSU | SDA设定时间 | 350 | ns | ||
THO | SDA保持时间 | 100 | ns |
DHT22采用标准的I2C协议进行通讯。因此关于I2C的更多细节该手册将不做赘述。欲获取下述章节以外的关于I2C协议的资料,请自行参阅。
首先,选择合适的电源,上电速率不能低于1V/ms。
每个传输系列都以Start状态作为开始并以Stop状态作为结束
图5 启动传输状态(S)-当SCK为高电平时,SDA由高电平转换为低电平。开始状态是由于主机控制的一种特殊的总线状态,指示从机传输开始。
图6 停止传输状态(P)-当SCK为高电平时,SDA由低电平转换为高电平。停止状态是由于主机控制的一种特殊的总线状态,指示从机传输结束。
2.6、发送命令
在启动传输后,随后传输的I2C首字节包括7位的I2C设备地址(当前只支持44H)和一个SDA方向位(读R:‘1’,写W:‘0’)。在第8个SCL时钟下降沿之后,通过拉低SDA信号线(ACK位),指示传感器数据通信正常。
传感器地址 | 44H |
触发温湿度测量 | 2C10H |
触发温度测量 | CC44H F3H |
触发湿度测量 | CC66H F5H |
DHT22读取温湿度时序图如下:白色由微控制器控制,传感器响应为灰色块
读取步骤如下:
(1)、复位传感器、初始化。
指令 | 十六进制编码 |
软复位 | 0x30A2 |
|
(2)、获取湿度运算系数与系统配置(可不读取)
指令 | 十六进制编码 |
读取HumA高8位 | 0xD208 |
读取HumA低8位 | 0xD209 |
读取HumB高8位 | 0xD20A |
读取HumB低8位 | 0xD20B |
读取配置字Cfg(可不读取) | 0xD206 |
|
(3)、触发测量温湿度
测温、测湿单独模式
通过发送测量命令CC44H或CC66H触发一次湿度或温度数据的采集。在传输期间,每个数据值始终跟随CRC检验和。下表中显示了16位命令。重复性(低,中和高 默认为高)和时钟延展(启用或禁止 默认是禁止)可以通过修改配置寄存器实现。重复性影响测量持续时间,从而会影响传感器的总功耗
指令 | 十六进制编码 |
测量温度 | 0xCC44 |
测量湿度 | 0xCC66 |
|
同时测量模式
指令 | 十六进制编码 |
测量温度和湿度 | 0x2C10 |
|
温度、相对湿度转换
通过上面两种方式可以获得16bit温度原始数据St、16bit湿度原始数据Sh
最终带入下面公式
温度(℃):
湿度(%RH):
RHrel = RH + 0.25*(T - 25.0) (注: 温漂1℃为 -0.25%RH)
注: RH限定在0~100, if(RH>100) RH=100;
Else if(RH<0) RH=0;
(4)修改配置寄存器
Cfg | Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0 |
0x02 | Reserved | Reserved | clk_strench | Mps2 | Mps1 | Mps0 | Repeatbility1 | Repeatbility1 |
描述 | 保留 | IIC接口时钟拉伸使能: 0:不允许拉伸 1:允许拉伸 | 每秒测量次数选择: 000:单次 | 重复性设置: 00:低可重复性 01:中等可重复性 10:高可重复性 |
指令 | 十六进制编码 |
修改配置字Cfg | 0x5206 |
|
(5)循环冗余校验(CRC)计算
在每个数据字之后发送的 8 位 CRC 校验和由 CRC 算法生成。其属性显示在下表中。
属性 | 数值 |
名称 | CRC-8 |
位宽 | 8位 |
保护数据 | 读/写 |
多项式 | 0x31(X8+X5+X4+1) |
初始数据 | 0xFF |
待测数据的每个字节是否按位反转 | 否 |
确保传感器性能正常稳定的工作,建议使用温度范围-40℃-80℃,湿度范围0-99.9%RH。超出建议的范围可能导致测量结果暂时性漂移。
湿度传感器为环境敏感型电子元器件,需要仔细防护。长期暴露在高浓度的化学蒸汽中将会致使传感器的测量产生漂移。因此建议将传感器存放于原包装内,并符合存储条件:温度范围10℃-50℃;湿度范围20-60%RH。在生产和运输过程中,要保证传感器远离高浓度的化学溶剂。要避免使用挥发性胶水、粘性胶带、不干胶贴纸,或者具有挥发性的包装材料,如发泡塑料袋、泡沫塑料。
相对湿度,很大程度上依赖于温度。产品在出厂前都做了温度的校准补偿,测量湿度时,应尽可能的保证传感器在同一温度下工作,安装在产品上时要尽可能的远离热源。否则将无法准确的测试到气体的相对湿度。
以上内容由本公司提供,版权所有,未经本公司之书面许可,此手册中任何段落,章节内容均不得被摘抄、拷贝或以任何形式复制、传播,否则一切后果由违者自负,本公司保留一切法律权利。
本公司保留对手册所描述之产品规格进行修改的权利,恕不另行通知。订货前,请垂询当地代理商以获悉本产品的最新规格。
使用及人身伤害
勿将本产品用于安全保护装置或急停设备上,以及由于本产品故障可能导致人身受到伤害的任何应用中;在使用本产品前,请仔细阅读本说明书中的内容;
禁止在易燃气体附近使用
禁止在易燃、易爆气体的场所使用;
严禁直接触及传感器
为防止污染感湿膜,避免手指直接触摸元件表面;汗液会污染感湿膜会导致性能漂移,接触传感器请戴防静电手指套;
工作环境
建议使用温度范围-40℃-80℃,湿度范围0-100%RH。超出建议的范围可能导致测量结果暂时性漂移;本产品对光线不敏感,但长时间暴露在太阳光或则紫外线辐射中,同样加速老化。
附件1
#define V4_I2C_ADDR 0x44 /* Addr 引脚接低电平*/
//获取湿度校准参数
static u16 HumA,HumB;
void DHT22Init(void)
{
ResetMD();
delay(10); //10us或者不用
HumA = Read_Rg(8);
HumA = (HumA<<8)|Read_Rg(9);
HumB = Read_Rg(10);
HumB = (HumB<<8)|Read_Rg(11);
}
//单次触发温湿度测量
u8 ReadDHT22(s16 *tem,u16 *Hum)
{
static u8 initFlag=0;
u8 i,errRe,ReadDatSH[6],CalCRC[3],errorflag;
s16 TemBuf;
long CapBuf;//s32
start();
write_byte(V4_I2C_ADDR<<1);// Add+W
delay(1);
respons();
write_byte(0x2c);//单字节读取寄存器 指令D2xx
respons();
write_byte(0x10);
respons();
stop();
delay(465);//2ms SCL空闲最小1ms
for(i=0;i<50;i++)//查询5次看测完结果
{
delay(230);//1ms
delay(230);
delay(230);
start();
write_byte(V4_I2C_ADDR<<1|0x01);// Add+R
errRe=respons();
if(errRe ==0)
break;//测量完成
else
stop();
}
if(errRe == 0)
{
ReadDatSH[0] = read_byte();
SendACK(ACK);
ReadDatSH[1] = read_byte();
SendACK(ACK);
ReadDatSH[2] = read_byte();
SendACK(ACK);
ReadDatSH[3] = read_byte();
SendACK(ACK);
ReadDatSH[4] = read_byte();
SendACK(ACK);
ReadDatSH[5] = read_byte();
SendACK(NACK);
stop();
}
CalCRC[0] = ReadDatSH[0];
CalCRC[1] = ReadDatSH[1];
CalCRC[2] = ReadDatSH[2];
errorflag = SHT3x_CheckCrc(CalCRC,2);
if(errorflag==0)
{
TemBuf = (u16)ReadDatSH[0]<<8|(ReadDatSH[1]);
TemBuf = 400+TemBuf/25.6;//*10 结果*10倍 286即28.6℃
*tem = TemBuf;
}
CalCRC[0] = ReadDatSH[3];
CalCRC[1] = ReadDatSH[4];
CalCRC[2] = ReadDatSH[5];
errorflag |= SHT3x_CheckCrc(CalCRC,2);
if(errorflag==0)
{
CapBuf = (u16)ReadDatSH[3]<<8|(ReadDatSH[4]);
CapBuf = (CapBuf-HumB)*600/(HumA-HumB)+300;
//20℃为5个湿度点 即1℃为0.25个湿度点 0.1℃ 为0.025
CapBuf = CapBuf+ 25*(TemBuf-250)/100;
if(CapBuf>1000)
CapBuf = 999;
else if(CapBuf<0)
CapBuf = 0;
*Hum = (u16)CapBuf;//同样结果*10
}
return errorflag;
}
//子函数-----------------------------
#define ACK 0
#define NACK 1
static u8 ACK_ret;
void start(void){
HDCSDA_SET();
delay(10); //IIC 时钟频率可以 0~100KHz
HDCSCL_SET();
delay(10);
HDCSDA_CLR();
delay(10);
HDCSCL_CLR();
}
void stop(void){
HDCSDA_CLR();
delay(10);
HDCSCL_SET();
delay(10);
HDCSDA_SET();
delay(10);
}
u8 respons(void)
{
u8 i=0,error=0;//写完后紧跟着WaitACK,所有可以改变SDA
HDCSDA_Input();
delay(10);
HDCSCL_SET();
delay(10);
ACK_ret = 0;
while(((HDCGet_SDA())!=0)&&i<50)i++;
if(i>45)
{
error = 1;
ACK_ret = 1;
}
HDCSCL_CLR();//SCK:0可以改变SDA
delay(10);
HDCSDA_Output();
return error;
}
void SendACK(u8 ack)
{
if(ack == 0)
{
HDCSDA_CLR();
}
else
{
HDCSDA_SET();
}
delay(10);
HDCSCL_SET();
delay(10);
HDCSCL_CLR();
delay(10);
HDCSDA_SET();
}
void write_byte(u8 date){
u8 i,temp;
temp=date;
for(i=0;i<8;i++)
{
HDCSCL_CLR();
// delay(10);
if((temp&0x80)==0x80)
{HDCSDA_SET();}else{HDCSDA_CLR();}
delay(10);
HDCSCL_SET();
delay(10);
temp=temp<<1;
}
HDCSCL_CLR();
delay(10);
// HDCSDA_SET();
// delay(10);
}
u8 read_byte(void){
u8 i,k;
HDCSDA_SET();//让P口准备读数
HDCSDA_Input();
for(i=0;i<8;i++)
{
HDCSCL_SET();
delay(10);
k <<= 1;
if(HDCGet_SDA())//==0x04
k |= 0x01;
HDCSCL_CLR();//SCK:0可以改变SDA
delay(10);
}
HDCSDA_Output();//
return k;
}
const u16 POLYNOMIAL = 0x131; //P(x)=x^8+x^5+x^4+1 = 100110001
//==============================================================================
u8 SHT3x_CheckCrc(u8 data[], u8 nbrOfBytes) //跟SHT30一样只是将CRC值到会到data后返回
//==============================================================================
{
u8 crc = 0xff; //0
u8 byteCtr,bit;
//calculates 8-Bit checksum with given polynomial
for (byteCtr = 0; byteCtr < nbrOfBytes; ++byteCtr)
{ crc ^= (data[byteCtr]);
for (bit = 8; bit > 0; --bit)
{ if (crc & 0x80) crc = (crc << 1) ^ POLYNOMIAL;
else crc = (crc << 1);
}
}
if (crc != data[nbrOfBytes])
{
data[nbrOfBytes] = crc;
return 0x01;
}
else return 0;
}
//软复位
void ResetMD(void)
{
start();
write_byte(V4_I2C_ADDR<<1);// Add+W
delay(1);
respons();
write_byte(0x30);
respons();
write_byte(0xA2);
respons();
stop();
}
//读取寄存器数据
u16 Read_Rg(u8 AddRg)
{
u8 errRe,ReadDatSH[3];
u16 ReDat;
start();
write_byte(V4_I2C_ADDR<<1);// Add+W
delay(1);
respons();
write_byte(0xD2);//单字节读取寄存器 指令D2xx
respons();
write_byte(AddRg);
respons();
delay(10);
start();
write_byte(V4_I2C_ADDR<<1|0x01);// Add+R
errRe=respons();
//if(ACK_ret == 0)
//{
ReadDatSH[0] = read_byte();
SendACK(ACK);
ReadDatSH[1] = read_byte();
SendACK(ACK);
ReadDatSH[2] = read_byte();
SendACK(NACK);
//}
stop();
errRe = SHT3x_CheckCrc(ReadDatSH,2);
if(errRe==0)
{
ReDat = ReadDatSH[0];
}else
{
ReDat = 0xff;
}
return ReDat;
}