저가형 PLC 대안을 직접 만든 이유

산업용 PLC는 현장에서 흔합니다. 미쓰비시, 지멘스, 로크웰 — 다 안정적이고 검증된 제품입니다. 그런데 소규모 제어용으로 PLC 한 대 사려면 30만원. 부속 케이블, 통신모듈, 프로그래밍 소프트웨어까지 더하면 50만원이 쉽게 넘어갑니다.

소형 자동화 / 교육용 / R&D 시제품 / 메이커 프로젝트에는 너무 과한 가격이고 너무 닫힌 생태계입니다. Modbus 연동 하나 하려면 RTU/TCP 슬레이브 모듈을 추가로 사야 하고, 클라우드로 데이터 보내려면 게이트웨이를 따로 달아야 합니다.

ZPi Controller 는 그래서 만들었습니다. 라즈베리파이 Zero 2 W + 4입력/4릴레이 보드 + .NET 9 + Blazor 조합으로:

  • 하드웨어: 5만원대 (Pi Zero 2 W + ZPi-IO08R 보드)
  • 소프트웨어: 오픈
  • 통신: Modbus TCP/RTU 슬레이브 + 마스터 + (예정) MQTT
  • 프로그래밍: 웹 브라우저만 있으면 됨
  • UI: AI 가 만들어주는 풀스크린 HMI (다음 글 참조)

모니터 페이지 — 입력/출력/메모리 라이브 상태

ZPi Controller 하드웨어·소프트웨어 구성

[Raspberry Pi Zero 2 W]

    ├─ ZPi-IO08R 보드 (4DI 광 절연 + 4DO 릴레이)
    ├─ 0.96" OLED (IP + 시간 + IO 표시, 옵션)
    └─ I2C / SPI / UART (확장)

[.NET 9 서비스 (systemd)]
    ├─ Blazor WebAssembly 관리 UI (포트 5000)
    ├─ Modbus TCP 슬레이브 (포트 502)
    ├─ Modbus RTU 마스터/슬레이브 (RS-485)
    ├─ 룰 엔진 (50ms tick) — 매트릭스 + 자연어 카드 + Python 코드
    └─ MCP 서버 (Claude Desktop / Code 통합)

ZPi Controller 핵심 기능 한눈에

페이지기능
모니터입력/출력/메모리/타이머/카운터 라이브 표시
룰 에디터입력→출력 매트릭스 + 추가 룰(자연어) + 고급 Python 코드(Tick()/OnInput()) — 셋이 같은 변수 풀 공유
ModbusTCP 슬레이브 / 마스터 (외부 슬레이브 폴링) / RTU 슬레이브 / 마스터 통합 설정
네트워크WiFi 스캔/접속/자동복원, 호스트명 변경 (mDNS)
Programs사용자 .NET / Python / 네이티브 프로그램 업로드 + 실행 + 자동시작
시스템OS/메모리/온도/IP, 비밀번호 변경, MCP 한 번 클릭 설치
ZView (이번 세션 추가)오퍼레이터용 풀스크린 HMI — AI 가 자연어로 생성

룰 에디터 — 한 화면에 3가지 방식 (v2)

ZPi Controller 룰 에디터 (v2) — 입력→출력 매트릭스 + 추가 룰(자연어) + 고급 Python 코드

웹 룰 에디터는 룰을 짜는 방식이 3가지이고, 셋 다 같은 변수 풀(IN/OUT/M/T/C/D)을 공유하며 매 스캔(50ms) 마지막에 함께 실행됩니다.

  1. 입력 → 출력 매트릭스 — 셀을 클릭하면 없음 → 직접(IN→OUT) → 반전(IN→!OUT) 으로 순환. 단순 직결은 코드 한 줄 없이 끝.
  2. 추가 룰 (자연어) — 매트릭스로 표현 안 되는 동작(메모리·타이머·카운터·주기·Modbus write 등)을 ”+ 룰 추가”로 카드처럼 쌓습니다.
  3. 고급 (Python 코드) — 그래도 부족하면 Python 으로 직접. Tick()(매 50ms) / OnInput(i, on)(입력 변경 시) 진입점에 로직을 채웁니다.

Python 코드에서 바로 쓰는 것들:

  • 변수: In[i] · Out[i] · M[i] · D[i] · C[i] · T[i].Elapsed · T[i].Running
  • 헬퍼: StartTimer(i, ms) · StopTimer(i) · IncCounter(i) · ResetCounter(i) · Log(...)
  • OLED: Oled.SetLine(0..2, "텍스트") · Oled.ClearLine(i) · Oled.Clear()

예를 들어 “IN0 켜지면 OUT0 ON, 1초 뒤 OUT1 도 ON” 은 이렇게:

void Tick()
{
    Out[0] = In[0];
    if (In[0] && !T[0].Running) StartTimer(0, 1000);
    Out[1] = T[0].Elapsed >= 1000;
    Oled.SetLine(0, $"IN0={In[0]}  OUT1={Out[1]}");
}

매트릭스로 80%를 클릭만으로 끝내고, 나머지 복잡한 것만 카드·Python 으로 — 그게 v2 룰 에디터의 방향입니다.

Modbus TCP·RTU 통신 구성

Modbus 통합 설정

  • TCP 슬레이브 (포트 502) — 외부 SCADA / HMI 가 본 보드를 폴링
  • TCP 마스터 — 본 보드가 다른 Modbus TCP 슬레이브를 폴링해서 D[] 레지스터에 매핑
  • RTU 슬레이브 (RS-485) — 같은 메모리 맵 RS-485 노출
  • RTU 마스터 (RS-485) — 외부 RTU 슬레이브 폴링

메모리 맵:

  • P (Coil) — 출력
  • M (Coil) — 내부 비트
  • T (Holding) — 타이머 ElapsedMs/100
  • C (Holding) — 카운터
  • D (Holding) — 데이터 레지스터
  • Wp / Wm — 비트들을 워드로 묶음

WiFi 끊김·부팅 지연 네트워크 자동복구

WiFi 페이지

라즈베리파이 WiFi가 끊기면 진짜 짜증 납니다. NetworkManager 프로필이 사라지거나 (특히 SD 카드 복제 후), DHCP 가 새 IP 를 줘서 mDNS 가 혼란스러워지거나, 부팅 시간이 1분 30초로 늘어나거나.

이번에 다 잡았습니다 — 자세한 건 5편.

Programs — 사용자 코드 호스팅

Programs 페이지

사용자 코드 호스팅은 LauncherTouch 스타일입니다. .NET 자체포함 exe / Python / 네이티브 바이너리를 zip 으로 업로드하면 systemd 보조 서비스처럼 돌려줍니다. 자동 재시작, 자동 시작, 로그 보기 다 지원. GPIO 점유는 EngineGate 가 조율 (룰엔진 ↔ 사용자 프로그램 자동 핸드오프).

시스템 페이지와 Claude MCP 연동

시스템 페이지

Claude MCP 연동은 버튼 하나로 끝납니다. 시스템 페이지에서 “MCP 설치 (PC연동)” 버튼을 누르면 Windows BAT 가 다운로드되고, 더블클릭하면 Claude Desktop / Code 양쪽에 자동 등록됩니다.

참고: 보드는 operator·admin 두 계정의 기본 비밀번호가 설정된 채 출고됩니다 (값은 동봉 매뉴얼 참조). 운영 전 반드시 변경하세요.

이게 가장 재밌는 부분. AI 가 PLC 를 직접 제어할 수 있고, 더 나아가 오퍼레이터용 HMI 페이지를 만들어서 배포까지 할 수 있습니다. 다음 글에서 자세히 다룹니다.

ZPi Controller 시리즈 다음 편

라즈베리파이 Zero 2 W 와 4입력/4릴레이 보드만으로 Modbus 슬레이브·마스터와 웹 룰 에디터를 갖춘 PLC 를 만들 수 있습니다.

문의