====== PC900 optocoupler ======
===== 기본 자료 =====
{{ :nano_ardule_midi_controller:pc900v_datasheet.pdf |PC900V 데이터시트}}
{{ :pictures:pc900.png?400 |}}
다음 그림의 출처: http://midi.teragonaudio.com/hardware/pc_intfc.htm
{{ :pictures:optocoupler_pinout_comparison.png?400 |}}
(상단에서 본 모습, 핀1 표시 점 기준)
┌───────┐
Anode |1 6| Vcc (+5V)
Cathode |2 5| GND (Emitter)
NC |3 4| Vout (Collector)
└───────┘
==== 핀 기능 요약 ====
* Pin 1 : LED Anode (+, DIN4에서 220Ω 직렬 후 연결)
* Pin 2 : LED Cathode (–, DIN5와 연결)
* Pin 3 : NC (사용 안 함)
* Pin 4 : Collector (출력, 풀업 후 아두이노 RX로)
* Pin 5 : Emitter (GND)
* Pin 6 : Vcc (+5V)
===== PC900V Drop-in Replacement =====
PC900V는 샤프(SHARP, 현재는 Vishay 등에 승계)에서 나온 **포토커플러**로, 포토트랜지스터 출력이며 약 80–100 kbps 정도의 응답 속도를 가집니다.
MIDI IN과 같은 31.25 kbps 신호에서는 충분히 동작하지만, 단종/구하기 어려운 경우가 있어 대체품을 찾게 됩니다.
==== 1. 핀 호환 Drop-in 대체품 ====
* **Vishay VO618A / VO615A**
→ PC900과 동일한 4핀 DIP 패키지, CTR 범위 유사.
* **Toshiba TLP521**
→ 흔한 범용 포토커플러, 속도는 MIDI용으로 충분.
* **Everlight EL817**
→ 국내외 유통량이 많음. CTR 넓고 속도는 약 50 kHz 수준으로 MIDI에 사용 가능.
==== 2. MIDI용으로 자주 쓰이는 대체품 ====
* **6N138 / 6N137**
* 핀 배열은 다르지만 MIDI IN 회로 예제에서 가장 많이 사용됨.
* 6N138: CTR 높으나 응답이 느려 강한 풀업 저항(220Ω 수준)을 요구.
* 6N137: 더 빠른 디지털용, 내부 슈미트 트리거 내장 → TTL 레벨로 안정적.
* **HCPL-0500, HCPL-0630**
* 고속/저지연용. MIDI에는 다소 오버스펙이지만 안정적 동작.
==== 3. 정리 ====
* **핀 배열 그대로 교체** 가능한 부품: VO618A, TLP521, EL817 등 4핀 DIP 계열.
* **MIDI IN 전용**으로는 6N138/6N137이 사실상 업계 표준.
* 단순 교체가 목적이라면 **VO618A** 같은 4핀 DIP가 가장 무난.
===== Arduino UNO 기반 PC900V 옵토커플러 테스터 (I2C 2004 LCD 표시) =====
아두이노 우노(UNO)로 PC900V(포토트랜지스터형 옵토커플러)를 단품 점검하고,
측정 결과를 I2C 20×4 LCD(2004)에 표시하는 예제입니다.
Phase1(저속 ON/OFF 논리 확인)과 Phase2(1 kHz/5 kHz 토글 응답 통계)를 지원합니다.
==== 1. 준비물 ====
* Arduino UNO 보드
* PC900V (또는 EL817/TLP521 등 4핀 포토트랜지스터형 옵토커플러)
* I2C 20×4 LCD 모듈 (주소 0x27 또는 0x3F)
* 저항: 220Ω(LED 직렬), 1kΩ~2.2kΩ(출력 풀업/로드 RL)
* 점퍼 케이블, 브레드보드
==== 2. 배선 ====
D9로 PC900V의 LED를 구동하고, D2(INT0)로 포토트랜지스터 출력을 읽습니다.
(I2C 20x4 LCD를 사용할 경우 A4/A5 배선 예시도 아래에 포함)
Arduino UNO PC900V (6pin DIP)
============ ==================
D9 (디지털 출력) -----[220Ω]----------> Pin1 (Anode, LED+)
GND ---------------------------------> Pin2 (Cathode, LED-)
+5V ---------------------------------> Pin6 (Vcc)
GND ---------------------------------> Pin5 (Emitter, GND)
D2 (디지털 입력, INT0) <------------+-- Pin4 (Collector, Output)
|
[RL = 1kΩ~2.2kΩ Pull-up]
|
+5V
=== 요약:===
* UNO D9 → 220Ω → PC900V Pin1 (LED+), Pin2은 GND.
* UNO +5V → Pin6 (Vcc), UNO GND → Pin5 (Emitter).
* PC900V Pin4 (Collector) → UNO D2 입력, 그리고 풀업저항(RL) 을 통해 +5V에 연결.
* 필요 시 Pin4→(74HC14 1게이트)→D2 로 신호 정형 권장.
* UNO의 0,1번 핀(RX/TX)은 USB 시리얼과 충돌하므로 사용하지 않습니다.
=== (선택) I2C 20×4 LCD 연결 예시 ===
테스트 결과를 LCD에 표시하려면 아래처럼 I2C LCD를 추가하세요. (주소 0x27 또는 0x3F)
UNO A4 (SDA) -------------------- LCD SDA
UNO A5 (SCL) -------------------- LCD SCL
UNO +5V ------------------------- LCD VCC
UNO GND ------------------------- LCD GND
{{ :pictures:aduino_uno_pc900_tester.png?400 |}}
==== 3. 기대 동작 ====
* LED ON(=D9 HIGH) → 트랜지스터 ON → D2가 **LOW**
* LED OFF(=D9 LOW) → 트랜지스터 OFF → D2가 **HIGH**
* Phase2에서 1 kHz/5 kHz 토글에 대해 엣지 개수와 HIGH/LOW 평균 펄스폭이 반주기 근처면 정상
==== 4. 스케치 (I2C 2004 LCD 표시) ====
* 라이브러리: LiquidCrystal_I2C (주소 기본 0x27, 필요 시 0x3F로 변경)
* 시리얼 모니터(115200bps)는 선택 사항(디버깅용)
// Arduino UNO + I2C 2004 LCD: PC900V Optocoupler Tester
// D9: drive(220Ω 통해 PC900V LED+), D2: sense(INT0, RL=1k~2.2kΩ로 +5V 풀업)
// LCD: 20x4 I2C (addr 0x27). 필요 시 0x3F 등으로 변경.
#include
#include
#define LCD_ADDR 0x27
LiquidCrystal_I2C lcd(LCD_ADDR, 20, 4);
const uint8_t DRIVE_PIN = 9; // Opto LED drive
const uint8_t SENSE_PIN = 2; // Opto output sense (INT0)
volatile uint32_t edgeCount = 0;
volatile uint32_t lastEdgeUs = 0;
volatile uint8_t lastState = 0;
volatile uint32_t highMin = 0xFFFFFFFF, highMax = 0, highSum = 0, highCnt = 0;
volatile uint32_t lowMin = 0xFFFFFFFF, lowMax = 0, lowSum = 0, lowCnt = 0;
void onSenseEdge() {
uint32_t now = micros();
uint8_t state = digitalRead(SENSE_PIN); // HIGH=1, LOW=0
uint32_t dt = now - lastEdgeUs;
if (lastEdgeUs != 0) {
if (state == LOW) {
// 방금 HIGH->LOW: 직전 구간은 HIGH 구간 길이
if (dt < highMin) highMin = dt;
if (dt > highMax) highMax = dt;
highSum += dt; highCnt++;
} else {
// 방금 LOW->HIGH: 직전 구간은 LOW 구간 길이
if (dt < lowMin) lowMin = dt;
if (dt > lowMax) lowMax = dt;
lowSum += dt; lowCnt++;
}
}
lastEdgeUs = now;
lastState = state;
edgeCount++;
}
void resetStats() {
noInterrupts();
edgeCount = 0;
lastEdgeUs = 0;
lastState = digitalRead(SENSE_PIN);
highMin = lowMin = 0xFFFFFFFF;
highMax = lowMax = 0;
highSum = lowSum = 0;
highCnt = lowCnt = 0;
interrupts();
}
void lcdHeader(const char* phase) {
lcd.clear();
lcd.setCursor(0,0); lcd.print("Opto Tester (UNO)");
lcd.setCursor(0,1); lcd.print(phase);
}
void showPhase1(bool ledOn, int senseVal) {
lcd.setCursor(0,2);
lcd.print("LED:");
lcd.print(ledOn ? "ON " : "OFF");
lcd.print(" SENSE:");
lcd.print(senseVal ? "HIGH" : "LOW ");
lcd.setCursor(0,3);
lcd.print("Expect ON->LOW, OFF->HIGH ");
}
void showPhase2Stats(uint32_t freqHz,
uint32_t edges,
uint32_t hMin, uint32_t hMax, uint32_t hAvg,
uint32_t lMin, uint32_t lMax, uint32_t lAvg) {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Phase2 @");
lcd.print(freqHz);
lcd.print("Hz Edg:");
lcd.print(edges);
lcd.setCursor(0,1);
lcd.print("HIGH us min/"); lcd.print(hMin);
lcd.print(" max/"); lcd.print(hMax);
lcd.setCursor(0,2);
lcd.print("HIGH avg:"); lcd.print(hAvg); lcd.print(" ");
lcd.setCursor(0,3);
lcd.print("LOW avg:"); lcd.print(lAvg); lcd.print(" ");
}
void phase1_basicToggle(uint16_t ms = 500, uint8_t repeats = 6) {
lcdHeader("Phase1: Slow Toggle");
for (uint8_t i=0; i
==== 5. 운용 팁 ====
* RL(출력 풀업/로드)은 **1k~2.2kΩ** 권장(속도/전류 밸런스 양호). 4.7kΩ도 가능하나 에지가 둔해질 수 있음.
* 파형이 불안정하면 **74HC14(1게이트)** 를 D2 앞에 추가.
* Phase2에서 1 kHz/5 kHz 측정 시 평균 펄스폭이 반주기(500 µs/100 µs) 근처이고 엣지 카운트가 안정적이면 정상.
* MIDI(31.25 kbps)는 비트 폭이 32 µs 수준으로, 본 테스트에서 5 kHz(100 µs 반주기)까지 안정적이면 기본 동작 마진은 충분한 편.
==== 6. 문제 해결 체크리스트 ====
* D9→220Ω→PC900V Anode(+) / Cathode(−)→GND 배선 재확인
* RL 값/배선 길이 확인(1k~2.2kΩ 권장)
* GND 공통, 전원 5 V 안정성 확인
* LCD 주소(0x27/0x3F) 확인 및 변경
* (선택) 74HC14로 신호 정형 후 D2로 입력