项目概述
随着工业4.0和物联网(IoT)技术的发展,越来越多的工厂借助智能化手段进行生产数据的采集和实时监控。本项目设计并实现一个物联网工厂检测系统,通过传感器采集关键参数,并利用云平台进行数据存储和分析,以提高生产效率和产品质量。
系统设计
系统设计分为四个层次:硬件层、网络层、平台层和应用层。
硬件层
硬件层是系统的基础,包括:
-
嵌入式系统:使用 STM32F4 单片机,具备强大的处理能力和丰富的外设接口,通过 ADC 连接各类传感器。
-
传感器:
- 温度传感器:DS18B20,适合工业环境。
- 压力传感器:MPX5700AP,检测范围0-700kPa。
- 湿度传感器:DHT22,精度高。
- 电流传感器:ACS712,支持交流和直流电流测量。
-
通信模块:
- Wi-Fi:ESP8266,适合高数据传输速率场景。
- LoRa:SX1278,适合长距离低功耗传输。
网络层
网络层负责设备通信,采用协议包括:
- MQTT:轻量级协议,适合低带宽、高延迟环境。
- TCP/IP:用于稳定连接。
平台层
平台层负责数据存储与处理,包括:
- 云平台:选择阿里云,提供强大存储和计算能力。
- 数据库:使用 MongoDB 存储非结构化数据,MySQL 存储结构化数据。
- 消息队列:RabbitMQ,解耦数据生产者和消费者。
- 大数据分析:Apache Spark,实时分析设备数据。
应用层
应用层提供用户交互界面,包括:
-
Web 开发:
- 前端:使用 React 开发实时监控界面。
- 后端:使用 Spring Boot 提供 RESTful API。
嵌入式硬件端代码
1. STM32 数据采集代码
以下代码展示如何使用 STM32 进行传感器数据的采集和处理。
#include "stm32f4xx_hal.h"
#include "sensor.h"
#include "communication.h"
// 定义 ADC 句柄
ADC_HandleTypeDef hadc1; // 温度传感器
ADC_HandleTypeDef hadc2; // 压力传感器
// 读取温度传感器数据
float readTemperature() {
HAL_ADC_Start(&hadc1); // 启动 ADC
HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY); // 等待转换完成
uint32_t adcValue = HAL_ADC_GetValue(&hadc1); // 读取 ADC 值
HAL_ADC_Stop(&hadc1); // 停止 ADC
float temperature = (adcValue / 4096.0) * 100; // 转换为温度(假设线性关系)
return temperature;
}
// 读取压力传感器数据
float readPressure() {
HAL_ADC_Start(&hadc2); // 启动 ADC
HAL_ADC_PollForConversion(&hadc2, HAL_MAX_DELAY); // 等待转换完成
uint32_t adcValue = HAL_ADC_GetValue(&hadc2); // 读取 ADC 值
HAL_ADC_Stop(&hadc2); // 停止 ADC
float pressure = (adcValue / 4096.0) * 700; // 转换为压力(假设线性关系)
return pressure;
}
// 主函数
void main() {
HAL_Init(); // 初始化 HAL 库
// 初始化 ADC 和其他外设
SystemClock_Config(); // 配置系统时钟
MX_ADC1_Init(); // 初始化 ADC1
MX_ADC2_Init(); // 初始化 ADC2
MX_USART2_UART_Init(); // 初始化串口,用于调试
while(1) {
// 采集数据
float temperature = readTemperature();
float pressure = readPressure();
// 通过 Wi-Fi 模块发送数据
sendDataToCloud(temperature, pressure);
HAL_Delay(1000); // 每秒采集一次数据
}
}
说明:
- 代码中使用 STM32F4 系列单片机的 ADC 进行传感器数据的采集。
readTemperature()
和readPressure()
函数负责从温度传感器和压力传感器读取数据,并进行相应的转换。- 在主循环中,每秒采集一次数据并调用
sendDataToCloud()
函数将数据发送到云平台。
2. MQTT 发送数据代码
以下代码展示如何将采集到的数据通过 MQTT 协议发送到云平台。
import paho.mqtt.client as mqtt
import json
import time
# MQTT 连接设置
broker = "broker.hivemq.com" # MQTT 代理服务器
port = 1883
topic = "factory/sensor/data"
# 连接回调函数
def on_connect(client, userdata, flags, rc):
print("Connected with result code " + str(rc))
# 创建 MQTT 客户端
client = mqtt.Client()
client.on_connect = on_connect
# 连接到 MQTT 代理
client.connect(broker, port, 60)
# 发送数据到云平台
def sendDataToCloud(temperature, pressure):
# 构造数据包
data = {
"temperature": temperature,
"pressure": pressure
}
# 发布数据
client.publish(topic, json.dumps(data))
print("Data sent: ", data)
# 启动 MQTT 客户端
client.loop_start()
# 示例数据发送
while True:
temp = 25.0 # 示例温度
press = 101.3 # 示例压力
sendDataToCloud(temp, press)
time.sleep(5) # 每5秒发送一次数据
说明:
- 使用
paho-mqtt
库实现 MQTT 客户端。 on_connect()
是连接成功后的回调函数。sendDataToCloud()
函数用于构造数据包并将数据发送到指定的 MQTT 主题。- 在示例循环中,每5秒发送一次示例的温度和压力数据。
Web 应用后端代码
搭建后端环境
1. 安装 JDK
首先,需要确保你的计算机上安装了 Java Development Kit (JDK)。可以从 Oracle JDK 官网 下载并安装 JDK 11 或更高版本。安装完成后,可以通过命令行检查安装情况:
java -version
2. 安装 Maven
Maven 是一个项目管理工具,用于构建和管理 Java 项目。可以从 Maven 官网 下载并安装 Maven。安装完成后,检查 Maven 是否安装成功:
mvn -version
3. 创建 Spring Boot 项目
使用 Maven 创建一个新的 Spring Boot 项目。可以使用命令行工具或通过 Spring Initializr 网站(https://start.spring.io/)生成项目。
在命令行中输入以下命令:
mvn archetype:generate -DgroupId=com.example.iot -DartifactId=iot-backend -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
4. 添加依赖
在项目根目录中的 pom.xml
文件中,添加 Spring Boot 和其他必要的依赖项。修改 pom.xml
文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.iot</groupId>
<artifactId>iot-backend</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>11</java.version>
<spring.version>2.5.6</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
5. 创建应用主类
在 src/main/java/com/example/iot
目录下创建一个名为 IoTApplication.java
的文件,作为应用的入口。
package com.example.iot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class IoTApplication {
public static void main(String[] args) {
SpringApplication.run(IoTApplication.class, args);
}
}
创建数据模型
创建一个数据模型类来表示传感器数据。在 src/main/java/com/example/iot
目录下创建一个名为 SensorData.java
的文件。
package com.example.iot;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection = "sensor_data") // MongoDB 集合名
public class SensorData {
@Id
private String id;
private float temperature;
private float pressure;
private long timestamp;
// 构造函数
public SensorData(float temperature, float pressure, long timestamp) {
this.temperature = temperature;
this.pressure = pressure;
this.timestamp = timestamp;
}
// Getter 和 Setter 方法
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
创建数据访问层
创建一个接口用于与 MongoDB 交互。在 src/main/java/com/example/iot
目录下创建一个名为 SensorDataRepository.java
的文件。
package com.example.iot;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface SensorDataRepository extends MongoRepository<SensorData, String> {
List<SensorData> findTop10ByOrderByTimestampDesc(); // 获取最新的10条数据
}
说明:
SensorDataRepository
接口继承自MongoRepository
,提供了 CRUD 操作和自定义查询功能。findTop10ByOrderByTimestampDesc()
方法用于获取最新的 10 条传感器数据。
创建服务层
在服务层中实现业务逻辑。创建一个名为 SensorDataService.java
的文件。
package com.example.iot;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class SensorDataService {
@Autowired
private SensorDataRepository sensorDataRepository;
// 保存传感器数据
public SensorData saveSensorData(SensorData sensorData) {
return sensorDataRepository.save(sensorData);
}
// 获取最新的传感器数据
public List<SensorData> getLatestData() {
return sensorDataRepository.findTop10ByOrderByTimestampDesc();
}
}
说明:
SensorDataService
类负责处理与传感器数据相关的业务逻辑,提供保存和获取数据的方法。
创建控制器层
在控制器层中处理 HTTP 请求。创建一个名为 SensorDataController.java
的文件。
package com.example.iot;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/sensors") // API 路径前缀
public class SensorDataController {
@Autowired
private SensorDataService sensorDataService;
// 接收并保存传感器数据
@PostMapping("/data")
public ResponseEntity<SensorData> postSensorData(@RequestBody SensorData sensorData) {
SensorData savedData = sensorDataService.saveSensorData(sensorData);
return ResponseEntity.ok(savedData);
}
// 获取最新传感器数据
@GetMapping("/latest")
public ResponseEntity<List<SensorData>> getLatestSensorData() {
List<SensorData> latestData = sensorDataService.getLatestData();
return ResponseEntity.ok(latestData);
}
}
说明:
SensorDataController
类处理与传感器相关的 HTTP 请求。postSensorData()
方法接收传感器数据并保存到数据库,使用 POST 请求。getLatestSensorData()
方法获取最新的传感器数据,使用 GET 请求。
配置 MongoDB 连接
在 src/main/resources/application.properties
文件中添加 MongoDB 连接信息:
spring.data.mongodb.uri=mongodb://localhost:27017/iot_db
说明:
- 将
localhost:27017
替换为你的 MongoDB 实例地址。 iot_db
是 MongoDB 中的数据库名称,可以根据需求自定义。
启动应用
在项目根目录下,使用以下命令启动 Spring Boot 应用:
mvn spring-boot:run
测试 API
使用 Postman 或 cURL 测试 API。
1. 保存传感器数据
使用 POST 请求向 http://localhost:8080/api/sensors/data
发送 JSON 数据:
{
"temperature": 25.0,
"pressure": 101.3,
"timestamp": 1625255040000
}
可以使用 Postman 或 cURL 进行请求测试:
使用 Postman:
- 打开 Postman。
- 创建一个新的请求,选择 POST 方法。
- 在请求 URL 中输入
http://localhost:8080/api/sensors/data
。 - 在 Body 选项卡中选择 raw,然后选择 JSON 格式。
- 输入上述 JSON 数据。
- 点击 Send 按钮。
使用 cURL:
可以通过命令行使用以下 cURL 命令:
curl -X POST http://localhost:8080/api/sensors/data -H "Content-Type: application/json" -d '{"temperature": 25.0, "pressure": 101.3, "timestamp": 1625255040000}'
预期结果:
如果数据保存成功,应该返回 200 OK 状态码,并返回保存的传感器数据,包括生成的 ID。
{
"id": "60e6f8c1d5f1a34c8b3a7d9a",
"temperature": 25.0,
"pressure": 101.3,
"timestamp": 1625255040000
}
2. 获取最新传感器数据
使用 GET 请求向 http://localhost:8080/api/sensors/latest
获取最新的传感器数据。
使用 Postman:
- 创建一个新的请求,选择 GET 方法。
- 在请求 URL 中输入
http://localhost:8080/api/sensors/latest
。 - 点击 Send 按钮。
使用 cURL:
可以通过命令行使用以下 cURL 命令:
curl -X GET http://localhost:8080/api/sensors/latest
预期结果:
如果请求成功,应该返回 200 OK 状态码,并返回最新的传感器数据列表。
[
{
"id": "60e6f8c1d5f1a34c8b3a7d9a",
"temperature": 25.0,
"pressure": 101.3,
"timestamp": 1625255040000
},
{
"id": "60e6f8c1d5f1a34c8b3a7d9b",
"temperature": 26.0,
"pressure": 102.0,
"timestamp": 1625255100000
}
]
项目总结
通过本项目,我们实现了一套完整的物联网工厂检测系统,涵盖了数据采集、传输、存储和可视化的各个环节。以下是项目的主要收获和总结:
- 硬件与传感器选择:通过 STM32 单片机和多种传感器的结合,成功实现了对温度、压力等数据的实时采集。
- 数据传输:使用 MQTT 协议,将采集的数据高效地发送到云平台,保证了数据传输的实时性和可靠性。
- 后端开发:通过 Spring Boot 框架创建 RESTful API,实现了数据的存储、检索和管理,提供了良好的扩展性。
- 数据可视化:通过前端开发实现了数据的实时可视化,为用户提供了直观的监控界面,提升了用户体验。
- 云服务应用:利用 MongoDB 存储传感器数据,通过有效的数据管理,便于后续的数据分析和挖掘。