2017 멀티캠퍼스/Raspberry Pi

#5 라즈베리파이 GPIO 조이스틱

꿈꾸는어린이 2018. 1. 14. 16:53


//

일시 : 2018.01.10 10 : 20AM ~ 12 : 00PM

내용 : 오전 파이썬 시험 후 GPIO 복습, 조이스틱.

//


GPIO 조이스틱

  • 4방향(up, down, left, right) 와 center 감지 O

  • 풀업 저항

    스위치를 눌렀을 경우(버튼이 감지될 경우) LOW 상태 => Low active

    입력 회로의 초기 상태를 HIGH로 해주기 위함.

  • 73HC14MTC : 채터링(high->low로 변할 때 전류가 순간적으로 요동치는 현상) 을 방지하기 위한 칩




풀업, 풀다운 저항

  • 전류는 전압도 중요하지만 전항이 있어야 한 방향으로 잘 흐를 수 있음

  • MCU나 임베디드 시스템 구상 시, 버튼이나 스위치같은 물리적인 입력이 일어나는 곳에 풀업(Pull-up) 저항이나 풀다운(Pull-down) 저항을 단다.

  • 풀업 저항이나 풀다운 저항을 두지 않으면 플로팅 현상(low인지 high인지 알 수 없는 상태, 0과 1이 번갈아 나타나는 불안정한 상태)이 발생.

    => 제대로 된 high/low 값을 보내기 위해 플로팅 현상을 해결해야함 -> 그래서 저항을 설치

  • pull-up 저항 : +쪽 (3.3v)에 설치

    pull-down 저항 : -쪽(0v, GND)에 설치

  • 풀업 저항일 때 스위치가 OFF이면 HIGH 상태(OFF되더라도 입력값에 혼동이 없음)

    스위치가 ON되면 GND(그라운드)와 연결되어 전류가 GND로 흐르기 때문에 LOW상태가 된다.

    (버튼이 그라운드와 연결되어 전류가 모두 버튼쪽으로 흐름)

풀업, 풀다운 참고

풀업, 풀다운 참고




실습

조이스틱 움직이는 방향에 따라 결과 출력하는 코드

  • GPIO.input(핀)함수 : 각 핀의 현재 CPU 상태를 읽어옴, 누르지 않은 상태면 False, 0 상태

  import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)

## up, down, left, right, center
gpio = [5, 6, 16, 20, 21]
## 현재 상태를 저장
stat = [0, 0, 0, 0, 0]

def print_jog_all():
   print ('up: %d, down: %d, left: %d, right: %d, center: %d' % (stat[0], stat[1], stat[2], stat[3], stat[4]))


try :
   for i in range(5):
       GPIO.setup(gpio[i], GPIO.IN)
       
   cur_stat = 0
   
   while True:
       for i in range(5):
           cur_stat = GPIO.input(gpio[i])
           
           ## 같지 않다 -> 신호반전, 즉 상태가 바꼈을 경우
           if cur_stat != stat[i]:
               stat[i] = cur_stat
               print_jog_all()
           
finally:
   print("cleaning up")
   GPIO.cleanup()



조이스틱 방향에 따라 LED불이 들어오도록 하는 코드

  • 상태led_pin1led_pin2
    UPFalseTrue
    DOWNTrueFalse
    LEFTTrueTrue
    RIGHTFalseFalse
    CENTERTrueTrue

  
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)

gpio = [5, 6, 16, 20, 21]
stat = [0, 0, 0, 0, 0]

led_pin1 = 14
led_pin2 = 15

GPIO.setup(led_pin1, GPIO.OUT)
GPIO.setup(led_pin2, GPIO.OUT)

def print_jog_all():
   print ('up : %d, down: %d, left: %d, right : %d, cen: %d'%(stat[0], stat[1], stat[2], stat[3], stat[4]))
   
def led(gpio, stat):
   if stat != 0:
       if gpio == 0:
           GPIO.output(led_pin1, False)
           GPIO.output(led_pin2, True)
       elif gpio == 1:
           GPIO.output(led_pin1, True)
           GPIO.output(led_pin2, False)
       elif gpio == 2:
           GPIO.output(led_pin1, True)
           GPIO.output(led_pin2, True)
       elif gpio == 3:
           GPIO.output(led_pin1, False)
           GPIO.output(led_pin2, False)
       elif gpio == 4:
           GPIO.output(led_pin1, True)
           GPIO.output(led_pin2, True)
       time.sleep(0.5)

   
try:
   for i in range(5):
       GPIO.setup(gpio[i], GPIO.IN)
       
   cur_stat = 0
   
   while True:
       for i in range(5):
           cur_stat = GPIO.input(gpio[i])
           
           if cur_stat != stat[i]:
               stat[i] = cur_stat
               print_jog_all()
               
           led(i, cur_stat)
           
           GPIO.output(led_pin1, False)
           GPIO.output(led_pin2, False)

finally:
   print("cleaning up")
   GPIO.cleanup()