- 이 프로젝트는 중소기업 R&D 현장맞춤형 인턴십 지원사업 과정 동안 개발한 BLE 기반 스마트 베개 제어 앱 '잠드림(ZamDream)'입니다.
- 사용자가 스마트폰(Android, iPhone)을 통해 베개의 높낮이 및 방향(향기 방출) 단계를 조절하고, 베개의 배터리 상태를 표시하여 편안한 수면 환경을 누릴수 있도록 서비스를 제공합니다.
화면 이름 | Android | iOS |
---|---|---|
시작 화면 |
||
디바이스 스캔 화면 |
||
디바이스 스캔 완료 화면 |
||
디바이스 연결 성공 화면 |
||
디바이스 연결 실패 화면 |
||
디바이스 컨트롤 메인 화면 |
||
디바이스 높낮이 컨트롤 화면 |
||
디바이스 방향 팬 컨트롤 화면 |
||
디바이스 방향 팬 (on) 화면 |
||
디바이스 연결 끊김 화면 |
-
React Native CLI
-
TypeScript
-
React Navigation
-
BLE
-
- BLE 기반 디바이스 연결 및 데이터 송수신
- 베개 5개 부위(머리, 목, 어깨, 머리 좌측, 머리 우측) 및 방향(향기 방출) 사용자 맞춤형 높낮이/단계 설정
- Zustand를 활용한 디바이스 연결 상태 및 베개 높낮이/단계 데이터 상태 관리
- MMKV를 활용한 디바이스 베개 높낮이 데이터 저장
1. 디바이스 데이터 전송 문제
-
이슈: Buffer 값을 Base64로 인코딩하여 전송해야 했으나, 정해진 프로토콜에서 동작하지 않는 값들이 존재.
-
해결: H/W 개발자와 협력하여, 알파벳 조합으로 이루어진 프로토콜 값만 Base64로 인코딩하여 전송하도록 프로토콜을 수정하고 조율.
Code
// 문자열을 Base64로 인코딩하는 함수 const encodeFromBufferToBase64 = (data: string): string => { return Buffer.from(data).toString('base64'); }; export default encodeFromBufferToBase64;
2. 배터리 상태 값 불일치
-
이슈: 디바이스에서 받아오는 배터리 상태 값이 실제 배터리 상태와 다르게 매번 변동.
-
해결: 배터리 상태를 3단계 구간으로 정리하여 전송하도록 조율.
- 0 ~ 30%:
30%
- 31 ~ 50%:
50%
- 51 ~ 100%:
100%
Code
const [batteryLevel, setBatteryLevel] = useState<number | null>(null); // 배터리 레벨을 저장하는 상태 const batteryImage = batteryLevel === 100 ? require('../assets/images/battery100.png') : batteryLevel === 50 ? require('../assets/images/battery50.png') : require('../assets/images/battery30.png'); { batteryLevel && ( <View style={{ flexDirection: 'row', justifyContent: 'center', alignItems: 'center', marginTop: 8, }}> <Image source={batteryImage} style={{ width: 24, height: 12, marginRight: 10, }} resizeMode="contain" /> <Text style={{ fontSize: 16, fontWeight: 'regular', color: '#ffffff', }}> {batteryLevel}% </Text> </View> ); }
- 0 ~ 30%:
3. H/W와 S/W 호환성 문제
-
이슈: 앱에서 기기로 데이터를 전송한 후 H/W에서 예외적 상황(연결 끊김 등) 발생.
- 예: 앱에서 현재 1단계인 상태에서 5단계 값을 기기로 전송했으나, H/W가 동작 도중 연결이 끊기는 문제 발생.
-
해결:
- 데이터를 전송하기 전에 디바이스 연결 상태를 체크하고, 연결이 끊겼을 경우 재연결 시도.
- 앱이 실행 중인 동안 연결 상태를 지속적으로 확인하며, 연결이 끊기면 즉시 재연결 시도.
Code
// 기기의 연결 상태를 확인하고, 연결이 끊어진 경우 재연결을 시도하는 함수 const checkBluetoothDeviceConnection = async (deviceID: string) => { const isConnected = await BLEService.manager.isDeviceConnected(deviceID); if (!isConnected) { await BLEService.manager.connectToDevice(deviceID).then(async () => { await discoverBlueToothDeviceServicesAndCharacteristics(deviceID); }); } }; export default checkBluetoothDeviceConnection;