在这里插入图片描述
一、项目概述

项目目标

随着工业自动化和智能化的不断发展,远程监控与巡检系统在工厂、建筑工地和灾后现场等多种场景中得到了广泛应用。本项目旨在设计一种基于智能小车的远程监控与巡检系统。该系统能够通过WiFi传输视频流,允许监控人员实时查看现场情况,同时通过手势控制小车的移动和拍摄角度,提升监测效率和安全性。

主要用途

  • 在工业环境中进行设备巡检与故障排查。

  • 在建筑工地上进行安全监测与进度管理。

  • 在灾后现场评估及救援任务中提供实时视频支持。

技术栈关键词

  • 硬件:STM32微控制器、ESP8266 WiFi模块、USB摄像头、电机驱动模块

  • 软件:Python、OpenCV、Flask、C语言

  • 通信协议:HTTP、TCP/IP

二、系统架构

系统架构概述如下:

硬件设计

  1. 控制核心:选择STM32F4系列微控制器,具有强大的处理能力和丰富的外设接口,适合实时控制任务。

  2. 摄像头:使用USB摄像头进行实时视频采集,支持720p或1080p高清画质。

  3. 无线通信模块:采用ESP8266模块,支持802.11b/g/n WiFi协议,负责与PC端进行数据通信。

  4. 电机控制模块:使用L298N电机驱动模块,能够控制小车的前进、后退、转向等动作。

软件设计

  1. PC端监控软件:基于Python开发,使用OpenCV进行图像处理和手势识别,Flask框架实现Web服务。

  2. 控制逻辑:在STM32上实现接收控制命令并驱动电机的逻辑,确保响应及时。

系统架构图

发送控制命令
控制小车运动
接收视频流
采集视频
WiFi通信
连接
PC端监控软件
STM32控制模块
智能小车
USB摄像头
WiFi模块
互联网

三、环境搭建和注意事项

硬件环境搭建

  • 单片机:准备STM32F4开发板,确保板载的GPIO、UART等接口可用。

  • 摄像头:确保USB摄像头能够与PC端兼容,测试在不同光照条件下的表现。

  • 电机驱动:连接L298N与电机,确保电源适配,避免电流过大导致模块损坏。

软件环境搭建

  • PC端环境:

  • Python 3.x

  • 安装OpenCV库:pip install opencv-python

  • 安装Flask库:pip install Flask

  • STM32环境:

  • 安装STM32CubeIDE或Keil进行开发和调试。

注意事项

  • 电源管理:确保电源模块能够为所有组件提供稳定的电压和电流。

  • 通信测试:在开发过程中,定期进行WiFi通信测试,检查信号强度和延迟问题。

  • 光照条件:在进行手势识别和视频监控时,尽量在光照充足的环境下工作,以提高识别准确性。

四、代码实现过程

代码实现过程分为两个主要部分:PC端监控软件和STM32控制程序。我们将详细介绍每个模块的实现步骤、代码逻辑和时序图。

1. PC端监控软件

PC端监控软件的主要职责是视频流捕获、手势识别和控制指令的发送。我们将使用Python和OpenCV来实现这些功能。

1.1 视频流捕获与显示模块

该模块负责从USB摄像头获取实时视频流,并在窗口中显示。

代码实现:

import cv2

def start_video_stream():
    cap = cv2.VideoCapture(0)  # 0表示默认摄像头
    if not cap.isOpened():
        print("Error: Could not open video stream.")
        return
        
    while True:
        ret, frame = cap.read()
        if not ret:
            print("Error: Could not read frame.")
            break
        
        # 显示视频流
        cv2.imshow('Video Stream', frame)
        
        # 按 'q' 键退出
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
            
    cap.release()
    cv2.destroyAllWindows()

if __name__ == "__main__":
    start_video_stream()

流程介绍:

  • 打开摄像头:使用cv2.VideoCapture(0)打开默认摄像头。

  • 循环读取帧:在while循环中使用cap.read()读取每一帧。

  • 显示帧:使用cv2.imshow()显示当前帧。

  • 退出条件:按下q键退出视频流。

1.2 手势识别模块

该模块通过图像处理识别特定的手势,并返回相应的控制命令。我们将使用OpenCV的图像处理功能进行手势识别。

代码实现:

import cv2
import numpy as np

def detect_gesture(frame):
    # 转换为灰度图
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    
    # 高斯模糊去噪
    blur = cv2.GaussianBlur(gray, (15, 15), 0)
    
    # 阈值化处理
    _, thresh = cv2.threshold(blur, 100, 255, cv2.THRESH_BINARY_INV)
    
    # 轮廓检测
    contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    
    if contours:
        # 找到最大轮廓
        max_contour = max(contours, key=cv2.contourArea)
        if cv2.contourArea(max_contour) > 500:  # 设定最小面积阈值
            # 识别手势逻辑
            # TODO: 根据轮廓的形状或面积判断手势
            return "FORWARD"  # 示例:返回前进命令
        
    return "STOP"

流程介绍:

  • 图像预处理:

  • 将输入帧转换为灰度图像,减少计算复杂度。

  • 使用高斯模糊去噪,减少噪声对轮廓检测的影响。

  • 阈值化:对模糊图像进行阈值化处理,将手势与背景分离。

  • 轮廓检测:使用cv2.findContours方法查找图像中的轮廓。

  • 手势判断:根据最大轮廓面积判断是否为有效手势,并返回相应的控制命令。

1.3 控制命令发送模块

该模块将识别到的手势转换为控制指令,并通过HTTP POST请求发送给STM32控制模块。

代码实现:

import requests

def send_command_to_car(command):
    url = "http://<STM32_IP_ADDRESS>/control"  # 替换为STM32的实际IP地址
    try:
        response = requests.post(url, json={'command': command})
        if response.status_code == 200:
            print(f"Command '{command}' sent successfully!")
        else:
            print("Error sending command:", response.status_code)
    except Exception as e:
        print("Exception occurred:", e)

if __name__ == "__main__":
    cap = cv2.VideoCapture(0)
    if not cap.isOpened():
        print("Error: Could not open video stream.")
        exit()

    while True:
        ret, frame = cap.read()
        if not ret:
            print("Error: Could not read frame.")
            break
        
        gesture = detect_gesture(frame)  # 检测手势
        send_command_to_car(gesture)      # 发送控制命令

        cv2.imshow('Video Stream', frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    cap.release()
    cv2.destroyAllWindows()

流程介绍:

  • 在主程序中,启动摄像头并进入主循环。

  • 每次读取一帧视频流后,调用detect_gesture(frame)函数识别手势。

  • 根据识别结果调用send_command_to_car(gesture)函数将命令发送给STM32。

  • 如果按下q键,则退出循环和释放资源。

2. STM32控制程序

STM32控制程序的职责是接收来自PC端的控制命令,解析命令并驱动电机控制小车的运动。

2.1 初始化设置

在STM32中,我们需要初始化GPIO、WiFi模块以及串口通信。

代码实现:

#include "stm32f4xx_hal.h"
#include "string.h"

UART_HandleTypeDef huart2; // 通过USART2进行WiFi通信

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);

// 电机控制函数
void move_forward() {
    // 控制电机前进的逻辑
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET); // 假设PA1控制电机前进
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET); // 假设PA2控制电机反向
}

void move_backward() {
    // 控制电机后退的逻辑
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);
}

void stop_movement() {
    // 停止电机
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);
}

// 控制命令解析函数
void parse_command(char* command) {
    if (strcmp(command, "FORWARD") == 0) {
        move_forward();
    } else if (strcmp(command, "BACKWARD") == 0) {
        move_backward();
    } else {
        stop_movement();
    }
}

int main(void) {
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_USART2_UART_Init();

    char command[20];

    // 主循环
    while (1) {
        // 读取命令
        if (HAL_UART_Receive(&huart2, (uint8_t*)command, sizeof(command), HAL_MAX_DELAY) == HAL_OK) {
            command[strcspn(command, "\r\n")] = 0; // 去除换行符
            parse_command(command); // 解析并执行命令
        }
    }
}

// USART2初始化
static void MX_USART2_UART_Init(void) {
    huart2.Instance = USART2;
    huart2.Init.BaudRate = 115200;  // 设置波特率
    huart2.Init.WordLength = UART_WORDLENGTH_8B;  // 数据位长度
    huart2.Init.StopBits = UART_STOPBITS_1;  // 停止位
    huart2.Init.Parity = UART_PARITY_NONE;  // 无奇偶校验
    huart2.Init.Mode = UART_MODE_TX_RX;  // 收发模式
    huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;  // 无硬件流控
    huart2.Init.OverSampling = UART_OVERSAMPLING_16;  // 过采样设置

    if (HAL_UART_Init(&huart2) != HAL_OK) {
        Error_Handler();  // 初始化失败时的处理
    }
}

// GPIO初始化
static void MX_GPIO_Init(void) {
    __HAL_RCC_GPIOA_CLK_ENABLE();  // 使能GPIOA时钟
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    // 配置电机控制引脚
    GPIO_InitStruct.Pin = GPIO_PIN_1 | GPIO_PIN_2;  // 假设PA1和PA2用于电机控制
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;  // 推挽输出
    GPIO_InitStruct.Pull = GPIO_NOPULL;  // 不使用上拉或下拉
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;  // 低速
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);  // 初始化GPIO
}

流程介绍:

  • USART初始化:配置USART的波特率、数据位、停止位和工作模式,以确保能够接收和发送数据。

  • GPIO初始化:配置用于电机控制的GPIO引脚为推挽输出模式。

2.2 主循环与命令处理

在主循环中,STM32将持续监测是否有新的命令到来,并根据收到的命令执行相应的动作。

完整代码实现:

int main(void) {
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_USART2_UART_Init();

    char command[20];  // 用于存储接收到的命令

    // 主循环
    while (1) {
        // 读取命令
        if (HAL_UART_Receive(&huart2, (uint8_t*)command, sizeof(command), HAL_MAX_DELAY) == HAL_OK) {
            command[strcspn(command, "\r\n")] = 0; // 去除换行符
            parse_command(command); // 解析并执行命令
        }
    }
}

// 错误处理函数
void Error_Handler(void) {
    // 用户可以添加自己的错误处理代码
    while (1) {
        // 在此处可以添加LED闪烁或其他错误指示
    }
}

流程介绍:

  • 主循环:在while (1)循环中,STM32使用HAL_UART_Receive函数接收命令。

  • 命令解析:接收到命令后,去除换行符并调用parse_command函数解析命令,执行相应的电机控制函数。

  • 错误处理:如果USART初始化失败,则调用Error_Handler()进行错误处理。

3. 系统运行流程

系统的整体运行流程如下:

  1. PC端监控软件启动:用户启动PC端监控软件,打开摄像头并开始捕获视频流。

  2. 实时手势识别:通过detect_gesture函数识别用户的手势,并根据手势类型生成对应的控制命令(例如:“FORWARD”、“BACKWARD”、“STOP”)。

  3. 发送控制命令:将识别到的命令通过HTTP POST请求发送至STM32控制模块。

  4. STM32接收命令:STM32在主循环中持续监听USART,接收到控制命令后解析并执行相应的电机控制操作。

  5. 小车运动控制:根据接收到的命令,小车执行前进、后退或停止的操作。STM32控制模块通过GPIO信号控制电机驱动模块,从而实现小车的移动。

  6. 实时视频监控:PC端监控软件持续接收视频流,监控人员可以在PC屏幕上实时查看小车所在环境的状态,确保监控效果。

  7. 反馈与调整:监控人员可以根据实时视频流调整手势或直接发送新的控制命令,以优化小车的移动路径或重新进行巡检。

4. 时序图

以下是系统交互的时序图,展示了PC端监控软件与STM32控制模块之间的交互流程。

PC端监控软件 STM32控制模块 USB摄像头 请求视频流 传输视频流 处理视频流 识别手势 发送控制命令 接收命令 解析命令 控制电机移动 确认命令执行 请求更新视频流 传输更新的视频流 更新显示 PC端监控软件 STM32控制模块 USB摄像头

5. 项目总结

在本项目中,我们成功设计并实现了一个基于智能小车的远程监控与巡检系统。该系统利用WiFi技术实现了视频流的传输和手势控制,具有以下几个主要功能:

  • 实时视频监控:通过USB摄像头采集的视频流,监控人员可以实时查看现场情况。

  • 手势控制:使用OpenCV进行手势识别,监控人员通过简单的手势即可控制小车的移动和方向。

  • 数据传输:通过WiFi模块,实现了PC与STM32之间的高效数据传输。

Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐