Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 与USB设备的FTDI通信-目标C_Objective C_Ftdi_Dmx512 - Fatal编程技术网

Objective c 与USB设备的FTDI通信-目标C

Objective c 与USB设备的FTDI通信-目标C,objective-c,ftdi,dmx512,Objective C,Ftdi,Dmx512,我正在尝试与Enttec USB DMX Pro进行通信。主要接收DMX 他们发布了一个Visual C++版本,但是我有点犹豫要怎么做才能转换成Obj-C。Enttec写道,“使用Mac的FTDI库与PRO对话,并参考D2XX编程指南打开并与设备对话。”有Objective-C的示例应用程序吗?有没有一种简单的方法可以与Enttec DMX USB Pro进行通信?我已经在Mac上对FTDI芯片做了大量的工作,因此我可以在这里提供一些见解。我使用了USB串行转换器的单通道和双通道变体,它们的行

我正在尝试与Enttec USB DMX Pro进行通信。主要接收DMX


他们发布了一个Visual C++版本,但是我有点犹豫要怎么做才能转换成Obj-C。Enttec写道,“使用Mac的FTDI库与PRO对话,并参考D2XX编程指南打开并与设备对话。”有Objective-C的示例应用程序吗?有没有一种简单的方法可以与Enttec DMX USB Pro进行通信?

我已经在Mac上对FTDI芯片做了大量的工作,因此我可以在这里提供一些见解。我使用了USB串行转换器的单通道和双通道变体,它们的行为方式都相同

FTDI既有虚拟COM端口驱动程序(用于在系统上创建串行COM端口,表示连接到其芯片的串行连接),也有D2XX直接通信库。你会想和后者合作,后者

Mac的D2XX库有一个独立的.dylib(最新的是libftd2x.1.2.2.dylib)或一个最近开始发布的新静态库。该包中还包括您需要的相应头文件(ftd2x.h和WinTypes.h)

在Xcode项目中,添加.dylib作为要链接的框架,并将ftd2x.h、WinTypes.h和ftd2x.cfg文件添加到项目中。在复制绑定框架构建阶段,确保libftd2x.1.2.2.dylib和ftd2x.cfg存在于该阶段。您可能还需要调整此库所需的相对路径,以便它在您的应用程序包中运行,因此您可能需要在命令行对其运行以下命令:

install_name_tool -id @executable_path/../Frameworks/libftd2xx.1.2.2.dylib libftd2xx.1.2.2.dylib
正确配置项目后,您将需要导入FTDI标题:

#import "ftd2xx.h"
并开始连接到串行设备。在你的问题中链接到的示例有一个可下载的C++示例,展示了它们如何与设备通信。您可以使用那里使用的几乎所有C代码,并将其放在Objective-C应用程序中。它们看起来只是在使用标准的FTDI d2x命令,在可下载的

这是我从一个应用程序中提取的一些代码,用于连接到以下设备之一:

    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;
            }                   
        }
    }
写入串行设备非常简单:

    __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;
    }
在上面的末尾,
response
将是一个NSData实例,其中包含您从端口读取的字节

此外,我建议您应该始终从主线程访问FTDI设备。尽管他们说他们支持多线程访问,但我发现任何类型的非主线程访问(甚至保证来自单个线程的独占访问)都会导致Mac上的间歇性崩溃


除了我上面描述的情况之外,您还可以参考D2XX编程指南,了解FTDI在其C库中提供的其他函数。同样,您只需从设备制造商提供给您的示例中选择适当的代码即可。

我遇到了类似的问题(尝试使用Objective-C写入EntTec Open DMX),但没有成功。在遵循@Brad的精彩回答后,我意识到每次发送DMX数据包时都需要切换中断状态

下面是我在一些测试代码中的循环示例,这些代码在帧之间以20毫秒的延迟发送数据包

while (1) {

    FT_SetBreakOn(usbRelayPointer);
    FT_SetBreakOff(usbRelayPointer);

    ftdiPortStatus = FT_Write(usbRelayPointer, startCode, 1, &bytesWrittenOrRead);
    ftdiPortStatus = FT_Write(usbRelayPointer, dataBuffer, (DWORD)[command length], &bytesWrittenOrRead);
    usleep(20000);
}

希望这对其他人有帮助

你所说的“驱动”,我不知道任何“目标C”特定的示例应用程序,但是如果你可以使用任何C或C++的Mac OS示例代码,那么它也应该在一个目标C应用程序中工作。是的,我试图在C或C++中找到一个MACOS示例代码……不确定它是否有用,但可能值得看看或者是渣块!非常感谢你,布拉德。这是非常有用的+1当然!我真的很感激你的帮助response@Brad:非常好的信息。我正在用J2DXX做同样的尝试,我能够与设备通信并检索设备信息等等。但我只是感到困惑,因为我并没有找到一种方法来说明我应该在mifare卡的哪个块中写入数据等等。。。此api不会读取或写入mifare卡,对吗?只针对读卡器device@inba-我不知道MIFARE是如何工作的,但以上只是通过FTDI USB串行转换器发送和接收数据的方式。您需要自己发送MIFARE需要的任何命令。非常好地解释和记录(+1)。使用C++,但是有了这些信息,我可以很容易地使用FTTD2XX库。谢谢好的,详细的描述!我很好奇这项技术在最新版本的OSX中是否仍然适用。这个问题的答案是:表明苹果可能在10.9中打破了某些东西。上述技术目前不适用于我。。。我还有一个问题要问:
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);
while (1) {

    FT_SetBreakOn(usbRelayPointer);
    FT_SetBreakOff(usbRelayPointer);

    ftdiPortStatus = FT_Write(usbRelayPointer, startCode, 1, &bytesWrittenOrRead);
    ftdiPortStatus = FT_Write(usbRelayPointer, dataBuffer, (DWORD)[command length], &bytesWrittenOrRead);
    usleep(20000);
}