完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
总的思路是以openmv 接收蓝牙的指令,如果是自动选项,就在openmv 运行识别红球进行固定距离跟踪的程序;如果是手动选项,openmv就直接把所得到的数据传给STM32,不做其它处理。那这里就需要做两件事情,一个是要接收蓝牙传过来的数据,一个是给STM32输出指令。
通过测试,openmv是有1和3两个串口可用,那就用1接收数据,用3输出数据。(计划很理想,但是有bug) 串口通信 OpenMV本质还是一个单片机,可以通过调用pyb中的UART使用串口通信,注意发送的数据类型为字符串,可以通过json.dumps()进行字符串转换 数据类型为字符串 from pyb import UART uart = UART(3, 9600) uart.write(‘hello’) uart.read(5) # read up to 5 bytes 字符串转换 uart3.write(ujson.dumps(cxy)+‘rn’) 数据打包 def send_data_packet(x, y):#数据打包 temp = struct.pack(“《bbii”, #格式为俩个字符俩个整型 0xAA, #帧头1 0xAE, #帧头2 int(x), # up sample by 4 #数据1 int(y)) # up sample by 4 #数据2 uart.write(temp) #串口发送 接收蓝牙数据 串口接收数据 #串口接收数据 import time from pyb import UART uart = UART(3, 9600,time_out_char=1000) while(True): if uart.any(): a=uart.readline().decode.strip() b=int(a) print(b) 接收到a代表的数据,用b输出,decode为字符串,无回车换行,但是一般有回车换行简单些,那就要在输入的时候写上。 IO口通信接收指令 p_out = Pin(‘P7’, Pin.OUT_PP)#设置p_out为输出引脚 p_out.high()#设置p_out引脚为高 p_in = Pin(‘P7’, Pin.IN, Pin.PULL_UP)#设置p_in为输入引脚,并开启上拉电阻 串口接收 STM32是以中断的方式接收数据 #stm32串口接收是以中断的方式 void USART2_IRQHandler(void) { static uint8_t rebuf[8]={0},i=0;#中断子程序每进入一次,只会接收一个Byte的数据。也就是说接收完一帧数据需要进入8次中断才行。 if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET)#OpenMV_Rx_BUF是一个外部变量用于保存从openmv接收到的数据,中断子程序中,每当进入中断,会首先判断帧头,如果不是 帧头,会直接丢弃,直到等到帧头的到来。 { rebuf[i++]=USART_ReceiveData(USART2); if(rebuf[0]!=0x4000)#帧头 i=0; if((i==2)&&(rebuf[1]!=0x4000))#判断帧头 i=0; if(i》=7)#代表一帧数据完毕 { memcpy(OpenMV_Rx_BUF,rebuf,i); i = 0; } USART_ClearFlag(USART2,USART_FLAG_RXNE); } 上面if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) OpenMV_Rx_BUF是一个外部变量用于保存从openmv接收到的数据,中断子程序中,每当进入中断,会首先判断帧头,如果不是 帧头,会直接丢弃,直到等到帧头的到来。 在openmv 中就可以用以下表示 FH = bytearray([0xb3,0xb3])#帧头 DF = bytearray([0xb4,0xb4])#帧尾 uart3.write(ujson.dumps(FH)+‘rn’) uart3.write(ujson.dumps(cxy)+‘rn’) uart3.write(ujson.dumps(DH)+‘rn’) 串口连接 openmv有uart1和uart3两个串口。 问题 1。蓝牙传递的指令对应的帧头帧尾还没有确定,还需更改。这个是需要用蓝牙模块通过USB转接口插在电脑上,用串口助手看,其中用手机上的SPP蓝牙软件传送,不知我这边是什么问题,线是对的,换手机和电脑都没用,蓝牙模块也是好的,已经给战友邮过去了,等待支援。 战友这里已解决,刚开始和我的问题是一样的,但是他那边多尝试了几遍就好了,但是又出现了输出乱码的情况,把波特率重置了一下就好了,感觉很可能是波特率的问题。 至于帧头帧尾,那不就是中括号的左右吗。。。 2。这个多次输入信息,不知道语法怎么表示了。 if b=[9]:#手动,这个多次输入信息,不知道语法怎么表示了 if b =[1]: ch=[1] uart3.write(ujson.dumps(FH)+‘rn’) uart3.write(ujson.dumps(ch)+‘rn’) uart3.write(ujson.dumps(DH)+‘rn’) print(“前进”) 用了懒方法,若b不为a,则是手动,最省事的方法就是开始的时候只能输入自动[a]和前进等指令,如果输入的不是自动[a],则根据指令直接传给单片机。 else# b不为a,则是手动,最省事的方法就是开始的时候只能输入自动[a]和前进等指令,如果输入的不是自动[a],则根据指令直接传给单片机 if b =[1]: ch=[1] uart3.write(ujson.dumps(FH)+‘rn’) uart3.write(ujson.dumps(ch)+‘rn’) uart3.write(ujson.dumps(DF)+‘rn’) print(“前进”) 当然,还可以用松键检测这种更为严谨的方法。 3.串口连接好,连上电脑,不亮灯。 线的接触问题。 4.可打开串口,但是电脑端接收不到数据。 是这个USB-TTL线和openmv的P4,P5接反了,所以,在这个时候不要怀疑世界,要先重新审视一下自己的装备。(蓝牙模块和USB-TTL线反接也很重要) 5.python语法错误 这个错误真的是弱爆了。还是平常自主写的太少了,比如 if: elif: else: if a == : 和c语言不一样,一定要加冒号,赋值的时候要是两个等号,还有缩进问题(还是最好在openmv ide里面编写程序,在记事本写的很悲伤)。 如果有语法错误,不知道在哪里,那就一行一行的看,一行一行注释,排除法找,最本质的方法是最有效的。 6.最花时间的一个问题,openmv只能发送数据,不能接收数据。 要是有示波器看看硬件问题还是程序问题就好了。 最后发现是openmv不能完美的接收数据,因为一接收数据,摄像头就不可以用了,是自身固件的问题,怪不得官网推荐用扩展板。 但是除了扩展板,还可以用单片机当中介,IO高低电平等多种方法,我们这边工具不够,再次邮寄。 最终是先拿openmv运行,只是输出数据,再拿esp32的蓝牙接收, openmv # Single Color RGB565 Blob Tracking Example # # This example shows off single color RGB565 tracking using the OpenMV Cam. import sensor, image, time, math,pyb from pyb import UART from pyb import Pin import ujson threshold_index = 0 # 0 for red, 1 for green, 2 for blue # Color Tracking Thresholds (L Min, L Max, A Min, A Max, B Min, B Max) thresholds = [(30, 100, 15, 127, 15, 127)] K=800#计算距离的辅助值 sensor.reset() sensor.set_pixformat(sensor.RGB565) sensor.set_framesize(sensor.QVGA) sensor.skip_frames(time = 5000) sensor.set_auto_gain(False) # must be turned off for color tracking sensor.set_auto_whitebal(False) # must be turned off for color tracking clock = time.clock() uart3 = UART(3, 9600) #p4p5 uart1 = UART(1, 9600) #p2p3 uart1= UART(1, 9600, timeout_char=1000) #蓝牙接收数据 #UART.init(baudrate=9600, bits=8, parity=None, stop=1) #IO口通信接收指令 #p_out=Pin(‘P7’,Pin.OUT_PP)#设置p_out为输出引脚 #p_out.high()#设置p_out引脚为高 #p_in=Pin(‘P7’,Pin.IN,Pin.PULL_UP)#设置p_in为输入引脚,并开启上拉电阻 while(True): p_out1 = Pin(‘P7’, Pin.OUT_PP)#设置p_out为输出引脚 p_out1.high()#设置p_out引脚为高 p_in1 = Pin(‘P7’, Pin.IN, Pin.PULL_UP)#设置p_in为输入引脚,并开启上拉电阻 value1 = p_in1.value() p_out2 = Pin(‘P8’, Pin.OUT_PP)#设置p_out为输出引脚 p_out2.high()#设置p_out引脚为高 p_in2 = Pin(‘P8’, Pin.IN, Pin.PULL_UP)#设置p_in为输入引脚,并开启上拉电阻 value2 = p_in2.value() #供单片机判断接收数据 FH = bytearray([0xb3,0xb3])#帧头 AH = bytearray([0x40]) DF = bytearray([0xb4,0xb4])#帧尾 HF = bytearray([0x40]) #手动 if value1==1 and value2==1: ch=[1] uart3.write(ujson.dumps(FH)+‘rn’) uart3.write(ujson.dumps(ch)+‘rn’) uart3.write(ujson.dumps(DF)+‘rn’) print(“前进”) clock.tick() elif value1==1 and value2==0: ch=[2] uart3.write(ujson.dumps(FH)+‘rn’) uart3.write(ujson.dumps(ch)+‘rn’) uart3.write(ujson.dumps(DF)+‘rn’) print(“后退”) elif value1==0 and value2==1: ch=[4] uart3.write(ujson.dumps(FH)+‘rn’) uart3.write(ujson.dumps(ch)+‘rn’) uart3.write(ujson.dumps(DF)+‘rn’) print(“左转”) elif value1==0 and value2==0: ch=[3] uart3.write(ujson.dumps(FH)+‘rn’) uart3.write(ujson.dumps(ch)+‘rn’) uart3.write(ujson.dumps(DF)+‘rn’) print(“右转”) else: img = sensor.snapshot() for blob in img.find_blobs([thresholds[threshold_index]], pixels_threshold=200, area_threshold=200, merge=True): # These values depend on the blob not being circular - otherwise they will be shaky. img.draw_rectangle(blob.rect()) img.draw_cross(blob.cx(), blob.cy()) # Note - the blob rotation is unique to 0-180 only. #if b == “[a]”: #接收蓝牙指令为自动 # print(clock.fps()) # print(blob.cx(),blob.cy()) if ((blob.cx()-160)《(-10)) : # 串口发送左 cxy=[4] uart3.write(ujson.dumps(FH)+‘rn’) uart3.write(ujson.dumps(cxy)+‘rn’) uart3.write(ujson.dumps(DF)+‘rn’) print(“左转”) if ((blob.cx()-160)》10) : # 串口发送右 cxy=[3] uart3.write(ujson.dumps(FH)+‘rn’) uart3.write(ujson.dumps(cxy)+‘rn’) uart3.write(ujson.dumps(DF)+‘rn’) print(“右转”) if ((blob.cy()-120)《(-30)) : # 串口发送前进 cxy=[1] uart3.write(ujson.dumps(FH)+‘rn’) uart3.write(ujson.dumps(cxy)+‘rn’) uart3.write(ujson.dumps(DF)+‘rn’) print(“前进”) if ((blob.cy()-120)》30) : # 串口发送后退 cxy=[2] uart3.write(ujson.dumps(FH)+‘rn’) uart3.write(ujson.dumps(cxy)+‘rn’) uart3.write(ujson.dumps(DF)+‘rn’) print(“后退”) esp32 #include “BluetoothSerial.h” #if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED) #error Bluetooth is not enabled! Please run `make menuconfig` to and enable it #endif BluetoothSerial SerialBT; //定义蓝牙对象 //esp32有三个串口,分别为Serial、Serial1、Serial2,其中Serial为默认串口,可用来下载程序。 HardwareSerial mySerial1(1); //定义Serial1对象 HardwareSerial mySerial2(2); //定义Serial2对象 unsigned char btrxdata[4]; //蓝牙接收数组 unsigned char btrxcount=0; //蓝牙接收标志位 unsigned char omvrxdata[4]; //openmv接收数组 unsigned char omvrxcount=0; //openmv接收标志位 unsigned char wordmode=0; //工作模式,0为手动模式即仅能通过蓝牙控制,1为自动模式可通过openmv控制 ,二者切换通过蓝牙控制 void setup() { pinMode(21, INPUT); //初始化io21,输入模式,用于检测hc05是否有连接。本程序中未使用 mySerial1.begin(9600,SERIAL_8N1,32,33); //初始化Serial1,波特率9600 rx为io32 tx为io33 mySerial2.begin(9600,SERIAL_8N1,18,19); //同上 Serial.begin(9600); //初始化Serial,仅填波特率即可,也可映射到任意io,参数格式同上 SerialBT.begin(“dog”); //初始化蓝牙,蓝牙名字为dog } void loop() { while(Serial.available()) //如果串口接收缓冲区有数据,就全部读取 { omvrxdata[omvrxcount++]=Serial.read(); if(wordmode == 1) //如果是自动模式就转发数据,否则丢弃 { if((omvrxdata[omvrxcount-3]==‘[’)&&(omvrxdata[omvrxcount-1]==‘]’)) { mySerial1.write(omvrxdata[0]); mySerial1.write(omvrxdata[1]); mySerial1.write(omvrxdata[2]); omvrxcount = 0; memset(omvrxdata,0,sizeof(omvrxdata)); //清空数组 } } if(omvrxcount == 3) { omvrxcount = 0; memset(omvrxdata,0,sizeof(omvrxdata)); } } while(SerialBT.available()) //如果蓝牙接收缓冲区有数据,就全部读取 { btrxdata[btrxcount++]=SerialBT.read(); if((btrxdata[btrxcount-2]==0x0a)&&(btrxdata[btrxcount-1]==‘]’)) { btrxcount = 0; //检测接收到的数据是否有控制数据 如果有则执行 若无则转发 memset(btrxdata,0,sizeof(btrxdata)); wordmode = 1; } if((btrxdata[btrxcount-2]==0x0b)&&(btrxdata[btrxcount-1]==‘]’)) { btrxcount = 0; memset(btrxdata,0,sizeof(btrxdata)); wordmode = 0; } if((btrxdata[btrxcount-2]==0x0c)&&(btrxdata[btrxcount-1]==‘]’)) { btrxcount = 0; memset(btrxdata,0,sizeof(btrxdata)); } if((btrxdata[btrxcount-3]==‘[’)&&(btrxdata[btrxcount-1]==‘]’)) { mySerial1.write(btrxdata[0]); mySerial1.write(btrxdata[1]); mySerial1.write(btrxdata[2]); btrxcount = 0; memset(btrxdata,0,sizeof(btrxdata)); } if(btrxcount == 3) { btrxcount = 0; memset(btrxdata,0,sizeof(btrxdata)); } } } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1763 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1617 浏览 1 评论
1059 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
723 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1670 浏览 2 评论
1933浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
726浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
567浏览 3评论
592浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
550浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-21 15:05 , Processed in 0.862902 second(s), Total 78, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号