GPIO
학습 목표
한 번 누른 버튼에서 여러 신호가 들어오는 현상을 시간 기록으로 읽고, 입력 처리 규칙을 정합니다.
실행 조건
기준 실습은 기록된 파형으로 수행합니다. 장치 확장에서는 원본 RPi.GPIO 코드의 BCM 번호·입력/출력 설정을 사용한 보드와 대조하세요.
GPIO Edge Detection
시작 조건
(t_ms,level)=[(0,0),(10,1),(12,0),(14,1),(50,0),(80,1)]입니다. 두 기록 사이에는 직전 level이 유지됩니다.
진행 방법
- 0~100 ms를 1 ms 간격으로 재구성하고 step plot을 그리세요.
- 원 기록에서 rising·falling edge 시점을 각각 찾으세요.
- rising edge만 Counter에 반영한 누적 개수를 기록하세요.
남길 결과
- 입력 step plot과 전환 시점 표.
import numpy as np
import matplotlib.pyplot as plt
events=[(0,0),(10,1),(12,0),(14,1),(50,0),(80,1)]
rising=[t for (t,x),(_,previous) in zip(events[1:],events[:-1]) if previous==0 and x==1]
print('raw rising',rising)
# TODO: 파형·falling edge·누적 Counter를 기록하세요.
결과 기록·자가 점검
t [ms]:
level:
edge 종류:
누적 rising count:
확인할 점
- 초기 level을 전환으로 잘못 세지 않았는가?
- 같은 level이 연속으로 읽혀도 새 edge로 세지 않는가?
Polling 간격의 영향
시작 조건
같은 파형을 ms 간격으로 읽습니다. 원본 edge 기록은 바꾸지 않습니다.
진행 방법
- 각 Polling 시점에서 직전 event의 level을 찾아 읽으세요.
- 읽힌 표본에서 rising edge를 다시 세어 원 기록과 비교하세요.
- 어떤 짧은 pulse가 사라졌는지 실제 구간을 지목하세요.
남길 결과
- 세 표본화 그림과 비교 표.
def sample_level(t):
return next(level for ts,level in reversed(events) if ts<=t)
for dt in [1,10,20]:
times=np.arange(0,101,dt);levels=[sample_level(t) for t in times]
print(dt,len(times))
# TODO: 샘플에서 전환을 세고 원 기록과 대조하세요.
결과 기록·자가 점검
Polling 간격 [ms]:
표본 수:
검출 rising 수:
놓친 구간:
확인할 점
- 원 파형을 고정한 채 샘플 간격만 바꾸었는가?
- Event 시각과 Polling으로 발견한 시각을 구분했는가?
접점 튐을 걸러내기
시작 조건
rising edge 사이의 최소 허용 간격을 20 ms로 둡니다. 마지막으로 허용한 edge를 기준으로 판단합니다.
진행 방법
- raw rising 목록에서 20 ms 미만 간격의 후속 edge를 무시하세요.
- 제한을 5,20,50 ms로 바꾸어 허용된 edge 수를 비교하세요.
- Week6-1_GPIO_LED_Test.ipynb의
GPIO.setmode와time.sleep인자를 읽고, 핀 번호 체계와 시간 단위를 이 활동의 기록과 연결해 설명하세요. 코드 읽기만으로 수행합니다.
남길 결과
- 세 조건의 표와 처리 규칙 3문장.
def debounce(times,min_gap):
accepted=[]
for t in times:
if not accepted or t-accepted[-1]>=min_gap:accepted.append(t)
return accepted
print(debounce(rising,20))
# TODO: 5·20·50 ms를 비교하세요.
결과 기록·자가 점검
최소 간격 [ms]:
raw count:
허용 count:
허용 시점 [ms]:
확인할 점
- 버린 edge가 마지막 허용 시각을 갱신하지 않는가?
- BCM 번호와 보드의 물리 핀 번호를 구분했는가?