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

大家好啊,我是情谊,今天我们来介绍一下我最近设计的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 LEDsensor.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 = Nonewhile True:clock.tick()img = sensor.snapshot()# 寻找二维码qr_codes = img.find_qrcodes()if qr_codes:# 获取第一个二维码的颜色信息qr_color = qr_codes[0].payload()last_qr_color = qr_colorblobs = Noneif 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 = Noneled_green.off()led_red.off()led_blue.off()else:# 如果没有检测到二维码,则继续识别上次记录的颜色qr_color = last_qr_colorblobs = Noneif 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 = Noneled_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 = 0x02elif qr_color == "red":area_low_byte = 0x01data_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();    
#endifif(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.rhkb.cn/news/401900.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用Python读取Excel数据在PPT中的创建图表

可视化数据已成为提高演示文稿专业度的关键因素之一。使用Python从Excel读取数据并在PowerPoint幻灯片中创建图表不仅能够极大地简化图表创建过程&#xff0c;还能确保数据的准确性和图表的即时性。通过Python这一桥梁&#xff0c;我们可以轻松实现数据自动化处理和图表生成&am…

时空自回归模型(STAR)及 Stata 具体操作步骤

目录 一、引言 二、文献综述 三、理论原理 四、实证模型 五、稳健性检验 六、程序代码及解释 附录 数据预处理 生成时空权重矩阵 一、引言 时空自回归模型&#xff08;Spatial-Temporal Autoregressive Model&#xff0c;简称 STAR&#xff09;在分析具有时空特征的数…

【Python养成】:输出两个等腰三角形且平行方向

项目场景&#xff1a; 遇到一个小小的高中小程序题目&#xff0c;有趣就做 了一下&#xff0c;供大家参考。 问题描述 要求使用python编程&#xff0c;实现如下图形。 原因分析&#xff1a; 其实就是 找规律和找空格。先左边后右边。具体解释可以找AI。太简单了没必要亲自讲解…

【C++进阶】map与set的封装实践

文章目录 map和setmapmap的框架迭代器operator()operator--()operator()和operator!()operator*()operator->() insertbegin()end()operator[] ()map的所有代码&#xff1a; set的封装迭代器的封装总结 map和set 通过观察stl的底层我们可以看见&#xff0c;map和set是通过红…

密码学基础---椭圆曲线一文打尽

1.ECC简介及密钥生成 当前公认安全有效的三大类公钥密钥体制分别为基于大数因子分解难题(RSA)、离散对数难题(DSA)和椭圆曲线离散对数&#xff08;ECC&#xff09;难题的密码体制。 最初RSA由于其容易理解被广泛运用&#xff0c;但随着计算机性能的提升&#xff0c;要保证RS…

Golang | Leetcode Golang题解之第336题回文对

题目&#xff1a; 题解&#xff1a; // 哈希表实现 class Solution {public List<List<Integer>> palindromePairs(String[] words) {List<List<Integer>> res new ArrayList<>();int n words.length;Map<String, Integer> indices ne…

AIGC:clip-interrogator

文字生成图片是近年来多模态和大模型研究的热门方向&#xff0c;openai提出的CLIP提供了一个方法建立起了图片和文字的联系&#xff0c;但是只能做到给定一张图片选择给定文本语义最相近的那一个&#xff0c;实际项目开发中我们总是需要从一张图片获取描述&#xff0c;clip-int…

高效录制新选择:2024年Windows录屏软件

录屏能帮助我们捕捉屏幕上的精彩瞬间&#xff0c;作为老师可以用来录制课程&#xff0c;作为会议记录员可以用来录制远程会议。那么有什么软件是适合windows录屏的呢&#xff1f;这次我们一起来探讨一下吧。 1.福昕录屏大师 链接&#xff1a;www.foxitsoftware.cn/REC/ 这款软…

什么是链表/双向链表

看csp j选择的时候看到链表题&#xff0c;那就来写一写吧 什么是链表 首先我们知道数组&#xff1a; 链表和数组有点像&#xff0c;他是这样的&#xff1a; 1----->2------->3------->4 链表中每个数据都有一个指针&#xff0c;指着自己的下一项数据是哪一个 比如…

Android高版本抓包总结

方案1 CharlesVirtualXposedJustTrustMe 推荐使用三星手机此方案 VirtualXposed下载链接&#xff1a;https://github.com/android-hacker/VirtualXposed/releases JustTrustMe下载链接&#xff1a;https://github.com/Fuzion24/JustTrustMe/releases/ 下载完成后使用adb命令…

编辑器和工具扩展

https://www.youtube.com/watch?vovpiYkYFlPM ui提示 检查资源的合法性

使用 Ollama 集成 GraphRag.Net:一步步教你如何实现

在当今的技术世界&#xff0c;人工智能 (AI) 正在以惊人的速度发展。对于开发者来说&#xff0c;使用最新的工具和框架来提升工作效率至关重要。而在 AI 领域&#xff0c;GraphRag.Net 作为一个强大的图算法框架&#xff0c;允许我们以高效的方式进行数据处理。同样&#xff0c…

【Java 并发编程】(二) 从对象内存布局开始聊 synchronized

对象的内存布局 首先抛出一个经典面试题: 一个 Object 对象占多大? 这里我用工具打印了出来, 发现是 “16bytes”, 也就是 16B; 为什么? 请继续往下看; 普通对象(除了数组), 由markword, 类型指针, 实例数据(就是对象里的成员), 对齐填充(整个对象大小要能被8B整数, 方便6…

电销机器人引领电销变革

以前电销都是都是通过盲打&#xff0c;现在有了电话机器人的出现&#xff0c;为电销公司带来新的篇章。 我们都知道外呼中心的人员离职率始终居高不下&#xff0c;人员的培训频繁成本很高&#xff0c;外部电话水平参差不齐&#xff0c;服务态度不够稳定等问题&#xff0c;都是难…

基础 - 前端知识体系详解

一、前端三要素 HTML&#xff08;结构&#xff09;&#xff1a; 超文本标记语言&#xff08;Hyper Text Markup Language&#xff09;&#xff0c;决定网页的结构和内容。CSS&#xff08;表现&#xff09;&#xff1a; 层叠样式表&#xff08;Cascading Style Sheets&#xff0…

【Mac】Downie 打开提示试用的解决办法?

前情 我们在使用 Downie 的时候&#xff0c;可能遇到提示试用的问题&#xff0c;如下图所示。 原因 旧版本的 Downie 没有卸载干净导致的。 解决办法 先使用 AppCleaner 卸载掉电脑上的 Downie 旧版本软件&#xff0c;必须使用 AppCleaner 卸载。重新安装 Downie 即可。

如何保证数据不丢失?(死信队列)

死信队列 1、什么是死信 死信通常是消息在特定的场景下表现&#xff1a; 消息被拒绝访问消费者发生异常&#xff0c;超过重试次数消息的Expiration过期时长或者队列TTL过期时间消息队列到达最大容量 maxLength 2、什么是死信队列 只由死信构成的消息队列是死信队列 死信队…

PhpStorm完全配置指南:打造高效PHP开发环境!

Phpstorm环境配置与应用&#xff0c;具体包括安装PhpStorm、配置PHP运行环境、Apache集成、调试和部署等步骤。下面将详细展开每个步骤的具体操作和注意事项。 PhpStorm的下载与安装 下载地址&#xff1a;访问PhpStorm的官网下载地址&#xff0c;选择合适的版本进行下载。建议选…

springboot、spring@JsonAlias(velue)的作用

‌JsonAlias注解用于为字段或参数指定反序列化时的别名。‌‌ 在Java开发中&#xff0c;‌特别是在使用Jackson库进行JSON序列化和反序列化时&#xff0c;‌JsonAlias注解扮演着重要的角色。‌它允许开发者为字段或参数指定一个或多个别名&#xff0c;‌这样在反序列化过程中&…

希尔排序,详细解析(附图解)

1.希尔排序思路 希尔排序是一种基于插入排序的算法&#xff0c;通过将原始数据分成若干个子序列&#xff0c;然后对子序列进行插入排序&#xff0c;逐渐减小子序列的间隔&#xff0c;最后对整个序列进行一次插入排序。 1.分组直接插入排序&#xff0c;目标接近有序--------…