🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。
为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是
🚩 基于STM32的自动加油站加油系统
🥇学长这里给一个题目综合评分(每项满分5分)
🧿 选题指导, 项目分享:
自主视觉无人加油站物联网系统,可自动识别油箱口,移动油管加油
以STM32F103RCT6为主控MCU,HK32F103C8T6为协处理MCU,搭载OpenMV3视觉识别模块、乐鑫WIFI模组、SIM800C(GSM)、TTS语音芯片、机智云物联网平台等特色设备。
系统方案框架
项目实物图如下:
具体功能
以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开发或服务器对接时所使用的参数。
机智云物联网平台结构图
项目原理图
首先对STM32F103芯片和HK32F103芯片进行初始化,再对OpenMV3摄像头识别模块、SIM800C(GSM)模块、乐鑫WIFI机智云物联网模块、TTS语音合成模块等进行初始化和配置。各设备初始化完成之后,系统进入正常工作模式。
设备接入机智云物联网平台,STM32F103通过串口与GAgent模组固件与云端通信,通过在云端上创建设备和数据节点,实现底层的设备运行信息上传机智云物联网服务器,并可通过移动便携式设备登录机智云平台,获取设备实时运行信息。
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;
}
乐鑫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) );
}