【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】

这篇具有很好参考价值的文章主要介绍了【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 哔哩哔哩视频效果链接:http://【毕业设计——STM32温湿度采集系统】 https://www.bilibili.com/video/BV1Hy421i7sk/?share_source=copy_web&vd_source=d711fa8bef565aeec8a4d279df8b85aa ~~大家可以给个关注,记得一键三连哦~~

一、项目描述:

设计是一种基于STM32的无线温湿度检测系统以智能化、自动化、高效化为出发点,充分利用物联网技术手段,实现温湿度检测系统,实现数据的采集、处理和反馈。首先STM32单片机通过温湿度传感器采集环境温湿度数据,并将数据显示在OLED显示屏上。其次STM32单片机对采集到的数据进行处理,包括计算、数据校验、异常检测等操作;接着将处理后的数据通过WIFI通信模块发送到数据上传到Things Cloud云平台,并在Things Cloud云平台和手机APP会记录采集好的数据显示出来;之后通过手机APP对接收到的数据进行分析处理,以判断环境温湿度是否异常;最后当环境温湿度异常时,STM32报警模块就发出报警及LED灯就会亮,Things Cloud云平台和手机App会记录采集好的数据并显示异常警告提醒用户和方便用户及时采取相应的措施以进一步改善温湿度环境,使室内温湿度环境更加的舒适性和稳定性。

二、项目功能模块:

主要技术:STM32开发、UART、DHT11传感器、OLED、WIFI通信和MQTT协议。

主要元器件:STM32F103、ESP8266、DHT11、舵机等。

编程软件:Keil5、ESPlorer。

平台:Things Cloud云平台

三、模块原理:

DHT11:

 DHT11 时序 采用单总线双向串行通信协议,每次采集都要由单片机发起开始信号,然后 DHT11 会向单片机发送响应并开始传输 40 位数据帧,高位在前。数据格式为: 8bit 湿度整数数据+8bit 湿度小数数据+8bit 温度整数数据+8bit 温度小数数据 +8bit 校验位,温湿度小数部分默认为 0,即单片机采集的数据都是整数,校验位 为 4 个字节的数据相加取结果的低 8 位数据作为校验和:

【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】,stm32,嵌入式硬件,单片机,c语言,lua

具体时序图如下:

【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】,stm32,嵌入式硬件,单片机,c语言,lua

主机或者单片机需要发送一个开始信号给 DHT11 传感器:主机先将 IO 设置为输 出,然后主机拉低总线(时间需要大于 18ms)后设置为输入并释放数据总线,等 待从机(DHT11)响应,主机开始的信号时序为:

【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】,stm32,嵌入式硬件,单片机,c语言,lua

如果传感器正常且存在,则会在收到主机的开始信号后拉低总线并持续 80us 来通 知主机此时传感器正常,然后拉高总线 80us,通知主机准备接收,响应的时序为:

【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】,stm32,嵌入式硬件,单片机,c语言,lua

如果传感器正常且存在,则会在收到主机的开始信号后拉低总线并持续 80us 来通 知主机此时传感器正常,然后拉高总线 80us,通知主机准备接收,响应的时序为:

【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】,stm32,嵌入式硬件,单片机,c语言,lua

接着传感器开始按照高位在前的顺序将数据按照如下的格式,一位一位的输出给主 机:

【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】,stm32,嵌入式硬件,单片机,c语言,lua

程序要区分数据 0 和数据 1 的格式:先判断此时引脚的电平状态,如果是低电平 就一直循环等待,直到高电平出现,高电平出现后延时 40us,并读取延时后的电 平状态,如果此时是高电平,则数据为 1,否则为 0。 传输完 40 位数据后,传感器再次输出一个 50us 的低电平后,将数据总线释放, 采集过程结束。

SG90 伺服电机基本原理:

SG90 是一种常见的微型伺服电机,广泛用于远程控制汽车、船只、直升机以及机 器人等领域。图示如下:

【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】,stm32,嵌入式硬件,单片机,c语言,lua

sg90 舵机是分为两种的,一种是转角范围 180°的舵机,另外一种是 360°转角 的舵机。 180°舵机是给一个 PWM 信号就转动到一定的角度,然后保持在这个转动之后的 位置,直到有下一个不同的 PWM 信号,才会转到其他的角度。 360°舵机是给一个 PWM 信号,就会按照一定的速度转动。 我们使用的是 360°舵机,电平持续时间与转速关系如下:

【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】,stm32,嵌入式硬件,单片机,c语言,lua

即周期 20ms 时,占空比在 2.5%-7.5%时为正转,2.5%时为正转最大速度,占空 比在 7.5%-12.5%时为反转,12.5%时为反转最大速度。

1.接线方式如下:

【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】,stm32,嵌入式硬件,单片机,c语言,lua

ESP8266:

该模块提供对 GPIO(通用输入/输出)子系统的访问。

所有访问均基于 NodeMCU 开发套件上的 I/O 索引号,而不是内部 GPIO 引脚。 例如,开发套件上的 D0 引脚映射到内部 GPIO 引脚 16。

如果不使用 NodeMCU 开发套件,请参阅下面的 GPIO 引脚映射以获取索引↔gpio 映射。

【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】,stm32,嵌入式硬件,单片机,c语言,lua

引脚对应关系如下:

【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】,stm32,嵌入式硬件,单片机,c语言,lua

I2C原理:

概述:

I2C(Inter-Integrated Circuit)通信是一种由 Philips 公司开发的串行通信协议,主 要用于近距离、低速的芯片间通信。它只需要两条双向的信号线,一条数据线 SDA(用于收发数据)和一条时钟线 SCL(用于通信双方时钟的同步)。I2C 通信 是半双工通信,意味着数据在一条数据线上传输,且同一时刻只能单向传输,要么 从主机到从机,要么从从机到主机。每个数据包的大小为 8 位,采用高位在前、 低位在后的传输顺序。 I2C 通信中,主机通过时钟线 SCL 发送时钟信号,并通过数据线 SDA 发送数据 (如从机地址、指令、数据包等)。在发送完一帧数据后,主机需等待从机的响应 才能继续发送下一帧数据。I2C 总线的操作时序包括写单个存储字节、写多个存储 字节、读单个存储字节和读多个存储字节等不同模式。 I2C 总线支持多主机模式,即可以有多个主机设备在总线上发起通信。在多主机系 统中,仲裁过程是必要的,以避免冲突。当两个主机同时发送数据时,谁先发送高 电平的将会输掉仲裁,即仲裁失败的主机将不再产生时钟脉冲,并需等待总线空闲 时才能重新传输。 I2C 通信中,每个从机都有一个唯一的 7 位或 10 位地址,用于区分不同的从机设 备。I2C 的标准传输速率有多种模式,包括标准模式(100 kbit/s)、快速模式 (400 kbit/s)、快速+模式(1 Mbit/s)等,适用于不同的应用场景。

特征:

【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】,stm32,嵌入式硬件,单片机,c语言,lua

  1. IIC总线组成:由数据线SDA和时钟线SCL构成的串行总线,并且连接上拉电阻保证总线在空闲状态下,为高电平状态。
  2. 在总线上可以同时运行多个主控器和外围器件设备,使用唯一地址信息标识设备进行通信。
  3. 通信速率:标准模式100kbit/s,快速模式400kbit/s,高速模式3.4Mbit;

总线时序图:

【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】,stm32,嵌入式硬件,单片机,c语言,lua

在整个IIC通信过程中,包含3个特殊信号

  1. 起始信号:START

在时钟线SCL保持高电平期间,数据线SDA上的电平被拉低(即负跳变),定义为I2C总线总线的启动信号,它标志着一次数据传输的开始。启动信号是一种电平跳变时序信号,而不是一个电平信号。启动信号是由主控器主动建立的,在建立该信号之前I2C总线必须处于空闲状态。

  1. 结束信号:STOP

在时钟线SCL保持高电平期间,数据线SDA被释放,使得SDA返回高电平(即正跳变),称为I2C总线的停止信号,它标志着一次数据传输的终止。停止信号也是一种电平跳变时序信号,而不是一个电平信号,停止信号也是由主控器主动建立的,建立该信号之后,I2C总线将返回空闲状态。

  1. 应答信号:ACK

I2C总线上的所有数据都是以8位字节传送的,发送器每发送一个字节,就在时钟脉冲9期间释放数据线,由接收器反馈一个应答信号。

1) 应答信号为低电平时,规定为有效应答位(ACK简称应答位),表示接收器已经成功地接收了该字节;

2) 应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功.

应答信号:对于主设备和从设备都可以使用

在整个通信过程中,需要保证数据的有效性:

在进行数据位读写的时候,只有保证SCL为高电平的时候,数据位才有效。

四、软件功能配置:

ESP8266配置:

使用 ESPlorer 测试 1、下载并安装 lua 编程及调试工具 ESPlorer 官网链接:ESPlorer – esp8266配套软件文件夹有免安装版本。 请自行配置好电脑的运行环境。 2、启动 ESPlorer ,设定串口通讯的波特率为 9600。 

下载好ESPlorer点击下面链接下载好固件

NodeMcu官方文档:NodeMCU Documentation

在线固件库构建NodeMCU custom builds (nodemcu-build.com)

【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】,stm32,嵌入式硬件,单片机,c语言,lua

【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】,stm32,嵌入式硬件,单片机,c语言,lua

打开ESPLorer,连接ESP8266,等待刷入新系统后,第一次系统载入。

【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】,stm32,嵌入式硬件,单片机,c语言,lua

云平台配置:

【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】,stm32,嵌入式硬件,单片机,c语言,lua

【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】,stm32,嵌入式硬件,单片机,c语言,lua

【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】,stm32,嵌入式硬件,单片机,c语言,lua

【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】,stm32,嵌入式硬件,单片机,c语言,lua

【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】,stm32,嵌入式硬件,单片机,c语言,lua

【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】,stm32,嵌入式硬件,单片机,c语言,lua

【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】,stm32,嵌入式硬件,单片机,c语言,lua

【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】,stm32,嵌入式硬件,单片机,c语言,lua

【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】,stm32,嵌入式硬件,单片机,c语言,lua

MQTT连接有三要素:

1:连接地址

2:用户名

3:密码

五、功能代码:

main.c文件:

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
		HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
		SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
		MX_GPIO_Init();
		MX_I2C1_Init();
		MX_ADC3_Init();
		MX_USART1_UART_Init();
		MX_TIM3_Init();
		MX_TIM1_Init();
		MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
		OLED_Init();
	  OLED_ShowCN(20,1,0);
		OLED_ShowCN(40,1,1);
		OLED_ShowCN(60,1,2);
		OLED_ShowCN(20,3,3);
		OLED_ShowCN(40,3,4);
		OLED_ShowCN(60,3,5);
		OLED_ShowCN(20,5,6);
		OLED_ShowCN(40,5,7);
		OLED_ShowCN(60,5,8);
		OLED_ShowCN(90,1,9);
		OLED_ShowStr(95,3,"%",2);
		OLED_ShowStr(95,5,"J",2);
	
	
		HAL_UART_Receive_IT(&huart2, (uint8_t *)rxBuffer, rxDataLen);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */

  while (1)
  {
		sConfig.Channel = ADC_CHANNEL_6; // 设置为通道 6
		sConfig.Rank = ADC_REGULAR_RANK_1;
		sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5; // 设置适合该通道的采样时间
		HAL_ADC_ConfigChannel(&hadc3, &sConfig); // 重新配置 ADC
// 开始 ADC 转换
		HAL_ADC_Start(&hadc3);
// 等待转换完成
		if (HAL_ADC_PollForConversion(&hadc3, 100) == HAL_OK)
		{
// 读取 ADC 值
		uint32_t light_sensor_data = HAL_ADC_GetValue(&hadc3);
// 将 ADC 值转换为 0-100 范围
		int light_sensor_percentage = (int)((light_sensor_data * 100) / 4095);
// 格式化并发送数据
		sprintf(msg, "L:%d%J", light_sensor_percentage);
		HAL_UART_Transmit(&huart1, (uint8_t *)msg, strlen(msg), 1000);
		int L= light_sensor_percentage/10;
		int L1= light_sensor_percentage%10;
	 OLED_ShowStr1(70,5,&L,1,2);
	 OLED_ShowStr1(80,5,&L1,1,2);
		}
// 停止 ADC 转换
		HAL_ADC_Stop(&hadc3);
//HAL_Delay(2000); // 稍微延迟,以便区分两个测量
/* 测量热敏电阻 */
//sConfig.Channel = ADC_CHANNEL_4; // 设置为通道 4
//sConfig.Rank = ADC_REGULAR_RANK_1;
//sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5; // 可以根据需要调整
//HAL_ADC_ConfigChannel(&hadc3, &sConfig); // 重新配置 ADC
// 开始 ADC 转换
//HAL_ADC_Start(&hadc3);
// 等待转换完成
//if (HAL_ADC_PollForConversion(&hadc3, 100) == HAL_OK)
//{
// 读取 ADC 值
//uint32_t thermistor_data = HAL_ADC_GetValue(&hadc3);
// 将 ADC 值转换为 0-100 范围
//int thermistor_percentage = (int)((thermistor_data * 100) / 4095);
// 格式化并发送数据
//sprintf(msg, "温度 = %d%℃\r\n", thermistor_percentage);
//HAL_UART_Transmit(&huart1, (uint8_t *)msg, strlen(msg), 1000);
	if(DHT_reade())
	{
//组包,并准备发送
	uint8_t len=snprintf((char
	*)message,sizeof(message),"T:%d,H:%d%%",Data[2],Data[0]);
//通过串口发送
	HAL_UART_Transmit(&huart1,message,(uint8_t)len,1000);
	int T=Data[2]/10;
	int T1=Data[2]%10;
	int H=Data[0]/10;
	int H1=Data[0]%10;
	OLED_ShowStr1(70,1,&T,1,2);
	OLED_ShowStr1(80,1,&T1,1,2);
	OLED_ShowStr1(70,3,&H,1,2);
	OLED_ShowStr1(80,3,&H1,1,2);


	}
   else
	{
	const char*error_msg="DHT11 fail\r\n";
	HAL_UART_Transmit(&huart1,(uint8_t
	*)error_msg,strlen(error_msg),1000); 
		
	}
if (Data[2] > thread)
	{
	HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_0);
	HAL_Delay(10);
	HAL_GPIO_WritePin(GPIOE, GPIO_PIN_5, GPIO_PIN_RESET); // 低电平亮
	HAL_Delay(500);
	HAL_GPIO_WritePin(GPIOE, GPIO_PIN_5, GPIO_PIN_SET); // 高电平熄灭
	HAL_Delay(500);
	//HAL_TIM_PWM_Start_IT(&htim3,TIM_CHANNEL_3);

	}
else
	{
 
	HAL_GPIO_WritePin(GPIOE, GPIO_PIN_5, GPIO_PIN_SET); // 高电平熄灭
	HAL_Delay(500);
 // HAL_TIM_PWM_Stop_IT(&htim3,TIM_CHANNEL_3);
		}	
 HAL_Delay(2000);
	}
	//HAL_Delay(2000);
	}
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  
  /* USER CODE END 3 */


/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
  PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	/*脴庐脵鸥脦禄脪陋脰戮脣鈥∶樎泵炩?溍嬧?⒚暵絓n,脮沤脵鸥脦禄脪陋脢露脣鈥∶樎泵炩?溍嬧?⒚暵絓r*/
	if(huart->Instance == USART2) 
	{
		if((USART_RX_STA & 0x8000) == 0)
		{
			if(USART_RX_STA & 0x4000)
			{
				if(rxData != 0x0a) 
				{
					USART_RX_STA = 0; 
				}
				else 
				{
					USART_RX_STA |= 0x8000;
				}
			}
			else 
			{
				if(rxData == 0x0d)
				{
					USART_RX_STA |= 0x4000;
				}
				else 
				{
					USART_RX_BUF[USART_RX_STA & 0X3FFF] = rxData;
					USART_RX_STA++;
					if(USART_RX_STA > (USART_REC_LEN - 1)) USART_RX_STA = 0;
				}
			}
		}
		if (USART_RX_STA & 0x8000)
		{
			if (strncmp((char *)USART_RX_BUF, "true", strlen("true")) == 0)
			{
				//HAL_GPIO_WritePin(GPIOE, GPIO_PIN_5, GPIO_PIN_RESET);
				//HAL_Delay(500);
				HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);
				htim3.Instance->CCR3 = 499;
			}
			else if (strncmp((char *)USART_RX_BUF, "false", strlen("false")) == 0)
			{
				//HAL_GPIO_WritePin(GPIOE, GPIO_PIN_5, GPIO_PIN_SET);
				HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_3);
			}
			HAL_UART_Transmit(&huart2, (uint8_t*)USART_RX_BUF, USART_RX_STA & 0X3FFF, 1000); // 1000ms 
			USART_RX_STA = 0;
			char rxBuffer[rxDataLen]="";
		}
		HAL_UART_Receive_IT(huart, &rxData, 1);
	}
}
/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

DHT11.c文件:

#include "dht11.h"
  uint8_t Data[5]={0x00,0x00,0x00,0x00,0x00};
//将 GPIO 调节为输入模式
void SET_PIN_INPUT(void) 
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
//将 GPIO 调节为输出模式
void SET_PIN_OUTPUT(void) 
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
//微秒级延时函数(向下)
void Delay_us(uint16_t us)
{
uint16_t dif=10000;
uint16_t us_con=10000-us;
__HAL_TIM_SET_COUNTER(&htim1,10000);//设置计数值为 10000
HAL_TIM_Base_Start(&htim1);//启动定时器
while(dif>us_con)
{
dif=__HAL_TIM_GET_COUNTER(&htim1);//获取定时器的计数值
}
HAL_TIM_Base_Stop(&htim1);//停止定时器
}
//电平读取函数
uint8_t DHT_read_byte(void)
{
uint8_t read_byte=0;//存放 8bit 的高低电平数据
uint8_t temp;//存放读取到的高低电平
uint8_t res=0;
uint8_t i;
for(i=0;i<8;i++)
{
//等待高电平到来
while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_5)==0&&res<100)
{
Delay_us(1); //1US 读取一次
res++; //防止卡死
}
res=0;
Delay_us(40);
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_5)==1)
{
temp=1;
}
else temp=0;
//等待低电平到来,开启下一次读取或读取结束
while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_5)==1&&res<100)
{
Delay_us(1); //1US 读取一次
res++; //防止卡死
}
res=0;
read_byte<<=1;//左移一位,空出末尾
read_byte |= temp;
}
return read_byte;
}
//DHT11 读取温湿度程序
uint8_t DHT_reade(void)
{
uint8_t res=0;
uint8_t i;
//首先发送 18ms 低电平
SET_PIN_OUTPUT();
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);
HAL_Delay(18);
//拉高 20us 高电平等待
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET);
Delay_us(20);
//32 向 DHT11 发送请求完成,之后等待接收消息
//IO 变为输入模式
SET_PIN_INPUT();
Delay_us(20);
//开始检测
//如果检测到低电平,说明 DHT11 有响应
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_5)==0)
{
while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_5)==0&&res<100)
{
Delay_us(1); //1US 读取一次
res++; //防止卡死
}
res=0;
while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_5)==1&&res<100)
{
Delay_us(1); //1US 读取一次
res++; //防止卡死
}
res=0; 
//反转电平过后,DHT11 开始传输数据
for(i=0;i<5;i++)
{
Data[i]=DHT_read_byte();
}
Delay_us(50); 
}
//校验
uint32_t sum=Data[0]+Data[1]+Data[2]+Data[3];
if((sum)==Data[4])
{
return 1;
}
else return 0;
}

I2C.c文件:

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    i2c.c
  * @brief   This file provides code for the configuration
  *          of the I2C instances.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "i2c.h"

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

I2C_HandleTypeDef hi2c1;

/* I2C1 init function */
void MX_I2C1_Init(void)
{

  /* USER CODE BEGIN I2C1_Init 0 */

  /* USER CODE END I2C1_Init 0 */

  /* USER CODE BEGIN I2C1_Init 1 */

  /* USER CODE END I2C1_Init 1 */
  hi2c1.Instance = I2C1;
  hi2c1.Init.ClockSpeed = 100000;
  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN I2C1_Init 2 */

  /* USER CODE END I2C1_Init 2 */

}

void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(i2cHandle->Instance==I2C1)
  {
  /* USER CODE BEGIN I2C1_MspInit 0 */

  /* USER CODE END I2C1_MspInit 0 */

    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**I2C1 GPIO Configuration
    PB6     ------> I2C1_SCL
    PB7     ------> I2C1_SDA
    */
    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* I2C1 clock enable */
    __HAL_RCC_I2C1_CLK_ENABLE();
  /* USER CODE BEGIN I2C1_MspInit 1 */

  /* USER CODE END I2C1_MspInit 1 */
  }
}

void HAL_I2C_MspDeInit(I2C_HandleTypeDef* i2cHandle)
{

  if(i2cHandle->Instance==I2C1)
  {
  /* USER CODE BEGIN I2C1_MspDeInit 0 */

  /* USER CODE END I2C1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_I2C1_CLK_DISABLE();

    /**I2C1 GPIO Configuration
    PB6     ------> I2C1_SCL
    PB7     ------> I2C1_SDA
    */
    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6);

    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_7);

  /* USER CODE BEGIN I2C1_MspDeInit 1 */

  /* USER CODE END I2C1_MspDeInit 1 */
  }
}

/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

xm.lua文件:

gpio.mode(4,gpio.OUTPUT,gpio.PULLUP)
local mytimer = tmr.create()   
wifi.setmode(wifi.STATION)
station_cfg={}   
station_cfg.ssid="HY"  
station_cfg.pwd="20252050"    
station_cfg.auto=false    
wifi.sta.config(station_cfg) 
wifi.sta.connect()


payload="{\"temperature\": 26,\"light\": 2000,\"switch\": true}" 
m= mqtt.Client("1234567",120,"4m3fazf8zygrj176","09XgoObvkj")
m:on("message",function(client,topic,message)
    print("主题是"..topic.."消息是"..message)
     t = sjson.decode(message)
   if t.command == true then
        gpio.write(4,gpio.LOW)
        print(t.command)
        
   else if t.command == false then
        gpio.write(4,gpio.HIGH)
         print(t.command)
   end
   end
end)

function value ()
        s = softuart.setup(9600,4,5)
        s:on("data",15,function(data)
        print(data)
        local input = data
        local pos1 = string.find(input, "L:")
        local result1 = string.sub(input, pos1 + 2, pos1 + 4)
        print(result1)

        
        local pos2= string.find(input, "T:")
        local result2 = string.sub(input, pos2 + 2, pos2 + 3)
        print(result2)

         
        local pos3 = string.find(input, "H:")
        local result3= string.sub(input, pos3 + 2, pos3 + 4)
        print(result3)
       ok, payload = pcall(sjson.encode, {Light=result1,Temperature=result2,Humidty=result3})
      if ok then
         print(payload)
            else
              print("failed to encode!")
            end
             m:publish("attributes",payload,0,0,
        function(client)         
            print("发布成功"..payload)          
        end)
         --tmr.delay(2000000)
 end ) 

      
end

function  MY_MQTT ()
        
         m:connect("sh-1-mqtt.iot-api.com",1883,
         function (client)                   
         print("已连接")
         value()   
        m:subscribe("attributes/push",0,
        function(client)
            print("订阅成功"..payload)
        end)      
       
    end)
    
end
        


mytimer:register(1000,tmr.ALARM_AUTO,
function()
    if wifi.sta.getip() == nil then
    print("正在连接")
    else
        print("连接成功 IP是"..wifi.sta.getip())
        mytimer:stop()
         MY_MQTT ()
    end
end)

mytimer:start()

六、成果展示:

手机app:

【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】,stm32,嵌入式硬件,单片机,c语言,lua

【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】,stm32,嵌入式硬件,单片机,c语言,lua

云平台:

【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】,stm32,嵌入式硬件,单片机,c语言,lua

【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】,stm32,嵌入式硬件,单片机,c语言,lua

整体效果:

【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】,stm32,嵌入式硬件,单片机,c语言,lua文章来源地址https://www.toymoban.com/news/detail-844895.html

到了这里,关于【STM32HAL库(智能家居)+DHT11传感器+ESP8266+Things Cloud云平台+手机APP】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【雕爷学编程】Arduino智能家居之使用Arduino Uno和DHT22传感器发送温度和湿度数据到ThingSpeak

    Arduino是一个开放源码的电子原型平台,它可以让你用简单的硬件和软件来创建各种互动的项目。Arduino的核心是一个微控制器板,它可以通过一系列的引脚来连接各种传感器、执行器、显示器等外部设备。Arduino的编程是基于C/C++语言的,你可以使用Arduino IDE(集成开发环境)来

    2024年02月04日
    浏览(47)
  • STM32+DHT11温湿度传感器

    DATA 用于微处理器与 DHT11之间的通讯和同步,采用单总线数据格式,一次 通讯时间4ms左右,数据分小数部分和整数部分,具体格式在下面说明,当前小数 部分用于以后扩展,现读出为零.操作流程如下: 一次完整的数据传输为40bit,高位先出。 数据格式:8bit湿度整数数据+8bit湿度小数数据

    2023年04月13日
    浏览(38)
  • STM32—DHT11温湿度传感器

    (1).下图一是DHT11总的时序图。 (2).图二对应图一的左边黑色部分,图三对应图一的绿色部分,图四的左部分图对应图一的红色部分,图四的右部分对应图一的黄色部分。 (3).首先图二部分是单片机向DHT11发送我要开始的信号,此时单片机IO口处于输出模式,输出低电平至少18MS,

    2024年02月19日
    浏览(43)
  • STM32--DHT11温湿度传感器

    本文介绍基于STM32F103实现的DHT11温湿度传感器数据采集及显示,完整代码见文末链接 一、DHT11传感器简介 DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期

    2024年02月16日
    浏览(42)
  • stm32读取DHT11温湿度传感器

    我们知道DHT11是单总线协议,只有一根数据线。 且内部有个上拉电路(下图)。那么数据线默认就是高电平那接下来就可以讲解主机如何和DHT11通讯的 读取DHT11的芯片手册,可以知道,DHT11一次完成的数据输出是40bit,高位先出。 格式:8bit湿度整数数据+8bit湿度小数数据 +8bi温

    2024年02月09日
    浏览(38)
  • stm32连接DHT11温湿度传感器

    目录 1. DHT11简介 1.1. 连接电路  1.2. 串行接口 (单线双向)  2. cubeMX设置 3. 代码开发  3.1. 实现定时函数 3.2. 打开串口调试 3.4. 测试代码实现 4. 运行效果 信息如下: 建议连接线长度短于20米时用5K上拉电阻,大于20米时根据实际情况使 用合适的上拉电阻  DHT11的供电电压为 3-5

    2023年04月16日
    浏览(37)
  • 玩转传感器——DHT11温湿度传感器(STM32版)

    DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。因此该产

    2024年02月03日
    浏览(42)
  • STM32+DHT11采集温湿度传感器数据

            DHT11 是一款湿温度一体化的数字传感器。该传感器包括一个电阻式测湿元件和一个 NTC 测温元件,并与一个高性能 8 位单片机相连接。通过单片机等微处理器简单的电路连接就能够 实时的采集本地湿度和温度。 DHT11 与单片机之间能采用简单的单总线进行通信,仅

    2024年02月07日
    浏览(34)
  • 【STM32】DHT11温湿度模块传感器详解&代码

    DHT11是数字温湿度传感器,测量范围:湿度20%-95%,温度0-50℃,广泛应用于加湿器、温湿度计、空调、汽车等领域。 如上图DATA引脚用于MCU与DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间4ms左右(超时时间的判断)。一次完整的数据传输为40bit,高位先出(MSB最高

    2024年02月12日
    浏览(44)
  • STM32+DHT11温湿度传感器(含完整代码)

    前言 DHT11数字温湿度传感器是一种数字信号输出的温湿度传感器,具有高可靠性和长期稳定性。它采用专用的数字模块和温湿度传感技术,提供准确的温湿度数据。传感器内部包含感湿元件和测温元件,并与高性能单片机连接。因此,该传感器具有优异的品质、快速响应、抗

    2024年04月08日
    浏览(62)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包