3. 과제의 수행내용 및 결과
3-1. 프로젝트 추진 일정 및 업무 분담 내용
<그림 23> 프로젝트 추진일정
번호 | 이름 | 학과 | 학년 | 역할 | 담당업무 |
1 | ㅇㅇㅇ | ㅇㅇㅇ | 4 | 팀장 | 프로젝트 조율, 하드웨어 제작 회계 담당 |
2 | ㅇㅇㅇ | ㅇㅇㅇ | 4 | 팀원 | 아이디어 도출, 사업구조 개발 |
3 | ㅇㅇㅇ | ㅇㅇㅇ | 4 | 팀원 | 하드웨어 제작, 회계 담당 |
4 | ㅇㅇㅇ | ㅇㅇㅇ | 4 | 팀원 | 아이디어 도출 및 사업구조 개발 |
5 | ㅇㅇㅇ | ㅇㅇㅇ | 4 | 팀원 | 아이디어 도출 및 사업구조 개발 |
6 | ㅇㅇㅇ | ㅇㅇㅇ | 4 | 팀원 | 소프트웨어 제작 |
7 | ㅇㅇㅇ | ㅇㅇㅇ | 4 | 팀원 | 데이터 수집 및 분석 |
8 | ㅇㅇㅇ | ㅇㅇㅇ | 4 | 팀원 | 데이터 수집 및 분석 |
<표 23> 업무 분담
3-2. 소프트웨어 제작 과정
- 아두이노 소스코드 설명
#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>
#include <SoftwareSerial.h>
/*
*
* 0: 수신기
* 1: 버튼(벨)
* 2: 미세먼지
*
*/
#define ADDR 2
Uint8_t ADDRS[][6] = {"1Node", "2Node", "3Node" }; // Recv, TR1, TR2
#include에 적혀있는 것들은 프로그램이 돌아가기 위한 헤더파일을 포함하고 있는 것에 대해 설명해주는 것이다. 0번은 수신기 아두이노에 업로드 되는 코드, 1번은 초인종(벨 감지) 아두이노에 업로드 되는 코드이며 2번은 미세먼지 감지 아두이노에 업로드 되는 코드이다
Define ADDR 2 로 업로드하면 미세먼지감지 코드만 업로드 된다. 즉 3가지 코드를 한 스케치에 몰아서 번호만 바꿔주면 각각의 코드만 업로드 된다.
마지막 코드는 RF통신 가능한 총 6개의 통신 중 3개를 사용한다는 것이다. (1Node : 수신기, 2Node : 벨 감지, 3Node : 미세먼지)
//
//수신기
#if ADDR == 0
SoftwareSerial mySerial(7, 8);
RF24 radio(9,10);
Void setup() {
mySerial.begin(9600);
pinMode(2,INPUT_PULLUP);
pinMode(3, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
Serial.begin(9600);
radio.begin();
radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX
radio.openReadingPipe(1, ADDRS[1]);
radio.openReadingPipe(2, ADDRS[2]);
radio.startListening();
}
ADDR 이 0으로 업로드 되었을 때 실행되는 수신기 코드이다. 블루투스 통신 이름은 mySerial이며 RF24의 이름이 radio이다. 블루투스 통신의 속도는 9600으로 한다.
시리얼 통신의 속도도 9600으로 설정하고 RF통신의 레벨은 통신 시 노이즈 감소를 위해 LOW로 설정하였다.
Rf통신의 수신 파이프의 주소를 설정한다.(1번은 ADDR1,즉 벨 감지 아두이노에서 수신 2번은 ADDR2, 먼지 센서 감지 아두이노에서 수신)
//
Int button;
Char stat;
Char recv;
Int blue=0;
unsigned long currentTime1 = 0;
unsigned long currentTime2 = 0;
unsigned long currentTime3 = 0;
boolean ent1 = false;
boolean ent2 = false;
boolean ent3 = false;
void loop() {
if (radio.available()) {
radio.read(&recv, sizeof(char));
if(recv == ' \0') {
Serial.println();
}
Serial.print(recv);
}
if (mySerial.available()) {
blue=mySerial.read();
Serial.println(blue);
}
if(digitalRead(2)==0) {
blue = 0;
digitalWrite(3,0);
digitalWrite(5,0);
digitalWrite(6,0);
currentTime1 = 0;
currentTime2 = 0;
currentTime3 = 0;
}
만약 rf에서 수신되는 값이 있다면 그 문자를 recv에 보낸다. 통신 끝 부호' \0'가맞을 경우 (통신 끝에 붙는 부호를 추출) 시리얼모니터에 recv값을 출력한다.
만약 블루투스에서 수신되는 값이 있다면, blue라는 변수에 블루투스 수신값을 저장하고 시리얼 모니터에 blue값을 출력한다. 만약에 디지털2번 핀의 값이 0과 같다면(스위치가 눌러졌다면) Blue변수에 0 을 저장하고 3,5,6번 led를 끄고, currentTime1,2,3 변수에 0을 저장한다.
//
if(recv == 'h') { // 버튼
digitalWrite(3,1);
currentTime1 = millis();
ent1 = true;
}
if(recv == 'y') { // 먼지
digitalWrite(5,1);
currentTime2 = millis();
ent2 = true;
}
if(blue == 1) { // 전화
digitalWrite(6,1);
currentTime3 = millis();
ent3 = true;
blue = 0;
}
만약 recv가 h와 같다면(버튼이 눌러지면 h신호를 수신하게 돼있음) 3번 led가 켜진다.
currentTime1 에는 현재시간이 저장된다.
만약 recv가 y와 같다면(미세먼지가 위험수치로 감지되면 y신호를 수신하게 되어있음)
5번 led가 켜진다.
만약blue가 1과 같다면(블루투스에서 1을 수신한다면=전화가온다면) 6번 led가 켜진다.
다음 전화를 수신하기 위하여 blue 변수 값 초기화시키기 위해 Blue에 0을 저장한다.
unsigned long nowTime = millis();
if(ent1 == true && nowTime-currentTime1 > 3000) {
digitalWrite(3,0);
ent1 = false;
}
unsigned long nowTime2 = millis();
if(ent2 == true && nowTime2-currentTime2 > 3000) {
digitalWrite(5,0);
ent2 = false;
}
unsigned long nowTime3 = millis();
if(ent3 == true && nowTime3-currentTime3 > 3000) {
digitalWrite(6,0);
ent3 = false;
}
}
부호 없는(양수) 변수 nowTime에는 현재시간을 저장하며, 만약 ent1 이 1과 같거나, nowTime에서currentTime1을 뺀 값이 3000보다 크다면(3초 지나면) 3번 led는 꺼진다. Ent1에는 다음 수신을 위하여 초기화하기 위해 0이 저장된다.
버튼(벨)
#elif ADDR == 1
RF24 radio(9,10);
Char write_str = 'h';
Void setup() {
radio.begin();
radio.setPALevel(RF24_PA_LOW);
radio.openWritingPipe(ADDRS[ADDR]);
pinMode(2, INPUT_PULLUP);
}
Int button;
Void loop() {
if (digitalRead(2) == 0) {
if (radio.write(&write_str, sizeof(char)));
delay(500);
}
}
ADDR 1로 업로드 하므로 벨 감지 송신부 코드가 실행된다. 문자형 변수 'write_str'의 값은 'h' 로 한다. Rf통신의 송신 파이프의 주소를 설정하며 2번을 입력 핀으로 설정한다. 만약, 2번 핀 값이 0과 같다면(스위치가 눌러졌다면) write_str 이라는 변수로 rf 송신한다.
송신 지연시간 0.5초이며 버튼이 눌러지면 0.5초마다 'h'전송한다.
미세먼지
#elif ADDR == 2
RF24 radio(9,10);
Char buf[6] = {0 };
Char buf2;
Int measurePin = 0; //Connect dust sensor to Arduino A0 pin
Int ledPower = 2; //Connect 3 led driver pins of dust sensor to Arduino D2
Int samplingTime = 280;
Int deltaTime = 40;
Int sleepTime = 9680;
Float voMeasured = 0;
Float calcVoltage = 0;
Float dustDensity = 0;
Void setup() {
Serial.begin(9600);
radio.begin();
radio.setPALevel(RF24_PA_LOW);
radio.openWritingPipe(ADDRS[ADDR]);
pinMode(6,OUTPUT);
pinMode(ledPower,OUTPUT);
}
Void loop() {
digitalWrite(ledPower,LOW); // power on the LED
delayMicroseconds(samplingTime);
voMeasured = analogRead(measurePin); // read the dust value
delayMicroseconds(deltaTime);
digitalWrite(ledPower,HIGH); // turn the LED off
delayMicroseconds(sleepTime);
calcVoltage = voMeasured * (5.0 / 1024.0);
dustDensity = 0.17 * calcVoltage - 0.1;
Serial.println(dustDensity); // unit: mg/m3
String fStr(dustDensity);
Char c = fStr.charAt(2); // 소수점 첫째 자리수
Serial.println(c);
if(c=='1' || c=='2' || c=='3'|| c=='4' || c=='5'|| c=='6' || c=='7') {
buf2 = 'y';
digitalWrite(6,1);
}
if(buf2=='y') {
if(radio.write(&buf2,sizeof(char)));
}
else if(buf2 == 'n') {
if(radio.write(&buf2,sizeof(char)));
}
delay(1000);
}
#endif
2번 핀을 켜지고 280ms 만큼 지연이 되면 A0핀의 값을 읽어와 voMeasured 변수에 저장한다(먼지센서 측정값) 그 후에 40ms만큼 지연하고 2번 핀이 꺼진다.
2번 핀이 꺼진 후 9680ms만큼 지연이 되며 voMeasured변수의 값 * (5.0/1024.0) 결과 값을 calcVoltage에 저장한다. (1024만큼의 먼지센서 값 범위를 전압 값으로 변환하는 과정)
0.17 * calcVoltage - 0.1 의결과 값(미세먼지 농도 값을 계산하는 과정)을 dustDensity 변수에 저장하고 시리얼모니터에 dustDensity값이 출력된다.
출력된 destDensity를 문자형으로 변환하여 fStr 에 저장하고 문자형 변수 c에 fStr값의 소수점 첫째 자리 수까지 저장한 것을 시리얼모니터에 변수c값을 출력한다.
(먼지센서 농도의 값을 소수점 첫째 자리까지 출력하기 위함)
만약 c가 1,2,3,4,5,6,7중의 하나와 같다면 Buf2에는 y를 저장하고 6번led가 켜진다.
(미세먼지농도 출력 값의 첫째 자리 숫자가 1,2,3,4,5,6,7과 같다면
(8,9를 포함하지 않은 이유는 8,9까지 올라가지 않기 때문이다.))rf 송신 값을 y로 전송한다.
만약, buf2 값이 y와 같다면(미세먼지농도가 올라갔다면) Buf2값을 rf 송신한다. 만약에 buf2 값이 n과 같다면 Buf2값을 rf 송신한다. 1초간의 지연이후에 프로그램은 종료된다.
- 앱 인벤터 소스코드
휴대폰에 문자메시지가 수신된다면 ‘label_phonenumber’ 란에 그 전화번호를 가져와 쓴다.
휴대폰에 전화가 수신된다면 ‘label_phonenumber’ 란에 그 전화번호를 가져와쓴다.
만약 휴대폰에 전화가 수신됐다가 끊어졌다면
‘label_phonenumber’ 란은 “0”으로 쓴다.(오류방지를 위하여 0을 공백처리 하지 않았다.)
앱 화면초기화 고정값 : ‘label_phonenumber’ 란은 “0”으로 쓴다.(오류방지를 위하여 공백처리 하지 않았다)
장치연결버튼의 이름인‘목록_선택1’선택 전 타이머는 비활성화하고,
목록_선택1의 요소 값은 블루투스 클라이언트의 주소와 이름으로 한다.(장치연결버튼을 눌렀을 때 목록_선택1이 실행되는데, 그 안의 값들을 블루투스 주소와 이름으로 하는 명령이며, 이 명령이 생략 될 경우 블루투스 요소들이 나타나지 않습니다)
만약, 블루투스_클라이언트1이 비활성화 되어있다면(휴대폰의 블루투스 기능이 꺼져있다면) “블루투스를 활성화 시켜 주세요.”라는 경고 창이 뜬다.
타이머 활성화 시(타이머 간격은 50ms로 설정) ‘label_phone_number의 텍스트 길이가 10보다 크다면 블루투스_클라이언트1에 숫자 “1”을 보내라.(타이머가 활성화돼있다면 50ms마다 숫자1을 아두이노로 보낸다.)
목록_선택1 선택 후 블루투스_클라이언트1 연결은 목록_선택1에서 항목을 선택하면 (장치연결버튼을 눌러 블루투스 목록을 선택하고, 연결됐다면) “연결됐습니다"라는 알림 창이 뜨고 타이머를 활성화한다.
선택이 안됐거나, 연결이 되지 않았다면
“연결되지않았습니다”라는 경고 창이 뜨며 타이머는 비활성화 된다.
연결끊기_버튼을 눌렀을 경우 “연결이 해제되었습니다.” 라는 경고 창을 띄우고 연결끊기 함수를 호출 한다 연결끊기 함수를 호출 할 시에는 블루투스_클라이언트에 숫자“2”를 보낸다(블루투스 연결끊기면 LED를 끄기 위하여 신호를 보냄)
마지막으로 블루투스_클라이언트의 연결을 끊는다.
3-3. 하드웨어 제작 과정
납땜이 필요한 PCB기판 대신에 간편한 브레드보드를 사용하여 아두이노 구현을 진행한다. 이후 글루건을 이용하여 보드의 홈에 센서들과 모듈을 고정시켜 아두이노를 완성하고 합판을 이용한 외관을 제작하여 최종 완성한다.
3-3-1. 전화수신 구현
<그림5> 블루투스 모듈 <그림6> 블루투스를 통한 수신모듈 구현
아두이노는 자체적으로 유선통신인 시리얼 통신을 사용한다. 휴대전화와 같은 무선통신을 유선통신으로 변환하기 위해 <그림5>과 같은 ‘아두이노 무선통신 모듈 2.4G Wireless nRF24L01P RFM04’을 사용한다. 이 모듈은 nRF24L01 모듈에 2.4GHz 송수신 칩을 포함하여 250Kbps 속도를 구현한 새로운 모듈로써 8핀 인터페이스, SPI통신을 사용하는 것이 특징이며 동작 상태를 확인 할 수 있는 LED가 있다.
<그림7> 앱 인벤터를 이용한 앱제작 <그림8> 완성된 어플리케이션 화면
이를 통해 변환된 시리얼통신으로 전화가 수신되면 bluetooth로 보내기 위해서 애플리케이션 개발이 필요하여 <그림7>와 같이 앱 인벤터를 이용하여 간단한 전용 애플리케이션을 개발 한다. 앱 인벤터란 블록 형태의 스크립트 구성으로 안드로이드용 애플리케이션을 제작가능 하다. 이 어플리케이션은 전화 수신을 감지하는 것이 주된 기능으로 수신된 전화번호를 ‘lable_phonenumber’란에 표시하고 ‘장치연결’버튼으로 블루투스 연결을 하며 ‘연결해제’버튼으로 블루투스 연결을 끊을 수 있다. 휴대폰의 블루투스 기능이 꺼져있으면 “블루투스를 활성화 시켜 주세요.”라는 경고 창이 뜬다. 장치 연결버튼을 눌러 블루투스 목록을 선택하고 연결되었다면 “연결됐습니다”라는 알림창이 뜨고 타이머를 활성화 한다. 선택이 안됐거나, 연결이 되지 않았다면 “연결이 되지 않았습니다”라는 경고 창이 뜨며 타이머는 비활성화 된다. 연결 끊기 버튼을 눌렀을 경우에는 “연결이 해제 되었습니다”라는 경고 창을 띄운다. 이때 타이머 기능을 사용하는 이유는 블루투스 송신에 오류를 막기 위해서이다. 타이머 기능을 두지 않으면 계속 값이 전송되는데 전송할 값이 없게 되면 애플리케이션과 아두이노 연동에 오류가 발생하여 애플리케이션이 종료되기 때문이다. 이로써 전화가 수신되면 애플리케이션에서 이를 인식하고 블루투스로 정보를 보내 파란색 LED전구를 점등하며 전화가 끊기면 자동으로 소등된다.
3-3-2. 초인종 인식 구현
<그림1> 택트버튼 스위치 <그림2> 택트버튼을 통한 초인종 구현
택트버튼 스위치는 스위치를 누르면 아두이노에 정보를 보내는 역할을 하는 부품이다. <그림2>와 같이 택트버튼과 LED전구를 연결하여 초인종을 누르는 것처럼 이 스위치를 누르면 초록색 LED 전구를 점등하고 2초 후 자동으로 점등한다.
3-3-3. 미세 먼지 센서 구현
<그림3> 미세먼지센서 <그림4> 미세먼지센서 구현
실내 주변공기 환경을 측정하기 위하여 아두이노 전용 미세 먼지 센서인 ‘ GP2Y1010AU0F’를 사용 하여 구현 하였다. 이는 담배 연기 또는 일반 미세입자 검출이 가능한 먼지센서로 전류 소모량이 매우 적고(20mA max,11mA typical)7V DC까지의 전원으로 동작이 가능하다. 위의 <그림4>은 미세먼지 센서에 라이터 불을 켜서 먼지센서 수위를 인식 하게 하는 과정이다. 설치된 미세먼지 센서가 주변공기의 환경을 인식하여 일정 수치를 초과 할 때에 빨간색 LED전구를 점등하며 이후 수치가 개선되면 자동으로 소등된다. 이 센서의 제품 스펙에 따르면 출력값의 최소값은 환경에 따라 변경될 수 있기에 계속 보정해야한다고 명시되어 있다. 이에 따라 음의 값이 나오지 않은 최소값을 평균 30~40정도 측정하였고 이를 ‘0’으로 잡아 연구를 진행하였다.
3-4. 과제의 수행결과
<그림12> 최종 레이아웃
위 <그림12>의 그림은 최종 레이아웃 사진을 포함하여 각각 초인종, 미세먼지, 전화수신을 구현한 사진이다. 초인종을 구현한 박스에는 브레드보드의 스위치커버를 길게 빼서 박스 위에서 누를 수 있도록 스위치와 커버를 고정하였고 미세먼지센서를 구현한 박스에는 미세먼지센서 구멍에 따라 박스 옆쪽에 구멍을 뚫어 고정시킴으로써 박스 외부의 주변 공기가 통할 수 있게 제작하였다. 또한 각각의 전구의 크기에 맞게 윗 판에 구멍을 뚫어 전구를 고정하였으며 블루투스 모듈의 LED도 외부에서 확인 할 수 있도록 구멍을 뚫어 윗 판에 고정하였다.
'♥교육♥ > 대학' 카테고리의 다른 글
어구재료학 : 어구재료의 구비조건과 재료별 종류 및 특징 (1) | 2023.08.23 |
---|---|
[과제]청각보조기구 캡스톤③-결과,기여도,마케팅,설문지 (0) | 2019.01.16 |
[과제]청각보조기구 캡스톤①-목적,필요성,사양,경제성(NPW,MARR,IRR,) (0) | 2019.01.14 |
[과제] SCM 혁신사례 SK하이닉스 반도체 SCM사례 (0) | 2019.01.13 |
[과제]정보시스템-패키지다이어그램 3-계층 테이블정규화 (0) | 2019.01.11 |