티스토리 뷰

목차

    반응형

    컴파일테크놀로지 디지털 IO 보드 프로그램 (C#프로그래밍)


    DIO CWDIO32 컴파일테크놀로지[컴파일테크놀로지 디지털 IO 보드] CWDIO 32


    프로그램 다운로드 - CWDIO32.zip [링크]

    제품 소개 페이지 - CW-DIO32 (필드 I/O, 리모트 I/O, DAQ, MODBUS) [링크]


    제가 직접 컴파일테크놀로지에서 판매하는 디지털 IO 보드(CWDIO32) 프로그램을 만들었습니다. 아쉽게도 디지털 IO 보드는 판매하면서 디지털 IO 보드 프로그램은 제공하질 않네요.


    이런 건 원래 컴파일테크놀로지에서 제공해야 하지 않나요? 아무튼,


    이하 주요 소스입니다.

    Program.cs 파일을 보시면 아래처럼 중복 실행 방지 코드가 삽입되어 있습니다. 이 프로그램은 백그라운드에서 구동되기에 중복으로 실행되면 안됩니다.


    DIO는 하나인데 두 곳에서 접근하면 예상치 못한 상황은 당연히 발생하겠죠.

    그래서 아래처럼 Main() 함수에 중복 실행 방지 코드가 들어가 있습니다.


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    [MTAThread]
    static void Main()
    {
        #region 중복 실행 방지
        // 현재 프로그램과 같은 프로세스가 구동 중이면 종료
        bool bCreated = false;
        string applicationName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
     
        if (CreateMutex(IntPtr.Zero, true, applicationName) != 0)
        {
            if (GetLastError() == ERROR_ALREADY_EXISTS)
            {
                bCreated = true;
            }
        }
     
        if (bCreated)
        {
            //MessageBox.Show("프로그램이 이미 실행 중입니다.", "확인");
            Application.Exit();
        }
        else
        {
            Application.Run(new FrmMain());
        }
        #endregion
    }
    cs


    컴파일테크놀로지 DIO 보드 CWDIO32[컴파일테크놀로지 디지털 IO 보드] CWDIO 32


    이어서, 메인에 보시면 refreshPort() 함수가 존재합니다.


    컴파일테크놀로지 CWDIO(io 보드) 각 포트의 상태(in, out)를 읽어오는 부분입니다.

    IsInput이란 배열에 값을 비교해서 상하위 비트에 1 또는 0을 씁니다. (1 또는 0, True 또는 False)

    근데, 여기서 그치면 안 되고, 해당 값에 맞게 실제 DIO를 제어해야 합니다.


    또 하나의 문제는 조금의 딜레이도 없이 무작정 제어를 하려다 보면 잘 안 됩니다. 그래서 Sleep() 함수에 10이란 인자를 넣습니다.


    이 IO 보드는 10ms 정도의 딜레이는 줘야 연속 제어가 가능합니다.


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    private void refreshPort()
    {
         #region 레지스트 갱신
       
        for (int i = 0; i < 8; i++)
        {
            sbHigh.Append(IsInput[i] == true ? "1" : "0");
            sbLow.Append(IsInput[i + 8== true ? "1" : "0");
        }
     
        // 서브키 아래 값 쓰기
        rgKey.SetValue("InputHigh", sbHigh);
        rgKey.SetValue("InputLow", sbLow);
     
        sbHigh.Remove(0, sbHigh.Length);
        sbLow.Remove(0, sbLow.Length);
     
        #endregion
     
        #region Output 확인 후 제어
        for (int i = 0; i < 16; i++)
        {
            try
            {
                strOutput = rgKey.GetValue(i.ToString()) as string;
                com.SendOutPort(i, strOutput.CompareTo("1"== 0 ? true : false);
                rgKey.DeleteValue(i.ToString(), false);
     
                Thread.Sleep(10);
            }
            catch (System.Exception ex) { }
        }
        #endregion
    }
    cs


    제 경우엔 MODBUS를 연동해 사용할 일이 있었습니다.


    컴파일테크놀로지 CWDIO32[컴파일테크놀로지 디지털 IO 보드] CWDIO 32


    그래서 아래처럼 Comport.cs 파일에 MODBUS 코드를 삽입해 두었는데 필요 없는 분들은 삭제하셔도 무방합니다. (아무튼, 저는 컴파일테크놀로지 직원이 아니라 사용자인데 제어 프로그램을 만들어 배포하고 있는 겁니다?!)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    #region MODBUS - 포트 On, Off 명령어 초기화
    byte[][] outPortArrOn = new byte[][]
    {
        new byte[8] { 0x010x050x170x5C0xFF0x000x490x9C },
        new byte[8] { 0x010x050x170x5D0xFF0x000x180x5C },
        new byte[8] { 0x010x050x170x5E0xFF0x000xE80x5C },
        new byte[8] { 0x010x050x170x5F0xFF0x000xB90x9C },
        new byte[8] { 0x010x050x170x600xFF0x000x890x90 },
        new byte[8] { 0x010x050x170x610xFF0x000xD80x50 },
        new byte[8] { 0x010x050x170x620xFF0x000x280x50 },
        new byte[8] { 0x010x050x170x630xFF0x000x790x90 }, // 7
        new byte[8] { 0x010x050x170x640xFF0x000xC80x51 },
        new byte[8] { 0x010x050x170x650xFF0x000x990x91 },
        new byte[8] { 0x010x050x170x660xFF0x000x690x91 },
        new byte[8] { 0x010x050x170x670xFF0x000x380x51 },
        new byte[8] { 0x010x050x170x680xFF0x000x080x52 },
        new byte[8] { 0x010x050x170x690xFF0x000x590x92 },
        new byte[8] { 0x010x050x170x6A0xFF0x000xA90x92 },
        new byte[8] { 0x010x050x170x6B0xFF0x000xF80x52 }, // 15
    };
     
    byte[][] outPortArrOff = new byte[][]
    {
        new byte[8] { 0x010x050x170x5C0x000x000x080x6C },
        new byte[8] { 0x010x050x170x5D0x000x000x590xAC },
        new byte[8] { 0x010x050x170x5E0x000x000xA90xAC },
        new byte[8] { 0x010x050x170x5F0x000x000xF80x6C },
        new byte[8] { 0x010x050x170x600x000x000xC80x60 },
        new byte[8] { 0x010x050x170x610x000x000x990xA0 },
        new byte[8] { 0x010x050x170x620x000x000x690xA0 },
        new byte[8] { 0x010x050x170x630x000x000x380x60 }, // 7
        new byte[8] { 0x010x050x170x640x000x000x890xA1 },
        new byte[8] { 0x010x050x170x650x000x000xD80x61 },
        new byte[8] { 0x010x050x170x660x000x000x280x61 },
        new byte[8] { 0x010x050x170x670x000x000x790xA1 },
        new byte[8] { 0x010x050x170x680x000x000x490xA2 },
        new byte[8] { 0x010x050x170x690x000x000x180x62 },
        new byte[8] { 0x010x050x170x6A0x000x000xE80x62 },
        new byte[8] { 0x010x050x170x6B0x000x000xB90xA2 }, // 15
    };
     
    byte[] inPortArrCheck = new byte[8] { 0x010x010x0B0xA40x000x100x7E0x01 };
     
    #endregion
    cs


    마지막으로 IO 보드의 데이터를 수신받는 부분입니다.


    역시, 제 상황에 맞게 수정해 놨으니 다른 분들은 필히 수정하셔야 합니다. 그대로 사용할 순 없으실 테니 수정하세요. 꼭.


    ps. IO 보드를 돈 주고 산 사람이 보드 제어 프로그램도 직접 만들어 사용하라니 ...


    컴파일테크놀로지 디지털 IO 보드[컴파일테크놀로지 디지털 IO 보드] CWDIO 32


    컴파일테크놀로지 디지털 IO 보드 프로그램 (C#프로그래밍)

    반응형