Merge branch 'jgy-dev-first-2024-12-09' into 'main'
初始版本,接近数据不对 See merge request tactilesensor/fingersensorsdk/finger/python!1
This commit is contained in:
41
.gitignore
vendored
Normal file
41
.gitignore
vendored
Normal file
@ -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/*
|
||||
182
cap_read.py
Normal file
182
cap_read.py
Normal file
@ -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()
|
||||
262
class_ch341.py
Normal file
262
class_ch341.py
Normal file
@ -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
|
||||
160
class_finger.py
Normal file
160
class_finger.py
Normal file
@ -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()
|
||||
255
class_sensorcmd.py
Normal file
255
class_sensorcmd.py
Normal file
@ -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
|
||||
|
||||
|
||||
|
||||
BIN
lib/ch341/CH341DLLA64.DLL
Normal file
BIN
lib/ch341/CH341DLLA64.DLL
Normal file
Binary file not shown.
BIN
lib/ch341/CH341DLLA64.LIB
Normal file
BIN
lib/ch341/CH341DLLA64.LIB
Normal file
Binary file not shown.
399
lib/ch341/ch341_lib.h
Normal file
399
lib/ch341/ch341_lib.h
Normal file
@ -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
|
||||
BIN
lib/ch341/libch347.so
Normal file
BIN
lib/ch341/libch347.so
Normal file
Binary file not shown.
67
sensorPara.py
Normal file
67
sensorPara.py
Normal file
@ -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),
|
||||
]
|
||||
Reference in New Issue
Block a user