AHT10传感器使用记录-esp8266

AHT10传感器使用记录-esp8266

把踩了的坑记录下来,以后忘了还能回头看看权当成功后的记录吧


part1 AHT10是什么

AHT10是一款温湿度传感器,使用IIC通信协议,参考手册可以在 奥松官网中找到


part2 为什么选择AHT10

因为假期在家也回不去学校,为了能够做一些能做的工作我买了esp8266的开发板,单有板子没有执行器和传感器也不成啊,那就整一个传感器玩呗,顺便熟悉一下协议也为后期工作做点 预热
家在北方,选择传感器也是有做智能家居的考量,量程要在 -40°C~40°C 以内,这款传感器刚好能用


part3 阅读手册的那点事

传感器手册下载好,先看工作电压

在这里插入图片描述

电压为3.3V,开发板刚好也是3.3V电压输出

  • 接线
aht10esp8266
vin3V3
GNDGND
SCLSCL(D1)
SDASDA(D2)
  • 开发板上的丝印有错误,需要注意接线顺序。可以通过获取开发板原理图来查看,可以向店家索要。

连接线参考

原理图

这里可以看到硬件的介绍。

  • 环境搭建

  1. 使用arduino的ide进行程序烧录,代码编写使用vscode。参考
  2. vscode安装插件arduino(Microsoft) C/C++ ESP8266FS
  3. 修改配置文件,arduino设置 settings.json文件中arduino的安装位置。
"arduino.path": "C:\\Arduino"

在view-command palette…中选择编辑 C++ edit configurations(JSON).编辑c_cpp_properties.json 的includePdath属性修改 <用户名> 改成你的计算机名字

{
    "configurations": [
        {
            "name": "Win32",
            "includePath": [
                "C:\\Users\\<用户名>\\AppData\\Local\\Arduino15\\packages\\esp8266\\tools\\**",
                "C:\\Users\\<用户名>\\AppData\\Local\\Arduino15\\packages\\esp8266\\hardware\\esp8266\\2.6.3\\**",
                "C:\\Arduino\\tools\\**",
                "C:\\Arduino\\hardware\\arduino\\avr\\**",
                "{$workspaceFolder}/libraries",
                "C:/Arduino/hardware/tools/avr/lib/gcc/avr/5.4.0/include",
                "C:/Arduino/hardware/arduino/avr/cores/arduino",
                "C:/Arduino/hardware/arduino/avr/variants/standard",
                "C:/Arduino"
            ],
            "defines": [
                "_DEBUG",
                "UNICODE",
                "_UNICODE"
            ],
            "compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.24.28314/bin/Hostx64/x64/cl.exe",
            "cStandard": "c11",
            "cppStandard": "c++17",
            "intelliSenseMode": "${default}",
            "forcedInclude": []
        }
    ],
    "version": 4
}

之后就可以在vscode中写代码,使用 arduino ide 编译和上传。也可以使用快捷键 Ctrl+ Alt+R进行编译
使用Ctrl+ Alt+U进行上传。

代码部分

#include <Wire.h>
uint8_t adress = 0x38; //设备地址 默认7位2进制数
float T; 

float RH; 

int data[6]; 

void setup()
{

    Wire.begin();
    Serial.begin(9600);

}

void loop()
{

    AHT10_measure();
    delay(2000);

}

void AHT10_measure()
{

    Wire.beginTransmission(0x38);

    Wire.requestFrom(0x38, 6);

    while (Wire.available())
    {
        for (int i = 0; i < 6; i++)
        {
            data[i] = Wire.read();
            // Serial.println(data[i]);
        }

        if (data[0] & 0x08 == 0)
        {
            // Serial.println("进行初始化");
            // Serial.println(Wire.read());
            Wire.write(0xE1);
            Wire.write(0x08);
            Wire.write(0x00);
        }
        else
        {
            Serial.println("不需要初始化");
            // Serial.println(Wire.read());
            Wire.write(0xAC);
            Wire.write(0x33);
            Wire.write(0x00);
            delayMicroseconds(75);


            if (data[0] & 0x80 == 0)
            {
                Serial.println("需要等待完成");
                // Serial.println(Wire.read());
            }
            else
            {
                Serial.println("不需要等待");
                // Serial.println(Wire.read());
            }
        }
    }
    Wire.endTransmission();
    RH = ((data[1] << 12) | (data[2] << 4)) | (data[3] >> 4);
    T = ((data[3] & 0x0f) << 16) | (data[4] << 8) | data[5];
    RH = (RH / pow(2, 20)) * 100;
    T = (T / pow(2, 20)) * 200 - 50;
    Serial.print("湿度为");
    Serial.println(RH);
    Serial.print("温度为");
    Serial.println(T);

}

值得注意的地方是:每次传输开始既要要求6字节的数据,根据手册所述,取得的第一字节内容为状态字,对状态字进行判断决定后边的5个字节的数据是否是有效的。

    Wire.beginTransmission(0x38);

    Wire.requestFrom(0x38, 6);
    while (Wire.available())
       {     for (int i = 0; i < 6; i++)
        {
            data[i] = Wire.read();
            // Serial.println(data[i]);
        }
       }

后续就是发送测量命令后再次获取6字节计算后边5字节的数据湿度数据由第2、3个字节和第4字节前四位,温度数据由第4字节后四位、第5、6字节组成。温湿度都是20位数据根据手册进行计算:

    RH = ((data[1] << 12) | (data[2] << 4)) | (data[3] >> 4);
    T = ((data[3] & 0x0f) << 16) | (data[4] << 8) | data[5];
    RH = (RH / pow(2, 20)) * 100;
    T = (T / pow(2, 20)) * 200 - 50;

这里RH为湿度,T为温度。官网给出的示例程序中计算算式有问题。

/*******************************************/
/*@版权所有:广州奥松电子有限公司          */
/*@作者:温湿度传感器事业部                */
/*@版本:V1.2                              */
/*******************************************/
/*******************************************/
/*@版本说明:                              */
/*@版本号:V1.2 修改AC命令的参数。         */
/*@版本号:V1.1 增加校准输出使能检测。     */
/*@版本号:V1.0 最初版本。                 */
/*******************************************/



void Delay_N10us(uint32_t t)//延时函数
{
  uint32_t k;

   while(t--)
  {
    for (k = 0; k < 2; k++)//110
      ;
  }
}



void SensorDelay_us(uint32_t t)//延时函数
{
	t = t-2;	
	for(; t>0; t--)
	{
		Delay_N10us(1);
	}

}

void Delay_3us(void)		//延时函数
{	
	Delay_N10us(1);
	Delay_N10us(1);
	Delay_N10us(1);
	Delay_N10us(1);
}
void Delay_1us(void)		//延时函数
{	
	Delay_N10us(1);
	Delay_N10us(1);
	Delay_N10us(1);
	Delay_N10us(1);
	Delay_N10us(1);

}


void SDA_Pin_Output_High(void)   //将P15配置为输出 , 并设置为高电平, P15作为I2C的SDA
{

 Gpio_InitIOExt(1,5,GpioDirOut,TRUE, FALSE, TRUE, FALSE);//config P15 to output
 Gpio_SetIO(1,5,1); 
}

void SDA_Pin_Output_Low(void)  //将P15配置为输出  并设置为低电平
{
 Gpio_InitIOExt(1,5,GpioDirOut,TRUE, FALSE, TRUE, FALSE);//config P15 to output
 Gpio_SetIO(1,5,0);  
}

void SDA_Pin_IN_FLOATING(void)  //SDA配置为悬浮输入
{
 Gpio_InitIO(1, 5, GpioDirIn);
}



void SCL_Pin_Output_High(void) //SCL输出高电平,P14作为I2C的SCL
{
 Gpio_SetIO(1, 4, 1);
}

void SCL_Pin_Output_Low(void) //SCL输出低电平
{
 Gpio_SetIO(1, 4, 0);
}

void Init_I2C_Sensor_Port(void) //初始化I2C接口
{	

 Gpio_InitIOExt(1,5,GpioDirOut,TRUE, FALSE, TRUE, FALSE);//将P15配置为开漏输出  并设置为高电平
 Gpio_SetIO(1,5,1);
	

 Gpio_InitIOExt(1,4,GpioDirOut,TRUE, FALSE, TRUE, FALSE);//将P14配置为开漏输出  并设置为高电平
 Gpio_SetIO(1,4,1);
	
}


void I2C_Start(void)		 //I2C主机发送START信号
{
 SDA_Pin_Output_High();
 SensorDelay_us(8);
 SCL_Pin_Output_High();
 SensorDelay_us(8);
 SDA_Pin_Output_Low();
 SensorDelay_us(8);
 SCL_Pin_Output_Low();
 SensorDelay_us(8);   
}


void ZSSC_I2C_WR_Byte(uint8_t Byte) //往AHT10写一个字节
{
	uint8_t Data,N,i;	
	Data=Byte;
	i = 0x80;
	for(N=0;N<8;N++)
	{
		SCL_Pin_Output_Low();
	  
		Delay_3us();	
		
		if(i&Data)
		{
			SDA_Pin_Output_High();
		}
		else
		{
			SDA_Pin_Output_Low();
		}	
			
        SCL_Pin_Output_High();
		Delay_3us();
		
		Data <<= 1;
		 
	}
	SCL_Pin_Output_Low();
	SensorDelay_us(8);   
	SDA_Pin_IN_FLOATING();
	SensorDelay_us(8);	
}	


uint8_t ZSSC_I2C_RD_Byte(void)//从AHT10读取一个字节
{
	uint8_t Byte,i,a;
	Byte = 0;
	SCL_Pin_Output_Low();
	SDA_Pin_IN_FLOATING();
	SensorDelay_us(8);	
	for(i=0;i<8;i++)
	{
    SCL_Pin_Output_High();		
		Delay_1us();
		a=0;
		if(Gpio_GetIO(1,5))a=1;
		Byte = (Byte<<1)|a;
		SCL_Pin_Output_Low();
		Delay_1us();
	}
    SDA_Pin_IN_FLOATING();
	SensorDelay_us(8);	
	return Byte;
}


uint8_t Receive_ACK(void)   //看AHT10是否有回复ACK
{
	uint16_t CNT;
	CNT = 0;
	SCL_Pin_Output_Low();	
	SDA_Pin_IN_FLOATING();
	SensorDelay_us(8);	
	SCL_Pin_Output_High();	
	SensorDelay_us(8);	
	while((Gpio_GetIO(1,5))  && CNT < 100) 
	CNT++;
	if(CNT == 100)
	{
		return 0;
	}
 	SCL_Pin_Output_Low();	
	SensorDelay_us(8);	
	return 1;
}

void Send_ACK(void)		  //主机回复ACK信号
{
	SCL_Pin_Output_Low();	
	SensorDelay_us(8);	
	SDA_Pin_Output_Low();
	SensorDelay_us(8);	
	SCL_Pin_Output_High();	
	SensorDelay_us(8);
	SCL_Pin_Output_Low();	
	SensorDelay_us(8);
	SDA_Pin_IN_FLOATING();
	SensorDelay_us(8);
}

void Send_NOT_ACK(void)	//主机不回复ACK
{
	SCL_Pin_Output_Low();	
	SensorDelay_us(8);
	SDA_Pin_Output_High();
	SensorDelay_us(8);
	SCL_Pin_Output_High();	
	SensorDelay_us(8);		
	SCL_Pin_Output_Low();	
	SensorDelay_us(8);
    SDA_Pin_Output_Low();
	SensorDelay_us(8);
}

void Stop_I2C(void)	  //一条协议结束
{
	SDA_Pin_Output_Low();
	SensorDelay_us(8);
	SCL_Pin_Output_High();	
	SensorDelay_us(8);
	SDA_Pin_Output_High();
	SensorDelay_us(8);
}

uint8_t JH_Read_Status(void)//读取AHT10的状态寄存器
{

	uint8_t Byte_first;	
	I2C_Start();
	ZSSC_I2C_WR_Byte(0x71);
	Receive_ACK();
	Byte_first = ZSSC_I2C_RD_Byte();
		

	Send_NOT_ACK();
	Stop_I2C();


	return Byte_first;
}

uint8_t JH_Read_Cal_Enable(void)  //查询cal enable位有没有使能?
{
	uint8_t val = 0;//ret = 0,
 
  val = JH_Read_Status();
  if((val & 0x68)==0x08)  //判断NOR模式和校准输出是否有效
  return 1;
  else  return 0;
 }



void JH_SendAC(void) //向AHT10发送AC命令
{

 I2C_Start();
 ZSSC_I2C_WR_Byte(0x70);
 Receive_ACK();
 ZSSC_I2C_WR_Byte(0xac);
 Receive_ACK();
 ZSSC_I2C_WR_Byte(0x33);
 Receive_ACK();
 ZSSC_I2C_WR_Byte(0x00);
 Receive_ACK();
 Stop_I2C();

}

void JH_Send_BA(void)//向AHT10发送BA命令
{


 I2C_Start();
 ZSSC_I2C_WR_Byte(0x70);
 Receive_ACK();
 ZSSC_I2C_WR_Byte(0xba);
 Receive_ACK();
 Stop_I2C();


}

void JH_Read_CTdata(uint32_t *ct) //读取AHT10的温度和湿度数据
{
	volatile uint8_t  Byte_1th=0;
	volatile uint8_t  Byte_2th=0;
	volatile uint8_t  Byte_3th=0;
	volatile uint8_t  Byte_4th=0;
	volatile uint8_t  Byte_5th=0;
	volatile uint8_t  Byte_6th=0;
	 uint32_t RetuData = 0;
	
	uint16_t cnt = 0;


	JH_SendAC();//向AHT10发送AC命令

	delay_ms(75);//等待75ms
    cnt = 0;
	while(((JH_Read_Status()&0x80)==0x80))//等待忙状态结束
	{
	 SensorDelay_us(1508);
	 if(cnt++>=100)
	 {
	  break;
	  }
	}
	I2C_Start();

	ZSSC_I2C_WR_Byte(0x71);//0x70+1   0x70为设备地址 1为方向位
	Receive_ACK();
	Byte_1th = ZSSC_I2C_RD_Byte();//状态字
	Send_ACK();
	Byte_2th = ZSSC_I2C_RD_Byte();//湿度字节
	Send_ACK();
	Byte_3th = ZSSC_I2C_RD_Byte();//湿度字节
	Send_ACK();
	Byte_4th = ZSSC_I2C_RD_Byte();//高4位为湿度  低4位为温度
	Send_ACK();
	Byte_5th = ZSSC_I2C_RD_Byte();//温度字节
	Send_ACK();
	Byte_6th = ZSSC_I2C_RD_Byte();//温度字节
	Send_NOT_ACK();
	Stop_I2C();

	RetuData = (RetuData|Byte_2th)<<8;
	RetuData = (RetuData|Byte_3th)<<8;
	RetuData = (RetuData|Byte_4th);
	RetuData =RetuData >>4;
	ct[0] = RetuData;
	RetuData = 0;
	RetuData = (RetuData|Byte_4th)<<8;
	RetuData = (RetuData|Byte_5th)<<8;
	RetuData = (RetuData|Byte_6th);
	RetuData = RetuData&0xfffff;
	ct[1] =RetuData; 

}


u8 JH_Init(void)   //初始化AHT10
{

	
	Init_I2C_Sensor_Port();
	SensorDelay_us(11038);

	I2C_Start();
	ZSSC_I2C_WR_Byte(0x70); //进入写状态
	Receive_ACK();
	ZSSC_I2C_WR_Byte(0xe1);//写系统配置寄存器
	Receive_ACK();
	ZSSC_I2C_WR_Byte(0x08);
	Receive_ACK();
	ZSSC_I2C_WR_Byte(0x00);
	Receive_ACK();
	Stop_I2C();

	delay_ms(500);//延时0.5S
   while(JH_Read_Cal_Enable()==0)//需要等待状态字status的Bit[3]=1时才去读数据。如果Bit[3]不等于1 ,发软件复位0xBA给AHT10,再重新初始化AHT10,直至Bit[3]=1
   {
    
	JH_Send_BA();  //复位
	delay_ms(100);
	SensorDelay_us(11038);

	I2C_Start();
	ZSSC_I2C_WR_Byte(0x70);
	Receive_ACK();
	ZSSC_I2C_WR_Byte(0xe1);//写系统配置寄存器
	Receive_ACK();
	ZSSC_I2C_WR_Byte(0x08);
	Receive_ACK();
	ZSSC_I2C_WR_Byte(0x00);
	Receive_ACK();
	Stop_I2C();
	count++;
	if(count>=10)return 0;
	delay_ms(500);
    }
   return 1;
}

int32_t main(void)
{
 uint32_t CT_data[2];
	volatile int  c1,t1;
	u8 ret=0;
	ret = JH_Init(); //初始化
	if(ret == 0)
	{
	 LCD_display("ERROR"):
	 while(1);
	 }
	
	while(1)
	{
	 while(JH_Read_Cal_Enable()==0)//等到校准输出使能位为1,才读取。
	 {
	  JH_Init();//如果为0再使能一次
      delay_ms(30);
	 }
	 //DisableIrq(); //由于是模拟I2C,为读取数据更准确 ,读取之前禁止中断
	 JH_Read_CTdata(CT_data);  //读取温度和湿度 , 可间隔1.5S读一次
	 c1 = CT_data[0]*1000/1024/1024;  //计算得到湿度值(放大了10倍,如果c1=523,表示现在湿度为52.3%)
	 t1 = CT_data[1] *200*10/1024/1024-500;//计算得到温度值(放大了10倍,如果t1=245,表示现在温度为24.5℃)
	 //EnableIrq(); //恢复中断
	 delay_ms(1500); //延时1.5S
	 
	 //为读取的数据更稳定,还可以使用平均值滤波或者窗口滤波,或者前面读取的值与后面的值相差不能太大。
	 }
	

 }	

t1计算式和手册不一致应该以手册为准。

  • 9
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
### 回答1: AHT10是一种温湿度传感器,可以通过MQTT协议进行数据传输。 AHT10温湿度传感器是一种数字式的环境传感器,可以测量周围环境的温度和湿度。它通过I2C总线与微控制器进行通信,提供高精度的温湿度数据。有了AHT10,我们可以实时监测室内外的温湿度变化,用于自动化控制、气象观测、智能家居等领域。 MQTT是一种轻量级的发布订阅消息传输协议,它适用于物联网设备之间的通信。MQTT协议使用发布者(Publisher)和订阅者(Subscriber)之间的发布/订阅模式,实现设备间的即时通信,具有低带宽和低功耗的特点。通过使用MQTT协议,我们可以将AHT10传感器采集到的温湿度数据发送到云平台或其他设备上,实现大规模分布式的温湿度数据监测和分析。 在使用AHT10时,我们可以将其与MQTT协议结合使用,将传感器获得的温湿度数据通过MQTT消息传输到目标设备。首先,我们需要将AHT10与微控制器连接,并编写相应的代码,用于读取传感器数据并通过MQTT协议进行发布。然后,我们需要配置MQTT服务器的连接参数,包括服务器地址、端口号、用户名密码等信息。最后,我们可以通过发布订阅模式,将AHT10传感器的数据发布到指定的主题(topic)上,订阅者可以通过订阅相应的主题来接收传感器数据。 总之,AHT10与MQTT协议的结合可以实现温湿度数据的采集、传输和监测,为我们提供及时准确的环境信息,为智能化应用和决策提供了重要的基础数据。 ### 回答2: AHT10是一种温湿度传感器,而MQTT是一种消息传输协议。 AHT10是一种数字温湿度传感器,具有高精度和快速响应的特点。它可以测量环境中的温度和湿度,并将数据以数字信号的形式输出。与传统的模拟传感器相比,AHT10具有更好的稳定性和准确性。 MQTT是一种轻量级的消息传输协议,被广泛应用于物联网(IoT)领域。它基于发布-订阅模式,支持低带宽、高延迟和不稳定网络环境下的消息传输。MQTT使用消息代理(broker)作为中介,实现设备之间的通信和数据的传输。 将AHT10和MQTT结合起来,可以实现温湿度数据的实时监测和传输。AHT10传感器可以测量环境中的温度和湿度,并将数据发送给连接到同一MQTT代理的设备。该设备可以订阅AHT10传感器的数据,并对数据进行处理、存储或进一步传输。通过使用MQTT协议,温湿度数据可以实时传输到云平台,以便进行远程监控和数据分析。 总结来说,AHT10和MQTT共同构成了温湿度监测与数据传输的解决方案。AHT10传感器负责实时采集环境温湿度数据,而MQTT协议则用于数据的传输和通信。这种组合在物联网和工业自动化等领域具有重要的应用价值。 ### 回答3: AHT10是一款数字式湿度和温度传感器,具有高精度和低功耗的特点。它采用了微电子机械系统(MEMS)技术,内置了ADC和温度补偿电路,能够提供准确的湿度和温度测量结果。 MQTT是一种轻量级的消息传递协议,它被广泛应用于物联网领域。通过MQTT协议,设备可以相互通信和传递消息,实现实时监控、数据交换以及远程控制等功能。MQTT协议的特点是简单、灵活、可靠,并且具有较低的带宽和存储开销。 AHT10与MQTT可以结合使用,通过AHT10传感器获取温度和湿度数据,并将数据通过MQTT协议传输到后台服务器或其他设备。这样,我们可以实现对温度和湿度的远程监控和数据分析,以便进行环境控制和决策制定。 需要注意的是,使用AHT10和MQTT时,我们需要进行相关的硬件和软件开发。首先,需要将AHT10传感器与微控制器或物联网设备连接,通过编程读取传感器数据。然后,通过MQTT客户端库将数据打包成MQTT消息,发送到指定的MQTT代理或服务器。接收方可以订阅相关主题,实时获取传感器数据并进行处理。 总之,AHT10和MQTT的结合可以实现对湿度和温度的远程监控和数据传输,为物联网应用提供了强大的支持。这种技术的应用范围广泛,可以适用于农业、工业、家居等各个领域。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值