总的思路是以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)+'\r\n')
数据打包
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)+'\r\n')
uart3.write(ujson.dumps(cxy)+'\r\n')
uart3.write(ujson.dumps(DH)+'\r\n')
串口连接
openmv有uart1和uart3两个串口。
问题
1.蓝牙传递的指令对应的帧头帧尾还没有确定,还需更改。这个是需要用蓝牙模块通过USB转接口插在电脑上,