obj*_*001 7 objective-c dmx512 ftdi
我正在尝试与Enttec USB DMX Pro进行通信.主要是接收DMX.
他们在这里发布了一个Visual C++版本,但我对如何转换为Obj-c感到有点困惑.Enttec写道,"使用适用于Mac的FTDI库与PRO交谈,并参考D2XX编程指南打开并与设备通信." Objective-C的所有示例应用程序都在那里?有没有简单的方法与Enttec DMX USB Pro进行通信?
Bra*_*son 25
我已经在Mac上使用FTDI芯片做了大量的工作,所以我可以在这里提供一点见解.我使用了USB串行转换器的单通道和双通道变体,它们的行为方式相同.
FTDI具有虚拟COM端口驱动程序,它们在您的系统上创建一个串行COM端口,代表连接到其芯片的串行连接,以及它们的D2XX直接通信库.您将要使用后者,可以从他们的站点下载各种平台.
用于Mac的D2XX库有一个独立的.dylib(最新版本为libftd2xx.1.2.2.dylib)或最近开始发布的新静态库.该软件包中包含您需要的相应头文件(ftd2xx.h和WinTypes.h).
在您的Xcode项目中,添加.dylib作为要链接的框架,并将ftd2xx.h,WinTypes.h和ftd2xx.cfg文件添加到您的项目中.在Copy Bundled Frameworks构建阶段,确保该阶段存在libftd2xx.1.2.2.dylib和ftd2xx.cfg.您可能还需要调整此库所需的相对路径,以使其在您的应用程序包中运行,因此您可能需要在命令行对其运行以下命令:
install_name_tool -id @executable_path/../Frameworks/libftd2xx.1.2.2.dylib libftd2xx.1.2.2.dylib
Run Code Online (Sandbox Code Playgroud)
一旦您的项目都配置正确,您将需要导入FTDI标头:
#import "ftd2xx.h"
Run Code Online (Sandbox Code Playgroud)
并开始连接到您的串行设备.您在问题中链接到的示例包含可下载的C++示例,该示例显示了它们与设备的通信方式.您可以使用几乎所有在那里使用的C代码并将其放在Objective-C应用程序中.他们只是希望使用标准的FTDI D2XX命令,这些命令在可下载的D2XX程序员指南中有详细描述.
这是我从我的一个应用程序中提取的一些代码,用于连接到以下设备之一:
DWORD numDevs = 0;
// Grab the number of attached devices
ftdiPortStatus = FT_ListDevices(&numDevs, NULL, FT_LIST_NUMBER_ONLY);
if (ftdiPortStatus != FT_OK)
{
NSLog(@"Electronics error: Unable to list devices");
return;
}
// Find the device number of the electronics
for (int currentDevice = 0; currentDevice < numDevs; currentDevice++)
{
char Buffer[64];
ftdiPortStatus = FT_ListDevices((PVOID)currentDevice,Buffer,FT_LIST_BY_INDEX|FT_OPEN_BY_DESCRIPTION);
NSString *portDescription = [NSString stringWithCString:Buffer encoding:NSASCIIStringEncoding];
if ( ([portDescription isEqualToString:@"FT232R USB UART"]) && (usbRelayPointer != NULL))
{
// Open the communication with the USB device
ftdiPortStatus = FT_OpenEx("FT232R USB UART",FT_OPEN_BY_DESCRIPTION,usbRelayPointer);
if (ftdiPortStatus != FT_OK)
{
NSLog(@"Electronics error: Can't open USB relay device: %d", (int)ftdiPortStatus);
return;
}
//Turn off bit bang mode
ftdiPortStatus = FT_SetBitMode(*usbRelayPointer, 0x00,0);
if (ftdiPortStatus != FT_OK)
{
NSLog(@"Electronics error: Can't set bit bang mode");
return;
}
// Reset the device
ftdiPortStatus = FT_ResetDevice(*usbRelayPointer);
// Purge transmit and receive buffers
ftdiPortStatus = FT_Purge(*usbRelayPointer, FT_PURGE_RX | FT_PURGE_TX);
// Set the baud rate
ftdiPortStatus = FT_SetBaudRate(*usbRelayPointer, 9600);
// 1 s timeouts on read / write
ftdiPortStatus = FT_SetTimeouts(*usbRelayPointer, 1000, 1000);
// Set to communicate at 8N1
ftdiPortStatus = FT_SetDataCharacteristics(*usbRelayPointer, FT_BITS_8, FT_STOP_BITS_1, FT_PARITY_NONE); // 8N1
// Disable hardware / software flow control
ftdiPortStatus = FT_SetFlowControl(*usbRelayPointer, FT_FLOW_NONE, 0, 0);
// Set the latency of the receive buffer way down (2 ms) to facilitate speedy transmission
ftdiPortStatus = FT_SetLatencyTimer(*usbRelayPointer,2);
if (ftdiPortStatus != FT_OK)
{
NSLog(@"Electronics error: Can't set latency timer");
return;
}
}
}
Run Code Online (Sandbox Code Playgroud)
断开连接非常简单:
ftdiPortStatus = FT_Close(*electronicsPointer);
*electronicsPointer = 0;
if (ftdiPortStatus != FT_OK)
{
return;
}
Run Code Online (Sandbox Code Playgroud)
然后写入串行设备非常简单:
__block DWORD bytesWrittenOrRead;
unsigned char * dataBuffer = (unsigned char *)[command bytes];
//[command getBytes:dataBuffer];
runOnMainQueueWithoutDeadlocking(^{
ftdiPortStatus = FT_Write(electronicsCommPort, dataBuffer, (DWORD)[command length], &bytesWrittenOrRead);
});
if((bytesWrittenOrRead < [command length]) || (ftdiPortStatus != FT_OK))
{
NSLog(@"Bytes written: %d, should be:%d, error: %d", bytesWrittenOrRead, (unsigned int)[command length], ftdiPortStatus);
return NO;
}
Run Code Online (Sandbox Code Playgroud)
(command是一个NSData实例,runOnMainQueueWithoutDeadlocking()它只是我用来保证在主队列上执行块的一个便利函数).
您可以使用以下内容从串行接口读取原始字节:
NSData *response = nil;
DWORD numberOfCharactersToRead = size;
__block DWORD bytesWrittenOrRead;
__block unsigned char *serialCommunicationBuffer = malloc(numberOfCharactersToRead);
runOnMainQueueWithoutDeadlocking(^{
ftdiPortStatus = FT_Read(electronicsCommPort, serialCommunicationBuffer, (DWORD)numberOfCharactersToRead, &bytesWrittenOrRead);
});
if ((bytesWrittenOrRead < numberOfCharactersToRead) || (ftdiPortStatus != FT_OK))
{
free(serialCommunicationBuffer);
return nil;
}
response = [[NSData alloc] initWithBytes:serialCommunicationBuffer length:numberOfCharactersToRead];
free(serialCommunicationBuffer);
Run Code Online (Sandbox Code Playgroud)
在上面的末尾,response将是一个NSData实例,包含您从端口读取的字节.
另外,我建议你应该总是从主线程访问FTDI设备.即使他们说他们支持多线程访问,我发现任何类型的非主线程访问(甚至保证来自单个线程的独占访问)都会导致Mac上的间歇性崩溃.
除了上面描述的情况之外,您可以参考D2XX编程指南,了解FTDI在其C库中提供的其他功能.同样,您只需要移动设备制造商提供给您的样本中的相应代码.
| 归档时间: |
|
| 查看次数: |
10832 次 |
| 最近记录: |