button_1_callback, ... , buttono_8_callback 로 정의된 동일한 패턴의 함수를 더 간단하게 하는 방법

조회수 739회

밑의 코딩에서 list함수를 이용하여 코딩을 더줄일수 있는 방법이 없을까요? 없거나 비효율 적이면 다른함수를 사용하는 방법을 알려주실수있나요?

import RPi.GPIO as GPIO #GPIO 라이브러리 불러오기
import time #시간 라이브러리 불러오기
import datetime

#I/O 리스트로 지정
IO_do = [22,6,13,19,26,11,27,4]
IO_di = [17,12,16,21,20,18,23,24]
Num = [1,2,3,4,5,6,7,8]
#불필요한 WARNING 제거
GPIO.setwarnings(False)

#GPIO 핀의 번호모드 설정
GPIO.setmode(GPIO.BCM)

#버튼 리스트 변수를 INPUT설정,PULLDOWN 저항 설정
for i in IO_di:
    GPIO.setup([i], GPIO.IN, pull_up_down=GPIO.PUD_DOWN) 
#LED 리스트 변수를 OUTPUT설정
for j in IO_do:
    GPIO.setup([j], GPIO.OUT)

#boolean 변수설정
light_1_on = False
light_2_on = False
light_3_on = False
light_4_on = False
light_5_on = False
light_6_on = False
light_7_on = False
light_8_on = False

#프로그램 시작을 알림
print("start")

#버튼 콜백 함수를 정의함 글로벌 함수 적용
def button_1_callback(ch):
    global light_1_on
    if light_1_on == False:
        GPIO.output(IO_do[0],1)
        print("LED1 ON")
    else:
        GPIO.output(IO_do[0],0)
        print("LED1 OFF")
    light_1_on = not light_1_on

def button_2_callback(ch):
    global light_2_on
    if light_2_on == False:
        GPIO.output(IO_do[1],1)
        print("LED2 ON")
    else:
        GPIO.output(IO_do[1],0)
        print("LED2 OFF")
    light_2_on = not light_2_on

def button_3_callback(ch):
    global light_3_on
    if light_3_on == False:
        GPIO.output(IO_do[2],1)
        print("LED3 ON")
    else:
        GPIO.output(IO_do[2],0)
        print("LED3 OFF")
    light_3_on = not light_3_on

def button_4_callback(ch):
    print(ch)
    global light_4_on
    if light_4_on == False:
        GPIO.output(IO_do[3],1)
        print("LED4 ON")
    else:
        GPIO.output(IO_do[3],0)
        print("LED4 OFF")
    light_4_on = not light_4_on

def button_5_callback(ch):
    print(ch)
    global light_5_on
    if light_5_on == False:
        GPIO.output(IO_do[4],1)
        print("LED5 ON")
    else:
        GPIO.output(IO_do[4],0)
        print("LED5 OFF")
    light_5_on = not light_5_on

def button_6_callback(ch):
    print(ch)
    global light_6_on
    if light_6_on == False:
        GPIO.output(IO_do[5],1)
        print("LED6 ON")
    else:
        GPIO.output(IO_do[5],0)
        print("LED6 OFF")
    light_6_on = not light_6_on

def button_7_callback(ch):
    print(ch)
    global light_7_on
    if light_7_on == False:
        GPIO.output(IO_do[6],1)
        print("LED7 ON")
    else:
        GPIO.output(IO_do[6],0)
        print("LED7 OFF")
    light_7_on = not light_7_on

def button_8_callback(ch):
    print(ch)
    global light_8_on
    if light_8_on == False:
        GPIO.output(IO_do[7],1)
        print("LED8 ON")
    else:
        GPIO.output(IO_do[7],0)
        print("LED8 OFF")
    light_8_on = not light_8_on    
# 이벤트 알림 방식 버튼핀의 Rising신호를 감지하면 콜백함수를 실행
 # 바운스타임을 설정하여 잘못된 신호를 방지합니다.
GPIO.add_event_detect(IO_di[0],GPIO.RISING,callback=button_1_callback, bouncetime=300)
GPIO.add_event_detect(IO_di[1],GPIO.RISING,callback=button_2_callback, bouncetime=300)
GPIO.add_event_detect(IO_di[2],GPIO.RISING,callback=button_3_callback, bouncetime=300)
GPIO.add_event_detect(IO_di[3],GPIO.RISING,callback=button_4_callback, bouncetime=300)
GPIO.add_event_detect(IO_di[4],GPIO.RISING,callback=button_5_callback, bouncetime=300)
GPIO.add_event_detect(IO_di[5],GPIO.RISING,callback=button_6_callback, bouncetime=300)
GPIO.add_event_detect(IO_di[6],GPIO.RISING,callback=button_7_callback, bouncetime=300)
GPIO.add_event_detect(IO_di[7],GPIO.RISING,callback=button_8_callback, bouncetime=300)

while 1:
    time.sleep(0.1)

1 답변

  • import RPi.GPIO as GPIO #GPIO 라이브러리 불러오기
    import time #시간 라이브러리 불러오기
    import datetime
    
    #I/O 리스트로 지정
    IO_do = [22,6,13,19,26,11,27,4]
    IO_di = [17,12,16,21,20,18,23,24]
    Num = [1,2,3,4,5,6,7,8]
    #불필요한 WARNING 제거
    GPIO.setwarnings(False)
    
    #GPIO 핀의 번호모드 설정
    GPIO.setmode(GPIO.BCM)
    
    #버튼 리스트 변수를 INPUT설정,PULLDOWN 저항 설정
    for i in IO_di:
        GPIO.setup([i], GPIO.IN, pull_up_down=GPIO.PUD_DOWN) 
    #LED 리스트 변수를 OUTPUT설정
    for j in IO_do:
        GPIO.setup([j], GPIO.OUT)
    
    #boolean 변수설정
    light_ons = [ False for _ in range(8)]
    
    #프로그램 시작을 알림
    print("start")
    
    #버튼 콜백 함수를 정의함 글로벌 함수 적용
    def button_callback(i):
        def button_callback_(ch):
            print(ch)
            global light_ons
            if light_ons[i] == False:
                GPIO.output(IO_do[i], 1)
                print("LED%d ON"%(i+1))
            else:
                GPIO.output(IO_do[i], 0)
                print("LED%d OFF"%(i+1))
            light_ons[i] = not light_ons[i]
        return button_callback_
    
    # 이벤트 알림 방식 버튼핀의 Rising신호를 감지하면 콜백함수를 실행
    # 바운스타임을 설정하여 잘못된 신호를 방지합니다.
    for i in range(8):
        GPIO.add_event_detect(IO_di[0],GPIO.RISING,callback=lambda i:button_callback(i), bouncetime=300)  
    
    while 1:
        time.sleep(0.1)
    

    이런식으로 하면 될 것 같은데, 한번 해보세요. 무슨 오류가 없을지 모르겠네요.

    아. 람다가 필요 없을것 같네요. 한번 해보세요.

    for i in range(8):
        GPIO.add_event_detect(IO_di[0],GPIO.RISING,callback=button_callback(i), bouncetime=300)  
    
    • Traceback (most recent call last): File "/home/pi/Desktop/test/GPIO test8.py", line 45, in GPIO.add_event_detect(IO_di[0],GPIO.RISING,callback=lambda i:button_callback(i), bouncetime=300) RuntimeError: Conflicting edge detection already enabled for this GPIO channel 알 수 없는 사용자 2021.1.6 11:05
    • 답변 감사합니다! 그런데 위에처럼 오류가 뜨네요 알 수 없는 사용자 2021.1.6 11:06
    • Traceback (most recent call last): File "/home/pi/Desktop/test/GPIO test8.py", line 45, in GPIO.add_event_detect(IO_di[0],GPIO.RISING,callback=button_callback(i), bouncetime=300) RuntimeError: Conflicting edge detection already enabled for this GPIO channel 알 수 없는 사용자 2021.1.7 16:30
    • ㅠㅠㅠ 오류뜨네요 알 수 없는 사용자 2021.1.7 16:30

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)