简 介: 对于智能车竞赛比赛系统中的电磁检测功能进行了调试,设置了程序运行的主要框架。

关键词智能车竞赛比赛系统计时系统ESP32电磁检测

§01 智能车竞赛裁判系统


  中间间隔了一段时间,在昨天完成了 对于ESP32智能车竞赛比赛系统硬件的初步调试 。智能车竞赛系统的功能在 基于ESP32模块利用检测线圈检测车模停止时间,室内视觉AI裁判系统 进行了定义,根据现在已经进行的 福建省智能车竞赛四川省智能车竞赛 来看,在即将到来的 暑期第十六届智能车竞赛 中,由于赛题的需求,对于比赛系统的更新势在必行。

  下面是福建省赛华侨大学唐懋老师发送过来的关于比赛系统功能改进的建议:

卓老师,我是华侨大学唐懋,今年福建省省赛承办人。根据您的要求,我主要对计时系统在比赛中的问题跟您描述一下:

  1. 智能视觉组目前无全国统一的计时系统,这个必须尽快推出和推广,否则影响面非常大。我们省赛是开会大家决定只出现数字在三叉路口,地面有二维码,其他动物水果就没有采用了。计时还是采用龙邱的传统计时系统。智能视觉组的确需要尽快推广符合比赛要求并且性能可靠稳定,性价比合理的计时系统。
  2. 龙邱的传统计时系统不适合单车拉力组,因为单车拉力组的电动机离地面较高,正常比赛难以触发,若贴上多个磁标,则会影响车体重心导致无法完赛这也是个需要面对的问题。而且单车要过计时线圈(贴在地面)那个坎,有的队伍会翻车。
  3. 龙邱的传统计时系统还是很不稳定,频频出现问题,我买六个计时系统,开赛没多久当场坏掉两个(一直滴滴响无法计时),干扰问题也非常严重,建议采取线圈和红外结合的方式,特别是单车组。

  今天(2021-06-10)对于智能车竞赛系统的动态功能进行完善。

1、主要测试功能

  • 三种传感器检测: (1)电磁线圈传感器;(2)光带传感器;(3)激光信号检测传感器;
  • 两种计算机连接方式:(1)通过WiFi与计算机联网;(2)通过USB与计算机联网;
  • 与比赛系统功能整合: 通过上述两种与计算机联网方式,将检测功能整合在原来的比赛系统中;

2、硬件与软件修改

  在这里,将下面在调试过程中出现的问题,涉及到对于第一版本的硬件和软件修改进行记录。在前期硬件调试出现的修改意见记录在博文 基于ESP32智能车竞赛比赛系统硬件初步调试-5-6 中。

§02 线圈检测功能


  基于线圈检测车模上带有的永磁铁磁标是传统 信标裁判系统 所使用的基本原理。特别是在室外光线变化比较大的情况下,它还是具有一定的优势。在 基于ESP32模块利用检测线圈检测车模停止时间,室内视觉AI裁判系统 已经进行了对采集到的线圈信号进行滤波处理,完成了对于磁标的检测试验。

1、数据采集与滤波

线圈信号采集端口:
OUT1:Pin34
Out2:Pin35

(1)数据采集

#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TEST1.PY                     -- by Dr. ZhuoQing 2021-06-10
#
# Note:
#============================================================from machine                import ADC,Timer,Pin#------------------------------------------------------------
led = Pin(5, Pin.OUT)#------------------------------------------------------------
adc1 = ADC(Pin(36))
adc2 = ADC(Pin(39))
adc3 = ADC(Pin(34))
adc4 = ADC(Pin(35))adc1.atten(ADC.ATTN_6DB)
adc2.atten(ADC.ATTN_6DB)
adc3.atten(ADC.ATTN_6DB)
adc4.atten(ADC.ATTN_6DB)SAMPLE_NUM = const(500)
AVERAGE_NUM = 16
ad1dim = [0] * SAMPLE_NUM
ad2dim = [0] * SAMPLE_NUM
ad3dim = [0] * SAMPLE_NUM
ad4dim = [0] * SAMPLE_NUMsample_point = 0
stop_flag = 0def ADC4Sample(_):global ad1dim,ad2dim,ad3dim,ad4dimglobal sample_pointglobal adc1,adc2,adc3global stop_flagled.on()ad1dim[sample_point] = adc1.read()ad2dim[sample_point] = adc2.read()ad3dim[sample_point] = adc3.read()ad4dim[sample_point] = adc4.read()sample_point += 1if sample_point >= SAMPLE_NUM:sample_point = 0led.off()#------------------------------------------------------------
SAMPLE_PERIOD = 1time0 = Timer(0)
time0.init(period=SAMPLE_PERIOD, mode=Timer.PERIODIC, callback=ADC4Sample)#------------------------------------------------------------
#        END OF FILE : test1.PY
#============================================================

(2)定时器数据采集

  在上面程序中,使用LED1(IO5)来指示在定时器中完成数据采集消耗的时间。测量LED的波形,可以获得实际数据采集频率和消耗的时间。

采集四路模拟信号:
采集频率:1000Hz
占用时间:400us/每次

▲ 图2.1 数据采集指示脉冲

(3)显示采集数据

#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# DRAW.PY                      -- by Dr. ZhuoQing 2021-06-10
#
# Note:
#============================================================from headm import *def thonnycmd(cmd):tspsendwindowkey('Thonny', 's', alt=1, noreturn=1)tspsendwindowkey('Thonny', '%s'%cmd, noreturn=1)def thonnyshs(cmd='', wait=0):tspsendwindowkey('Thonny', 's', alt=1, noreturn=1)if len(cmd) > 0:tspsendwindowkey('Thonny', '%s\r'%cmd, noreturn=1)if wait > 0:time.sleep(wait)tspsendwindowkey('Thonny', 'ac', control=1, noreturn=1)tspfocuswindow('TEASOFT:1')return clipboard.paste()thonnyshs('print(ad3dim,ad4dim)', 2)
pastestr = clipboard.paste()
data1 = [float(s) for s in pastestr.split('[')[-1].split(']')[0].split(',')]
data2 = [float(s) for s in pastestr.split('[')[-2].split(']')[0].split(',')]plt.plot(data1)
plt.plot(data2)
plt.xlabel("Sample")
plt.ylabel("Value")
plt.grid(True)
plt.tight_layout()
plt.show()#------------------------------------------------------------
#        END OF FILE : DRAW.PY
#============================================================

▲ 采集到的两路信号

▲ 采集到有磁铁波动时的信号

  从上面的波形来看,这两个线圈应该是是叠加一起,但是极性相反。将其中一个线圈的极性调整过来重新测量。

▲ 采集到ADC信号波形

(4)数据滤波

#------------------------------------------------------------
SAMPLE_AVERAGE_LENGTH   = 40
def sampleaverage40ms(s):global sample_pointscopy = s.copy()if sample_point > 0:scopy = scopy[sample_point:] + scopy[:sample_point]for i in range(len(s) - SAMPLE_AVERAGE_LENGTH):scopy[-i-1] = sum(scopy[-(i+SAMPLE_AVERAGE_LENGTH+1):-(i+1)]) / SAMPLE_AVERAGE_LENGTHreturn scopy

▲ 使用20ms窗口数据平滑滤波效果

▲ 使用40ms窗口数据平滑滤波效果

2、改进的数据滤波

(1)数据采集滤波代码

  通过全局变量 sample_mode来表示不同的采集模式:

两种ADC采集模式:
sample mode=0:采集adc3,adc4
sample mode=1:采集adc1,adc2
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TEST1.PY                     -- by Dr. ZhuoQing 2021-06-10
#
# Note:
#============================================================from machine                import ADC,Timer,Pin,freq
import time#------------------------------------------------------------
led = Pin(5, Pin.OUT)
freq(240000000)#------------------------------------------------------------
adc1 = ADC(Pin(36))
adc2 = ADC(Pin(39))
adc3 = ADC(Pin(34))
adc4 = ADC(Pin(35))adc1.atten(ADC.ATTN_6DB)
adc2.atten(ADC.ATTN_6DB)
adc3.atten(ADC.ATTN_6DB)
adc4.atten(ADC.ATTN_6DB)SAMPLE_NUM = const(500)
AVERAGE_NUM = 16
ad1dim = [0] * SAMPLE_NUM
ad2dim = [0] * SAMPLE_NUM
ad3dim = [0] * SAMPLE_NUM
ad4dim = [0] * SAMPLE_NUMSAMPLE_AVERAGE_LENGTH   = 40
ad3average = [0] * SAMPLE_AVERAGE_LENGTH
ad4average = [0] * SAMPLE_AVERAGE_LENGTH
ad34point = 0
ad3sigma = 0
ad4sigma = 0#------------------------------------------------------------
sample_point = 0
stop_flag = 0sample_mode = 0                     # 0 : sample adc3, adc4# 1 : sample adc1, adc2
#------------------------------------------------------------def ADC4Sample(_):global ad1dim,ad2dim,ad3dim,ad4dimglobal sample_pointglobal adc1,adc2,adc3, adc4global ad3average, ad4average, ad34point, ad3sigma, ad4sigmaled.on()if sample_mode == 1:ad1dim[sample_point] = adc1.read()ad2dim[sample_point] = adc2.read()if sample_mode == 0:adc = adc3.read()ad3sigma += adcad3sigma -= ad3average[ad34point]ad3average[ad34point] = adcadc = adc4.read()ad4sigma += adcad4sigma -= ad4average[ad34point]ad4average[ad34point] = adcad34point += 1if ad34point >= SAMPLE_AVERAGE_LENGTH:ad34point = 0ad3dim[sample_point] = ad3sigma / SAMPLE_AVERAGE_LENGTHad4dim[sample_point] = ad4sigma / SAMPLE_AVERAGE_LENGTHsample_point += 1if sample_point >= SAMPLE_NUM:sample_point = 0led.off()#------------------------------------------------------------
SAMPLE_PERIOD = 1time0 = Timer(0)
time0.init(period=SAMPLE_PERIOD, mode=Timer.PERIODIC, callback=ADC4Sample)#------------------------------------------------------------
#        END OF FILE : test1.PY
#============================================================

  下面是强磁铁对应的采集信号:

▲ 滤波后采集到在有磁铁情况下的信号

  下面是小型磁铁对应的采集信号:

▲ 滤波后采集到在有磁铁情况下的信号

  从上图中可以看到采集数据位置 sample_point的附近引起的数据的突变情况。

§03 线圈触发检测


1、软件主程序

(1)程序功能

  • 在Timer采集的时候使用40ms数据滤波;
  • 建立两个通道的基准线;
  • 检查两个通道ADC值是否与基准线偏离超过给定的阈值。
程序参数:
AD34 BASE ALPHA :100-基准线滤波惯性系数
AD34 CHECK THRESHOLD :检查信号变化阈值

(2)程序代码

#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TEST1.PY                     -- by Dr. ZhuoQing 2021-06-10
#
# Note:
#============================================================from machine                import ADC,Timer,Pin,freq
import time#------------------------------------------------------------
led = Pin(5, Pin.OUT)
freq(240000000)#------------------------------------------------------------
adc1 = ADC(Pin(36))
adc2 = ADC(Pin(39))
adc3 = ADC(Pin(34))
adc4 = ADC(Pin(35))adc1.atten(ADC.ATTN_6DB)
adc2.atten(ADC.ATTN_6DB)
adc3.atten(ADC.ATTN_6DB)
adc4.atten(ADC.ATTN_6DB)SAMPLE_NUM = const(500)
AVERAGE_NUM = 16
ad1dim = [0] * SAMPLE_NUM
ad2dim = [0] * SAMPLE_NUM
ad3dim = [0] * SAMPLE_NUM
ad4dim = [0] * SAMPLE_NUMSAMPLE_AVERAGE_LENGTH   = 40
ad3average = [0] * SAMPLE_AVERAGE_LENGTH
ad4average = [0] * SAMPLE_AVERAGE_LENGTH
ad34point = 0
ad3sigma = 0
ad4sigma = 0#------------------------------------------------------------
AD34_BASE_ALPHA         = 0.0005
ad3baseline = 0
ad4baseline = 0AD34_CHECK_THRESHOLD    = 100
ad3checktime = 0
ad4checktime = 0#------------------------------------------------------------
sample_point = 0
stop_flag = 0
sample_mode = 0                     # 0 : sample adc3, adc4# 1 : sample adc1, adc2total_count = 0#------------------------------------------------------------
def ADC4Sample(_):global ad1dim,ad2dim,ad3dim,ad4dimglobal sample_pointglobal adc1,adc2,adc3, adc4global ad3average, ad4average, ad34point, ad3sigma, ad4sigmaglobal ad3checktime, ad4checktime,total_countglobal ad3baseline, ad4baselineled.on()#--------------------------------------------------------total_count += 1#--------------------------------------------------------if sample_mode == 1:ad1dim[sample_point] = adc1.read()ad2dim[sample_point] = adc2.read()if sample_mode == 0:adc = adc3.read()ad3sigma += adcad3sigma -= ad3average[ad34point]ad3average[ad34point] = adcadc = adc4.read()ad4sigma += adcad4sigma -= ad4average[ad34point]ad4average[ad34point] = adcad34point += 1if ad34point >= SAMPLE_AVERAGE_LENGTH:ad34point = 0ad3dim[sample_point] = ad3sigma / SAMPLE_AVERAGE_LENGTHad4dim[sample_point] = ad4sigma / SAMPLE_AVERAGE_LENGTH#----------------------------------------------------value = ad3sigma / SAMPLE_AVERAGE_LENGTHif ad3baseline == 0:if ad34point == SAMPLE_AVERAGE_LENGTH - 1:ad3baseline = valueelse: ad3baseline = ad3baseline * (1 - AD34_BASE_ALPHA) +AD34_BASE_ALPHA * valueif abs(value - ad3baseline) > AD34_CHECK_THRESHOLD:if ad3checktime == 0:ad3checktime = total_countvalue = ad4sigma / SAMPLE_AVERAGE_LENGTHif ad4baseline == 0:if ad34point == SAMPLE_AVERAGE_LENGTH - 1:ad4baseline = valueelse: ad4baseline = ad4baseline * (1 - AD34_BASE_ALPHA) + AD34_BASE_ALPHA * valueif abs(value - ad4baseline) > AD34_CHECK_THRESHOLD:if ad4checktime == 0:ad4checktime = total_count#--------------------------------------------------------sample_point += 1if sample_point >= SAMPLE_NUM:sample_point = 0#--------------------------------------------------------led.off()#------------------------------------------------------------
SAMPLE_PERIOD = 1time0 = Timer(0)
time0.init(period=SAMPLE_PERIOD, mode=Timer.PERIODIC, callback=ADC4Sample)#------------------------------------------------------------
while True:if ad3checktime != 0:print(ad3checktime)ad3checktime = 0if ad4checktime != 0:print(ad4checktime)ad4checktime = 0time.sleep_ms(100)#------------------------------------------------------------
#        END OF FILE : test1.PY
#============================================================

2、程序功能测试

  手持小型磁铁在检测线圈晃动,会引起检测时间输出。

(1)测试电单车是否能够触发?

  怎么前面唐懋老师所提出的对于电单车,来自于LQ的电磁感应无法正常剪出,如果粘贴更多的磁铁则会引起电单车不稳定。下面就测试一下普通的电单车是否可以只使用一个永磁铁来触发线圈。

  下图是用于触发线圈的磁标。

▲ 图3.2.1 磁标

永磁铁尺寸:
厚度:1.63mm
宽度:9.67mm
长度:19.52mm

  使用双面胶将磁标粘贴在电单车底部。

▲ 图3.2.2 使用双面胶将磁标粘贴在电单车底部

  通过实际检验可以知道,当电单车经过线圈是,可以比较可靠的触发感应线圈计时。

▲ 图3.2.3 电单车压过线圈会触发线圈计时

※ 调试总结 ※


  对于计时线圈检测功能进行了调试。通过内部采集存储缓存区,可以观察到线圈采集信号的波形。这个存储区ad3dim, ad4dim在正式程序运行的时候是不需要的。 通过测试程序,验证了如下功能:

  • 通过对采集到的信号使用40ms的窗口平滑滤波,可以将外部50Hz的干扰信号降低的最低。
  • 利用一阶惯性平滑滤波获取两个通道的动态基线电平;
  • 设置全局计数变量 total_count,来标记检测电平变化的时间间隔;
  • 如果出现了电平变化,在全局变量 ad3checktime, ad4checktime记录下变化的时刻。

  通过实验验证,使用感应线圈可以比较精确检测到电单车经过时刻。如果希望点券不影响单车运行,可以考虑在其上加盖一层厚的纸张,来减少对于车模的影响。

  不过线圈存在所带来的颠簸也是仿真路面颠簸的最好形式。


■ 相关文献链接:

  • 基于ESP32智能车竞赛比赛系统硬件初步调试-5-6
  • 基于ESP32模块利用检测线圈检测车模停止时间,室内视觉AI裁判系统
  • 第三届福建省大学生智能车竞赛
  • 第十六届智能车竞赛备战新进展
  • 第十六届全国大学生智能车汽车竞赛第二次扩大会议
  • 信标组裁判系统原理与实现

● 相关图表链接:

  • 图2.1 数据采集指示脉冲
  • 采集到的两路信号
  • 采集到有磁铁波动时的信号
  • 采集到ADC信号波形
  • 使用20ms窗口数据平滑滤波效果
  • 使用40ms窗口数据平滑滤波效果
  • 滤波后采集到在有磁铁情况下的信号
  • 滤波后采集到在有磁铁情况下的信号
  • 图3.2.1 磁标
  • 图3.2.2 使用双面胶将磁标粘贴在电单车底部
  • 图3.2.3 电单车压过线圈会触发线圈计时

基于ESP32的竞赛裁判系统功能调试-计时线圈功能相关推荐

  1. 基于ESP32的竞赛裁判系统功能调试-硬件修改建议

    简 介: 基于前面对于基于ESP32比赛系统的第一版本的调试,给出了在硬件方面的修改意见,便于应用到未来的智能车竞赛比赛中去. 关键词: 智能车竞赛,ESP32,比赛系统 §01 基于ESP32裁判系 ...

  2. 基于ESP32的竞赛裁判系统功能调试-光电条检测板

    简 介: 通过实验验证量光电检测板在比赛系统中用于检测车模通过是的功能.前面给出了对于主控板以及光电板上的参数修改内容. 关键词: 比赛系统,智能车竞赛,光电检测板 §01 竞赛裁判系统   在刚刚调 ...

  3. 基于ESP32的竞赛裁判系统功能调试-与微机通讯

    简 介: 通过调试测试了基于ESP32设计的智能车竞赛的比赛系统方案与比赛软件联系的功能. 关键词: 智能车竞赛,比赛系统,ESP32 §01 比赛系统与微机通讯 在 基于ESP32智能车竞赛比赛系统 ...

  4. 基于ESP32的竞赛裁判系统功能调试-激光信号调试

    简 介: 通过揣进测试了新版的基于ESP32的裁判系统对于激光信号的检测能力. 关键词: 智能车竞赛,125Hz,激光信号 §01 智能车竞赛裁判系统   对于 基于ESP32的智能车竞赛裁判系统 中 ...

  5. 基于esp32的手机蓝牙收发调试器

    一,实验准备 开始之前,先吹一波ESP32,乐鑫YYDS!ESP32包含WIFI模块和蓝牙4.0模块,双核CPU工作频率为80-240Mhz,其大致功能如下图所示: 外设接口 • 34 个 GPIO ...

  6. 基于ESP32智能车竞赛比赛系统硬件初步调试-5-6

    简 介: 给出了对于基于ESP32设计的智能车竞赛的の比赛系统的硬件调试过程.基本上验证了硬件设计的合理与正确性.在第一部分的"修改建议"中也给出了硬件电路的修改意见. 关键词: ...

  7. 基于ESP32智能车竞赛裁判系统第二版硬件调试-6-26

    简 介: 对于新版的比赛裁判系统进行硬件测试,验证了新版的硬件满足比赛的要求.对于感光板的不同区域灵敏度不同的问题,最后验证是由于LED的分布电容所引起的时间常数不同造成了.对于单条串联的LED修改成 ...

  8. 基于ESP32的智能车竞赛新版裁判系统的软件功能要求与实现

    简 介: 本文给出了第十六届智能车竞赛裁判系统最终的软件设计和功能实现.并进行了验证,是它可以满足比赛基本计时要求. 最后给出了完整的程序. 关键词: 智能车竞赛,ESP32,视觉AI §01 智能车 ...

  9. AI视觉组基于ESP32的裁判系统第一版本设计要求

    简 介: 面对第十六届全国大学生智能车竞赛中新增加的一些组别的要求,比如室内AI组,对于车模任务增加的检测任务,设计了基于ESP32为核心的比赛系统.本文给出了对于比赛系统功能的要求. 关键词: 比赛 ...

最新文章

  1. AppBaseJs 类库 网上常用的javascript函数及其他js类库写的
  2. beyond compare比较工具设置
  3. 电动力学每日一题 2021/10/14
  4. PHP常量:define和const的不同之处
  5. python为什么叫爬虫-python为什么叫网络爬虫
  6. DPDK分析——UIO
  7. python 简明教程
  8. 学生成绩管理系统测试用例C语言,学生成绩管理系统测试用例.docx
  9. WPS Office V15.3.2绿化版免费下载
  10. Vue2.0源码解析 - 知其然知其所以然之keep-alive原理分析(一)
  11. 单片机 MSP430 串口 计算 波特率
  12. 香蕉树上第一根芭蕉——关于C语言中链表(动态链表静态链表)使用说明
  13. Android性能优化系列:内存优化
  14. 气象插值软件anusplin的使用
  15. 神剑轩辕java,上古十大神剑有哪些 有一把居然是专门用来弑君杀父的
  16. sam文件获取与解密
  17. shell 自动搜索历史记录
  18. 《遥远的救世主》遵守客观规律(一)——对王庙村能做什么分析
  19. 解决OBS录屏软件窗口采集不全的问题
  20. Mean ± SEM or Mean(SD)

热门文章

  1. 参数化之利用CSV Data Set Config从文件读取参数并关联变量
  2. 20165206 2017-2018-2 《Java程序设计》第三周学习总结
  3. mongodb的监控与性能优化
  4. 设计模式(一)-单例模式
  5. 浅谈Android组件化
  6. Linux系统编程——线程私有数据
  7. 利用微软Atlas消费外部Web服务
  8. PowerDesigner的一下简单使用技巧
  9. Log4j源代码学习
  10. WCF第一个Demo