使用 STM32F10x 微控制器与 DHT11 温湿度传感器 和 ESP8266 Wi-Fi 模块 进行通信,实现数据采集并发送到远程 TCP 服务器是一个常见的 IoT 项目。以下详细描述了如何实现该项目,包括硬件连接、软件编写和通信测试。
1. 硬件准备
1.1 所需硬件
- STM32F103 (例如 STM32F103C8T6): 微控制器开发板,用于读取传感器数据。
- DHT11 温湿度传感器: 用于测量环境的温度和湿度。
- ESP8266 Wi-Fi 模块: 通过 Wi-Fi 连接 TCP 服务器并传输数据。
- 面包板和跳线: 用于测试和连接模块。
1.2 硬件连接
1.2.1 DHT11 传感器与 STM32F10x 连接
- DHT11 引脚与 STM32F10x 引脚的连接如下:
DHT11 引脚 | STM32F103 引脚 |
---|---|
VCC | 3.3V |
GND | GND |
DATA | PA1(可选) |
1.2.2 ESP8266 与 STM32F10x 连接
ESP8266 工作在 3.3V,需要通过 UART 与 STM32 进行通信。
ESP8266 引脚 | STM32F103 引脚 |
---|---|
VCC | 3.3V |
GND | GND |
RXD | PA2(STM32 TX) |
TXD | PA3(STM32 RX) |
注意,ESP8266 的 RX 引脚只能接收 3.3V 信号,STM32 的引脚也是 3.3V,故可以直接连接。如果使用 5V 微控制器,需要通过电压分压器降压。
2. 软件准备
2.1 开发环境配置
2.1.1 STM32CubeMX 和 Keil 配置
- 使用 STM32CubeMX 配置 STM32 的外设,比如 GPIO 和 USART(用于与 ESP8266 通信)。
- 生成的项目文件可在 Keil 或 STM32CubeIDE 中进行编写和编译。
2.1.2 安装库
- 使用 DHT 库 读取传感器数据。
- 使用 STM32 的 HAL 库 控制 GPIO 和 USART 通信。
- 使用 ESP8266 的 AT 指令集来处理 Wi-Fi 和 TCP 连接。
2.2 代码编写
以下代码展示了如何使用 STM32F103 收集 DHT11 数据并通过 ESP8266 发送到 TCP 服务器。
2.2.1 DHT11 传感器代码
首先,编写一个简单的函数来读取 DHT11 温湿度传感器数据。
c
#include "stm32f1xx_hal.h"
#define DHT11_PIN GPIO_PIN_1 // DHT11连接的引脚
#define DHT11_PORT GPIOA // 使用PA1
// 函数原型声明
void DHT11_Init(void);
uint8_t DHT11_Read(uint8_t *temperature, uint8_t *humidity);
// 初始化 DHT11 引脚
void DHT11_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
// 配置为输出模式
GPIO_InitStruct.Pin = DHT11_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(DHT11_PORT, &GPIO_InitStruct);
}
// 从 DHT11 读取温湿度数据
uint8_t DHT11_Read(uint8_t *temperature, uint8_t *humidity) {
// 这里包含完整的DHT11数据读取代码,
// 需要考虑时序,并根据不同微控制器的时钟频率调整延时。
// 省略具体时序代码。
// 成功读取后,存储到 humidity 和 temperature 中。
*temperature = 25; // 示例数据
*humidity = 60; // 示例数据
return 1; // 返回 1 表示读取成功
}
2.2.2 ESP8266 模块代码
通过 USART 与 ESP8266 通信,并通过 AT 指令集控制其连接 Wi-Fi 和发送数据到 TCP 服务器。
c
#include "stm32f1xx_hal.h"
#include <string.h>
UART_HandleTypeDef huart1;
// 初始化 USART1(与 ESP8266 通信的串口)
void USART1_Init(void) {
__HAL_RCC_USART1_CLK_ENABLE();
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200; // 设置波特率为 115200
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
HAL_UART_Init(&huart1);
}
// 向 ESP8266 发送 AT 指令
void ESP8266_SendCommand(char *cmd) {
HAL_UART_Transmit(&huart1, (uint8_t*)cmd, strlen(cmd), HAL_MAX_DELAY);
}
// 连接 Wi-Fi
void ESP8266_ConnectWiFi(char *ssid, char *password) {
char cmd[100];
// 设置模式为 1 (Station 模式)
ESP8266_SendCommand("AT+CWMODE=1\r\n");
HAL_Delay(1000);
// 连接 Wi-Fi
sprintf(cmd, "AT+CWJAP=\"%s\",\"%s\"\r\n", ssid, password);
ESP8266_SendCommand(cmd);
HAL_Delay(5000);
}
// 向 TCP 服务器发送数据
void ESP8266_SendDataToServer(char *serverIP, int port, char *data) {
char cmd[100];
// 开启 TCP 连接
sprintf(cmd, "AT+CIPSTART=\"TCP\",\"%s\",%d\r\n", serverIP, port);
ESP8266_SendCommand(cmd);
HAL_Delay(2000);
// 发送数据
sprintf(cmd, "AT+CIPSEND=%d\r\n", strlen(data));
ESP8266_SendCommand(cmd);
HAL_Delay(1000);
// 发送实际数据
ESP8266_SendCommand(data);
HAL_Delay(1000);
// 关闭连接
ESP8266_SendCommand("AT+CIPCLOSE\r\n");
}
2.2.3 主程序
在主程序中,读取 DHT11 数据,并通过 ESP8266 发送到 TCP 服务器。
c
int main(void) {
HAL_Init(); // 初始化 HAL 库
DHT11_Init(); // 初始化 DHT11
USART1_Init(); // 初始化 USART1 (ESP8266 通信)
// 连接 Wi-Fi
ESP8266_ConnectWiFi("your_SSID", "your_PASSWORD");
uint8_t temperature = 0, humidity = 0;
while (1) {
if (DHT11_Read(&temperature, &humidity)) {
// 构建发送到服务器的数据
char data[100];
sprintf(data, "Temperature: %d C, Humidity: %d %%", temperature, humidity);
// 发送数据到服务器
ESP8266_SendDataToServer("your_server_ip", 12345, data);
}
HAL_Delay(5000); // 每 5 秒发送一次数据
}
}
3. 代码详解
3.1 初始化
- DHT11_Init(): 设置 DHT11 连接引脚的 GPIO 模式。
- USART1_Init(): 初始化 USART1 以与 ESP8266 通信,波特率设置为 115200。
- ESP8266_ConnectWiFi(): 使用 AT 指令连接 Wi-Fi 网络。
3.2 数据采集与发送
- DHT11_Read(): 读取温湿度数据,返回到
temperature
和humidity
变量。 - ESP8266_SendDataToServer(): 使用 AT 指令,通过 TCP 连接将数据发送到服务器。
4. 测试步骤
4.1 配置 TCP 服务器
- 在本地计算机或云服务器上设置一个 TCP 服务器,监听指定端口以接收 STM32 发送的数据。
- 可以使用类似 Netcat 或 Python 脚本来创建一个简单的 TCP 服务器:
python
import socket
HOST = '0.0.0.0' # 监听所有 IP
PORT = 12345 # 与 STM