ToB企服应用市场:ToB评测及商务社交产业平台
标题:
基于OpenMV与STM32的数据通信项目(代码开源)_openmv与stm32连接
[打印本页]
作者:
用多少眼泪才能让你相信
时间:
2024-8-6 21:51
标题:
基于OpenMV与STM32的数据通信项目(代码开源)_openmv与stm32连接
既有得当小白学习的零底子资料,也有得当3年以上经验的小伙伴深入学习提拔的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!
由于文件比力多,这里只是将部分目次截图出来,全套包罗大厂面经、学习笔记、源码讲义、实战项目、大纲门路、电子书籍、讲解视频,而且后续会连续更新
需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)
如果你需要这些资料,可以戳这里获取
作者推荐 OpenMV 学习网站:
官方网站:Download – OpenMV
OpenMV中国官方代理(星瞳科技):序言 · OpenMV中文入门教程
1.2 OpenMV项目
中国
OpenMV
官方代理是星瞳科技,星瞳科技在其官网提供了超多详细且丰富的
OpenMV
使用案例,
例如:特征点检测、测距、扫描识别、寻找色块、模板匹配、颜色外形识别与人脸识别等
。
上述图片中的案例都是可以借助
OpenMV
进行实现的,当然思量到
STM32F7/STM32H7
等系列
CPU
算力的上限,可能输出图像像素以及
FPS
并不是特别精良的。有能力和专研精神的读者朋友可以尝试高级的计算机视觉开发工具,
例如:Jeston Nano、K210、K510、RK3568、RK3588与树莓派4/5B系列等(部分产品的性能与算力非常有竞争力)!
增补提醒:本项目中使用 OpenMV 的数字识别作为案例,进行与 STM32 之间的数据通信!
二、博客项目概述
2.1 OpenMV的Mnist数字识别
OpenMV
提供了超级多的计算机视觉的案例,作者选择常用的
mnist
数字识别项目作为
OpenMV
终端处置惩罚的事件(电赛送药小车标题与之类似),该案例可以直接通过星瞳科技官网进行获取(老旧版本的 OpenMV 可能需要升级固件才气使用该案例):
案例地址:
Mnist数字识别 · OpenMV中文入门教程
作者手上的
OpenMV
为
OpenMV3 R1
,CPU 的处置惩罚性能非常一样平常。官方在
OpenMV4 H7 Plus
上面运行大概每秒
45
帧,在
OpenMV4 H7
上面运行大概每秒
25
帧左右。mnist 数字识别案例使用了 CNN 卷积神经网络进行识别,例程利用 mnis t数字数据集,自行练习神经网络得到手写数字识别神经网络模子,性能和准确率很高(可以直接使用案例的权重文件即可)。
★运行目次前,将官网提供的 mnist 数字识别的
trained.tflite
文件下载到电脑,并复制到
OpenMV
的存储中。
mnist数字识别代码:
# This code run in OpenMV4 H7 or OpenMV4 H7 Plus
import sensor, image, time, os, tf
sensor.reset() # Reset and initialize the sensor.
sensor.set_pixformat(sensor.GRAYSCALE) # Set pixel format to RGB565 (or GRAYSCALE)
sensor.set_framesize(sensor.QVGA) # Set frame size to QVGA (320x240)
sensor.set_windowing((240, 240)) # Set 240x240 window.
sensor.skip_frames(time=2000) # Let the camera adjust.
clock = time.clock()
while(True):
clock.tick()
img = sensor.snapshot().binary([(0,64)])
for obj in tf.classify("trained.tflite", img, min_scale=1.0, scale_mul=0.5, x_overlap=0.0, y_overlap=0.0):
output = obj.output()
number = output.index(max(output))
print(number)
print(clock.fps(), "fps")
复制代码
案例测试:
2.2 项目整体阐明
OpenMV
集成了非常多的库函数,常用的数据通信使用
UART
串口,本篇博客就以
UART
通信为例。
本项目利用
OpenMV
的数字识别案例进行数字识别,将识别到的数字信息通过
OpenMV
的
UART
串口发送至
STM32F103C8T6
。而
STM32F103C8T6
通过
I2C
协议将
OpenMV
传输过来的数字信息体现在
0.96
寸的
OLED
屏幕上。该项目的整体实现还是非常简单,特别是计算机视觉的数字识别部分,
OpenMV
直接封装为案例,极大地方便研发职员的后续使用。当然,本篇博客最核心部分是
OpenMV
与
STM32
的通信部分的处置惩罚,包罗数据包的处置惩罚编程!
三、传输数据包协议
3.1 数据包通信概述
传输完全体数据包可以包罗:
帧头
、地址信息、数据类型、数据长度、数据块、校验码、
帧尾
。
正常环境下,思量到传输速率问题不会使用完全体数据包。大多数环境下,工程师仅使用简版数据包:
帧头
、
数据字节长度
与
帧尾
!
传输数据包的过程包罗 2 个部分:(1) 数据包编码,上文所说的数据包组成;(2) 数据包分析,下文所说的数据包分析;
传输****数据过程中的数据包分析通常有 2 种方式:(1)、停止内部分析;(2)、停止外部分析;
**第一种方法:**
停止服务函数内部直接分析使用,该方法适用于数据帧简单,数据复杂程度低的环境。可以满足停止函数的快进快出,该方法可以使整个项目代码框架轻便,方便后期纠错改正!!!
**第二种方法:**
停止服务函数外部分析使用,该方法适用于数据帧繁杂,数据复杂程度高的环境。该环境下,每每无法满足停止服务函数的快进快出,轻易卡死在停止内部。这种环境下,工程师可以在停止中只接收数据,随后通过 extern 全局变量将数据在外部进行分析处置惩罚。现实工程中,该方法使用可能性高,盼望读者朋友可以完全掌握该技能!!!
本篇博客项目使用停止内部分析数据包的方法,该方法也是作者电赛常用手段之一(部分环境下分析完的数据可能需要数据融合或是滤波处置惩罚,该环境使不得当在停止服务函数中分析的)
3.2 数据包传输(HEX方式)
数据包传输方式是机器设备间通信最常见的方法,**数据包传输方式一样平常分为 3 种:(1) 固定包长,含帧头帧尾;(2) 可变包长,含帧头帧尾;(3) 可变包长,含数据字节长度及帧头帧尾;**详情如下图所示:
作者增补阐明:上图中的帧头为 0xFE,帧尾为 0xEF;这里的帧头和帧尾是可以自界说的,但通常环境下会选择帧头为 0xFE,帧尾为 0xEF,这是为什么呢?
**答:**通常帧头和帧尾的计划需要制止与通信过程中的数据具有相似性,不然轻易导致误把通信数据当初帧头帧尾进行处置惩罚,从而分析出错误的数据!当然,复杂的数据包帧头也可以不局限于 1 个字节,读者朋友可以根据本身现实环境计划。作者项目使用直接使用了帧头为 0xFE,帧尾为 0xEF 的数据包进行传输!
四、CubeMX配置
1、RCC配置外部高速晶振(精度更高)——HSE;
2、SYS配置:Debug设置成Serial Wire
(
否则可能导致芯片自锁
);
3、USART1配置:设置UART1串口;波特率:115200;开启UART串口停止;
4、I2C配置:设置I2C1与 0.96 寸OLED进行通信;
5、时钟树配置
6、工程配置
五、代码与分析
5.1 OpenMV数据发生端代码
5.1.1 OpenMV的串口数据传输
星瞳科技官网提供了
OpenMV
的串口 UART 的使用案例,升级到最新版固件就可以直接运行。作者使用
CH340
芯片将串口数据上传至电脑终端进行测试(读者朋友搞工程的时候,也建议按部就班的搭建和完善代码流程)。
OpenMV 串口通信代码:
# This code run in OpenMV4 H7 or OpenMV4 H7 Plus
import sensor, image, time, os, tf
from pyb import UART
sensor.reset() # Reset and initialize the sensor.
sensor.set_pixformat(sensor.GRAYSCALE) # Set pixel format to RGB565 (or GRAYSCALE)
sensor.set_framesize(sensor.QVGA) # Set frame size to QVGA (320x240)
sensor.set_windowing((240, 240)) # Set 240x240 window.
sensor.skip_frames(time=2000) # Let the camera adjust.
#OpenMV串口UART传输数据
uart = UART(3, 115200) # 实例化一个串口3,波特率为115200,必须与STM32接收端保持一致
clock = time.clock()
while(True):
clock.tick()
img = sensor.snapshot().binary([(0,64)])
for obj in tf.classify("trained.tflite", img, min_scale=1.0, scale_mul=0.5, x_overlap=0.0, y_overlap=0.0):
output = obj.output()
number = output.index(max(output))
print(number)
print(clock.fps(), "fps")
uart.write("Hello World!\r")
复制代码
5.1.2 OpenMV发送端完整代码
在上述官方提供的
OpenMV
的
2
个例程代码的底子上联合项目现实环境进行编写代码。
OpenMV
只能传输十六进制的数据给
STM32
,否则
STM32
将收不到数据,就是单片机和
OpenMV
都能正常和电脑通信,但是两者联合就不能正常通信。十六进制数据的实现紧张通过
bytearray()
这个函数,代码格式如下:**OUT\_DATA =bytearray([0x2C,0x12,cx,cy,cw,ch,0x5B])**
**代码分析:**通过界说
Sending_Data()
函数,进行
OpenMV
端的数据发送。在
mnist
数字识别的
while
函数的
for
循环中将识别到的
number
数据包连续
Sending_Data()
发送到
STM32
开发板上。
mnist.py代码:
# This code run in OpenMV4 H7 or OpenMV4 H7 Plus
import sensor, image, time, os, tf
from pyb import UART
sensor.reset() # Reset and initialize the sensor.
sensor.set_pixformat(sensor.GRAYSCALE) # Set pixel format to RGB565 (or GRAYSCALE)
sensor.set_framesize(sensor.QVGA) # Set frame size to QVGA (320x240)
sensor.set_windowing((240, 240)) # Set 240x240 window.
sensor.skip_frames(time=2000) # Let the camera adjust.
#OpenMV串口UART传输数据
uart = UART(3, 115200) # 实例化一个串口3,波特率为115200,必须与STM32接收端保持一致
#定义数据包发送函数
def Sending_Data(Num):
global uart;
OutData = bytearray([0xFE,0xBC,Num,0xEF]) #构建发送数据的数据包
uart.write(OutData); #必须要传入一个字节数组
clock = time.clock()
while(True):
clock.tick()
img = sensor.snapshot().binary([(0,64)])
for obj in tf.classify("trained.tflite", img, min_scale=1.0, scale_mul=0.5, x_overlap=0.0, y_overlap=0.0):
output = obj.output()
number = output.index(max(output))
Sending_Data(number)
print(number)
print(clock.fps(), "fps")
复制代码
mnist数字识别数据传输:
5.2 STM32数据接收端代码
5.2.1 0.96寸OLED代码
本篇博客项目中使用
0.96
寸
OLED
将
OpenMV
识别的
mnist
数字结果进行输出,
0.96
寸的
OLED
驱动代码可以参考作者的另一篇博客。思量到博客篇幅有限,
0.96
寸
OLED
驱动就不详细赘述了,盼望读者朋友可以自行掌握!
博客地址:
http://t.csdnimg.cn/gDcev
5.2.2 STM32接收端完整代码
**代码分析:**本篇项目代码中
STM32
接收端关键操作都是依靠于
HAL_UART_RxCpltCallback()
函数实现的。
OpenMV
与
STM32
数据传输过程中的解码在停止回调函数中直接通过
OpenMV_Data_Receive()
函数实现。
USART1_RXbuff
变量为
USART1
开启后连续传输的数据,将该变量放入
OpenMV_Data_Receive()
进行解码。
★核心函数 OpenMV_Data_Receive() 分析:
OpenMV
与
STM32
数据传输稍微复杂点的其实就是
STM32
接收端的解码过程,常规环境下
OpenMV
发送端的数据是一组数据包。这组数据包的组成是程序员本身界说的,好比作者
OpenMV
端的数据包格式为:
0xFE,0xBC,Num,0xEF
。其中,
0xFE,0xBC 为帧头
,
Num 为需要解码出的真正数据
,
0xEF 为帧尾
。
STM32
接收端需要根据
OpenMV
发送端的数据包格式进行解码,
HAL_UART_Receive_IT()
函数稳定将接收到的数据赋值
USART1_RXbuff
,通过
OpenMV_Data_Receive()
函数进行解码。根据上述
OpenMV
发送端的代码,可以得出需要首先解码
帧头的 0xFE 与 0xBC
,
OpenMV_Data_Receive()
函数中界说
RxBuffer[4]
数组来接收每一帧的数据(作者每一帧数据有
4
个字节数据,读者朋友可以根据现实环境设置数组大小),设置
RxState
状态位来递进判断是否准确接收到目标数据。在成功接收到
2
个帧头数据之后,通过 **OLED_ShowNum()**函数将
OpenMV
识别出的数字体现出来。
**关键点:**
串口接收停止回调函数
/* USER CODE BEGIN PTD */
uint8_t USART1_RXbuff; //中断数据接收缓冲区
/* USER CODE END PTD */
HAL_UART_Receive_IT(&huart1,(void *)&USART1_RXbuff,1); /* 开启串口中断接收 */
复制代码
/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
uint16_t tempt;
if(huart->Instance==USART1)
{
tempt=USART1_RXbuff;
OpenMV_Data_Receive(tempt);
}
HAL_UART_Receive_IT(&huart1,(void *)&USART1_RXbuff,1); //再次开启中断接收
}
/* USER CODE END 4 */
复制代码
openmv.h:
#ifndef __OPENMV_H
#define __OPENMV_H
#include "stm32f1xx.h"
void OpenMV_Data_Receive(int16_t OpenMV_Data); /* STM32接收端处理OpenMV传输的数据 */
#endif
复制代码
openmv.c:
/********************************* (C) COPYRIGHT **********************************
* File Name : openmv.c
* Author : 混分巨兽龙某某
* Version : V1.0.0
* Data : 2023/11/03
* Contact : QQ:1178305328
* Description : OpenMV and STM32 Communication Files
***********************************************************************************/
#include "openmv.h"
#include "usart.h"
#include "stdio.h"
#include "oled.h"
**收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。**
![img](https://img-blog.csdnimg.cn/img_convert/ee2e379e67acfd84d0b15cffb886ac69.png)
![img](https://img-blog.csdnimg.cn/img_convert/52c1607b8ea40e806fcf113cf3f0ee54.png)
**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**
**需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人**
**都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
.h"
#include "usart.h"
#include "stdio.h"
#include "oled.h"
**收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。**
[外链图片转存中...(img-2hUPaXOn-1715802158664)]
[外链图片转存中...(img-5KaP20T5-1715802158665)]
**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**
**需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人**
**都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4