C#

C# TwinCAT 설정 접근 방법 (ITcSysManager)

겨울꿈개발자 2020. 6. 28. 14:21

산업용 통신으로 많이 사용되는 EtherCAT은 Beckhoff사에서 만든 프로토콜입니다.

(출처: https://ko.wikipedia.org/wiki/EtherCAT)

 

Beckhoff 사는 EtherCAT UI인 TwinCAT을 제공하고 있으며,

EtherCAT 통신을 사용하는 거의 모든 제품들은 해당 UI를 통해서 제어할 수 있습니다.

 

또한 C, C++, C# 등의 프로그래밍 언어로 EtherCAT 통신을 수행할 수 있는 프로그램을 작성할 수 있습니다.

바로 Beckhoff 사에서 관련 API들을 제공하고 있기 때문입니다.

 

기본적으로 TwinCAT을 설치하면 관련 API들이 포함되어 있는 라이브러리가 TwinCAT 프로그램 내에 있습니다.

해당 라이브러리를 통해 EtherCAT 통신이 가능한 셈이죠.

 

기본적으로 ADS 라이브러리를 통해서 아래와 같이 Read/Write가 가능합니다.

다만 어떤 객체에 대해서 동작을 수행할 것인지를 정해야 하는데,

해당 객체를 지정하는 방법은 IndexGroup/IndexOffset을 이용합니다.

(그 외에 다른 방법들도 있는 것으로 보이지만, 제가 직접 사용해보지는 않았습니다.)

해당 값은 TwinCAT 프로젝트에서 Scan Device 이후에 확인되는 장치 내 객체들의 정보를 직접 확인할 수 있습니다.

ADS 라이브러리 Read/Write 예제

문제는 사용자가 직접 TwinCAT 프로젝트를 열어서 확인을 해야 한다는 점입니다.

프로그램이 직접 장치 내에 어떤 객체들이 있는 지 확인하고, 각 객체들의 접근 값(IndexGroup/IndexOffset 등)을 알 수 있다면, 사용자가 좀 더 편하게 EtherCAT 통신을 할 수 있겠죠.

 

서론이 길었지만, 해당 글은 C# 프로그램이 직접 TwinCAT 프로젝트를 열어서 관련 객체들에 대한 정보를 가져오는 것에 대해서 서술하고 있습니다.

역시 관련 정보들은 Beckhoff 홈페이지에서 확인할 수 있었습니다.

 

ITcSysManager::LookupTreeItem을 이용하면 됩니다.

해당 함수의 리턴 값을 iterators를 이용하면 자식 노드들에 접근할 수 있습니다.

I/O Devices 노드의 자식 노드들이 EtherCAT 장치들이고,

EtherCAT 장치들의 자식 노드들이 장치 내 객체들이기 때문에,

결국은 객체에 접근할 수 있게 됩니다.

해당 객체의 이름은 Name이라고 하는 속성이 가지고 있으며,

IndexGroup, IndexOffset 또한 해당 객체 내에 특정 속성이 가지고 있을 거라고 보고 있습니다.

ITcSysManager::LookupTreeItem 사용 예제

여기까지는 쉽게 찾았습니다만, 문제는 ITcSysManager는 인터페이스 이름입니다.

따라서 해당 인터페이스 내의 LookupTreeItem 함수는 바로 호출할 수 없습니다.

해당 인터페이스를 상속받는 클래스가 필요하기 때문이죠.

저는 해당 클래스를 구하는 방법을 찾는데 시간이 조금 걸렸습니다.

결국은 Beckhoff 홈페이지에 있더라고요... (구글링을 열심히 하다보니 결국 돌고 돌아 Beckhoff 홈페이지에 있었습니다.)

언젠가 한번 Beckhoff 매뉴얼을 한번 정독할 필요가 있을 것 같습니다.

 

Visual Studio DTE를 사용하여 TwinCAT 프로젝트를 열고, 해당 프로젝트로부터 ITcSysManager를 가져와야 합니다.

그 이후에는 해당 인터페이스 함수들을 사용하여 TwinCAT 설정들을 가져올 수 있죠.

TwinCAT 설정 접근 관련 그림

Beckhoff 예제에서는 DTE를 통해 TwinCAT 프로젝트를 만들고, 해당 프로젝트로부터 ITcSysManager를 가져옵니다.

우선 예제의 VisualStudio.DTE.10.0은 각자 본인이 사용하는 PC 내에 설치되어 있는 TwinCAT 버전에 따라 다릅니다.

이 또한 Beckhoff에서 설명하고 있으며, 저 같은 경우에는 TwinCAT XAE Shell 버전을 사용하기 때문에

"TcXaeShell.DTE.15.0"을 사용하였습니다.

TwinCAT 프로젝트 생성 및 SystemManager 가져오는 예제 코드
TwinCAT 버전에 따라 선택해야 하는 DTE 버전

또한 예제에서는 Create 함수를 통해 TwinCAT 프로젝트를 직접 생성하지만, 저는 이미 생성된 프로젝트를 열기 위해 Open 함수를 사용하였습니다. 그럴 경우에 예제처럼 Template을 따로 추가해줄 필요는 없게 됩니다.

 

그 뒤에 바로 Object 객체에 접근하여 ITcSysManager을 가져올 수 있게 됩니다.

Object 객체에 접근할 경우에 COMException이 발생할 수 있습니다.

COM 기능을 사용할 경우에 동시 접근에 대한 예외가 발생할 수 있습니다.

저 같은 경우에는 해당 예외가 발생할 수 있는 부분에

try~catch 구문을 이용하여 해당 예외가 발생하면 0.1초 뒤에 다시 해당 코드를 실행하도록 수정하였습니다.

Beckhoff 매뉴얼에서 또한 해당 부분에 대해 명시하고 있으며, 이를 위해 특정 인터페이스를 사용할 것을 권장하고 있으나, 저는 우선 해당 기능을 테스트하고 있는 수준이기 때문에 try~catch 구문으로 임의로 예외 처리하였습니다.

 

또한 dte.MainWindow.Visible 값을 false로 해줌으로써 프로그램이 매번 실행될때마다 TwinCAT 프로젝트 UI 창을 띄우지 않도록 하였습니다.

 

그 이후에는 위에서 설명한 LookupTreeItem 함수를 통해 I/O Devices 노드 내 자식 노드들에 접근하여 필요한 정보들을 가져오면 됩니다.

 

여기까지가 C# 프로그램으로 TwinCAT 프로젝트를 열고 이를 바탕으로 EtherCAT 통신에 필요한 정보들을 가져오는 방법입니다. 이러한 API들을 잘 활용하면 사용자가 직접 TwinCAT 프로젝트를 열지 않고도 프로그램을 통해서 EtherCAT 통신을 쉽게 수행할 수 있게 됩니다.

 

다만 프로그램을 실행할때마다 TwinCAT 프로젝트를 열어야 하기 때문에 시간이 많이 소요됩니다. 기본적으로 EtherCAT 장치가 추가되거나 제거되지 않는 한, 관련 정보들을 잘 변하지 않습니다. 가끔 관련 정보들이 변할때도 있기도 합니다만, 얻을 수 있는 이득에 비해서 소요되는 시간이 좀 있는 거 같습니다.

우선은 TwinCAT 프로젝트를 통해 EtherCAT 통신을 하는 한계라고 생각을 합니다. 다른 EtherCAT 제어 S/W를 사용한다면 해당 문제를 해결할 수 있을지도 모르겠습니다.

 

P.S.

ADS 관련 사진을 찾다가 흥미로운 부분을 발견했네요.

ADS 포트 번호에 SystemManager가 10300으로 정해져있더라고요.

(그 외에 고정된 포트번호를 잘 이용하면 ADS 라이브러리만으로도 EtherCAT 통신에 필요한 정보들을 모두 얻을지도 모릅니다.)

이를 잘 이용하면 TwinCAT 프로젝트를 열지 않고도 System Manager에 접근을 할 수 있을 거 같습니다.

제가 한번 해보고 잘 되면 글을 올리도록 하겠습니다.

 

감사합니다!