gFinger 손끝으로 만드는 세상

C# Program을 Real Time 성능에 가깝게





문제점


PLC를 사용하다가 보면 REAL-TIME 응답이 필요한 경우가 많이있습니다.

PLC의 경우 I/O 통신에서 극한적인 경우 1ms 정도, 보통 10~20ms 정도에 응답이 됩니다.

그러나 PC의 경우 하드디스크 억세스, 통신 연결 시도, 통신 실패, 가베지 컬렉션등이 발생하면 심한 경우 몇 초 이상의 딜레이, 지터 (JITTER)가 발생합니다.

PC를 PLC에 연결하여 사용하는 경우 PC는 OS 자체가 REAL-TIME이 아니기 때문에 속도를 요하는 통신 프로그램에서는 더욱 힘듭니다.

근본적으로 PC에 WINDOW는 REAL-TIME OS가 아니기 때문입니다.

따라서 REAL-TIME O/S하에서 PROCESS가 동작해야 해결될 문제입니다.

그래도 아래와 같은 코드를 넣으면 최대한 REAL-TIME에 가깝도록 되기는 합니다.

간단히 실험해 본 결과 10ms THREAD에서 시스템 부하를 조금씩 늘려 본 결과 10ms ~ 12ms 정도로 비교적 양호한 결과를 얻었습니다.



방법


아래와 같이 Program의 Priority를 올려주고 Thread의 Priority를 올려주는 방법을 사용하여 꽤 높은 Real-Time응답을 얻을 수 있었습니다.


 


///////////////////////////////////////////////
// For Real Time
//////////////////////////////////////////////
Process.GetCurrentProcess().PriorityBoostEnabled = true;
Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.RealTime;

///////////////////////////////////////////////////////////
// For Real Time
///////////////////////////////////////////////////////////
PLCopenThread.Priority = ThreadPriority.Highest;


참조링크

https://stackoverflow.com/questions/12050925/increasing-thread-and-process-priority-to-reduce-execution-time-for-a-processor


'컴퓨터 이야기 > c#' 카테고리의 다른 글

visual studio 빌드 후 이벤트  (0) 2018.11.29
Text File Save Dialog  (0) 2018.06.09
File Name을 선택해서 Text 파일 읽기  (0) 2018.06.09
How to move and resize a form without a border?  (0) 2018.06.09
Form을 Drag해서 이동  (0) 2018.06.09

다음은 중량을 측정하는 저울의 무게를 RS-232 통신으로 일정 시간 마다 읽어 Display하는 소스의 핵심 부분이다.

 

If comWeigher.PortOpen = True Then comWeigher.PortOpen = False
comWeigher.CommPort = 1
comWeigher.Settings = "9600,N,8,1"
comWeigher.PortOpen = True  '현재 포트를 연다.
Text2.Text = comWeigher.PortOpen
Timer1.Enabled = True
Timer1.Interval = 5000 ' 5 sec
buffer$ = ""

Do
   DoEvents
   buffer$ = buffer$ & comWeigher.Input
   Position = InStr(1, buffer$, "#0001    ", vbBinaryCompare)
   If Position > 0 Then
      buffer$ = Mid(buffer$, Position)
      If InStr(1, buffer$, "Kg", vbBinaryCompare) Then
         result1 = Mid$(buffer$, 10, 8)
         result = ""
         For i = 1 To Len(result1)
            If Mid(result1, i, 1) >= "0" And Mid(result1, i, 1) <= "9" Then
               result = result + Mid(result1, i, 1)
            End If
         Next i
         Exit Do
      End If
   End If
   Text1.Text = buffer$
Loop While (Timer1.Enabled = True) ' 5 sec 이후에는 timer 가 중지 됨
comWeigher.PortOpen = False  ' 포트를 닫는다.
Text2.Text = comWeigher.PortOpen
Text1.Text = Val(result)
Timer1.Enabled = False