• 검색 결과가 없습니다.

Mini Project- Final -Mini Project- Final -

N/A
N/A
Protected

Academic year: 2022

Share "Mini Project- Final -Mini Project- Final -"

Copied!
20
0
0

로드 중.... (전체 텍스트 보기)

전체 글

(1)

Mini Project - Final -

Mini Project - Final -

전자과 _ 공대생

(2)

ㄴㅁㅇㄹㄴㅁㅇㄹ

목 차

1. 프로젝트 주제 및 설명

.

2. 작동 원리

3. 사용하는 부품 및 설명

4. 최종 코딩 및 작동 영상

(3)

ㄴㅁㅇㄹㄴㅁㅇㄹ

1. 프로젝트 주제 및 설정

.

미니 프로젝트 주제 : 스마트 화분

원리 : 화분의 수분 량을 측정하여 설정해둔 값보다 적을 경우 화분에 물 공급

(4)

ㄴㅁㅇㄹㄴㅁㅇㄹ

2. 작동 원리

.

수분센서 수분량 수집

수분센서임계치 미달 1. 워터펌프 가동

2. LCD 작동 - 현재 수분량 표시

- 상태 문구 Warning 표시 3. RGB LED 빨간색으로 변경

1. 워터펌프 중단 2. LCD 작동 - 현재 수분량 표시 - 상태 문구 Normal 표시 3. RGB LED 초록색으로 변경

Y N

스위치를 2누를 경우초이상 전원 OFF

전원 ON

(5)

ㄴㅁㅇㄹㄴㅁㅇㄹ

3. 사용하는 부품 및 설명

.

1. ADC 모듈 (MCP3008)

- 8 채널 존재 (MCP3004 는 4 채널 존재 )

- 사용하는 이유 : 아날로그 전압 값을 디지털 값으로 읽기 위하여

- 라즈베리파이는 별도로 변환 역할 X, 따라서 ADC 칩을 사용해야만 함

- 토양 수분 센서의 아날로그 전압 값을 디지털 값 ( 수분 % 나타날 때 사용 ) 으로 읽기 위해서 사용

- (1~8) 왼쪽 다리 8 개는 채널 - 채널을 이용하여 아날로그 값 IN

- (9)DGND : 디지털의 GND - GND 에 연결

- (10)\CS/SHDN : 칩 선택 또는 INPUT 을 막는 역할

- 라즈베리파이에서는 SS(CE0 또는 CE1) 에 연결 - 프로젝트에서는 CE0 에 연결 - (11)DIN/(12)DOUT : 데이터가 IN, OUT - 라즈베리파이에는 MOSI, MISO 에 연결 - MOSI : 마스터 출력 , 슬레이브 입력 / MISO : 마스터 입력 , 슬레이브 출력

- (13)CLK : 클럭 , 클럭이 발생할 경우에만 동작 - 라즈베리파이에는 SCLK 에 연결 - SCLK : 직렬 클럭 ( 마스터로부터의 출력 )

- (14)AGND : 아날로그의 GND - GND 에 연결

- (15)V(REF) : 래퍼런스 전압 입력을 넣어주는 것 - +3.3V 에 연결

- (16)VDD : 칩의 동작 전원 (2.7V~5.5V) - +3.3V 에 연결

(6)

ㄴㅁㅇㄹㄴㅁㅇㄹ

3. 사용하는 부품 및 설명

.

1. ADC 모듈 (MCP3008)

# 어떻게 아날로그 값을 디지털 값으로 바꿔서 출력하는가 #

- 위 사진은 공식

- V(REF) 는 +3.3V 계속 인가 ( 고정 값 )

- Vin 의 값이 줄어들 때마다 디지털 출력 값도 줄어듬

- 좋은 예시로 가변 저항을 이용하여 Vin 값 조절하면서 출력 값 확인

(7)

ㄴㅁㅇㄹㄴㅁㅇㄹ

3. 사용하는 부품 및 설명

.

- MCP3008 구동하려면 동작 방식과 SPI 통신으로 보내야 할 데이터를 알아야 함 - 신호 타이밍은 8 비트로 세 번 나눠져있음

- 첫 바이트는 라즈베리파이로 DIN 을 통해 start 를 알린다 .

- 두 번째 바이트의 상위 4 비트를 가지고 ADC 값을 얻고자 하는 채널을 선택 - 나머지 비트들은 동작에 영향을 미치지 않음

- D0 입력까지 다 받으면 DOUT 핀을 통해 ADC 값을 라즈베리파이로 보내기 시작 - ADC 값은 null 비트로 시작

- 따라서 DOUT 로 전달되는 신호 중 두 번째 바이트의 하위 2 비트가 10 비트 ADC 값의 최상위 비트 가 됨- 그 뒤 세 번째 바이트의 8 비트가 나머지 ADC 값의 하위 8 비트가 됨

- 해서 최종 10 비트로 디지털 값 표현

(8)

ㄴㅁㅇㄹㄴㅁㅇㄹ

3. 사용하는 부품 및 설명

.

2. 토양 수분 센서 (SEN-13322)

- 토양 수분 센서는 토양 ( 흙 ) 의 수분 ( 물의 함량 ) 을 측정하여 그 값을 나타낸 것 - 전극이 부착된 양 쪽 수분 측정용 프로브를 이용하여 저항 값을 측정

- 프로브끼리 전기를 흘렸을 때 잘 흐르지 않는다면 흙에 물이 많다는 뜻 - 반대로 잘 흐를 경우 흙에 물이 적다는 뜻

- 사용 방법 : 센서 프로브를 흙에 꽂아서 사용

- 흙에 꽂게 되면 그 흙의 수분 함유량으로 인해 센서 자체가 저항이 됨 - 핀 : VCC, GND, SIG(A0)

- 여기서 A0 는 단순히 저항치에 의한 전압의 출력으로 측정하는 것 - 따라서 아날로그 전압 값을 디지털 값으로 보려면 ADC 모듈이 필요

- 아날로그 전압 값은 말 그대로 전압 값이 나오고 디지털 값은 전압 값에 따라 0~1023 사이 값을 출력 - 전압 값이 높으면 저항이 낮고 물이 많다 !

- 전압 값이 낮으면 저항이 높고 물이 적다 !

(9)

ㄴㅁㅇㄹㄴㅁㅇㄹ

3. 사용하는 부품 및 설명

.

3. 모터 드라이버 (L298N)

- 사용 방법 : 전원 인가는 배터리 ( 건전지 - 최대 12V 이므로 낮은 전압 사용 ) 로 함 - 전원 인가는 아래 3 개의 파란색에 연결하게 됨

- 왼쪽부터 +12V, GND, +5V 역할을 함

- 양 쪽 2 개의 파란색에는 사용할 DC 모터를 연결

- 프로젝트에서는 모터를 하나만 사용하므로 한 곳만 연결하면 됨 - ENA 와 5V 를 점퍼 핀으로 연결함으로써 최대 출력으로 동작 - 즉 , 계속해서 ENABLE 중

- INA, INB 는 서로 다른 전압을 받아야 작동 - 둘 다 HIGH 거나 LOW 면 동작 X

- INA 이 HIGH 이고 INB 가 LOW 면 정방향으로 회전 - 반대면 역방향으로 회전

(10)

ㄴㅁㅇㄹㄴㅁㅇㄹ

3. 사용하는 부품 및 설명

.

4. LCD

- LCD 의 핀은 총 4 개

- VCC 는 전압에 , GND 는 GND 에 연결 , SDA 와 SCL 은 라즈베리파이의 3, 5 번핀 (BOARD) 에 연결 (SDA, SCL)

- 라즈베리파이에서 제공해주는 I2C_LCD_driver 라이브러리 사용

- 우선 sudo raspi-config 에서 interface options 에서 i2c 기능을 enable 시킴 - sudo apt-get install i2c-tools 을 하여 i2c-tools 라이브러리를 추가 ( 설치 ) 함

- sudo apt-get install python smbus 을 하여 python smbus 라이브러리를 추가 ( 설치 ) 함 - reboot 하여 재부팅 한 후 i2cdetect -y 1 로 연결되었는지 확인

- sudo git clone https://github.com/DeveloperDreamming/LCD1602_i2c_Python.git 를 하여 LCD 기본 프로그램을 다운 (Github 주소 )

- ls 로 확인하면 2 개의 file 로 구성

- 하나는 LCD 를 제어하기 위한 설정 및 명령어가 구현 - 나머지 하나는 예제가 있음

- 하지만 이 경로는 수정 , 삭제 , 추가 권한이 없으므로 지나가는 모든 경로에 권한 부여 - 권한 부여 후 sudo mv 파일명 디렉터리명 / 을 이용하여 home 에 있던 파이썬 파일을 LCD1602_i2c_Python 안으로 이동

(11)

ㄴㅁㅇㄹㄴㅁㅇㄹ

3. 사용하는 부품 및 설명

.

4. 스위치

- 사용 목적 : 스위치를 이용하여 라즈베리파이 전원 ON/OFF - 전원을 사용하기 위해 라즈베리파이에 있는 라이브러리 사용

- 거기서 핀 번호 3(BCM 기준 / BOARD 는 5 번 ) 을 무조건 사용해야 함 - 하지만 이미 그 핀 번호는 LCD 의 SCL 로 사용 중

- 따라서 둘 중 하나 포기해야하는 상황

- 결론적으로 LCD 는 포기하지 않고 스위치로 라즈베리파이 전원 OFF 기능만 추가하기로 함 - 풀업 사용

- 우선 플로팅 상태란 스위치가 열리게 될 때 0 도 1 도 아닌 0 과 1 사이에서 방황하는 아무런 상태도 아닌 것을 뜻 함

- 즉 , 스위치가 열리게 되면 전류가 흐르고 있는지 안 흐르고 있는지 확인할 수 없음 - 따라서 플로팅 상태일 때를 감지하여 0(LOW) 과 1(HIGH) 을 출력

- 여기서 풀업은 0(LOW) 일 때 ON 이 되고 1(HIGH) 일 때 OFF 가 됨 - 풀다운은 반대

- 회로를 보면 스위치가 열려있을 때 ( 누르지 않았을 때 ) 전류가 GND 로 빠지지 못함 - 따라서 파란 선이 1(HIGH) 상태가 되어 OFF 상태가 됨

- 반대로 스위치를 누르면 전류가 GND 로 빠지게 되어 파란 선이 0(LOW) 상태가 되어 ON 상태가 됨

(12)

ㄴㅁㅇㄹㄴㅁㅇㄹ

3. 사용하는 부품 및 설명

5. RGB LED.

- 기본적으로 RED, GREEN, BLUE 로 구성

- 3 가지 색깔을 섞어서 다양한 색을 나타낼 수 있음 - 섞는 방법 : 전류의 세기 조정 or 가변 저항 사용

- 전류의 세기 조정은 PWM 의 값을 조정하면 바꿀 수 있음

- RGB LED 의 PWM 은 0~100 사이로 설정할 수 있으며 최댓값은 100 으로 정해져 있음 - 센서마다 PWM 의 최댓값이 다르지만 내가 쓰는 RGB LED 의 최댓값은 100

- 만약 PWM=100 이면 , 전류가 끊임없이 흐르고 있다는 뜻

- 5V 가 계속 인가되고 있다는 뜻이였으며 LED 밝기는 최대치가 됨 - PWM=50 이면 , 전류가 흐르다가 안 흐르다를 반복하고 있다는 뜻 - 0V 와 5V 를 주기적으로 반복하고 있다는 뜻

- 흐르다 안 흐르다를 반복하는 것은 LED 도 켜졌다 꺼졌다를 반복해야되는게 아니냐 ???

- 하지만 전류가 흐르고 안 흐르는 시간이 사람의 눈으로 확인할 수 없을 정도로 빠름

- 해서 사람의 눈으로는 LED 의 on/of 을 확인하기보다는 밝기의 세기를 확인할 수 있음

- 따라서 PWM=100 일때보다 전류가 적게 흐르기 때문에 LED 의 밝기도 절반 정도 약하게 나옴

(13)

ㄴㅁㅇㄹㄴㅁㅇㄹ

3. 사용하는 부품 및 설명

5. RGB LED.

- PWM=1 이면 , 사실상 전류가 안 흐르는 수준 ( 흐르긴 흐름 ) - 0V 가 들어오다가 아주 잠깐 5V 가 들어오고 다시 0V 가 들어옴 - LED 의 밝기는 거의 꺼진 상태급으로 나옴

- 마지막 PWM=0 이면 , 전류가 흐르지 않는 상태 - 0V 가 계속해서 들어오고 있다는 뜻

- 따라서 LED 가 꺼진 상태

(14)

ㄴㅁㅇㄹㄴㅁㅇㄹ

4. 최종 코딩 및 작동 영상

.

※ 백그라운드 재생 ! ※

- sudo nano /etc/rc.local 을 입력하여 내용 수정

- 안에 내용 중 [exit 0] 이전 라인에 아래 라인을 추가

- python /home/pi/LCD1602_i2c_Python/miniproject.py - 자기 파이썬 파일 루트를 적으면 됨

※ 백그라운드 중지 ! ※

- 터미널에 ps -ef | grep 파일명 .py 을 검색

- 그러면 백그라운드에 돌아가고 있는 파일명이 나옴

- 여기서 root [ 숫자 1] [ 숫자 2] ~~ 가 나오는데 [ 숫자 1] 를 외워야 함 - 이제 터미널에 sudo kill 15 [ 숫자 1] 을 쳐준다

- 여기서 15 는 종료 신호이며 9 를 쓰면 강제 종료

- 위에처럼 쳐주시면 백그라운드에서 돌고 있는 친구를 종료시킬 수 있음

(15)

ㄴㅁㅇㄹㄴㅁㅇㄹ

4. 최종 코딩 및 작동 영상

.

import RPi.GPIO as GPIO import I2C_LCD_driver import time

import spidev

from subprocess import call from datetime import datetime IN1 = 5

IN2 = 6 R = 16 G = 20 B = 21 btnPin = 22

shutdown_sec = 2 HUM_THRESHOLD=20 HUM_MAX=0

GPIO.setwarnings(False) GPIO.setmode(GPIO.BCM) GPIO.setup(IN1, GPIO.OUT) GPIO.setup(IN2, GPIO.OUT) GPIO.setup(R, GPIO.OUT) GPIO.setup(G, GPIO.OUT) GPIO.setup(B, GPIO.OUT) GPIO.setup(btnPin, GPIO.IN)

GPIO, I2C_LCD_driver(LCD), time(delay), spidev(

모터 드라이 버 )

[call, datetime](

스위치로 라즈베리파이 종료를 위해서 사용 )

핀 번호들 지정 (BCM 기준 )

shutdown_sec

는 몇 초이상 누를 시 라즈베리파이 종료를 위한 것

HUM_THRESHOLD

은 원하는 수분 량 기준

HUM_MAX

은 수분 센서 출력 초기 값

Warning

이 안뜨게 설정

mode

은 BCM 으로 설정

OUTPUT, INPUT

설정

(16)

ㄴㅁㅇㄹㄴㅁㅇㄹ

4. 최종 코딩 및 작동 영상

.

spi=spidev.SpiDev() spi.open(0,0)

spi.max_speed_hz=500000 def read_spi_adc(adcChannel):

adcValue = 0

buf = spi.xfer2([1,(8+adcChannel)<<4,0]) adcValue = ((buf[1]&3)<<8)+buf[2]

return adcValue

def map(value, min_adc, max_adc, min_hum, max_hum):

adc_range = max_adc-min_adc hum_range = max_hum-min_hum

scale_factor = float(adc_range)/float(hum_range) return min_hum+((value-min_adc)/scale_factor)

def getPressTime():

elapsed = 0

if pressTime is not None:

elapsed = (datetime.now() - pressTime).total_seconds()

return elapsed

- 모터드라이버 초기 설정

라즈베리파이에서 CE0 에 연결했으므로 (0,0) 오픈 CE1에 연결하면 (0,1) 오픈

모터 속도 제한

- read_spi_adc 함수 ADC 값을 가져오는 함수

buf는 3바이트의 데이터 1, (8+vol)<<4, 0 을 순차적으로 보내고 3바이트를 받 xfer2[value] -> Din 역할

아까 설명했지만 1 은 start 역할 , (8+vol)<<4 는 상위 4비트는 채널 선택이므로 밀어내고 나머지 비트를 사용 , 마지막은 무관 (전체 사용 )하므로 0 입력

다음 줄은 두 번째 바이트 (buf[1] 을 8비트 밀어내고 하위 2비트만 상위 2비트로 사용 ) 과 세 번째 바이트 (buf[2]) 로 값을 복원

return하는 이유는 delay 걸릴 때마다 다른 값을 출력할 수도 있기 때문 사실 위에 코딩은 국룰 코딩임

- map 함수

센서 값을 백분율로 변환하기 위한 함수 adc 칩한테 받은 값을 백분율로 변환

value는 현재 받고 있는 값 , min,max_adc 는 adc출력 값의 최소 ,최대값 / min,max_hum은 습도를 표현할 수 있는 최소 , 최대값

사실 위에 코딩도 국룰 코딩임 - getPressTime 함수

스위치를 얼마나 오래 눌렀는가 측정하는 함수 elapsed 변수를 사용하여 값 저장

현재 시간에서 누른 시간을 뺀 게 몇 초인지 확인

return한 이유는 delay 를 이용하여 값이 바뀔 수도 있기 때문에 초기값 0으로 복원 사실 위에 코딩도 국룰 코딩임

(17)

ㄴㅁㅇㄹㄴㅁㅇㄹ

4. 최종 코딩 및 작동 영상

.

try:

strPer="%"

mylcd = I2C_LCD_driver.lcd() adcChannel=0

strCur=""

while True:

input = GPIO.input(btnPin) if input == 0:

if prevInput == -1 or prevInput == 1:

pressTime = datetime.now() elif prevInput == 0:

if getPressTime() >= shutdown_sec:

call(['shutdown', '-h', 'now'], shell=False)

break

prevInput = input

adcValue = read_spi_adc(adcChannel)

hum = 100-int(map(adcValue,HUM_MAX,1023,0,100))

변수 strPer, strCur 에 값 지정 / strCur 은 LCD 문구 쓸 예정 mylcd 변수에 I2C_LCD_driver에서 lcd파일 저장

adcChannel=0은 adc 칩의 채널 0 을 사용하겠다는 뜻 input 변수에 btnpin(bcm기준 22) 을 input으로 가져옴 input 변수가 0 일 경우 (풀업 사용했으므로 버튼을 눌렀을 경우 ) 이전 인풋이 -1이거나 1(스위치 안 누름 ) 이면 무반응

이전 인풋이 0 일 경우 (스위치 누름 ), 내가 설정한 초보다 많이 누를 경우 shutdown -h now를 불러온다 .

shutdown 명령어

여기서 shutdown 은 리눅스 종료 , -h 는 시스템을 종료 , now 지금을 뜻하여 shutdown 은 지금 즉시 종료라는 뜻

그리고 break 로 멈춤

prevInput=input이라고 지정

/ 즉 , prevInput 은 input(스위치 상태 ) 의 이전 값

adcValue 변수는 read_spi_adc(adcChannel) 값을 저장 hum은 데이터를 % 로 변환시켜서 값을 저장

습도가 높을수록 낮은 값을 나타내므로 100-값을 하여 습도가 높을수록 높은 값을 나타나게 함

(18)

ㄴㅁㅇㄹㄴㅁㅇㄹ

4. 최종 코딩 및 작동 영상

.

if hum < HUM_THRESHOLD:

GPIO.output(IN1, GPIO.HIGH) GPIO.output(IN2, GPIO.LOW) GPIO.output(R, GPIO.HIGH) GPIO.output(G, GPIO.LOW) GPIO.output(B, GPIO.LOW) print 'yes'

strCur="Warning"

else:

GPIO.output(IN1, GPIO.LOW) GPIO.output(IN2, GPIO.LOW) GPIO.output(R, GPIO.LOW) GPIO.output(G, GPIO.HIGH) GPIO.output(B, GPIO.LOW) print 'no'

strCur="Normal"

mylcd.lcd_clear()

mylcd.lcd_display_string("HUM:%d%s"%(hum, strPer), 1) mylcd.lcd_display_string("STATUS:%s"%strCur, 2)

time.sleep(0.5) finally:

GPIO.cleanup() spi.close()

만약 hum(측정된 값 ) 이 설정해 둔 값보다 낮을 경우 , IN1, IN2(모터 ) 가 작동 (서로 다른 전압 부여 )

RGB중 RED 만 나오도록 RED 만 전압 부여

print ‘yes’는 터미널에서도 확인하기 위해서 사용했었음 strCur=”Warninig”은 LCD 화면에 나타날 문구

만약 hum(측정된 값 ) 이 설정해 둔 값보다 높을 경우 , IN1, IN2(모터 ) 는 스탑 (같은 전압 부여 )

RGB중 GREEN 만 나오도록 GREEN 만 전압 부여 print ‘no’는 터미널에서도 확인하기 위해서 사용했었음 strCur=”Normal”은 LCD 화면에 나타날 문구

mylcd.lcd_clear()을 사용하여 lcd화면 한번 클리어 시켜줌 mylcd.lcd_display_string을 사용하여 글자 작성

우선 HUM:%d%s”%(hum, strPer) “ 은 HUM:” 은 그대로 LCD에 나오고 뒤에 값들은 hum 변수 ( 정수 ) 와 strPer( 문자 ) 작성그리고 뒤에 있는 1 은 첫 번째 줄에다가 작성하겠다는 뜻

“STATUS:%s”%strCur”은 STATUS:” 는 그대로 나오고 뒤에 strCur(문자 ) 를 작성

뒤에 2 는 두번째 줄에 작성하겠다는 뜻

time.sleep(0.5) 을 하여 0.5 초 딜레이 생성

finally -> try구문에서 빠져나왔을 경우 (컨트롤 + c) GPIO를 클리어 시킴

spi를 닫음 (모터 중지 )

(19)

ㄴㅁㅇㄹㄴㅁㅇㄹ

4. 최종 코딩 및 작동 영상

작동 영상은 여기에 추가가 불가능하여 따로 보여드리겠습니다 ..

파일 blog > daily27 > 작동 영상

(20)

이상 발표를 마치겠습니다 .

들어주셔서 감사합니다

참조

관련 문서

DMB 활성화 전략... Thank you for

광원을 태양의 위치에 두고 행성들이 마치 태양에서 빛을 받아 반사하는 듯한 효과를 주게 한다.

[r]

[r]

• 태양계의 전반적인 위치와 공전 및 자전을 구현하고 텍스쳐 맵핑을 태양계의 전반적인 위치와 공전 및 자전을 구현하고 텍스쳐 맵핑을 이용하여 실제

[r]

[r]

유비 쿼터스 시대의 새로운