ToB企服应用市场:ToB评测及商务社交产业平台

标题: 基于STM32的边缘计算实时数据处理可视化系统:嵌入式C++、 FreeRTOS、Kafka [打印本页]

作者: 王國慶    时间: 2024-12-8 21:24
标题: 基于STM32的边缘计算实时数据处理可视化系统:嵌入式C++、 FreeRTOS、Kafka
一、项目概述

本项目旨在设计并实现一个基于STM32的边缘计算实时数据处理系统。该系统可以或许在边缘装备端举行数据采集、预处理,并将处理后的数据实时传输到后端服务器举行进一步分析和存储。
本项目主要解决以下问题:
通过边缘计算与实时数据处理相结合,本系统可广泛应用于工业物联网、智能家居、环境监测等多个范畴,为用户提供高效、安全、实时的数据分析服务。
二、系统架构

本系统采用分层架构设计,主要包括边缘层、网络层和云端层三个部门。
2.1 硬件选型


2.2 软件技术栈


2.3 系统架构图

     三、环境搭建

3.1 开辟环境


3.2 STM32环境配置

配置示例:
  1. // 时钟配置
  2. RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  3. RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  4. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  5. RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  6. RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  7. RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  8. RCC_OscInitStruct.PLL.PLLM = 8;
  9. RCC_OscInitStruct.PLL.PLLN = 336;
  10. RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  11. RCC_OscInitStruct.PLL.PLLQ = 7;
  12. RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  13.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  14. RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  15. RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  16. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  17. RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
  18. HAL_RCC_OscConfig(&RCC_OscInitStruct);
  19. HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
  20. // UART配置
  21. huart2.Instance = USART2;
  22. huart2.Init.BaudRate = 115200;
  23. huart2.Init.WordLength = UART_WORDLENGTH_8B;
  24. huart2.Init.StopBits = UART_STOPBITS_1;
  25. huart2.Init.Parity = UART_PARITY_NONE;
  26. huart2.Init.Mode = UART_MODE_TX_RX;
  27. huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  28. huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  29. HAL_UART_Init(&huart2);
  30. // FreeRTOS配置
  31. osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
  32. defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
复制代码
3.3 后端环境配置

Kafka配置示例 (server.properties):
  1. broker.id=0
  2. listeners=PLAINTEXT://localhost:9092
  3. num.network.threads=3
  4. num.io.threads=8
  5. socket.send.buffer.bytes=102400
  6. socket.receive.buffer.bytes=102400
  7. socket.request.max.bytes=104857600
  8. log.dirs=/tmp/kafka-logs
  9. num.partitions=1
  10. num.recovery.threads.per.data.dir=1
  11. offsets.topic.replication.factor=1
  12. transaction.state.log.replication.factor=1
  13. transaction.state.log.min.isr=1
  14. log.retention.hours=168
  15. log.segment.bytes=1073741824
  16. log.retention.check.interval.ms=300000
复制代码
注意事项:

四、代码实现

4.1 STM32边缘装备数据采集与预处理

  1. #include "main.h"
  2. #include "cmsis_os.h"
  3. #include "dht22.h"
  4. #include "bmp280.h"
  5. // 定义传感器数据结构
  6. typedef struct {
  7.     float temperature;
  8.     float humidity;
  9.     float pressure;
  10. } SensorData;
  11. // 数据采集任务
  12. void DataCollectionTask(void const * argument)
  13. {
  14.     SensorData data;
  15.     for(;;)
  16.     {
  17.         // 读取DHT22温湿度数据
  18.         DHT22_Read(&data.temperature, &data.humidity);
  19.         
  20.         // 读取BMP280气压数据
  21.         data.pressure = BMP280_ReadPressure();
  22.         
  23.         // 数据预处理 (示例: 简单的移动平均滤波)
  24.         static float temp_buffer[5] = {0};
  25.         static int buffer_index = 0;
  26.         
  27.         temp_buffer[buffer_index] = data.temperature;
  28.         buffer_index = (buffer_index + 1) % 5;
  29.         
  30.         float avg_temp = 0;
  31.         for(int i = 0; i < 5; i++) {
  32.             avg_temp += temp_buffer[i];
  33.         }
  34.         data.temperature = avg_temp / 5;
  35.         
  36.         // 发送数据到MQTT发布任务
  37.         xQueueSend(mqttPublishQueue, &data, portMAX_DELAY);
  38.         
  39.         osDelay(5000); // 每5秒采集一次数据
  40.     }
  41. }
  42. // MQTT发布任务
  43. void MQTTPublishTask(void const * argument)
  44. {
  45.     SensorData data;
  46.     char mqtt_message[100];
  47.     for(;;)
  48.     {
  49.         if(xQueueReceive(mqttPublishQueue, &data, portMAX_DELAY) == pdTRUE)
  50.         {
  51.             // 格式化MQTT消息
  52.             snprintf(mqtt_message, sizeof(mqtt_message),
  53.                      "{"temp":%.2f,"hum":%.2f,"press":%.2f}",
  54.                      data.temperature, data.humidity, data.pressure);
  55.             
  56.             // 通过ESP8266发送MQTT消息
  57.             ESP8266_MQTT_Publish("sensor/data", mqtt_message);
  58.         }
  59.     }
  60. }
复制代码
4.2 Spring Boot后端服务

  1. @Service
  2. public class SensorDataService {
  3.     private final KafkaTemplate<String, String> kafkaTemplate;
  4.     private final InfluxDBClient influxDBClient;
  5.     @Autowired
  6.     public SensorDataService(KafkaTemplate<String, String> kafkaTemplate, InfluxDBClient influxDBClient) {
  7.         this.kafkaTemplate = kafkaTemplate;
  8.         this.influxDBClient = influxDBClient;
  9.     }
  10.     @KafkaListener(topics = "sensor.data", groupId = "sensor-group")
  11.     public void consumeSensorData(String message) {
  12.         try {
  13.             JSONObject jsonObject = new JSONObject(message);
  14.             double temperature = jsonObject.getDouble("temp");
  15.             double humidity = jsonObject.getDouble("hum");
  16.             double pressure = jsonObject.getDouble("press");
  17.             // 存储数据到InfluxDB
  18.             Point point = Point.measurement("sensor_data")
  19.                     .addTag("sensor_id", "stm32_01")
  20.                     .addField("temperature", temperature)
  21.                     .addField("humidity", humidity)
  22.                     .addField("pressure", pressure)
  23.                     .time(Instant.now(), WritePrecision.NS);
  24.             WriteApiBlocking writeApi = influxDBClient.getWriteApiBlocking();
  25.             writeApi.writePoint("sensor_bucket", "org", point);
  26.             // 进行数据分析 (示例: 简单的阈值检测)
  27.             if (temperature > 30 || humidity > 80) {
  28.                 sendAlert("High temperature or humidity detected!");
  29.             }
  30.         } catch (JSONException e) {
  31.             log.error("Error parsing sensor data: ", e);
  32.         }
  33.     }
  34.     private void sendAlert(String message) {
  35.         // 实现告警逻辑,如发送邮件或推送通知
  36.         log.warn("Alert: " + message);
  37.     }
  38. }
复制代码
4.3 代码阐明

STM32边缘装备代码

Spring Boot后端服务代码

这些代码实现了从STM32边缘装备采集数据,通过MQTT传输,再由Spring Boot后端吸收并存储到InfluxDB的完备流程。系统设计思量了实时性、可靠性和可扩展性,为物联网应用提供了一个solid的基础架构。
4.4 Grafana数据可视化

示例查询:
  1. SELECT mean("temperature") AS "avg_temp",
  2.        mean("humidity") AS "avg_hum",
  3.        mean("pressure") AS "avg_press"
  4. FROM "sensor_data"
  5. WHERE $timeFilter
  6. GROUP BY time($__interval)
复制代码
五、项目总结

本项目成功实现了一个基于STM32的边缘计算实时数据处理系统,主要功能和实现过程如下:
通过这个系统,我们成功地将数据处理前移到边缘装备,减轻了后端服务器的负担,同时实现了近实时的数据分析和可视化。该系统具有精良的可扩展性,可以根据需求添加更多的传感器和分析功能。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4