Openmv与其他单片双向串口通信
目的
为了让openmv进行阈值切换或者只运行某一部分代码,因此需要openmv与其他单片建立双向通信进行更改内部参数。
起因
openmv自带接收函数uart.read() 进行接收,但接收回来的数据类型为字符串不能用于数值的比较,需要将字符串打散转化为字符类型,因此我采用强制转换的方法,代码如下
def
recive_data():
global tmp_data
if uart
.any(): #等待接收
t
= uart
.read(); #读入数据
tmp_data
=int(t
) #强制转换为整型变量
print(tmp_data
)
注意:因为将字符串强制转换为整型,此代码只能接收以数字所建立的标志位。其他标志会引起代码报错,这也是代码的一个大bug,希望大家多多指教。
以下收发颜色捕捉的完整代码
import json
import ustruct
import sensor
, image
, time
from pyb import UART
thresholds
= [(30, 50, 40, 90, 35, 80), # red_thresholds
(30, 60, -80, -20, 0,40), # green_thresholds
(10, 40, 0, 40, -80, -20)] # blue_thresholds
clock
= time
.clock()
uart
= UART(3,115200)
uart
.init(115200, bits
=8, parity
=None
, stop
=1)
def
sending_data(cx
,cy
):
global uart
;
#frame=[0x2C,18,cx%0xff,int(cx/0xff),cy%0xff,int(cy/0xff),0x5B];
#data = bytearray(frame)
data
= ustruct
.pack("<bbhhhhb", #格式为俩个字符俩个短整型
(2字节
)
0x2C, #帧头
1
0x12, #帧头
2
int(cx
), # up sample by
4 #数据
1
int(cy
), # up sample by
4 #数据
2
int(c
), #
int(R
),
0x5B)
uart
.write(data
); #必须要传入一个字节数组
print(cx
)
print(cy
)
print(c
)
print(R
)
def
sending_data1(q
):
global uart
;
#frame=[0x2C,18,cx%0xff,int(cx/0xff),cy%0xff,int(cy/0xff),0x5B];
#data = bytearray(frame)
data
= ustruct
.pack("<bbhhhhb", #格式为俩个字符俩个短整型
(2字节
)
0x2C, #帧头
1
0x12, #帧头
2
int(cx
), # up sample by
4 #数据
1
int(cy
), # up sample by
4 #数据
2
int(q
), #
int(40),
0x5B)
uart
.write(data
); #必须要传入一个字节数组
def
recive_data():
global tmp_data
if uart
.any():
t
= uart
.read();
tmp_data
=int(t
)
print(tmp_data
)
def
compare(shu1
,shu2
):
if (shu1
>= shu2
):
return shu1
else:
return shu2
def
find_max(blobs
): #定义寻找色块面积最大的函数
max_size
=0
for blob in blobs
:
if blob
.pixels() > max_size
:
max_blob
=blob
max_size
= blob
.pixels()
return max_blob
c
=0
tmp_data
=0
while(1):
if(tmp_data
==1):
sensor
.reset()
sensor
.set_pixformat(sensor
.RGB565
)
sensor
.set_framesize(sensor
.QVGA
)
sensor
.skip_frames(time
= 2000)
sensor
.set_auto_gain(False
) # must be turned off
for color tracking
sensor
.set_auto_whitebal(False
) # must be turned off
for color tracking
sensor
.set_vflip(False
)
sensor
.set_hmirror(False
)
while(1):
img
= sensor
.snapshot().lens_corr(1.8)
for blob in img
.find_blobs(thresholds
, pixels_threshold
=300, area_threshold
=300):
blobs
=img
.find_blobs(thresholds
, pixels_threshold
=300, area_threshold
=300)
if blobs
:#如果找到了目标颜色
max_b
= find_max(blobs
)
img
.draw_rectangle(max_b
.rect())
img
.draw_cross(max_b
.cx(), max_b
.cy())
x
= max_b
.density()
if(x
<0.6 and x
>0.4):
c
=1
elif(x
>0.7 and x
<0.8):
c
=2
elif(x
>0.8):
c
=3
cx
= max_b
.cx()
cy
= max_b
.cy()
R
= max_b
.w()
sending_data(cx
,cy
)
recive_data()
elif(tmp_data
==2):
sensor
.reset()
sensor
.set_pixformat(sensor
.RGB565
)
sensor
.set_framesize(sensor
.QQVGA
)
sensor
.skip_frames(time
= 2000)
sensor
.set_auto_gain(False
) # must be turned off
for color tracking
sensor
.set_auto_whitebal(False
) # must be turned off
for color tracking
sensor
.set_vflip(False
)
sensor
.set_hmirror(False
)
while(1):
img
= sensor
.snapshot()
max_size
= 0
for c in img
.find_circles(threshold
= 4000, x_margin
= 10, y_margin
= 10, r_margin
= 10,r_min
= 2, r_max
= 100, r_step
= 2):
area
= (c
.x()-c
.r(), c
.y()-c
.r(), 2*c
.r(), 2*c
.r())
cx
=c
.x()
cy
=c
.y()
#area为识别到的圆的区域,即圆的外接矩形框
statistics
= img
.get_statistics(roi
=area
)#像素颜色统计
print(statistics
)
#
(0,100,0,120,0,120)是红色的阈值,所以当区域内的众数(也就是最多的颜色),范围在这个阈值内,就说明是红色的圆。
#l_mode(),a_mode(),b_mode()是L通道,A通道,B通道的众数。
if 5<statistics
.l_mode()<20 and
0<statistics
.a_mode()<40 and
0<statistics
.b_mode()<40:#
if the circle is red
img
.draw_rectangle(area
, color
= (255, 0, 255))
#sending_data(c.x(),c.y())
c
=1
R
=0
sending_data(cx
,cy
)
elif
20<statistics
.l_mode()<40 and
-40<statistics
.a_mode()<0 and
-40<statistics
.b_mode()<0:
img
.draw_rectangle(area
, color
= (255, 255, 0))
c
=2
R
=0
sending_data(cx
,cy
)
elif
40<statistics
.l_mode()<60 and
-20<statistics
.a_mode()<40 and
-40<statistics
.b_mode()<50:
img
.draw_rectangle(area
, color
= (255, 255, 0))
c
=3
R
=0
sending_data(cx
,cy
)
recive_data()
else :
recive_data()
后续
其他单片机的接收函数只需要配置串口中断,然后在相应串口中断服务函数里面写好相应的解析函数即可,具体不在详解。发送函数只需发送0-9数字即可。