7.2주차
시험 공지
시험은 월요일(24일)
우리꺼는 가져와도 상관은 없어. 2시간 시험에, 이론도 보고 실습도 본다.
먼저 이론 시험을 본다. 이걸 다 작성하면 이거 제출하고 문제지를 바꾸어 간다.
그런 다음 실습문제를 풀면 된다. 시간 안배를 잘해라,,,,모두 다 통로쪽에 앉아라.
시험지 펜으로만 가능. 연필은 감점. 이론 시험은 올려놓고 보지 말고 실습은 상관 없다. 검색도 상관없고 다 상관없다. 실습 시험은 오픈북.
서술형. 파이썬 기초,,,,,,,,는 냄. 리눅스는 안냄. 이론 시험은 개념에 대해서 잘 숙지하고 있는 과정이기 때문에 수어동안에 배웠던 중요한 개념을 잘 이해하고 서술할 수 있는 정도. 잘 이해하고 있는지에 대한 문제를 낸다.
중요한 몇몇 개념들을 잘 이해하고 있는지 문제에 나옴. 강사님 기준,,,,,,,,,,,1시간 50분 볼 수 있는 ,, 적절한 양으로,,,?
Proximity Sensor(근접 센서)
물리적인 접촉 없이 전자계의 힘을 이용하여 물체의 존재 여부, 통과, 연속흐름, 적체 등의 감지 및 위치 제어에 이용하는 장치이다.
근접 센서의 종류
-
자기 근접센서: 가까워진 물체의 자기 유도 현상을 검출하는 방식.
자기 근접 센서는 자성체가 아니지만 전류를 흘려보내 자성이 생기게 된다. 즉, 주변으로 자기상이 생기게 된다. 근데 자기장이 방해를 받으면 그 파향이 바뀌게 되고 그걸 이용해서 방해물이 지나가 자기장의 왜곡이 있는지 없는지를 인지하는 원리이다.
- 홀센서 기반: 자기장을 이용
-
광학 근접 센서: 빛을 이용
하나는 빛을 발사하고 하나는 감흥을 한다.
파란색이 광학 근접 센서가 보내는 영역인데, 그 영역 안에 아무것도 없으면 센서가 정해놓은 특정 세기를 받는다.
만약에 방해물이 들어오게 되면 빛 반사를 통해서 빛이 세지게 되고 이를 통해서 근접한 것을 인지할 수 있다. 그림에서 발간색이 달라진 신호이고 이를 통해서 인지가 가능하다.
Proximity_Sensor.py
import RPi.GPIO as GPIO
import signal
import sys
import time
def signal_handler(signal, frame):
print("pricess stop")
GPIO.cleanup()
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
GPIO.setmode(GPIO.BCM)
# 근접 센서 핀 번호
COLLISION = 22
GPIO.setup(COLLISION, GPIO.IN)
while True:
if GPIO.input(COLLISION) == 1:
print("Carefull ~~ Ooooooops")
if GPIO.input(COLLISION) == 0:
print("Not Collision")
time.sleep(0.2)
GPIO.input 값이 1이라는 근접했다는 뜻, 그렇지 않다면 0을 의미한다. 여기서 피피티 실습 코드랑은 0과 1의 위치가 반대로 되어있지만,, 이거는 연결 문제인 것 같기도 하다.
🌟 Proximity_Sensor2.py
앞차와 접근 시 경고음을 3회 발생합니다. 근접 센서를 사용하여 근접 시 beep음을 3회 발생하는 응용 프로그램을 작성해 보세요.
import RPi.GPIO as GPIO
import time
import sys
import signal
GPIO.setmode(GPIO.BCM)
COLLISION = 22
Buzer = 20
GPIO.setup(COLLISION, GPIO.IN)
GPIO.setup(Buzer, GPIO.OUT)
while True:
#
if GPIO.input(COLLISION) == 1:
print("Carefull ~~ Ooooooops")
GPIO.output(Buzer, GPIO.HIGH)
# 기본적으로 high 내가 쏜 및이 온다. 빛이 방해를 받으면 신호가 1이 아니게 된다.
if GPIO.input(COLLISION) == 0:
print("Not Collision")
GPIO.output(Buzer, GPIO.LOW)
time.sleep(0.2)
일반적으로 1이고, 막으면 0이 된다. 내꺼는 반대로 되어 있는듯? -> 바뀜… 이상하지만, ㅎ
여기서 하나의 센서에 대해서 두 개의 이벤트를 처리할 수 없다고 말이 나왔던 이유:
만약에 이벤트를 처리하기 위해서는
import RPi.GPIO as GPIO
import time
import sys
import signal
def signal_handler(signal, frame):
print("pricess stop")
GPIO.cleanup()
sys.exit(0)
# 충동시 이벤트 처리 함수
def carefull(channel):
GPIO.output(SOUND, GPIO.HIGH)
# 근접하지 않았을 경우 이벤트 처리 함수
def carefull(channel):
GPIO.output(SOUND, GPIO.LOW)
signal.signal(signal.SIGINT, signal_handler)
GPIO.setmode(GPIO.BCM)
COLLISION = 22
SOUND = 20
GPIO.setup(COLLISION, GPIO.IN)
GPIO.setup(SOUND, GPIO.OUT)
# 이벤트 처리
GPIO.add_event_detect(COLLISION, GPIO.RISING, callback=carefull)
GPIO.add_event_detect(COLLISION, GPIO.FALLING, callback=notColi)
while True:
if GPIO.input(COLLISION) == 0:
print("Carefull ~~ Ooooooops")
if GPIO.input(COLLISION) == 1:
print("Not Collision")
time.sleep(0.2)
이렇게 코드를 작성할 수 있을 것이다. 하지만 이렇게 된다면 RuntimeError: Conflicting edge detection already enabled for this GPIO channel
이와 같은 에러가 나서 하나의 센서에 두개의 이벤트를 처리할 수 없다고 나오는 것 같다.
Proximity_Sensor3.py
전압 변화를 확인하기 위해서 작성한 코드
🌟 이벤트 처리 예시 코드
import RPi.GPIO as GPIO
import sys
import time
import signal
GPIO.setwarnings(False)
def signal_handler(signal, frame):
print("process stop")
GPIO.cleanup()
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
# 카운터 값을 하나 증가해준다.
def my_callback(channel):
global eventCounter
eventCounter += 1
global humandetect
humandetect = 1
GPIO.setmode(GPIO.BCM)
## 근접 센서
### 1: Not Detect / 0: Proxy Detect
PROXY = 22
GPIO.setup(PROXY, GPIO.IN)
# global
eventCounter = 0
humandetect = 0
counter = 0
GPIO.add_event_detect(PROXY, GPIO.FALLING, callback=my_callback)
while True:
if humandetect == 1:
print("Detect %d" %eventCounter)
humandetect = 0
while not GPIO.input(PROXY):
counter += 1
print("Low %d " %counter)
time.sleep(1)
counter = 0
else:
print("No detect")
time.sleep(0.5)
동작 원리는 default가 전압 5V이고, 어떤 물체가 근접한 경우는 0으로 떨어진다고 했다. 따라서 이벤트를 1에서 0으로 바뀐 FALLING인 경우 my_callback으로 넘어가도록 코드를 짰고, 그 안에 while not GPIO.input(PROXY)
를 통해서 0일 때(근접해있는 동안) 반복문을 계속 돌도록 했다.
No detect
No detect
No detect
No detect
Detect 2
Low 1
Low 2
Low 3
Low 4
Low 5
Low 6
Low 7
Detect 3
No detect
No detect
No detect
이렇게 출력이 되었다면 처음에는 1이므로 detect되지 않다가 근접했을 때, 반복문을 돌리면서 계속 Low를 출력하는 것을 확인할 수 있다 .
Gas Sensor
가스 센서 원리정도만 알면 될 것 같다. 감흥하는 센서 표면에 이상물질이 표면에 닿으면 전기 현상이 일어난다. 공기 외의 신호가 들어온다면 뭔가 다른 가스가 있음을 감지한다.
🌟 이벤트
-
GPIO.add_event_detect(GAS_IN, GPIO.FALLING, callback=my_callback, bouncetime=정수)
- channel: GAS_IN 입력 채널 번호
- 신호 발생 이벤트: Falling/Rising 타입
- 해당 이벤트 발생 시 실행할 사용자 callback 함수 지정
- Bouncetime=정수
-
GPIO.remove_event_detect(channel)
이벤트도 제거가 필요하다. 이벤트 핸들러가 많을수록 느려지므로 불필요한 이벤트 인터럽트는 제거가 필요하다.
불꽃 감지 센서
불꽃에서 방출되는 특정 파장 대역의 에너지를 흡수 및 검출하여 불꽃의 존재 유무, 위치를 센싱한다.
시험 예상 문제
가까워지면 서보 모터를 90도 돌리는 문제
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO_TRIGGER = 18
GPIO_ECHO = 21
GPIO_MOTOR = 23
GPIO.setup(GPIO_TRIGGER, GPIO.OUT)
GPIO.setup(GPIO_ECHO, GPIO.IN)
GPIO.setup(GPIO_MOTOR, GPIO.OUT)
PWM_RC=GPIO.PWM(GPIO_MOTOR, 100)
PWM_RC.start(7.5)
try:
while True:
stop = 0
start = 0
# 먼저 트리거 핀을 OFF 상태로 유지한다.
GPIO.output(GPIO_TRIGGER, False)
time.sleep(2)
GPIO.output(GPIO_TRIGGER, True)
time.sleep(0.00001)
GPIO.output(GPIO_TRIGGER, False)
# 에코핀이 ON되는 시점을 시작 시간으로 잡는다.
while GPIO.input(GPIO_ECHO) == 0:
start = time.time()
# 에코 핀이 다시 OFF되는 시점을 반사파 수신 시간으로 잡는다.
while GPIO.input(GPIO_ECHO) == 1:
stop = time.time()
# Calculate pulse length
elapsed = stop - start
if (stop and start):
distance = (elapsed * 34000.0) / 2
if distance <= 10:
PWM_RC.ChangeDutyCycle(5)
time.sleep(1)
PWM_RC.ChangeDutyCycle(95)
time.sleep(1)
except KeyboardInterrupt:
print("Ultrasoic Distance Measurement End")
GPIO.cleanup()
# Reset GPIO settings
GPIO.cleanup()
댓글남기기