프로젝트 설계, 관리

안녕하세요!

PC에서 PLC 제어 프로그램 작성 중 궁금한 점이 생겼는데요.
처음 시도해보는 거라 선배님들의 조언을 듣고 싶습니다.

보통 PLC와 통신할 때는 특정 주소부터 원하는 사이즈(블록 크기)만큼 읽고 쓴다고 하더군요.

그래서 전역으로 읽기(Read), 쓰기(Write) 메모리 공간과, PLC에서 상태를 읽어내는 Read Thread, 쓰는 Write Thread 두 개를 상시로 구동하도록 만들었습니다.

특정 클래스에서 ‘Read’ 메모리를 참고하여 상태가 바뀐 것을 확인하고, PLC에 써야 할 때는 ‘Write’ 메모리에 값을 변경하도록 구현했습니다. 동작에는 전혀 문제가 없었는데요.

한편으로는 PLC 값 변경이 필요할 때마다, PLC에 직접 접근해서 Write 작업을 하는 것이 맞는지 의문이 들기도 합니다(이 경우 PLC Write Thread를 생성하지 않음).

느낌으로는 비동기, 동기 방식 같은데… 어떻게 구현하는 것이 안정적인지, 상관이 없는지 조언을 듣고 싶습니다.

읽어주셔서 감사합니다 :slight_smile:

4개의 좋아요

클래스의 클라이언트가 UI 스레드라면, 비동기로 처리하시고, 아니라면, 동기 방식도 고민해보세요.

그런데, 비동기로 처리하는 경우, 데드락이 걸리지 않게, 관리해줘야 합니다.
아래 동영상을 참고 하세요.

2개의 좋아요

값변경이 필요하지만 PLC까지 접근할 필요가 없다는건,
짧은시간내의 여러 값변경중의 최종값에 대해서만 PLC에 반영하면 된다는 뜻인가요?
여러 비동기중의 일부 동기적인 처리가 필요하시다면 TPL Dataflow를 적용해보세용

2개의 좋아요

모두 답글 달아주셔서 감사합니다!

제가 사용하는 PLC는 미쯔비시이며 MX Component 라이브러리를 사용해서 Read, Write를 사용하고 있습니다.

제가 질문을 애매하게 드린 것 같습니다.

PLC에서 항상 값을 읽어내는 스레드와 PLC에 항상 값을 쓰는 스레드, 이렇게 두 개를 운영하는 것이 좋을 지, 필요할 때마다 PLC에 접근해서 직접 쓰는게 좋을지 궁금했습니다.

그림에서는 'Class’를 1개로 표현했지만 사실 여러 군데에서 PLC에 Write해야 합니다.
그래서 개별적으로 PLC에 접근해서 Write할 지, PLC Write 스레드가 돌고 있으니 공통 메모리의 값만 변경하는게 좋을 지 고민하던 것이었습니다.

2개의 좋아요

n개의 PLC Write시(영역이 굉장히 많이 나뉘어 있어서 빈번하다면) 일괄로(변경점이 있는 번지 기준으로 최대 메모리 영역만큼)처리 하기 위해 공통 메모리로 많이 썼습니다.

2개의 좋아요

답변 주셔서 감사합니다.

제가 명확하게 이해가 되지 않는 부분이 있어서 아래 그림으로 추가 설명 드리겠습니다.

  1. PLC와 통신하는 _plc 객체를 생성하고, 필요할 때 마다 직접 Write 함수를 호출하여 특정 주소의 값을 변경하는 방법입니다.
    image

  2. 특정 스레드에서 PLC 객체가 있고, _memory를 특정 주소에 계속 쓰고만 있습니다. 값 변경이 필요하면 _memory의 특정 번지 값을 변경하는 방법입니다.
    image

두 방법 모두 잘 동작하는 것은 확인했습니다. 하지만 어떤 방법이 더 나은지(?) 경험이 없다 보니 고민 중인 부분입니다.

읽어주셔서 감사합니다. 조언 부탁드립니다!

2개의 좋아요

1:1 I/F나 처리 속도가 고속을 요구 하지 않을 경우 1번방법 문제 없을 것으로 보이나, N개처리 및 고속의 경우 2번 방법으로 처리하는 편이 좋습니다.

2개의 좋아요

어떤 방법이 더 나은 방법인지는 목적에 따라 다를 것 같습니다.

  1. 일반적인 방법이고 필요한 값만 읽거나 쓰므로 빠른 동작성을 가집니다.
  2. PLC와 제어/모니터 프로그램 간의 데이터 동기 목적으로 사용할 수 있는 방법입니다. 메모리 배열에 읽고 쓰는 것으로 PLC 제어를 할 수 있어서 그런 면에서는 편리한 방법일 수 있습니다. 특히 모니터링 정보가 있을 경우 유용한 방법일 수 있습니다.

장/단점

  • 1의 경우

    • 장점: 가장 일반적인 방법, 2에 비해 작은 트래픽, 동시적 오동작 여지 적음
    • 단점: 2에 비해 사용이 번거로울 수 있음
  • 2의 경우

    • 장점: 매핑된 배열을 읽고 쓰는 것으로 PLC 제어/모니터링을 할 수 있음. 모니터링 시 편리
    • 단점: 1에 비해 높은 트래픽, 폴링 간격에 따라 이전 값을 읽을 수 있음
3개의 좋아요

아마 2번 방법은 내부적으로 처리할 때, 주기적으로 Write를 일괄적으로 하려고 하는 것 같은데요.

다만 올려주신 내용에서는 memory 배열을 어떻게 처리하는지에 대한 소스코드는 없다보니 판단이 어렵네요.
만약 memory[0] ~ memory[999]까지를 주기적으로 block write하는 방식으로 되어 있다면 변경 내용이 한꺼번에 많이 생기지 않는 이상 리소스 낭비입니다. 1번 방법이 차라리 나을지도 모르겠으나, 이마저도 빈도가 높다면 좋은 방법은 아닐거구요.

미쯔비시 프로토콜에 보시면 복수의 메모리를 Write하는 함수가 있습니다. (random write를 한꺼번에 여러개)
그걸 호출하시는게 가장 좋아보입니다.

큰 흐름은 2번을 유지하시되 (Read,Write가 구분되어 있고, deadlock이나 디버깅 상의 약간이라도 편의를 위한다면)
변경하고 싶은 memory번지와 값을 Pool에 여러개 저장해놨다가 빠른 주기로 random write 하는게 좋아보입니다.
단, 한꺼번에 많은 내용이 자주 바뀐다면 Block write가 낫구요.

2개의 좋아요

shared memory를 한번 고민해보셔도 좋을 것 같아요

답변 달아주신 많은 분들께 감사 드립니다~!
두 가지 방법으로 경험을 쌓아보겠습니다 :slight_smile: