總的思路是以openmv 接收藍牙的指令,如果是自動選項,就在openmv 運行識別紅球進行固定距離跟蹤的程序;如果是手動選項,openmv就直接把所得到的數據傳給STM32,不做其它處理。那這裏就需要做兩件事情,一個是要接收藍牙傳過來的數據,一個是給STM32輸出指令。
通過測試,openmv是有1和3兩個串口可用,那就用1接收數據,用3輸出數據。
串口通信
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轉接口插在電腦上,用串口助手看,其中用手機上的SPP藍牙軟件傳送,不知我這邊是什麼問題,線是對的,換手機和電腦都沒用,藍牙模塊也是好的,已經給戰友郵過去了,等待支援。
戰友這裏已解決,剛開始和我的問題是一樣的,但是他那邊多嘗試了幾遍就好了,但是又出現了輸出亂碼的情況,把波特率重置了一下就好了,感覺很可能是波特率的問題。
2.這個多次輸入信息,不知道語法怎麼表示了。
if b=[9]:#手動,這個多次輸入信息,不知道語法怎麼表示了
if b =[1]:
ch=[1]
uart3.write(ujson.dumps(FH)+'\r\n')
uart3.write(ujson.dumps(ch)+'\r\n')
uart3.write(ujson.dumps(DH)+'\r\n')
print("前進")
用了懶方法,若b不爲a,則是手動,最省事的方法就是開始的時候只能輸入自動[a]和前進等指令,如果輸入的不是自動[a],則根據指令直接傳給單片機。
else# b不爲a,則是手動,最省事的方法就是開始的時候只能輸入自動[a]和前進等指令,如果輸入的不是自動[a],則根據指令直接傳給單片機
if b =[1]:
ch=[1]
uart3.write(ujson.dumps(FH)+'\r\n')
uart3.write(ujson.dumps(ch)+'\r\n')
uart3.write(ujson.dumps(DF)+'\r\n')
print("前進")
當然,還可以用鬆鍵檢測這種更爲嚴謹的方法。
3.串口連接好,連上電腦,不亮燈。
4.可打開串口,但是電腦端接收不到數據。
是這個USB-TTL線和openmv的P4,P5接反了,所以,在這個時候不要懷疑世界,要先重新審視一下自己的裝備。(藍牙模塊和USB-TTL線反接也很重要)
5.