스위치를 이용한 3 Color LED 제어 > 스마트기기시스템

본문 바로가기

[실습] 스위치를 이용한 3 Color LED 제어

필기자
2025-03-19 09:48 761 1
  • - 첨부파일 : KakaoTalk_20240223_175217786.mp4 (4.7M) - 다운로드

본문

스위치를 이용한 3 Color LED 제어

목 적
  • 라즈베리파이에 GPIO 이벤트 방식에 대해 이해한다.
  • 라즈베리파이에 복합적인 액츄레이터 모듈 구현에 대해 이해한다.
목 차
1. LED 버튼 앳츄레이터 묘듈 설치
2. LED 버튼 앳츄레이터 묘듈 구동

1. LED 버튼 앳츄레이터 뮤듈 설치
  • YwRobot LED 버튼 모듈
    • 내장된 LED를 가진 푸시버튼 스위치로 버튼을 누르면 LED가 켜지거나 꺼진다.
    • 학습, 실험, 프로토타이핑에 주로 사용되며, 마이크로컨트롤러 보드에 쉽게 연결할 수 있다.
    • 전원(VCC), 접지(GND), 신호(OUT) 등의 핀을 포함하며, 디지털 입력으로 버튼 상태를 마이크로컨트롤러가 읽는다.
    • 다양한 전자 프로젝트에 사용자 인터페이스 요소로 활용된다.
    • GPIO 연결
      • GND  : Ground 접지(핀 14)
      • VCC : 5V Power(핀 2)
      • OUT : GPIO 18(핀 12)
3529946166_jkFaMZHr_2eab44a214ed250463cd60b73c405e237f33d967.png


3529946166_FDwUP0dR_5036660ebb036ac3a8b25abd023144426094f275.png

2. LED 버튼 앳츄레이터 묘듈 구동
  • 라즈베리파이 가상환경에서 파이썬 코딩
    • VSCode에서 3_color_led_switch.py 파일 생성
    • GPIO 17, 27, 22 핀을 출력 모드로 설정, GPIO 18 핀을 입력 모드로 설정
    • GPIO 18 핀의 이벤트에 따라 LED 색상 변경
3529946166_JHyt5wq8_30dee2be69065df679cec29c5e6c7df515489046.png

import RPi.GPIO as GPIO
import time

# 핀 번호 설정
BUTTON_PIN = 18  # 버튼이 연결될 GPIO 핀 번호
BLUE_PIN = 17
GREEN_PIN = 22
RED_PIN = 27

# 글로벌 변수
led_state = 0  # LED 상태 (0: 모두 꺼짐, 1: 파란색, 2: 초록색, 3: 빨간색)

# GPIO 설정 함수
def setup_gpio():
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(BUTTON_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    GPIO.setup(BLUE_PIN, GPIO.OUT)
    GPIO.setup(GREEN_PIN, GPIO.OUT)
    GPIO.setup(RED_PIN, GPIO.OUT)

# 모든 LED 끄는 함수
def turn_off_leds():
    global led_state
    led_state = 0
    GPIO.output(BLUE_PIN, GPIO.LOW)
    GPIO.output(GREEN_PIN, GPIO.LOW)
    GPIO.output(RED_PIN, GPIO.LOW)

# LED 상태 변경 함수
def change_led_state():
    global led_state
    led_state += 1
    if led_state > 3:
        led_state = 1
    if led_state == 1:
        GPIO.output(BLUE_PIN, GPIO.HIGH)
        GPIO.output(GREEN_PIN, GPIO.LOW)
        GPIO.output(RED_PIN, GPIO.LOW)
    elif led_state == 2:
        GPIO.output(BLUE_PIN, GPIO.LOW)
        GPIO.output(GREEN_PIN, GPIO.HIGH)
        GPIO.output(RED_PIN, GPIO.LOW)
    elif led_state == 3:
        GPIO.output(BLUE_PIN, GPIO.LOW)
        GPIO.output(GREEN_PIN, GPIO.LOW)
        GPIO.output(RED_PIN, GPIO.HIGH)

# 버튼 이벤트 콜백 함수
def button_callback(channel):
    start_time = time.time()

    # 버튼이 눌린 상태 유지 확인
    while GPIO.input(channel) == GPIO.LOW:
        # 누린 상태는 LOW, 뗀 상태는 HIGH
        # 버튼이 눌린 상태이면 무한반복 -> 버튼이 뗀 상태이면 반복문 빠짐
        # GPIO.FALLING 상태로 눌린 순간 이벤트가 발생하지만 GPIO.RISING 처럼 움직임(버튼을 뗀 순간 다음 로직 실행).
        time.sleep(0.01)  # 디바운싱 대기

    button_press_duration = time.time() - start_time
    if button_press_duration >= 1:  # 1초 이상 누르면 LED 끄기
        turn_off_leds()
    else:  # 짧게 누르면 LED 색상 변경
        change_led_state()

# GPIO 종료 함수
def cleanup_gpio():
    GPIO.cleanup()

# 메인 함수
def main():
    setup_gpio()
    # 프로그램 시작 시 모든 LED 끄기
    turn_off_leds()
    # 버튼 이벤트 감지 설정
    # GPIO.FALLING 는 누르는 순간(LOW) 이벤트 발생
    GPIO.add_event_detect(BUTTON_PIN, GPIO.FALLING, callback=button_callback, bouncetime=300)

    try:
        while True:
            time.sleep(0.1)
    except KeyboardInterrupt:
        pass
    finally:
        cleanup_gpio()

# 실행 진입점
if __name__ == "__main__":
    main()
  • GPIO.add_event_detect()
    • GPIO 핀에 이벤트 감지(callback) 기능을 추가하는 데 사용된다.
    • 특정 핀의 상태 변경(예: 라이징 엣지, 폴링 엣지)을 비동기적으로 감지한다.
    • 변경이 감지될 때마다 지정된 콜백 함수를 자동으로 호출할 수 있다. 
인자 이름 데이터 타입 기능
channel int 이벤트 감지를 추가할 GPIO 핀의 번호.
GPIO.RISING, GPIO.FALLING, GPIO.BOTH   감지할 이벤트의 종류를 지정. RISING은 0에서 1로의 변화, FALLING은 1에서 0으로의 변화, BOTH는 둘 다 감지.
callback function 이벤트가 감지될 때 호출될 콜백 함수.
bouncetime int 선택적. 이벤트 콜백 호출 사이에 적용될 디바운스(신호안정) 시간(밀리초 단위).
 
이벤트 감지 플레그 설명
GPIO.RISING GPIO 핀의 신호가 LOW에서 HIGH로 변할 때
GPIO.FALLING GPIO 핀의 신호가 HIGH에서 LOW로 변할 때
GPIO.BOTH GPIO 핀의 신호가 변화할 때(LOW에서 HIGH 또는 HIGH에서 LOW)
 
  • 3_color_led_switch.py 실행
    • VSCode > 하단 터미널 > python 3_color_led_switch.py 실행
3529946166_msx9dXOL_fc0a9561daaa2d6da4caa13409dfa39f308f94f5.png

3529946166_z0LxMApW_1c1878d201961d7e9d1eda6478b11c9dae54af24.gif

[문제: RGB LED 색상 조합 제어 실습]
  • 하나의 공통형 RGB LED를 사용하여, 버튼을 누를 때마다 LED 색상이 아래 순서대로 변경되도록 하시오.
    • 3_color_led_switch_ranibow.py 파일 생성
    • 버튼 누를 때마다 색상 변경 순서
      • 1. 빨강
      • 2. 초록
      • 3. 파랑
      • 4. 노랑
      • 5. 하늘
      • 6. 보라
      • 7. 흰색
      • 8. OFF
※ 버튼은 짧게 누를 때만 반응, 길게 눌렀을 때는 무시.
※ 버튼은 GPIO.FALLING 이벤트로 감지.
※ LED 색의 정보는 배열을[0~7] 활용 함. 


import RPi.GPIO as GPIO
import time
# 핀 설정
BUTTON_PIN = 18
RED_PIN = 27
GREEN_PIN = 22
BLUE_PIN = 17

# 상태 변수
led_state = 0  # 0: OFF, 1~7: 색 조합
# GPIO 설정
def setup_gpio():
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(BUTTON_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    GPIO.setup(RED_PIN, GPIO.OUT, initial=GPIO.LOW)
    GPIO.setup(GREEN_PIN, GPIO.OUT, initial=GPIO.LOW)
    GPIO.setup(BLUE_PIN, GPIO.OUT, initial=GPIO.LOW)
# LED 색상 설정
def set_color(state):
    colors = (
        (0, 0, 0),  # off
        (1, 0, 0),  # 빨강
        (0, 1, 0),  # 초록
        (0, 0, 1),  # 파랑
        (1, 1, 0),  # 노랑
        (0, 1, 1),  # 하늘
        (1, 0, 1),  # 보라
        (1, 1, 1),  # 흰색
    )
    r, g, b = colors[state]
    #GPIO.output(RED_PIN, GPIO.HIGH if r else GPIO.LOW) # r == 1 ? GPIO.HIGH : GPIO.LOW
    #GPIO.output(GREEN_PIN, GPIO.HIGH if g else GPIO.LOW)
    #GPIO.output(BLUE_PIN, GPIO.HIGH if b else GPIO.LOW)
    #GPIO.output(RED_PIN, r) # r == 1 ? GPIO.HIGH : GPIO.LOW
    #GPIO.output(GREEN_PIN, g)
    #GPIO.output(BLUE_PIN, b)
    GPIO.output([RED_PIN, GREEN_PIN, BLUE_PIN], [r,g,b])

# 버튼 콜백
def button_callback(channel):
    global led_state
    start = time.time()
    while GPIO.input(BUTTON_PIN) == GPIO.LOW:
        time.sleep(0.01)
    duration = time.time() - start
    if duration < 1:
        led_state += 1
        if led_state > 7:
            led_state = 0
        set_color(led_state)
# 메인
def main():
    setup_gpio()
    GPIO.add_event_detect(BUTTON_PIN, GPIO.FALLING, callback=button_callback, bouncetime=300)
    try:
        while True:
            time.sleep(0.1)
    except KeyboardInterrupt:
        pass
    finally:
        GPIO.cleanup()
if __name__ == "__main__":
    main()

댓글목록1

필기자님의 댓글

필기자
2025-04-01 11:35
cp -r /usr/lib/python3/dist-packages/RPi /home/pi/iot/iot/lib/python3.11/site-packages/
pip install lgpio
python -c "import RPi.GPIO as GPIO; print(GPIO.__file__)"
게시판 전체검색