using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;   
using System.Threading;

// @Name: do_immediately.cs
// @Author: Smacq
// @Copyright: Smacq
// @Date: 2024/12/25
// @Brief:
// This code focuses on the Do functions of the USB - 3000 device, performing digital output operations.
// It sets the Do output to HIGH/LOW, where 0V is LOW (default) and 3.3V is HIGH.
// The DO channels vary depending on the module, either Do_4 or Do_8.
// You can refer to the user manual for more information about functions or device details.
//
// Execution result when only connecting USB for USB - 3000(DO_4):
// 0
// 0
// Now Do3 - 0 is all HIGH
//...
// 0
// Now Do3 - 0 is all LOW
// 0
// Now DO 0 is 1
//...
// 0
// Now DO 0 is 0
// 0

class Program
{
    static void Main(string[] args)
    {
        // Device index starts from zero
        int DevIndex = 0;

        // For all select digital output channel:
        // 0xFF is select all digital output channel.
        uint All_Do_Channel = 0xFF;

        // For all Do output Do_Value HIGH is 1 or LOW is 0:
        // Do_channel_4: 0~0xF(1111) Do3~Do0, Do_channel_8: 0~0xFF(1111 1111) Do7~Do0.
        uint All_Do_Value = 0xF;

        // For select single digital output channel:
        // Do_channel_4: 0~3 -> Do3~Do0, Do_channel_8: 0~7 -> Do7~Do0.
        uint single_Do_Channel = 0;

        // single Do output Do_Value HIGH is 1:
        uint single_Do_Value_HIGH = 1;

        // single Do output Do_Value LOW is 0:
        uint single_Do_Value_LOW = 0;

        int error_code;

        // Open specific device and print return Do_Value.
        error_code = USB3000DLL.USB3OpenDevice(DevIndex);
        Console.WriteLine(error_code);

        // Set All Do Pin output HIGH and then LOW, interval of 1 second.
        for (int i = 0; i < 3; ++i)
        {
            // Set Do Pin output, 15 = 0xF = 4-bit(1111) Do3 - 0 all HIGH.
            error_code = USB3000DLL.SetUSB3DoImmediately(DevIndex, All_Do_Channel, All_Do_Value);
            Console.WriteLine(error_code);
            if (error_code == 0)
            {
                Console.WriteLine("Now Do3 - 0 is all HIGH");
            }
            // Necessary delay for easy observation
            Thread.Sleep(1000);
            // Set Do Pin output, 0 = 0x0 = 4-bit(0000) Do3 - 0 all LOW.
            error_code = USB3000DLL.SetUSB3DoImmediately(DevIndex, All_Do_Channel, 0);
            Console.WriteLine(error_code);
            if (error_code == 0)
            {
                Console.WriteLine("Now Do3 - 0 is all LOW");
            }
            // Necessary delay for easy observation
            Thread.Sleep(1000);
        }

        // Set single DO_0 output HIGH/LOW, interval of 1 second.
        for (int i = 0; i < 3; ++i)
        {
            error_code = USB3000DLL.SetUSB3DoImmediately(DevIndex, single_Do_Channel, single_Do_Value_HIGH);
            Console.WriteLine(error_code);
            if (error_code == 0)
            {
                Console.WriteLine("Now DO {0} is {1}", single_Do_Channel, single_Do_Value_HIGH);
            }
            Thread.Sleep(1000);
            error_code = USB3000DLL.SetUSB3DoImmediately(DevIndex, single_Do_Channel, single_Do_Value_LOW);
            Console.WriteLine(error_code);
            if (error_code == 0)
            {
                Console.WriteLine("Now DO {0} is {1}", single_Do_Channel, single_Do_Value_LOW);
            }
            Thread.Sleep(1000);
        }

        // Close Device
        error_code = USB3000DLL.USB3CloseDevice(DevIndex);
        Console.WriteLine(error_code);
    }

    class USB3000DLL
    {
        [DllImport("USB3000.dll")]
        public static extern int FindUSB3DAQ();
        [DllImport("USB3000.dll")]
        public static extern int USB3OpenDevice(int DevIndex);
        [DllImport("USB3000.dll")]
        public static extern int USB3CloseDevice(int DevIndex);
        [DllImport("USB3000.dll")]
        public static extern int USB3ReadDevcieSN(int DevIndex);
        [DllImport("USB3000.dll")]
        public static extern int USB3ReadDevcieModel(int DevIndex);

        //--------------------------------------------------------------------------
        // Ananlog Input Configuration

        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AiSampleRate(int DevIndex, uint SamplePeriod);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AiSampleMode(int DevIndex, byte AiSampleMode);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AiConnectType(int DevIndex, byte AiConnectType);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AiRange(int DevIndex, byte Chan, float AiRange);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AiChanSel(int DevIndex, byte Chan, byte Sel);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AiTrigSource(int DevIndex, byte AiTrigSource);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AiConvSource(int DevIndex, byte AiConvSource);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AiPreTrigPoints(int DevIndex, uint AiPreTrigPoints);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AiOneShotPoints(int DevIndex, uint AiOneShotPoints);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3ClrAiFifo(int DevIndex);

        //--------------------------------------------------------------------------
        // Digital I/O Configuration

        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DiSampleRate(int DevIndex, uint SamplePeriod);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DiSampleMode(int DevIndex, byte DiSampleMode);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DiTrigSource(int DevIndex, byte DiTrigSource);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DiConvSource(int DevIndex, byte DiConvSource);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DiPreTrigPoints(int DevIndex, uint DiPreTrigPoints);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DiOneShotPoints(int DevIndex, uint DiOneShotPoints);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3ClrDiFifo(int DevIndex);

        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DoSampleRate(int DevIndex, uint SamplePeriod);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DoSampleMode(int DevIndex, byte DoSampleMode);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DoTrigSource(int DevIndex, byte DoTrigSource);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DoConvSource(int DevIndex, byte DoConvSource);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DoCycle(int DevIndex, uint DoCycle);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DoDataFifo(int DevIndex, uint[] Value, uint Len);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3ClrDoFifo(int DevIndex);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DoWaveCtrl(int DevIndex, uint Chan);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DoImmediately(int DevIndex, uint Chan, uint Value);

        //--------------------------------------------------------------------------
        // Ananlog Output Configuration

        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AoSampleRate(int DevIndex, byte Chan, uint SamplePeriod);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AoSampleMode(int DevIndex, byte Chan, byte AoSampleMode);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AoTrigSource(int DevIndex, byte Chan, byte AoTrigSource);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AoConvSource(int DevIndex, byte Chan, byte AoConvSource);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AoCycle(int DevIndex, byte Chan, byte AoCycle);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AoDataFifo(int DevIndex, byte Chan, float[] Voltage, uint Len);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3ClrAoFifo(int DevIndex, byte Chan);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AoSync(int DevIndex, byte Chans);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AoImmediately(int DevIndex, byte Chan, float Voltage);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AoImmediately4Chans(int DevIndex, float Volt0, float Volt1, float Volt2, float Volt3);

        //--------------------------------------------------------------------------
        // Trig Control

        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AiSoftTrig(int DevIndex);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DiSoftTrig(int DevIndex);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3DoSoftTrig(int DevIndex);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3AoSoftTrig(int DevIndex, byte Chan);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3GlobalSoftTrig(int DevIndex);

        [DllImport("USB3000.dll")]
        public static extern int SetUSB3ClrTrigger(int DevIndex);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3ClrAiTrigger(int DevIndex);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3ClrDiTrigger(int DevIndex);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3ClrDoTrigger(int DevIndex);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3ClrAoTrigger(int DevIndex, byte Chan);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3ClrGlobalSoftTrig(int DevIndex);

        //--------------------------------------------------------------------------
        // Sync Configuration

        [DllImport("USB3000.dll")]
        public static extern int SetUSB3ExtTrigOutSource(int DevIndex, byte Source);
        [DllImport("USB3000.dll")]
        public static extern int SetUSB3ExtConvOutSource(int DevIndex, byte Source);

        //--------------------------------------------------------------------------
        // Get Data Acquired

        [DllImport("USB3000.dll")]
        public static extern int USB3GetAi(int DevIndex, uint Points, float[] Ai, int TimeOut);
        [DllImport("USB3000.dll")]
        public static extern int USB3GetDi(int DevIndex, uint Points, byte[] Di, int TimeOut);
    }

}