基于ESP32的竞赛裁判系统功能调试-与微机通讯
简 介: 通过调试测试了基于ESP32设计的智能车竞赛的比赛系统方案与比赛软件联系的功能。
关键词
: 智能车竞赛,比赛系统,ESP32
§01 比赛系统与微机通讯
在 基于ESP32智能车竞赛比赛系统硬件初步调试-5-6 基础上,调试智能车竞赛 基于ESP32裁判系统 与微机通讯功能。通讯功能主要包括两大类:
- 通过USB(Type-C USB接口)与微机相连;
- 通过WiFi与微机相连;
在调试完成之后,通过与比赛系统原有的通讯功能相连,完成比赛系统整体的功能调用。
1、USB连接接口
在ESP32模块上存在三个UART端口。其中UART0被用于REPL接口。在ESP32裁判系统设计中,使用了UART1作为与微机通讯的串口。
串口端口 | UART0 | UART1 | UART2 |
---|---|---|---|
TXD端口线 | 1 | 10 | 17 |
RXD端口线 | 3 | 9 | 16 |
ESP32裁判系统通过CH340G将USB端口转换成标准的UART端口,与ESP32的UART1相连。
在设计中,串口UART1设置的端口设置似乎与ESP32的标准的缺省位置不同。
- UART1端口设置:
-
RXD1
:PIN17-SD2
TXD1
:PIN18-SD3
▲ 图1.1 ESP32核心板串口端口560
2、对于ESP32主板的修改
(1)USB 串口电阻二极管
对于TXD1,RXD1上的R14(330Ω)与D2(1N5819)取消。
▲ 消除RXD1,TXD1上的电阻和二极管
(2)使用UART2
根据后面测试,使用UART1出现错误。修改使用UART2。
3、裁判系统通信协议
参见后面的【3】部分的内容。
§02 调试USB端口
1、测试ESP32UART
(1)测试程序
import time
from machine import UART,Pin
led = Pin(5, Pin.OUT)
uart1 = UART(1, baudrate=115200, rx=9, tx=10)
print("Test UART1...")
count = 0
while True:count += 1if count & 1:led.on()else: led.off()uart1.write(b'U')time.sleep_ms(10)
(2)测量输出波形
通过测量TXD1上的波形,确认TXD1输出的信息。
▲ 图2.1 TXD1上的波形
2、通过USB连入微机
将ESP32模块通过USB接入微机,在计算机“设备管理区”中出现USB-SERIAL CH340(COM44)。
▲ 图2.2 USB对应的微机的端口
(1)测试发送与接收
【Ⅰ.ESP32程序】
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TESTUART1.PY -- by Dr. ZhuoQing 2021-06-12
#
# Note:
#============================================================import time
from machine import UART,Pinled = Pin(5, Pin.OUT)uart1 = UART(1, baudrate=115200, rx=9, tx=10)print("Test UART1...")
count = 0
#------------------------------------------------------------
a = 85
b = a.to_bytes(1, 'little')
print(b)#------------------------------------------------------------
while True:count += 1if count & 0x10:led.on()else: led.off()#--------------------------------------------------------#--------------------------------------------------------
# uart1.write(b'U')if uart1.any() > 0:str = uart1.read()print(type(str))print(str)bb = str[0]+1uart1.write(bb.to_bytes(1, 'little'))time.sleep_ms(10)#------------------------------------------------------------
# END OF FILE : testuart1.PY
#============================================================
【Ⅱ.测试程序】
★ 注意:下面的程序使用UART1出现错误。
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TESTUART1PC.PY -- by Dr. ZhuoQing 2021-06-12
#
# Note:
#============================================================from head import *
import serial
from _ast import Or
from serial.serialutil import SerialException#------------------------------------------------------------
testcmd = serial.Serial()
testcmd.baudrate = 115200
testcmd.timeout = 0.05
try:testcmd.port = 'COM44'
except:printf('Set testcmd port COM44 error. ')try:testcmd.open()
except serial.serialutil.SerialException:printf('Open testcmd port COM44 error.')
else:printf('Open testcmd port COM44 Ok.')
#------------------------------------------------------------while True:testcmd.write(b'U')byte = testcmd.read(1)printf(byte)time.sleep(.1)#------------------------------------------------------------
# END OF FILE : TESTUART1PC.PY
#============================================================
【Ⅲ.测试结果】
发送‘U’,接收到’V’。
3、出现问题
(1)错误现象
不知道为什么?进行初始化之后,出现了错误:
Guru Meditation Error: Core 0 panic'ed (IllegalInstruction). Exception was unhandled.
Memory dump at 0x40105a60: ffbf0000 ffffffff ffffffff
Core 0 register dump:
PC : 0x40105a67 PS : 0x00060e30 A0 : 0x8010ebec A1 : 0x3ffce950
A2 : 0x00000009 A3 : 0x00000000 A4 : 0x0ffd114c A5 : 0x00000000
A6 : 0x00000001 A7 : 0x00000000 A8 : 0x3ff440a4 A9 : 0x00000004
A10 : 0x00000000 A11 : 0x3ff49054 A12 : 0x00060e20 A13 : 0x00000001
A14 : 0x0000cdcd A15 : 0x00000029 SAR : 0x00000017 EXCCAUSE: 0x00000000
EXCVADDR: 0x00000000 LBEG : 0x4000c46c LEND : 0x4000c477 LCOUNT : 0xffffffff ELF file SHA256: 0000000000000000Backtrace: 0x40105a64:0x3ffce950 0x4010ebe9:0x3ffce980 0x400f7422:0x3ffce9b0 0x400f76bd:0x3ffcea20 0x400e8f4d:0x3ffcea70 0x400df7ed:0x3ffcea90 0x400ed0b9:0x3ffceab0 0x400e3944:0x3ffceb50 0x400df7ed:0x3ffcebd0 0x400df816:0x3ffcebf0 0x40104c52:0x3ffcec10 0x40104ded:0x3ffceca0 0x400f60a1:0x3ffcecf0 0x4009b831:0x3ffced20Rebooting...
ets Jun 8 2016 00:22:57rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:5148
load:0x40078000,len:12880
load:0x40080400,len:3484
entry 0x40080630
MicroPython v1.14 on 2021-02-02; ESP32 module with ESP32
Type "help()" for more information.
为什么会出现这个问题,现在还不得而知。
(2)修改方法
使用UART2 替代UART1。
uart1 = UART(2, baudrate=115200, rx=16, tx=17, timeout=10)
#uart1 = UART(1, baudrate=115200, rx=9, tx=10, timeout=10)
修改之后问题解决了。
▲ 图2.3 使用短路线将原来的UART1修改成UART2560
§03 比赛系统通讯
- 比赛系统来自于SCDET19,现在拷贝到:
>D:\zhuoqing\window\cb\SmartCar\SCDETXX\SCDET21
1、通信协议
上位机是通过USB转UART模块与控制模块通信。对于上位机由于是虚拟串口,所以串口的波特率,数据位数,停止位与起始位等对于通信没有影响。
(1)单片机UART协议
对于下位机,设置UART协议为:
- UART通讯协议:
-
波特率
:115200
数据位
:8位
停止位
:1位
起始位
:1位
校验位
:无
(2)发送与接收命令帧个数
下面通信协议是站在底层模块的角度来定义发送与接收命令帧。
- 发送命令帧:
帧字节 | 字节1 | 字节2 | 字节3 | 字节4 | 字节5 | 字节6 | 字节7 |
---|---|---|---|---|---|---|---|
字节定义 | 0x55 | Cmd | byte1 | byte2 | byte3 | byte4 | Check |
- 命令字节含义:
-
0x55
:固定帧头
Cmd
:返回的工作模式,详见【1-2】
byte1,2,3,4
:长整型参数,byte1高字节,byte4低字节
check
:校验和 - 校验和的计算公式:
- check=(0x55+cmd+byte1+byte2+byte3+byte4)^0xff
工作模式 | 代码 | 备注 |
---|---|---|
SENDFLAG_NOCHECK | 0x80 | |
SENDFLAG_CHECK | 0x81 | 此时发送当前定时器(32bit)数值 |
SENDFLAG_LAST | 0x82 | |
SENDFLAG_STOP | 0xff | |
SENDFLAG_SNAPSHORT | 0x83 |
发送命令帧是通过函数DSSendCOmmand(mode,time)
来进行。其中
- DSSendCommand函数参数:
-
mode
:1-byte,返回状态
time
:4-byte,时间参数
- 接收命令站:
【表1-3 接收命令数据帧】
帧字节 | 字节1 | 字节2 | 字节3 | 字节4 |
---|---|---|---|---|
字节定义 | Cmd | byte1 | byte2 | Check |
- 命令帧字节定义:
-
Cmd
:命令字节
byte1,byte2
:短整型参数,一般是时间参数time
Check
:校验和 - 校验和计算公式:
- check=(Cmd+byte1+byte2)^0xff
下面给出了接收命令中的命令字节定义,以及相应的返回命令帧内容。请注意,返回命令是通过DSSendCommand(mode,time)
完成,所以在表格“备注”中只给出上述函数的两个参数(mode,time)
。
接受命令 | 代码 | 功能 | 备注 |
---|---|---|---|
DSCMD_HELLO | 0x00 | 测试连通性 |
返回命令帧参数(DSRET_HELLO, 0x0) DSRET_HELLO:0x90 |
DSCMD_INIT | 0x01 |
对于模块进行初始化: (1) 清除定时器-32bit (2) 允许发送; (3) 将接收到time设置为检测3秒延迟 (4) 初始化其它参数 (5) 设置发送使能为1 |
返回命令参数(DSRET_INIT, 0x0) DSRET_INIT:0x91 |
DSCMD_STARTSEND | 0x10 |
开始发送命令: (1) 将接受到的time设置为发送延迟周期 |
返回命令参数(SENDFLAG_LAS,lastcount) |
DSCMD_STOPSEND | 0x11 | 清除发送使能状态 | 返回命令参数(SENDFLAG_CHECK, Count32) |
DSCMD_BEEP | 0x12 | 启动Beep声音 | 无返回 |
DSCMD_SENDSNAPSHORT | 0x13 |
发送Snapshot: (1)停止发送 |
返回命令参数(SENDFLAG_CHECK, Count32) |
DSCMD_TURNOFFLEIGHT | 0x14 | 关灭所有的信标灯 | 仅仅用于信标灯控制 |
DSCMD_SETCONTINUECHECK | 0x15 | 设置连续检测状态,不再有延迟时间了 | 无 |
DSCMD_SETBEACONSEEQUENCY | 0x16 | ||
DSCMD_BEACONSTART | 0x17 | 启动第一个信标 | |
DSCMD_BEACONSTOP | 0x18 | 停止信标灯 | |
DSCMD_GETBEACONSTATE | 0x19 | 获取信标灯状态 | |
DSCMD_BEACONINIT | 0x12 | 对于信标灯进行初始化 | |
错误字节 | == | BEEP-OFF | 无 |
§04 测试程序
1、ESP32代码
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TESTALL.PY -- by Dr. ZhuoQing 2021-06-13
#
# Note:
#============================================================from machine import UART,Pin,Timer,ADC
import time
import machine#------------------------------------------------------------
machine.freq(240000000)led = Pin(5, Pin.OUT)
speaker = Pin(21, Pin.OUT)
speaker.off()#------------------------------------------------------------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)ad1dim = [0] * SAMPLE_NUM
ad2dim = [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 = 250
ad3checktime = 0
ad4checktime = 0#------------------------------------------------------------
sample_point = 0
stop_flag = 0sample_mode = 0 # 0 : sample adc3, adc4# 1 : sample adc1, adc2total_count = 0#------------------------------------------------------------
uart1 = UART(2, baudrate=115200, rx=16, tx=17, timeout=10)#------------------------------------------------------------
DSCMD_NONE = 0xff
DSCMD_HELLO = 0x00
DSCMD_INIT = 0x01
DSCMD_STARTSEND = 0x10
DSCMD_STOPSEND = 0x11
DSCMD_BEEP = 0x12
DSCMD_SENDSNAPSHOT = 0x13
DSCMD_TURNOFFLIGHT = 0x14
DSCMD_SETCONTINUECHECK = 0x15
DSCMD_SETBEACONSEQUENCY = 0x16
DSCMD_BEACONSTART = 0x17
DSCMD_BEACONSTOP = 0x18
DSCMD_GETBEACONSTATE = 0x19
DSCMD_BEACONINIT = 0x1aDSRET_NCHECK = 0x80
DSRET_CHECK = 0x81
DSRET_LAST = 0x82
DSRET_HELLO = 0x90
DSRET_INIT = 0x91SENDFLAG_LAST = 0x82
SENDFLAG_CHECK = 0x81
SENDFLAG_NOCHECK = 0x80
SENDFLAG_STOP = 0xff
SENDFLAG_SNAPSHOT = 0x83#------------------------------------------------------------
def receCmd():if uart1.any() == 0: return DSCMD_NONE,0framebyte = uart1.read(4)if len(framebyte) != 4: return DSCMD_NONE, 0framelist = list(framebyte)time = int.from_bytes(framebyte[1:3], 'big')sumnum = sum(framelist[0:3]) & 0xff ^ 0xffif sumnum != framelist[3]: return DSCMD_NONE, 0return framelist[0], time#------------------------------------------------------------
def sendCmd(cmd, time):senddim = [0x55,cmd]senddim.extend(list(time.to_bytes(4, 'big')))sumnum = sum(senddim)&0xff^0xffsenddim.extend([sumnum])sendbytes = bytes(senddim)uart1.write(sendbytes)#------------------------------------------------------------
def procCmd(cmd, time):global count32,sendflag,delay3s,count32,sendenableflagglobal initflag,lastcount32,snapshot32,speakercount,senddelay,sendcountif cmd == DSCMD_NONE: returnif cmd == DSCMD_HELLO:sendCmd(DSRET_HELLO, 0x0)returnif cmd == DSCMD_INIT:sendCmd(DSRET_INIT, 0x0)count32 = 0x0delay3s = timecount3s = timeinitflag = 1lastcount32 = 0snapshot32 = 0sendcount = 0sendenableflag = 1sendflag = SENDFLAG_STOPreturnif cmd == DSCMD_STARTSEND:sendCmd(SENDFLAG_LAST, lastcount32)count3s = delay3ssendflag = 0x0sendenableflag = 0x1senddelay = timesendcount = 0returnif cmd == DSCMD_STOPSEND:sendCmd(SENDFLAG_CHECK, count32)sendenableflag = 0sendflag = 0sendcount = 0returnif cmd == DSCMD_BEEP:speakercount = 500returnif cmd in (DSCMD_SETBEACONSEQUENCY,DSCMD_BEACONSTART,DSCMD_BEACONSTOP,DSCMD_GETBEACONSTATE,DSCMD_TURNOFFLIGHT,DSCMD_BEACONINIT):returnprint(cmd, time)#------------------------------------------------------------
speakercount = 500def speaker1ms():global speakercountif speakercount > 0:speakercount -= 1speaker.on()else:speaker.off()#------------------------------------------------------------
def sendTime():global count32,snapshot32,lastcount32,sendflagif sendflag == SENDFLAG_STOP: returnif initflag == 0: returntimesend = count32if sendflag == SENDFLAG_LAST:timesend = lastcount32elif sendflag == SENDFLAG_CHECK or sendflag == SENDFLAG_NOCHECK:timesend = count32elif sendflag == SENDFLAG_SNAPSHOT:timesend = snapshot32sendCmd(SENDFLAG_SNAPSHOT, snapshot32)sendflag = SENDFLAG_NOCHECKsendCmd(sendflag, timesend)sendflag = SENDFLAG_STOP#------------------------------------------------------------
count32 = 0 # Global 1ms counter
sendflag = SENDFLAG_STOP # send flag
sendenableflag = 0 # Enable send
senddelay = 100 # Everay send period
sendcount = 0 # count for send delay
delay3s = 3000 # No check delay
count3s = 3000 # count for no check delay
initflag = 0 #
lastcount32 = 0 #
snapshot32 = 0 ##------------------------------------------------------------#------------------------------------------------------------
def ADC4Sample(_):global count32,sendenableflag,sendflag,senddelay,sendcountglobal delay3s,count3s,initflag,lastcount32,snapshot32global speakercount#--------------------------------------------------------count32 += 1speaker1ms()#--------------------------------------------------------if count32 & 0x100:led.on()else: led.off()#--------------------------------------------------------if sendenableflag != 0:sendcount += 1if sendcount >= senddelay:sendcount = 0if sendflag == SENDFLAG_STOP:if count32 < delay3s:sendflag = SENDFLAG_NOCHECKelse: sendflag = SENDFLAG_CHECKelse:sendcount += 1if sendcount >= senddelay:sendcount = 0if sendflag == SENDFLAG_STOP:sendflag = SENDFLAG_CHECK#--------------------------------------------------------global ad1dim,ad2dimglobal sample_pointglobal adc1,adc2,adc3, adc4global ad3average, ad4average, ad34point, ad3sigma, ad4sigmaglobal ad3checktime, ad4checktime,total_countglobal ad3baseline, ad4baselinetotal_count += 1#--------------------------------------------------------detectflag = 0if 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 = 0#----------------------------------------------------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_countdetectflag = 1value = 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_countdetectflag = 1#--------------------------------------------------------sample_point += 1if sample_point >= SAMPLE_NUM:sample_point = 0#--------------------------------------------------------if detectflag > 0:speakercount = 200if count3s >= delay3s:if sendenableflag > 0:if detectflag > 0:count3s = 1lastcount32 = count32snapshot32 = 0x0sendflag = SENDFLAG_LASTelse:if detectflag > 0:snapshot32 = count32count3s = 1else:if detectflag > 0:snapshot32 = count32count3s += 1#------------------------------------------------------------
time0 = Timer(0)
time0.init(period=1, mode=Timer.PERIODIC, callback=ADC4Sample)#------------------------------------------------------------
print("Test UART1...")
count = 0
showcount = 0while True:#--------------------------------------------------------showcount += 1if showcount > 500:showcount = 0#--------------------------------------------------------cmd,tm = receCmd()if cmd != DSCMD_NONE:procCmd(cmd, tm)sendTime()#--------------------------------------------------------time.sleep_ms(2)#------------------------------------------------------------
# END OF FILE : testtime.PY
#============================================================
2、测试比赛系统
测试上面的模块满足比赛系统的借口要求。
▲ 图4.1 比赛系统界面
※ 调试结论 ※
通过调试,对于基于ESP32的比赛系统进行了调试。对于用于通信的串口进行调试。现在它满足程序的要求。
■ 相关文献链接:
- 基于ESP32智能车竞赛比赛系统硬件初步调试-5-6
- AI视觉组基于ESP32的裁判系统第一版本设计要求
● 相关图表链接:
- 表1-1 ESP32三个UART端口引线缺省端口
- 图1.1 ESP32核心板串口端口560
- 消除RXD1,TXD1上的电阻和二极管
- 图2.1 TXD1上的波形
- 图2.2 USB对应的微机的端口
- 图2.3 使用短路线将原来的UART1修改成UART2560
- 表1-1 发送命令数据帧
- 表1-2 工作模式字节
- 表1-3 接收命令数据帧
- 表1-4 接收命令字节定义
- 图4.1 比赛系统界面
基于ESP32的竞赛裁判系统功能调试-与微机通讯相关推荐
- 基于ESP32的竞赛裁判系统功能调试-硬件修改建议
简 介: 基于前面对于基于ESP32比赛系统的第一版本的调试,给出了在硬件方面的修改意见,便于应用到未来的智能车竞赛比赛中去. 关键词: 智能车竞赛,ESP32,比赛系统 §01 基于ESP32裁判系 ...
- 基于ESP32的竞赛裁判系统功能调试-光电条检测板
简 介: 通过实验验证量光电检测板在比赛系统中用于检测车模通过是的功能.前面给出了对于主控板以及光电板上的参数修改内容. 关键词: 比赛系统,智能车竞赛,光电检测板 §01 竞赛裁判系统 在刚刚调 ...
- 基于ESP32的竞赛裁判系统功能调试-计时线圈功能
简 介: 对于智能车竞赛比赛系统中的电磁检测功能进行了调试,设置了程序运行的主要框架. 关键词: 智能车竞赛,比赛系统,计时系统,ESP32,电磁检测 §01 智能车竞赛裁判系统 中间间隔了一段时 ...
- 基于ESP32的竞赛裁判系统功能调试-激光信号调试
简 介: 通过揣进测试了新版的基于ESP32的裁判系统对于激光信号的检测能力. 关键词: 智能车竞赛,125Hz,激光信号 §01 智能车竞赛裁判系统 对于 基于ESP32的智能车竞赛裁判系统 中 ...
- 基于esp32的手机蓝牙收发调试器
一,实验准备 开始之前,先吹一波ESP32,乐鑫YYDS!ESP32包含WIFI模块和蓝牙4.0模块,双核CPU工作频率为80-240Mhz,其大致功能如下图所示: 外设接口 • 34 个 GPIO ...
- 基于ESP32的智能车竞赛新版裁判系统的软件功能要求与实现
简 介: 本文给出了第十六届智能车竞赛裁判系统最终的软件设计和功能实现.并进行了验证,是它可以满足比赛基本计时要求. 最后给出了完整的程序. 关键词: 智能车竞赛,ESP32,视觉AI §01 智能车 ...
- 基于ESP32智能车竞赛比赛系统硬件初步调试-5-6
简 介: 给出了对于基于ESP32设计的智能车竞赛的の比赛系统的硬件调试过程.基本上验证了硬件设计的合理与正确性.在第一部分的"修改建议"中也给出了硬件电路的修改意见. 关键词: ...
- 基于ESP32智能车竞赛裁判系统第二版硬件调试-6-26
简 介: 对于新版的比赛裁判系统进行硬件测试,验证了新版的硬件满足比赛的要求.对于感光板的不同区域灵敏度不同的问题,最后验证是由于LED的分布电容所引起的时间常数不同造成了.对于单条串联的LED修改成 ...
- AI视觉组基于ESP32的裁判系统第一版本设计要求
简 介: 面对第十六届全国大学生智能车竞赛中新增加的一些组别的要求,比如室内AI组,对于车模任务增加的检测任务,设计了基于ESP32为核心的比赛系统.本文给出了对于比赛系统功能的要求. 关键词: 比赛 ...
最新文章
- SD-WAN的体系结构是如何提高网络灵活性和效率?
- php发送邮件smtp源码,php下使用SMTP发邮件的代码
- nginx 实现mysql的负载均衡【转】
- 安卓dts音频解码_DTS音效、解码、编码概念剖析
- JS在html中加法器,JavaScript_JavaScript程序设计之JS调试,本文主要通过一个加法器,介 - phpStudy...
- Linux上的ffmpeg完全使用指南
- 网络舆情监测系统学习笔记——GIT的…
- cad问题小百科 持续更新
- Windows本地认证
- cdrx4自动排版步骤_教你用CorelDRAW X4轻松排出干净整齐段落 coreldraw段落文字快速排版技巧图文教...
- 操作系统核心与驱动程序
- Excel复制单元格样式
- 2022年第二十三届华东杯大学生数学建模竞赛
- matlab 修改heatmap colorbar 热图
- element方法的自定义参数传参方式
- 创建多媒体APP 之 音频播放:管理音频焦点
- 领先三星、华为,全球首款可折叠柔性屏手机惊艳上市
- Mac电脑怎么关闭键盘的重复按键功能?
- 30天30队:2013-14季,俄克拉荷马州雷霆
- 钣金cad插件_ug,CAD,SolidWorks,钣金??????非标等设计一站式学习,