콘텐츠로 바로 가기

Application Note: Designing Signal Processing Applets for Programmable Frame Grabbers#

모든 프로그래밍 가능한 프레임 그래버는 그래픽 기반 FPGA 프로그래밍 환경 VisualApplets 을 사용하여 사용자만의 개별적인 이미지 처리 솔루션(애플릿)을 프로그래밍할 수 있도록 설계되었습니다.

GPI/GPO 운영자 VisualApplets#

VisualApplets 를 사용하면 애플리케이션에 맞는 맞춤형 트리거 시스템을 설계할 수 있습니다. 예를 들어, 개별 물리적 입출력 핀에서 어떤 신호가 송신되거나 수신되는지 지정할 수 있습니다.

VisualApplets 에서는 개별 핀을 애플릿 설계에 연결하는 데 사용할 수 있는 두 가지 연산자가 있습니다:

연산자 GPI (트리거 IN 신호용)

연산자 GPO (트리거 OUT 신호용)

VisualApplets GPI 및 GPO 연산자를 사용한 설계

위의 그림은 신호 처리를 구현하는 방법을 보여주는 예시입니다. 구현하고자 하는 신호 처리 기능은 구체적인 요구 사항에 따라 달라집니다. 애플리케이션에 적합한 연산자를 찾으려면 신호 라이브러리를 참조하십시오. 또한 요구 사항에 따라 전면 GPIO를 선택하십시오.

위의 예시는 두 개의 입력 신호에 대한 다운스케일링 기능을 보여줍니다. GPI1과 Front GPI0에서 프로그래머블 프레임 그래버로 두 개의 신호가 입력됩니다. 신호는 먼저 데바운싱 처리되고, 상승 에지 또는 하강 에지가 선택된 후, 8배 또는 3배의 비율로 다운스케일링됩니다. 두 신호 모두에 대한 신호 길이가 설정된 후, 신호는 FrontGPO0, GPO1, GPO2 및 카메라로 전달되어 이미지 획득을 제어합니다.

GPI/GPO 연산자 사용#

프론트 GPIO 또는 트리거 확장 보드에서 사용하려는 각 트리거 IN/트리거 OUT 핀은 GPI/GPO 연산자 인스턴스와 상호 연결해야 합니다.

정보

연산자 GPI와 연산자 GPO는 기능이 동일하므로, 이하에서는 두 연산자를 함께 설명합니다.

  1. 디자인 내의 연산자 아이콘을 더블 클릭하면 ‘모듈 속성’ 창이 열립니다.

VisualApplets GPI 운영자

'모듈 속성' 창이 열립니다:

VisualApplets 모듈 속성 창

보시다시피, 이 연산자에는 두 개의 매개변수가 있습니다:

  • Pin_ID: Pin_ID 매개변수를 사용하면 선택한 커넥터에서 어떤 특정 핀을 대상으로 할지 지정할 수 있습니다.
  • ConnectorType: ConnectorType 매개변수를 사용하면 어떤 커넥터(전면 GPIO 또는 GPIO를 통한 트리거 확장 보드)를 지정할지 정의할 수 있습니다.

정보

CXP-12 프레임 그래버의 경우, ConnectorType 매개변수는 다음의 Pin_ID 파라미터에 HTML 로그 파일(*.html)의 경로와 이름을 지정할 수 있습니다.

매개변수 커넥터 유형#

이 매개변수를 사용하면 15핀 D-Sub 소켓에 제공된 트리거 핀 중 어떤 그룹을 대상으로 할지 지정할 수 있습니다 (Front GPIO), 또는 트리거 확장 보드에 제공된 것들(GPIO). 이 매개변수의 값 범위는 {전면 GPIO, GPIO}입니다.

Value Front GPIO#

값을 선택하면 Front GPIO, 프로그래머블 프레임 그래버의 슬롯 브래킷에 있는 다음 커넥터(트리거 핀 그룹)를 연결하십시오:

프레임 그래버의 전면 GPIO

Value GPIO#

값을 선택하면 GPIO, 프로그래밍 가능한 프레임 그래버에서 다음과 같은 트리거 핀 그룹을 설정합니다:

프레임 그래버의 GPIO

GPIO는 트리거 확장 보드에 연결하는 데 사용됩니다:

GPIO를 통해 트리거 보드 연결하기

Parameter Pin_ID#

이 매개변수를 사용하면 선택한 커넥터(트리거 핀 그룹)에서 어떤 개별 핀을 지정할지 정의할 수 있습니다. 매개변수의 값 범위는 Pin_ID is {0;7} or {0;3} for connector type GPIO 또는 Front GPIO.

정보

매개변수의 값 범위 Pin_ID for marathon frame grabbers and operator GPO is {0;1}.

VisualApplet 연산자 참조를 활용한 전면 GPIO 핀 구성#

전면 GPIO 핀

VisualApplet 연산자 참조를 활용한 전면 GPIO 핀 구성

차동 모드에서는 핀 9를 사용하여 Pin_ID=3인 GPI 연산자에서 하나의 싱글-엔디드 신호를 수신할 수 있습니다. “차동” 모드(기본값)를 참조하십시오.

주의

프레임 그래버 트리거 시스템은 Voltage IN 핀을 통해 공급 전압을 받아야 합니다. PWR 핀이 없는 장치를 연결하려는 경우, 외부 전원을 통해 Voltage IN 핀에 전원을 공급해야 합니다.

전면 GPIO의 INPUT 트리거#

만약 당신이

  • 다음과 같은 GPI 연산자 (트리거 입력 신호를 정의하기 위한),
  • 매개변수를 설정했습니다 Connector Type 에서 Front GPIO,

매개변수의 값 Pin_ID 다음 핀들을 처리하십시오:

핀 ID가 지정된 전면 GPIO

전면 GPIO의 입력(GPI) 핀은 구성할 수 있습니다. 6개의 입력 핀을 사용하여 다음 중 하나를 수신할 수 있습니다:

  1. 3개의 차동 신호, 또는
  2. 2개의 차동 신호와 1개의 단일 종단 신호, 또는
  3. 4개의 싱글 엔드 신호.

전면 GPIO의 입력 핀을 특정 신호 유형(차동 또는 단일 종단)에 맞게 구성하려면 다음 두 가지 모드를 사용할 수 있습니다:

  • Mode Differential (a와 b 두 가지 선택지를 제시하며)
  • Mode Single-ended (옵션 c 제공)

전면 GPIO의 기본 모드는 mode입니다. Differential. 모드 전환 방법은 해당 항목을 참조하십시오. 입력 구성 프레임 그래버 사용 설명서에서.

주의

기본 설정에서 전면 GPIO의 GPIO 핀은 다음과 같은 기능을 제공합니다:

  • 풀업 모드의 차동 입력 신호 3개 또는 차동 입력 신호 2개 및 싱글 엔디드 입력 신호 1개
  • 두 개의 TTL 출력 신호

입력 신호의 다른 구성이 필요한 경우, 예를 들어:

  • 풀다운 모드,
  • 4개의 단일 종단 신호(차동 신호는 없음),

필요에 따라 GPI를 쉽게 구성할 수 있습니다. 구성을 위해서는 ‘ Framegrabber SDK ’과 함께 시스템에 설치된 명령줄 도구를 사용하면 됩니다.

Mode Differential (기본값)#

모드에서 Differential (기본값)으로, 전면 GPIO의 6개 입력 핀은 모두 차동 신호를 수신하도록 구성되어 있습니다:

  • 핀 8/9 -> 1개의 차동 신호
  • 핀 11/12 -> 1개의 차동 신호
  • 핀 13/14 -> 1개의 차동 신호

또는 8/9번 핀 쌍을 사용할 수도 있습니다(모드에서 Differential) 단일 종단 신호 하나를 수신하기 위한:

  • 9번 핀 -> 1개의 단일 종단 신호
  • 핀 11/12 -> 1개의 차동 신호
  • 핀 13/14 -> 1개의 차동 신호

모드 내 개별 핀 Differential:

“차동” 모드의 개별 핀

11번 및 12번 핀:

  • 핀 11과 12로 들어오는 신호는 하나의 차동 신호로 해석됩니다(핀 11은 + 값, 핀 12는 - 값).
  • VisualApplets 내에서 이 차동 신호를 수신하려면 Pin_ID가 0인 GPI 연산자 인스턴스를 사용하십시오.

13번 및 14번 핀:

  • 핀 13과 14로 들어오는 신호는 하나의 차동 신호로 해석됩니다(핀 13은 + 값, 핀 14는 - 값).
  • VisualApplets 내에서 이 차동 신호를 수신하려면 Pin_ID가 1인 GPI 연산자 인스턴스를 사용하십시오.

8번 및 9번 핀:

  • 핀 8과 9로 들어오는 신호는 하나의 차동 신호로 해석됩니다(핀 8은 + 값, 핀 9는 - 값).
  • VisualApplets 내에서 이 차동 신호를 수신하려면 Pin_ID가 2인 GPI 연산자 인스턴스를 사용하십시오.

또는 8/9번 핀 쌍을 사용하여 단일 종단 신호 하나를 수신할 수도 있습니다(단, 모드에서는 Differential): 이 경우,

  • 단일 종단 입력 신호를 물리적 핀 9에 연결합니다.
  • VisualApplets 내에서 이 단일 종단 신호를 수신하려면 Pin_ID가 3인 GPI 연산자 인스턴스를 사용하십시오.

Mode Single-Ended#

모드에서 Single-ended (구성 가능), 전면 GPIO의 6개 입력 핀은 4개의 싱글 엔드 신호를 수신하도록 구성됩니다:

  • 8번 핀 -> 단일 종단 신호 1개
  • 9번 핀 -> 1개의 단일 종단 신호
  • 핀 11 -> 단일 종단 신호 1개
  • 핀 13 -> 단일 종단 신호 1개

모드 내 개별 핀 Single-ended:

“단일 종단” 모드의 개별 핀

핀 11 및 12의 신호:

  • 핀 11의 입력 신호는 싱글 엔드 신호로 해석됩니다.
  • VisualApplets 내에서 이 싱글 엔드 신호를 수신하려면 Pin_ID가 0인 GPI 연산자 인스턴스를 사용하십시오.
  • 이 모드에서는 12번 핀이 사용되지 않습니다. Single-ended.

핀 13 및 14의 신호:

  • 핀 13으로 들어오는 신호는 싱글 엔드 신호로 해석됩니다.
  • VisualApplets 내에서 이 싱글 엔디드 신호를 수신하려면, Pin_ID가 1인 GPI 연산자 인스턴스를 사용하십시오.
  • 이 모드에서는 14번 핀이 사용되지 않습니다. Single-ended.

8번 및 9번 핀:

  • 핀 8과 9로 들어오는 신호는 두 개의 싱글 엔드 신호로 해석됩니다.
  • VisualApplets 내에서 이러한 싱글 엔디드 신호를 수신하려면 다음을 사용하십시오.

    • 핀 8에 대해 Pin_ID가 2인 GPI 연산자 인스턴스, 그리고
    • 핀 9에 대해 Pin_ID가 3인 GPI 오퍼레이터 인스턴스.

트리거 출력 TTL 전면 GPIO에서#

만약 당신이

  • 트리거 출력 신호를 정의할 때는 GPO 연산자를 사용하고,
  • '커넥터 유형' 매개변수를 '전면 GPIO'로 설정하셨으며,

매개변수 Pin_ID의 값은 다음 핀들을 가리킵니다:

전면 GPIO TTL 출력 핀 ID

이 두 핀은 TTL 신호(5V)를 전송하고 있습니다.

전면 GPIO에서 출력되는 TTL 신호 (5 V):

전면 GPIO에서 출력되는 TTL 신호 (5 V)

트리거 확장 보드(GPIO를 통해)에 신호를 전송하는 트리거 신호#

GPIO 커넥터는 트리거 확장 보드에 연결하도록 설계된 프로그래머블 프레임 그래버의 물리적 트리거 인터페이스입니다:

프레임 그래버 및 트리거 보드의 GPIO

GPIO 커넥터, 즉 각 트리거 확장 보드는 다음과 같은 기능을 제공합니다.

  • 8개의 디지털 입력 (IN 0 - 7) (8개의 단일 종단 신호 또는 4개의 차동 신호)
  • 8개의 디지털 출력(OUT 0 - 7)

8개의 입력에는 0부터 7까지의 인덱스가 부여되어 있습니다. 8개의 출력에도 0부터 7까지의 인덱스가 부여되어 있습니다.

핀 배열에 대한 자세한 내용은 SUB-D15 - TTL Trigger 보드의 ‘핀 배열’ 또는 Opto-Coupled Trigger 5 - Opto-Coupled Trigger 5 보드 확장 보드의 ‘핀 배열’을 참조하십시오.

Pin_ID TTL Trigger 확장 보드에 관한 과제#

포트 A#

핀 번호 Pin_ID Visual Applets에서
1 0
2 1
3 2
4 3
5
6
7
8
9
10
11 0
12 1
13 2
14 3
15 0

포트 B#

핀 번호 Pin_ID Visual Applets에서
(단일 종단 신호)
1 4
2 5
3 6
4 7
5
6
7
8
9
10
11 4
12 5
13 6
14 7
15

Pin_ID OPTO Trigger 5 확장 보드에 대한 과제#

포트 A#

핀 번호 Pin_ID Visual Applets에서
(단일 종단 신호)
Pin_ID Visual Applets에서
(차동 신호)
1 0
2 1
3 2
4 3
5
6
7
8
9
10
11 0 0
12 1 0
13 2 2
14 3 2
15

포트 B#

핀 번호 Pin_ID Visual Applets에서
(단일 종단 신호)
Pin_ID Visual Applets에서
(차동 신호)
1 4
2 5
3 6
4 7
5
6
7
8
9
10
11 4 4
12 5 4
13 6 6
14 7 6
15

트리거 시스템 구성#

트리거 설정은 다음 두 가지 방법으로 확인할 수 있습니다:

  • microDisplay X: 여기에서는 GUI를 통해 트리거 매개변수 값을 입력하여 특정 구성의 결과를 확인할 수 있습니다.
  • SDK: 특정 이미지 처리 소프트웨어 애플리케이션에 프레임 그래버 프로그래밍 인터페이스를 구현하기 위한 것입니다.

트리거 시스템에 요구되는 사항은 사용 용도에 따라 달라집니다:

  • 영역 스캔의 경우, 하나의 트리거 유형(프레임 트리거)만 필요합니다.
  • 라인 스캔의 경우, 라인 트리거(각 라인마다 트리거 펄스를 전송함)와 프레임 트리거, 두 가지 트리거 유형이 필요합니다. 라인 스캔 애플리케이션에서 프레임 트리거는 이미지에 몇 개의 라인이 추가될지를 제어합니다.

영역 스캔 및 라인 스캔 카메라를 작동시키는 방법에 대한 자세한 정보는 여기에서 확인하실 수 있습니다.

정보

프레임 그래버 트리거 시스템에 대한 자세한 내용은 ‘GPIO 커넥터’ 항목을 참조하십시오.

정보

사용 가능한 매개변수가 무엇인지(그리고 특정 설정이 어떤 영향을 미칠 수 있는지)에 대한 정보는 사용 중인 애플릿의 설명서를 참조하십시오.

하드웨어에서 Applet 실행#

선행 조건:

프로그래밍 가능한 프레임 그래버에서 애플릿을 실행하기 전에, 먼저 *.hap 파일(애플릿)을 호스트 PC에 설치된 Basler Framegrabber SDK 로 복사한 다음, 프로그래밍 가능한 프레임 그래버에 플래시하십시오.

정보

플래싱은 marathon 에 명시된 프레임 그래버에만 필요합니다.

‘하드웨어 애플릿: 아이디어에서 응용까지’ 항목에서 ‘ VisualApplets ’ 설계를 하드웨어 애플릿으로 변환하는 방법에 대한 자세한 정보를 확인할 수 있습니다.

  1. 다음 내용을 복사하세요. *.hap VisualApplets 에서 빌드한 파일을 다음 디렉터리에 [Framegrabber SDK installation directory]/Hardware Applets/[frame grabber model]. 프로그래밍 가능한 프레임 그래버 모델 이름이 포함된 하위 디렉터리가 없다면, 이를 생성하십시오. VisualApplets 에서 기본 설정을 사용한 경우, 해당 *.hap VisualApplets 설치 디렉터리의 하위 디렉터리에 있는 파일 Designs.

  2. “플래싱” 섹션에 설명된 대로 프로그래밍 가능한 프레임 그래버에 애플릿을 설치하십시오.

이 작업을 마친 후에는 다음과 같은 작업을 수행할 수 있습니다:

예시: 신호 처리 예제 설계의 하드웨어 애플릿을 microDisplay X 에 불러오면, 아래 그림과 같이 매개변수 트리에서 다운스케일링 계수 및 신호 폭과 같은 동적 매개변수를 설정할 수 있습니다.

신호 처리 설계 예시

자신만의 소프트웨어에서 애플릿 실행하기#

자신의 소프트웨어에서 이 애플릿을 사용하려면:

  1. Basler 애플리케이션 프로그래밍 인터페이스에서는 다음 호출을 사용하십시오. Fg_Init 애플릿을 실행하려면, 다음의 위치 경로를 지정하십시오. *.hap VisualApplets로 생성한 파일입니다.

사용 가능한 모든 함수 호출에 대한 자세한 설명과 참조 내용은 Framegrabber API 매뉴얼과 Framegrabber API 함수 참조를 참조하십시오.

C++ SDK의 기반으로 VisualApplets 의 내부 SDK 코드 생성기를 사용할 수 있습니다. 이 기능은 아이콘 메뉴에서 찾거나 VisualApplets 의 ‘Build and Generate SDK example’ 항목에서 확인할 수 있습니다. 이 기능은 해당 CMake 파일과 Visual Studio 프로젝트 파일을 자동으로 생성합니다( ‘하드웨어 애플릿: 아이디어에서 애플리케이션까지’ 항목도 참조하십시오).

자동 SDK 코드에는 이미지 획득 및 매개변수 설정에 필요한 다음과 같은 기능 블록이 포함되어 있습니다:

  • 프레임 그래버 초기화
  • 버퍼에 대한 메모리 할당
  • 정의 Get 및 Set 매개변수
  • 디스플레이 생성
  • 현재 연결된 각 포트에 대해 애플릿 및 카메라에서 데이터 수집 시작
  • 이미지 가져오기
  • 인수 중단
  • 디스플레이 닫기
  • 버퍼에 대한 메모리 해제
  • 프레임 그래버 초기화 해제

다음은 신호 처리 예제에 대한 C++ Framegrabber API 의 예제 코드입니다.

  • 프레임 그래버 초기화 및 버퍼용 메모리 할당:
int main ()
{

    // ---------------------------------------------------------------------------
    // Frame Grabber: Initialization
    // ---------------------------------------------------------------------------


    int nrOfCycles = 5000; // Acquire 5000 frames, TODO: insert the number according to your needs
    unsigned int boardIndex = 0; // TODO: Use the correct board index at multi frame grabber systems
    int rc = 0; // return code

    Fg_Struct* fg = Fg_Init("SignalProcessingDesign.hap", boardIndex);
    if(fg == NULL){
        fprintf(stderr, "Error in Fg_Init(): %s\n", Fg_getLastErrorDescription(NULL));
        fprintf(stderr, "Press <Return> to continue...\n");
        getchar();
        return -1;
    }

    int nrOfParameter = Fg_getNrOfParameter(fg);
    fprintf(stderr, "No. of Parameter: %d\n", nrOfParameter);

    int i;
    for (i = 0; i < nrOfParameter; i++) {
        const char *name = Fg_getParameterName(fg,i);
        fprintf(stderr," Param %d: %s,%x\n",i,name,Fg_getParameterId(fg,i));
    }


    / ---------------------------------------------------------------------------
    // Frame Grabber: Allocate memory for buffer(s)
    // ---------------------------------------------------------------------------


    // Feature Cnt 0,0
    int width0 = 1024;
    int height0 = 1024;
    int byteWidth0 = 1;
    size_t bufSize0 = width0 * height0 * (size_t)byteWidth0;
    const unsigned int mem0_bufs = 4;
    dma_mem *pmem0 = Fg_AllocMemEx(fg, bufSize0 * mem0_bufs, mem0_bufs);
    if(pmem0 == NULL){
        fprintf(stderr, "Error in Fg_AllocMemEx(): %s\n", Fg_getLastErrorDescription(fg));
        Fg_FreeGrabber(fg);
        fg = NULL;
        fprintf(stderr, "Press <Return> to continue...\n");
        getchar();
        return -1;
    }
  • 다음의 발췌문: Get 및 Set 매개변수 섹션. 여기에서는 동적 매개변수를 설정하는 방법을 확인할 수 있습니다. 다음 코드는 다운스케일 계수를 설정하는 방법과 특정 펄스를 연산자의 매개변수로 선택하는 방법을 보여줍니다. Device1_Process0_ByFactor8:
// ---------------------------------------------------------------------------
// Frame Grabber: Get* and Set* parameters for Process0
// ---------------------------------------------------------------------------


/*============ Downscale : ByFactor8 ============== */


int Device1_Process0_ByFactor8_Downscale_Id = Fg_getParameterIdByName(fg, "Device1_Process0_ByFactor8_Downscale");
if(Device1_Process0_ByFactor8_Downscale_Id <= 0) {
    fprintf(stderr, "\n");
    fprintf(stderr, "Error in Fg_getParameterIdByName(Device1_Process0_ByFactor8_Downscale): %s (%d)\n", Fg_getLastErrorDescription(fg), Device1_Process0_ByFactor8_Downscale_Id);
    fprintf(stderr, "Press <Return> to continue...\n");
    getchar();
}

unsigned int Device1_Process0_ByFactor8_Downscale;
Device1_Process0_ByFactor8_Downscale = 8;
rc = Fg_setParameterWithType(fg, Device1_Process0_ByFactor8_Downscale_Id, Device1_Process0_ByFactor8_Downscale, 0);
if(rc < 0) {
    fprintf(stderr, "\n");
    fprintf(stderr, "Error in Fg_setParameterWithType(Device1_Process0_ByFactor8_Downscale_Id): %s (%d)\n", Fg_getLastErrorDescription(fg), rc);
    fprintf(stderr, "Press <Return> to continue...\n");
    getchar();
}

int Device1_Process0_ByFactor8_SelectedPulse_Id = Fg_getParameterIdByName(fg, "Device1_Process0_ByFactor8_SelectedPulse");
if(Device1_Process0_ByFactor8_SelectedPulse_Id <= 0) {
    fprintf(stderr, "\n");
    fprintf(stderr, "Error in Fg_getParameterIdByName(Device1_Process0_ByFactor8_SelectedPulse): %s (%d)\n", Fg_getLastErrorDescription(fg), Device1_Process0_ByFactor8_SelectedPulse_Id);
    fprintf(stderr, "Press <Return> to continue...\n");
    getchar();
}

unsigned int Device1_Process0_ByFactor8_SelectedPulse;
Device1_Process0_ByFactor8_SelectedPulse = 1;
rc = Fg_setParameterWithType(fg, Device1_Process0_ByFactor8_SelectedPulse_Id, Device1_Process0_ByFactor8_SelectedPulse, 0);
if(rc < 0) {
    fprintf(stderr, "\n");
    fprintf(stderr, "Error in Fg_setParameterWithType(Device1_Process0_ByFactor8_SelectedPulse_Id): %s (%d)\n", Fg_getLastErrorDescription(fg), rc);
    fprintf(stderr, "Press <Return> to continue...\n");
    getchar();
}

정보

자동으로 생성된 C++ Framegrabber API 코드에서, 데이터 수집 중 매개변수 설정과 관련이 없는 모든 매개변수는 삭제해도 됩니다. 데이터 수집 중에 구성해야 하는 매개변수만 남겨두십시오.

  • 디스플레이를 생성하고, 데이터 수집을 시작하며, 이미지를 캡처합니다:
// ---------------------------------------------------------------------------
// Frame Grabber: Create the display(s)
// ---------------------------------------------------------------------------

int id0 = CreateDisplay(8 * byteWidth0, width0, height0);
if(id0 < 0) {
    fprintf(stderr, "Error in CreateDisplay(): %s (%d)\n", Fg_getLastErrorDescription(fg), id0);
    Fg_FreeMemEx(fg, pmem0);
    pmem0 = NULL;
    Fg_FreeGrabber(fg);
    fg = NULL;
    fprintf(stderr, "Press <Return> to continue...\n");
    getchar();
    return id0;
}
SetBufferWidth(id0, width0, height0);


// ---------------------------------------------------------------------------
// Frame Grabber: Start acquisition at applet and camera for each present port
// ---------------------------------------------------------------------------

rc = Fg_AcquireEx(fg, 0, nrOfCycles, ACQ_STANDARD, pmem0);
if(rc != 0) {
    fprintf(stderr, "Error in Fg_AcquireEx() for channel 0: %s\n", Fg_getErrorDescription(fg, rc));
    CloseDisplay(id0);
    Fg_FreeMemEx(fg, pmem0);
    pmem0 = NULL;
    Fg_FreeGrabber(fg);
    fg = NULL;
    fprintf(stderr, "Press <Return> to continue...\n");
    getchar();
    return rc;
}

// ---------------------------------------------------------------------------
// Frame Grabber: Grab images
// ---------------------------------------------------------------------------

frameindex_t frameNo0 = 0;
for(i = 1; i <= nrOfCycles; ++i){
frameNo0 = Fg_getLastPicNumberBlockingEx(fg, frameNo0 + 1, 0, 5, pmem0);
    if(frameNo0 < 0) {
        fprintf(stderr, "Error in Fg_getLastPicNumberBlockingEx(): %s (%d)\n", Fg_getLastErrorDescription(fg), frameNo0);
        fprintf(stderr, "Press <Return> to continue...\n");
        getchar();
        break;
    } else {
        fprintf(stderr, "grabbed image %d\n", frameNo0 );
    }

    void *iPtr0 = Fg_getImagePtrEx(fg, frameNo0, 0, pmem0);
    if(iPtr0 == NULL) {
        fprintf(stderr, "Error in Fg_getImagePtrEx(): %s\n", Fg_getLastErrorDescription(fg));
        Fg_stopAcquireEx(fg, 0, pmem0, 0);
        CloseDisplay(id0);
        Fg_FreeMemEx(fg, pmem0);
        pmem0 = NULL;
        Fg_FreeGrabber(fg);
        fg = NULL;
        fprintf(stderr, "Press <Return> to continue...\n");
        getchar();
        return -1;
    }
    DrawBuffer(id0, iPtr0, frameNo0, "");
}
  • 인수 중지, 디스플레이 닫기, 버퍼에 할당된 메모리 해제:
// ---------------------------------------------------------------------------
// Frame Grabber: Stop acquisition
// ---------------------------------------------------------------------------

rc = Fg_stopAcquireEx(fg, 0, pmem0, 0);
if(rc < 0) {
    fprintf(stderr, "Error in Fg_stopAcquireEx(): %s (%d)\n", Fg_getLastErrorDescription(fg), rc);
    fprintf(stderr, "Press <Return> to continue...\n");
    getchar();
}


// ---------------------------------------------------------------------------
// Frame Grabber: Close the display
// ---------------------------------------------------------------------------

CloseDisplay(id0);


// ---------------------------------------------------------------------------
// Frame Grabber: Release the memory for buffer(s)
// ---------------------------------------------------------------------------

rc = Fg_FreeMemEx(fg, pmem0);
if(rc < 0) {
    fprintf(stderr, "Error in Fg_FreeMemEx(): %s (%d)\n", Fg_getLastErrorDescription(fg), rc);
    fprintf(stderr, "Press <Return> to continue...\n");
    getchar();
}
pmem0 = NULL;


// ---------------------------------------------------------------------------
// Frame Grabber: Uninitialization
// ---------------------------------------------------------------------------

rc = Fg_FreeGrabber(fg);
if(rc < 0) {
    fprintf(stderr, "Error in Fg_FreeGrabber(): %s\n", Fg_getLastErrorDescription(NULL));
    fprintf(stderr, "Press <Return> to continue...\n");
    getchar();
}
fg = NULL;


fprintf(stderr, "Press <Return> to exit...\n");
getchar();

return (0);
}

이 예제 코드를 더 큰 규모의 SDK 환경에 통합할 수 있습니다.