摘要: 本文将手把手教你搭建一个完整的物联网数据监控平台,使用STM32采集温湿度数据,通过ESP8266 WiFi模块上传至Linux服务器,并利用Python脚本将数据存储到MySQL数据库,最后实现每日平均值的计算和可视化展示。

关键词: STM32, ESP8266, Linux, MySQL, 物联网, 温湿度传感器, 数据可视化

一、系统架构

本项目采用典型的物联网三层架构:

  • 感知层: STM32单片机读取DHT11温湿度传感器数据,并通过ESP8266 WiFi模块发送至服务器。
  • 网络层: ESP8266连接路由器,将数据传输至公网IP的Linux服务器。
  • 应用层: Linux服务器上的Python脚本接收数据,并存储到MySQL数据库。同时,脚本还会计算每日平均值,并提供简单的可视化图表。

二、硬件准备

  • STM32开发板
  • DHT11温湿度传感器
  • ESP8266 WiFi模块
  • 杜邦线若干

三、软件准备

  • STM32CubeMX
  • Keil MDK
  • Putty
  • Xshell
  • MySQL
  • Python 3.x
  • Navicat for MySQL (可选)

四、STM32端开发

4.1 使用STM32CubeMX配置工程
  1. 新建工程,选择STM32F103C8T6芯片。
  2. 配置RCC时钟源为外部晶振。
  3. 配置GPIO引脚,用于DHT11数据读取和ESP8266通信。
  4. 配置USART1用于与ESP8266通信。
  5. 生成Keil MDK工程代码。
4.2 编写STM32代码
// DHT11数据读取函数
void DHT11_Read_Data(float *temperature, float *humidity);

// ESP8266数据发送函数
void ESP8266_Send_Data(char *data);

int main(void)
{
    // 初始化
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_USART1_UART_Init();
    DHT11_Init();

    float temperature, humidity;
    char data[50];

    while (1)
    {
        // 读取DHT11数据
        DHT11_Read_Data(&temperature, &humidity);

        // 格式化数据
        sprintf(data, "temperature=%.1f&humidity=%.1f", temperature, humidity);

        // 通过ESP8266发送数据
        ESP8266_Send_Data(data);

        HAL_Delay(5000); // 每5秒采集一次数据
    }
}

4.3 编译下载
  1. 在Keil MDK中编译工程。
  2. 将编译生成的hex文件下载到STM32开发板。

五、Linux服务器配置

5.1 安装软件
  1. 使用apt-get安装必要的软件包:
sudo apt-get update
sudo apt-get install python3 python3-pip mysql-server
  1. 安装Python库:
pip3 install flask pymysql
5.2 创建MySQL数据库及数据表
  1. 登录MySQL:
mysql -u root -p
  1. 创建数据库:
CREATE DATABASE iot_data;
  1. 创建数据表:
USE iot_data;
CREATE TABLE temp_humidity (
    id INT AUTO_INCREMENT PRIMARY KEY,
    temperature FLOAT,
    humidity FLOAT,
    datetime DATETIME DEFAULT CURRENT_TIMESTAMP
);
5.3 编写Python数据接收脚本
from flask import Flask, request
import pymysql

app = Flask(__name__)

# MySQL数据库连接信息
db_config = {
    'host': 'localhost',
    'user': 'root',
    'password': 'your_password',
    'database': 'iot_data'
}

@app.route('/data', methods=['POST'])
def receive_data():
    # 获取POST请求中的数据
    temperature = request.form.get('temperature')
    humidity = request.form.get('humidity')

    # 连接MySQL数据库
    conn = pymysql.connect(**db_config)
    cursor = conn.cursor()

    try:
        # 插入数据
        sql = "INSERT INTO temp_humidity (temperature, humidity) VALUES (%s, %s)"
        cursor.execute(sql, (temperature, humidity))
        conn.commit()
        print("数据插入成功!")
    except Exception as e:
        print(f"数据插入失败:{e}")
        conn.rollback()
    finally:
        cursor.close()
        conn.close()

    return 'OK'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)
5.4 编写Python数据处理脚本
import pymysql
from datetime import date, timedelta

# MySQL数据库连接信息
db_config = {
    'host': 'localhost',
    'user': 'root',
    'password': 'your_password',
    'database': 'iot_data'
}

def calculate_daily_average():
    # 计算昨天的日期
    yesterday = date.today() - timedelta(days=1)

    # 连接MySQL数据库
    conn = pymysql.connect(**db_config)
    cursor = conn.cursor()

    try:
        # 查询昨天的数据
        sql = f"SELECT AVG(temperature), AVG(humidity) FROM temp_humidity WHERE DATE(datetime) = '{yesterday}'"
        cursor.execute(sql)
        result = cursor.fetchone()

        # 打印结果
        if result:
            avg_temp, avg_humidity = result
            print(f"{yesterday} 的平均温度:{avg_temp:.2f}℃,平均湿度:{avg_humidity:.2f}%")
        else:
            print(f"{yesterday} 没有数据记录。")

    except Exception as e:
        print(f"数据查询失败:{e}")
    finally:
        cursor.close()
        conn.close()

if __name__ == '__main__':
    calculate_daily_average()

六、ESP8266配置

6.1 连接ESP8266

使用USB转TTL模块连接ESP8266,并配置好串口调试工具(如Putty)。

6.2 配置ESP8266工作模式
AT+CWMODE=1  // 设置为Station模式
AT+CWJAP="your_wifi_ssid","your_wifi_password"  // 连接WiFi
AT+CIPSTART="TCP","your_server_ip",5000  // 建立TCP连接
6.3 修改STM32代码,通过ESP8266发送数据
// ESP8266数据发送函数
void ESP8266_Send_Data(char *data)
{
    // 发送AT指令
    char cmd[100];
    sprintf(cmd, "AT+CIPSEND=%d\r\n", strlen(data));
    HAL_UART_Transmit(&huart1, (uint8_t *)cmd, strlen(cmd), 1000);

    // 等待发送提示
    HAL_UART_Receive(&huart1, rx_buffer, sizeof(rx_buffer), 1000);

    // 发送数据
    HAL_UART_Transmit(&huart1, (uint8_t *)data, strlen(data), 1000);

    // 发送结束符
    HAL_UART_Transmit(&huart1, (uint8_t *)"\r\n", 2, 1000);
}

 

  1. 运行Python数据接收脚本: 在Linux服务器上执行 python3 data_receiver.py 启动Flask应用,监听来自ESP8266的数据。

  2. 烧录STM32程序并观察串口输出:

    • 编译并烧录STM32代码到开发板。
    • 打开串口调试工具,设置波特率与代码一致。
    • 观察串口输出,确认DHT11数据读取正常,且ESP8266成功连接WiFi并发送数据。
  3. 查看MySQL数据库确认数据存储:

    • 使用Navicat for MySQL或命令行工具连接到MySQL数据库。
    • 查看iot_data数据库中的temp_humidity表,确认数据已成功插入。
  4. 运行Python数据处理脚本:

    • 等待一段时间,让系统积累一些温湿度数据。
    • 每天定时运行python3 data_processor.py脚本,计算前一天的平均温湿度并输出到控制台。

八、数据可视化 (可选)

为了更直观地展示温湿度数据,可以使用Python的数据可视化库(如Matplotlib)生成图表。

import matplotlib.pyplot as plt
import pymysql
from datetime import datetime, timedelta

# ... (数据库连接信息与calculate_daily_average函数代码)

# 获取过去7天的平均温湿度数据
def get_weekly_average():
    data = []
    today = datetime.today()
    for i in range(7):
        day = today - timedelta(days=i)
        sql = f"SELECT AVG(temperature), AVG(humidity) FROM temp_humidity WHERE DATE(datetime) = '{day.strftime('%Y-%m-%d')}'"
        cursor.execute(sql)
        result = cursor.fetchone()
        if result:
            data.append((day.strftime('%Y-%m-%d'), result[0], result[1]))
        else:
            data.append((day.strftime('%Y-%m-%d'), None, None))
    return data

if __name__ == '__main__':
    # ... (计算并打印日平均值)

    # 获取数据并绘制图表
    data = get_weekly_average()
    dates = [row[0] for row in data]
    temperatures = [row[1] for row in data]
    humidities = [row[2] for row in data]

    plt.plot(dates, temperatures, label="Temperature (°C)")
    plt.plot(dates, humidities, label="Humidity (%)")
    plt.xlabel("Date")
    plt.ylabel("Value")
    plt.title("Weekly Average Temperature and Humidity")
    plt.legend()
    plt.show()
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐