Table of Contents
Programming 방법
ComfileTech.Cfnet.Cfheader 라이브러리에서 제공하는 API를 이용하여 프로그램 작성방법을 설명합니다.
CFHEADER모듈 인스턴스 생성
CFHEADER 모듈의 ADDR. (DIP 스위치) 주소 값은, 프로그램 내에서 Cfheader.Instances[ADDR] 형태로 해당 모듈 인스턴스를 참조하는 데 사용됩니다. 즉, CFHEADER 모듈의 DIP 스위치로 설정한 주소가 0이라면, 코드에서는 Cfheader.Instances[0]로 해당 인스턴스를 참조해야 합니다
var cfheaderAtAddress0 = Cfheader.Instances[0]; // CFHEADER ADDR.0 : 어드레스 0번 헤더모듈 객체생성 var CfheaderAtAddress1 = Cfheader.Instances[1]; // CFHEADER ADDR.1 : 어드레스 1번 헤더모듈 객체생성 // etc...
- [연결된 CFHEADER 확인방법 (Code)] : HOST PC와 다수의 CFHEADER 모듈 연결 시, 프로그램 코드 내에서 연결된 각 CFHEADER 모듈의 정보를 확인할 수 있습니다.
CFNET IO 모듈 인스턴스
CFHEADER에 연결된 각 CFNET IO 모듈의 인스턴스는 Cfheader 인스턴스 컬렉션을 통해 접근할 수 있습니다. Cfheader에는 AnalogInputModules,
AnalogOutputModules , DigitalInputModules 및 DigitalOutputModules 컬렉션이 있습니다.
모듈의 ADDR(Address) 값을 기준으로 컬렉션을 구성하여, 해당 주소에 맞는 인스턴스를 생성해야 합니다.
시스템 구성이 CFHEADER[ADDR.0] + CFADC[ADDR.0] + CFDAC[ADDR.3] + CFDI[ADDR.7] + CFDO [ADDR.4] 일 경우 인스턴스 설정은 아래와 같습니다.
var cfheader0 = Cfheader.Instances[0]; var analogInputModuleAtAddress0 = cfheader0.AnalogInputModules[0]; var analogOutputModuleAtAddress3 = cfheader0.AnalogOutputModules[3]; var digitalInputModuleAtAddress7 = cfheader0.DigitalInputModules[7]; var digitalOutputModuleAtAddress4 = cfheader0.DigitalOutputModules[4];
- [연결된 CFNET IO 확인방법 (Code)] : CFHEADER 모듈에 연결된 CFNET IO 모듈의 정보를 프로그램 코드에서 확인할 수 있습니다.
USB 커뮤니케이션
HOST PC와 CFHEADER 간 USB 통신을 시작하려면, 생성한 Cfheader 인스턴스의 Open() 메서드를 호출하여 통신을 초기화해야 합니다.
- USB 연결 초기화 : Cfheader.Open()
- 메모리 전송 : CFHEADER 통신 동작원리 ←- Cfheader.Sync() 참조
- 백그라운드에서 자동 메모리 전송 : CFHEADER 통신 동작원리 ←- BackgroundSync.Start()참조
- USB 연결을 종료: Cfheader.Close()
CFDO/DI 디지털 입출력
CFDO 디지털 출력모듈 Code 및 동작 영상
CFDI 디지털 입력모듈 Code 및 동작 영상
CFDO/DI 모듈의 Digital In/Out 제어는 Cfheader.DigitalOutputModules, Channels[] 와 같은 인스턴스의 State 객체를 통해 읽기 및 쓰기가 가능합니다.
DigitalOutputModules[ ].State 속성을 사용하면 16개의 포트 상태를 일괄적으로 읽거나 쓸 수 있습니다.또한,
DigitalOutputModules[ ].Channel[ ].State 속성을 통해 각 포트(채널)를 개별적으로 읽거나 쓸 수도 있습니다.
var CFHEADER_0 = Cfheader.Instances[0]; var CFDO_0 = CFHEADER_0.DigitalOutputModules[0]; //CFDO ADDR. 0번 출력모듈 var CFDO_0_CH1 = CFHEADER_0.DigitalOutputModules[0].Channels[1]; //CFDO ADDR. 0번 출력모듈의 1번 포트 CFDO_0.State = 0XFF00; //CFDO ADDR. 0번 모듈 출력 상태를 0xff00으로 출력 CFDO_0_CH1.State = true; //CFDO ADDR. 0번 모듈 1번 Port(채널)을 on 출력 var CFDI_0 = CFHEADER_0.DigitalInputModules[0]; //CFDI ADDR. 0번 입력모듈 var CFDI_0_CH1 = CFHEADER_0.DigitalInputModules[0].Channels[1]; //CFDI ADDR. 0번 입력모듈의 1번 포트 Console.WriteLine($"CFIO : {CFDI_0.State:X}"); //CFDI ADDR. 0번 입력모듈의 상태를 읽어옵니다.
- 입출력 예제코드 ( CFHEADER[ADDR.0] + CFDO[ADDR.0] + CFDI[ADDR.0] )
using System; using ComfileTech.Cfnet.Cfheader; class Program { static void Main(string[] args) { var CFHEADER_0 = Cfheader.Instances[0]; var CFDO_0 = CFHEADER_0.DigitalOutputModules[0]; //CFD0 출력 모듈 ADDR. 0번 모듈 인스턴스 var CFDO_CH1 = CFDO_0.Channels[1]; var CFDI_0 = CFHEADER_0.DigitalInputModules[0]; //CFDI입력 모듈 ADDR. 0번 모듈 인스턴스 CFHEADER_0.Open(); CFHEADER_0.BackgroundSync.Start(); while (true){ CFDO_0.State = 0XFFFF; Thread.Sleep(100); CFDO_0.State = 0; Thread.Sleep(100); CFDO_CH1.State = true; Thread.Sleep(100); CFDO_CH1.State = false; Thread.Sleep(100); Console.WriteLine($"CFIO : {CFDI_0.State:X}"); } } }
CFADC 아날로그 입력
AnalogInputModule 클래스는 CFADC-A4L 아날로그 모듈의 입력 값을 읽을 때 사용하는 클래스입니다.
AnalogInputModule.Channels[ ]의 속성에서 변환된 데이터값(RawValue), 전압(Voltage), 전류(Current)로 읽을 수 있습니다. 전압과 전류 속성은 RawValue 값을 기반으로 계산되며, 정확한 값을 얻기 위해 보정(Calibration)이 필요할 수 있습니다.
sing ComfileTech.Cfnet.Cfheader; var cfheader0 = Cfheader.Instances[0]; var analogInputModule0 = cfheader0.AnalogInputModules[0]; var CFADC_0_CH0 = analogInputModule0.Channels[0]; cfheader0.Open(); while (true){ cfheader0.Sync(); Console.WriteLine($"Channel {CFADC_0_CH0.Address,2}: {CFADC_0_CH0.RawValue,8} {CFADC_0_CH0.Voltage,8:F2}V {CFADC_0_CH0.Current,8:F2}A"); }
CFDAC 아날로그 출력
AnalogOutputModule 클래스는 CFDAC-2V 아날로그 모듈에 출력 값을 전달할 때 사용하는 클래스입니다. CFDAC-2V 모듈은 2개의 채널을 가지고 있습니다.
AnalogOutputModule.Channels[ ] 속성값으로 아날로그 전압 출력을 설정할 수 있습니다.
각 채널의 전압은 RawValue 속성을 통해 아날로그 전압 출력을 설정할 수 있습니다.Voltage 속성을 통해 명시적인 전압 값으로 설정할 수 있습니다.
using ComfileTech.Cfnet.Cfheader; using System.Diagnostics; var cfheader0 = Cfheader.Instances[0]; var CFDAC_0_CH0 = cfheader0.AnalogOutputModules[0].Channels[0]; var CFDAC_0_CH1 = cfheader0.AnalogOutputModules[0].Channels[1]; cfheader0.Open(); while (true) { CFDAC_0_CH0.Voltage = (float)5.24; CFDAC_0_CH1.RawValue = (ushort)1000; cfheader0.Sync(); }
Real-time 설정
Improving Real-time Performance(영문설명)
Host PC와 CFHEADER 모듈 간에 실시간(Software Real-Time) 제어를 구현하기 위한 동작 방식과 설정 방법을 설명합니다.
Host PC는 1ms 주기로 USB 패킷 통신을 수행합니다. 통신 패킷이 전송되면 인터럽트가 발생하며, 해당 인터럽트를 통해 CFHEARD와 동기화됩니다. 동기화 되는 통신 주기 속도는 NumberOfUsbFramesToSync속성값으로 설정합니다.
- NumberOfUsbFramesToSync 속성값 :
- -1 : IO 모듈과의 I2C 통신은 USB 호스트로부터 USB 패킷이 수신될 때만 발생합니다. 즉, USB 호스트 애플리케이션이 타이밍을 제어합니다.
- 0 : IO 모듈과의 I2C 통신은 마지막 I2C 통신이 종료된 직후 즉시 발생합니다. 즉, 타이밍 동기화가 전혀 이루어지지 않습니다.
- 1 : IO 모듈과의 I2C 통신은 SoF 인터럽트(1ms)마다 한 번씩 발생합니다. 즉, I2C 타이밍이 USB 호스트의 SoF 인터럽트와 동기화됩니다. 그러나 많은 IO 모듈이 연결되어 있을 경우, 이 시간이 충분하지 않을 수 있습니다.
- 2 : IO 모듈과의 I2C 통신은 2번의 SoF 인터럽트(2ms)마다 한 번씩 발생합니다. 이는 1과 동일하지만, I2C가 완료될 수 있는 더 많은 시간을 제공합니다.
- 3 : IO 모듈과의 I2C 통신은 3번의 SoF 인터럽트(3ms)마다 한 번씩 발생합니다.
- 4…etc..
HOST PC Real-time 설정
Windows 및 Linux와 같은 Host PC는 실시간 운영체제가 아니므로, USB 패킷을 CFHEADER 모듈에 실시간으로 스케줄링하는 것은 제한적일 수 있습니다. 다음 설정을 통해 실시간 성능을 향상시킬 수 있습니다.
Windows
아래와 같이 Host PC에서 실행될 프로그램(.exe)의 우선순위를 실시간(Real-time) 으로 설정합니다. 이때 관리자 권한으로 설정합니다.
Windows의 실시간 성능을 더욱 향상시키기 위해서는 운영 체제 자체의 설정을 변경해야 할 경우가 있습니다. 이때, Windows Soft-Real-Time관련 문서를 참고하세요.
Linux
Linux는 프로세스 및 스레드에 대해 실시간 스케줄링 설정, 우선순위 지정, CPU 코어 예약 등의 구성이 가능합니다.
자세한 내용은 CompfilePi 애플리케이션 노트 improving real-time performance 를 참조하십시오.
