基于STM32的智慧厨房安全全栈嵌入式系统:融合FreeRTOS、MQTT、Flask、Vue.js、Flutter等技术的解决方案

1. 项目概述

智慧厨房安全系统是一个基于STM32微控制器的物联网项目,旨在提高厨房安全性和用户体验。该系统通过各种传感器监测厨房环境,如温度、湿度、烟雾浓度等,并通过Wi-Fi将数据传输到云端进行分析和存储。用户可以通过手机APP实时查看厨房状态,接收警报通知,远程控制设备。

本项目涵盖了嵌入式开发、后端服务器、前端应用和云平台等全栈技术,是一个综合性的物联网解决方案。

2. 系统设计

2.1 硬件设计

硬件系统主要包括:

  • STM32F4系列微控制器作为主控
  • DHT22温湿度传感器
  • MQ-2烟雾传感器
  • MQ-5可燃气体传感器
  • ESP8266 Wi-Fi模块
  • 蜂鸣器和LED用于本地警报
  • OLED显示屏用于显示实时数据

硬件系统架构图:

2.2 软件架构

软件系统包括:

  • STM32固件:采用FreeRTOS实时操作系统
  • MQTT Broker:用于设备和服务器间的通信
  • 后端服务器:使用Python Flask框架
  • 数据库:采用MySQL存储历史数据
  • Web前端:基于Vue.js框架
  • 移动APP:使用Flutter开发跨平台应用
  • Home Assistant:集成用于智能家居控制

软件系统架构图:

3. 代码实现

3.1 STM32固件核心代码

以下是STM32固件的主要结构,使用FreeRTOS创建了两个任务:主任务和MQTT发布任务。

cpp 复制代码
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "sensors.h"
#include "wifi.h"
#include "mqtt_client.h"

// 互斥信号量
SemaphoreHandle_t xDataMutex;
// 全局传感器数据结构体
SensorData_t gSensorData;

// 主任务函数
void vMainTask(void *pvParameters)
{
    while(1)
    {
        // 获取互斥信号量
        xSemaphoreTake(xDataMutex, portMAX_DELAY);
        // 读取传感器数据
        ReadSensorData(&gSensorData);
        // 释放互斥信号量
        xSemaphoreGive(xDataMutex);

        // 检查阈值
        CheckThresholds(&gSensorData);
        // 任务延时
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

// MQTT发布任务函数
void vMQTTPublishTask(void *pvParameters)
{
    while(1)
    {
        // 获取互斥信号量
        xSemaphoreTake(xDataMutex, portMAX_DELAY);
        // 发布传感器数据
        MQTT_PublishSensorData(&gSensorData);
        // 释放互斥信号量
        xSemaphoreGive(xDataMutex);
        // 任务延时
        vTaskDelay(pdMS_TO_TICKS(5000));
    }
}

// 主函数
int main(void)
{
    // 硬件初始化
    HardwareInit();
    // 创建互斥信号量
    xDataMutex = xSemaphoreCreateMutex();
    // 创建主任务
    xTaskCreate(vMainTask, "MainTask", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);
    // 创建MQTT发布任务
    xTaskCreate(vMQTTPublishTask, "MQTTPublishTask", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);
    // 启动调度器
    vTaskStartScheduler();
    for(;;);
}
代码说明:
  • vMainTask函数:该函数执行主任务,负责读取传感器数据并检查是否超出阈值。在每次读取和处理数据之前获取互斥信号量,以确保数据安全。
  • vMQTTPublishTask函数:该函数执行MQTT发布任务,定期将传感器数据发布到MQTT Broker。与主任务类似,它也在操作数据之前获取互斥信号量。
  • main函数:硬件初始化后,创建互斥信号量和任务,并启动FreeRTOS调度器。

3.2 传感器驱动代码

以下是传感器驱动代码,实现了对各类传感器数据的读取和阈值检查。

cpp 复制代码
#include "sensors.h"

// 读取传感器数据
void ReadSensorData(SensorData_t* data)
{
    data->temperature = ReadTemperature();
    data->humidity = ReadHumidity();
    data->smoke = ReadSmokeLevel();
    data->gas = ReadGasLevel();
}

// 检查传感器数据是否超出阈值
void CheckThresholds(SensorData_t* data)
{
    if(data->temperature > TEMP_THRESHOLD || 
       data->humidity > HUMIDITY_THRESHOLD ||
       data->smoke > SMOKE_THRESHOLD || 
       data->gas > GAS_THRESHOLD)
    {
        TriggerAlarm();
    }
    else
    {
        ClearAlarm();
    }
}
代码说明:
  • ReadSensorData函数:封装了具体的传感器数据读取操作,包括温度、湿度、烟雾和可燃气体传感器。
  • CheckThresholds函数:检查读取到的传感器数据是否超过预设阈值,如果超过则触发报警,否则清除报警。

3.3 MQTT通信代码

以下是使用ESP8266模块通过UART与STM32通信,并通过MQTT协议将数据上传至云端的代码示例。

cpp 复制代码
#include "mqtt_client.h"
#include "wifi.h"

// MQTT发布传感器数据
void MQTT_PublishSensorData(SensorData_t* data)
{
    char payload[128];
    snprintf(payload, sizeof(payload), "{\"temperature\":%.2f,\"humidity\":%.2f,\"smoke\":%.2f,\"gas\":%.2f}",
             data->temperature, data->humidity, data->smoke, data->gas);
    MQTT_Publish("kitchen/sensorData", payload);
}

// 初始化Wi-Fi并连接到AP
void WiFi_Init(void)
{
    ESP8266_Init();
    ESP8266_JoinAP("SSID", "PASSWORD");
    ESP8266_StartMQTT("broker.hivemq.com", 1883, "kitchenClient");
}
代码说明:
  • MQTT_PublishSensorData函数:将传感器数据格式化为JSON字符串,并通过MQTT协议发布到指定的主题。
  • WiFi_Init函数:初始化ESP8266模块,并连接到指定的Wi-Fi接入点,然后启动MQTT客户端连接到MQTT Broker。

4. 后端开发

4.1 Flask后端示例

以下是使用Python Flask框架实现的后端服务器代码示例。

python 复制代码
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://username:password@localhost:3306/kitchen_db'
db = SQLAlchemy(app)

class SensorData(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    temperature = db.Column(db.Float)
    humidity = db.Column(db.Float)
    smoke = db.Column(db.Float)
    gas = db.Column(db.Float)
    timestamp = db.Column(db.DateTime, default=db.func.current_timestamp())

@app.route('/data', methods=['POST'])
def receive_data():
    data = request.json
    new_data = SensorData(
        temperature=data['temperature'],
        humidity=data['humidity'],
        smoke=data['smoke'],
        gas=data['gas']
    )
    db.session.add(new_data)
    db.session.commit()
    return jsonify({'status': 'success'}), 200

@app.route('/data', methods=['GET'])
def get_data():
    data = SensorData.query.all()
    result = []
    for entry in data:
        result.append({
            'temperature': entry.temperature,
            'humidity': entry.humidity,
            'smoke': entry.smoke,
            'gas': entry.gas,
            'timestamp': entry.timestamp
        })
    return jsonify(result), 200

if __name__ == '__main__':
    db.create_all()
    app.run(debug=True)
代码说明:
  • SensorData模型:定义了传感器数据的数据库模型,包括温度、湿度、烟雾、气体浓度和时间戳字段。
  • receive_data路由:处理POST请求,接收传感器数据并存储到数据库中。
  • get_data路由:处理GET请求,从数据库中获取所有传感器数据并返回JSON格式的响应。

4.2 数据库设计

使用MySQL数据库存储传感器数据。数据库表的设计如下:

sql 复制代码
CREATE TABLE SensorData (
    id INT AUTO_INCREMENT PRIMARY KEY,
    temperature FLOAT,
    humidity FLOAT,
    smoke FLOAT,
    gas FLOAT,
    timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

4.3 Web前端示例

以下是使用Vue.js框架实现的Web前端代码示例。

html 复制代码
<!DOCTYPE html>
<html>
<head>
    <title>智慧厨房安全系统</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <style>
        table {
            width: 100%;
            border-collapse: collapse;
        }
        th, td {
            border: 1px solid black;
            padding: 8px;
            text-align: left;
        }
        th {
            background-color: #f2f2f2;
        }
    </style>
</head>
<body>
<div id="app">
    <h1>智慧厨房安全系统</h1>
    <table>
        <tr>
            <th>Temperature</th>
            <th>Humidity</th>
            <th>Smoke</th>
            <th>Gas</th>
            <th>Timestamp</th>
        </tr>
        <tr v-for="data in sensorData" :key="data.timestamp">
            <td>{{ data.temperature }}</td>
            <td>{{ data.humidity }}</td>
            <td>{{ data.smoke }}</td>
            <td>{{ data.gas }}</td>
            <td>{{ data.timestamp }}</td>
        </tr>
    </table>
</div>

<script>
new Vue({
    el: '#app',
    data: {
        sensorData: []
    },
    created() {
        this.fetchSensorData();
    },
    methods: {
        fetchSensorData() {
            axios.get('http://localhost:5000/data')
                .then(response => {
                    this.sensorData = response.data;
                })
                .catch(error => {
                    console.error('Error fetching sensor data:', error);
                });
        }
    }
});
</script>
</body>
</html>
代码说明:
  • HTML结构:定义了一个简单的表格来显示传感器数据。
  • Vue实例 :创建了一个Vue实例,初始化了sensorData数组,并在实例创建时调用fetchSensorData方法。
  • fetchSensorData方法 :使用Axios库发送GET请求到后端服务器,获取传感器数据并将其存储在sensorData数组中。

4.4 移动APP示例

以下是使用Flutter框架实现的移动应用代码示例。

java 复制代码
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: SensorDataScreen(),
    );
  }
}

class SensorDataScreen extends StatefulWidget {
  @override
  _SensorDataScreenState createState() => _SensorDataScreenState();
}

class _SensorDataScreenState extends State<SensorDataScreen> {
  List<dynamic> sensorData = [];

  @override
  void initState() {
    super.initState();
    fetchSensorData();
  }

  Future<void> fetchSensorData() async {
    final response = await http.get(Uri.parse('http://localhost:5000/data'));
    if (response.statusCode == 200) {
      setState(() {
        sensorData = json.decode(response.body);
      });
    } else {
      throw Exception('Failed to load sensor data');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('智慧厨房安全系统'),
      ),
      body: ListView.builder(
        itemCount: sensorData.length,
        itemBuilder: (context, index) {
          final data = sensorData[index];
          return ListTile(
            title: Text('Temperature: ${data['temperature']}'),
            subtitle: Text(
              'Humidity: ${data['humidity']} \nSmoke: ${data['smoke']} \nGas: ${data['gas']} \nTimestamp: ${data['timestamp']}',
            ),
          );
        },
      ),
    );
  }
}
代码说明:
  • Flutter应用结构 :创建了一个简单的Flutter应用,其中包含一个SensorDataScreen来显示传感器数据。
  • fetchSensorData方法 :使用http库发送GET请求到后端服务器,获取传感器数据并解析为JSON格式,然后更新状态。

5. 项目总结

本项目通过STM32微控制器、传感器、ESP8266 Wi-Fi模块等硬件设备,结合FreeRTOS、MQTT、Flask、Vue.js、Flutter等软件技术,构建了一个综合性的智慧厨房安全系统。项目的主要成果和总结如下:

5.1 硬件设计

项目的硬件部分采用了STM32F4系列微控制器作为主控,配合DHT22温湿度传感器、MQ-2烟雾传感器、MQ-5可燃气体传感器等多种传感器,对厨房环境进行实时监测。同时,ESP8266 Wi-Fi模块实现了数据的无线传输,蜂鸣器和LED提供了本地报警功能,OLED显示屏用于显示当前传感器数据。

5.2 软件架构

软件部分采用FreeRTOS实时操作系统,实现了任务的调度和管理。通过MQTT协议,传感器数据可以实时上传到云端进行存储和分析。后端服务器使用Python Flask框架,结合MySQL数据库,实现了数据的接收、存储和查询功能。前端部分采用Vue.js框架,实现了Web端的实时数据展示和用户交互。移动端则使用Flutter框架开发,实现了跨平台的移动应用,方便用户随时随地查看厨房状态。

5.3 系统集成

项目的系统集成部分通过Home Assistant实现了智能家居的控制和管理。用户可以通过Web前端或移动APP实时查看厨房环境数据,接收报警通知,并远程控制相关设备。同时,系统还可以根据预设的阈值自动触发报警,确保厨房的安全。

5.4 项目成果

  1. 实时环境监测:通过多种传感器实时监测厨房环境,包括温度、湿度、烟雾和可燃气体浓度。
  2. 无线数据传输:通过ESP8266 Wi-Fi模块实现了数据的无线传输,用户可以通过互联网随时查看数据。
  3. 智能报警:系统可以根据设定的阈值自动触发报警,并通过蜂鸣器和LED进行本地提示,同时通过MQTT发送报警通知到用户的手机。
  4. 数据存储与分析:传感器数据可以存储在云端数据库中,方便用户进行历史数据查询和分析。
  5. 跨平台应用:通过Web前端和Flutter移动应用,用户可以在多种设备上访问系统,操作便捷。

5.5 项目挑战与解决方案

  1. 实时性要求高:为确保数据的实时性和系统响应速度,项目采用了FreeRTOS进行任务调度,并使用MQTT协议进行高效的消息传递。
  2. 数据安全性:在数据传输过程中,采用HTTPS加密协议,确保数据的安全性和完整性。
  3. 系统可靠性:通过合理的硬件设计和软件架构,确保系统的稳定运行,避免因硬件故障或软件错误导致系统崩溃。
相关推荐
萧瑟余晖5 分钟前
Java深入解析篇九之NIO详解
java·网络·nio
The Chosen One98525 分钟前
高进度算法模板速记(待完善)
java·前端·算法
Gu Gu Study29 分钟前
ScoutLoop开放域深度研究引擎(agent的初步设计想法)
人工智能·python
卷无止境1 小时前
写代码这件事,到底该讲究点什么?
后端·python
卷无止境1 小时前
循环复杂度到底在算什么,Python 代码怎么才能写得让人一看就懂
后端·python
lpfasd1231 小时前
MediaCrawler 项目深度分析
chrome·python·chrome devtools
Dxy12393102162 小时前
Python项目打包成EXE完整教程(PyInstaller实战避坑)
开发语言·python
鲜花飘飘扬2 小时前
HTTP请求头中表示代理IP地址的属性及获取情况
网络协议·tcp/ip·http
bamb002 小时前
一个项目带你入门AI应用开发01
python
0566463 小时前
Python康复训练——常用标准库
开发语言·python·学习