본문 바로가기
PLC 프로그래밍/MELSEC PLC

MX-Link 사용하기 [3]

by lemy 2019. 3. 25.
반응형



MX-Link 사용하기 [3]


출처: melsec PLC 동호회(http://cafe.daum.net/melsec)의 회색늑대 (grizlupo)님의 "MX-Link 사용하기" 연재글 입니다. 

회색늑대 (grizlupo)님의 통신 이야기중 MX-Link에 관련하여 전반적으로 이해 할 수 있는 좋은 글입니다. 총 3회 분량의 글 입니다.


이 번에는 디바이스에 값을 쓰는 mdSend 함수를 사용해 보겠습니다. MMSCL32 모듈에서 mdSend 선언을 확인해 보면 msReceive와 그의 같은 인수를 요구합니다.


ByVal path As Long,

ByVal Stno As Integer,

ByVal Devtyp As Integer,

ByVal devno As Integer,

size As Integer,

buf As Any


이건 별로 설명할 것도 없네요. msSend 자체는 별 다른 설명이 필요 없을 것 같습니다.

일 단 한 번 사용해 보겠습니다.


Public Sub send_test()

Dim result As Integer

Dim path As Long


result = mdOpen(1, 0, path)

If result <> 0 Then

MsgBox "mdOpen 실패!: " + Str(result)

If result <> 66 Then

Exit Sub

End If

End If


Dim buf(0 To 9) As Integer

buf(0) = 1

buf(1) = 2


result = mdSend(path, 255, DevD, 100, 10 * 2, buf(0))

If result <> 0 Then

MsgBox "mdSend 실패!: " + Str(result)

End If


result = mdClose(path)

If result <> 0 Then

MsgBox "mdClose 실패!: " + Str(result)

End If

End Sub


이렇게 작성하시고, 실행해 보면 D100과 D101에 각각 1과 2가 기록되고, 나머지 D102에서 D109까지는 0이 됨을 확인할 수 있을 겁니다. 물론 D102 이후는 원래가 0이었을 테니까 기록된다는 느낌을 못 받겠지만요 ^^ 참 쉽죠!


mdReceive나 mdSend만 사용해도 대부분의 필요한 기능을 충분히 수행하실 수 있습니다.


예제에서는 워드 디바이스인 D를 사용했지만 M, B, X, Y 같은 비트 디바이스도 이 함수들을 이용해서 읽고 쓸 수 있습니다. 

단, 최소 8비트 즉, 바이트 단위로 읽힌다는 것입니다. 그 리고 쓸 때도 마찬가지로 최소 8비트를 한꺼번에 기록하게 됩니다.


비트 디바이스를 다룰 때는 또 한가지 읽거나 쓸 디바이스의 시작번지가 8의 배수여야 한다 는 것입니다. 즉, M0 부터 M7 까지를 읽을 수는 있지만 M1 부터 M8 까지를 읽을 수는 없습 니다. 

이런 경우에는 M0에서 M15가지를 읽어야 합니다. 터치 스크린을 사용하다 보면 이런 식의 제한이 있는 것을 보셨을 겁니다.


바이트 경계를 맞추지 않고, 8의 배수가 아닌 비트 디바이스를 시작번지로 해서 읽거나 쓰 려고 할 때, mdReceive와 mdSend는 -2 에러가 발생합니다. 

Device number error 라고 되어 있고, 그 아래로 비트 디바이스를 사용하는 경우 8 어쩌구 저쩌구 하는 얘기가 함께 적혀 있습니다. 지금까지 설명한 것처럼 시작번지에 대해서 바이트 경계를 지키라는 것입니다. 물론 -2라는 에러는 디바이스 번호가 정말로 잘못된 경우에도 생깁니다. 

가령 존재하지도 않는 지나치게 큰 시작번지를 준다든지 하면 생깁니다. D20000을 읽으려고 하면 -2번 에러가 생깁니다.


반대의 경우 즉, 워드 디바이스를 읽으면서 크기를 2의 배수가 되지 않게 설정하는 경우 -5 에러가 생깁니다. 찾아보면 Size Error 입니다. 이미 설명 드린 것처럼 크기는 바이트 단위로 주어집니다. 때문에 한 워드를 읽을 때는 반드시 크기를 2로 하셔야 합니다.


이런 정도면 이제 디바이스를 읽고 쓰는 데 별 문제가 없을 것 같습니다.

하지만 디바이스에 값을 쓰는 것을 다루는 만큼 두 함수를 더 살펴보겠습니다. mdDevSet과 mdDevRst입니다. 

함수 이름에서도 느껴지시겠지만 이것은 비트 디바이스의 값을 1 혹은 0으 로 만드는 함수입니다. mdSend로 값을 기록하면 되는데 왜 굳이 이런 함수가 필요할까요?


필요 없다고 생각하시는 분들도 계실 겁니다. 그리고 이런 함수 없이도 mdSend만으로도 적 절하게 비트 조작을 하면 한 비트만을 조작하는 것이 얼마든지 가능하니까요. 즉, M0에서 M7 사이의 비트 중에서 M2만을 ON 시키고 싶다면 기존의 값을 읽어서 다른 값들이 현재 무엇인지를 알아낸 다음에 그중에서 M2만을 ON 시킨 다음에 다시 기록하면 원하는 기능을 얻을 수는 있습니다.


하지만 mdSend가 최소한 8비트를 한꺼번에 기록한다는 점은 여전히 문제의 소지를 안고 있 습니다. 즉, mdSend를 사용하는 경우에는 M2를 ON 시키기 위해서는 기존의 값을 반드시 읽고 그것을 적절하게 고쳐서 다시 기록해야 합니다. 


문제는 기존의 값을 읽은 후에 다시 기 록하기 전에 그 값이 바꿔 버린 경우입니다. 그 순간 바뀐 사실을 모르는 mdSend는 엄청난 실수를 하게 되는 것입니다. 

바로 이런 염려가 있는 곳에 mdDevSet과 mdDevRst를 사용합니 다. 그리고 이 두 함수는 한 비트를 기록하는 용도 입니다. 한 비트 만을 읽어드리는 mdDevGet 같은 함수는 없습니다.


mdDevSet이나 mdDevRst 같은 함수를 사용하지 않으려면 PC가 값을 기록하는 영역에 대해서 는 PLC가 절대로 값을 수정하지 않도록 하는 원칙을 정하는 경우도 맞습니다. 읽기 영역과 쓰기 영역을 엄격하게 구분하면 앞서와 같은 문제는 발생하지 않게 됩니다.


이런 상황은 굳이 MX-Link를 활용하는 차원이 아니더라도 PC나 다른 장비들과 인터페이스를 하는 과정에서 비슷한 문제에 부딪히는 경우가 있습니다. 

대부분의 경우 그 해답은 역시 읽기 영역과 쓰기 영역을 엄격하게 구분하는 것입니다.

mdDevSet이나 mdDevRst에 대한 예제를 만들지는 않겠습니다. 직접 해 보십시요.


===================================================================================


Device 읽기/쓰기 샘플 소스(VBA)


Option Explicit                         'All variables are declared clearly.

'/****************************************************************************/

'/*  <MACRO>    DeviceRead_Click                                               */

'/*  [[[Processing of DeviceRead button]]]                                       */

'/****************************************************************************/

Sub DeviceRead_Click()

    Dim lRet As Long                   'Return value

    Dim idata(10) As Integer           'Read device values

    Dim icnt As Integer                'Work count

        

    On Error GoTo Error 'Error Handler


    'Setting the property (LogicalStationNumber) is set.

     Worksheets("DeviceRead-Write").ActUtlType1.ActLogicalStationNumber = Val(Worksheets("DeviceRead-Write").Cells(1, 2).Value)

    'Open communication.

    lRet = Worksheets("DeviceRead-Write").ActUtlType1.Open()

    'When abnormally ending.

    If (lRet <> 0) Then

        'The troubleshooting message corresponding to the error code is displayed.

        ErrorViewMessage (lRet)

        Exit Sub

    End If

    

    'After reading D10-D19, it displays on a cell.  

    'The ReadDeviceBlock method is executed.

    lRet = Worksheets("DeviceRead-Write").ActUtlType1.ReadDeviceBlock2("D10", 10, idata(0)) '"D0"


    'When read-out is successful.

    If (lRet = 0) Then

        'When normally ending.

        'The read device value is set as a cell.

        With Worksheets("DeviceRead-Write")

            For icnt = 0 To 9

                .Cells(6 + icnt, 4).Value = idata(icnt)

            Next icnt

        End With

        MsgBox "DeviceRead" & vbLf & "Success!!"

        

    Else

        'When read-out goes wrong.

        'The troubleshooting message corresponding to the error code is displayed.

        ErrorViewMessage (lRet)

    End If

    

    'Close communication.

    lRet = Worksheets("DeviceRead-Write").ActUtlType1.Close()

    

    Exit Sub


Error:  'Exception processing.

    'Close communication.

    lRet = Worksheets("DeviceRead-Write").ActUtlType1.Close()

    'An error is displayed.

    MsgBox Error$(Err), vbCritical

    End

    

End Sub


'/****************************************************************************/

'/*  <MACRO>    DeviceWrite_Click                                               */

'/*  [[[Processing of DeviceWrite button]]]                                       */

'/****************************************************************************/

Sub DeviceWrite_Click()

    Dim lRet As Long                   'Return value

    Dim szData As String               'Device name

    Dim idata(10) As Integer           'Write device values

    Dim icnt As Integer                'Work count

        

    On Error GoTo Error 'Error Handler


    'Setting the property (LogicalStationNumber) is set.

    Worksheets("DeviceRead-Write").ActUtlType1.ActLogicalStationNumber = Val(Worksheets("DeviceRead-Write").Cells(1, 2).Value)

    'Open communication

    lRet = Worksheets("DeviceRead-Write").ActUtlType1.Open()

    'When abnormally ending.

    If (lRet <> 0) Then

        'he troubleshooting message corresponding to the error code is displayed.

        ErrorViewMessage (lRet)

        Exit Sub

    End If

    

    'Write the cell data of D10-D19 to a PLC device.   

    'Store in the device value (idata) which is to be written in the data of a cell.

    With Worksheets("DeviceRead-Write")

        For icnt = 0 To 9

            idata(icnt) = CInt(.Cells(6 + icnt, 7).Value)

        Next icnt

    End With


    'Write a value to a PLC device.

    szData = "D10" & vbLf & "D11" & vbLf & "D12" & vbLf & "D13" & vbLf & "D14" & vbLf & "D15" & vbLf & "D16" & vbLf & "D17" & vbLf & "D18" & vbLf & "D19"

    lRet = Worksheets("DeviceRead-Write").ActUtlType1.WriteDeviceRandom2(szData, 10, idata(0))


    'When writing is successful

    If (lRet = 0) Then

        MsgBox "DeviceWrite" & vbLf & "Success!!"


    Else

        'When writing goes wrong.

        'The troubleshooting message corresponding to the error code is displayed.

        ErrorViewMessage (lRet)

    End If

    

    'Close communication.

    lRet = Worksheets("DeviceRead-Write").ActUtlType1.Close()

    

    Exit Sub


Error:  'Exception processing.

    'Close communication.

    lRet = Worksheets("DeviceRead-Write").ActUtlType1.Close()

    'An error is displayed.

    MsgBox Error$(Err), vbCritical

    End

    

End Sub


'/****************************************************************************/

'/*  <MACRO>    ViewErrorMessage                                             */

'/*  [[[Processing of an error message]]]                                         */

'/****************************************************************************/

Sub ErrorViewMessage(rtncode)

    Dim lRet As Long            'Return value

    Dim szMessage As String     'Troubleshooting message


        'Get a troubleshooting message from ActSupportMsg control.

        'Execute the ReadDeviceBlock method.

        lRet = Worksheets("DeviceRead-Write").ActSupportMsg1.GetErrorMessage(rtncode, szMessage)

  

      'When it succeeds in GetErrorMessage,

        'Display a troubleshooting message in the message box.

        If lRet = 0 Then

            'When GetErrorMessage is successful

            'Display a troubleshooting message.

            MsgBox szMessage, vbExclamation

   

     Else

            'When GetErrorMessage goes wrong.

            'Display an error code.

            MsgBox "Errorcode = " & Hex(lRet) & "[Hex]"

        End If


End Sub






반응형

댓글