• 【毕业设计】基于STM32的自动加油站加油系统 -物联网 单片机 嵌入式



    0 前言

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。

    为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是

    🚩 基于STM32的自动加油站加油系统

    🥇学长这里给一个题目综合评分(每项满分5分)

    • 难度系数:3分
    • 工作量:4分
    • 创新点:4分

    🧿 选题指导, 项目分享:

    https://gitee.com/dancheng-senior/project-sharing-1/blob/master/%E6%AF%95%E8%AE%BE%E6%8C%87%E5%AF%BC/README.md


    1 简介

    自主视觉无人加油站物联网系统,可自动识别油箱口,移动油管加油


    2 主要器件

    以STM32F103RCT6为主控MCU,HK32F103C8T6为协处理MCU,搭载OpenMV3视觉识别模块、乐鑫WIFI模组、SIM800C(GSM)、TTS语音芯片、机智云物联网平台等特色设备。
    系统方案框架在这里插入图片描述


    3 实现效果

    项目实物图如下:
    在这里插入图片描述
    具体功能

    • 建立汽车油箱口识别算法模型,通过机器视觉识别算法正确解析获取油箱口的相对坐标位置并联动机械臂进行准确定位。
    • 设备接入机智云物联网服务器,通过移动便携设备下载机智云客户端程序,即可选择相应的加油套餐和获取当前加油信息。
    • 实现加油站园区上位机端管理软件,通过上位机管理软件可对园区内的自主加油枪设备进行统一管理以及获取园区内设备的实时信息。
    • 友好的人机交互设备,从视觉和语音方面让用户和管理人员实时了解设备的当前运行状态。
    • 主动安全报警设备,实时监测园区内的燃油挥发情况以及火情检测,做到第一时间紧急事件报警处理。

    4 设计原理

    4.1 硬件部分

    以STM32F103RCT6为主控芯片,HK32F103C8T6为协处理芯片,两个控制器主要负责与所有功能模块进行通信以及数据交互。通过采集OpenMV3特征检测数据及图像特征值,并通过BP神经网络训练方法提高油箱口识别准确度;配置乐鑫WIFI模组连接机智云物联网平台,在机智云平台上创建设备的数据节点,实现机智云数据的解析与封包、传感器数据与通信数据的转换逻辑;处理手机端App用户控制端、上位机管理端以及各功能模块的数据交互。

    OpenMV3机器视觉识别模块主要采用特征检测(find_keypoint),先将目标物的特征值保存在KPTS1中,匹配出目标特征的多种比例大小和角度。利用AGAST特征点检测采取的算法与最开始的目标特征值进行匹配,将特征值作为BP神经网络的输入,利用神经网络的不断迭代训练输出最终参数,能大大提高识别准确度。

    通过乐鑫公司的ESP8266(WiFi)模块实现机智云平台的对接,快速实现硬件智能化。通过机智云提供的智能云平台、手机APP、联网模块的整套解决方案,为该产品分配Product Key和Product Secret参数。Product Key参数由开发者写入设备MCU(设备主控板),并告知WiFi模块,WiFi模块登录机智云后,机智云将会识别该Product Key的产品,Product Secret参数是APP开发或服务器对接时所使用的参数。
    机智云物联网平台结构图
    在这里插入图片描述
    项目原理图
    在这里插入图片描述

    4.2 软件部分

    首先对STM32F103芯片和HK32F103芯片进行初始化,再对OpenMV3摄像头识别模块、SIM800C(GSM)模块、乐鑫WIFI机智云物联网模块、TTS语音合成模块等进行初始化和配置。各设备初始化完成之后,系统进入正常工作模式。

    1. 判断是否进行油箱口视觉模型训练,如果选择对油箱口进行识别模型训练,则OpenMV3提取油箱口特征值进行BP神经网络模型训练;否则等待加油指令。
    2. 当系统接收到加油指令时,判断加油枪是否已准确定位至油箱口,如果还未定位成功则继续进行视觉定位和姿态调整;如果定位完成则启动加油。
    3. 已启动加油时,通过中断将当前加油信息通过机智云WIFI模组上传云端。设备通过GAgent协议与云端握手,并在云端上创建数据节点。将设备运行信息实时上传机智云服务器,用户可通过手机App以及上位机端获取设备实时运行信息。
    4. 判断所加油量是否和用户所选择加油套餐相匹配,若相匹配则本次加油操作完成,若未达到加油量则继续执行加油操作。具体系统软件流程图如图所示。

    在这里插入图片描述
    设备接入机智云物联网平台,STM32F103通过串口与GAgent模组固件与云端通信,通过在云端上创建设备和数据节点,实现底层的设备运行信息上传机智云物联网服务器,并可通过移动便携式设备登录机智云平台,获取设备实时运行信息。
    在这里插入图片描述


    5 部分实现代码

    OpenMV3摄像头识别模块
    判断是否进行油箱口视觉模型训练,如果选择对油箱口进行识别模型训练,则OpenMV3提取油箱口特征值进行BP神经网络模型训练;否则等待加油指令。
    视觉部分用AGAST算法进行特征提取,并且进行目标追踪。提取最开始的图像模型作为目标物体特征,KPTS1保存目标物体的特征,默认会匹配目标特征的多种比例大小。将待识别目标物放置摄像头中央识别,识别过程中出现特征角点,证明已识别记录目标特征。

    AGAST相关代码

    #include 
    #include 
    using namespace std;
    using namespace cv;
    
    int main()
    {
        Mat srcImage = imread("D:/sunflower.png");
            Mat srcGrayImage;
            if (srcImage.channels() == 3)
            {
                cvtColor(srcImage,srcGrayImage,CV_RGB2GRAY);
            }
            else
            {
                srcImage.copyTo(srcGrayImage);
            }
            vector<KeyPoint>detectKeyPoint;
            Mat keyPointImage;
    
            Ptr<AgastFeatureDetector> agast = AgastFeatureDetector::create();
            agast->detect(srcGrayImage,detectKeyPoint);
            drawKeypoints(srcImage,detectKeyPoint,keyPointImage,Scalar(0,0,255),DrawMatchesFlags::DEFAULT);
    
            imshow("src image",srcImage);
            imshow("keyPoint",keyPointImage);
    
            waitKey(0);
            return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    乐鑫wifi模块

    相关SDK
    在这里插入图片描述
    部分代码

    #include 
    #include 
    #include "esp_log.h"
    #include "esp_console.h"
    #include "argtable3/argtable3.h"
    #include "cmd_decl.h"
    #include "freertos/FreeRTOS.h"
    #include "freertos/event_groups.h"
    #include "esp_wifi.h"
    #include "tcpip_adapter.h"
    #include "esp_event_loop.h"
    #include "cmd_wifi.h"
    
    static EventGroupHandle_t wifi_event_group;
    const int CONNECTED_BIT = BIT0;
    
    static esp_err_t event_handler(void *ctx, system_event_t *event)
    {
        /* For accessing reason codes in case of disconnection */
        system_event_info_t *info = &event->event_info;
    
        switch(event->event_id) {
        case SYSTEM_EVENT_STA_GOT_IP:
            xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
            break;
        case SYSTEM_EVENT_STA_DISCONNECTED:
            ESP_LOGI(__func__, "Disconnect reason : %d", info->disconnected.reason);
            if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) {
                /*Switch to 802.11 bgn mode */
                esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N);
            }
            esp_wifi_connect();
            xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
            break;
        default:
            break;
        }
        return ESP_OK;
    }
    
    static void initialise_wifi(void)
    {
        esp_log_level_set("wifi", ESP_LOG_WARN);
        static bool initialized = false;
        if (initialized) {
            return;
        }
        tcpip_adapter_init();
        wifi_event_group = xEventGroupCreate();
        ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
        wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
        ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
        ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
        ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_NULL) );
        ESP_ERROR_CHECK( esp_wifi_start() );
        initialized = true;
    }
    
    static bool wifi_join(const char* ssid, const char* pass, int timeout_ms)
    {
        initialise_wifi();
        wifi_config_t wifi_config = { 0 };
        strncpy((char*) wifi_config.sta.ssid, ssid, sizeof(wifi_config.sta.ssid));
        if (pass) {
            strncpy((char*) wifi_config.sta.password, pass, sizeof(wifi_config.sta.password));
        }
    
        ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
        ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );
        ESP_ERROR_CHECK( esp_wifi_connect() );
    
        int bits = xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
                1, 1, timeout_ms / portTICK_PERIOD_MS);
        return (bits & CONNECTED_BIT) != 0;
    }
    
    /** Arguments used by 'join' function */
    static struct {
        struct arg_int *timeout;
        struct arg_str *ssid;
        struct arg_str *password;
        struct arg_end *end;
    } join_args;
    
    static int connect(int argc, char** argv)
    {
        int nerrors = arg_parse(argc, argv, (void**) &join_args);
        if (nerrors != 0) {
            arg_print_errors(stderr, join_args.end, argv[0]);
            return 1;
        }
        ESP_LOGI(__func__, "Connecting to '%s'",
                join_args.ssid->sval[0]);
    
        bool connected = wifi_join(join_args.ssid->sval[0],
                               join_args.password->sval[0],
                               join_args.timeout->ival[0]);
        if (!connected) {
            ESP_LOGW(__func__, "Connection timed out");
            return 1;
        }
        ESP_LOGI(__func__, "Connected");
        return 0;
    }
    
    void register_wifi()
    {
        join_args.timeout = arg_int0(NULL, "timeout", "", "Connection timeout, ms");
        join_args.timeout->ival[0] = 5000; // set default value
        join_args.ssid = arg_str1(NULL, NULL, "", "SSID of AP");
        join_args.password = arg_str0(NULL, NULL, "", "PSK of AP");
        join_args.end = arg_end(2);
    
        const esp_console_cmd_t join_cmd = {
            .command = "join",
            .help = "Join WiFi AP as a station",
            .hint = NULL,
            .func = &connect,
            .argtable = &join_args
        };
    
        ESP_ERROR_CHECK( esp_console_cmd_register(&join_cmd) );
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124

    6 最后

  • 相关阅读:
    vue3中的route和router
    企业级智能PDF及文档处理SDK GdPicture.NET 14.2 Crack
    MySQL半同步复制源码解析
    Black Friday案例分析
    整理SpringBoot整合MyBatisPlus+Dubbo问题解决方法
    深度强化学习 第 5 章 SARSA 算法
    micro-app 研究-提前准备
    安装Anaconda之后cmd打不开
    【NLP】第 4 章:文本预处理、词干提取和词形还原
    七夕,你来人间一趟,总要谈一场轰轰烈烈的恋爱
  • 原文地址:https://blog.csdn.net/m0_71572576/article/details/126197130