반응형
RS485는 산업 현장에서 가장 널리 사용되는 통신 방식 중 하나입니다! 장거리, 다중 장치, 노이즈 내성이 뛰어난 이 통신 방식을 완전히 마스터해보겠습니다. 🔌⚡
🔍 RS485란 무엇인가?
정의와 개요
RS485 (Recommended Standard 485)는 반이중 통신(Half-Duplex)을 지원하는 차동 신호(Differential Signal) 기반의 시리얼 통신 표준입니다.
주요 특징
✅ 장거리 통신: 최대 1.2km
✅ 다중 장치: 최대 32개 노드
✅ 높은 전송 속도: 최대 10Mbps
✅ 강력한 노이즈 내성
✅ 저전력 소모
✅ 산업 표준 (EIA-485)
⚡ RS485의 핵심 원리
차동 신호 (Differential Signal)
RS485의 핵심은 두 개의 선(A+, B-)을 사용한 차동 신호입니다.
논리 1 (Mark): A+ > B+ (약 +2V 이상 차이)
논리 0 (Space): A+ < B- (약 -2V 이상 차이)
예시:
A+ = +5V, B- = +2V → 차이 = +3V → 논리 1
A+ = +2V, B- = +5V → 차이 = -3V → 논리 0
노이즈 제거 원리
외부 노이즈가 두 선에 동일하게 영향을 미침
→ 차이값은 변하지 않음
→ 데이터 손실 없음!
예시:
노이즈 전: A+=+5V, B-=+2V (차이=+3V)
노이즈 후: A+=+6V, B-=+3V (차이=+3V) ← 동일!
🔌 하드웨어 구성
기본 연결 구조
Device 1 ─┬─ A+ ────────────── A+ ─┬─ Device 2
└─ B- ────────────── B- ─┘
터미네이션 저항 (120Ω)을 양 끝에 연결
핀 배치 및 연결
표준 핀 구성:
- A+ (또는 D+): 차동 신호 양극
- B- (또는 D-): 차동 신호 음극
- GND: 신호 기준점 (선택사항)
터미네이션 저항
목적: 신호 반사 방지
값: 120Ω (특성 임피던스와 매칭)
위치: 통신 라인의 양 끝
📊 RS485 vs 다른 통신 방식
통신 방식 비교표
특성 | RS232 | RS422 | RS485 | I2C | SPI |
---|---|---|---|---|---|
최대 거리 | 15m | 1.2km | 1.2km | 1m | 1m |
최대 장치 | 2개 | 10개 | 32개 | 127개 | 제한없음 |
최대 속도 | 115kbps | 10Mbps | 10Mbps | 400kbps | 수십MHz |
선 개수 | 3선 | 4선 | 2선 | 2선 | 3+선 |
노이즈 내성 | 낮음 | 높음 | 높음 | 낮음 | 낮음 |
산업용 | ❌ | ⭕ | ⭕ | ❌ | ❌ |
RS485가 우수한 이유
장거리: 차동 신호로 신호 감쇠 최소화
다중 장치: 버스 토폴로지 지원
노이즈 내성: 차동 신호로 공통 모드 노이즈 제거
안정성: 산업 환경에서 검증된 신뢰성
🛠️ 실제 구현 방법
1. 아두이노 + RS485 모듈
하드웨어 연결
아두이노 UNO ─── RS485 모듈
VCC ──────────── 5V
GND ──────────── GND
RO(수신) ─────── 핀 2 (SoftwareSerial RX)
DI(송신) ─────── 핀 3 (SoftwareSerial TX)
DE/RE ─────────── 핀 4 (송수신 제어)
A+ ─────────────── 터미널 블록
B- ─────────────── 터미널 블록
마스터 장치 코드
#include <SoftwareSerial.h>
SoftwareSerial rs485(2, 3); // RX, TX
const int enablePin = 4; // DE/RE 핀
void setup() {
Serial.begin(9600);
rs485.begin(9600);
pinMode(enablePin, OUTPUT);
digitalWrite(enablePin, LOW); // 수신 모드
}
void sendCommand(String command) {
digitalWrite(enablePin, HIGH); // 송신 모드
delay(1);
rs485.print(command);
rs485.flush(); // 송신 완료까지 대기
digitalWrite(enablePin, LOW); // 수신 모드
}
void loop() {
// 슬레이브에게 명령 전송
sendCommand("GET_TEMP");
delay(100);
// 응답 수신
if (rs485.available()) {
String response = rs485.readString();
Serial.println("응답: " + response);
}
delay(1000);
}
슬레이브 장치 코드
#include <SoftwareSerial.h>
SoftwareSerial rs485(2, 3);
const int enablePin = 4;
void setup() {
Serial.begin(9600);
rs485.begin(9600);
pinMode(enablePin, OUTPUT);
digitalWrite(enablePin, LOW); // 수신 모드
}
void sendResponse(String response) {
digitalWrite(enablePin, HIGH); // 송신 모드
delay(1);
rs485.print(response);
rs485.flush();
digitalWrite(enablePin, LOW); // 수신 모드
}
void loop() {
if (rs485.available()) {
String command = rs485.readString();
command.trim();
if (command == "GET_TEMP") {
float temperature = 25.6; // 센서에서 읽은 온도
sendResponse(String(temperature));
}
}
}
2. 라즈베리파이 + RS485 HAT
하드웨어 설정
# RS485 HAT 활성화
sudo raspi-config
# Interface Options → Serial Port → Yes
# 시리얼 콘솔 비활성화, 하드웨어 활성화
Python 코드 예제
import serial
import time
import RPi.GPIO as GPIO
# RS485 설정
rs485_port = '/dev/ttyS0'
baud_rate = 9600
enable_pin = 18 # DE/RE 핀
# GPIO 설정
GPIO.setmode(GPIO.BCM)
GPIO.setup(enable_pin, GPIO.OUT)
GPIO.output(enable_pin, GPIO.LOW) # 수신 모드
# 시리얼 포트 열기
ser = serial.Serial(rs485_port, baud_rate, timeout=1)
def send_data(data):
"""RS485로 데이터 송신"""
GPIO.output(enable_pin, GPIO.HIGH) # 송신 모드
time.sleep(0.001) # 1ms 대기
ser.write(data.encode())
ser.flush() # 송신 완료 대기
time.sleep(0.001)
GPIO.output(enable_pin, GPIO.LOW) # 수신 모드
def receive_data():
"""RS485로 데이터 수신"""
if ser.in_waiting > 0:
return ser.read(ser.in_waiting).decode().strip()
return None
try:
while True:
# 데이터 송신
send_data("Hello RS485!")
time.sleep(0.1)
# 응답 수신
response = receive_data()
if response:
print(f"수신: {response}")
time.sleep(1)
except KeyboardInterrupt:
ser.close()
GPIO.cleanup()
🔧 Modbus RTU 프로토콜
Modbus RTU 개요
Modbus RTU는 RS485 통신에서 가장 널리 사용되는 프로토콜입니다.
프레임 구조
[장치ID][기능코드][데이터][CRC]
예시: 01 03 00 00 00 02 C4 0B
- 01: 슬레이브 주소 (1번)
- 03: 기능 코드 (Read Holding Registers)
- 00 00: 시작 주소 (0번)
- 00 02: 레지스터 수 (2개)
- C4 0B: CRC 체크섬
주요 기능 코드
01: Read Coils (코일 읽기)
02: Read Discrete Inputs (입력 상태 읽기)
03: Read Holding Registers (홀딩 레지스터 읽기)
04: Read Input Registers (입력 레지스터 읽기)
05: Write Single Coil (단일 코일 쓰기)
06: Write Single Register (단일 레지스터 쓰기)
Python Modbus 구현
import modbus_tk.defines as cst
import modbus_tk.modbus_rtu as modbus_rtu
import serial
# RS485 포트 설정
rs485_port = '/dev/ttyUSB0'
master = modbus_rtu.RtuMaster(
serial.Serial(port=rs485_port,
baudrate=9600,
bytesize=8,
parity='N',
stopbits=1)
)
master.set_timeout(1.0)
try:
# 슬레이브 1번에서 레지스터 0-1 읽기
result = master.execute(1, cst.READ_HOLDING_REGISTERS, 0, 2)
print(f"레지스터 값: {result}")
# 슬레이브 1번의 레지스터 0에 값 쓰기
master.execute(1, cst.WRITE_SINGLE_REGISTER, 0, output_value=1234)
except Exception as e:
print(f"통신 오류: {e}")
finally:
master.close()
🌐 Node-RED RS485 연동
node-red-contrib-modbus 사용
// Modbus Read 노드 설정
{
"unitid": 1,
"fc": 3,
"start": 0,
"count": 2,
"server": {
"type": "serial",
"serialPort": "/dev/ttyUSB0",
"serialBaudrate": 9600,
"serialDatabits": 8,
"serialStopbits": 1,
"serialParity": "none"
}
}
데이터 처리 Function
// RS485 Modbus 데이터 파싱
if (msg.payload && Array.isArray(msg.payload)) {
var humidity = msg.payload[0] / 10;
var temperature = msg.payload[1] / 10;
return {
payload: {
temperature: temperature,
humidity: humidity,
timestamp: new Date().toISOString()
},
topic: "sensor_data"
};
}
🚨 문제 해결 가이드
일반적인 문제들
1. 통신이 전혀 안 되는 경우
점검 사항:
✅ A+, B- 선 연결 확인
✅ 터미네이션 저항 120Ω 연결
✅ 전원 공급 상태 확인
✅ 보드레이트 일치 확인
✅ 장치 주소(Unit ID) 확인
2. 간헐적 통신 오류
원인과 해결책:
- 노이즈 → 실드 케이블 사용, 접지 개선
- 신호 반사 → 터미네이션 저항 확인
- 전원 문제 → 안정된 전원 공급
- 케이블 불량 → 케이블 교체
3. 데이터 손상
체크 포인트:
- CRC 에러 증가 → 케이블 품질, 길이 확인
- 프레이밍 에러 → 보드레이트, 패리티 확인
- 오버런 에러 → 송수신 타이밍 조정
디버깅 도구
시리얼 모니터링
# Linux에서 RS485 통신 모니터링
sudo minicom -D /dev/ttyUSB0 -b 9600
# Windows에서는 Hercules, RealTerm 등 사용
프로토콜 분석기
추천 도구:
- Modbus Poll (Windows)
- QModMaster (크로스 플랫폼)
- pymodbus (Python 라이브러리)
🏭 산업 현장 응용 사례
1. 공장 자동화 (Factory Automation)
마스터: PLC 또는 HMI
슬레이브:
- 온도 센서 (Unit ID: 1)
- 압력 센서 (Unit ID: 2)
- 모터 드라이버 (Unit ID: 3)
- 밸브 컨트롤러 (Unit ID: 4)
2. 빌딩 자동화 (Building Automation)
시스템 구성:
- 중앙 제어실 (마스터)
- 각 층별 환경 센서
- HVAC 시스템 제어
- 조명 제어 모듈
- 보안 시스템
3. 에너지 관리 시스템
모니터링 대상:
- 전력 미터 (전력 사용량)
- 온습도 센서 (환경 데이터)
- 태양광 인버터 (발전량)
- 배터리 관리 시스템
🔧 고급 구성 및 최적화
멀티 드롭 네트워크
마스터 ─┬─ 슬레이브 1 (Unit ID: 1)
├─ 슬레이브 2 (Unit ID: 2)
├─ 슬레이브 3 (Unit ID: 3)
└─ 슬레이브 32 (Unit ID: 32)
최대 32개 장치까지 연결 가능
중계기 사용
장거리 통신 시 RS485 중계기 사용:
마스터 ── 1.2km ── 중계기 ── 1.2km ── 슬레이브
→ 총 2.4km까지 연장 가능
성능 최적화 팁
✅ 최적 보드레이트 선택
- 근거리: 115200 bps
- 중거리: 38400 bps
- 장거리: 9600 bps
✅ 폴링 간격 조정
- 중요 데이터: 100ms
- 일반 데이터: 1초
- 상태 정보: 10초
✅ 타임아웃 설정
- 응답 대기: 100-500ms
- 재시도 횟수: 3회
- 에러 시 지연: 1초
📈 향후 기술 동향
Industrial Ethernet 전환
현재: RS485 + Modbus RTU
미래: Ethernet + Modbus TCP
EtherCAT, PROFINET 등
IoT 통합
RS485 → Gateway → Internet → Cloud
로컬 RS485 네트워크를 IoT로 확장
무선 RS485
RS485 + 무선 모듈
- LoRa RS485 Gateway
- Wi-Fi RS485 Bridge
- Zigbee RS485 Adapter
마무리하며 🎉
RS485는 산업 현장의 신뢰할 수 있는 동반자입니다!
단순해 보이는 2선 통신이지만, 그 안에는 수십 년간 축적된 산업용 통신의 노하우가 담겨있습니다. 장거리, 다중 장치, 강력한 노이즈 내성이라는 삼박자를 모두 갖춘 완벽한 통신 방식이죠.
아두이노 취미 프로젝트부터 대규모 공장 자동화까지, RS485 하나면 모든 것이 가능합니다! 💪
💬 RS485 경험담을 공유해주세요!
- 어떤 프로젝트에서 RS485를 사용해보셨나요?
- 가장 인상적이었던 통신 거리나 장치 수는?
- RS485 관련 문제 해결 경험이 있다면?
🛒 RS485 시작 키트
- RS485 to USB 컨버터
- RS485 모듈 (MAX485 기반)
- 터미네이션 저항 (120Ω)
- 트위스트 페어 케이블
- 멀티미터
🔗 참고 자료
#RS485 #Modbus #산업통신 #자동화 #IoT #시리얼통신 #차동신호 #공장자동화 #PLC #센서통신
'하드웨어' 카테고리의 다른 글
라즈베리파이 5 GPIO 문제 완전 해결: rpi-lgpio로 Node-RED 정상화하기 (1) | 2025.05.31 |
---|---|
라즈베리파이 USB 카메라 완벽 설정: 연결부터 실시간 스트리밍까지 (0) | 2025.05.30 |
라즈베리파이 GPIO 완전 정복: 기초부터 8채널 릴레이 제어까지 (0) | 2025.05.30 |
Node-RED로 XY-MD02 온습도 센서 실시간 모니터링하기 (1) | 2025.05.29 |
[아두이노&라즈베리파이 완전정복 #4] 전자공학 기초: 알아두면 쓸모있는 기본 지식 (3) | 2025.05.26 |