아두이노 우노 Q PC817 옵토커플러: 12V/24V DC 입력 신호 모니터링

PC817 옵토커플러를 사용하면 Arduino UNO Q가 전선 대신 빛을 통해 12V 또는 24V 회로를 감시할 수 있으므로, 고전압 쪽의 어떤 것도 보드에 도달할 수 없습니다. 이는 UNO Q에서 특히 중요합니다. 3.3V STM32 MCU 뒤에 Debian Linux를 실행하는 Qualcomm 프로세서가 있기 때문입니다 — 기계 캐비닛의 24V 스파이크로 절대 잃고 싶지 않은 보드입니다.

이 회로를 만드는 이유는 열에 아홉은 장치에 대한 단순한 질문입니다: 저 기계가 지금 실제로 동작하고 있는가? 기계의 24V 운전 램프 양단에 PC817 옵토커플러 모듈을 연결하면 그 답이 디지털 핀이 됩니다 — STM32가 읽고, Linux 측이 기록하고, Telegram이 알려주는 핀입니다.

이 튜토리얼에서 배울 내용:

Arduino UNO Q pc817 옵토커플러 절연 24v 입력

준비물

1×Arduino UNO Q 아마존
1×USB Cable for Arduino Uno Q 아마존
1×PC817 Optocoupler Module - 12V version 아마존
1×PC817 Optocoupler Module - 3-5V version 아마존
1×브레드보드 쿠팡 | 아마존
1×점퍼케이블 쿠팡 | 아마존
1×(추천) 아두이노 우노용 스크루 터미널 블록 쉴드 쿠팡 | 아마존
1×(추천) Sensors/Servo Expansion Shield for Arduino Uno 쿠팡 | 아마존
1×(추천) 아두이노 우노용 브레드보드 쉴드 쿠팡 | 아마존
1×(추천) 아두이노 우노용 케이스 쿠팡 | 아마존
1×(추천) 아두이노 우노용 프로토타이핑 베이스 플레이트 & 브레드보드 키트 아마존
공개: 이 포스팅 에 제공된 일부 링크는 아마존 제휴 링크입니다. 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

모듈 종류는 하나만 필요합니다 - 어떤 것인지는 다음 섹션에서 알려줍니다.

PC817 옵토커플러에 대하여

PC817 내부에는 적외선 LED가 절연 간격을 사이에 두고 포토트랜지스터와 마주 보고 있습니다. LED에 전류가 흐르면 그 빛이 트랜지스터를 켜므로, 신호는 전기가 아닌 빛으로 건너갑니다 — 이 때문에 양쪽이 전기적으로 분리된 상태를 유지합니다. 데이터시트는 이 간격의 정격을 1분간 5000 Vrms로 규정합니다.

Sharp 데이터시트의 주요 수치이며, 완제품 모듈에 올라간 PC817에도 똑같이 적용됩니다:

항목 값
LED 순방향 전압 (Vf) 일반적으로 약 1.2 V, 최대 1.4 V
LED 순방향 전류 (If) 일반 5-20 mA, 연속 최대 20 mA
컬렉터-이미터 전압 (VCEO) 최대 35 V
컬렉터 전류 (IC) 최대 50 mA
컬렉터 전력 손실 150 mW
절연 전압 5000 Vrms (1분)
전류 전달비 (CTR) 등급에 따라 50% ~ 600%
스위칭 속도 상승 약 4 us, 하강 약 3 us
동작 온도 -30 C ~ +100 C

어떤 PC817 모듈이 필요한가요?

완제품 PC817 모듈에는 직렬 저항이 이미 납땜되어 있고, 절연된 쪽에는 나사 단자가, 그리고 보통 상태 LED가 있습니다. 바로 이 장착된 저항이 핵심입니다: 저항은 하나의 입력 전압에 맞춰져 있습니다. 그래서 모듈은 세 가지 종류로 따로 판매되며, 중요한 구매 결정은 감시하려는 신호에 맞는 것을 고르는 것 하나뿐입니다.

감시하려는 신호 구입할 모듈 종류
24V DC — 기계 운전/고장 램프, PLC 출력, 산업용 캐비닛 24V 모듈
12V DC — 펌프, 릴레이 및 접촉기 코일, 차량 회로, 경보 패널 12V 모듈
3.3V 또는 5V 로직 — 다른 보드, 센서 출력, 저전압 제어 카드 3-5V 모듈

※ 주의:

종류는 봉투에 붙은 스티커가 아니라 저항입니다. 12V 모듈에 24V 라인을 연결하면 내부 LED에 의도한 전류의 약 두 배가 흘러 LED가 손상됩니다. 반대로 24V 모듈에 12V 라인을 연결하면 LED가 충분히 구동되지 않아, 출력이 늦게 스위칭하거나, 불안정하게 스위칭하거나, 아예 스위칭하지 않을 수 있습니다. 모듈을 사용하면 아무것도 계산할 필요가 없습니다: 종류를 고르는 것이 *곧* 계산입니다.

다채널 보드도 있습니다 — 같은 설계의 2, 4, 8채널 버전입니다 — 하지만 한 보드의 모든 채널은 그 보드의 종류를 공유하므로, 4채널 24V 모듈은 24V 라인 네 개만 감시할 수 있습니다.

3-5V 종류는 구색 맞추기용이 아닙니다. 5V 또는 3.3V 로직 신호도 두 회로가 별도의 전원에서 동작하거나, 긴 케이블의 양 끝에 있거나, 한쪽이 모터 드라이버나 상용 전원으로 동작하는 가전제품 내부의 저전압 제어 카드처럼 노이즈가 많은 것과 보드를 공유할 때는 절연할 가치가 있습니다 — 절연은 전압의 크기가 아니라 접지 경로를 끊는 것입니다. 또한 PC817 입력은 전원이 공급할 수 있는 전류의 양이 아니라 실제로 흐르는 전류에 반응한다는 점도 알아 두면 좋습니다: 10 A를 공급할 수 있는 5V 레일도 50 mA짜리 레일보다 모듈의 LED에 더 부담을 주지 않습니다. 어느 쪽이든 온보드 저항이 그 전류를 정해 주기 때문입니다. 더 큰 전원이 실제로 바꾸는 것은 다른 곳에서 배선 실수가 생겼을 때 결과가 얼마나 나빠지는가입니다 — 이것이 절연해야 하는 또 하나의 이유입니다.

모듈은 액티브 HIGH인가요, 액티브 LOW인가요?

칩 단품부터 시작해 봅시다. 이 부분은 확정된 물리이기 때문입니다. Arduino UNO Q 디지털 핀은 내부 풀업으로 높게 유지되므로, 포토트랜지스터는 핀을 끌어내리는 것만 할 수 있습니다:

외부 12V/24V 신호 PC817 LED 포토트랜지스터 Arduino UNO Q 핀 읽기 값
있음 켜짐 도통 LOW
없음 꺼짐 차단 HIGH

모듈은 이야기가 다릅니다. 어떤 제조사는 포토트랜지스터를 그대로 출력으로 내보내 위 표와 똑같이 동작하고, 다른 제조사는 보드에 반전 단계를 추가하여 출력이 입력을 따르도록 만듭니다. 두 종류 모두 같은 사진과 같은 설명으로 판매되므로, 책상 위에 있는 것이 어느 쪽인지 알 수 있는 유일하게 믿을 만한 방법은 1분을 들여 직접 확인하는 것입니다 — 한 번만 하면 됩니다.

  • 아래와 같이 모듈을 배선하고 이 페이지의 첫 번째 스케치를 실행합니다. 스케치는 App Lab 콘솔에 1초에 두 번 PRESENT 또는 ABSENT를 출력합니다.
  • IN+ / IN- 단자에 전원을 넣지 않은 상태로 콘솔을 확인합니다. ABSENT가 출력되어야 합니다.
  • 이제 IN+ / IN-에 신호를 넣습니다. 콘솔이 PRESENT로 바뀌어야 합니다. 그 출력을 만드는 핀 레벨이 여러분 모듈의 *활성* 레벨입니다.
  • 입력 쪽에 전원이 들어올 때마다 켜지는 모듈 자체의 상태 LED와 대조해 보세요: LED가 켜져 있는데도 콘솔이 계속 ABSENT라고 한다면, 모듈의 출력이 스케치의 가정과 반대입니다.
  • 둘이 반대라면, 스케치 맨 위의 한 줄만 바꾸고 다시 로드하세요 — 배선을 바꿀 필요도, 코드를 다시 쓸 필요도 없습니다:
const bool MODULE_ACTIVE_LOW = false; // was true

이 페이지의 두 MCU 스케치 모두 이 상수를 가지고 있고 모든 측정값을 이 상수에서 도출하므로, 한 곳에서 한 번만 수정하면 됩니다. Linux 측은 원시 핀 레벨을 전혀 보지 않습니다 — MCU가 Bridge를 통해 완성된 "present" 또는 "absent"를 전달하므로 — 모듈이 어떻게 동작하든 Python 파일은 그대로 두면 됩니다.

칩 단품으로 만들기

4핀 DIP 칩 단품을 브레드보드에 꽂아 사용하고 싶다면, 저항을 직접 골라야 한다는 점만 빼고 위의 모든 내용이 그대로 적용됩니다. 1번 핀은 점 또는 홈으로 표시되어 있습니다.

pc817 옵토커플러 핀아웃
  • 1번 핀 — 애노드 (A): 절연된 신호의 +, 직렬 저항을 거쳐 들어옵니다
  • 2번 핀 — 캐소드 (K): 12V/24V 회로의 접지, Arduino UNO Q GND가 아닙니다
  • 3번 핀 — 이미터 (E): Arduino UNO Q GND
  • 4번 핀 — 컬렉터 (C): Arduino UNO Q 디지털 입력 핀

LED 전류가 약 10 mA가 되도록 저항 값을 정합니다:

$$R = \frac{V_{in} - 1.2}{0.01}$$

  • 3.3V → 220 ohm (약 9.5 mA)
  • 5V → 390 ohm (약 9.7 mA)
  • 12V → 1 kohm (약 10.8 mA)
  • 24V → 2.2 kohm (약 10.4 mA, 1/2 W 부품 사용)

같은 회로를 12V 라인에서 24V 라인으로 옮기면 저항도 함께 바꿔야 합니다 — 세 가지 모듈 종류는 바로 이 실수를 여러분 대신 막아 주기 위해 존재합니다.

절연 규칙

12V/24V 회로의 접지를 Arduino UNO Q GND에 연결하면 안 됩니다. 두 접지를 분리해 두는 것이 핵심입니다 — 보드를 보호하는 것은 칩 자체가 아니라 바로 이 분리입니다. 둘을 연결해도 PC817은 여전히 잘 스위칭하지만, 절연은 사라지고 기계와 Linux 프로세서 사이가 직접 전선으로 연결된 상태로 돌아갑니다.

배선도

Arduino UNO Q의 STM32 MCU는 3.3V 부품이므로, 옵토커플러의 출력 쪽은 3.3V로 풀업되며 그보다 높아지지 않습니다. 절연된 쪽이 12V로 동작하든 24V로 동작하든 핀에는 아무 차이가 없습니다 — 트랜지스터는 핀을 GND로 단락시키거나 그대로 두거나 둘 중 하나입니다.

PC817 옵토커플러 모듈 배선

Arduino UNO Q pc817 옵토커플러 절연 모듈 배선도

이 이미지는 Fritzing을 사용하여 만들어졌습니다. 이미지를 확대하려면 클릭하세요.

단자는 다섯 개이며, 이들 사이의 구분 자체가 절연 장벽입니다 — IN+와 IN-는 기계에 속하고, VCC/GND/OUT은 Arduino UNO Q에 속하며, 두 그룹 사이를 건너는 전선은 없습니다.

모듈 단자 연결 대상
IN+ (입력 쪽) 12V/24V 신호의 +
IN- (입력 쪽) 12V/24V 회로의 접지 (보드 GND와 분리 유지)
VCC (출력 쪽) Arduino UNO Q 3.3V
GND (출력 쪽) Arduino UNO Q GND
OUT / DO (출력 쪽) Arduino UNO Q 2번 핀

※ 주의:

모듈의 VCC는 5V가 아니라 3.3V 핀에서 공급하세요. 모듈의 출력 핀은 VCC에 넣은 전압을 따르며, Arduino UNO Q의 STM32 입력은 3.3V를 기대합니다. 그리고 장착하는 모듈은 반드시 그 12V 또는 24V 신호에 맞는 종류여야 한다는 것을 기억하세요 — 종류가 맞지 않는 것은 코드로 고칠 수 없습니다.

PC817 칩 단품 배선

PC817 핀 연결 대상
1번 핀 - 애노드 (A) 직렬 저항을 거쳐 12V/24V 신호의 + (12V는 1 kohm, 24V는 2.2 kohm)
2번 핀 - 캐소드 (K) 12V/24V 회로의 접지 (보드 GND와 분리 유지)
3번 핀 - 이미터 (E) Arduino UNO Q GND
4번 핀 - 컬렉터 (C) Arduino UNO Q 2번 핀, INPUT_PULLUP 사용

내부 풀업이 가장 쉬운 방법이며, 핀을 MCU 자체의 3.3V 레일에 연결합니다. 외부 풀업을 사용하고 싶다면, 2번 핀에서 Arduino UNO Q의 3.3V 핀으로 10 kohm 저항을 연결하세요 — STM32 입력은 5V용이 아니므로 5V에 연결하면 안 됩니다.

부하 양단에 PC817을 병렬로 배선하기

위의 두 배선도는 12V/24V 라인을 처음부터 자유롭게 배선할 수 있다고 은근히 가정합니다. 실제 기계에서는 그렇지 않습니다: 라인은 이미 무언가에 전원을 공급하고 있으며, 그 무언가가 바로 여러분이 감시하려는 대상입니다. 따라서 옵토커플러는 기존 장치 양단에 연결됩니다 — 장치와 병렬로, 장치가 이미 연결된 같은 두 단자에 매달립니다.

24V 산업용 기계의 운전/고장 램프 라인을 예로 들어 봅시다. 아래 Telegram 섹션에서 "Conveyor 3 started"로 바뀌는 바로 그 라인입니다. 램프는 캐비닛의 스위칭된 24V와 0V 복귀선 사이에 배선되어 있고, 24V 모듈은 그곳에 그냥 함께 연결됩니다:

연결 지점 연결 대상
24V 램프의 스위칭된 + 단자 모듈 IN+
24V 램프의 0V 복귀 단자 모듈 IN-

이 연결에 추가할 저항은 없습니다: 24V 모듈에 이미 올바른 저항이 들어 있으며, 이것이 라인에 맞는 종류를 구입하는 이유의 전부입니다. (칩 단품 방식이라면 여기에 2.2 kohm을 1번 핀과 직렬로 넣습니다.)

캐비닛 안의 어떤 것도 자르거나, 뽑거나, 경로를 바꾸지 않습니다. 이 연결은 몇 밀리암페어만 소비하며, 이는 램프, 접촉기 코일, 솔레노이드 밸브, 모터가 이미 소비하는 전류에 비하면 아무것도 아니므로, 기계는 이전과 똑같이 동작합니다 — 회로 안에 끼워 넣은 것이 아니라 회로 옆에 덧붙인 읽기 전용 측정입니다.

※ 주의:

옵토커플러를 절대 장치와 직렬로 연결하지 마세요. 직렬로 연결하면 램프, 코일, 모터의 전체 부하 전류가 내부 LED를 통과하게 되고, 회로가 켜지는 순간 PC817은 파괴됩니다 — 모듈의 온보드 저항은 이를 막아 주지 못합니다. 입력 쪽은 수십 밀리암페어 정격의 LED일 뿐입니다. 항상 장치 양단에 연결하세요.

이 연결이 처음부터 잘 동작할지는 네 가지 세부 사항에 달려 있습니다:

  • 극성은 선택 사항이 아닙니다. IN+와 IN-는 LED의 양 끝이므로 전류는 한 방향으로만 흐릅니다. 반대로 연결하면 옵토커플러는 절대 켜지지 않습니다 — 손상도 없고, 측정값도 없고, 이유에 대한 힌트도 없습니다. 전선 피복을 벗기기 전에 두 단자 중 어느 쪽이 양극인지 확인하세요.
  • 유도성 부하는 다이오드로 클램프하세요. 접촉기 코일, 릴레이, 솔레노이드 밸브, 모터는 꺼지는 순간 큰 역전압 스파이크를 발생시키며, PC817 입력 LED는 역방향 6 V까지만 견딥니다. 일반 다이오드를 모듈의 입력 단자 양단에 직접 역병렬로 장착하세요 — 다이오드 캐소드는 IN+에, 다이오드 애노드는 IN-에 연결합니다 (칩 단품에서는 1번과 2번 핀). 정상 동작 시에는 역바이어스되어 아무 일도 하지 않고, 스파이크가 발생하면 도통하여 역전압을 1볼트보다 훨씬 낮게 유지합니다. 작은 연결에는 1N4148, 더 큰 연결에는 1N4007이면 충분합니다.
  • 측정값이 절대 해제되지 않으면 블리더 저항을 추가하세요. PLC 트랜지스터 출력, 트라이액 출력, LED 램프 드라이버는 꺼져 있을 때도 흔히 1밀리암페어 정도가 누설됩니다. 이 적은 전류로도 입력 LED가 부분적으로 켜지며, 캐비닛이 꺼져 있는데도 Arduino UNO Q가 기계를 동작 중으로 보고합니다 — 측정값이 ABSENT로 절대 돌아오지 않고 모듈의 상태 LED가 희미하게 빛난다면 이 경우입니다. 입력 단자 양단에 4.7 kohm ~ 10 kohm 저항을 장착하면 누설 전류가 LED보다 쉬운 경로로 빠져나가 측정값이 안정됩니다.
  • DC 라인 전용입니다. 입력에 LED가 하나뿐이므로 PC817은 한 극성에만 반응하며, AC 라인을 감지하는 데는 맞지 않는 부품입니다 — AC에는 입력단에 LED 두 개가 역병렬로 들어 있는 옵토커플러가 필요합니다.

기계가 켜져 있는지 꺼져 있는지 모니터링하기

장치 앞이 아니라 장치 양단에 연결되어 있으므로, 핀은 여러분의 의도가 아니라 기계의 실제 전기적 상태를 따릅니다. 작업자가 물리적인 시작 버튼을 누르거나, PLC가 일정에 따라 라인에 전원을 넣거나, 캐비닛의 다른 곳에 있는 타이머가 접점을 닫는 것 — Arduino UNO Q는 이 모든 것을 봅니다. 마찬가지로 중요한 것은, 시작 명령이 내려졌는데도 라인이 꺼진 채로 있는 경우도 본다는 점입니다. 이것이 회로를 단순한 신호 감지기에서 운전 시간 카운터, 유휴 시간 기록, 고장 램프 감시기, "정말 시작했나?" 확인 장치로 끌어올려 줍니다.

마지막 것이 바로 Arduino UNO Q의 Linux 부분이 제 값을 하는 곳입니다: 아래 Bridge 섹션은 각 상태 변화를 Python에 전달하고, 그 다음 Telegram 섹션은 상태 변화를 1초 안에 메시지로 바꿉니다 — 그래서 24V가 나오지 않는 시작 명령은 몇 시간 뒤에 발견되는 대신 휴대폰의 알림이 됩니다.

※ 주의:

솔직한 한계 하나: PC817은 장치에 전원이 들어와 있다는 것을 알려줄 뿐, 장치가 제 일을 하고 있다는 것을 알려주지는 않습니다. 걸려서 멈춘 모터, 끊어진 히터 소자, 막힌 컨베이어도 여전히 라인에서 전력을 소비하므로 PRESENT로 읽힙니다. 기계가 정말로 일하고 있는지 알려면, 이 신호와 함께 전류, 온도, 움직임을 감시하세요.

PC817 프로그래밍 방법

  • 모듈의 OUT 단자가 연결될 핀을 선택합니다:
#define PC817_PIN 2
  • 모듈의 극성을 한 곳에서 선언하여, 추측이 틀려도 스케치 전체를 뒤지는 대신 한 줄만 고치면 되게 합니다:
const bool MODULE_ACTIVE_LOW = true;
  • 절연된 라인이 꺼져 있는 동안 핀이 3.3V에 있도록 내부 풀업을 활성화합니다:
pinMode(PC817_PIN, INPUT_PULLUP);
  • 원시 핀 레벨을 읽은 다음, 어디에도 LOW를 하드코딩하지 않고 상수를 통해 해석합니다:
int raw = digitalRead(PC817_PIN); bool line_present = MODULE_ACTIVE_LOW ? (raw == LOW) : (raw == HIGH);
  • 결과에 따라 동작합니다:
if (line_present) Serial.println("24V line: PRESENT"); else Serial.println("24V line: ABSENT");
  • 라인의 레벨이 아니라 라인이 바뀌는 순간을 잡으려면, 이전 측정값을 기억해 두고 비교합니다:
if (line_present != last_present) { last_present = line_present; Monitor.println(line_present ? "24V line went PRESENT" : "24V line went ABSENT"); }

이 모든 것에 라이브러리는 필요 없습니다 — PC817은 아두이노 우노 Q - 버튼이나 아두이노 우노 Q - 리미트 스위치와 똑같이 일반 digitalRead()로 읽으며, 다만 24볼트가 간격 너머에 안전하게 머물러 있을 뿐입니다.

Arduino UNO Q 코드

Arduino UNO Q에는 함께 동작하는 두 개의 프로세서가 있습니다:

  • STM32 MCU는 절연된 입력 핀을 담당하며 500 ms마다 읽습니다
  • Qualcomm MPU는 Wi-Fi가 있는 Debian Linux를 실행합니다 — 이 첫 번째 섹션에서는 유휴 상태로 있으며, 뒤 섹션에서 Bridge를 통해 참여시킵니다
/* * 이 Arduino UNO Q 코드는 newbiely.kr 에서 개발되었습니다 * 이 Arduino UNO Q 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino-uno-q/arduino-uno-q-pc817-optocoupler-monitor-12v-24v-dc-input-signal */ // PC817 optocoupler on Arduino UNO Q - isolated digital input. // Use the module variant that matches the signal: 3-5V, 12V or 24V. The series // resistor is already fitted on the module and is sized for that variant. // (On the bare 4-pin chip you fit the resistor yourself: 1 kohm for 12V, // 2.2 kohm for 24V.) // The STM32 MCU runs at 3.3V logic, so INPUT_PULLUP ties the pin to 3.3V - the // pin can never go above 3.3V no matter what the isolated side is doing. #define PC817_PIN 2 // Most PC817 modules pull the output LOW when the input signal is present, and // so does the bare chip wired with a pull-up. Some modules invert on-board and // work the other way round - if yours does, change this to false. const bool MODULE_ACTIVE_LOW = true; void setup() { Serial.begin(9600); // Internal pull-up to the MCU 3.3V rail - no external resistor needed pinMode(PC817_PIN, INPUT_PULLUP); Serial.println("Arduino UNO Q PC817 isolated input ready"); Serial.print("Watching the 24V line on pin 2 - module treated as "); Serial.println(MODULE_ACTIVE_LOW ? "active-LOW" : "active-HIGH"); } void loop() { int raw = digitalRead(PC817_PIN); // The single place the module polarity is resolved bool line_present = MODULE_ACTIVE_LOW ? (raw == LOW) : (raw == HIGH); if (line_present) Serial.println("24V line: PRESENT"); else Serial.println("24V line: ABSENT"); delay(500); }

빠른 단계

Arduino UNO Q를 처음 사용하시나요? 진행하기 전에 아두이노 우노 Q 시작하기 튜토리얼을 따라 하세요.

  • 먼저 올바른 모듈 종류를 고르세요: 24V 라인에는 24V 모듈, 12V 라인에는 12V 모듈, 로직 레벨 신호에는 3-5V 모듈을 사용합니다. 이것은 코드로 구제할 수 없는 단 하나의 선택입니다.
  • 모듈 배선: 위의 배선도를 따르고, 12V/24V 접지가 Arduino UNO Q GND 근처에도 가지 않는지 다시 확인합니다.
  • 연결: USB-C 케이블로 Arduino UNO Q를 컴퓨터에 연결합니다.
  • Arduino App Lab 열기: Arduino App Lab을 실행하고 Arduino UNO Q를 감지할 때까지 기다립니다.
  • 새 App 만들기: Create New App 버튼을 클릭합니다.
Arduino UNO Q의 아두이노 app lab에서 새 app 만들기
  • App에 이름을 지정합니다. 예: PC817IsolatedInput
  • Create를 클릭하여 확인합니다.
Arduino UNO Q의 아두이노 app lab app 폴더와 파일
  • 스케치 붙여넣기: 위의 MCU 코드를 sketch/sketch.ino에 복사합니다. 다른 파일은 기본값으로 둡니다.
  • 라이브러리 필요 없음 — PC817은 내장 digitalRead() 함수로 읽습니다.
  • 업로드: Arduino App Lab에서 Run 버튼을 클릭합니다.
Arduino UNO Q의 아두이노 app lab에서 run 버튼 클릭
  • 시리얼 모니터를 보면서 절연된 12V/24V 신호를 켰다 껐다 합니다 — 이것이 앞에서 설명한 극성 테스트도 겸합니다.

App Lab 콘솔 출력

DIYables_Apps
Stop
sketch.ino
1#include "Arduino_RouterBridge.h"
Serial Monitor
Python
Message (Enter to send a message to "Newbiely" on usb(2820070321))
New Line
9600 baud
[2026-05-14 08:12:03] Arduino UNO Q PC817 isolated input ready [2026-05-14 08:12:03] Watching the 24V line on pin 2 - module treated as active-LOW [2026-05-14 08:12:04] 24V line: ABSENT [2026-05-14 08:12:04] 24V line: ABSENT [2026-05-14 08:12:05] 24V line: PRESENT [2026-05-14 08:12:05] 24V line: PRESENT [2026-05-14 08:12:06] 24V line: ABSENT

※ 주의:

기계가 꺼져 있을 때 PRESENT, 켜져 있을 때 ABSENT가 보이나요? 모듈이 보드에서 반전하는 것입니다 — MODULE_ACTIVE_LOW를 false로 설정하고 다시 실행하세요. 배선은 그대로 두면 됩니다. 반대로 핀이 전혀 바뀌지 않는다면, 흔한 원인은 종류 불일치입니다: 12V 라인에 연결된 24V 모듈은 LED를 거의 켜지 못합니다. 다른 것을 건드리기 전에 모듈의 상태 LED를 콘솔과 대조해 보세요.

Bridge: Linux + MCU

이 섹션에서는 Linux 측이 절연된 입력을 볼 수 있도록 Arduino UNO Q의 두 프로세서를 함께 연결합니다:

  • PC817 출력은 MCU 핀에 연결됩니다 — MCU는 loop()에서 이를 감시하고, 디바운스하고, MODULE_ACTIVE_LOW로 해석하며, 각 변화를 이벤트로 기억합니다
  • MPU는 그 핀에 접근할 수 없습니다 — RPC로 상태는 Bridge.call("get_line"), 대기 중인 변화는 Bridge.call("get_event")로 요청합니다. MPU는 원시 핀 레벨이 아니라 완성된 "present" / "absent"를 받으므로, 모듈 극성은 MCU에서 한 번만 정해지고 다시는 신경 쓸 필요가 없습니다. MCU는 응답만 할 뿐이며, Linux 측의 어떤 것도 절연된 입력을 구동할 수 없습니다
  • MPU에는 Wi-Fi가 있습니다 — 완전한 Debian Linux이므로, 모든 상태 변화를 파일에 기록하거나 기계가 시작된 지 1초 안에 Telegram 메시지를 보낼 수 있습니다
  • Arduino_RouterBridge는 두 프로세서 간의 RPC 링크를 제공합니다
  • ⚠️ /dev/ttyHS1(Linux)과 Serial1(MCU)은 라우터가 예약한 것입니다 — 사용자 코드에서 절대 열지 마세요

요약하면: 24V 라인 변화 → MCU가 이벤트를 기록 → MPU가 Bridge로 폴링 → Linux가 기록하거나 전달. 두 프로세서가 어떻게 통신하는지 전체 그림을 보려면 아두이노 우노 Q - Linux와 MCU 간의 통신을 참고하세요.

MCU 코드 (Bridge)

/* * 이 Arduino UNO Q 코드는 newbiely.kr 에서 개발되었습니다 * 이 Arduino UNO Q 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino-uno-q/arduino-uno-q-pc817-optocoupler-monitor-12v-24v-dc-input-signal */ // PC817 optocoupler on Arduino UNO Q - MCU side of the Bridge. // The MCU owns the isolated input pin and exposes it READ-ONLY to Linux: // get_line -> "present" / "absent" (the state right now) // get_event -> "on" / "off" / "none" (a state change waiting to be consumed) // Module polarity is resolved here, so Linux only ever receives a finished // answer and never has to know about pin levels. // The 12V/24V ground never touches the board GND - that is what keeps the // isolation intact. #include "Arduino_RouterBridge.h" #define PC817_PIN 2 #define DEBOUNCE_MS 20 // Most PC817 modules pull the output LOW when the input signal is present, and // so does the bare chip wired with a pull-up. Some modules invert on-board and // work the other way round - if yours does, change this to false. const bool MODULE_ACTIVE_LOW = true; int last_state = HIGH; bool line_on_event = false; bool line_off_event = false; // The single place the module polarity is resolved bool is_line_present(int raw) { return MODULE_ACTIVE_LOW ? (raw == LOW) : (raw == HIGH); } String get_line(String arg) { return is_line_present(digitalRead(PC817_PIN)) ? "present" : "absent"; } // Returns one pending change and clears it, so Linux never sees it twice String get_event(String arg) { if (line_on_event) { line_on_event = false; return "on"; } if (line_off_event) { line_off_event = false; return "off"; } return "none"; } void setup() { Bridge.begin(); Monitor.begin(); pinMode(PC817_PIN, INPUT_PULLUP); last_state = digitalRead(PC817_PIN); Bridge.provide("get_line", get_line); Bridge.provide("get_event", get_event); Monitor.println("Arduino UNO Q PC817 Bridge ready"); Monitor.println(is_line_present(last_state) ? "24V line: PRESENT" : "24V line: ABSENT"); } void loop() { int state = digitalRead(PC817_PIN); if (state != last_state) { // Field wiring can be long, so confirm the change before trusting it delay(DEBOUNCE_MS); if (digitalRead(PC817_PIN) != state) return; last_state = state; if (is_line_present(state)) { line_on_event = true; Monitor.println("24V line went PRESENT - machine running"); } else { line_off_event = true; Monitor.println("24V line went ABSENT - machine stopped"); } } }

Python 코드 (Bridge)

/* * 이 Arduino UNO Q 코드는 newbiely.kr 에서 개발되었습니다 * 이 Arduino UNO Q 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino-uno-q/arduino-uno-q-pc817-optocoupler-monitor-12v-24v-dc-input-signal */ # PC817 optocoupler on Arduino UNO Q - Linux side of the Bridge. # Linux cannot touch the isolated input pin: it asks the MCU over RPC. # Never open /dev/ttyHS1 here - it belongs to the Arduino Router. # The MCU has already applied MODULE_ACTIVE_LOW, so what arrives here is a # finished "present" / "absent" - there is no polarity setting on this side. from arduino.app_utils import * import time def loop(): line = Bridge.call("get_line") if line == "present": print("24V line: PRESENT (machine running)") else: print("24V line: ABSENT (machine stopped)") time.sleep(1) App.run(user_loop=loop)

빠른 단계

  • 연결: 같은 배선을 유지합니다 — 옵토커플러는 MCU 쪽에 그대로 둡니다.
  • Arduino App Lab을 열고 PC817Bridge라는 이름의 새 App을 만듭니다.
  • MCU 스케치를 sketch/sketch.ino에 붙여넣습니다.
  • Python 코드를 App의 Python 파일에 붙여넣습니다.
  • 첫 번째 스케치에서 MODULE_ACTIVE_LOW를 false로 설정해야 했다면, 여기서도 똑같이 설정하세요 — 두 스케치 사이에서 일치해야 하는 유일한 줄입니다.
  • Install the library: Click the Add sketch library button (the open book icon with a + sign) in the left sidebar.
add sketch 라이브러리 in 아두이노 app lab on Arduino UNO Q
  • Search for Arduino_RouterBridge created by Arduino and click the Install button.
My Apps / DIYables Apps
Run
Bricks
No bricks added...
Sketch Libraries
No sketch libra...
Files
python
sketch
.gitignore
README.md
app.yaml
sketch.ino
Add sketch library
Arduino_RouterBridge Arduino

This library provides a simple RPC bridge for Arduino UNO Q boards, allowing communication between the board and other devices using MsgPack serialization.

0.4.1
Install
More Info
  • 업로드: Run 버튼을 클릭합니다.
Arduino UNO Q의 아두이노 app lab에서 run 버튼 클릭
  • 절연된 12V/24V 신호를 켰다 껐다 하면서 두 콘솔이 반응하는 것을 확인합니다.
  • ⚠️ 경고: Linux에서 /dev/ttyHS1을 열거나 MCU에서 Serial1을 사용하지 마세요 — Arduino Router가 이들을 소유하고 있으며, 건드리면 Bridge가 동작하지 않습니다.

App Lab 콘솔 출력

DIYables_Apps
Stop
sketch.ino
1#include "Arduino_RouterBridge.h"
Serial Monitor
Python
Message (Enter to send a message to "Newbiely" on usb(2820070321))
New Line
9600 baud
[2026-05-14 08:30:00] Arduino UNO Q PC817 Bridge ready [2026-05-14 08:30:00] 24V line: ABSENT [2026-05-14 08:30:11] 24V line went PRESENT - machine running [2026-05-14 08:34:46] 24V line went ABSENT - machine stopped
DIYables_Apps
Stop
sketch.ino
1#include "Arduino_RouterBridge.h"
Serial Monitor
Python
[2026-05-14 08:30:01] 24V line: ABSENT (machine stopped) [2026-05-14 08:30:12] 24V line: PRESENT (machine running) [2026-05-14 08:30:13] 24V line: PRESENT (machine running) [2026-05-14 08:34:47] 24V line: ABSENT (machine stopped)

Telegram

12V 또는 24V 라인에는 비교할 값이 없습니다 — 있거나 없거나 둘 중 하나입니다. 그래서 여기서 유용한 알림은 상태 변화 알림입니다: 절연된 라인이 살아나는 순간과 다시 꺼지는 순간 봇이 메시지를 보내며, 기계 캐비닛에서는 이것이 "시작됨"과 "정지됨"을 뜻합니다.

아직 봇이 없다면 먼저 아두이노 우노 Q - 텔레그램 봇을 참고하세요.

MCU 스케치: 이전 Bridge 섹션의 MCU 스케치를 그대로 사용합니다.

Python 코드 (Telegram)

/* * 이 Arduino UNO Q 코드는 newbiely.kr 에서 개발되었습니다 * 이 Arduino UNO Q 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino-uno-q/arduino-uno-q-pc817-optocoupler-monitor-12v-24v-dc-input-signal */ # PC817 optocoupler on Arduino UNO Q - Telegram bot on the Linux side. # Pushes an alert the moment the isolated 24V line turns on or off, and answers # /line on demand. The MCU sketch (pc817_optocoupler_Bridge.cpp) must already be # running on the STM32 - it resolves module polarity with MODULE_ACTIVE_LOW and # hands this script a finished "present" / "absent". from arduino.app_utils import * import requests import time TELEGRAM_BOT_TOKEN = "YOUR_TELEGRAM_BOT_TOKEN" CHAT_ID = "YOUR_CHAT_ID" MACHINE_NAME = "Conveyor 3" last_update_id = 0 def get_updates(): global last_update_id url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/getUpdates" params = {"offset": last_update_id + 1, "timeout": 5} try: response = requests.get(url, params=params, timeout=10) data = response.json() if data["ok"]: return data["result"] except Exception as e: print(f"Error getting updates: {e}") return [] def send_message(chat_id, text): url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage" payload = {"chat_id": chat_id, "text": text} try: requests.post(url, data=payload, timeout=10) except Exception as e: print(f"Error sending message: {e}") def loop(): global last_update_id # Auto-alert on every change of the isolated 24V line event = Bridge.call("get_event") if event == "on": msg = f"🟢 {MACHINE_NAME} started - 24V run line is live" print(msg) send_message(CHAT_ID, msg) elif event == "off": msg = f"🔴 {MACHINE_NAME} stopped - 24V run line went dead" print(msg) send_message(CHAT_ID, msg) # Answer commands sent from Telegram for update in get_updates(): last_update_id = update["update_id"] if "message" not in update: continue message = update["message"] chat_id = message["chat"]["id"] text = message.get("text", "").strip() print(f"Received: {text}") if text == "/start": send_message(chat_id, "Arduino UNO Q PC817 Isolated Input Bot\n" "/line - is the 24V line present right now?\n" "/machine - running or stopped?") elif text == "/line": line = Bridge.call("get_line") send_message(chat_id, f"24V line: {line.upper()}") elif text == "/machine": line = Bridge.call("get_line") state = "RUNNING" if line == "present" else "STOPPED" send_message(chat_id, f"{MACHINE_NAME}: {state}") else: send_message(chat_id, "Unknown command. Send /start for help.") time.sleep(0.5) App.run(user_loop=loop)

빠른 단계

  • YOUR_TELEGRAM_BOT_TOKEN을 BotFather에서 받은 봇 토큰으로 바꿉니다.
  • YOUR_CHAT_ID를 여러분의 Telegram 채팅 ID로 바꿉니다.
  • MACHINE_NAME을 24V 라인이 실제로 속한 장치 이름으로 바꿉니다.
  • 이 Python 코드를 App의 Python 파일에 붙여넣습니다. MCU 스케치는 그대로 둡니다.
  • 이 파일의 어떤 부분도 모듈 극성을 알거나 신경 쓰지 않습니다 — MCU가 이미 해석했으므로, 맞춰야 할 두 번째 설정이 없습니다.
  • Run 버튼을 클릭한 다음, 절연된 라인을 켰다 껐다 해 보세요 — 1초 안에 Telegram에 알림이 도착해야 합니다.
  • 언제든지 /line을 보내 지금 24V 신호가 있는지 물어볼 수 있습니다.

App Lab 콘솔 출력

DIYables_Apps
Stop
sketch.ino
1#include "Arduino_RouterBridge.h"
Serial Monitor
Python
[2026-05-14 08:40:00] Waiting for Telegram messages... [2026-05-14 08:40:19] 🟢 Conveyor 3 started - 24V run line is live [2026-05-14 08:52:04] 🔴 Conveyor 3 stopped - 24V run line went dead [2026-05-14 08:52:31] Received: /line
Telegram
Telegram 12:45
Welcome to Telegram!
ArduinoBot 10:19
Chatting with Arduino...
telegram-botfather
BotFather Yesterday
Your bot has been created.

ArduinoBot

bot
Today
🟢 Conveyor 3 started - 24V run line is live
10:15 AM
🔴 Conveyor 3 stopped - 24V run line went dead
10:16 AM
/line
10:17 AM ✓✓
24V line: ABSENT
10:18 AM
/machine
10:19 AM ✓✓
Conveyor 3: STOPPED
10:20 AM

OpenClaw

You can adapt the OpenClaw to this tutorial by refering the instruction on 아두이노 우노 Q - OpenClaw Tutorial

프로젝트 아이디어

Linux 측이 참여하면 절연된 입력은 훨씬 더 흥미로워집니다:

  • 24V 기계 가동 시간 기록기: 기계의 24V "운전" 램프 라인을 24V 모듈에 연결합니다 — Python이 모든 시작과 정지 시각을 Linux 파일 시스템의 CSV에 기록하고, 매일 저녁 총 운전 시간과 사이클 수를 담은 Telegram 요약을 보냅니다
  • 운전 시간 카운터와 유휴 시간 기록: 절연된 입력을 하나의 장치에 대한 순수한 켜짐/꺼짐 모니터로 사용합니다 — Python이 기계에 전원이 들어와 있던 총 시간, 작업 사이에 유휴 상태였던 시간, 시작 횟수를 누적하고, /hours Telegram 명령에 그날의 수치로 답합니다
  • 고장 램프 감시기: 고장 램프 회로에 두 번째 24V 모듈을 연결하고 별도의 Bridge 함수로 노출합니다 — 고장 라인이 켜지는 순간 Linux가 알림을 보내고, 꺼져 있는 동안은 조용히 있습니다
  • 12V 펌프 대시보드: 12V 모듈로 12V 펌프의 코일 전원을 모니터링하고, Linux 측에서 실시간 상태를 작은 아두이노 우노 Q - 웹 서버로 제공하여, 네트워크의 누구나 펌프가 동작 중인지 볼 수 있게 합니다
  • 차량 시동 추적기: 12V 시동 또는 전조등 회로를 감시합니다 — Linux 측이 주행마다 회로가 살아 있던 시간을 기록하고, 회로가 꺼지면 합계를 Telegram으로 보냅니다
  • PLC 출력 미러: 옵토커플러로 24V PLC 출력을 읽고, 다른 MCU 핀으로 구동하는 아두이노 우노 Q - 릴레이에 그대로 반영하여, UNO Q가 산업용 캐비닛과 여러분의 저전압 장비 사이의 안전한 다리 역할을 하게 합니다

스스로 도전해 보기

Arduino UNO Q에서 PC817을 더 활용할 준비가 되셨나요? 다음을 시도해 보세요:

  • 쉬움: 절연된 라인이 있을 때마다 온보드 LED를 켜고, 출력되는 라벨을 PRESENT/ABSENT에서 여러분의 기계에 맞는 표현으로 바꿉니다.
  • 보통: 부팅 이후 24V 라인이 살아난 횟수를 세는 get_on_count Bridge 함수와, 이번 사이클에서 살아 있던 시간을 반환하는 get_on_seconds 함수를 추가한 다음 — /stats Telegram 명령으로 둘 다 보고합니다.
  • 고급: 4채널 24V 모듈을 MCU 핀 네 개에 연결하고, 네 상태를 모두 하나의 Bridge 호출로 노출한 다음, 정확히 어느 채널이 바뀌었는지 알려주는 Telegram 메시지 하나를 Python이 보내게 합니다 — 캐비닛 전체를 위한 작은 절연 I/O 모니터의 시작입니다.

함수 참조

관련 튜토리얼