这是一个针对特定应用的测试工具,主要实现两个串口设备之间自动通讯与测试。
界面如下:
代码如下:
#!/usr/bin/env python
# coding=utf-8
import serial
import struct
import time
import math
import threading
import tkinter as tk
from tkinter import ttk
import tkinter.font as tkFont
import serial.tools.list_ports
import re
import json
class uploader(object):
MAX_PACK_SIZE = 64
MAX_FLASH_PRGRAM_TIME = 0.001 # Time on an F7 to send SYNC, RESULT from last data in multi RXed
def __init__(self, portname, baudrate_bootloader):
# Open the port, keep the default timeout short so we can poll quickly.
# On some systems writes can suddenly get stuck without having a
# write_timeout > 0 set.
# chartime 8n1 * bit rate is us
self.chartime = 10 * (1.0 / baudrate_bootloader)
# we use a window approche to SYNC,<result> gathring
self.port = serial.Serial(portname, baudrate_bootloader, timeout=3, write_timeout=0)
def close(self):
if self.port is not None:
self.port.close()
def open(self):
# upload timeout
timeout = time.time() + 0.2
# attempt to open the port while it exists and until timeout occurs
while self.port is not None:
portopen = True
try:
portopen = self.port.is_open
except AttributeError:
portopen = self.port.isOpen()
if not portopen and time.time() < timeout:
try:
self.port.open()
except OSError:
# wait for the port to be ready
time.sleep(0.04)
except serial.SerialException:
# if open fails, try again later
time.sleep(0.04)
else:
break
def __send(self, c):
# print("send " + binascii.hexlify(c))
self.port.write(c)
def __recv(self, count=1):
c = self.port.read(count)
if len(c) < 1:
raise RuntimeError("timeout waiting for data (%u bytes)" % count)
# print("recv " + binascii.hexlify(c))
return c
def __recv_uint8(self):
uint8 = struct.unpack("<B", self.__recv(1))
return uint8[0]
def __recv_int(self):
raw = self.__recv(4)
val = struct.unpack("<I", raw)
return val[0]
def receive_one_message(self):
str_msg = self.port.readline()
if len(str_msg) < 1:
raise RuntimeError("timeout waiting for data")
# print("recv " + binascii.hexlify(c))
return str_msg.decode('utf-8')
class painter(object):
PRINT_ON = 'print_on\r\n'
PRINT_OFF = 'print_off\r\n'
SET_ANTENNA_RF1 = '''ETST {"airAntSelect":"ant1"}\r\n'''
SET_ANTENNA_RF2 = '''ETST {"airAntSelect":"ant2"}\r\n'''
SET_ANTENNA_AUTO = '''ETST {"airAntSelect":"ant2"}\r\n'''
FREQ_LIST = ['2410', '2427', '2444', '2461', '2478']
SET_VGA_HEAD = 'set_tx_vga '
SET_VGA_TAIL = ' \r\n'
SET_GET_VGA = 'get_tx_vga\r\n'
TEST_COUNT = 15
SET_TESTMODE = ['''ETST {"testMode":"enable","continuousTx":"disable","continuousRx":"disable","mcs":"BPSK_1/2(2.08Mbps)","loFreq":2410,"power_db":27}\r\n''',
'''ETST {"testMode":"enable","continuousTx":"disable","continuousRx":"disable","mcs":"BPSK_1/2(2.08Mbps)","loFreq":2427,"power_db":27}\r\n''',
'''ETST {"testMode":"enable","continuousTx":"disable","continuousRx":"disable","mcs":"BPSK_1/2(2.08Mbps)","loFreq":2444,"power_db":27}\r\n''',
'''ETST {"testMode":"enable","continuousTx":"disable","continuousRx":"disable","mcs":"BPSK_1/2(2.08Mbps)","loFreq":2461,"power_db":27}\r\n''',
'''ETST {"testMode":"enable","continuousTx":"disable","continuousRx":"disable","mcs":"BPSK_1/2(2.08Mbps)","loFreq":2478,"power_db":27}\r\n''']
RE_STR_GND = r'.*?fail:.*?([0-9]+).*?SNR:.*?([0-9]+).*?RSSI:.*?([0-9]+).*?RSSI_B:.*?([0-9]+).*?rx_F:.*?([0-9]+).*?stat:.*?([0-9])'
RE_STR_AIR = r'.*?fail:.*?([0-9]+).*?SNR:.*?([0-9]+).*?RSSI:.*?([0-9]+).*?RSSI_B:.*?([0-9]+).*?rx_F:.*?([0-9]+).*?stat:.*?([0-9])'
def __init__(self):
self.file_path = None
self.window = tk.Tk()
scwidth = self.window.winfo_screenwidth()
scheight = self.window.winfo_screenheight()
window_size = '+%d' % ((scwidth - 900) / 2) + '+%d' % ((scheight - 700) / 2)
self.warning = tk.StringVar()
self.fail_RMS_input = tk.StringVar()
self.snr_lmt_input = tk.StringVar()
self.rssi_RMS_input = tk.StringVar()
self.vga_initial_input = tk.StringVar()
self.device_num_input = tk.StringVar()
self.rssi_differ_input = tk.StringVar()
self.auto_increase = tk.IntVar()
self.freq_2410 = tk.IntVar()
self.freq_2427 = tk.IntVar()
self.freq_2444 = tk.IntVar()
self.freq_2461 = tk.IntVar()
self.freq_2478 = tk.IntVar()
self.font_warning = tkFont.Font(size = 16, weight = tkFont.BOLD)
self.window.title("三合一底噪灵敏度测试工具V0.6 2021-04-26")
self.window.geometry(window_size)
self.main_frame = tk.Frame(self.window)
self.input_frame = tk.Frame(self.main_frame)
self.label_port_fc = tk.Label(self.input_frame, text="飞机串口:", width=10)
self.combox_port_fc = ttk.Combobox(self.input_frame, width=40)
self.label_port_gs = tk.Label(self.input_frame, text="遥控器串口:", width=10)
self.combox_port_gs = ttk.Combobox(self.input_frame, width=40)
self.button_start = tk.Button(self.input_frame, text="打开\n串口", width=5, height=2,
command=lambda: self.thread_it(self.start_test))
self.text_warning = tk.Label(self.input_frame, textvariable=self.warning, width=30, height=7, bg='white',
wraplength = 330, font = self.font_warning)
self.checkbox_frame = tk.Frame(self.main_frame)
self.label_freq = tk.Label(self.checkbox_frame, text="测试频率:")
self.checkbox_2410 = tk.Checkbutton(self.checkbox_frame, text="2410MHz ", width=10,
variable=self.freq_2410) # , state = tk.DISABLED)
self.checkbox_2427 = tk.Checkbutton(self.checkbox_frame, text="2427MHz ", width=10,
variable=self.freq_2427) # , state = tk.DISABLED)
self.checkbox_2444 = tk.Checkbutton(self.checkbox_frame, text="2444MHz ", width=10,
variable=self.freq_2444) # , state = tk.DISABLED)
self.checkbox_2461 = tk.Checkbutton(self.checkbox_frame, text="2461MHz ", width=10,
variable=self.freq_2461) # , state = tk.DISABLED)
self.checkbox_2478 = tk.Checkbutton(self.checkbox_frame, text="2478MHz ", width=10,
variable=self.freq_2478) # , state = tk.DISABLED)
self.label_fail_RMS = tk.Label(self.checkbox_frame, text="FAIL_RMS:")
self.label_rssi_RMS = tk.Label(self.checkbox_f