Download - IoT 및 안드로이드 포트폴리오 - 한수빈
2
목차
• 프로젝트 개요
프로젝트
3• 프로젝트 주요기능 5• 프로젝트 구성도 6• 기기간 통신 구성 7
스마트 램프
• 스마트 램프 내부 8• 스마트 램프 코드 블록 9• 스마트 램프 메인 루프 10• 스마트 램프 LED 명령처리 방식 11
어플리케이션
• 어플리케이션 최초 시작 12• 사용자 테스트 13• 회원 등록 14• 스피너 사용 15• 위치 찾기 16• MainActivity 17• App 에서의 블루투스 통신 19• Bluetooth 메뉴 20• 홈 메뉴 21• 조명 메뉴 22• 조명 메뉴 - 세부화면 23• 모니터링 메뉴 24• 내 정보 메뉴 25• 내 정보 메뉴 - 수면정보 26• 설정 27• PendingIntent 를 사용하는 기능의 구조 28• 노티피케이션 서비스 29• 기상 알람과 날씨 알림 30• 미흡한 점 31
3
• 프로젝트명 : SleepKit
• 프로젝트 목표 : 스마트 램프를 통한 컬러 테라피와 앱을 활용한 램프 제어 및 수면 관리에 도움
• 담당파트 : 기획 , 하드웨어 프로그램 및 앱 개발 (1인 개발 )
• 사용언어 : Java(Android), C(Arduino)
• 안드로이드 사용 라이브러리 : android support lib(v7:22.2.0), simplebluetoothlibrary, material-dialogs, MPAndroidChart
• 개발기간 : 6개월 (하드웨어 , App)
프로젝트 개요
4
• 먼지 , 온습도 센서가 부착되어 있는 스마트 램프와 안드로이드 Application 으로 구성되어 있음
• 스마트 램프는 Arduino 와 주변 센서들을 이용해서 만들어졌고 , App 과의 블루투스 연동을 통해 제어됨
스마트 램프 SleepKit App
프로젝트 개요
5
App
• 블루투스 연동을 통하여 스마트램프 제어
• 기상 직후 설문을 통한 수면 자가진단
• 노티피케이션을 이용한 수면 조언
• 수면기록을 토대로 차트 표현
• 기상 시 알람과 함께 날씨 알림
스마트 램프
• Led Dimming( 끄기 , 켜기 , 점점 어두워지기 , 밝아지기 , 주기적인 색상변환 등 )
• Led 를 이용한 알람 기능
• 센서를 통한 수면환경 측정 ( 먼지농도 , 온습도 )
프로젝트 주요기능
6
Product
MCU
LED LightSensor
온습도 미세먼지BluetoothModule
SEND RECEIVE
sensor datacontrol com-mand
schedule(alarm)
앱
프로젝트 구성도
7
기기간 통신 구성
• 기기간 통신은 블루투스 페어링을 사용
• 메시지 문법을 정의하여 문법대로 통신
8
• Arduino(With Bluetooth)• Grove Temp, Humi Sen-
sor• Dust Sensor• Led Strip
스마트 램프 내부
9
Setup
센서 , LED 초기화EEPROM 에서 이전 설정 불러오기
타임 인터럽트 설정
출력버퍼 비우기
Loop
블루투스 명령어 받기(LED 모드 변경 , 센서 값 출력 )
센서 값 읽기
요청 받은 명령 처리(LED 모드 변경 , 센서 값 출력 )
Time Inter-rupt
LED Dimming 스케줄에 따른 Led 제어
기기 전원 On 시 실행 프로그램 메인 루프 루프도중 주기적으로 실행
스마트 램프 코드 블록
10
스마트 램프 메인 루프
요청 목록 ( 배열 )
명령어 해석
센서 값 읽기명령 처리
저장불러오기
• 명령어 해석 단계에서 블루투스 읽기버퍼가 빌 때 까지명령어 해석 후 해석마다 배열에 해석된 명령어 저장
• 센서 값 읽기 단계에서 센서 값을 읽은 후 센서 값 배열에 저장
• 배열에 존재하는 해석된 명령어들을 인덱스 순서대로 처리
11
스마트 램프 LED 명령처리 방식
명령 처리
현재 스케줄에 따른
변수처리
(RGB 변수 [] 등 )
LED 작동 (RGB 변수 [])
조건 분기에 따른 스케줄 인덱스 증가
Time Interrupt
끄기 색 1 설정 루프색 2 설정 색 2 로 변화색 1 시작
LED 스케줄 배열
EX )
LED 모드 , 색 1, 색 2, 시간 등 전달
LED 스케줄 배열에 스케줄 배정 , 매개변수 저장
12
• Shared Preference 를 통해 앱의 첫 구동을 확인 , 사용자 가입을 하도록 유도
어플리케이션 최초 시작
13
• 3 지선다의 성격유형 테스트와 2 지선다의 수면유형 테스트를 진행• 수면타입 지도를 배열의 형태로 짜서 yes, no 에 따라 정해진 답으로 가도록 유도
사용자 테스트
14
• 회원등록 화면은 Activity 한 개와 9 개의 정보입력 Fragment 로 구성 , 각각의 Fragment 는 JoinFragment라는
추상클래스를 상속받으며 , JoinFragment 에는 회원정보를 Activity 로 전달하기 위한 Listener 와 다음 목적지
Fragment 를 set, 그 이외에 필요한 과정은 인터페이스를 사용하여 획일화 하고 공통되는 과정은 Override 함
회원 등록
15
• 회원등록 절차에 스피너가 많아 스피너를 생성하는 클래스를 구현하여 스피너 사용• 스피너 내용을 입력하는 메소드와 아이템이 선택되었을 때 이벤트 메소드를 인터페이스화
하여사용
// 스피너에 사용되는 Item List 를 작성하여 반환
// 스피너의 아이템이 선택되었을 때 호출 됨
스피너 사용
16
• Material Dialog 라이브러리를 사용하여 Material 형태의 다이얼로그 사용• GPS 가 켜져있지 않으면 GPS 를 키도록 함• 구글 API, GeoCoder 클래스를 이용하여 현 위치의 좌표를 얻고 ~ 시 ~ 구 까지 지역
이름을 알 수 있음
위치 찾기
17
App 설명
• 가입 이후 MainActivity 로 이동하게 됨 . MainActivity 는 위와 같은 구조로 구성되어 있음
• 메뉴 이동을 위한 Navigation Drawer 구성과 Toolbar 가 화면에 적용되어 있음• Toolbar, NavDrawer 는 Activity 단에서 제어함
Fragment
Toolbar
Navigation Drawer
MainActivity
18
• MainActivity 는 그림과 같은 기능을 담당• 회원가입 이후 모든 화면은 MainActivity 에 BluetoothFragment 가 Attach 되어
보여짐
Toolbar OptionMenu
Bluetooth 객체
Navigation DrawerFragment 와의
메시지 교환을 위한 Listener
Fragment 관리
MainActivity
MainActivity 역할
BluetoothFragment
extends BaseFragment
BaseFrag-ment
Backstack 관리
Fragment Man-ager 의 함수 사용
extends Fragment
Attach
19
• 블루투스 통신 자체는 오픈소스 라이브러리를 활용하였고 , 블루투스 객체는 MainActivity 에서 관리된다 .• 메시지 Send 는 MainActivity 의 sendMessage 메소드를 활용 , 메시지 Receive 는 Activity 에 Listener
를 등록하여 이벤트가 일어났을 때 Listener 로 Callback 하도록 하였다 .• BluetoothFragment 를 상속하는 Fragment 는 Attach 시 자동으로 activity 에 Listener 를 생성하여 등록을
하며 , Listener 를 생성하는 메소드는 추상메소드이므로 , Fragment 마다 Listener 의 내용을 다르게 할 수 있다 .
App 에서의 블루투스 통신
BluetoothFragment
protected abstract MainActivity.BluetoothLister createLis-tener();
public void onAttach(… …){ MainActivity.BluetoothListener = return createListener();}
MainActivity
void onBluetoothReceive(String s){ if(bt != null) bt.call(s);}
private BluetoothListener bt;
public void sendMessage(String s){
…}
Call 가능
등록
생성된 리스너의 메소드를 호출
20
• Toolbar 의 Bluetooth 메뉴는 어떤 메뉴에서든 실행할 수 있음• 블루투스가 켜져 있지 않을 시 그림과 같이 확인 메시지가 뜸• 페어링 목록에 있지않은 기기는 Scan 을 하여 목록에 추가 가능
Bluetooth 메뉴
21
• 등록 시 기입했던 정보를 보여줌
• 앱 이용시 취침 , 기상버튼을 통해 기록한 정보가 sqlite 에 저장되어 최근 수면을 잘 했는지 분석하여 3 가지 상태로 표현
• 현재 시간과 취침시간을 비교하여 현재까지의 수면조언을 보여줌 , Layout 에 addView 되는 형식으로 차곡차곡 조언이 누적된다 .• 취침 , 기상버튼으로 취침 , 기상시각을 sqlite 에 저장하고 , 만약 램프와 페어링되어 있다면 램프를 수면모드로 바꾸거나 해제한다
• 예상수면시간과 기상시간은 램프에 입력되어 수면시각 이후 일정 시간동안 수면모드 , 기상 전 일정시간 전부터 기상모드로 불빛이 변화한다 .
홈 메뉴
1
2
3
1
4
2
5 5
345
22
• 조명메뉴는 램프의 조명 메뉴 중 4 가지를 제어 할 수 있도록 만들어졌으며 , 화면은 listView 로 만들어져 있고 listView 는 viewHolder 를 사용하여 view 를 중복으로 불러오지 않도록 하였음
• 각 메뉴의 오른쪽에는 메뉴를 통해 램프를 키면 어떤 색이 나올 지 보여주고 있음 , SharedPreference 를 이용하여 구현
• 램프 특성상 조명모드는 한번에 한 개 밖에 되지 않으므로 여러 개의 Switch 가 On 되지 않도록 하였음 , listView 에 set 되는 Adapter 에 Switch 들을 Collection 안에 모아 넣고 , 각 스위치 별로 ON, OFF 의 상태를 확인하도록 구현함
• 블루투스 연결이 되지 않았을 때 Switch 가 On 되지 않도록 함
조명 메뉴
12
3
1
4
234
23
조명 메뉴 – 세부 화면
• 조명 메뉴에서 낮잠 모드를 제외한 3 개의 메뉴는 색을 조정할 수 있는 세부 화면이 있음
• 등록시 했던 테스트의 결과에 따라 유형에 맞는 추천 색깔이 나타나게 됨
• ColorPicker 를 구현하여 자유롭게 색상 선택 가능
• 세부 화면에서 선택한 색깔들은 SharedPreference 에 저장되어 이전에 사용했던 색깔들이 우선적으로 보여지고 , 상위 메뉴에서도 미리 볼 수 있음
1 2
12
24
• 스마트 램프의 센서를 통한 실시간 수면환경 체크 및 수면기록들을 차트로 볼 수 있는 메뉴
• 수면환경 아래의 차트 화면들은 SlidingTab, ViewPager 로 구성
• 램프와 연결이 된 상태라면 onResume 에서 블루투스 통신을 통해 센서 값이 화면에 표시 됨
• 수면시간은 막대 그래프 , 취침과 기상시각은 변화를 알 수 있도록 꺾은 선 그래프로 표현
• 하루가 24 시간이기 때문에 수면 시간에 따라 그래프가 급격히 보일 수 있으므로 Y축의 최소 최대 값을 차트의 표현되는 데이터의 max,min 값에 +- 2 시간으로 하여 데이터 표현을 완만하게 그려냈음
• 사용자가 직접 수면을 기록한 날만 차트에 표현되며 , 그 이외의 날은 공란으로 표기되도록 함
모니터링 메뉴
1
2
12
25
• 내 정보 메뉴로써 앱에 등록했던 정보들을 보거나 수정하는 것이 가능 , 총 4 개의 카테고리가 있음
• 계정 정보를 확인 가능
• 이용자의 지역정보를 다시 한번 확인하는 것으로 , 등록 시 사용하는 지역정보 찾기와 동일
• 등록 전 했던 테스트를 다시 하거나 결과를 볼 수 있는 메뉴로 , ViewPager, SlidingTab 으로 화면이 구성되어 있음
내 정보 메뉴
1 3
12
1
2
3
3
26
• 등록 시 기입했던 정보 중 앱 사용에 영향을 주는 항목 일부가 모여있는 메뉴로 수정이 가능
• ViewPager 와 SlidingTab 으로 구성
• 수정하기 버튼을 누를 경우 수정을 할 수 있도록 UI 가 구성되며 , 화살표를 터치하면 다이얼로그가 나와 수정을 할 수 있게 됨
• 입력한 정보에 따라 체크박스가 미리 체크되어 나오며 , onChecked 이벤트가 발생할 때 마다 SharedPreference 에 내용이 수정되어 저장됨
내 정보 메뉴 - 수면정보
1
3
2
1
2
3
2
1
27
• 앱의 설정을 바꾸는 메뉴로 , 노티피케이션의 On/Off 여부와 기상 알람의 설정을 할 수 있음
• onCheckedChange 리스너를 통해 스위치 Off 를 알고 앱 컨셉에 따라 그림과 같이 다이어로그가 나타남
설정
28
PendingIntent 를 사용하는 기능의 구조
• 본 앱에서는 PendingIntent 와 AlarmManager 를 사용하여 다음과 같은 컴포넌트들로 노티피케이션과 알람 기능을 예약함
• Reservation Service : 알람 기능과 노티피케이션 기능을 예약하는 서비스
• Alarm Activity : 사용자에게 기상 알람을 하는 역할
• Notification Service : 사용자에게 노티피케이션을 띄우는 서비스
• 앱 최초 실행 이후 Reservation Service 가 자기 자신을 예약하기 때문에 노티피케이션과 알람 타이밍을 놓치지 않음
BroadCastReceiver
AlarmActivity
NotificationService
ReservationService
Boot, 최초실행
Key 값
Run!
하루에 한 번 자기 자신을 예약
Key 값
29
• 현재 취침시각까지 남은 시각에 따라 매 시간마다 수면에 관한 조언을 노티피케이션 함
• 설정메뉴에서 설정한 노티피케이션 On/Off 여부에 따름
• 서비스가 시작될 때 인텐트에 포함된 키 값에 따라 어떤 노티피케이션을 보여줄지 분류함
노티피케이션 서비스
30
• 사용자가 설정한 기상시각에 맞춰 날씨와 함께 위와 같은 기상 알람 화면이 표시 됨
• 알람 화면은 일정한 간격의 진동과 노래와 함께 표시되며 , 사용자 설정에 따라 On/Off 여부가 결정 됨
• 날씨 정보는 사용자가 등록 시 설정된 지역의 현재 날씨를 보여주며 , OpenWhetherMap.org 의 API 를 사용하였음
• 날씨 정보는 Json 을 파싱한 것이고 , 기상시각 5 분 전 AsyncTask 를 상속한 클래스에 의해 파싱이 이루어짐
• 파싱한 정보는 SharedPreference 에 입력되어 저장 된 다음 알람 화면이 표시 될 때 Preference 에서 가져와 날씨 정보를 표시함
기상 알람과 날씨 알림
31
• 정상작동을 확인하는 명령어를 넣지 않음
• 램프의 현재 모드 , 총 실행 시간 등을 알리는 명령어를 넣지 않음
미흡한 점
스마트 램프
• 사용자가 기상시각 , 취침시각을 변경하였을 때 알람 , 노티 예정 시각을 바로 재설정 하지 않음
• SharedPreferece 의 키 값을 얻어오기 위해 상수를 사용하는 것으로 초기 설계를 함 (Enum 을 사용했어야 했음 )• 램프로부터 센서 값을 가져온 후 센서 값이 제대로 받아졌는지 확인하지 않고 바로 사용함
• View 에 애니메이션을 사용하지 않아 사용성이 떨어지는 부분이 있음
어플리케이션
32
감사합니다