라즈베리파이(Raspberrypi)

[라즈베리파이]웹 제어로 LED켜고 끄기(web server, remote control, flask)

끄적끄적아무거나 2022. 12. 26. 09:05
반응형

 

목차

     

     

    Raspberry Pi 웹서버에서 LED 제어하기

    이번에는 보드의 GPIO23번 핀에 LED를 연결하고 flask를 사용해서 웹서버를 구동합니다. 외부에 노트북을 사용해서 해당 웹서버(Web server)에 접속하고 브라우저에 나온 버튼을 클릭하여 LED를 켜고 끄는 시험을 해보겠습니다. 

     

    하드웨어 연결은 아래와 같이 합니다. 

     

    원래 GPIO23번 핀과 GND 사이에 1kohm 저항(Resistor)을 둬서 LED를 보호해야 하나 귀찮아서 다이렉트로 연결했습니다. LED를 오래 쓰실려면 꼭 저항을 직렬로 연결해주세요

     

     

     

     

     

    전체 코드>>

    #!/usr/bin/python3
    
    from flask import Flask, render_template_string
    import RPi.GPIO as GPIO
    
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(23, GPIO.OUT)
    
    app = Flask(__name__)
    
    led_state = "off"
    def led_onoff(led_state):
        print("led_state : ",led_state)
        if led_state == 1:
            GPIO.output(23, 1)
        elif led_state == 0:
            GPIO.output(23, 0)
    
    control_page = """
    <script>
    function btn_click(state)
    {
        if(state == 0){
            state = 1;
        } else {
            state = 0;
        }
        window.location.href='/' + state
    }
    </script>
    
    <input type='button' onClick='btn_click({{gpio23}})' value='led switch'/>
    """
    
    @app.route('/')
    @app.route('/<state>')
    def led_start(state="n"):
        print("state : ",state)
        if state != "n" and state != "favicon.ico":
            led_onoff(int(state))
            return render_template_string(control_page, gpio23=int(state))
        else :
            return render_template_string(control_page, gpio23=0)
    
    if __name__ == '__main__':
        app.run(host='0.0.0.0', debug=True, port=9999)

     

     

     

     

     

    결과>>

    위와 같이 웹 브라우저에 접속해서 led 버튼을 클릭 할때마다 전원(Power)이 들어왔다가 꺼졌다가 하는 것을 확인할 수 있습니다. 

     

     

     

    주석>>

    from flask import Flask, render_template_string
    import RPi.GPIO as GPIO

    flask와 GPIO를 이용하기 위해 라이브러리를 불러 옵니다.

     

     

    GPIO.setmode(GPIO.BCM)
    GPIO.setup(23, GPIO.OUT)

    GPIO23번 핀을 출력 핀으로 사용 합니다.23번 핀의 위치는 위쪽에 핀맵에서 확인 가능합니다.

     

     

     

    led_state = "off"
    def led_onoff(led_state):
        print("led_state : ",led_state)
        if led_state == 1:
            GPIO.output(23, 1)
        elif led_state == 0:
            GPIO.output(23, 0)

    led_onoff함수를 실행하면 입력값에 따라 GPIO23번 핀의 출력을 줬다가 껐다가 할 수 있습니다. 

     

     

     

     

    control_page = """
    <script>
    function btn_click(state)
    {
        if(state == 0){
            state = 1;
        } else {
            state = 0;
        }
        window.location.href='/' + state
    }
    </script>
    
    <input type='button' onClick='btn_click({{gpio23}})' value='led switch'/>
    """

    별도의 html 파일을 templates 폴더에 만들기 귀찮고 간단하게 html을 작성할 때 위와 같이 넣어 줍니다.

    <script></script>는 자바스크립트(Javascript)코드로 btn_click 함수를 실행 합니다. 입력값을 확인하고 입력값을 0또는 1로 변환하고 window.location.href로 기존의 주소에 state값을 추가한 주소로 이동 합니다.

     

     

     

     

     

    @app.route('/')
    @app.route('/<state>')
    def led_start(state="n"):
        print("state : ",state)
        if state != "n" and state != "favicon.ico":
            led_onoff(int(state))
            return render_template_string(control_page, gpio23=int(state))
        else :
            return render_template_string(control_page, gpio23=0)

    기본 IP:Port를 입력하거나 /<state>값의 주소를 넣었을 때 led_start함수를 실행합니다. 

     

     

     

    if state != "n" and state != "favicon.ico":

    초기 값 n 또는 페이지를 부른 다음에 항상 GET으로 favicon.ico를 호출 하기 때문에 이 경우가 아닌 실제 state 값이 들어온 경우 if문을실행 합니다. 

     

     

    return render_template_string(control_page, gpio23=int(state))

    render_template_string 으로 html 페이지 접속이 아닌 string으로 만든 앞서 control_page 변수 값으로 이동합니다. 이때 입력 값으로 gpio23값을 state 값으로 가져 갑니다.

     

     

    반응형