GPIO는 라즈베리파이의 손과 발이다
지금까지 우리는 라즈베리파이를 작은 컴퓨터처럼 사용했다. 운영체제를 설치하고, 터미널에서 명령어를 실행하고, 파이썬 코드를 작성했다. 이제 그 코드가 화면 안에서만 끝나지 않고 실제 부품을 움직이게 만들 차례다.
GPIO는 General Purpose Input/Output의 줄임말이다. 뜻은 "일반적인 목적으로 쓰는 입력과 출력 핀"이다. 라즈베리파이 보드 위의 40핀 헤더가 바로 그 연결 지점이다. 이 핀을 이용하면 LED를 켜고, 버튼 눌림을 읽고, 센서 값을 받아오고, 부저나 릴레이 같은 장치를 제어할 수 있다.
GPIO를 다룰 때 가장 먼저 이해해야 할 말은 입력과 출력이다.
출력: 라즈베리파이가 바깥으로 신호를 보낸다. 예를 들어 LED 켜기.
입력: 바깥의 상태를 라즈베리파이가 읽는다. 예를 들어 버튼이 눌렸는지 확인하기.
이번 장의 핵심은 단순하다. 파이썬 코드로 GPIO 핀에 전기 신호를 보내 LED 하나를 켜고 끈다. 그리고 버튼 입력을 읽어 LED 동작을 바꾼다. 이 작은 경험이 라즈베리파이 프로젝트의 출발점이다.
AI 생성 이미지
핀 번호는 두 가지 방식으로 부른다
GPIO를 처음 배울 때 자주 헷갈리는 부분이 핀 번호다. 라즈베리파이의 40핀 헤더는 실제 위치를 기준으로 1번부터 40번까지 셀 수 있다. 이것을 보통 물리 핀 번호 또는 BOARD 방식이라고 한다.
하지만 파이썬 코드에서는 브로드컴 칩의 GPIO 번호를 사용하는 경우도 많다. 이것을 BCM 방식이라고 한다. 예를 들어 코드에서 GPIO18이라고 부르는 핀은 물리 핀 18번이 아니라, 브로드컴 칩 기준의 GPIO18이다. 이 GPIO18은 실제 헤더에서는 물리 핀 12번에 해당한다.
정리하면 다음과 같다.
| 방식 | 의미 | 예 |
|---|---|---|
| BOARD | 헤더의 실제 위치 번호 | 물리 핀 12번 |
| BCM | 브로드컴 칩의 GPIO 번호 | GPIO18 |
파이썬에서 RPi.GPIO 라이브러리를 사용할 때는 어떤 번호 체계를 쓸지 먼저 선언해야 한다. BOARD 방식과 BCM 방식은 둘 다 사용할 수 있지만, 코드 시작 부분에서 명확히 정해야 한다1. 이 장에서는 GPIO 자료와 예제가 많고, 핀 이름을 이해하기 쉬운 BCM 방식을 사용한다.
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)이 두 줄은 중요하다. 첫 줄은 GPIO 기능을 쓰기 위해 라이브러리를 불러온다. 둘째 줄은 앞으로 코드에서 핀 번호를 BCM 기준으로 쓰겠다는 뜻이다.
GPIO 출력은 3.3V 신호다
GPIO 핀에서 HIGH 신호를 보내면 해당 핀은 약 3.3V가 된다. LOW 신호를 보내면 0V가 된다1. 이 차이를 이용해 LED를 켜고 끈다.
하지만 전기는 한쪽으로 나가기만 해서는 동작하지 않는다. 전류가 흐르려면 나가는 길과 돌아오는 길이 모두 필요하다. 라즈베리파이 회로에서 그 기준점이 GND다. GND는 그라운드, 즉 0V 기준점이다.
LED 회로를 단순하게 생각해 보자.
GPIO18에서 3.3V 출력
→ LED와 저항을 지나 전류가 흐름
→ GND로 돌아감
→ LED가 켜짐즉 LED가 켜지려면 다음 세 가지가 필요하다.
GPIO 핀에서 나오는 출력 신호
LED와 저항으로 이어진 전류의 길
전류가 돌아갈 GND 연결
초보자는 GND를 빼먹는 경우가 많다. GPIO 핀만 연결하면 신호가 전달될 것 같지만, 회로가 닫히지 않으면 전류가 안정적으로 흐르지 않는다. LED가 켜지지 않는다면 가장 먼저 GND 연결을 확인하자.
LED 회로에 필요한 부품
이번 실습에는 많은 부품이 필요하지 않다.
라즈베리파이
브레드보드
LED 1개
330Ω 안팎의 저항 1개
점퍼선 몇 개
브레드보드는 납땜 없이 부품을 꽂아 회로를 만드는 실습용 판이다. 내부에서 같은 줄이나 같은 레일끼리 연결되어 있으므로, 부품 다리를 적절한 구멍에 꽂아 전기가 흐를 길을 만들 수 있다.
LED에는 방향이 있다. 긴 다리는 애노드라고 하며 +쪽에 연결한다. 짧은 다리는 캐소드라고 하며 GND 쪽에 연결한다2. LED를 반대로 연결하면 보통 고장 나지는 않지만 불이 켜지지 않는다. 불이 켜지지 않을 때는 코드만 의심하지 말고 LED 방향도 확인해야 한다.
저항은 방향이 없다. 어느 쪽으로 연결해도 된다. 중요한 것은 LED와 저항이 직렬로 연결되어야 한다는 점이다. 직렬은 전류가 한 길로 차례대로 지나가는 연결이다.
예를 들면 다음과 같이 연결할 수 있다.
GPIO18 → LED 긴 다리 → LED 짧은 다리 → 저항 → GND또는 이렇게 연결해도 된다.
GPIO18 → 저항 → LED 긴 다리 → LED 짧은 다리 → GND두 방식 모두 LED와 저항이 한 줄로 이어져 있으므로 괜찮다.
왜 저항이 꼭 필요할까
LED는 작은 전류로도 빛을 낸다. 문제는 저항 없이 GPIO와 GND 사이에 LED만 연결하면 전류가 너무 많이 흐를 수 있다는 점이다. 그러면 LED가 손상될 수 있고, 심하면 라즈베리파이의 GPIO 핀에도 무리가 간다.
저항은 전류가 지나가는 길을 조금 좁혀 주는 부품이라고 생각하면 쉽다. 물이 흐르는 호스에 비유하면, 저항은 물이 한꺼번에 너무 많이 쏟아지지 않도록 흐름을 제한하는 역할을 한다. LED 회로에서 330Ω 정도의 저항을 함께 쓰는 이유가 여기에 있다2.
처음에는 "LED 하나 켜는 데 왜 부품을 하나 더 써야 하지?"라고 느낄 수 있다. 하지만 전자회로에서 부품을 보호하는 습관은 매우 중요하다. 특히 라즈베리파이의 GPIO는 실험용 신호 핀이지만, 무한히 튼튼한 전원 공급 장치가 아니다. GPIO는 외부 부품에 신호를 주는 용도이지, 큰 전류를 마음껏 공급하는 용도가 아니다.
LED 연결하기
배선을 바꾸기 전에는 라즈베리파이를 종료하고 전원을 분리하자. GPIO 핀 주변에서 점퍼선이 잘못 닿으면 쇼트가 날 수 있다. 쇼트는 전기가 의도하지 않은 짧은 길로 흘러 부품을 손상시키는 상황이다.
이번 실습에서는 다음 핀을 사용한다.
LED 출력: BCM GPIO18
GND: 라즈베리파이의 GND 핀 중 하나
GPIO18은 물리 핀 12번이다. 핀 번호를 볼 때는 반드시 지금 쓰는 기준이 BCM인지 BOARD인지 확인해야 한다.
연결 순서는 다음과 같다.
라즈베리파이 전원을 끈다.
GPIO18에서 브레드보드로 점퍼선을 연결한다.
그 선이 연결된 줄에 LED의 긴 다리를 꽂는다.
LED의 짧은 다리 쪽에 저항을 이어 꽂는다.
저항의 반대쪽을 GND와 연결한다.
배선이 서로 닿아 쇼트가 나지 않는지 확인한다.
라즈베리파이 전원을 켠다.
브레드보드 구조에 따라 실제 위치는 달라질 수 있다. 중요한 것은 위치 자체가 아니라 전류의 흐름이다. GPIO18에서 출발한 전류가 LED와 저항을 지나 GND로 돌아가야 한다.
파이썬으로 LED 켜고 끄기
이제 터미널에서 실습용 폴더를 만들고 파일을 작성하자.
mkdir -p ~/projects/gpio_led
cd ~/projects/gpio_led
nano led_test.py파일에 다음 코드를 입력한다.
import RPi.GPIO as GPIO
import time
LED_PIN = 18
GPIO.setmode(GPIO.BCM)
GPIO.setup(LED_PIN, GPIO.OUT)
try:
GPIO.output(LED_PIN, GPIO.HIGH)
time.sleep(2)
GPIO.output(LED_PIN, GPIO.LOW)
time.sleep(1)
finally:
GPIO.cleanup()저장한 뒤 실행한다.
python3 led_test.py코드를 살펴보자.
LED_PIN = 18LED를 연결한 핀 번호를 변수로 저장했다. 여기서 18은 BCM 번호다. 앞에서 GPIO.setmode(GPIO.BCM)이라고 선언했기 때문이다.
GPIO.setup(LED_PIN, GPIO.OUT)이 줄은 GPIO18을 출력 모드로 설정한다. 출력 모드는 라즈베리파이가 바깥으로 신호를 보내는 상태다.
GPIO.output(LED_PIN, GPIO.HIGH)이 줄은 GPIO18을 HIGH 상태로 만든다. 즉 3.3V 신호를 내보낸다. 회로가 올바르게 연결되어 있으면 LED가 켜진다.
GPIO.output(LED_PIN, GPIO.LOW)이 줄은 GPIO18을 LOW 상태로 만든다. 즉 0V가 되어 LED가 꺼진다.
마지막의 GPIO.cleanup()은 사용한 GPIO 설정을 정리한다1. 프로그램이 끝날 때 핀 상태를 정리하는 습관을 들이면 다음 실행이나 다른 프로젝트에서 예상하지 못한 동작을 줄일 수 있다.
LED 깜빡이기
LED를 한 번 켜고 끄는 데 성공했다면 반복문을 사용해 깜빡이게 만들 수 있다.
import RPi.GPIO as GPIO
import time
LED_PIN = 18
GPIO.setmode(GPIO.BCM)
GPIO.setup(LED_PIN, GPIO.OUT)
try:
while True:
GPIO.output(LED_PIN, GPIO.HIGH)
time.sleep(0.5)
GPIO.output(LED_PIN, GPIO.LOW)
time.sleep(0.5)
except KeyboardInterrupt:
print("프로그램을 종료합니다.")
finally:
GPIO.cleanup()이 코드는 while True 때문에 계속 실행된다. 멈추려면 터미널에서 Ctrl + C를 누른다. 그러면 KeyboardInterrupt가 발생하고, 마지막에 GPIO.cleanup()이 실행된다.
여기까지 하면 소프트웨어가 실제 세계를 제어한다는 느낌을 받을 수 있다. 파이썬 코드의 HIGH 한 줄이 전기 신호가 되고, 그 신호가 LED의 빛으로 바뀐다.
버튼 입력으로 LED 제어하기
이제 출력만 하지 말고 입력도 받아 보자. 버튼을 누르면 LED가 켜지고, 버튼을 떼면 LED가 꺼지도록 만든다. 이 구조는 앞으로 센서와 액추에이터를 연결할 때도 그대로 쓰인다.
이번 실습에서는 다음 핀을 사용한다.
LED 출력: BCM GPIO18
버튼 입력: BCM GPIO17
버튼의 반대쪽: GND
버튼은 GPIO17과 GND 사이에 연결한다. 코드에서는 GPIO17을 입력으로 설정하고 내부 풀업 저항을 사용한다.
풀업 저항은 입력 핀이 아무것도 눌리지 않았을 때 값을 HIGH 쪽으로 안정시키는 역할을 한다. 버튼을 누르면 GPIO17이 GND와 연결되어 LOW가 된다. 그래서 이 방식에서는 버튼을 떼면 HIGH, 버튼을 누르면 LOW로 읽힌다.
import RPi.GPIO as GPIO
import time
LED_PIN = 18
BUTTON_PIN = 17
GPIO.setmode(GPIO.BCM)
GPIO.setup(LED_PIN, GPIO.OUT)
GPIO.setup(BUTTON_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
try:
while True:
if GPIO.input(BUTTON_PIN) == GPIO.LOW:
GPIO.output(LED_PIN, GPIO.HIGH)
print("버튼 눌림: LED 켜짐")
else:
GPIO.output(LED_PIN, GPIO.LOW)
print("버튼 떼어짐: LED 꺼짐")
time.sleep(0.1)
except KeyboardInterrupt:
print("프로그램을 종료합니다.")
finally:
GPIO.cleanup()GPIO.setup(BUTTON_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)은 GPIO17을 입력 모드로 설정하고 내부 풀업을 켠다. GPIO.input(BUTTON_PIN)은 핀의 현재 상태를 읽는다. HIGH이면 참에 가까운 값, LOW이면 거짓에 가까운 값으로 다룰 수 있다1.
여기서 중요한 흐름은 다음과 같다.
버튼 상태 읽기 → 조건 판단 → LED 출력 변경 → 다시 반복앞 장에서 배운 파이썬의 조건문과 반복문이 전자회로와 만나는 순간이다. 버튼이라는 입력이 라즈베리파이에 들어오고, 라즈베리파이는 그 상태를 판단한 뒤 LED라는 출력 장치를 제어한다.
잘 안 될 때 확인할 것
LED가 켜지지 않는다고 바로 고장이라고 생각할 필요는 없다. 대부분은 작은 실수다.
먼저 핀 번호 체계를 확인하자. 코드에서 GPIO.setmode(GPIO.BCM)을 사용했다면 18은 물리 핀 18번이 아니라 BCM GPIO18이다. GPIO18은 물리 핀 12번이다.
다음으로 LED 방향을 확인한다. 긴 다리는 +쪽, 짧은 다리는 GND 쪽이다. LED는 극성이 맞아야 켜진다.
저항이 빠지지 않았는지도 확인한다. LED가 잠깐 켜졌다고 해서 저항 없이 계속 실험하면 안 된다. LED와 GPIO 핀을 보호하려면 저항을 함께 써야 한다.
마지막으로 GND 연결을 확인한다. GPIO에서 신호가 나와도 돌아오는 길이 없으면 회로가 완성되지 않는다. GPIO, LED, 저항, GND가 하나의 길로 이어져 있는지 차분히 따라가 보자.
GPIO 실습은 처음에는 느리게 하는 편이 좋다. 배선을 바꿀 때는 전원을 끄고, 핀 번호를 다시 확인하고, 코드는 짧게 실행한다. 이 습관이 라즈베리파이를 오래 안전하게 사용하는 가장 좋은 방법이다.
참고
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.