본문 바로가기
  • 우당탕탕속의 잔잔함
Programming/Raspberry Pi

[GPIO] Raspberry Pi에 스위치/버튼 연결 후 Shutdown/Reboot, Keyboard Event 수행

by zpstls 2023. 3. 23.
반응형

이번 포스트는 Raspberry Pi에 Button(Switch)를 부착하고 이를 활용하는 방법에 대해 다뤄보고자 합니다.

 

 

우선, 일전에 다뤄보았던 Video Player에 활용될 수 있는 사항이니 궁금하시다면 참고해 주세요.

 

[QT] Python을 이용한 Video Player 개발

이번 포스트는 Python을 기반으로 여러 가지 Video를 플레이하는 프로그램을 만들어보도록 하겠습니다. 그리고 이를 Raspberry Pi에서 플레이해보도록 할 것입니다. 우선, 개발하고자 하는 프로그램에

mj-thump-thump-story.tistory.com

(활용도에 대해 잠깐 설명하자면, 버튼 0을 누르면 OS가 종료되거나, 버튼 1을 누르면 다음 영상으로 넘어가고 버튼 2를 누르면 이전 영상으로 돌아가도록 하는 등의 기능을 구현할 수 있을 것입니다.)

 

 

Raspberry Pi에는 Power Button이 Board에 포함되어 있지 않습니다. 때문에 전원을 인가해주면 인가시점에 바로 부팅이 시작됩니다. 그래서... OS에서 데스크톱 종료를 해주고 다시 부팅해 주기 위해서는 전원을 뺐다가 다시 꼽아주어야 합니다. 별거 아니긴 합니다만 귀찮을 때도 있습니다.

이를 덜 귀찮게(?) 수행하기 위해 Power Button을 하나 만들어보도록 하겠습니다.

 

우선, 센서(스위치) 연결도는 다음과 같습니다.

연결도

여기서 참고로 Raspberry Pi 버전마다, 그리고 GPIO 라이브러리마다 Pin 번호가 조금씩 상이할 수 있습니다.

GPIO의 경우는 보통 C기반인 WiringPi를 많이 사용합니다. 위 이미지 좌측의 Pin Map도 WiringPi를 기준으로 작성된 것입니다. Raspberry Pi 버전에 따른 적절한 Pin Map 버전을 찾아 활용하면 됩니다.

여기까지 구성되었다면, 이제 WiringPi를 다음과 같은 과정을 통해 설치합니다.

$ sudo apt-get install git-core
$ git clone https://github.com/WiringPi/WiringPi
$ cd WiringPi
$ ./build

 

설치가 완료되었다면, 이제 Switch를 Power Button으로 활용하기 위해 다음과 같은 코드를 작성해 줍니다.

#! /usr/bin/env python

import RPi.GPIO as GPIO
from subprocess import call
from datetime import datetime
import time

# pushbutton connected to this GPIO pin, using pin 5 also has the benefit of
# waking / powering up Raspberry Pi when button is pressed
shutdownPin = 5

# if button pressed for at least this long then shut down. if less then reboot.
shutdownMinSeconds = 2

# button debounce time in seconds
debounceSeconds = 0.01

GPIO.setmode(GPIO.BOARD)
GPIO.setup(shutdownPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)

buttonPressedTime = None


def buttonStateChanged(pin):
    global buttonPressedTime

    if not (GPIO.input(pin)):
        # button is down
        if buttonPressedTime is None:
            buttonPressedTime = datetime.now()
    else:
        # button is up
        if buttonPressedTime is not None:
            elapsed = (datetime.now() - buttonPressedTime).total_seconds()
            buttonPressedTime = None
            if elapsed >= shutdownMinSeconds:
                # button pressed for more than specified time, shutdown
                call(['shutdown', '-h', 'now'], shell=False)
            elif elapsed >= debounceSeconds:
                # button pressed for a shorter time, reboot
                call(['shutdown', '-r', 'now'], shell=False)


# subscribe to button presses
GPIO.add_event_detect(shutdownPin, GPIO.BOTH, callback=buttonStateChanged)

while True:
    # sleep to reduce unnecessary CPU usage
    time.sleep(5)

버튼을 길게 누르면 전원이 꺼지고 짧게 누르면 리부트가 됩니다. 이때 중요한 것은 원래 부팅은 약간의 스파크만 일으켜주면 구현할 수 있다는 점과 위 프로그램은 부팅과 동시에 자동으로 실행되어야 한다는 것입니다.

리눅스에서 프로그램을 Background에서 실행시키고 싶을 때는 명령어 뒤에 &를 붙여주면 됩니다. 즉 이러한 명령어를 부팅 시 수행할 수 있도록 해주면 됩니다.

다음과 같이 /etc/rc.local 파일을 수정해 줍니다. 아래의 빨간 박스 내용을 추가해 주면 됩니다.

/etc/rc.local File

위와 같은 과정을 수행했음에도 제대로 수행이 되지 않는다면, 다음과 같은 과정을 수행해 줍니다.

$ sudo nano /etc/xdg/lxsession/LXDE-pi/autostart

# lxterminal -e python /home/pi/Desktop/~.py를 추가해준다.

이제 라즈베리파이가 부팅되면 ~.py가 자동적으로 Background에서 구동될 것입니다.

 

추가적으로, 버튼을 누르면 특정 키보드키가 눌려지는 효과를 구현해 볼 수도 있습니다. 이를 위해서는 Python 기반의 마우스와 키보드 제어 라이브러리, PyAutoGUI를 사용하면 됩니다. 뭐... 다른 방식도 있겠지만 말이죠.

설치를 위해서 다음과 같은 과정을 수행합니다.

$ sudo pip3 install python3-xlib
$ sudo pip3 install pyautogui

설치가 완료되었다면, 아래와 같은 간단한 함수를 통해 키보트 이벤트를 수행해 볼 수 있습니다.

import pyautogui

pyautogui.typewrite("o")
pyautogui.typewrite("i")

위 코드는 키보드 o와 i를 누르는 효과를 줍니다.

앞서 작성해 보았던, Shutdown, Reboot 버튼 컨트롤 프로그램과 같은 방식으로 위 코드를 활용하면, 스위치를 눌렀을 때 키보드가 눌린 것과 같은 효과를 낼 수 있을 것입니다. 물론 이 프로그램도 부팅과 동시에 백그라운드에서 수행되어야 할 것입니다.

 

 

이와 같이, 아주 간단하게 Raspberry Pi에 센서를 연결해 활용하는, 아주 기초적인 부분에 대해 다뤄보았습니다.

어려운 기능을 구현하는 것이 아니라면 이러한 버튼만으로도 수행할 수 있는 프로젝트들이 꽤 많을 것이라 생각됩니다.

 

이번 포스트는 여기서 마무리하도록 하겠습니다.

반응형

댓글