Lighting USB OpenDMX FTD2XX DMXking

后端 未结 5 504
一向
一向 2021-01-21 00:44

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

相关标签:
5条回答
  • 2021-01-21 01:02

    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);
    
    
        }
    
    0 讨论(0)
  • 2021-01-21 01:06

    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);
            }
    
        }
    
    }
    

    }

    0 讨论(0)
  • 2021-01-21 01:07

    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);
    
    0 讨论(0)
  • 2021-01-21 01:22

    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.

    0 讨论(0)
  • 2021-01-21 01:23

    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

    0 讨论(0)
提交回复
热议问题