灯光 USB OpenDMX FTD2XX DMXking

发布于 2024-11-05 12:33:28 字数 1965 浏览 1 评论 0原文

几个简单的问题。我有一个 DMX king USB 照明控制器,我正在尝试控制它。

它基于 Open DMX 协议(来自 Entec),提供了 ac# 类。 我已将设备插入 RGB 罐,如果我使用其驱动程序测试 USB 设备,它会连接到 COM4,当我将其软件切换到传输模式时,我可以设置单独的 DMX 通道。

使用他们的 OpenDMX 类,进行一些修改(核心是相同的,我只是添加了一些额外的错误检查,我可以找到设备,查询它的信息等。 当我打开设备时,我会得到一个手柄。 我可以使用 FT_Write 写入该设备,但无论我做什么,实际上都没有灯亮起。

以下是一些相关的代码片段:

public static byte[] buffer;

[DllImport("FTD2XX.dll")]
public static extern FT_STATUS FT_Open(UInt32 uiPort, ref uint ftHandle);
[DllImport("FTD2XX.dll")]
public static extern FT_STATUS FT_Write(uint ftHandle, IntPtr lpBuffer, UInt32 dwBytesToRead, ref UInt32 lpdwBytesWritten);

public static void writeData()
{
    while (!done)
    {
        try
        {
            initOpenDMX();
            status = FT_SetBreakOn(handle);
            status = FT_SetBreakOff(handle);
            bytesWritten = write(handle, buffer, buffer.Length);
            if (bytesWritten == 0)
            {
                break;
            }

            System.Threading.Thread.Sleep(25);
        }
        catch (Exception)
        {
            break;
        }
    }
    Connected = false;
    done = false;
}

所有状态均返回为 FT_Ok,bytesWritten 返回为 512(此 USB 控制器上的通道数)

我一直认为我错过了诸如将设备设置为传输模式或类似模式的操作(它只有一个 DMX 插座)

public static void initOpenDMX()
{
    status = FT_ResetDevice(handle);
    status = FT_SetDivisor(handle, (char)12); // set baud rate
    status = FT_SetDataCharacteristics(handle, BITS_8, STOP_BITS_2, PARITY_NONE);
    status = FT_SetFlowControl(handle, (char)FLOW_NONE, 0, 0);
    status = FT_ClrRts(handle);
    status = FT_SetLatencyTimer(handle, (byte)40);
    status = FT_Purge(handle, PURGE_TX);
    status = FT_Purge(handle, PURGE_RX);
}

我也尝试了 Entec OpenDMX 类,没有经过我的任何修改,它似乎也没有做任何事情。

只是想强调他们的控制软件运行良好,因此灯和控制器兼容。我认为我使用 FTD2xx 的方式缺少一些东西。 没有出现任何错误(一切都是 FT_OK),因此这表明 DLL 正在工作 - 特别是因为我可以使用 FT_ListDevices 和 FT_GetDeviceInfo 方法查询设备。

有什么想法吗?

加雷思

Couple of quick questions. I have a DMX king USB lighting controller that I'm trying to control.

It's based on the Open DMX protocol (from Entec) who make available a c# class.
I've got the device plugged into an RGB can, and if I test the USB device with their driver, it connects to COM4 and when I switch their software into transmit mode, I can then set individual DMX channels.

Using their OpenDMX class, with a few modifications (the core is the same, i've just added some extra error checking, I can locate the device, query it's information etc.
When I open the device I get a handle.
I can write to that device with FT_Write but no matter what I do, no lights actually come on.

Here's a few relevant code snippets:

public static byte[] buffer;

[DllImport("FTD2XX.dll")]
public static extern FT_STATUS FT_Open(UInt32 uiPort, ref uint ftHandle);
[DllImport("FTD2XX.dll")]
public static extern FT_STATUS FT_Write(uint ftHandle, IntPtr lpBuffer, UInt32 dwBytesToRead, ref UInt32 lpdwBytesWritten);

public static void writeData()
{
    while (!done)
    {
        try
        {
            initOpenDMX();
            status = FT_SetBreakOn(handle);
            status = FT_SetBreakOff(handle);
            bytesWritten = write(handle, buffer, buffer.Length);
            if (bytesWritten == 0)
            {
                break;
            }

            System.Threading.Thread.Sleep(25);
        }
        catch (Exception)
        {
            break;
        }
    }
    Connected = false;
    done = false;
}

All the status come back as FT_Ok, and bytesWritten comes back as 512 (the number of channels on this USB controller)

I keep thinking I've missed something like setting the device into a transmit mode or similar (it only has one DMX socket)

public static void initOpenDMX()
{
    status = FT_ResetDevice(handle);
    status = FT_SetDivisor(handle, (char)12); // set baud rate
    status = FT_SetDataCharacteristics(handle, BITS_8, STOP_BITS_2, PARITY_NONE);
    status = FT_SetFlowControl(handle, (char)FLOW_NONE, 0, 0);
    status = FT_ClrRts(handle);
    status = FT_SetLatencyTimer(handle, (byte)40);
    status = FT_Purge(handle, PURGE_TX);
    status = FT_Purge(handle, PURGE_RX);
}

I've also tried the Entec OpenDMX class without any modifications from me and it doesn't seem to do anything either.

Just want to stress that their control software is working fine, so the light and controller are compatible. I think something is missing in the way I'm using FTD2xx.
There's no errors coming through (everything is FT_OK) so this suggests the DLL is working - especially since I can query the device using the FT_ListDevices and FT_GetDeviceInfo methods.

Any ideas?

Gareth

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

情话难免假 2024-11-12 12:33:28

为了解决这个问题,我给制造商发了电子邮件。
原来该设备不是 OpenDMX,实际上它是 DMXProUSB
该协议非常相似,并且基于 FTDI 芯片,这就是代码部分工作的原因,但其中有一个微控制器。
我将 C++ 示例控制器文件转换为 C# 并使其全部正常工作。
如果这种情况再次出现,我很乐意分享 DMXProUSB 的 C# 代码,但没有支持。
我已将代码通过电子邮件发送给制造商(dmxking),并在 github 上放置了一份副本: https:// github.com/agrath/Sniper.Lighting.Dmx

感谢您的帮助

To resolve this, I emailed the manufacturer.
It turned out that the device wasn't OpenDMX, in fact it was a DMXProUSB
The protocol was pretty similar, and it was based on the FTDI chip which is why the code partly worked, but it has a microcontroller in it.
I converted the C++ example controller file to C# and got it all working.
If this ever comes up again, I am happy to share the resulting c# code for the DMXProUSB however with no support.
I have emailed the code to the manfacturer (dmxking) and have placed a copy on github: https://github.com/agrath/Sniper.Lighting.Dmx

Thanks for your help

水中月 2024-11-12 12:33:28

我通过机械 VB 到 C# 转换器运行 Hippy 的 VB 版本,找到了一把钥匙
不同之处。 FT_WRITE 使用字符串将数据传递给非托管代码。 C# 类使用
指向字节数组的 IPtr。

这个版本适合我:

using System;
using System.Runtime.InteropServices;
using System.Threading;

// based on Hippy's VB Example
// http://members.westnet.com.au/rowanmac/opendmx.html#tx
// Working link: https://web.archive.org/web/20150217155014/http://members.westnet.com.au:80/rowanmac/opendmx.html

namespace Test
{
class Program
{


    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_Open(short intDeviceNumber, ref int lngHandle);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_Close(int lngHandle);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_SetDivisor(int lngHandle, int div);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_Read(int lngHandle, string lpszBuffer, int lngBufferSize, ref int lngBytesReturned);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_Write(int lngHandle, string lpszBuffer, int lngBufferSize, ref int lngBytesWritten);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_Write(int lngHandle, IntPtr lpBuffer, int lngBufferSize, ref int lngBytesWritten);

    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_SetBaudRate(int lngHandle, int lngBaudRate);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_SetDataCharacteristics(int lngHandle, byte byWordLength, byte byStopBits, byte byParity);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_SetFlowControl(int lngHandle, short intFlowControl, byte byXonChar, byte byXoffChar);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_ResetDevice(int lngHandle);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_SetDtr(int lngHandle);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_ClrDtr(int lngHandle);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_SetRts(int lngHandle);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_ClrRts(int lngHandle);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_GetModemStatus(int lngHandle, ref int lngModemStatus);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_Purge(int lngHandle, int lngMask);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_GetStatus(int lngHandle, ref int lngRxBytes, ref int lngTxBytes, ref int lngEventsDWord);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_GetQueueStatus(int lngHandle, ref int lngRxBytes);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_GetEventStatus(int lngHandle, ref int lngEventsDWord);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_SetChars(int lngHandle, byte byEventChar, byte byEventCharEnabled, byte byErrorChar, byte byErrorCharEnabled);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_SetTimeouts(int lngHandle, int lngReadTimeout, int lngWriteTimeout);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_SetBreakOn(int lngHandle);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_SetBreakOff(int lngHandle);

    // FTDI Constants
    const short FT_OK = 0;
    const short FT_INVALID_HANDLE = 1;
    const short FT_DEVICE_NOT_FOUND = 2;
    const short FT_DEVICE_NOT_OPENED = 3;
    const short FT_IO_ERROR = 4;

    const short FT_INSUFFICIENT_RESOURCES = 5;
    // Word Lengths
    const byte FT_BITS_8 = 8;
    // Stop Bits
    const byte FT_STOP_BITS_2 = 2;
    // Parity
    const byte FT_PARITY_NONE = 0;
    // Flow Control
    const byte FT_FLOW_NONE = 0x0;
    // Purge rx and tx buffers
    const byte FT_PURGE_RX = 1;

    const byte FT_PURGE_TX = 2;

    public static int handle=0;



    public static byte[] buffer = new byte[4];  // can be up to 512, shorter is faster

    private static string lpszBuffer=""+ (char) 0 + (char) 64 + (char) 64+ (char) 0;


    static void Main(string[] args)
    {
        init();
    }

    public static string init()
    {
        short n = 0;
        // ==== ATTEMPT TO OPEN DEVICE ====
        if (FT_Open(n, ref handle) != FT_OK)
        {
            return "FTTD Not Found";
        }
        // ==== PREPARE DEVICE FOR DMX TRANSMISSION ====
        // reset the device
        if (FT_ResetDevice(handle) != FT_OK)
        {
            return "Failed To Reset Device!";

        }
        // get an ID from the widget from jumpers
     //   GetID(ref n);
        // set the baud rate
        if (FT_SetDivisor(handle, 12) != FT_OK)
        {
            return "Failed To Set Baud Rate!";
        }
        // shape the line
        if (FT_SetDataCharacteristics(handle, FT_BITS_8, FT_STOP_BITS_2, FT_PARITY_NONE) != FT_OK)
        {
            return "Failed To Set Data Characteristics!";
        }
        // no flow control
        if (FT_SetFlowControl(handle, FT_FLOW_NONE, 0, 0) != FT_OK)
        {
            return "Failed to set flow control!";
        }
        // set bus transiever to transmit enable
        if (FT_ClrRts(handle) != FT_OK)
        {
            return "Failed to set RS485 to send!";
        }
        // Clear TX & RX buffers
        if (FT_Purge(handle, FT_PURGE_TX) != FT_OK)
        {
            return "Failed to purge TX buffer!";
        }
        // empty buffers
        if (FT_Purge(handle, FT_PURGE_RX) != FT_OK)
        {
            return "Failed to purge RX buffer!";
        }

        setDmxValue(0, 0);   // should always be zero
        setDmxValue(1, 64);
        setDmxValue(2, 64);
        setDmxValue(3, 0);

        Thread thread = new Thread(new ThreadStart(writeDataThread));
        thread.Start();


        return "Ok";

    }
    // init


    public static void setDmxValue(int channel, byte value)
    {
        buffer[channel] = value;
        lpszBuffer="";
        for (int i = 0; i < buffer.Length; ++i)
        {
            lpszBuffer += (char)buffer[i];
        }
    }

    public static void writeDataThread()
    {
        bool done = false;

        int lngBytesWritten=0;

        while (!done)
        {
            FT_SetBreakOn(handle);
            FT_SetBreakOff(handle);
            FT_Write(handle, lpszBuffer, buffer.Length, ref lngBytesWritten);
            System.Threading.Thread.Sleep(50);
        }

    }

}

}

I ran Hippy's VB version through a mechanical VB to C# translator and found one key
difference. FT_WRITE uses a string to pass data to the unmanaged code. The C# class uses
an IPtr pointing to a byte array.

This version works for me:

using System;
using System.Runtime.InteropServices;
using System.Threading;

// based on Hippy's VB Example
// http://members.westnet.com.au/rowanmac/opendmx.html#tx
// Working link: https://web.archive.org/web/20150217155014/http://members.westnet.com.au:80/rowanmac/opendmx.html

namespace Test
{
class Program
{


    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_Open(short intDeviceNumber, ref int lngHandle);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_Close(int lngHandle);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_SetDivisor(int lngHandle, int div);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_Read(int lngHandle, string lpszBuffer, int lngBufferSize, ref int lngBytesReturned);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_Write(int lngHandle, string lpszBuffer, int lngBufferSize, ref int lngBytesWritten);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_Write(int lngHandle, IntPtr lpBuffer, int lngBufferSize, ref int lngBytesWritten);

    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_SetBaudRate(int lngHandle, int lngBaudRate);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_SetDataCharacteristics(int lngHandle, byte byWordLength, byte byStopBits, byte byParity);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_SetFlowControl(int lngHandle, short intFlowControl, byte byXonChar, byte byXoffChar);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_ResetDevice(int lngHandle);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_SetDtr(int lngHandle);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_ClrDtr(int lngHandle);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_SetRts(int lngHandle);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_ClrRts(int lngHandle);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_GetModemStatus(int lngHandle, ref int lngModemStatus);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_Purge(int lngHandle, int lngMask);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_GetStatus(int lngHandle, ref int lngRxBytes, ref int lngTxBytes, ref int lngEventsDWord);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_GetQueueStatus(int lngHandle, ref int lngRxBytes);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_GetEventStatus(int lngHandle, ref int lngEventsDWord);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_SetChars(int lngHandle, byte byEventChar, byte byEventCharEnabled, byte byErrorChar, byte byErrorCharEnabled);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_SetTimeouts(int lngHandle, int lngReadTimeout, int lngWriteTimeout);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_SetBreakOn(int lngHandle);
    [DllImport("FTD2XX.DLL", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    private static extern int FT_SetBreakOff(int lngHandle);

    // FTDI Constants
    const short FT_OK = 0;
    const short FT_INVALID_HANDLE = 1;
    const short FT_DEVICE_NOT_FOUND = 2;
    const short FT_DEVICE_NOT_OPENED = 3;
    const short FT_IO_ERROR = 4;

    const short FT_INSUFFICIENT_RESOURCES = 5;
    // Word Lengths
    const byte FT_BITS_8 = 8;
    // Stop Bits
    const byte FT_STOP_BITS_2 = 2;
    // Parity
    const byte FT_PARITY_NONE = 0;
    // Flow Control
    const byte FT_FLOW_NONE = 0x0;
    // Purge rx and tx buffers
    const byte FT_PURGE_RX = 1;

    const byte FT_PURGE_TX = 2;

    public static int handle=0;



    public static byte[] buffer = new byte[4];  // can be up to 512, shorter is faster

    private static string lpszBuffer=""+ (char) 0 + (char) 64 + (char) 64+ (char) 0;


    static void Main(string[] args)
    {
        init();
    }

    public static string init()
    {
        short n = 0;
        // ==== ATTEMPT TO OPEN DEVICE ====
        if (FT_Open(n, ref handle) != FT_OK)
        {
            return "FTTD Not Found";
        }
        // ==== PREPARE DEVICE FOR DMX TRANSMISSION ====
        // reset the device
        if (FT_ResetDevice(handle) != FT_OK)
        {
            return "Failed To Reset Device!";

        }
        // get an ID from the widget from jumpers
     //   GetID(ref n);
        // set the baud rate
        if (FT_SetDivisor(handle, 12) != FT_OK)
        {
            return "Failed To Set Baud Rate!";
        }
        // shape the line
        if (FT_SetDataCharacteristics(handle, FT_BITS_8, FT_STOP_BITS_2, FT_PARITY_NONE) != FT_OK)
        {
            return "Failed To Set Data Characteristics!";
        }
        // no flow control
        if (FT_SetFlowControl(handle, FT_FLOW_NONE, 0, 0) != FT_OK)
        {
            return "Failed to set flow control!";
        }
        // set bus transiever to transmit enable
        if (FT_ClrRts(handle) != FT_OK)
        {
            return "Failed to set RS485 to send!";
        }
        // Clear TX & RX buffers
        if (FT_Purge(handle, FT_PURGE_TX) != FT_OK)
        {
            return "Failed to purge TX buffer!";
        }
        // empty buffers
        if (FT_Purge(handle, FT_PURGE_RX) != FT_OK)
        {
            return "Failed to purge RX buffer!";
        }

        setDmxValue(0, 0);   // should always be zero
        setDmxValue(1, 64);
        setDmxValue(2, 64);
        setDmxValue(3, 0);

        Thread thread = new Thread(new ThreadStart(writeDataThread));
        thread.Start();


        return "Ok";

    }
    // init


    public static void setDmxValue(int channel, byte value)
    {
        buffer[channel] = value;
        lpszBuffer="";
        for (int i = 0; i < buffer.Length; ++i)
        {
            lpszBuffer += (char)buffer[i];
        }
    }

    public static void writeDataThread()
    {
        bool done = false;

        int lngBytesWritten=0;

        while (!done)
        {
            FT_SetBreakOn(handle);
            FT_SetBreakOff(handle);
            FT_Write(handle, lpszBuffer, buffer.Length, ref lngBytesWritten);
            System.Threading.Thread.Sleep(50);
        }

    }

}

}

蓝眼睛不忧郁 2024-11-12 12:33:28

我在开放的 dmx 站点上编写了 C# 类。
它基于用 VB 编写的 Hippy's Open DMX 驱动程序。

// 旧的损坏链接:
http://members.westnet.com.au/rowanmac/opendmx.html#发送
// 工作链接: https://web.archive.org/web/20150217155014/http://members.westnet.com.au:80/rowanmac/opendmx.html

C# 类未初始化 FDDI 芯片上的某些内容。

这多年来一直折磨着我。

我对 FT_SetFlowControl 有怀疑。在VB应用程序中,第二个参数是一个短整型。但在 C# 类中对它的任何等效调用只有在第二个参数强制转换为 char 时才有效。

    [DllImport("FTD2XX.dll")]
    public static extern FT_STATUS FT_SetFlowControl(uint ftHandle, UInt16 usFlowControl, byte uXon, byte uXoff);

I wrote the C# class on the open dmx site.
It was based on Hippy's Open DMX driver written in VB.

// Old broken link:
http://members.westnet.com.au/rowanmac/opendmx.html#tx
// Working link: https://web.archive.org/web/20150217155014/http://members.westnet.com.au:80/rowanmac/opendmx.html

The C# Class in not initializing something on the FDDI chip.

This has been tormenting me for years.

I have my suspicions about FT_SetFlowControl. In the VB app, the second parameter is a short int. But any call to it's equivalent in the C# class will only work if the second parameter is cast to a char.

    [DllImport("FTD2XX.dll")]
    public static extern FT_STATUS FT_SetFlowControl(uint ftHandle, UInt16 usFlowControl, byte uXon, byte uXoff);
陈独秀 2024-11-12 12:33:28

我用 Marshal.Copy 解决了这个问题

    public static void writeDataThread(int Length)
    {

        int lngBytesWritten = 0;
        IntPtr pnt = Marshal.AllocHGlobal(Length);

        Marshal.Copy(buffer, 0, pnt, Length);
        FT_SetBreakOn(handle);
        FT_SetBreakOff(handle);
        string  StartCode =  null;
        FT_Write(handle, StartCode, 1, ref lngBytesWritten);
        FT_Write(handle, pnt, Length, ref lngBytesWritten);


    }

I fix the problem with Marshal.Copy

    public static void writeDataThread(int Length)
    {

        int lngBytesWritten = 0;
        IntPtr pnt = Marshal.AllocHGlobal(Length);

        Marshal.Copy(buffer, 0, pnt, Length);
        FT_SetBreakOn(handle);
        FT_SetBreakOff(handle);
        string  StartCode =  null;
        FT_Write(handle, StartCode, 1, ref lngBytesWritten);
        FT_Write(handle, pnt, Length, ref lngBytesWritten);


    }
呆橘 2024-11-12 12:33:28

FTDI 芯片除了串行端口之外还有 GPIO 引脚。希望文档告诉您是否需要设置这些。该函数是FT_SetBitMode。文档此处

FTDI chips have GPIO pins in addition to the serial ports. Hopefully the documentation tells you whether these need to be set. The function is FT_SetBitMode. Documentation here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文