stm32智能颜色送餐小车(openmv二维码识别+颜色识别+oled显示)

news2025/2/27 1:54:29

大家好啊,我是情谊,今天我们来介绍一下我最近设计的stm32产品,我们在今年七月份的时候参加了光电设计大赛,我们小队使用的就是stm32的智能送餐小车,虽然止步于省赛,但是还是一次成长的经验吧,那么我也来分享一下我们小队这次的产品设计,希望里面的一些模块可以给你们一点的参考建议。

我先说说我的博客文章的设计吧,我准备的是以模块的方式展示代码,但是文章的最后我会附带我们小队设计的stm32小车的完整代码

接下来我再说说我的小车实现的功能:

1二维码识别,使用openmv扫描对应颜色的二维码后,oled屏幕上显示对应的菜品名称,并且小车识别追踪该颜色物体

2压力传感器感知物体重量,当压力传感器的重量超过一定值后小车才会运动,注意!这个功能和上面的二维码识别并不冲突,上面扫码后openmv只能识别到该颜色,但是小车却不能动,只有压力传感器有示数才会运动

3APP点单,我们小组是使用ESP8266wifi模块制作了一个APP来模拟点单

4温度传感器时刻感知环境温度,这个模块的功能其实就是在送餐途中进行保温使用的

5蜂鸣器播报,客户下单后蜂鸣器会进行鸣叫

6红外光管避障,我们小组并未在避障方面进行过多的功能,所以只有简单的避障功能:小车识别到前方有物体,然后停下来,等到前方没有物体后继续运动

以上就是我的产品的全部功能了

注意注意!!!

我文章末尾上传的代码只有功能1和功能2和功能6的代码,功能3我只能负责给你们说说怎么做,如果实在需要代码,请联系我,这部分代码不是免费的,功能4和功能5的代码不在我的电脑上,所以我就不进行讲解了。

器件端

首先声明一下

本次实验的芯片是基于stm32c8t6

本次实验使用的openmv型号为openmvH7

OpenMV开发环境搭建

OpenMV IDE是用于OpenMV Cam的集成开发环境,具有强大的文本编辑器,调试终端和带有直方图显示的帧缓冲区查看器。

官方下载链接:Download – OpenMV,截至本文写作时间,最新版本为v4.2.1。

本次实验接口为串口三

代码端 

openmv

import sensor, image, time
from pyb import UART
from pyb import LED

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time=2000)

# 初始化LED灯
led_red = LED(1)
led_green = LED(2)
led_blue = LED(3)

# 初始化UART
uart = UART(3, 9600)

clock = time.clock()

last_qr_color = None

while True:
    clock.tick()
    img = sensor.snapshot()

    # 寻找二维码
    qr_codes = img.find_qrcodes()

    if qr_codes:
        # 获取第一个二维码的颜色信息
        qr_color = qr_codes[0].payload()
        last_qr_color = qr_color
        blobs = None

        if qr_color == "green":
            # 绿色物体识别
            green_threshold = (0, 100, -12, 11, -108, 34)
            blobs = img.find_blobs([green_threshold], pixels_threshold=100, area_threshold=100, merge=True)
            led_green.on()
            led_red.off()
            led_blue.off()

        elif qr_color == "red":
            # 红色物体识别
            red_threshold = (0, 80, 30, 127, 30, 127)
            blobs = img.find_blobs([red_threshold], pixels_threshold=100, area_threshold=100, merge=True)
            led_green.off()
            led_red.on()
            led_blue.off()

        else:
            # 其他颜色处理
            blobs = None
            led_green.off()
            led_red.off()
            led_blue.off()

    else:
        # 如果没有检测到二维码,则继续识别上次记录的颜色
        qr_color = last_qr_color
        blobs = None

        if qr_color == "green":
            # 绿色物体识别
            green_threshold = (30, 100, -64, -8, -32, 32)
            blobs = img.find_blobs([green_threshold], pixels_threshold=100, area_threshold=100, merge=True)
            led_green.on()
            led_red.off()
            led_blue.off()

        elif qr_color == "red":
            # 红色物体识别
            red_threshold = (0, 80, 30, 127, 30, 127)
            blobs = img.find_blobs([red_threshold], pixels_threshold=100, area_threshold=100, merge=True)
            led_green.off()
            led_red.on()
            led_blue.off()

        else:
            # 其他颜色处理
            blobs = None
            led_green.off()
            led_red.off()
            led_blue.off()

    if blobs:
        for blob in blobs:
            img.draw_rectangle(blob.rect())
            img.draw_cross(blob.cx(), blob.cy())
            area = blob.w() * blob.h()
            # 根据颜色修改 area & 0xff 的值
            if qr_color == "green":
                area_low_byte = 0x02
            elif qr_color == "red":
                area_low_byte = 0x01
            data_packet = bytearray([0xb3, 0xb3, blob.cx(), blob.cy(), area >> 8, area_low_byte, 0x5b])
            uart.write(data_packet)
            print("颜色: %s x:%d y:%d 面积:%d" % (qr_color, blob.cx(), blob.cy(), area))

    print(clock.fps())

代码讲解:上面的openmv端代码可以识别信息为“红色”二维码与“绿色”二维码,下面为你们粘贴了二维码图,识别到一个二维码后,openmv转变为识别对应颜色,向单片机发送4个数据,但是有用的只有三个数据,你们可以根据需要删除不需要数据。

红色二维码

绿色二维码 

大家可以使用上面的二维码进行实验,也可以修改二维码和openmv识别信息 

接下来在stm32端接受openmv发送的信息

Serial.c

#include "stm32f10x.h"                  
#include <stdio.h>
#include <stdarg.h>

int openmv[7];
int16_t Num;          
int16_t theta;          
int16_t rho;
int16_t yanse;
int i;


void Usart3_Init(uint32_t Bound)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOB,&GPIO_InitStructure);

	
	USART_InitTypeDef USART_InitStructure;
	USART_InitStructure.USART_BaudRate = Bound;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
	USART_Init(USART3,&USART_InitStructure);
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);
	USART_Cmd(USART3,ENABLE);
}

void Openmv_Data(void)
{
    Num=openmv[2];
    rho=openmv[3];
	theta =openmv[4];
	yanse = openmv[5];
}
 
void Openmv_Receive_Data(int16_t data)
{
	static u8 state = 0;
	if(state==0&&data==0xb3)
	{
		state=1;
		openmv[0]=data;
	}
	else if(state==1&&data==0xb3)
	{
		state=2;
		openmv[1]=data;
	}
	else if(state==2)
	{
		state=3;
		openmv[2]=data;
	}
	else if(state==3)
	{
		state = 4;
		openmv[3]=data;
	}
  else if(state==4)
	{
		state = 5;
		openmv[4]=data;
	} 
	 else if(state==5)
	{
		state = 6;
		openmv[5]=data;
	} 
	else if(state==6)		
	{
        if(data == 0x5B)
        {
            state = 0;
            openmv[6]=data;
            Openmv_Data();
        }
        else if(data != 0x5B)
        {
            state = 0;
            for(i=0;i<7;i++)
            {
                openmv[i]=0x00;
            }           
        }
	}    
	else
		{
			state = 0;
            for(i=0;i<7;i++)
            {
                openmv[i]=0x00;
            }
		}
}


void USART_SendByte(USART_TypeDef* USARTx, char  str)
{
 
		USART_SendData(USARTx, str);
 
		while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
 
	
 
}



void USART3_IRQHandler(void)                	
	{
	u8 com_data;
#if SYSTEM_SUPPORT_OS 		
	OSIntEnter();    
#endif
	if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) 
		{
			USART_ClearFlag(USART3,USART_FLAG_RXNE);
      com_data = USART3->DR;
			Openmv_Receive_Data(com_data);    
			Openmv_Data();		                	
 		
     } 
#if SYSTEM_SUPPORT_OS 	
	OSIntExit();  											 
#endif
} 
	

上面由于代码注释出现乱码问题,所以笔者还是建议从下方的链接处查看

Serial.h

#ifndef __SERIAL_H
#define __SERIAL_H

#include <stdio.h>
#include "sys.h"
#include "stm32f10x.h"                  




void Usart3_Init(uint32_t Bound);
#endif

main.c

#include "stm32f10x.h"                 
#include "delay.h"
#include "OLED.h"
#include "Serial.h"
#include "sys.h"              
#include "stdio.h"
#include "HX711.h"
#include "encoder.h"
extern int16_t Num;     //x     
extern int16_t theta;     //size     
extern int16_t rho;				//y
extern int16_t yanse;	

static int16_t img_width=160;     //cx
static int16_t img_high=120;      //cy
static int16_t img_size=1000;      //size
//50 32 32055
static uint8_t KeyNum;
void OLED_SHOW(void)
{  
	if (yanse == 0x01)
		option = 1;
	if (yanse == 0x02)
		option = 2;
	 
	 	OLED_Refresh_Gram(); 

    if (option == 1)
    {

		OLED_ShowChinese(0,0,4,16,1); 
		OLED_ShowChinese(16,0,5,16,1); 
		OLED_ShowChinese(32,0,6,16,1); 
    }
    else if (option == 2)
    {
		OLED_ShowChinese(0,0,7,16,1); 
		OLED_ShowChinese(16,0,8,16,1); 
		OLED_ShowChinese(32,0,9,16,1); 

    }
	
}

int main(void)
{
	
	
	delay_init(72);         
	LED_Init();                    
	LED=0; 
    0KEY_Init();
	Usart3_Init(9600);          
	OLED_Init();
	KeyNum = Key_GetNum();
	while (1)
	 {
			Led_Flash(50);
			OLED_SHOW();
		
    }
}

oled端的代码我就不在进行书写,大家可以参照我的另一篇文章里讲解了https://mp.csdn.net/mp_blog/creation/editor/141165560

好了,以上就是openmv二维码识别+颜色识别+oled显示的全部代码了,如果有什么问题,欢迎各位在评论区留言,本人看到一定会回消息的,还有一个问题,代码本身是由程序中截取出来的所以可能会出现部分代码出现错误,所以还是建议根据下方提供的链接查源代码,明天我会更新stm32智能颜色送餐小车(红外光管避障)如果本文章对你有用的话,请给一个小小的赞呗,你的赞就是对我的最大的鼓励!谢谢大家!

代码链接处:链接:链接: https://pan.baidu.com/s/1buk_I9_bZ_rIou1iW9v1jA?pwd=2180 提取码: 2180

最后一个需要注意以下,本代码中的pid参数我全部都置零了,请根据自己的小车进行调节!

mmexport1723541008067

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2040791.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度学习基础之反向传播算法

目录 原理与过程 1. 前向传播&#xff08;Forward Pass&#xff09; 2. 计算误差&#xff08;Error Calculation&#xff09; 3. 反向传播&#xff08;Backpropagation&#xff09; 4. 参数更新&#xff08;Parameter Update&#xff09; 应用与实例 总结 反向传播算法…

1秒出图,全球最快的开源Stable Diffusion出炉

前言 OneFlow 将 Stable Diffusion 的推理性能推向了一个全新的 SOTA。 第一辆汽车诞生之初&#xff0c;时速只有 16 公里&#xff0c;甚至不如马车跑得快&#xff0c;很长一段时间&#xff0c;汽车尴尬地像一种“很酷的玩具”。人工智能作图的出现也是如此。 AI 作图一开始的…

大数据面试SQL(八):求连续段的起始位置和结束位置

文章目录 求连续段的起始位置和结束位置 一、题目 二、分析 三、SQL实战 四、样例数据参考 求连续段的起始位置和结束位置 一、题目 有一张表t2_id记录了id&#xff0c;id不重复&#xff0c;但是会存在间断&#xff0c;求出连续段的起始位置和结束位置。 样例数据&…

两个若依系统,不能同时登录问题解决方案

原因&#xff1a; 问题根源在于两个独立的系统&#xff08;A系统与B系统&#xff09;共享了同一cookie键名来存储各自用户的认证令牌&#xff08;token&#xff09;。这种设计导致了以下情形&#xff1a; 当用户在A系统登录后&#xff0c;一个token被存储在cookie中&#xff0…

【LeetCode每日一题】——623.在二叉树中增加一行

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时间频度】九【代码实现】十【提交结果】 一【题目类别】 广度优先遍历 二【题目难度】 中等 三【题目编号】 623.在二叉树中增加一行 四【题目描述】…

c语言学习,memset()函数分析

1&#xff1a;memset() 函数说明&#xff1a; 将字符c&#xff08;unsigned char&#xff09;复制到str字符串的前n个字符 2&#xff1a;函数原型&#xff1a; void * memset(void * str,int c,size_t n) 3&#xff1a;函数参数&#xff1a; 参数str要填充的指针,c 要设置的值…

2024下半年EI学术会议一览表

2024下半年将举办多个重要的EI学术会议&#xff0c;涵盖了从机器视觉、图像处理与影像技术到感知技术、绿色通信、计算机、大数据与人工智能等多个领域。 2024下半年EI学术会议一览表 第二届机器视觉、图像处理与影像技术国际会议&#xff08;MVIPIT 2024&#xff09;将于2024…

threejs webgl效果 功能特效

雷达效果 ​飘扬的红旗 光柱效果 OD线 下雪 下雨 光墙效果 能源球 烟火效果 threejs烟花效果 光圈效果 threejs 光圈 波动 function initScene() {scene new THREE.Scene();}function initCamera() {camera new THREE.PerspectiveCamera(45, window.innerWidth / window.inne…

培训学校课程管理系统-计算机毕设Java|springboot实战项目

&#x1f34a;作者&#xff1a;计算机毕设残哥 &#x1f34a;简介&#xff1a;毕业后就一直专业从事计算机软件程序开发&#xff0c;至今也有8年工作经验。擅长Java、Python、微信小程序、安卓、大数据、PHP、.NET|C#、Golang等。 擅长&#xff1a;按照需求定制化开发项目、 源…

MiniCPM-V 2.6 面壁“小钢炮”,多图、视频理解多模态模型,部署和推理实战教程

MiniCPM-V 2.6是清华和面壁智能最新发布的多模态模型&#xff0c;亦称面壁“小钢炮”&#xff0c;它是 MiniCPM-V 系列中最新、性能最佳的模型。该模型基于 SigLip-400M 和 Qwen2-7B 构建&#xff0c;仅 8B 参数&#xff0c;但却取得 20B 以下单图、多图、视频理解 3 SOTA 成绩…

leetcode300. 最长递增子序列,动态规划附状态转移方程

leetcode300. 最长递增子序列 给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而不改变其余元素的顺序。例如&#xff0c;[3,6,2,7] 是数组 [0,3,1,6,2,2…

【扩散模型(七)】Stable Diffusion 3 diffusers 源码详解2 - DiT 与 MMDiT 相关代码(上)

系列文章目录 【扩散模型&#xff08;一&#xff09;】中介绍了 Stable Diffusion 可以被理解为重建分支&#xff08;reconstruction branch&#xff09;和条件分支&#xff08;condition branch&#xff09;【扩散模型&#xff08;二&#xff09;】IP-Adapter 从条件分支的视…

“从零开始的HTML 表格”——WEB开发系列09

HTML 表格是一种用于在网页上组织和显示信息的结构性元素&#xff0c;它能够将数据以行和列的形式呈现&#xff0c;帮助用户更清晰地理解数据关系。表格在展示统计数据、产品列表、日程安排等方面非常实用。 一、HTML 表格的基本结构 HTML 表格用 ​​<table>​​ 标签来…

创意无限!2024年热门视频剪辑软件精选

从专业级电影剪辑工具到简单易用的手机APP&#xff0c;再到集创意与高效于一身的桌面应用&#xff0c;各类剪辑软件如雨后春笋般涌现。本文将带你一窥2024年火热的剪辑视频的软件。 1.福昕视频剪辑 连接直达>>https://www.pdf365.cn/foxit-clip/ 这款视频编辑工具凭…

Oracle 12.2集群搭建遇到ORA-ORA-15227,ORA-15031,ORA-15018问题处理

报错&#xff1a; [FATAL] [DBT-30056] Labeling of disks failed. ORA-15227: could not perform label set/clear operation ORA-15031: disk specification /dev/asmdisk/ocr01 matches no disks [FATAL] [DBT-30002] Disk group OCR creation failed. ORA-15018: diskgrou…

用Python实现9大回归算法详解——03. 岭回归算法

1. 岭回归的基本概念与动机 1.1 为什么使用岭回归&#xff1f; 在线性回归中&#xff0c;当特征之间存在强烈的相关性&#xff08;即多重共线性&#xff09;时&#xff0c;回归系数会变得不稳定&#xff0c;导致模型在新数据上的表现很差。多重共线性会导致普通最小二乘法&am…

stm32f407新建项目工程及烧录

1、新建一个文件夹&#xff0c;打开keil5将项目工程放入文件夹中 2、弹出选择对应型号设备 3、弹出选择对应库 可以看见出现下图&#xff1a;感叹号表示有错 最后如图所示&#xff1a;点击ok就行了 4、创建对应的文件夹存放文件 4、建立main.c 5、添加对应的设置 最后写一个空白…

sp-eric靶机

端口扫描 靶机ip地址为192.168.7.46 目录扫描 访问80端口 拼接访问 /admin.php 发现登录框 测试sql注入&#xff0c;弱口令等&#xff0c;无结果 扫描目录发现了.git文件&#xff0c;存在源码泄漏 将其下载到kali上读取 python2 GitHack.py -u http://192.168.7.180/.git/…

Linux11

Linux运行级别 graphical.target图形化模式 runlevel查看运行级别 init 6自动重启 centos7单用户模式修改密码 Windows安全模式可用来删除木马&#xff0c;更为方便 单用户模式修改密码 选择第一个 按e键进入编辑模式&#xff0c;并完成以下修改&#xff08;注意&#xff0…

linux上Java生成图片中文乱码

在生成图形二维码时&#xff0c;设置底部中文导出空白乱码&#xff0c;效果如下&#xff1a; 这里服务器使用的是centos7&#xff0c;解决方案下载simsun.ttc文件&#xff0c;放入至jdk安装目录“/opt/jdk/jre/lib/fonts”中&#xff0c;具体根据自身本机jdk安装路径存放&…