728x90

산업 프로토콜을 아두이노에 연결해보자! – IoT와 OPC UA의 연결고리 만들기

아두이노는 가볍고 빠르게 센서 데이터를 처리할 수 있어, 소형 자동화, IoT 실험, 데이터 수집용 게이트웨이로 자주 활용됩니다.
하지만 산업용 시스템(OPC UA 기반 PLC, SCADA 등)과 직접 연동하려면 다소 복잡한 설정이 필요하죠.

이 글에서는 아두이노를 OPC UA 시스템과 연동하는 2가지 접근 방식을 소개하고, 실제 구현에 필요한 설정과 노하우까지 정리해드립니다.

  • MCU 보드: Arduino Uno / Mega / ESP32 (ESP 추천)
  • 연동 방식:
    1. 아두이노 → 중계 서버 → OPC UA Server
    2. 아두이노 직접 OPC UA Client (ESP32+라이브러리 활용 시 가능)
  • 통신 프로토콜: OPC UA (opc.tcp://...)
  • 사용 환경:
    • 아두이노 IDE + 센서 코드
    • 중계용 Python/Node.js 서버 또는 ESP32 자체 OPC UA 구현
  •  

🧩 구조별 연동 방식 비교

방식 구성 장점 단점
중계 서버 방식 아두이노 → 시리얼 or MQTT → 중계 서버(Python) → OPC UA 구조 단순, 구현 쉬움 실시간성 다소 낮음
직접 OPC UA Client ESP32에서 OPC UA 요청 전송 실시간성 좋고 구조 간단 구현 복잡, 메모리 제약

1️⃣ 중계 서버 방식 (추천 접근)

📦 구성도

 

🧪 아두이노 코드 예제 (센서 값 전송)

// 예: 온도 센서 데이터 Serial로 전송
void loop() {
  int temp = analogRead(A0);
  Serial.println(temp);
  delay(1000);
}

🐍 Python 중계 서버 예제 (opcua 라이브러리 사용)

 
from opcua import Server
import serial

# OPC UA 서버 생성
server = Server()
server.set_endpoint("opc.tcp://0.0.0.0:4840/")
node = server.register_namespace("ArduinoData")
objects = server.get_objects_node()
sensor_obj = objects.add_object(node, "TemperatureSensor")
temp_val = sensor_obj.add_variable(node, "Temperature", 0.0)
temp_val.set_writable()

# 시리얼 연결
arduino = serial.Serial('COM3', 9600)

server.start()
try:
    while True:
        data = arduino.readline().decode().strip()
        temp_val.set_value(float(data))
except KeyboardInterrupt:
    server.stop()

📌 이 방식은 실시간 센서 데이터를 OPC UA 서버로 전달할 수 있어, SCADA, Node-RED, UA Client와 연동 용이합니다.


2️⃣ ESP32 직접 OPC UA 연동 (고급)

  • ESP32는 WiFi 지원 + 메모리 여유 → OPC UA 통신 가능
  • OPC UA 클라이언트 구현 라이브러리 필요
    • freemodbus + libuaclient (C++)
    • 또는 ESP32 + Arduino core + OPC UA 구현체 (매우 제한적)

❗️ 하지만 OPC UA는 메모리/성능 요구가 높아, 직접 구현보다는 중계 게이트웨이 구조가 현실적입니다.


🛠️ 실무 노하우 & 팁

항목
아두이노 ↔ Python 통신 시리얼 통신은 안정성 높지만, MQTT로 확장도 고려 가능
Node-RED 연동 Python 대신 Node-RED + OPC UA 노드로 중계 가능
OPC UA 서버 주소 opc.tcp://localhost:4840/ → 실제 PLC 연동 시 외부 IP 사용
인증서 이슈 테스트 시 SecurityPolicy.None 사용, 운영 시 인증서 필요
SCADA 연동 UA 클라이언트로 UAExpert, Ignition, WinCC 등에서 실시간 시각화 가능

 

 

728x90
728x90

GX Works3로 설정하고, Visual Studio로 바로 연동하세요!

Mitsubishi MELSEC PLC는 일본 자동화 업계의 대표 주자입니다.
기존엔 전용 프로토콜(MC, SLMP 등)만 지원했지만, 최신 iQ-R/iQ-F 시리즈는 OPC UA 서버 기능을 내장하면서 IT와 OT 통합의 중심에 섰습니다.

이 글에서는 C# 기반 OPC UA 클라이언트를 활용해 MELSEC PLC와 통신하는 방법을 소개합니다.
GX Works3에서 OPC UA 설정을 마치고 나면, Visual Studio에서 노드값을 읽고 변경 이벤트를 실시간으로 받을 수 있습니다

  • 통신 프로토콜: OPC UA (opc.tcp:// 포트 49320 등)
  • 개발 언어: C# (.NET 6 이상)
  • 개발 환경: Visual Studio 2022 이상
  • 사용 라이브러리: OPCFoundation.NetStandard.Opc.Ua
  • 주요 기능:
    • GX Works3에서 설정한 태그(NodeId) 연동
    • 실시간 변경 감지 (Subscription)
    • 인증서 기반 보안 통신 구성 팁 제공

1. 미쯔비시 MELSEC OPC UA 기본 설정

지원 모델 예시:

  • iQ-R Series: R04CPU-P, R08ENCPU 등
  • iQ-F Series: FX5U (OPC UA 옵션 모듈 필요)
  • Q 시리즈: Q03UDVCPU + QJ71E71 TCP/IP 모듈 + OPC UA 게이트웨이 필요

기본 설정 방법 (GOT or GX Works3 사용):

  • OPC UA 기능 활성화
  • 통신 포트 설정 (opc.tcp://192.168.0.10:49320)
  • 사용자 인증 or Anonymous 설정
  • 보안 정책 선택 (None, Basic256 등)
  • Server 인증서 등록 (클라이언트에서 신뢰 필요)

2. C# OPC UA 통신 – 기본 예제

Mitsubishi PLC도 LS산전과 동일하게 OPC Foundation 라이브러리 사용 가능. 핵심 코드는 비슷하지만, 노드 네이밍 규칙이 제조사마다 다릅니다.

 
var endpointURL = "opc.tcp://192.168.3.101:49320"; // Mitsubishi PLC OPC UA 주소
var nodeId = "ns=4;s=Channel1.Device1.D100"; // D100 주소에 연결된 태그

노드 ID 규칙은 OPC UA Gateway 또는 Mitsubishi의 설정 툴에서 확인 가능.


3. 예제 코드 – 값 읽기

 
var session = await Session.Create(config, endpoint, false, "MELSEC Client", 60000, null, null);
Console.WriteLine("미쯔비시 OPC UA 연결 성공.");

string nodeId = "ns=4;s=Channel1.Device1.D100"; // D100 메모리 주소
DataValue value = session.ReadValue(nodeId);
Console.WriteLine($"D100 현재값: {value.Value}");

4. 예제 코드 – Subscription 이벤트 처리

 
var subscription = new Subscription(session.DefaultSubscription)
{
    PublishingInterval = 1000
};

var monitoredItem = new MonitoredItem(subscription.DefaultItem)
{
    StartNodeId = "ns=4;s=Channel1.Device1.D100",
    DisplayName = "D100",
    SamplingInterval = 500
};

monitoredItem.Notification += OnValueChanged;
subscription.AddItem(monitoredItem);
session.AddSubscription(subscription);
subscription.Create();

private static void OnValueChanged(MonitoredItem item, MonitoredItemNotificationEventArgs e)
{
    foreach (var value in item.DequeueValues())
    {
        Console.WriteLine($"D100 변경됨: {value.Value}");
    }
}

5. 실무 노하우

항목 설명
포트 변경 OPC UA 포트 기본값이 49320으로, 방화벽에서 열어야 함
인증서 정책 Mitsubishi는 Client 인증서 신뢰 필요. CertificateStore 경로 확인
태그 구조 OPC UA 게이트웨이나 GX Works3로 설정한 태그 구조를 반드시 확인
보안 정책 테스트 시 SecurityPolicy.None으로 설정, 운영환경에서는 TLS 권장
통신 오류 대처 접속 지연 or Bad Status 발생 시, 재시도 또는 KeepAlive 체크 필수

6. Mitsubishi 노드 구조 확인 팁

  • MELSOFT OPC UA Configurator 사용하여 노드 ID 구조 확인
  • iQ-R의 경우 실제 노드 ID는 ns=4;s=Channel1.Device1.D100처럼 구성됨
  • GX Works3에서 변수 이름을 등록하면 심볼 기반 노드 사용 가능

https://www.youtube.com/watch?v=kUUtLGdolsE

 

 

728x90
728x90

 

  • 목표: LS산전 PLC와 C# 앱 간의 OPC UA 통신 기본 예제 구현
  • 언어/환경: Visual Studio, C#, .NET Framework 또는 .NET 6 이상

OPC UA란?

OPC UA (Open Platform Communications Unified Architecture)는 산업 자동화 환경에서 기기 간 데이터 통신을 위한 플랫폼 독립형, 확장성 있는 표준 프로토콜입니다.

OPC UA는 기존 DCOM 기반 OPC Classic의 한계를 극복하며, 보안, 플랫폼 독립성, 확장성을 갖춘 통신 방식으로 대부분의 PLC 제조사에서 지원합니다.

1. LS산전 OPC UA 기본 설정 확인

LS ELECTRIC PLC (예: XGT 시리즈)는 OPC UA 서버 기능이 내장된 모델이 있으며, 별도의 OPC UA 서버 보드GLOFA-GMWIN 등의 툴 설정이 필요합니다.

kepware 채널 설정


필수 조건
:

  • LS PLC에 OPC UA 기능이 활성화되어 있어야 함 / 이더넷 포트  <–> 컴퓨터, 공유기에 랜으로 연결
  • IP 주소, 포트 (기본: opc.tcp://<IP주소>:4840) 확인
  • 서버 인증서 설정 허용 또는 신뢰 인증서 사전 등록

2. C# OPC UA 클라이언트 라이브러리 설치

C#에서는 OPC Foundation의 OPC UA .NET Standard 라이브러리를 사용합니다.

NuGet 패키지 설치:

Install-Package OPCFoundation.NetStandard.Opc.Ua
 

또는 .NET CLI 사용 시:

dotnet add package OPCFoundation.NetStandard.Opc.Ua

3. 기본 통신 예제 코드 (데이터 읽기)

다음은 LS산전 OPC UA 서버에 연결하여 노드 값을 읽는 간단한 예제입니다.

 
using System;
using System.Threading.Tasks;
using Opc.Ua;
using Opc.Ua.Client;
using Opc.Ua.Configuration;

namespace LsOpcUaClient
{
    class Program
    {
        static async Task Main(string[] args)
        {
            // 애플리케이션 구성
            var config = new ApplicationConfiguration()
            {
                ApplicationName = "LSOpcUaClient",
                ApplicationType = ApplicationType.Client,
                SecurityConfiguration = new SecurityConfiguration
                {
                    ApplicationCertificate = new CertificateIdentifier(),
                    AutoAcceptUntrustedCertificates = true, // 테스트용
                },
                TransportConfigurations = new TransportConfigurationCollection(),
                TransportQuotas = new TransportQuotas { OperationTimeout = 15000 },
                ClientConfiguration = new ClientConfiguration { DefaultSessionTimeout = 60000 }
            };

            await config.Validate(ApplicationType.Client);

            // OPC UA 엔드포인트 설정
            var endpointURL = "opc.tcp://192.168.0.100:4840"; // PLC의 OPC UA 주소 입력
            var endpointDescription = CoreClientUtils.SelectEndpoint(endpointURL, useSecurity: false);
            var endpointConfiguration = EndpointConfiguration.Create(config);
            var endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration);

            // 세션 생성
            var session = await Session.Create(config, endpoint, false, "LS OPC UA Client", 60000, null, null);
            Console.WriteLine("OPC UA 세션 연결 완료.");

            // 노드 값 읽기
            string nodeId = "ns=2;s=TAG1"; // PLC의 실제 노드 ID 입력
            DataValue value = session.ReadValue(nodeId);
            Console.WriteLine($"노드 값: {value.Value}");

            // 세션 종료
            session.Close();
            Console.WriteLine("세션 종료 완료.");
        }
    }
}

🔍 주요 설명:

  • endpointURL: LS PLC의 IP와 포트를 입력
  • nodeId: LS PLC에 정의된 태그 (예: s=DB1.Tag1 또는 ns=2;s=MyTag)
  • AutoAcceptUntrustedCertificates = true: 인증서 자동 수락 (실제 운영에선 보안 정책 필요)

4. 예제 실행 전 체크리스트

항목확인
PLC의 OPC UA 서버 활성화 여부
포트 방화벽 허용 (기본 4840)
PLC에 등록된 노드 ID 확인
인증서 정책 확인 및 설정


5. [실무 팁] 데이터 변경 이벤트 처리 (Subscription 방식)

OPC UA는 클라이언트가 주기적으로 값을 읽는 Polling 방식 외에도, 서버에서 값 변경 시 자동 통지받는 Subscription 방식을 지원합니다.
이를 활용하면 다음과 같은 이점이 있습니다:

✅ Subscription 방식의 장점

  • 실시간 데이터 반영 가능
  • CPU 부하 절감 (Polling 대비)
  • 산업 현장 이벤트 기반 제어에 적합

예제: 값 변경 시 자동 알림 받기

// Subscription 및 이벤트 핸들링 예제
var subscription = new Subscription(session.DefaultSubscription) 
{
    PublishingInterval = 1000 // 1초 간격으로 변경사항 체크
};

// 모니터링할 노드 지정
var monitoredItem = new MonitoredItem(subscription.DefaultItem)
{
    DisplayName = "MyTag",
    StartNodeId = "ns=2;s=TAG1", // LS PLC의 노드 ID
    SamplingInterval = 500,      // 샘플링 주기 (ms)
    QueueSize = 10,
    DiscardOldest = true
};

// 변경 시 이벤트 핸들러 등록
monitoredItem.Notification += OnValueChanged;

// 구독 항목에 추가하고 세션에 등록
subscription.AddItem(monitoredItem);
session.AddSubscription(subscription);
subscription.Create();

 

콜백 함수 정의

private static void OnValueChanged(MonitoredItem item, MonitoredItemNotificationEventArgs e)
{
    foreach (var value in item.DequeueValues())
    {
        Console.WriteLine($"[{DateTime.Now}] {item.DisplayName} 변경됨: {value.Value}");
    }
}

6. 실무 노하우: Subscription 구현 시 주의점

설명
1. PublishingInterval 과 SamplingInterval 적절 조절 너무 짧게 잡으면 불필요한 이벤트가 많아지고 성능 저하
2. QueueSize 조정 네트워크 지연 시 데이터 누락 방지
3. Network Loss 대비 재접속 로직 구현 KeepAlive 체크 및 세션 오류 시 재연결
4. 노드가 Null 또는 Bad Status인 경우 체크 일부 PLC에서는 데이터 초기화 전 Null 또는 StatusCode.Bad 리턴
5. 인증서 신뢰 문제로 Subscription 실패 가능 개발 중 AutoAcceptUntrustedCertificates = true 설정으로 임시 우회

고급 확장: 알람 연동

  • LS PLC에서 설정한 특정 조건 (예: 알람 태그)이 True로 바뀌는 순간만 감지하여 UI에 경고 표시
  • 예: ns=2;s=Alarm_MotorOverheat가 True → 팝업 or 로그 기록
if ((bool)value.Value == true)
{
    Console.WriteLine("🔥 모터 과열 경고!");
}

이처럼 Subscription 기반 구조는 SCADA 시스템, 디지털 트윈, AI 기반 제어 시스템에서 핵심 요소로 사용됩니다.

* 전용 모듈이 없는 경우, BridgeWare의 LSE OPC Server를 사용하여 LS산전 PLC(Glofa, XGT, Master-K)와 데이터를 수집 가능 / 모드버스 TCP 이용

728x90

+ Recent posts