기글 하드웨어 모바일 포럼
노트북, 넷북, 타블렛, 스마트폰, 핸드폰, 이북, PMP, MID 등의 모바일 기기와 그 소프트웨어에 대한 이야기를 자유롭게 나누는 곳입니다.
라즈베리파이의 GPIO를 투닥거리면서 가지고 놀고 있었습니다.
그러다가 어제오늘 파이썬으로 코드를 짰는데 희한한 일이 발생하네요.
GPIO를 입력으로 하는 소스코드를 짰는데,
C나 C++에선 아무 문제 없이 동작하던게
파이썬에선 문제가 발생하는군요.
그 문제란게...
전선만 연결했을 뿐인데 해당 GPIO의 입력값이 HIGH가 됩니다?!
손으로 GPIO를 만졌을때 HIGH로 뜨는건 이해하겠습니다만
GPIO들이 하나같이 전선을 제거하면 값이 LOW가 되고,
전선을 연결하면 값이 HIGH가 되는 기현상이 발생하네요 ㄷㄷ
참고로 전선 반대편엔 아무것도 없습니다(...)
-----
지금 테스트해보니 C/C++에서도 해당 현상이 발생하네요.
파이썬 하기 전엔 멀쩡했는데... ;ㅅ;
2016.05.12 20:45:09
파이썬에 사용했던 소스코드입니다(들여쓰기는 필터링 하시길...표현이 안되어서).
아래 코드에서 핀 7번만 계속 바꿔가면서 했는데도 그러네요.
웃긴건 아래 파이썬 돌리고 나서 C/C++ 소스코드로 다시 시도해봤는데 C/C++ 소스코드에서도 똑같은 현상이 발생한다는거죠.
참고로 그 C/C++ 소스코드는 이런 문제가 없었던 멀쩡한 소스코드였습니다.
풀업/풀다운 레지스터 문제였으면 그 C/C++ 소스코드에서도 처음부터 문제가 발생했어야 했는데
처음엔 멀쩡했다가 파이썬 사용했다가 와보니 해당 현상이 발생한다는거...
putty 창 두개 띄워서 한쪽에선 소스 컴파일 및 실행, 다른 창에선 gpio readall로 모니터링 해봤는데
전선 연결하는 순간 값이 1로 떠버리더군요.
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
GPIO.setup(11, GPIO.OUT)
GPIO.setup(7, GPIO.IN)
try:
while 1:
if GPIO.input(7) == 1:
GPIO.output(11, 1)
else:
GPIO.output(11, 0)
except KeyboardInterrupt:
GPIO.cleanup()
아래 코드에서 핀 7번만 계속 바꿔가면서 했는데도 그러네요.
웃긴건 아래 파이썬 돌리고 나서 C/C++ 소스코드로 다시 시도해봤는데 C/C++ 소스코드에서도 똑같은 현상이 발생한다는거죠.
참고로 그 C/C++ 소스코드는 이런 문제가 없었던 멀쩡한 소스코드였습니다.
풀업/풀다운 레지스터 문제였으면 그 C/C++ 소스코드에서도 처음부터 문제가 발생했어야 했는데
처음엔 멀쩡했다가 파이썬 사용했다가 와보니 해당 현상이 발생한다는거...
putty 창 두개 띄워서 한쪽에선 소스 컴파일 및 실행, 다른 창에선 gpio readall로 모니터링 해봤는데
전선 연결하는 순간 값이 1로 떠버리더군요.
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
GPIO.setup(11, GPIO.OUT)
GPIO.setup(7, GPIO.IN)
try:
while 1:
if GPIO.input(7) == 1:
GPIO.output(11, 1)
else:
GPIO.output(11, 0)
except KeyboardInterrupt:
GPIO.cleanup()
2016.05.13 01:18:33
집에 와서 올려주신 소스 제가 가지고 있는 라즈베리파이 2 에서 확인해보았습니다.
위에서 올리신 소스로는 확실히 전선 연결시에 1로 뜨는걸 확인했구요.
GPIO.setup(7, GPIO.IN)를
GPIO.setup(7, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)으로 수정하시면
정상적으로 동작합니다. 기본 python용 GPIO 라이브러리는 수행과 동시에 풀업/풀다운 레지스터를 날리나 봅니다. 그러니 어떤 C 라이브러리를 쓰시는지 모르겠지만 그 이후에 수행하는 C 언어로 컴파일한 것들도 영향을 받는듯 하는데요...다른 python라이브러리인 wiringPi2쪽을 설치하고 약간 수정해서 보니 이쪽은 풀업/풀다운 셋팅을 별도로 지정하지 않아도 해당 현상이 발생하지 않네요.
저는 wiringPi C언어 라이브러리만 다루다보니 Python쪽은 이런일이 있는줄은 몰랏네요. ㅎ
수정: 다시보니 핀번호를 착각한거 같아서 수정해보니 wiringpi2 라이브러리도 마찮가지네요. 풀업/풀다운 셋팅은 필수로 들어가셔야 할거 같네요 ㅎ
위에서 올리신 소스로는 확실히 전선 연결시에 1로 뜨는걸 확인했구요.
GPIO.setup(7, GPIO.IN)를
GPIO.setup(7, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)으로 수정하시면
정상적으로 동작합니다. 기본 python용 GPIO 라이브러리는 수행과 동시에 풀업/풀다운 레지스터를 날리나 봅니다. 그러니 어떤 C 라이브러리를 쓰시는지 모르겠지만 그 이후에 수행하는 C 언어로 컴파일한 것들도 영향을 받는듯 하는데요...다른 python라이브러리인 wiringPi2쪽을 설치하고 약간 수정해서 보니 이쪽은 풀업/풀다운 셋팅을 별도로 지정하지 않아도 해당 현상이 발생하지 않네요.
저는 wiringPi C언어 라이브러리만 다루다보니 Python쪽은 이런일이 있는줄은 몰랏네요. ㅎ
수정: 다시보니 핀번호를 착각한거 같아서 수정해보니 wiringpi2 라이브러리도 마찮가지네요. 풀업/풀다운 셋팅은 필수로 들어가셔야 할거 같네요 ㅎ
2016.05.13 02:28:53
저도 배워가는중이라 관심이 많이 가네요.
https://pypi.python.org/pypi/RPi.GPIO/0.6.2
기본 파이썬 GPIO라이브러리 소스가 위에 올라와 있네요.
라즈베리파이 MCU datasheet는
https://cdn-shop.adafruit.com/product-files/2885/BCM2835Datasheet.pdf 에서 확인 가능하구요. pull-up/pull-down 레지스터 관련 페이지(100페이지-101페이지) 내용 확인후 라이브러리 소스를 봤는데요.
이제 자야하니(...) 대충 넘겨가며 봤습니다만 python에서 GPIO를 사용할때 GPIO.setup 함수 사용시 풀업/풀다운 설정을 안걸어주면 PUD_OFF들어가면서 풀업/풀다운과 관련된 레지스터 내용을 비워버리네요.
GPIO.cleanup시에도 비워버리구요.
wiringPi 쪽은 소스는 안봤지만 API만 두고 추론해 볼때 이쪽은 셋업시 레지스터는 건드리지 않기에, 이보다 먼저 실행한 python GPIO에서 레지스터를 비우니 C언어쪽에서 별도로 레지스터를 설정해 주지 않는이상 python GPIO에서 설정한 레지스터의 설정 그대로 가지고 가는게 되어서 위와 같은 현상이 발생한걸로 보입니다.
향후 python GPIO 사용시 다른 GPIO를 이용한 프로그램들하고 사용할때 문제가 될듯하네요. wiringPi C언어쪽도 그렇고 가능하면 다른 여타 라이브러리 이용해서 GPIO사용시에는 반드시 풀업/풀다운 설정이 있는지 확인해서 핀 사용시 반드시 셋팅을 걸어주는게 좋을 것 같습니다.
뭐 어째보면 사실 라이브러리 개발하는 쪽 입장에서라면 저렇게 초기화 해주고 비워주는건 당연한 수순이었을 것이라 생각이 되네요.
https://pypi.python.org/pypi/RPi.GPIO/0.6.2
기본 파이썬 GPIO라이브러리 소스가 위에 올라와 있네요.
라즈베리파이 MCU datasheet는
https://cdn-shop.adafruit.com/product-files/2885/BCM2835Datasheet.pdf 에서 확인 가능하구요. pull-up/pull-down 레지스터 관련 페이지(100페이지-101페이지) 내용 확인후 라이브러리 소스를 봤는데요.
이제 자야하니(...) 대충 넘겨가며 봤습니다만 python에서 GPIO를 사용할때 GPIO.setup 함수 사용시 풀업/풀다운 설정을 안걸어주면 PUD_OFF들어가면서 풀업/풀다운과 관련된 레지스터 내용을 비워버리네요.
GPIO.cleanup시에도 비워버리구요.
wiringPi 쪽은 소스는 안봤지만 API만 두고 추론해 볼때 이쪽은 셋업시 레지스터는 건드리지 않기에, 이보다 먼저 실행한 python GPIO에서 레지스터를 비우니 C언어쪽에서 별도로 레지스터를 설정해 주지 않는이상 python GPIO에서 설정한 레지스터의 설정 그대로 가지고 가는게 되어서 위와 같은 현상이 발생한걸로 보입니다.
향후 python GPIO 사용시 다른 GPIO를 이용한 프로그램들하고 사용할때 문제가 될듯하네요. wiringPi C언어쪽도 그렇고 가능하면 다른 여타 라이브러리 이용해서 GPIO사용시에는 반드시 풀업/풀다운 설정이 있는지 확인해서 핀 사용시 반드시 셋팅을 걸어주는게 좋을 것 같습니다.
뭐 어째보면 사실 라이브러리 개발하는 쪽 입장에서라면 저렇게 초기화 해주고 비워주는건 당연한 수순이었을 것이라 생각이 되네요.
작성된지 2주일이 지난 글에는 새 코멘트를 달 수 없습니다.