2022年电赛E题声源定位跟踪系统

2023-05-16

我们组本来是奔着视觉题去的,可是到比赛的时候突然发现好像就无人机比较合适,但是我们都没玩过无人机,本想转战小车,可是材料突然发现要两辆小车,材料也不够来不及买,于是我们就选了声源这道题,但是从来没有接触到这方面,最离谱的是刚开始我意会错题目,还想上摄像头和激光雷达哈哈哈哈。

 

 

之后我们就选用了k210的麦克风阵列来玩玩,还好之前有接触过,本想自己组装奈何实力不够,只能用现成的模块。

第一天我们试了网上的开源代码,发现这个阵列模块太容易受干扰了,于是我们组想先在k210阵列收音滤波后再转stm32控制舵机。代码如下,这个代码也可以直接k210接舵机使用,但是我们发现效果不佳。

from Maix import MIC_ARRAY as mic
from Maix import GPIO
import lcd,time,image
import math
import utime
from Maix import GPIO
from board import board_info
from fpioa_manager import fm
from machine import Timer,PWM
import time
#导入 FFT 模块

#输入时域数据(例如音频数据)并进行 FFT 运算
#res = FFT.run(data, points, shift)
###!!!!!!!!!!!!!!!!!!!!!!!注意注意注意!!!!!!!这些字一定要读!!!!!!!!!!
###!!!!!!!!!!!!!!!!!!!!!!!注意注意注意!!!!!!!!!!!!!!!!!!
###!!!!!!!!!!!!!!!!!!!!!!!注意注意注意!!!!!!!!!!!!!!!!!!
##########################################################################
##角度只取了阵列上字母s方向的五个RGB灯珠,大概60°,覆盖赛道,所以你的声源超过这个范围系统是不会反应的#############
##############距离只能在比赛规定场地测算,注意声源和系统垂直距离是275cm(D区中间)##################################
#########舵机口17,舵机我用的是270°舵机#######红外是1口,用HY.value(0)控制引脚高低电平#################################################
################你如果是180°舵机,需要把109行左右的Servo(S1,-Angle*0.666)中的0.666删掉#########################################
mic.init()#默认配置
lcd.init()   #320*240
#mic.init(i2s_d0=34, i2s_d1=8, i2s_d2=33, i2s_d3=9, i2s_ws=32, i2s_sclk=10,\
            #sk9822_dat=7, sk9822_clk=35)#可自定义配置 IO
io_led_red = 1
fm.register(io_led_red, fm.fpioa.GPIO0)#配置红外的GPIO
HY=GPIO(GPIO.GPIO0, GPIO.OUT)

fm.register(0, fm.fpioa.GPIO1)#配置两个开关的GPIO   是0和2脚 01是第二题 10第三题 11第四题
KG0=GPIO(GPIO.GPIO1, GPIO.IN, GPIO.PULL_DOWN)
                                                 #建议拿第四题测试
fm.register(2, fm.fpioa.GPIO2)#配置两个开关的GPIO   是0和2脚 01是第二题 10第三题 11第四题
KG1=GPIO(GPIO.GPIO2, GPIO.IN, GPIO.PULL_DOWN)
#KG0.value(1)
#image.font_load(image.UTF8, 16, 16, '/sd/0xA00000_font_uincode_16_16_tblr.Dzk')
#image.font_load(image.UTF8, 16, 16, 0xA00000)   #加载字库
tim = Timer(Timer.TIMER0, Timer.CHANNEL0, mode=Timer.MODE_PWM)
S1 = PWM(tim, freq=50, duty=0, pin=17)#舵机初始化

num=0
num2=0
Angle_LB = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
t=0
t1=0
t2=0
maxnum=0
minnum=0
jiaodu=0
Angle_last=0
b=[3,1,2,5,6]
i=100
a=[]
Biaozhi2=0    #函数2标志位
cishu=0
pid=0
err=0
JD=0
#以上变量都是给函数用的工具人,不用调用或者读取,没用

##########################卡尔曼##############################
KF_lastP=0.1  #上次的协方差
KF_nowP=0   #本次的协方差
KF_x_hat=0     #卡尔曼滤波的计算值,即为后验最优值
KF_Kg=0        #卡尔曼增益系数
KF_Q=0         #过程噪声
KF_R=0.01         #测量噪声
##################################################卡尔曼##########################
def Kalman_Filter(value):
    global KF_lastP        #上次的协方差
    global KF_nowP         #本次的协方差
    global KF_x_hat        #卡尔曼滤波的计算值,即为后验最优值
    global KF_Kg           #卡尔曼增益系数
    global KF_Q            #过程噪声
    global KF_R            #测量噪声
    output=0        #output为卡尔曼滤波计算值
    x_t=KF_x_hat    #当前先验预测值 = 上一次最优值
    KF_nowP=KF_lastP+KF_Q       #本次的协方差矩阵
    KF_Kg=KF_nowP/(KF_nowP+KF_R)#卡尔曼增益系数计算
    output=x_t+KF_Kg*(value-x_t)#当前最优值
    KF_x_hat=output     #更新最优值
    KF_lastP=(1-KF_Kg)*KF_nowP#更新协方差矩阵
    return output

##############################函数0###############################################
def get_med(jiaodu,cs):
    global a
    global num2
    a.append(jiaodu)
    if num2==(cs-1) :
        num2=0
        for j in range(1,len(a)):
            for i in range(len(a)-1):
                if a[i] > a[i+1]:
                    a[i], a[i+1] = a[i+1],a[i]
        t2=a[int((cs-1)/2)]
        a=[]      #清空,准备下一次测量
        return t2

    else :
        num2+=1
        return 1000

##############################函数1###############################################
def get_LB(jd,cs):       #滤波,jd是传入数据,cs是滤波等级要大于2,越高越慢,返回滤波后的数据
    global Angle_LB
    global num
    global minnum
    global jiaodu
    global maxnum
    Angle_LB[num]=jd
    if Angle_LB[num]>Angle_LB[maxnum] : maxnum=num  #取最大最小值的位号
    if Angle_LB[num]<Angle_LB[minnum] : minnum=num


    if num==cs:
       Angle_LB[maxnum]=0                          #去掉最大值最小值
       Angle_LB[minnum]=0
       for i in range(cs):
           jiaodu+=Angle_LB[i]
       jiaodu/=(cs-1)
       num=0
       maxnum=0
       minnum=0
       return int(jiaodu)
    else:
        num+=1
        return 1000
##############################函数2##########舵机函数###############################
def Servo(servo,angle):
    S1.duty((angle+90)/180*10+2.5)
##############################函数3######第四题函数###############################
def get_mic_dir4():
    global Angle_LB
    global Angle_last
    global pid
    global JD
    AngleX=0
    AngleY=0
    AngleR=0
    Angle=0
    AngleAddPi=0
    Juli=0
    mic_list=[]
    imga = mic.get_map()    # 获取声音源分布图像(返回声源黑白位图)
    b = mic.get_dir(imga)   # 计算、获取声源方向(从声源位图计算声源方向 返回12个强度值 对应12个LED灯)
    #print(b[0],b[1],b[2],b[10],b[11])

    for i in range(len(b)):
        if b[i]>=0:
            AngleX+= b[i] * math.sin(i * math.pi/6)
            AngleY+= b[i] * math.cos(i * math.pi/6)
    AngleX=round(AngleX,6) #计算坐标转换值
    AngleY=round(AngleY,6)
    if AngleY<0:AngleAddPi=180
    if AngleX<0 and AngleY > 0:AngleAddPi=360
    if AngleX!=0 or AngleY!=0: #参数修正
        if AngleY==0:
            Angle=90 if AngleX>0 else 270 #填补X轴角度
        else:
            Angle=AngleAddPi+round(math.degrees(math.atan(AngleX/AngleY)),4) #计算角度



        if (Angle>0 and Angle<45)or (Angle>315 and Angle<360):



                if Angle>315 and Angle<360:             #处理315-360的角度值
                    Angle=Angle-360

                Angle=Angle_last*0.1+ Angle*0.9      #低通滤波

                t=get_LB(Angle,3)           #滤波,jd是传入数据,cs是滤波等级,越高越慢,返回滤波后的数据


                if t !=1000 :
                    #t1=get_med(t,3)    #再取中位数
                    #if t1 !=1000 :
                    if t>30 : t=30
                    if t<-30 : t=-30
                    Angle=t
                    Kalman_Filter(Angle)
                    Angle_last=Angle
                    lcd.draw_string(60, 200, "Angle: " + str(-Angle), lcd.BLUE, lcd.BLACK)
                    lcd.draw_string(60, 180, "Distance: " + str(275/math.cos(-Angle*math.pi/180)), lcd.BLUE, lcd.BLACK)

                    #Servo(S1,-pid*0.666)       #控制270°舵机,180°把0.666删除
                    lcd.fill_rectangle(251,10, 25, 225, (0, 0, 0))    #清空右边的区域
                    lcd.fill_rectangle(251,int(108+math.tan(Angle*math.pi/180)*167), 15, 15, (0, 255,200))#角度位置实时
                    JD=Angle


        AngleR=round(math.sqrt(AngleY*AngleY+AngleX*AngleX),4) #计算强度
        mic_list.append(AngleX)     #X坐标
        mic_list.append(AngleY)     #Y坐标
        mic_list.append(AngleR)     #强度
        mic_list.append(Angle)      #角度

        #Juli=2.5/math.cos(Angle)
        #mic_list.append(Juli)
        #print(Juli)
    a = mic.set_led(b,(10,10,0))# 配置 RGB LED 颜色值   (从计算的声源方向设置点亮对应的LED灯)
    #lcd.display(0,color=(255,0,0))
    #img1=draw_line(100,0,100,240,color=(255,0,0))
    #lcd.display(img1)

    #lcd._line(150,0,150,240,color=(255,0,0))
    #img.draw_rectangle((30,30,50,50), color = (255, 0, 0))


    return mic_list #返回列表,X坐标,Y坐标,强度,角度
##############################函数3######第三题函数###############################
def get_mic_dir3():
    global Angle_LB
    global Angle_last
    global cishu
    AngleX=0
    AngleY=0
    AngleR=0
    Angle=0
    AngleAddPi=0
    Juli=0
    mic_list=[]
    imga = mic.get_map()    # 获取声音源分布图像(返回声源黑白位图)
    b = mic.get_dir(imga)   # 计算、获取声源方向(从声源位图计算声源方向 返回12个强度值 对应12个LED灯)
    #print(b[0],b[1],b[2],b[10],b[11])
    cishu+=1   #判断进入函数的次数
    if cishu==1 :
        HY.value(1)              # 第一次设置红外地线高电平,关闭红外
    for i in range(len(b)):
        if b[i]>=2:
            AngleX+= b[i] * math.sin(i * math.pi/6)
            AngleY+= b[i] * math.cos(i * math.pi/6)
    AngleX=round(AngleX,6) #计算坐标转换值
    AngleY=round(AngleY,6)
    if AngleY<0:AngleAddPi=180
    if AngleX<0 and AngleY > 0:AngleAddPi=360
    if AngleX!=0 or AngleY!=0: #参数修正
        if AngleY==0:
            Angle=90 if AngleX>0 else 270 #填补X轴角度
        else:
            Angle=AngleAddPi+round(math.degrees(math.atan(AngleX/AngleY)),4) #计算角度



        if (Angle>0 and Angle<45)or (Angle>315 and Angle<360):

                if Angle>315 and Angle<360:             #处理330-360的角度值
                    #if Angle<340 : Angle=Angle-5
                    Angle=Angle-360
                #if Angle>10 and Angle<45:
                    #Angle=Angle+10
                Angle=Angle_last*0.1+ Angle*0.9      #低通滤波

                t=get_LB(Angle,10)           #滤波,jd是传入数据,cs是滤波等级,越高越慢,返回滤波后的数据


                if t !=1000 :
                    t1=get_med(t,3)    #再取中位数
                    if t1 !=1000 :
                        if t1>30 : t1=30
                        if t1<-30 : t1=-30
                        Angle=t1
                        Angle_last=Angle
                        HY.value(0)              # 设置红外地线低电平,开启红外
                        lcd.draw_string(60, 200, "Angle: " + str(-Angle), lcd.BLUE, lcd.BLACK)
                        lcd.draw_string(60, 180, "Distance: " + str(275/math.cos(-Angle*math.pi/180)), lcd.BLUE, lcd.BLACK)
                        #距离只能在比赛规定场地测算,注意声源和系统垂直距离是275cm(D区中间)

                        Servo(S1,-Angle*0.666)       #控制270°舵机,180°把0.75删除
                        lcd.fill_rectangle(251,10, 25, 225, (0, 0, 0))    #清空右边的区域
                        lcd.fill_rectangle(251,int(108+math.tan(Angle*math.pi/180)*165), 15, 15, (0, 255,200))#角度位置实时



        AngleR=round(math.sqrt(AngleY*AngleY+AngleX*AngleX),4) #计算强度
        mic_list.append(AngleX)     #X坐标
        mic_list.append(AngleY)     #Y坐标
        mic_list.append(AngleR)     #强度
        mic_list.append(Angle)      #角度

        #Juli=2.5/math.cos(Angle)
        #mic_list.append(Juli)
        #print(Juli)
    a = mic.set_led(b,(10,10,0))# 配置 RGB LED 颜色值   (从计算的声源方向设置点亮对应的LED灯)
    #lcd.display(0,color=(255,0,0))
    #img1=draw_line(100,0,100,240,color=(255,0,0))
    #lcd.display(img1)

    #lcd._line(150,0,150,240,color=(255,0,0))
    #img.draw_rectangle((30,30,50,50), color = (255, 0, 0))


    return mic_list #返回列表,X坐标,Y坐标,强度,角度

##############################函数5###############################################
def get_mic_dir2():   ######################第二题函数
    global Angle_LB
    global Angle_last
    AngleX=0
    AngleY=0
    AngleR=0
    Angle=0
    AngleAddPi=0
    Juli=0
    mic_list=[]
    imga = mic.get_map()    # 获取声音源分布图像(返回声源黑白位图)
    b = mic.get_dir(imga)   # 计算、获取声源方向(从声源位图计算声源方向 返回12个强度值 对应12个LED灯)
    #print(b[0],b[1],b[2],b[10],b[11])
    Servo(S1,0)       #控制270°舵机保持中立
    HY.value(1)              # 设置红外地线高电平,关闭红外
    for i in range(len(b)):
        if b[i]>=2:
            AngleX+= b[i] * math.sin(i * math.pi/6)
            AngleY+= b[i] * math.cos(i * math.pi/6)
    AngleX=round(AngleX,6) #计算坐标转换值
    AngleY=round(AngleY,6)
    if AngleY<0:AngleAddPi=180
    if AngleX<0 and AngleY > 0:AngleAddPi=360
    if AngleX!=0 or AngleY!=0: #参数修正
        if AngleY==0:
            Angle=90 if AngleX>0 else 270 #填补X轴角度
        else:
            Angle=AngleAddPi+round(math.degrees(math.atan(AngleX/AngleY)),4) #计算角度



        if (Angle>0 and Angle<45)or (Angle>315 and Angle<360):



                if Angle>315 and Angle<360:             #处理330-360的角度值
                    if Angle<330 : Angle=Angle-9
                    Angle=Angle-350
                #Angle=Angle_last*0.3+ Angle*0.7      #低通滤波

                t=get_LB(Angle,5)           #滤波,jd是传入数据,cs是滤波等级,越高越慢,返回滤波后的数据


                if t !=1000 :
                    t1=get_med(t,3)    #再取中位数
                    if t1 !=1000 :
                        if t1>30 : t1=30
                        if t1<-30 : t1=-30
                        Angle=t1
                        Angle_last=Angle
                        lcd.draw_string(60, 200, "Angle: " + str(-Angle), lcd.BLUE, lcd.BLACK)
                        lcd.draw_string(60, 180, "Distance: " + str(275/math.cos(-Angle*math.pi/180)), lcd.BLUE, lcd.BLACK)
                        #距离只能在比赛规定场地测算,注意声源和系统垂直距离是275cm(D区中间)


                        lcd.fill_rectangle(251,10, 25, 225, (0, 0, 0))    #清空右边的区域
                        lcd.fill_rectangle(251,int(108+math.tan(Angle*math.pi/180)*165), 15, 15, (0, 255,200))#角度位置实时
                        #Biaozhi2=1   #等于1就不会再进入该函数了


        AngleR=round(math.sqrt(AngleY*AngleY+AngleX*AngleX),4) #计算强度
        mic_list.append(AngleX)     #X坐标
        mic_list.append(AngleY)     #Y坐标
        mic_list.append(AngleR)     #强度
        mic_list.append(Angle)      #角度

        #Juli=2.5/math.cos(Angle)
        #mic_list.append(Juli)
        #print(Juli)
    a = mic.set_led(b,(10,10,0))# 配置 RGB LED 颜色值   (从计算的声源方向设置点亮对应的LED灯)
    #lcd.display(0,color=(255,0,0))
    #img1=draw_line(100,0,100,240,color=(255,0,0))
    #lcd.display(img1)

    #lcd._line(150,0,150,240,color=(255,0,0))
    #img.draw_rectangle((30,30,50,50), color = (255, 0, 0))


    return mic_list #返回列表,X坐标,Y坐标,强度,角度
################################下面是只运行一次的程序###############################
lcd.fill_rectangle(46,5, 230, 4, (255, 0, 0))    #上边线
lcd.fill_rectangle(46,5, 4, 230, (255, 0, 0))    #左边线
lcd.fill_rectangle(46,235, 230, 4, (255, 0, 0))    #下边线
lcd.fill_rectangle(276,5, 4, 234, (255, 0, 0))   #右边线
lcd.fill_rectangle(237,5, 4, 234, (255, 0, 0))    #右边线2

lcd.fill_rectangle(0,77, 47, 4, (255, 0, 0))    #左区域上边线
lcd.fill_rectangle(0,154, 47, 4, (255, 0, 0))    #左区域下边线
lcd.fill_rectangle(0,77, 4, 77, (255, 0, 0))    #左区域左边线
#img.draw_string(20, 60, b'你好,世界', scale=1, color=(0,0,255), x_spacing=2, mono_space=1)


##############################主循环,###############################################
#这里因为我的2引脚有问题,下拉不了,如果你的引脚初始电平是0,就不用(~KG1.value()+2)这个处理了
#可以直接用KG1.value()==1来判断,如果有问题,就把这几个if删掉,保留第四题中的函数,程序才能跑
while True:
   #引脚0和2的电平是01代表第二题,且第二题只会进行一次,返回一个值在屏幕
    #if (KG0.value()==0)and((~KG1.value()+2)==1) :
       #get_mic_dir2()
                                     ##引脚0和2的电平是10代表第三题
    #if (KG0.value()==1)and((~KG1.value()+2)==0) :
       #get_mic_dir3()
                                     ###引脚0和2的电平是11代表第四题
    #if (KG0.value()==1)and((~KG1.value()+2)==1) :
       get_mic_dir4()
       err=JD-pid           #简易PID控制舵机
       pid+=err*0.1
       Servo(S1,-pid*0.666)       #控制270°舵机,180°把0.666删除

    #print(KG0.value(),(~KG1.value()+2))
    #get_mic_dir()
    #time.sleep_ms(1)

第二天我们组装麦克风阵列和云台开始调试。代码如下最后发现还是定点还是会有很大的误差,时准时不准。代码更改如下

from Maix import MIC_ARRAY as mic
from Maix import GPIO
import lcd,time,image
import math
import utime
from Maix import GPIO
from board import board_info
from fpioa_manager import fm
from machine import Timer,PWM
import time
#导入 FFT 模块

#输入时域数据(例如音频数据)并进行 FFT 运算
#res = FFT.run(data, points, shift)
###!!!!!!!!!!!!!!!!!!!!!!!注意注意注意!!!!!!!这些字一定要读!!!!!!!!!!
###!!!!!!!!!!!!!!!!!!!!!!!注意注意注意!!!!!!!!!!!!!!!!!!
###!!!!!!!!!!!!!!!!!!!!!!!注意注意注意!!!!!!!!!!!!!!!!!!
##########################################################################
##角度只取了阵列上字母s方向的五个RGB灯珠,大概60°,覆盖赛道,所以你的声源超过这个范围系统是不会反应的#############
##############距离只能在比赛规定场地测算,注意声源和系统垂直距离是275cm(D区中间)##################################
#########舵机口17,舵机我用的是270°舵机#######红外是1口,用HY.value(0)控制引脚高低电平#################################################
################你如果是180°舵机,需要把109行左右的Servo(S1,-Angle*0.666)中的0.666删掉#########################################
mic.init(i2s_d0=23, i2s_d1=22, i2s_d2=21, i2s_d3=20, i2s_ws=19, i2s_sclk=18, sk9822_dat=24, sk9822_clk=25)
lcd.init()   #320*240
#mic.init(i2s_d0=34, i2s_d1=8, i2s_d2=33, i2s_d3=9, i2s_ws=32, i2s_sclk=10,\
            #sk9822_dat=7, sk9822_clk=35)#可自定义配置 IO
io_led_red = 1
fm.register(io_led_red, fm.fpioa.GPIO0)#配置红外的GPIO
HY=GPIO(GPIO.GPIO0, GPIO.OUT)

fm.register(0, fm.fpioa.GPIO1)#配置两个开关的GPIO   是0和2脚 01是第二题 10第三题 11第四题
KG0=GPIO(GPIO.GPIO1, GPIO.IN, GPIO.PULL_DOWN)
                                                 #建议拿第四题测试
fm.register(2, fm.fpioa.GPIO2)#配置两个开关的GPIO   是0和2脚 01是第二题 10第三题 11第四题
KG1=GPIO(GPIO.GPIO2, GPIO.IN, GPIO.PULL_DOWN)
#KG0.value(1)
#image.font_load(image.UTF8, 16, 16, '/sd/0xA00000_font_uincode_16_16_tblr.Dzk')
#image.font_load(image.UTF8, 16, 16, 0xA00000)   #加载字库
tim = Timer(Timer.TIMER0, Timer.CHANNEL0, mode=Timer.MODE_PWM)
S1 = PWM(tim, freq=50, duty=0, pin=17)#舵机初始化

num=0
num2=0
Angle_LB = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
t=0
t1=0
t2=0
maxnum=0
minnum=0
jiaodu=0
Angle_last=0
b=[3,1,2,5,6]
i=100
a=[]
Biaozhi2=0    #函数2标志位
cishu=0
pid=0
err=0
JD=0
#以上变量都是给函数用的工具人,不用调用或者读取,没用

##########################卡尔曼##############################
KF_lastP=0.1  #上次的协方差
KF_nowP=0   #本次的协方差
KF_x_hat=0     #卡尔曼滤波的计算值,即为后验最优值
KF_Kg=0        #卡尔曼增益系数
KF_Q=0         #过程噪声
KF_R=0.01         #测量噪声
##################################################卡尔曼##########################
def Kalman_Filter(value):
    global KF_lastP        #上次的协方差
    global KF_nowP         #本次的协方差
    global KF_x_hat        #卡尔曼滤波的计算值,即为后验最优值
    global KF_Kg           #卡尔曼增益系数
    global KF_Q            #过程噪声
    global KF_R            #测量噪声
    output=0        #output为卡尔曼滤波计算值
    x_t=KF_x_hat    #当前先验预测值 = 上一次最优值
    KF_nowP=KF_lastP+KF_Q       #本次的协方差矩阵
    KF_Kg=KF_nowP/(KF_nowP+KF_R)#卡尔曼增益系数计算
    output=x_t+KF_Kg*(value-x_t)#当前最优值
    KF_x_hat=output     #更新最优值
    KF_lastP=(1-KF_Kg)*KF_nowP#更新协方差矩阵
    return output

##############################函数0###############################################
def get_med(jiaodu,cs):
    global a
    global num2
    a.append(jiaodu)
    if num2==(cs-1) :
        num2=0
        for j in range(1,len(a)):
            for i in range(len(a)-1):
                if a[i] > a[i+1]:
                    a[i], a[i+1] = a[i+1],a[i]
        t2=a[int((cs-1)/2)]
        a=[]      #清空,准备下一次测量
        return t2

    else :
        num2+=1
        return 1000

##############################函数1###############################################
def get_LB(jd,cs):       #滤波,jd是传入数据,cs是滤波等级要大于2,越高越慢,返回滤波后的数据
    global Angle_LB
    global num
    global minnum
    global jiaodu
    global maxnum
    Angle_LB[num]=jd
    if Angle_LB[num]>Angle_LB[maxnum] : maxnum=num  #取最大最小值的位号
    if Angle_LB[num]<Angle_LB[minnum] : minnum=num


    if num==cs:
       Angle_LB[maxnum]=0                          #去掉最大值最小值
       Angle_LB[minnum]=0
       for i in range(cs):
           jiaodu+=Angle_LB[i]
       jiaodu/=(cs-1)
       num=0
       maxnum=0
       minnum=0
       return int(jiaodu)
    else:
        num+=1
        return 1000
##############################函数2##########舵机函数###############################
def Servo(servo,angle):
    S1.duty((angle+90)/180*10+2.5)
##############################函数3######第四题函数###############################
def get_mic_dir4():
    global Angle_LB
    global Angle_last
    global pid
    global JD
    AngleX=0
    AngleY=0
    AngleR=0
    Angle=0
    AngleAddPi=0
    Juli=0
    mic_list=[]
    imga = mic.get_map()    # 获取声音源分布图像(返回声源黑白位图)
    b = mic.get_dir(imga)   # 计算、获取声源方向(从声源位图计算声源方向 返回12个强度值 对应12个LED灯)
    #print(b[0],b[1],b[2],b[10],b[11])

    for i in range(len(b)):
        if b[i]>=0:
            AngleX+= b[i] * math.sin(i * math.pi/6)
            AngleY+= b[i] * math.cos(i * math.pi/6)
    AngleX=round(AngleX,6) #计算坐标转换值
    AngleY=round(AngleY,6)
    if AngleY<0:AngleAddPi=180
    if AngleX<0 and AngleY > 0:AngleAddPi=360
    if AngleX!=0 or AngleY!=0: #参数修正
        if AngleY==0:
            Angle=90 if AngleX>0 else 270 #填补X轴角度
        else:
            Angle=AngleAddPi+round(math.degrees(math.atan(AngleX/AngleY)),4) #计算角度



        if (Angle>0 and Angle<45)or (Angle>315 and Angle<360):



                if Angle>315 and Angle<360:             #处理315-360的角度值
                    Angle=Angle-360

                Angle=Angle_last*0.1+ Angle*0.9      #低通滤波+

                t=get_LB(Angle,3)           #滤波,jd是传入数据,cs是滤波等级,越高越慢,返回滤波后的数据


                if t !=1000 :
                    #t1=get_med(t,3)    #再取中位数
                    #if t1 !=1000 :
                    if t>30 : t=30
                    if t<-30 : t=-30
                    Angle=t
                    Kalman_Filter(Angle)
                    Angle_last=Angle
                    lcd.draw_string(60, 200, "Angle: " + str(-Angle), lcd.BLUE, lcd.BLACK)
                    lcd.draw_string(60, 180, "Distance: " + str(275/math.cos(-Angle*math.pi/180)), lcd.BLUE, lcd.BLACK)

                    #Servo(S1,-pid*0.666)       #控制270°舵机,180°把0.666删除
                    lcd.fill_rectangle(251,10, 25, 225, (0, 0, 0))    #清空右边的区域
                    lcd.fill_rectangle(251,int(108+math.tan(Angle*math.pi/180)*167), 15, 15, (0, 255,200))#角度位置实时
                    JD=Angle


        AngleR=round(math.sqrt(AngleY*AngleY+AngleX*AngleX),4) #计算强度
        mic_list.append(AngleX)     #X坐标
        mic_list.append(AngleY)     #Y坐标
        mic_list.append(AngleR)     #强度
        mic_list.append(Angle)      #角度

        #Juli=2.5/math.cos(Angle)
        #mic_list.append(Juli)
        #print(Juli)
    a = mic.set_led(b,(10,10,0))# 配置 RGB LED 颜色值   (从计算的声源方向设置点亮对应的LED灯)
    #lcd.display(0,color=(255,0,0))
    #img1=draw_line(100,0,100,240,color=(255,0,0))
    #lcd.display(img1)

    #lcd._line(150,0,150,240,color=(255,0,0))
    #img.draw_rectangle((30,30,50,50), color = (255, 0, 0))


    return mic_list #返回列表,X坐标,Y坐标,强度,角度
##############################函数3######第三题函数###############################
def get_mic_dir3():
    global Angle_LB
    global Angle_last
    global cishu
    AngleX=0
    AngleY=0
    AngleR=0
    Angle=0
    AngleAddPi=0
    Juli=0
    mic_list=[]
    imga = mic.get_map()    # 获取声音源分布图像(返回声源黑白位图)
    b = mic.get_dir(imga)   # 计算、获取声源方向(从声源位图计算声源方向 返回12个强度值 对应12个LED灯)
    #print(b[0],b[1],b[2],b[10],b[11])
    cishu+=1   #判断进入函数的次数
    if cishu==1 :
        HY.value(1)              # 第一次设置红外地线高电平,关闭红外
    for i in range(len(b)):
        if b[i]>=2:
            AngleX+= b[i] * math.sin(i * math.pi/6)
            AngleY+= b[i] * math.cos(i * math.pi/6)
    AngleX=round(AngleX,6) #计算坐标转换值
    AngleY=round(AngleY,6)
    if AngleY<0:AngleAddPi=180
    if AngleX<0 and AngleY > 0:AngleAddPi=360
    if AngleX!=0 or AngleY!=0: #参数修正
        if AngleY==0:
            Angle=90 if AngleX>0 else 270 #填补X轴角度
        else:
            Angle=AngleAddPi+round(math.degrees(math.atan(AngleX/AngleY)),4) #计算角度



        if (Angle>0 and Angle<45)or (Angle>315 and Angle<360):

                if Angle>315 and Angle<360:             #处理330-360的角度值
                    #if Angle<340 : Angle=Angle-5
                    Angle=Angle-360
                #if Angle>10 and Angle<45:
                    #Angle=Angle+10
                Angle=Angle_last*0.1+ Angle*0.9      #低通滤波

                t=get_LB(Angle,10)           #滤波,jd是传入数据,cs是滤波等级,越高越慢,返回滤波后的数据


                if t !=1000 :
                    t1=get_med(t,3)    #再取中位数
                    if t1 !=1000 :
                        if t1>30 : t1=30
                        if t1<-30 : t1=-30
                        Angle=t1
                        Angle_last=Angle
                        HY.value(0)              # 设置红外地线低电平,开启红外
                        lcd.draw_string(60, 200, "Angle: " + str(-Angle), lcd.BLUE, lcd.BLACK)
                        lcd.draw_string(60, 180, "Distance: " + str(275/math.cos(-Angle*math.pi/180)), lcd.BLUE, lcd.BLACK)
                        #距离只能在比赛规定场地测算,注意声源和系统垂直距离是275cm(D区中间)

                        Servo(S1,-Angle*0.666)       #控制270°舵机,180°把0.75删除
                        lcd.fill_rectangle(251,10, 25, 225, (0, 0, 0))    #清空右边的区域
                        lcd.fill_rectangle(251,int(108+math.tan(Angle*math.pi/180)*165), 15, 15, (0, 255,200))#角度位置实时



        AngleR=round(math.sqrt(AngleY*AngleY+AngleX*AngleX),4) #计算强度
        mic_list.append(AngleX)     #X坐标
        mic_list.append(AngleY)     #Y坐标
        mic_list.append(AngleR)     #强度
        mic_list.append(Angle)      #角度

        #Juli=2.5/math.cos(Angle)
        #mic_list.append(Juli)
        #print(Juli)
    a = mic.set_led(b,(10,10,0))# 配置 RGB LED 颜色值   (从计算的声源方向设置点亮对应的LED灯)
    #lcd.display(0,color=(255,0,0))
    #img1=draw_line(100,0,100,240,color=(255,0,0))
    #lcd.display(img1)

    #lcd._line(150,0,150,240,color=(255,0,0))
    #img.draw_rectangle((30,30,50,50), color = (255, 0, 0))


    return mic_list #返回列表,X坐标,Y坐标,强度,角度

##############################函数5###############################################
def get_mic_dir2():   ######################第二题函数
    global Angle_LB
    global Angle_last
    AngleX=0
    AngleY=0
    AngleR=0
    Angle=0
    AngleAddPi=0
    Juli=0
    mic_list=[]
    imga = mic.get_map()    # 获取声音源分布图像(返回声源黑白位图)
    b = mic.get_dir(imga)   # 计算、获取声源方向(从声源位图计算声源方向 返回12个强度值 对应12个LED灯)
    #print(b[0],b[1],b[2],b[10],b[11])
    Servo(S1,0)       #控制270°舵机保持中立
    HY.value(1)              # 设置红外地线高电平,关闭红外
    for i in range(len(b)):
        if b[i]>=2:
            AngleX+= b[i] * math.sin(i * math.pi/6)
            AngleY+= b[i] * math.cos(i * math.pi/6)
    AngleX=round(AngleX,6) #计算坐标转换值
    AngleY=round(AngleY,6)
    if AngleY<0:AngleAddPi=180
    if AngleX<0 and AngleY > 0:AngleAddPi=360
    if AngleX!=0 or AngleY!=0: #参数修正
        if AngleY==0:
            Angle=90 if AngleX>0 else 270 #填补X轴角度
        else:
            Angle=AngleAddPi+round(math.degrees(math.atan(AngleX/AngleY)),4) #计算角度



        if (Angle>0 and Angle<45)or (Angle>315 and Angle<360):



                if Angle>315 and Angle<360:             #处理330-360的角度值
                    if Angle<330 : Angle=Angle-9
                    Angle=Angle-350
                #Angle=Angle_last*0.3+ Angle*0.7      #低通滤波

                t=get_LB(Angle,5)           #滤波,jd是传入数据,cs是滤波等级,越高越慢,返回滤波后的数据


                if t !=1000 :
                    t1=get_med(t,3)    #再取中位数
                    if t1 !=1000 :
                        if t1>30 : t1=30
                        if t1<-30 : t1=-30
                        Angle=t1
                        Angle_last=Angle
                        lcd.draw_string(60, 200, "Angle: " + str(-Angle), lcd.BLUE, lcd.BLACK)
                        lcd.draw_string(60, 180, "Distance: " + str(275/math.cos(-Angle*math.pi/180)), lcd.BLUE, lcd.BLACK)
                        #距离只能在比赛规定场地测算,注意声源和系统垂直距离是275cm(D区中间)


                        lcd.fill_rectangle(251,10, 25, 225, (0, 0, 0))    #清空右边的区域
                        lcd.fill_rectangle(251,int(108+math.tan(Angle*math.pi/180)*165), 15, 15, (0, 255,200))#角度位置实时
                        #Biaozhi2=1   #等于1就不会再进入该函数了


        AngleR=round(math.sqrt(AngleY*AngleY+AngleX*AngleX),4) #计算强度
        mic_list.append(AngleX)     #X坐标
        mic_list.append(AngleY)     #Y坐标
        mic_list.append(AngleR)     #强度
        mic_list.append(Angle)      #角度

        #Juli=2.5/math.cos(Angle)
        #mic_list.append(Juli)
        #print(Juli)
    a = mic.set_led(b,(10,10,0))# 配置 RGB LED 颜色值   (从计算的声源方向设置点亮对应的LED灯)
    #lcd.display(0,color=(255,0,0))
    #img1=draw_line(100,0,100,240,color=(255,0,0))
    #lcd.display(img1)

    #lcd._line(150,0,150,240,color=(255,0,0))
    #img.draw_rectangle((30,30,50,50), color = (255, 0, 0))


    return mic_list #返回列表,X坐标,Y坐标,强度,角度
################################下面是只运行一次的程序###############################
lcd.fill_rectangle(46,5, 230, 4, (255, 0, 0))    #上边线
lcd.fill_rectangle(46,5, 4, 230, (255, 0, 0))    #左边线
lcd.fill_rectangle(46,235, 230, 4, (255, 0, 0))    #下边线
lcd.fill_rectangle(276,5, 4, 234, (255, 0, 0))   #右边线
lcd.fill_rectangle(237,5, 4, 234, (255, 0, 0))    #右边线2

lcd.fill_rectangle(0,77, 47, 4, (255, 0, 0))    #左区域上边线
lcd.fill_rectangle(0,154, 47, 4, (255, 0, 0))    #左区域下边线
lcd.fill_rectangle(0,77, 4, 77, (255, 0, 0))    #左区域左边线
#img.draw_string(20, 60, b'你好,世界', scale=1, color=(0,0,255), x_spacing=2, mono_space=1)


##############################主循环,###############################################
#这里因为我的2引脚有问题,下拉不了,如果你的引脚初始电平是0,就不用(~KG1.value()+2)这个处理了
#可以直接用KG1.value()==1来判断,如果有问题,就把这几个if删掉,保留第四题中的函数,程序才能跑
while True:
   #引脚0和2的电平是01代表第二题,且第二题只会进行一次,返回一个值在屏幕
    #if (KG0.value()==0)and((~KG1.value()+2)==1) :
       #get_mic_dir2()
                                     ##引脚0和2的电平是10代表第三题
    #if (KG0.value()==1)and((~KG1.value()+2)==0) :
       #get_mic_dir3()
                                     ###引脚0和2的电平是11代表第四题
    #if (KG0.value()==1)and((~KG1.value()+2)==1) :
       get_mic_dir4()
       err=JD-pid           #简易PID控制舵机
       pid+=err*0.1
       Servo(S1,-pid*0.666)       #控制270°舵机,180°把0.666删除

    #print(KG0.value(),(~KG1.value()+2))
    #get_mic_dir()
    #time.sleep_ms(1)

第三天,选音乐,没办法像大佬他们一样用特定频率去接收音频,接着就是调试,调试

 第四天写论文听天由命哈哈哈哈,之后就封箱等检测了。需要stm32端代码的可以私聊我。

最近有玩这声源题的小伙伴有点多,在这里放百度云的链接,之前打电赛的代码都放里面了,有单纯k210和模块的连接就可运行的代码,也有k210与stm32之间通讯控制的代码,继电器控制激光笔,用stm32代码先烧录k210对应的代码进k210在接stm32。代码因为比赛时间紧写得不好,我们是在里面写了两套,一套是两个麦克风阵列模块,一套是我们比赛只用一个麦克风阵列模块,都写在一个stm32代码里面了,有需要的小伙伴可参考一下,代码写得不好的话轻喷哈哈哈。

链接:https://pan.baidu.com/s/1-y6ok394kM8b801JyysLbQ 
提取码:1111 
--来自百度网盘超级会员V3的分享

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

2022年电赛E题声源定位跟踪系统 的相关文章

  • QT/C++——主窗口和事件处理

    一 主窗口 上面就是一个主窗口 xff0c 主窗口中的每一个都是Action 这次新建工程要选择mainwindow ifndef MAINWINDOW H define MAINWINDOW H include lt QMainWindo
  • QT/C++——网络编程

    目录 一 基础知识复习 二 UDP 客户端 xff1a 服务器 xff1a 三 TCP 服务器 xff1a 客户端 xff1a 四 小项目 客户端 xff1a 服务器 xff1a 一 基础知识复习 这部分内容前面讲的比较详细 xff0c 现
  • Linux驱动开发——高级I/O操作(一)

    一个设备除了能通过读写操作来收发数据或返回 保存数据 xff0c 还应该有很多其他的操作 比如一个串口设备还应该具备波特率获取和设置 帧格式获取和设置的操作 一个LED设备甚至不应该有读写操作 xff0c 而应该具备点灯和灭灯的操作 硬件设
  • ubuntu22.04安装与配置

    目录 一 环境及下载 iso下载 VM配置 二 虚拟机与环境配置 虚拟机开始后的配置 一些工具配置 参考 xff1a VMware Workstation Pro 文档 一 环境及下载 iso下载 Download Ubuntu Deskt
  • Linux——互斥与同步

    目录 一种典型的竞态 内核中的并发 中断屏蔽 原子变量 自旋锁 读写锁 顺序锁 一种典型的竞态 假设整型变量i是驱动代码中的一个个全局变量 xff0c 在驱动的某个例程中执行了i 43 43 操作 xff0c 而在中断服务程序中也执行了i
  • 基于max30102的物联网病房监测系统(传感驱动和数据处理)

    目录 一 实物展示 二 主体介绍 三 MAX30102的驱动 四 MAX30102的数据处理 奋斗一个星期 xff0c 每个引脚都是扒皮焊接然后再把皮包回去的 这几天吸的垃圾气体感觉要少活两年 一 实物展示 这次吸取上次教训 xff0c 把
  • 基于max30102的物联网病房监测系统(中断处理和主题逻辑)

    目录 五 中断处理 六 主体框架 对采集数据的初始化 核心功能的实现 烟雾 通信帧格式 wifi接收数据的处理 OLED显示 五 中断处理 void SysTick Handler void TimingDelay Decrement vo
  • 无人机4G数传方案(合宙cat1模块)

    一 合宙Cat1简介 YED C724 核心板是由银尔达 xff08 yinerda xff09 基于合宙 Air724 模组推出的低功耗 xff0c 超小体积 xff0c 高性能嵌入式 4G Cat1 核心版 xff0c 标准的 2 54
  • C++学习ros2话题机制(发布与订阅)

    C 43 43 学习ros2 一 创建文件和文件夹1 结构2 创建工作空间和工作包3 直接创建node cpp文件 二 编写节点文件 xff08 发布订阅 xff09 1 node1 cpp xff08 发布 xff09 2 CMakeLi
  • AttributeError: module ‘keras.backend’ has no attribute ‘set_image_dim_ordering’

    问题 原始代码如下 xff1a keras span class token punctuation span backend span class token punctuation span set image dim ordering
  • openmv识别红色物体并返回坐标给stm32单片机,通过pid控制舵机云台

    本人搜索了有关于舵机云台pid控制的代码 xff0c 但是都没有搜到想要的结果 xff0c 现在自己写出来了代码 xff0c 所以就将自己写的代码分享出来 xff0c 和大家一起学习进步 1 openmv识别红色物体 43 返回中心坐标的的
  • vs解决报错:C++ qualified name is not allowed(E0283)

    我们看 把在GCC下编译过关的c 43 43 程序放在vs下却不能过 仅给出部分代码 其他以此类推 先不要慌着改 看下详细信息 看上去都是语法错误 但这真的没任何语法错误啊 百度上查找下 报错信息都不一样 别人是类里面多加限定符 我这是正常
  • Linux下的man命令

    目录 一 man是什么 xff1f 二 man命令的使用1 通过man man查看man手册2 通过man来进行查询 四 总结 一 man是什么 xff1f man所代表的的是英文单词manual xff0c 也就是帮助手册的意思 xff0
  • IO多路复用之select

    目录 一 IO多路复用二 select函数三 select实现socket服务器 xff08 1 xff09 流程图 xff1a xff08 2 xff09 代码讲解 xff1a 四 总结代码示例 xff1a 一 IO多路复用 IO多路复用
  • curl 和 wget 命令下载

    curl 和 wget 命令下载 一 wget下载1 wget介绍2 wget下载方法 二 curl下载1 curl介绍2 curl下载方法 三 wget下载sqlite实例总结 一 wget下载 1 wget介绍 wget 是一个从网络上
  • Linux下载安装和使用SQLite

    Linux安装SQLite 一 SQLite下载二 SQLite安装三 SQLite的使用1 解决无法直接用sqlit3命令2 解决无法编译的问题 总结 一 SQLite下载 首先 xff0c 前往SQLite官网下载页面找到包含confi
  • 解决:‘config.status: error: Something went wrong bootstrapping makefile fragments......’问题

    解决 xff1a config status error Something went wrong bootstrapping makefile fragments 问题 一 问题二 解决方法 一 问题 首先我们来看安装sqlite时报的这
  • TFTP服务器搭建与使用

    文章目录 一 TFTP协议二 TFTP服务器搭建1 安装TFTP服务器2 创建TFTP服务文件夹3 配置tftp文件4 配置tftpd hpa文件 三 TFTP服务器使用 一 TFTP协议 TFTP xff08 Trivial File T
  • 深入探讨Linux驱动开发:Linux设备树

    文章目录 一 设备树介绍二 设备树框架1 设备树框架2 节点基本格式3 节点部分属性简介 总结 一 设备树介绍 设备树 xff08 Device Tree xff0c 简称 DT xff09 是一种在嵌入式系统中描述硬件设备的一种数据结构和
  • 深入探讨Linux驱动开发:驱动介绍与hello驱动实例

    文章目录 前言一 Linux驱动介绍1 用户态和内核态2 内核功能介绍3 驱动程序介绍 二 驱动程序分类与注意事项1 驱动程序分类2 内核驱动开发注意事项 三 hello驱动开发1 驱动模块2 模块加载和卸载函数3 编写hello模块4 M

随机推荐

  • ROS中使用乐视 奥比中光(Astra Pro)深度相机显示彩色和深度图像

    环境 UbuntuROS Kinect or Melodic 奥比中光ROS驱动包安装地址 xff1a https github com orbbec ros astra camera 1 安装ROS 2 安装依赖 span class t
  • 深入探讨Linux驱动开发:字符设备驱动开发与测试

    文章目录 一 字符设备驱动介绍1 设备驱动介绍 二 设备号1 设备号介绍2 分配与释放设备编号 dev t类型 静态分配设备号 动态分配设备号 释放主次设备号 手动创建设备节点 自动创建设备节点 删除设备节点 三 字符设备注册1 cdev结
  • ZED-深度感知使用

    文章目录 1 深度感知配置2 得到深度数据2 1 得到深度值 3 展示深度图4 获取点云数据4 1 从点云数据中计算距离 5 得到法线图像6 调整深度分辨率 1 深度感知配置 可以在初始化时使用InitParameters xff0c 在运
  • Linux系统之 开机自启动程序脚本 编写

    Linux系统启动加载程序 最近完成了项目 xff0c 来个开机自启运行 找到已编译好的程序 xff08 以下是我编译的house xff09 span class token function ls span l span class t
  • 算法时间复杂度、空间复杂度分析

    算法时间复杂度 在计算机程序编写前 xff0c 依据统计方法对算法进行估算 xff0c 经过总结 xff0c 我们发现一个高级语言编写的程序程序在计算机上运行所消耗的时间取决于下列因素 1 算法采用的策略和方案 编译产生的代码质量 3 问题
  • Linux 选择题一百道

    cron 后台常驻程序 daemon 用于 xff1a A 负责文件在网络中的共享 B 管理打印子系统 C 跟踪管理系统信息和错误 D 管理系统日常任务的调度 在大多数Linux发行版本中 xff0c 以下哪个属于块设备 block dev
  • 程序返回return与系统退出exit

    程序返回return与系统退出exit return是语言级别的 xff0c 它表示了调用堆栈的返回 xff1b exit则是系统调用级别的 xff0c 它表示了一个进程的结束 return是返回函数调用 xff0c 如果返回的是main函
  • 结构体、结构体变量、结构体指针、字符串

    结构体 数组是用于保存一组相同类型数据的 而结构体是用于保存一组不同类型数组的 在使用结构体之前必须先定义结构体类型 因为C语言不知道你的结构体中需要存储哪些类型数据 我们必须通过定义结构体类型来告诉C语言 我们的结构体中需要存储哪些类型的
  • linux下脚本实现 切换root用户并执行

    借助一个工具 expect sudo apt span class token operator span get install expect 编写脚本 xff1a vim root sh span class token operato
  • csdn极客江南

    零基础学会 C 语言课程学习突破 1500 人 xff1a 学习地址 xff1a https edu csdn net course detail 31452 spm 61 1001 2014 3001 5507TS TS 专栏文章更新至第
  • 音视频编码格式认知

    编码格式对应的就是音频编码和视频编码 xff0c 音频编码标准和视频编码标准 xff0c 每种编码标准都对应的编码算法 xff0c 其目的是通过一定编码算法实现数据的压缩 减少数据的冗余 视频编码指的是通过特定的压缩技术 xff0c 将某个
  • TensorFlow、PyTorch各版本对应的CUDA、cuDNN关系

    TensorFlow PyTorch各版本对应的CUDA cuDNN关系 xff08 截止2021年4月7日 xff09 TensorFowLinuxCPUGPU macOSCPUGPU WindowsCPUGPU PyTorchCPUGP
  • Android源码新大陆

    vold amp av http aospxref com android 13 0 0 r3 xref system vold model http aospxref com android 13 0 0 r3 xref framewor
  • QT读取GPS模块时,显示不完全,一条指令只能ReadAll32个字节,数据被分开

    在用QT读取GPS模块的时候 xff0c 发现读取到的数据总是显示不出来经度 xff0c 用debug调试 xff0c 发现数据被分开 xff0c 一条指令只能读到N那里 xff0c GNRMC 064401 65 A 3110 47069
  • STM32CubeMX配置串口DMA传输实现不定长数据收发

    串口简介 串口是全双工的串行通信协议 串口通信指串口按位 xff08 bit xff09 发送和接收字节 xff08 一个字节有8位 xff09 尽管比特字节 xff08 byte xff09 的串行通信慢 xff0c 但是串口可以在使用一
  • 单片机串口不够用怎么办?

    扩展串口 一 为什么要扩展串口 xff1f 一块单片机的串口是有限的 xff0c 一般2 4个 当我们做一个项目时需要连接多个外设时跟单片机通讯时 xff0c 且通讯都是以串口形式 那么我们只能去扩展串口来满足我们的应用需求 二 解决方法
  • C语言:自定义实现strcat函数

    include lt stdio h gt include lt assert h gt char My Strcat char str1 const char str2 assert str1 amp amp str2 指针不为空 cha
  • 了解串口协议,及完成STM32的USART串口通讯程序,并用keil观察波形

    文章目录 前言一 串口协议1 RS 2322 485标准 二 RS 232 485和TTL电平1 RS 232电平2 4853 TTL电平4 区别 三 USB TTL转2321 CH3402 发送接收3 USB转RS 232 四 完成一个S
  • UART RS232 RS485协议原理及应用

    一 URAT UART Universal Asynchronous Receiver Transmitter 通用异步收发传输器 xff0c 简称串口 xff0c 是设备间进行异步通信的模块 UART负责处理数据总线和串行口之间的串 并
  • 2022年电赛E题声源定位跟踪系统

    我们组本来是奔着视觉题去的 xff0c 可是到比赛的时候突然发现好像就无人机比较合适 xff0c 但是我们都没玩过无人机 xff0c 本想转战小车 xff0c 可是材料突然发现要两辆小车 xff0c 材料也不够来不及买 xff0c 于是我们