我正在使用具有适用于 Windows 的本机软件的 FTDI 设备,但没有适用于 Linux 的软件。我正在尝试使用pylibftdi
. 我想翻译C# code
设备制造商提供的并且据称可以工作(不清楚是否属实)但没有成功。到目前为止,我已经完成了以下工作:
$ lsusb
Bus 006 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 003: ID 046d:c52b Logitech, Inc. Unifying Receiver
Bus 001 Device 002: ID 04f2:0833 Chicony Electronics Co., Ltd KU-0833 Keyboard
**Bus 001 Device 006: ID 0403:6001 Future Technology Devices International, Ltd FT232 Serial (UART) IC**
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
粗体设备 ( Bus 001 Device 006: ID 0403:6001
) 是我想从中读取的设备。
- 然后安装
pylibftdi
并验证设备是否可以通过pylibftdi
API 读取:
$ python3
Python 3.9.5 (default, Jun 4 2021, 12:28:51)
[GCC 7.5.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys, pylibftdi as ftdi
>>> print(ftdi.Driver().list_devices())
[('FTDI', 'Cognionics Quick-20 20CH 1706Q20N', 'AI2SUN90')]
- 很明显,设备已连接并被识别。但是,当我尝试从设备中读取数据时,我收到了空数组:
>>> d = ftdi.Device()
>>> vars(d)
{'_opened': True, 'driver': <pylibftdi.driver.Driver object at 0x7fd819320910>, 'fdll': <CDLL 'libftdi.so.1', handle 557bc3ca6560 at 0x7fd8190aee80>, 'device_id': None, 'mode': 'b', 'encoding': 'latin1', 'encoder': <encodings.latin_1.IncrementalEncoder object at 0x7fd819320a60>, 'decoder': <encodings.latin_1.IncrementalDecoder object at 0x7fd8190aefd0>, '_baudrate': 9600, 'interface_select': None, 'device_index': 0, 'list_index': None, 'ctx': <ctypes.c_char_Array_1024 object at 0x7fd819342c40>}
>>> d.read(100)
b''
>>> d.read(100)
b''
>>> d.read(100)
b''
- 该
C#
代码(由制造商提供)据称可以工作,但我无法对其进行测试。似乎最简单的方法是将其转换为python
但即使这样也具有挑战性,因为我不知道如何复制ftdi
正在使用的常量和函数调用。提供的C#
代码是:
UInt32 ftDevCount = 0;
ftStatus = ftDev.GetNumberOfDevices(ref ftDevCount);
ftdiDeviceList = new FTDI.FT_DEVICE_INFO_NODE[ftDevCount];
ftStatus = ftDev.GetDeviceList(ftdiDeviceList);
String[] deviceNames = new String[ftDevCount];
for (int c = 0; c < ftDevCount; c++)
{
deviceNames[c] = ftdiDeviceList[c].Description.ToString();
}
Connecting to a device and configuring the serial port settings
if (ftDev.OpenBySerialNumber(ftdiDeviceList[devID].SerialNumber) == FTDI.FT_STATUS.FT_OK)
{ ftDev.SetFlowControl(FTDI.FT_FLOW_CONTROL.FT_FLOW_RTS_CTS, 0x11, 0x13);
ftDev.SetDataCharacteristics(FTDI.FT_DATA_BITS.FT_BITS_8, FTDI.FT_STOP_BITS.FT_STOP_BITS_1, FTDI.FT_PARITY.FT_PARITY_NONE);
ftDev.SetLatency(2);
ftDev.SetBaudRate((uint)3000000);
connectedName = ftdiDeviceList[devID].Description.ToString();
return true;
}
else
{
return false; //failed to open!
}
public byte ReadByte()
{
UInt32 bytesRead = 0;
byte[] t_data = new byte[1];
ftDev.Read(t_data, 1, ref bytesRead);
return t_data[0];
}
public void WriteByte(byte dat)
{
UInt32 bytesWritten = 0;
byte[] data = new byte[1];
data[0] = dat;
ftDev.Write(data, 1, ref bytesWritten);
}
//wait for sync byte 0xFF
while (byteInterface.ReadByte() != 255) {};
//read packet counter
int packetCount = byteInterface.ReadByte();
//read the 20 EEG channels
int NumEEG = 20;
for (int c = 0; c < NumEEG; c++)
{
msb = byteInterface.ReadByte();
lsb2 = byteInterface.ReadByte();
lsb1 = byteInterface.ReadByte();
int tempEEG = (msb << 24) | (lsb2 << 17) | (lsb1 << 10);
}
int NumACC = 3;
//read the 3 ACC channels
for (int c = 0; c < NumACC; c++)
{
msb = byteInterface.ReadByte();
lsb2 = byteInterface.ReadByte();
lsb1 = byteInterface.ReadByte();
int tempACC = (msb << 24) | (lsb2 << 17) | (lsb1 << 10);
}
//read packet tail
int impStatus = byteInterface.ReadByte();
//read battery voltage
int batteryByte = byteInterface.ReadByte();
//read trigger
int trigger = (byteInterface.ReadByte()<<8) + byteInterface.ReadByte();
ftDev.SetFlowControl(FTDI.FT_FLOW_CONTROL.FT_FLOW_RTS_CTS, 0x11, 0x13);
ftDev.SetDataCharacteristics(FTDI.FT_DATA_BITS.FT_BITS_8, FTDI.FT_STOP_BITS.FT_STOP_BITS_1, FTDI.FT_PARITY.FT_PARITY_NONE);
ftDev.SetLatency(2);
ftDev.SetBaudRate((uint)3000000);
进入某事python
。我想我可以使用 重置波特率d.baudrate = 3000000
,我可以使用更改延迟计时器,d.ftdi_fn.ftdi_set_latency_timer(2)
但我不知道如何设置数据特征,常量的含义(FTDI.FT_DATA_BITS.FT_BITS_8
等),以及如何设置与C#
代码相同的流量控制.
- 其他 SO 帖子也参考了此处找到的 D2XX 程序员指南,但没有看到将其应用于此问题的方法
任何建议,将不胜感激。