diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7a0f77d --- /dev/null +++ b/.gitignore @@ -0,0 +1,41 @@ +# Python 编译产物和临时文件 +*.pyc +__pycache__/ +*.pyo +*.pyd +*.pyz +*.pyw + +# virtualenv / venv / env +env/ +venv/ +.venv/ + +# pipenv +.venv +Pipfile.lock + +# poetry +.venv +poetry.lock + +# PyCharm +.idea/ +*.iml + +# Visual Studio Code +.vscode/ + +# 日志和临时文件 +*.log +logs/ +temp/ +Log/ + +# macOS +.DS_Store + +# Windows +Thumbs.db + +det_images/* \ No newline at end of file diff --git a/cap_read.py b/cap_read.py new file mode 100644 index 0000000..62034a7 --- /dev/null +++ b/cap_read.py @@ -0,0 +1,182 @@ +from enum import * +import threading +import queue # 导入 queue 模块 +from class_ch341 import * +from class_sensorcmd import * +from class_finger import * +from collections import namedtuple +import socket + + +DEF_CDC_SYNC_MS = 1000 #电容同步间隔 +DEF_GET_CAP_MS = (30) #读取电容间隔 +DEF_PRO_CYC = 100 + +# 定义一个全局的队列,用于线程间通信 +capReadQueue = queue.Queue() + +# 341通信 +class EnumCh341ConnectStatus(Enum): + CH341_CONNECT_INIT = 0 + CH341_CONNECT_OPEN = 1 + CH341_CONNECT_SET_SPEED = 2 + CH341_CONNECT_SAMPLE_START = 3 + CH341_CONNECT_CHECK = 4 + CH341_CONNECT_SAMPLE_STOP = 5 + +class ClassCapRead: + def __init__(self): + self.ch341 = ClassCh341() + + # 最大连接5个手指 + self.fingers = list() # 传感器列表 + for i in range(5): + self.fingers.append(ClassFinger(2+i, self.ch341)) + + self.currCh341State = 0 # 当前ch341连接状态 + self.prevCh341State = 0 # 上次ch341连接状态 + + self.ch341CheckTimer = 0 + self.mcuInit = 0 + self.pcaAddr = 0x70 # iic控制芯片地址 + + self.ch341Init = 0 # ch341初始化标志位 + + self.syncTimer = 0 + + self.connectStatus = EnumCh341ConnectStatus.CH341_CONNECT_INIT + + self.connectDebug() + + def __del__(self): + self.disConnectDebug() + self.ch341.disconnect() + print("ch341释放") + pass + + def connectDebug(self): + #连接到调试的服务器 + self.vofaClient = socket.socket() + addr = ('127.0.0.1', 1347) + try: + self.vofaClient.connect(addr) + # client.send('hello world\r\n'.encode()) + self.socketConnected = True + print('连接服务器成功') + except Exception as e: + self.socketConnected = False + print('连接服务器失败') + + def disConnectDebug(self): + if self.vofaClient: + self.vofaClient.close() + + def set_sensor_enable(self, idx): + _pack = list() + _pack.append(idx) + self.ch341.write(self.pcaAddr, _pack) + + def ch341Connect(self): + if self.connectStatus == EnumCh341ConnectStatus.CH341_CONNECT_INIT: + if(True == self.ch341.init()): + self.connectStatus = EnumCh341ConnectStatus.CH341_CONNECT_OPEN + elif self.connectStatus == EnumCh341ConnectStatus.CH341_CONNECT_OPEN: + if(True == self.ch341.open()): + self.connectStatus = EnumCh341ConnectStatus.CH341_CONNECT_SET_SPEED + else: + self.connectStatus = EnumCh341ConnectStatus.CH341_CONNECT_INIT + elif self.connectStatus == EnumCh341ConnectStatus.CH341_CONNECT_SET_SPEED: + if(True == self.ch341.set_speed(self.ch341.IIC_SPEED_400)): + self.connectStatus = EnumCh341ConnectStatus.CH341_CONNECT_SAMPLE_START + else: + print("set speed err") + self.connectStatus = EnumCh341ConnectStatus.CH341_CONNECT_SAMPLE_START + + elif self.connectStatus == EnumCh341ConnectStatus.CH341_CONNECT_SAMPLE_START: + self.connectStatus = EnumCh341ConnectStatus.CH341_CONNECT_CHECK + self.timer = threading.Timer(DEF_GET_CAP_MS/1000, self.capRead) + self.timer.start() + elif self.connectStatus == EnumCh341ConnectStatus.CH341_CONNECT_CHECK: + self.ch341CheckTimer += DEF_PRO_CYC + if(self.ch341CheckTimer >= 1000): + self.ch341CheckTimer = 0 + if(False == self.ch341.connectCheck()): + print("ch341 拔出") + self.connectStatus = EnumCh341ConnectStatus.CH341_CONNECT_SAMPLE_STOP + elif self.connectStatus == EnumCh341ConnectStatus.CH341_CONNECT_SAMPLE_STOP: + self.syncTimer = 0 + for i in range(0, len(self.fingers)): + self.fingers[i].disconnected() + self.connectStatus = EnumCh341ConnectStatus.CH341_CONNECT_INIT + else: + self.connectStatus = EnumCh341ConnectStatus.CH341_CONNECT_INIT + + def capRead(self): + capReadTime = time.time() + ms_capReadTime = capReadTime + + connectedSensorChan = 0 + connectedSensorCnt = 0 + for fingerIndex in range(0, len(self.fingers)): + self.set_sensor_enable(1 << (self.fingers[fingerIndex].pcaIdx)) + connectedSensorChan |= 1 << (self.fingers[fingerIndex].pcaIdx) + + if self.fingers[fingerIndex].connect == False: + if True == self.fingers[fingerIndex].checkSensor(): + print(f"sensor[{fingerIndex}] connected") + else: + print(f"addr = {fingerIndex}, connected false") + else: + self.fingers[fingerIndex].capRead() + connectedSensorCnt += 1 + + if self.socketConnected == True: + fingerIndex = 0 + _log1 = "" + # 输出原始通道数值 + for index in range(0, self.fingers[fingerIndex].projectPara.sensor_num): + _log1 += str(self.fingers[fingerIndex].readData.channelCapData[index]) + _log1 += ',' + for index in range(0, self.fingers[fingerIndex].projectPara.ydds_num): + _log1 += str(int(self.fingers[fingerIndex].readData.nf[index]*1000)) + _log1 += ',' + _log1 += str(int(self.fingers[fingerIndex].readData.tf[index]*1000)) + _log1 += ',' + _log1 += str(self.fingers[fingerIndex].readData.tfDir[index]) + _log1 += ',' + _log1 += str(0) + _log1 += '\r\n' + #print(_log1) + if self.socketConnected == 1: + self.vofaClient.send(_log1.encode()) + + # 大于1个传感器连接需要设置接近采集序列 + if connectedSensorCnt > 1 and (time.time() - self.syncTimer) > DEF_CDC_SYNC_MS: + self.syncTimer = time.time() + self.set_sensor_enable(connectedSensorChan) + + if self.connectStatus == EnumCh341ConnectStatus.CH341_CONNECT_CHECK: + capReadTime = time.time() + difftime = int(capReadTime*1000-ms_capReadTime*1000) + print(f"diffTime={difftime}") + #定时器在任务完成后重新启动 + if(difftime>DEF_GET_CAP_MS): + timer = threading.Timer(DEF_GET_CAP_MS/1000, self.capRead) + else: + timer = threading.Timer((DEF_GET_CAP_MS-difftime)/1000, self.capRead) + timer.start() + + +def capReadThread(): + # 线程的主体功能 + cap = ClassCapRead() + + while True: + cap.ch341Connect() + time.sleep(DEF_PRO_CYC/1000) + +def main(): + capReadThread() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/class_ch341.py b/class_ch341.py new file mode 100644 index 0000000..ec877a3 --- /dev/null +++ b/class_ch341.py @@ -0,0 +1,262 @@ +import time +import os +import sys +from ctypes import * +import ctypes +import glob + +# ch341类:iic读写,int引脚读写,速度设置 +class ClassCh341: + # 接口固定宏 + _mCH341A_CMD_I2C_STREAM = 0xAA # I2C接口的命令包,从次字节开始为I2C命令流 + _mCH341A_CMD_I2C_STM_STA = 0x74 # I2C接口的命令流:产生起始位 + _mCH341A_CMD_I2C_STM_STO = 0x75 # I2C接口的命令流:产生停止位 + _mCH341A_CMD_I2C_STM_OUT = 0x80 # I2C接口的命令流:输出数据,位5-位0为长度,后续字节为数据,0长度则只发送一个字节并返回应答 + _mCH341A_CMD_I2C_STM_IN = 0xC0 # I2C接口的命令流:输入数据,位5-位0为长度,0长度则只接收一个字节并发送无应答 + _mCH341A_CMD_I2C_STM_MAX = 63 # I2C接口的命令流单个命令输入输出数据的最大长度 + _mCH341A_CMD_I2C_STM_SET = 0x60 # I2C接口的命令流:设置参数,位2=SPI的I/O数(0=单入单出,1=双入双出),位1位0=I2C速度(00=低速,01=标准,10=快速,11=高速) + _mCH341A_CMD_I2C_STM_US = 0x40 # I2C接口的命令流:以微秒为单位延时,位3-位0为延时值 + _mCH341A_CMD_I2C_STM_MS = 0x50 # I2C接口的命令流:以亳秒为单位延时,位3-位0为延时值 + _mCH341A_CMD_I2C_STM_DLY = 0x0F # I2C接口的命令流单个命令延时的最大值 + _mCH341A_CMD_I2C_STM_END = 0x00 # I2C接口的命令流:命令包提前结束 + + _mStateBitINT = 0x00000400 + + IIC_SPEED_20 = 0 + IIC_SPEED_100 = 1 + IIC_SPEED_400 = 2 + IIC_SPEED_750 = 3 + + def __init__(self): + self.deviceID = ctypes.c_uint32() + pass + + def init(self): + if os.name == 'nt': # Windows 环境 + libPath = os.path.dirname(sys.argv[0]) + r'/lib/ch341/CH341DLLA64.DLL' + elif os.name == 'posix': + libPath = './lib/ch341/libch347.so' + dllExist = os.path.exists(libPath) + if not dllExist: + print('未找到库文件') + return False + else: + try: + if os.name == 'nt': # Windows 环境 + self.ic = windll.LoadLibrary(libPath) # ch341接口 + + self.ch341GetInput = self.ic.CH341GetInput + self.ch341CloseDevice = self.ic.CH341CloseDevice + self.ch341WriteData = self.ic.CH341WriteData + self.ch341WriteRead = self.ic.CH341WriteRead + self.ch341SetOutput = self.ic.CH341SetOutput + self.ch341SetStream = self.ic.CH341SetStream + + elif os.name == 'posix': + self.ic = cdll.LoadLibrary(libPath) # ch341接口 + + self.ch341GetInput = self.ic.CH34xGetInput + self.ch341CloseDevice = self.ic.CH34xCloseDevice + self.ch341WriteData = self.ic.CH34xWriteData + self.ch341WriteRead = self.ic.CH34xWriteRead + self.ch341SetOutput = self.ic.CH34xSetOutput + self.ch341SetStream = self.ic.CH34xSetStream + + print("ch341加载成功") + return True + except Exception as e: + print("ch341加载失败") + return False + + # 判断ch341是否插入 + # return:0未插入,1插入 + def open(self): + if os.name == 'nt': # Windows 环境 + try: + self.fd = self.ic.CH341OpenDevice(0) + if self.fd == -1: + print("CH341 device open failed on Windows.") + return False + else: + self.fd = 0 #todo 改成扫描端口 + print("CH341 device opened successfully on Windows.") + return True + except Exception as e: + print(f"Error occurred while opening CH341 device on Windows: {e}") + return False + + elif os.name == 'posix': # Linux 环境 + try: + devices = glob.glob('/dev/ch34x_pis*') # 动态查找设备 + if devices: + device_path = devices[0].encode() + self.fd = self.ic.CH34xOpenDevice(device_path) + if self.fd == -1: + print("CH341 device open failed on Linux.") + return False + else: + print("CH341 device opened successfully on Linux.") + return True + else: + print("No CH341 device found on Linux.") + return False + except Exception as e: + print(f"Error occurred while opening CH341 device on Linux: {e}") + return False + + else: + print("Unsupported operating system.") + return False + + def disconnect(self): + self.ch341CloseDevice(self.fd) + + def connectCheck(self): + if True == self.ch341GetInput(self.fd, ctypes.byref(self.deviceID)): + return True + else: + return False + + # iic写数据 + # addr:iic从机地址 + # data:要写的数据列表 + # return:写入长度,不一定正确 + def write(self, addr, data): + sLen = len(data) + tmpData = [] # 临时列表 + tmpLen = sLen # 发送数据 + + pack = [] # 发送列表 + cnt = 20 # 每包数量 + packNum = sLen // cnt # 拆包数量 + sLen %= cnt # 不足字节数 + + tmpData.extend(data) + + pack.append(self._mCH341A_CMD_I2C_STREAM) + pack.append(self._mCH341A_CMD_I2C_STM_STA) + pack.append(self._mCH341A_CMD_I2C_STM_OUT | 1) + pack.append(addr << 1) + for i in range(0, packNum): + pack.append(self._mCH341A_CMD_I2C_STM_OUT | cnt) + pack.extend(tmpData[0:20]) + del tmpData[0:20] + pack.append(self._mCH341A_CMD_I2C_STM_END) + sendBuf = (c_byte * len(pack))() + for j in range(0, len(pack)): + sendBuf[j] = pack[j] + sendLen = (c_byte * 1)() + sendLen[0] = len(pack) + if not self.ch341WriteData(self.fd, sendBuf, sendLen): + return 0 + if sendLen == 0: + return 0 + pack.clear() + pack.append(self._mCH341A_CMD_I2C_STREAM) + if sLen >= 1: + pack.append(self._mCH341A_CMD_I2C_STM_OUT | sLen) + pack.extend(tmpData[0:sLen]) + pack.append(self._mCH341A_CMD_I2C_STM_STO) + pack.append(self._mCH341A_CMD_I2C_STM_END) + sendBuf = (c_byte * len(pack))() + for j in range(0, len(pack)): + sendBuf[j] = pack[j] + sendLen = (c_byte * 1)() + sendLen[0] = len(pack) + if not self.ch341WriteData(self.fd, sendBuf, sendLen): + return 0 + if sendLen == 0: + return 0 + return tmpLen + + # iic读数据 + # addr:iic从机地址 + # data:读取数据列表。根据列表大小确定读取长度 + # return:读取长度,不一定正确 + def read(self, addr, data): + if id(data) == 0 or len(data) == 0: + return 0 + rLen = len(data) + #print(f"rLen={rLen}") + pack = [] + readBuf = [] + readLen = 0 + + packNum = rLen // 30 + rLen %= 30 + if rLen == 0: + rLen = 30 + packNum -= 1 + #print(f"packNum={packNum}") + pack.append(self._mCH341A_CMD_I2C_STREAM) + pack.append(self._mCH341A_CMD_I2C_STM_STA) + pack.append(self._mCH341A_CMD_I2C_STM_OUT | 1) + pack.append((addr << 1) | 0x01) + pack.append(self._mCH341A_CMD_I2C_STM_MS | 1) + for i in range(0, packNum): + pack.append(self._mCH341A_CMD_I2C_STM_IN | 30) + pack.append(self._mCH341A_CMD_I2C_STM_END) + sendBuf = (c_byte * len(pack))() + for j in range(0, len(pack)): + sendBuf[j] = pack[j] + recLen = (c_byte * 1)() + recBuf = (c_byte * self._mCH341A_CMD_I2C_STM_MAX)() + if not self.ch341WriteRead(self.fd, len(pack), sendBuf, self._mCH341A_CMD_I2C_STM_MAX, 1, recLen, recBuf): + return 0 + if recLen == 0: + return 0 + for j in range(0, recLen[0]): + readBuf.append(recBuf[j]) + readLen += 30 + pack.clear() + pack.append(self._mCH341A_CMD_I2C_STREAM) + if rLen > 1: + pack.append(self._mCH341A_CMD_I2C_STM_IN | (rLen - 1)) + pack.append(self._mCH341A_CMD_I2C_STM_IN | 0) + pack.append(self._mCH341A_CMD_I2C_STM_STO) + pack.append(self._mCH341A_CMD_I2C_STM_END) + sendBuf = (c_byte * len(pack))() + for j in range(0, len(pack)): + sendBuf[j] = pack[j] + recLen = (c_byte * 1)() + recBuf = (c_byte * self._mCH341A_CMD_I2C_STM_MAX)() + if not self.ch341WriteRead(self.fd, len(pack), sendBuf, self._mCH341A_CMD_I2C_STM_MAX, 1, recLen, recBuf): + return 0 + if recLen[0] == 0: + return 0 + for j in range(0, recLen[0]): + readBuf.append(recBuf[j]) + data.clear() + data.extend(readBuf) + readLen = len(pack) + #print(f"readLen={len(readBuf)}") + return readLen + + # 设置int引脚状态 + # lvl:高低电平。1高电平,0低电平 + def set_int(self, lvl): + status = (c_long * 1)() + self.ic.CH341GetInput(0, status) + time.sleep(0.01) + if lvl: + self.ch341SetOutput(self.fd, 0x03, 0xFF00, status[0] | self._mStateBitINT) + else: + self.ch341SetOutput(self.fd, 0x03, 0xFF00, status[0] & (~self._mStateBitINT)) + + # 读取int引脚状态 + # 返回:高低电平 + def get_int(self): + status = (c_long * 1)() + self.ic.CH341GetInput(0, status) + return (status[0] & self._mStateBitINT) >> 10 + + # 设置IIC速度 + # return:0错误,1成功 + def set_speed(self, speed): + if speed != self.IIC_SPEED_20 and speed != self.IIC_SPEED_100 and speed != self.IIC_SPEED_400 and speed != self.IIC_SPEED_750: + return False + if False == self.ch341SetStream(self.fd, speed | 0): + print("speed err") + return False + else: + return True diff --git a/class_finger.py b/class_finger.py new file mode 100644 index 0000000..c1814e2 --- /dev/null +++ b/class_finger.py @@ -0,0 +1,160 @@ + +from class_sensorcmd import * +from sensorPara import * +import struct + + +# 电容数据存储结构 +class capData: + def __init__(self): + self.sensorIndex = 0 # 电容序号,与iic addr相同 + self.channelCapData = list() # 原始通道数值 + self.tf = list() # 切向力数组 + self.tfDir = list() # 切向力方向数组 + self.nf = list() # 法向力数组 + self.sProxCapData = list() # 接近(自电容)数组 + self.mProxCapData = list() # 接近(互电容)数组 + self.cnt = 0 # 计数,测试用 + + def init(self, addr, yddsNum, sProxNum, mProxNum, capChannelNum): + self.sensorIndex = addr # 电容序号,与iic addr相同 + self.channelCapData = list(range(capChannelNum))# 原始通道数值 + self.tf = list(range(yddsNum)) # 切向力数组 + self.tfDir = list(range(yddsNum)) # 切向力方向数组 + self.nf = list(range(yddsNum)) # 法向力数组 + self.sProxCapData = list(range(sProxNum)) # 接近(自电容)数组 + self.mProxCapData = list(range(mProxNum)) # 接近(互电容)数组 + self.cnt = 0 # 计数,测试用 + + def deinit(self): + self.channelCapData = None + self.tf = None + self.tfDir = None + self.nf = None + self.sProxCapData = None + self.mProxCapData = None + +# 传感器类:包换传感器相关参数 +class ClassFinger: + def __init__(self, pca_idx, ch341): + self.snsCmd = ClassSensorCmd(ch341) + self.pcaIdx = pca_idx # iic使能芯片序号,从2开始 + self.readData = capData() + self.disconnected() + + # 检查传感器是否连接,如果读写地址正确则认为连接正常 + def checkSensor(self): + # 广播的方式读取当前传感器地址,并默认将iic地址配置为和pca相同的地址 + addrRead = self.snsCmd.getAddr(0) + if addrRead != self.pcaIdx: + if self.pcaIdx != self.snsCmd.setAddr(addrRead, self.pcaIdx): + print(f"set addr false, setaddr={self.pcaIdx}") + return False + else: + addrRead = self.pcaIdx + print(f"update iic addr, new addr ={addrRead}") + + # 设置发送数据类型为原始值 + if True != self.snsCmd.setSensorSendType(addrRead, 0): + print(f"setSensorSendType err, addr = {addrRead}") + + # 设置电容采集序列,这里按照地址来分配采集时序,只要每个传感器不同即可 + if self.snsCmd.setSensorCapOffset(addrRead, addrRead) != True: + print(f"setSensorCapOffset err, addr = {addrRead}") + + # 实际用户使用中只需要根据使用的传感器来定义参数即可,不需要读取项目号 + projectRead = self.snsCmd.getSensorProjectIdex(self.addr) + print(f"project={projectRead}") + findProjectFlg = False + if projectRead > 0: + for pro in finger_params: + if pro.prg == projectRead: + self.projectPara = pro + print(f"finger connected, project = {self.projectPara.name}") + findProjectFlg = True + + if findProjectFlg == False: + print("not found vailed project, project para use default") + + self.connected(addrRead) + + return True + + # 传感器连接,初始化参数 + def connected(self, addr): + self.addr = addr + self.connect = True + self.connectTimer = time.time() + self.packIdx = 0 + self.data = list() + self.data.extend(range(self.projectPara.pack_len))# + + self.readData.init(addr, self.projectPara.ydds_num, self.projectPara.s_prox_num, self.projectPara.m_prox_num, self.projectPara.sensor_num) + + #print(f"datalen={len(self.data)}") + + # 传感器断开,复位参数 + def disconnected(self): + self.addr = 0xFF # iic地址 + self.connect = False # 连接标志位 + self.packIdx = 0 # 采样序号 + self.connectTimer = 0 # 连接超时计时 + + self.projectPara = finger_params[0] + + self.readData.deinit() + + def capRead(self): + for retry in range(0, 3): + if self.snsCmd.getSensorCapData(self.addr, self.data) == True: + if self.data[5] != self.projectPara.sensor_num: + print(f"cap channel num err, read num = {self.data[5]}, expect num = {self.projectPara.sensor_num}") + + if self.data[4] != self.packIdx: + self.packIdx = self.data[4] + self.connectTimer = time.time() + + # 根据通道值占用字节大小获取通道数据 + if self.projectPara.cap_byte == 4: + for j in range(0, self.projectPara.sensor_num): + self.readData.channelCapData[j] = ((self.data[6 + j * self.projectPara.cap_byte] & 0xFF) + + ((self.data[6 + j * self.projectPara.cap_byte + 1] & 0xFF) << 8) + + ((self.data[6 + j * self.projectPara.cap_byte + 2] & 0xFF) << 16) + + ((self.data[6 + j * 4 + 3] & 0xFF) << 24)) + else: + for j in range(0, self.projectPara.sensor_num): + self.readData.channelCapData[j] = ((self.data[6 + j * self.projectPara.cap_byte] & 0xFF) + + ((self.data[6 + j * self.projectPara.cap_byte + 1] & 0xFF) << 8) + + ((self.data[6 + j * self.projectPara.cap_byte + 2] & 0xFF) << 16)) + + yddsOffset = 6 + self.projectPara.sensor_num*self.projectPara.cap_byte + + if self.projectPara.ydds_type == 2: + struct_size = sizeof(DynamicYddsComTs) + for i in range(self.projectPara.ydds_num): + offset = yddsOffset + i * struct_size + struct_data = self.data[offset : offset + struct_size] + struct_data = [value & 0xFF for value in struct_data] + struct_data = bytes(struct_data) # 转换为 bytes 类型 + instance = DynamicYddsComTs.from_buffer_copy(struct_data) + self.readData.nf[i] = instance.nf + self.readData.tf[i] = instance.tf + self.readData.tfDir[i] = instance.tfDir + self.readData.sProxCapData[i] = instance.prox + elif self.projectPara.ydds_type == 4: + pass + + print(f"capChannelDat={self.readData.channelCapData}") + for i in range(self.projectPara.ydds_num): + print(f"nf[{i}] = {self.readData.nf[i]}") + print(f"tf[{i}] = {self.readData.tf[i]}") + print(f"tfDir[{i}] = {self.readData.tfDir[i]}") + print(f"sProxCapData[{i}] = {self.readData.sProxCapData[i]}") + + break + else: + pass + + # 2S未接收到数据超时 + if (time.time() - self.connectTimer) > 2: + self.disconnected() diff --git a/class_sensorcmd.py b/class_sensorcmd.py new file mode 100644 index 0000000..818fd55 --- /dev/null +++ b/class_sensorcmd.py @@ -0,0 +1,255 @@ +import time +from class_ch341 import * +from enum import * + + +class ClassSensorCmd: + def __init__(self, ch341): + # 命令定义 + self.CMD_GET_CHANNEL_NUM = 0x01 # 读取通道数量 + self.CMD_GET_SENSOR_CAP_DATA = 0x60 # 读取传感器数据 + self.CMD_SET_SENSOR_UART_SEND_TYPE = 0x61 # 设置串口输出模式 + self.CMD_GET_SENSOR_CHANNEL = 0x62 # 读取通道数量 + self.CMD_SET_SENSOR_AUTO_DAC = 0x63 # 自动dac + self.CMD_GET_SENSOR_ERR_CODE = 0x64 # 读取错误码 + self.CMD_SET_SENSOR_CHANNEL_CALIBRATE = 0x65 # 设置通道重量标定 + self.CMD_GET_SENSOR_CHANNEL_CALIBRATE = 0x66 # 读取通道重量标定 + self.CMD_SET_SENSOR_AUTO_THRESHOLD = 0x67 # 设置自动阈值 + self.CMD_GET_SENSOR_THRESHOLD = 0x68 # 读取自动阈值 + self.CMD_SET_SENSOR_THRESHOLD = 0x69 # 设置通道阈值 + self.CMD_SET_SENSOR_TOUCH_THRESHOLD = 0x6A # 设置压力阈值 + self.CMD_SET_SENSOR_CHANNEL_CALIBRATE_QUICK = 0x6B # 最大力快速标定 + self.CMD_GET_SENSOR_TEST_HZ = 0x6C # 读取采样率 + self.CMD_GET_SENSOR_CALI_N_LIST = 0x6D # 读取标定列表 + self.CMD_SET_SENSOR_CHANNEL_GROUP_CALIBRATE = 0x6E # 设置通道组重量标定 + + self.CMD_SET_SENSOR_IIC_ADDR = 0x70 # 设置传感器IIC地址 + self.CMD_GET_SENSOR_IIC_ADDR = 0x71 # 读取传感器IIC地址 + self.CMD_SET_SENSOR_CDC_SYNC = 0x72 # 采集停止,用于同步 + self.CMD_SET_SENSOR_CDC_START_OFFSET = 0x73 # 设置电容开始偏移 + self.CMD_GET_SENSOR_TEMP = 0x74 # 读取温度 + self.CMD_SET_SENSOR_CDC_CFG_SAVE = 0x75 # 保存cdc配置 + self.CMD_SET_SENSOR_FACTOR = 0x76 # 恢复出厂设置 + self.CMD_SET_SENSOR_RESTART = 0x77 # 软件复位 + self.CMD_SET_SENSOR_WEIGHT_CALIBRATE = 0x78 # 设置重量标定参数 + self.CMD_SET_SENSOR_BASE_RESET = 0x79 # 基线复位 + self.CMD_SET_SENSOR_UNIFORMIZATION = 0x7A # 归一化 + self.CMD_SET_SENSOR_CHANNEL_ENABLE = 0x7B # 通道使能 + self.CMD_SET_SENSOR_CHANNEL_BASE_RESET = 0x7C # 单独通道复位 + self.CMD_GET_SENSOR_WEIGHT_CALIBRATE = 0x7D # 读取重量标定参数 + self.CMD_GET_SENSOR_CHANNEL_STATE = 0x7E # 读取电容通道状态 + self.CMD_SET_SENSOR_SEND_TYPE = 0x7F # 数据传输类型 + + self.CMD_GET_VERSION = 0xA0 # 读取软件版本 + self.CMD_SOFT_RESTART = 0xA1 # 软件复位 + self.CMD_GET_TYPE = 0xA2 # 读取设备类型 + self.CMD_SET_TYPE = 0xA3 # 设置设备类型 + self.CMD_SET_INF = 0xA5 # 设置输出接口 + self.CMD_GET_PRG = 0xA6 # 获取项目类型 + + self._ch341 = ch341 + self.sendTimePre = list() + self.sendTimePre.append(time.time()) + self.sendTimePre.append(time.time()) + self.sendTimeNow = list() + self.sendTimeNow.append(time.time()) + self.sendTimeNow.append(time.time()) + self.sendCnt = list() + self.sendCnt.append(0) + self.sendCnt.append(0) + + # 计算校验和 + # pack 数据 + def calcSum(self, pack): + if len(pack) <= 5: + return 0 + _sum = 0 + for i in range(0, len(pack)): + _sum += (pack[i] & 0xFF) + pack.append(_sum & 0xFF) + pack.append(_sum >> 8) + + # 检查校验值 + # pack:要检查的数据 + # return 0:校验值不一致 + # 1:校验值一致 + def checkSum(self, pack): + if len(pack) <= 5: + return False + _sum = 0 + for i in range(0, len(pack) - 2): + _sum += (pack[i] & 0xFF) + chkL = _sum & 0xFF + chkH = (_sum >> 8) & 0xFF + rchkL = pack[len(pack) - 2] & 0xFF + rchkH = pack[len(pack) - 1] & 0xFF + if chkL == rchkL and chkH == rchkH: + return True + else: + return False + + # 设置传感器iic地址 + # addr:当前地址 + # new_addr:系地址 + # return:读取的地址 + def setAddr(self, addr, new_addr): + _pack = list() + _pack.append(0xAA) + _pack.append(0x55) + _pack.append(0x03) + _pack.append(self.CMD_SET_SENSOR_IIC_ADDR) + _pack.append(0x00) + _pack.append(0x00) + _pack.append(0x00) + _pack.append(new_addr) + _pack.append(0x00) + self.calcSum(_pack) + self._ch341.write(addr, _pack) + _pack.clear() + _pack.extend(list(range(11))) + time.sleep(0.01) + self._ch341.read(new_addr, _pack) + checksum = self.checkSum(_pack) + if checksum == True and ((self.CMD_SET_SENSOR_IIC_ADDR|0x80) == c_uint8(_pack[3]).value): + return _pack[7] & 0xFF + return 0 + + def getAddr(self, addr): + _pack = list() + _pack.append(0xAA) + _pack.append(0x55) + _pack.append(0x03) + _pack.append(self.CMD_GET_SENSOR_IIC_ADDR) + _pack.append(0x00) + _pack.append(0x00) + _pack.append(0x00) + _pack.append(0x00) + _pack.append(0x00) + self.calcSum(_pack) + self._ch341.write(addr, _pack) + _pack.clear() + _pack.extend(list(range(11))) + time.sleep(0.01) + self._ch341.read(addr, _pack) + if self.checkSum(_pack) == True: + return _pack[7] & 0xFF + return 0 + + def getSensorVersion(self, addr): + pass + + # 读取电容通道数 + # addr:传感器地址 + def getSensorNum(self, addr): + _pack = list() + _pack.append(0xAA) + _pack.append(0x55) + _pack.append(0x03) + _pack.append(self.CMD_GET_CHANNEL_NUM) + _pack.append(0x00) + _pack.append(0x00) + _pack.append(0x00) + _pack.append(0x00) + _pack.append(0x00) + self.calcSum(_pack) + self._ch341.write(addr, _pack) + _pack.clear() + _pack.extend(list(range(15))) + time.sleep(0.01) + self._ch341.read(addr, _pack) + if self.checkSum(_pack) == True: + return (_pack[5] & 0xFF) + (_pack[6] & 0xFF) * 256 + return 0 + + # 读取项目编号 + # addr:传感器地址 + def getSensorProjectIdex(self, addr): + _pack = list() + _pack.append(0xAA) + _pack.append(0x55) + _pack.append(0x03) + _pack.append(self.CMD_GET_PRG) + _pack.append(0x00) + _pack.append(0x00) + _pack.append(0x00) + _pack.append(0x00) + _pack.append(0x00) + self.calcSum(_pack) + self._ch341.write(addr, _pack) + _pack.clear() + _pack.extend(list(range(11))) + time.sleep(0.01) + self._ch341.read(addr, _pack) + if self.checkSum(_pack) == True: + return (_pack[7] & 0xFF) + (_pack[8] & 0xFF) * 256 + return 0 + + # 设置发送类型 + # addr:传感器地址 + def setSensorSendType(self, addr, sendType): + _pack = list() + _pack.append(0xAA) + _pack.append(0x55) + _pack.append(0x03) + _pack.append(self.CMD_SET_SENSOR_SEND_TYPE) + _pack.append(0x00) + _pack.append(0x00) + _pack.append(0x00) + _pack.append(sendType) + _pack.append(0x00) + self.calcSum(_pack) + self._ch341.write(addr, _pack) + _pack.clear() + _pack.extend(list(range(11))) + time.sleep(0.01) + self._ch341.read(addr, _pack) + if (self.checkSum(_pack) == True) and ((self.CMD_SET_SENSOR_SEND_TYPE|0x80) == c_uint8(_pack[3]).value): + return True + return False + + # 设置采集偏置 + # addr:传感器地址 + def setSensorCapOffset(self, addr, offset): + _pack = list() + _pack.append(0xAA) + _pack.append(0x55) + _pack.append(0x03) + _pack.append(self.CMD_SET_SENSOR_CDC_START_OFFSET) + _pack.append(0x00) + _pack.append(0x00) + _pack.append(0x00) + _pack.append(offset) + _pack.append(0x00) + self.calcSum(_pack) + self._ch341.write(addr, _pack) + _pack.clear() + _pack.extend(list(range(6))) + time.sleep(0.01) + self._ch341.read(addr, _pack) + checksum = self.checkSum(_pack) + if (checksum == True) and ((self.CMD_SET_SENSOR_CDC_START_OFFSET|0x80) == c_uint8(_pack[3]).value): + return True + return False + + # 读取电容数据 + # addr:传感器地址 + def getSensorCapData(self, addr, buf): + tarLen = len(buf) + err = self._ch341.read(addr, buf) + if(err == 0): + print("get data err") + checkSum = self.checkSum(buf) + + if(tarLen != len(buf)): + buf.clear() + buf.extend(range(tarLen)) + # try: + if (len(buf) == tarLen and buf[0] & 0xFF) == 0x55 and (buf[1] & 0xFF) == 0xAA and checkSum == True: + return True + else: + #print(f"time={time.time()},len(buf) = {len(buf)}, tarLen={tarLen}, buf[0]={buf[0]}, buf[1]={buf[1]}, sum={checkSum}") + pass + return False + + + diff --git a/lib/ch341/CH341DLLA64.DLL b/lib/ch341/CH341DLLA64.DLL new file mode 100644 index 0000000..12a11a5 Binary files /dev/null and b/lib/ch341/CH341DLLA64.DLL differ diff --git a/lib/ch341/CH341DLLA64.LIB b/lib/ch341/CH341DLLA64.LIB new file mode 100644 index 0000000..c62ba77 Binary files /dev/null and b/lib/ch341/CH341DLLA64.LIB differ diff --git a/lib/ch341/ch341_lib.h b/lib/ch341/ch341_lib.h new file mode 100644 index 0000000..88b0093 --- /dev/null +++ b/lib/ch341/ch341_lib.h @@ -0,0 +1,399 @@ +#ifndef _CH341_LIB_H +#define _CH341_LIB_H + +typedef enum _EEPROM_TYPE { + ID_24C01, + ID_24C02, + ID_24C04, + ID_24C08, + ID_24C16, + ID_24C32, + ID_24C64, + ID_24C128, + ID_24C256, + ID_24C512, + ID_24C1024, + ID_24C2048, + ID_24C4096 +} EEPROM_TYPE; + +typedef enum _CHIP_TYPE { + CHIP_CH341 = 0, + CHIP_CH347T = 1, + CHIP_CH347F = 2, +} CHIP_TYPE; + +typedef enum { + TYPE_TTY = 0, + TYPE_HID, + TYPE_VCP, +} FUNCTYPE; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * CH34XOpenDevice - open device + * @pathname: device path in /dev directory + * + * The function return positive file descriptor if successful, others if fail. + */ +extern int CH34xOpenDevice(const char *pathname); + +/** + * CH34XCloseDevice - close device + * @fd: file descriptor of device + * + * The function return true if successful, false if fail. + */ +extern bool CH34xCloseDevice(int fd); + +/** + * CH34x_GetDriverVersion - get vendor driver version + * @fd: file descriptor of device + * @Drv_Version: pointer to version string + * + * The function return true if successful, false if fail. + */ +extern bool CH34x_GetDriverVersion(int fd, unsigned char *Drv_Version); + +/** + * CH34x_GetChipVersion - get chip version + * @fd: file descriptor of device + * @Version: pointer to version + * + * The function return true if successful, false if fail. + */ +extern bool CH34x_GetChipVersion(int fd, unsigned char *Version); + +/** + * CH34x_GetChipType - get chip type + * @fd: file descriptor of device + * @ChipType: pointer to chip type + * + * The function return true if successful, false if fail. + */ +extern bool CH34x_GetChipType(int fd, CHIP_TYPE *ChipType); + +/** + * CH34X_GetDeviceID - get device vid and pid + * @fd: file descriptor of device + * @id: pointer to store id which contains vid and pid + * + * The function return true if successful, false if fail. + */ +extern bool CH34X_GetDeviceID(int fd, uint32_t *id); + +/** + * CH34xSetParaMode - set chip parrallel work mode + * @fd: file descriptor of device + * @Mode: work mode, 0/1->EPP mode, 2->MEM mode + * + * The function return true if successful, false if fail. + */ +extern bool CH34xSetParaMode(int fd, uint8_t Mode); + +/** + * CH34xInitParallel - initial chip parrallel work mode + * @fd: file descriptor of device + * @Mode: work mode, 0/1->EPP mode, 2->MEM mode + * + * The function return true if successful, false if fail. + */ +extern bool CH34xInitParallel(int fd, uint8_t Mode); + +/** + * CH34xEppRead - read data or addr in parrallel EPP mode + * @fd: file descriptor of device + * @oBuffer: pointer to read buffer + * @ioLength: read length + * @PipeMode: 0->read pipe0 data, 1->read pipe1 addr + * + * The function return read 0 if successful, others if fail. + */ +extern int CH34xEppRead(int fd, uint8_t *oBuffer, uint32_t ioLength, uint8_t PipeMode); + +/** + * CH34xEppWrite - write data or addr in parrallel EPP mode + * @fd: file descriptor of device + * @iBuffer: pointer to write buffer + * @ioLength: write length + * @PipeMode: 0->write pipe0 data, 1->write pipe1 addr + * + * The function return 0 if successful, others if fail. + */ +extern int CH34xEppWrite(int fd, uint8_t *iBuffer, uint32_t ioLength, uint8_t PipeMode); + +/** + * CH34xEppWriteData - write data in parrallel EPP mode + * @fd: file descriptor of device + * @iBuffer: pointer to write buffer + * @ioLength: write length + * + * The function return 0 if successful, others if fail. + */ +extern int CH34xEppWriteData(int fd, uint8_t *iBuffer, uint32_t ioLength); + +/** + * CH34xEppReadData - read data in parrallel EPP mode + * @fd: file descriptor of device + * @oBuffer: pointer to read buffer + * @ioLength: read length + * + * The function return 0 if successful, others if fail. + */ +extern int CH34xEppReadData(int fd, uint8_t *oBuffer, uint32_t ioLength); + +/** + * CH34xEppWriteAddr - write addr in parrallel EPP mode + * @fd: file descriptor of device + * @iBuffer: pointer to write buffer + * @ioLength: write length + * + * The function return 0 if successful, others if fail. + */ +extern int CH34xEppWriteAddr(int fd, uint8_t *iBuffer, uint32_t ioLength); + +/** + * CH34xEppReadAddr - read addr in parrallel EPP mode + * @fd: file descriptor of device + * @oBuffer: pointer to read buffer + * @ioLength: read length + * + * The function return 0 if successful, others if fail. + */ +extern int CH34xEppReadAddr(int fd, uint8_t *oBuffer, uint32_t ioLength); + +/** + * CH34xEppSetAddr - set addr in parrallel EPP mode + * @fd: file descriptor of device + * @iAddr: addr data + * + * The function return 0 if successful, others if fail. + */ +extern int CH34xEppSetAddr(int fd, uint32_t iAddr); + +/** + * CH34xSetTimeout - set USB data read and write timeout + * @fd: file descriptor of device + * @iWriteTimeout: data download timeout in milliseconds + * @iReadTimeout: data upload timeout in milliseconds + * + * The function return true if successful, false if fail. + */ +extern bool CH34xSetTimeout(int fd, uint32_t iWriteTimeout, uint32_t iReadTimeout); + +/** + * CH34xInitMEM - initial chip in parrallel MEM mode + * @fd: file descriptor of device + * + * The function return true if successful, false if fail. + */ +extern bool CH34xInitMEM(int fd); + +/** + * CH34xMEMReadData - read data in parrallel MEM mode + * @fd: file descriptor of device + * @oBuffer: pointer to read buffer + * @ioLength: read length + * @PipeMode: 0->read pipe0, 1->read pipe1 + * + * The function return 0 if successful, others if fail. + */ +extern int CH34xMEMReadData(int fd, uint8_t *oBuffer, uint32_t ioLength, uint8_t PipeMode); + +/** + * CH34xMEMWriteData - write data in parrallel MEM mode + * @fd: file descriptor of device + * @iBuffer: pointer to write buffer + * @ioLength: write length + * @PipeMode: 0->write pipe0, 1->write pipe1 + * + * The function return 0 if successful, others if fail. + */ +extern int CH34xMEMWriteData(int fd, uint8_t *iBuffer, uint32_t ioLength, uint32_t PipeMode); + +/** + * CH34xSetStream - configure spi/i2c interface in stream mode + * @fd: file descriptor of device + * @Mode: stream mode + * ->bit0~1: set I2C SCL rate + * --> 00 : low rate 20KHz + * --> 01 : standard rate 100KHz + * --> 10 : fast rate 400KHz + * --> 11 : high rate 750KHz + * ->bit2: set spi mode + * --> 0 : one in one out(D3: clk, D5: out, D7: in) + * --> 1 : two in two out(D3 :clk, D4/D5: out, D6/D7 :in) + * ->bit7: set spi data mode + * --> 0 : low bit first + * --> 1 : high bit first + * other bits must keep 0 + * + * The function return true if successful, false if fail. + */ +extern bool CH34xSetStream(int fd, uint8_t Mode); + +/** + * CH34xSetDelaymS - delay operation + * @fd: file descriptor of device + * @iDelay: delay time in millseconds + * + * The function return true if successful, false if fail. + */ +extern bool CH34xSetDelaymS(int fd, uint32_t iDelay); + +/** + * CH34xReadData - read for spi/i2c operation + * @fd: file descriptor of device + * @oReadBuffer: pointer to read buffer + * @oReadLength: pointer to read length + * + * The function return true if successful, false if fail. + */ +extern bool CH34xReadData(int fd, void *oReadBuffer, uint32_t *oReadLength); + +/** + * CH34xWriteData - write data for spi/i2c operation + * @fd: file descriptor of device + * @iWriteBuffer: pointer to write buffer + * @iWriteLength: pointer to write length + * + * The function return true if successful, false if fail. + */ +extern bool CH34xWriteData(int fd, void *iWriteBuffer, uint32_t *iWriteLength); + +/** + * CH34xWriteRead - write data then read for spi/i2c operation + * @fd: file descriptor of device + * @iWriteLength: write length + * @iWriteBuffer: pointer to write buffer + * @iReadStep: per read length + * @iReadTimes: read times + * @oReadLength: pointer to read length + * @oReadBuffer: pointer to read buffer + * + * The function return true if successful, false if fail. + */ +extern bool CH34xWriteRead(int fd, uint32_t iWriteLength, void *iWriteBuffer, uint32_t iReadStep, uint32_t iReadTimes, + uint32_t *oReadLength, void *oReadBuffer); + +/** + * CH34xGetInput - get io status of CH341 + * @fd: file descriptor of device + * @iStatus: pointer to io status + * Note: + * Bit7~Bit0<==>D7-D0, Bit8<==>ERR#, Bit9<==>PEMP, Bit10<==>INT# + * Bit11<==>SLCT, Bit13<==>WAIT#, Bit14<==>DATAS#/READ#, Bit15<==>ADDRS#/ADDR/ALE, Bit23<==>SDA + * + * The function return true if successful, false if fail. + */ +extern bool CH34xGetInput(int fd, uint32_t *iStatus); + +/** + * CH34xSetOutput - set direction and output data of CH341 + * @fd: file descriptor of device + * @iEnable: set direction and data enable + * --> Bit16 High : effect on Bit15~8 of iSetDataOut + * --> Bit17 High : effect on Bit15~8 of iSetDirOut + * --> Bit18 High : effect on Bit7~0 of iSetDataOut + * --> Bit19 High : effect on Bit7~0 of iSetDirOut + * --> Bit20 High : effect on Bit23~16 of iSetDataOut + * @iSetDirOut: set io direction + * -- > Bit High : Output + * -- > Bit Low : Input + * @iSetDataOut: set io data + * Output: + * -- > Bit High : High level + * -- > Bit Low : Low level + * Note: + * Bit7~Bit0<==>D7-D0, Bit8<==>ERR#, Bit9<==>PEMP, Bit10<==>INT# + * Bit11<==>SLCT, Bit13<==>WAIT#, Bit14<==>DATAS#/READ#, Bit15<==>ADDRS#/ADDR/ALE + * + * The pins below can only be used in output mode: + * Bit16<==>RESET#, Bit17<==>WRITE#, Bit18<==>SCL, Bit29<==>SDA + * + * The function return true if successful, false if fail. + */ +extern bool CH34xSetOutput(int fd, uint32_t iEnable, uint32_t iSetDirOut, uint32_t iSetDataOut); + +/** + * CH34xSet_D5_D0 - set direction and output data of D5-D0 on CH341 + * @fd: file descriptor of device + * @iSetDirOut: set io direction + * -- > Bit High : Output + * -- > Bit Low : Input + * @iSetDataOut: set io data + * Output: + * -- > Bit High : High level + * -- > Bit Low : Low level + * + * The function return true if successful, false if fail. + */ +extern bool CH34xSet_D5_D0(int fd, uint8_t iSetDirOut, uint8_t iSetDataOut); + +/** + * CH34xStreamI2C - write/read i2c in stream mode + * @fd: file descriptor of device + * @iWriteLength: write length + * @iWriteBuffer: pointer to write buffer + * @iReadLength: read length + * @oReadBuffer: pointer to read buffer + * + * The function return true if successful, false if fail. + */ +extern bool CH34xStreamI2C(int fd, uint32_t iWriteLength, void *iWriteBuffer, uint32_t iReadLength, void *oReadBuffer); + +/** + * CH34xReadEEPROM - read data from eeprom + * @fd: file descriptor of device + * @iEepromID: eeprom type + * @iAddr: address of eeprom + * @iLength: read length + * @oBuffer: pointer to read buffer + * + * The function return true if successful, false if fail. + */ +extern bool CH34xReadEEPROM(int fd, EEPROM_TYPE iEepromID, uint32_t iAddr, uint32_t iLength, uint8_t *oBuffer); + +/** + * CH34xWriteEEPROM - write data to eeprom + * @fd: file descriptor of device + * @iEepromID: eeprom type + * @iAddr: address of eeprom + * @iLength: write length + * @iBuffer: pointer to write buffer + * + * The function return true if successful, false if fail. + */ +extern bool CH34xWriteEEPROM(int fd, EEPROM_TYPE iEepromID, uint32_t iAddr, uint32_t iLength, uint8_t *iBuffer); + +/** + * CH34xStreamSPIx - write/read spi in stream mode + * @fd: file descriptor of device + * @iChipSelect: cs enable + * @iLength: the length of data + * @ioBuffer: one in one out buffer + * @ioBuffer2: two in two out buffer + * + * The function return true if successful, false if fail. + */ +extern bool CH34xStreamSPIx(int fd, uint32_t iChipSelect, uint32_t iLength, void *ioBuffer, void *ioBuffer2); + +/** + * CH34xStreamSPI4 - write/read spi in 4-line stream mode + * @fd: file descriptor of device + * @iChipSelect: cs enable + * @iLength: the length of data + * @ioBuffer: one in one out buffer + * + * The function return true if successful, false if fail. + */ +extern bool CH34xStreamSPI4(int fd, uint32_t iChipSelect, uint32_t iLength, void *ioBuffer); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/ch341/libch347.so b/lib/ch341/libch347.so new file mode 100644 index 0000000..a2d78e8 Binary files /dev/null and b/lib/ch341/libch347.so differ diff --git a/sensorPara.py b/sensorPara.py new file mode 100644 index 0000000..5b76521 --- /dev/null +++ b/sensorPara.py @@ -0,0 +1,67 @@ +from typing import List, Optional +from ctypes import Structure, sizeof, c_float, c_uint32, c_uint16 + + +class DynamicYddsComTs(Structure): + _pack_ = 1 # 按 1 字节对齐 + _fields_ = [ + ("nf", c_float), + ("nfCap", c_uint32), + ("tf", c_float), + ("tfCap", c_uint32), + ("tfDir", c_uint16), + ("prox", c_uint32), + ] + +#todo 其他三维力类型待补充 + + +class FingerHeatMap: + def __init__(self, rows: int, cols: int, file_path: str, cap_count: int, cap_indices: List[int]): + self.rows = rows + self.cols = cols + self.file_path = file_path + self.cap_count = cap_count + self.cap_indices = cap_indices + +class FingerParamTS: + def __init__(self, prg: int, pack_len: int, sensor_num: int, touch_num: int, ydds_num: int, + s_prox_num: int, m_prox_num: int, cap_byte: int, ydds_type: int, had_err: int, + cali_num: int, name: str, display_type_para: str, p_heat_map: Optional[List[FingerHeatMap]]): + self.prg = prg + self.pack_len = pack_len + self.sensor_num = sensor_num + self.touch_num = touch_num + self.ydds_num = ydds_num + self.s_prox_num = s_prox_num + self.m_prox_num = m_prox_num + self.cap_byte = cap_byte + self.ydds_type = ydds_type + self.had_err = had_err + self.cali_num = cali_num + self.name = name + self.display_type_para = display_type_para + self.p_heat_map = p_heat_map + +# 定义 fingerHeatMap 数据 +finger2_power_cap_index = [ + FingerHeatMap(16, 8, "TS-F-A/heatMapPara16_8.dat", 7, [0, 1, 2, 3, 4, 5, 6, 255, 255, 255, 255, 255, 255, 255, 255, 255]) +] + +finger17_power_cap_index = [ + FingerHeatMap(6, 7, "TS-T-A/weight6X7X6.dat", 6, [0, 1, 4, 5, 6, 7, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]), + FingerHeatMap(6, 7, "TS-T-A/weight6X7X6.dat", 6, [2, 3, 8, 9, 10, 11, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]) +] + +# 定义 fingerParams 数据 +finger_params = [ + FingerParamTS(2, 62, 8, 7, 1, 1, 0, 4, 2, 0, 22, "通用手指", "TypeA", finger2_power_cap_index), + FingerParamTS(17, 78, 16, 13, 2, 2, 1, 3, 4, 1, 22, "两指-大包", "TypeB", finger17_power_cap_index), + FingerParamTS(18, 462, 50, 49, 50, 1, 0, 3, 4, 1, 22, "两指-阵列", "TypeC", finger2_power_cap_index), + FingerParamTS(19, 62, 8, 7, 1, 0, 0, 4, 2, 0, 22, "通用手指New", "TypeA", finger2_power_cap_index), + FingerParamTS(20, 45, 7, 6, 2, 1, 0, 3, 4, 1, 27, "强脑-大拇指(量)", "TypeD", finger2_power_cap_index), + FingerParamTS(21, 69, 11, 8, 3, 2, 1, 3, 4, 1, 27, "强脑-食指(量)", "TypeE", finger2_power_cap_index), + FingerParamTS(22, 69, 11, 8, 3, 2, 1, 3, 4, 1, 27, "强脑-中指(量)", "TypeE", finger2_power_cap_index), + FingerParamTS(23, 69, 11, 8, 3, 2, 1, 3, 4, 1, 27, "强脑-无名指(量)", "TypeE", finger2_power_cap_index), + FingerParamTS(24, 45, 7, 6, 2, 1, 0, 3, 4, 1, 27, "强脑-小拇指(量)", "TypeD", finger2_power_cap_index), +]