본문 바로가기

Linux/라즈베리파이

라즈베리파이 on / off 전원 스위치, 버튼 만들기

728x90
반응형

 

 

 

라즈베리파이에 전원 Off 뿐 아니라 On도 되는 스위치를 만드려고 합니다.

따라서 완전히 Power를 Off하지 말고 

shutdown -h now

또는

sudo halt

를 통해 halt 상태(시스템 종료)로 놓고 wakeup시키면 다시 켜집니다.

wakeup은 5번 핀(GPIO 3, I2C SCL핀)으로만 가능합니다. (하드웨어상으로 그렇게 되어 있음.)

그래서 5번핀을 사용한다면 가장 간단하게 전원 스위치를 만들 수 있습니다.

하지만, 이핀은 I2C SCL핀이기 때문에 I2C통신과 동시에 사용하는데 무리가 있습니다.

I2C 통신을 사용하기 위해, 다른 핀을 사용한 코드도 소개하였습니다. 이 경우, 버튼은 하나이지만 핀을 2개 사용합니다.

또한, 라즈베리파이 3 B, 전원 버튼은 푸쉬형 버튼을 사용하였습니다.

마지막으로 코드 실행 없이  전원 버튼 만드는 법도 소개하였습니다.

  • 5번핀만을 사용한 전원 스위치
  • I2C 통신을 사용하는 전원스위치 만들기
  • python code나 script 사용 없이 전원 버튼 만들기

 

 

5번핀만을 사용한 전원 스위치

아래와 같이 핀 넘버를 확인하여 스위치 하나는 그라운드, 하나는 5번핀에 연결합니다.

 

  • pin number 확인
gpio readall

 

 

핀 넘버를 확인하여 5번핀(GPIO 3)과 그라운드에 연결해주었습니다.

저는 라즈베리파이 3 B를 사용하였으니 유의해주세요. 

 

  • 코드
pip3 install RPi.GPIO

GPIO 사용을 위해 RPi.GPIO를 설치해줍니다.

 

#!/usr/bin/python

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

btnPin = 5

GPIO.setmode(GPIO.BOARD)
GPIO.setup(btnPin, GPIO.IN, GPIO.PUD_UP)

while True:
    GPIO.wait_for_edge(btnPin,GPIO.RISING,bouncetime=100)
    time.sleep(0.1)
    #print(GPIO.input(btnPin))
    if GPIO.input(btnPin)==0:
        call(['shutdown', '-h','now'], shell=False)

라이징 엣지 신호가 오면 시스템이 꺼지도록(halt state)하였습니다.

  • #!/usr/bin/python : 맨 위에 적어 실행파일로 만들어 줍니다.
  • GPIO.setmode(GPIO.BOARD) : GPIO.BCM 모드를 사용하면 핀 번호는 3이 됩니다.
  • GPIO.setup(btnPin, GPIO.IN, GPIO.PUD_UP) : input신호를 받고, 내부 풀업저항을 사용합니다. 
  • GPIO.wait_for_edge(btnPin, GPIO.RISING, boucetime=100) : 핀의 rising edge가 감지될때까지 대기합니다. bounctime으로 채터링을 조절할 수 있습니다.

풀업저항을 사용하였기 때문에 버튼은 눌리면 0, 안 눌릴때는 1의 값을 가집니다.

코드를 보면 적어도 0.1초간은 눌려야 꺼지도록 하였습니다.

또한 while문을 사용하여 인식을 못하였을때를 대비하였습니다.

꺼져있을 때, 다시 스위치를 눌러 신호를 보내면 wakeup이 되기 때문에(5번핀이므로) 켜지게 됩니다.

 

위 파일을 저장 후, 부팅시 자동으로 켜지게 하기 위해 /etc/rc.local을 수정해줍니다.

sudo nano /etc/rc.local

 

 

exit 0 전에 python '파일 경로.py'를 추가해줍니다.

저장후 sudo reboot을 통해 재부팅 하여 스위치를 실험해보세요.

 

 

I2C통신을 사용하는 전원 스위치 만들기

앞에서 소개하였다시피, 5번핀은 I2C SCL핀이기 때문에 I2C와 동시에 사용할 수 없었습니다.

따라서 전원 버튼만 다른 핀을 사용하고, 5번핀을 따로 wakeup용도로만 사용하여 해결하였습니다.

아이디어를 밑의 그림의 출처 깃허브를 통해 얻었습니다. 

출처: https://github.com/lihak/rpi-power-button

위의 그림처럼 연결하여 turn off를 핀 18번으로 하고, 5번핀을 wakeup(turn on)용도로 사용합니다.

그리고 I2C통신을 하기 위해 5번핀에 다시  I2C SCL을 연결해줍니다.

adc와 psd사용을 위해 i2c통신을 사용하였는데요, 전부 연결하면 위처럼 됩니다.

따라서 5번 핀에 I2C SCL과 버튼핀 두개가 연결됩니다.

두개가 연결되어 있는데도 I2C통신이 가능한 이유는, 첫번째로 푸쉬 버튼이기 때문입니다.

처음에 토글 스위치를 사용하였는데, 토글 스위치는 0이될수도 있고 1이 될수도 있습니다.(회로가 연결될수 있고, 끊어질수 있습니다.)

하지만 푸쉬 버튼은 버튼이 눌릴때만 회로가 연결 됩니다. 따라서 아무런 작동을 하지 않을 때 5번핀은 SCL핀에 연결되어 I2C 통신을 하게 됩니다.

푸쉬 버튼이 눌릴 때만, 버튼 18번 핀과 연결되어 I2C가 종료되고, 시스템이 종료됩니다.

하지만 시스템이 종료되기 때문에 I2C의 연결 유무는 상관 없게 됩니다. 

라즈베리파이를 다시 키기 위하여 푸쉬 버튼을 누르면, 5번 핀에 연결되어 있기 때문에 wakeup신호가 들어가게 됩니다.

따라서 라즈베리파이가 다시 시작 되고, 역시 SCL핀이 18번 핀과 연결되어 있지 않아 정상 작동하게 됩니다. 

이렇게 하여 배선을 위와 같이 하고, shutdown.py 코드의 버튼 핀만 18번으로 고쳐 I2C와 전원 버튼 동시 사용을 성공하였습니다. ^^

#!/usr/bin/python

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

btnPin = 18

GPIO.setmode(GPIO.BOARD)
GPIO.setup(btnPin, GPIO.IN, GPIO.PUD_UP)

while True:
    GPIO.wait_for_edge(btnPin,GPIO.RISING,bouncetime=100)
    time.sleep(0.1)
    #print(GPIO.input(btnPin))
    if GPIO.input(btnPin) == 0:
        call(['shutdown', '-h','now'], shell=False)
    

 

 

python code나 script 없이 전원 버튼 만들기

위의 코드를 사용하지않고 /boot/config.txt 파일을 수정하면 

단순히 python 코드를 실행할 필요 없이 전원 버튼을 동작시킬 수 있습니다.

sudo nano /boot/config.txt

파일을 열어 dtoverlay=gpio-shutdown,gpio_pin=24,active_low=1,gpio_pull=up 을 추가해줍니다.

pyshical pin 번호는 18번이므로, gpio_pin에는 bcm핀번호인 24를 적어주어야 합니다.

이렇게 저장하면, 따로 파일을 만들 필요 없이 위와 같은 배선만으로 잘 동작하는것을 볼 수 있습니다.

 

 

 

  • 참고 문서

Power on /off button for Pi

github.com/lihak/rpi-power-button

 

 

728x90
반응형