MoonNote

반응형
     

 

 

 

 이번 시간에는 타이밍(Timing) 함수에 대해 알아보도록 하겠습니다. 이전 시간에 반복문(For, While 문) 구조와 연속적인 실행에서 데이터를 넘기기 위한(Shift Register)에 대해 알아보았는데요. 여기에서 '루프 실행을 내가 원하는 주기마다 어떻게 실행하지?'라는 궁금증이 하나 생길 겁니다. 바로 랩뷰(LabVIEW) 타이밍 함수와 관련된 내용인데요. 이전 시간에 잠깐씩 언급은 되었지만 이번 시간에 한번 자세히 살펴보도록 하겠습니다.

 

타이밍 팔레트 (Timing Palette)

타이밍 팔레트의 위치는 함수 팔레트 >> 프로그래밍 >> 타이밍에 위치해 있습니다. 본문에서 다룰 함수는 랩뷰에서 대표적으로 많이 쓰이는 함수인 [Tick 카운트(ms)], [기다림(ms)], [다음 ms배수까지 기다림] 3가지 함수입니다. 

 

랩뷰(LabVIEW) 타이밍 함수

 

각각의 함수 설명입니다. (LabVIEW 도움말 참조)

- [Tick 카운트(ms)] : ms 타이머의 값을 반환합니다.

- [기다림(ms)] : 지정된 ms를 기다리고 ms 타이머의 값을 반환합니다.

- [다음 ms 배수까지 기다림] : ms 타이머의 값이 지정된 ms 배수의 배수가 될 때까지 기다립니다. 이 함수를 사용하여 여러 작업을 동기화합니다. 루프 안에서 이 함수를 호출하여 루프 실행 속도를 조절할 수 있습니다. 그러나, 첫 번째 루프 주기가 짧을 가능성이 있습니다. 0의 값을 ms 배수 입력에 연결하여 현재 스레드가 CPU의 컨트롤을 양도하도록 강제합니다.

이 함수는 비동기적으로 시스템을 호출하나, 노드 자체는 동기적으로 작동합니다. 그러므로, 이 함수는 지정된 시간이 지날때까지 실행을 완료하지 않습니다.

 

Loop Time 지정하기

반복문에서의 루프 타임 지정은 [기다림(ms)] 또는 [다음 ms 배수까지 기다림] 함수를 사용합니다. 기본 사용법은 루프 안쪽에 타이밍 함수를 위치시켜준 후 좌측의 입력 터미널에 원하는 타이머(ms) 값을 지정하기만하면 됩니다. 예시로 두 함수를 사용하여 루프 타임을 100ms로 지정해본 것이 아래 이미지입니다.

 

[기다림(ms)] 함수와 [다음 ms 배수까지 기다림] 함수

 

 

루프 타임을 지정하는 이유

루프 타임을 사용하는 가장 기본적인 이유는 위에서 본 것처럼 ¹반복 실행되는 코드의 주기를 사용자가 설정하여 제어하는 것입니다. 이 외에도 다른 이유로 보통 반복문에서는 반드시 루프 타임 지정을 권하고 있는데요. 우리가 사용하는 LabVIEW는 OS 위에서 실행되는 S/W라는 점과 연관지어 생각해보면 이해하기 쉽습니다. 제가 사용하고 있는 PC의 경우 Intel(R) Core(TIM) i7-8550 CPU @ 1.80 GHz     1.99 GHz와 16.0 GB RAM을 사용합니다. 

PC 시스템 정보

 

흔히 우리가 사용하는 PC는 작업 관리자 패널('Ctrl+Shift+ESC' 키)을 통해 CPU 코어 개수와 현재 사용중인 리소스 정보를 확인할 수 있습니다. 제 PC의 경우 0~7번까지 8개의 코어가 있네요.

CPU 논리 프로세스 : 8

 

다시 본문으로 돌아와서 설명을 이어나가자면 LabVIEW에서의 반복문(For문, While문)도 결국에는 CPU의 리소스를 할당받아서 실행되는데 '만약 타임 지정을 하지않았다면?' 해당 CPU의 코어 중 1개를 임의로 지정해서 가장 빠른 속도로 코드를 처리하게 됩니다. 즉, CPU 코어 1개의 리소스를 최대치로 끌어올려 사용하는 것이죠. 예시로 아래 이미지는 LabVIEW에서 단순 While 문 하나를 생성하고 실행하였을 때 CPU 리소스가 최대치로 올라가는 그래프입니다.

루프 타임없이 실행시 CPU 리소스 증가

따라서 루프 타임을 사용하는 다른 이유는 ²CPU 리소스를 필요한만큼만 효율적으로 사용하기 위해 타임 설정을 한다라고 보시면 되겠습니다.

 

루프 타임 지정 함수(기다림, 다음ms배수까지 기다림)를 이용한 CPU 리소스 최적화

 

루프 타임 확인하는 방법

[기다림(ms)] 또는 [다음 ms 배수까지 기다림] 함수를 사용해서 루프 타임을 지정하는 것까진 알았는데, 만일 사용자가 루프 타임을 체크해보려고 한다면 어떻게해야 할까요? 이해를 돕기 위한 예시를 하나 들어보자면 실제 코드 개발자는 루프타임을 0.5초(500ms)로 지정해두었는데 실행하였을 때 결과가 10배정도 차이나는 5초정도 후에 나타나는 것처럼 보이는 것입니다. 이런 현상에 대한 원인은 ¹특정 랩뷰 함수가 실행 불가한 상태에서 설정된 시간만큼 기다렸다가 에러를 출력하거나, ²장비를 제어하는 과정에서 소프트웨어 타임이 아닌 하드웨어 타임(장비쪽 타임에 의해 제어되는 경우)에 의해 제어되어 소프트웨어 설정이 무시되는 경우 등 다양하게 존재합니다. 이럴 때 개발자는 디버깅을 위해 루프 타임을 체크해볼 필요가 있는 것이죠. 루프 타임을 체크를 위한 코드 작성의 몇가지 예를 소개해보겠습니다.

 

① '[경과 시간 Express] 함수 + 시프트 레지스터' 사용

 타이밍 함수 팔레트 좌측 하단에보면 함수 테두리에 파란색으로 표시된 [경과 시간 Express] 함수를 사용하는 것입니다. 파란 테두리로 표시된 Express 함수는 랩뷰에서 상위 레벨의 함수로 사용자가 각 기능을 세부적으로 코딩할 필요없이 기본적으로 함수 자체에 대부분의 기능들이 만들어져있습니다. [경과 시간 Express] 함수에서 나오는 경과 시간(초) 출력 정보를 입·출력 시프트 레지스터 아래의 이미지처럼 와이어링하여 '현재 경과 시간 - 이전 경과 시간'을 만들어주도록 합니다.

[경과 시간 Express] 함수를 사용한 루프 타임 확인 코드

코드를 실행해보면 지정하였던 100ms에 근접하게 루프가 실행되고 있음을 확인할 수 있습니다. 정확하게 0.1초(100ms)로 측정되지 않고 1, 2ms가 차이나는 이유는 Windows OS의 특성상 그런 것입니다. (LabVIEW 외에도 여러 윈도우 서비스들이 OS상에서 실행되고 있기 때문에 Windows에서는 정확한 타임으로 제어가 어려움)

 

② '[Tick 카운트(ms)] 함수 + 시프트 레지스터' 사용

두 번째 방법은 [Tick 카운트(ms)] 사용하는 방법입니다. 우리가 사용하는 PC의 시간 정보는 보드 자체에서 생성되는 Clock을 기준으로 특정 레지스터에 시, 분, 초 등의 시간 정보를 저장하도록 되어있습니다. 예를 들어, 2.1 GHz의 클럭 소스를 가지는 PC의 경우 내부적으로 해당 클럭에 대해 카운팅을 하는데 2.1G만큼 카운팅이되면 PC가 '아, 1초가 지났구나.'라고 알 수 있는 것이죠. 랩뷰 [Tick 카운트(ms)] 함수는 이를 ms 단위로 틱 값을 출력해주는 것일 뿐 현재 생성 되고 있는 Clock의 틱정보를 반환해준다고 이해하시면 되겠습니다. 코드는 1번과 동일하고 함수만 [Tick 카운트]로 변경하면 됩니다. 함수 출력 단위가 ms인 점을 참고하여 100이라는 값이 출력되면 While 루프는 100ms마다 실행된다고 아시면 되겠습니다.

[Tick 카운트] 함수를 사용한 루프 타임 확인 코드

 

③ '[Tick 카운트(ms)] 함수 + 피드백 노드' 사용

루프 간 데이터를 전달하는 요소는 시프트 레지스터가 일반적이지만, 이와 유사한 기능을 하는 피드백 노드를 사용하는 것입니다. 화살표 모양에 따라 입출력 터미널이 좌측 또는 우측으로 설정되고 방향은 함수 우클릭 메뉴에 '방향 변경'으로 설정할 수 있습니다.

[피드백 노드]를 사용한 루프 타임 확인 코드

 

경과 시간 확인하는 방법

루프 타임을 확인하였던 것을 조금만 응용하면 [Tick 카운트(ms)] 함수를 이용해서 경과 시간을 체크하는 코드를 만들 수 있습니다. 코딩이 조금 어려우신 분들은 [경과 시간 Express] 함수를 바로 사용하면 되긴 하지만 조금씩 Raw Level 함수들로 코드를 짜는 습관을 들이는 것을 권장합니다. 방법은 루프 타임 체크와 동일하게 ¹While 루프, ²시프트 레지스터, ³[Tick 카운트(ms)] 함수를 가지고 기능을 만들며 자세히 보시면 루프 타임 때와는 다르게 출력 레지스터 터널쪽에 전달되는 와이어링의 위치만 아래의 이미지처럼 변경된 것을 알 수 있습니다.

[Tick 카운트(ms)] 함수를 이용한 경과 시간 확인 코드

 

[기다림(ms)] vs [다음 ms배수까지 기다림]

 '[기다림(ms)]과 [다음 ms배수까지 기다림] 함수 차이점은 무엇인가?'라고 하였을 때 대답을 하기 쉽지 않으실 수 있습니다. 포스팅에서도 루프 타임을 지정하는 함수 2개로 설명하였을 뿐 함수별 어떤 특징이 있는지는 소개하지 않았으니까요. 2개의 While 루프를 가지고 각각의 함수가 어떻게 작동하는지 하나씩 살펴보겠습니다.

 

[기다림(ms)] 함수

지정된 시간(ms)만큼 기다리고 ms 타이머의 값을 반환합니다. 2개의 While 루프가 있다고 가정해볼 때 VI를 실행하면 1번 루프와 2번 루프의 실행 시간이 실제로는 차이가 날 수 밖에 없습니다. 즉, 2개의 While 루프 모두 지정된 시간 주기로 실행이 되지만 Sync가 맞지 않는다고 볼 수 있겠네요. 대부분의 사용자들은 While 루프 2개만 생성하면 코드가 알아서 쓰레드로 실행되기 때문에 크게 이 부분에 대해서 고려하지 않을 수도 있습니다. 이미지로 표현해보면 아래의 이미지와 같습니다.

[기다림(ms)] 함수

 

[다음 ms 배수까지 기다림] 함수

ms 타이머의 값이 지정된 ms의 배수가 될 때까지 기다리고 실행됩니다. 아이콘을 보시면 흔히 음악 시간에서 볼 법한 메트로놈 아이콘으로 함수를 만들어 뒀지요? 시작 시점이 어디냐에 따라서 첫 시작 루프의 타임이 결정되고 이후에는 지정한 ms의 배수에 맞춰 소프트웨어상에서 실행되는 함수입니다. 실제 랩뷰 도움말(Ctrl+H)를 열어서 설명을 보면 이렇게 쓰여있습니다. "첫 번째 루프의 주기가 짧을 수 있습니다." 이 말을 위의 메트로놈 내용과 같이 생각해보면 100ms로 타임을 설정해두었다고 하였을 때 첫 실행 시작이 10ms 후라던지 20ms 후였다고 한다면, 최초 루프 실행 주기는 90ms 또는 80ms가 된다는 것입니다. 그 다음부터는 100ms 주기로 맞추어 돌아가는 것이죠. 따라서, [다음 ms 배수까지 기다림] 함수는 소프트웨어 상에서 함수를 사용해서 여러 루프들을 동기화를 맞출 수도 있는 장점도 가지고 있습니다.

 

 

알고 보면 더 재밌는 랩뷰..아이콘 모양에서도 직관적인게 드러나지요? 😀
랩뷰 타이밍 팔레트에 보면 시간정보를 나타내주는 타임스탬프 관련 함수들도 있으니 한번씩 도움말을 참조하여 써보시기 바랍니다.
이상으로 랩뷰 타이밍 관련 튜토리얼을 마치도록 하겠습니다.

 

 

 

 

 

 

 

※ 이 글이 도움이 되었다면 "🤍공감" 버튼을 클릭해주세요. 클릭 한번이 글 쓰는데 큰 힘이 됩니다.

 

공유하기

facebook twitter kakaoTalk kakaostory naver band