August 3, 2020

[58호]낙상사고자를 살리는 마지막 사이렌, Life Bell

58 ict 라이프벨 (1)

 

2019 ICT 융합 프로젝트 공모전 참가상

낙상사고자를 살리는 마지막 사이렌, Life Bell

글 | 한동대학교 반병우

1. 심사평
칩센 이미 상용화를 준비하고 있는 제품에 대하여 평가를 하는 것이 맞는것인지 모르겠습니다. 개발자께서 이미 사전 조사를 하여 알고 계시겠으나, 금번 개발 작품과 같이 낙상 사고 대비를 위한 제품을 포함하여 Silver care 관련한 수많은 제품들이 준비되고 기획되고 있습니다. 요양병원등과 같은 B2B의 형태도 중요하지만, 지역 기관등을 통하여 선제적인 보급과 스마트폰 뿐이 아닌 여타 기관에서 관리중인 시스템과 연계하는 부분도 검토가 필요하지 않을까 합니다.
뉴티씨 실제로 삶에서 노인들이 낙상하는 경우나 도움이 필요한데 즉시 도움을 주지 않을 경우 사고가 커져 심지어는 사망에 이르게 되는데, 이런 경우에 자동으로 낙상사고를 알려서 즉시 도움을 받을 수 있도록 하는 장치입니다. 매우 실질적인 제품이기에, 상품화하여 모든 노인분들이 착용하면 좋겠습니다.
위드로봇 낙상의 패턴을 분석하는 것이 가장 어려운 부분인데, 이 부분의 추가 연구가 필요합니다.
펌테크 실생활에 사용이 될 수 있는 실용성, 아이디어, 창의성이 돋보이는 작품으로 생각됩니다. 전체 하드웨어 시스템 구성은 비교적 심플한 구성인 반면에 낙상사고를 실질적으로 대비하기에 손색이 없을 정도로 잘 기획된 작품이라고 생각됩니다 다만 작품의 동작 영상을 볼 수 없어 출품작의 최종 완성도를 정확히 판단할 수가 없었습니다.

2. 작품 개요
내가 중학교 때 할머니가 낙상 사고로 돌아가셨다. 더 안타까운 점은 바로 옆방에 내가 있었음에도 대처를 하지 못했다는 점이다. 그리고 이런 슬픈 일이 나의 일만이 아니라는 것을 알게 되었다. 낙상 사고는 우리나라 사고사망원인 2위로 실제로 많은 사람들의 목숨을 위협하고 있다. 하지만 현재 그 어떤 회사도 이를 막을 만한 제품을 만들어 내지 못하고 있다. 이러한 사회적 문제점을 해결하고자 이번 ‘Life Bell’을만 들게 되었다. 낙상 사고를 막기 위해 우리 사회엔 지팡이 등 넘어지지 않기 위한 도구가 이미 존재한다. 하지만 이러한 도구들도 낙상 사고를 막지 못하고 있다. 그래서 우리는 이미 넘어진 후 생존을 위한 도구를 생각하게 되었고, 이를 만들어 보급함으로써 실제로 정말 많은 사람의 생명을 구하고 싶다.

58 ict 라이프벨 (2)

2.1. 아이디어 필요성
고령자의 안전사고는 매년 점점 더 증가하고 있다. 여기서 우리가 눈여겨 볼 점은 그 중 절반 정도(47.4%)가 낙상사고였다는 것이다. 이러한 낙상사고에는 4분이라는 골든 타임이 존재하지만 사고를 당한 노인분들이 이 상황에서 스스로 대처하시거나 주변사람들에게 도움을 청하는 것은 쉽지 않은 현실이다. 그 결과 노인들의 낙상 사고 사망률은 타 연령대의 10배에 달한다. 더 나아가 이미 우리 사회엔 지팡이와 같이 넘어지지 않기 위한 도구가 존재하지만, 이런 도구들도 낙상 사고를 막지 못하고 있다. 그래서 우린 이미 사고가 발생 한 후 생존을 위한 도구를 생각하게 되었다.

2.2. 아이디어 목표
· 정확한 낙상 감지
· 낙상 감지후 신속한 대처 절차

3. 주요 동작 및 특징
3.1. ‘Life Bell’의 기본 동작 및 역할

58 ict 라이프벨 (3)

착용자의 몸의 기울기를 측정하는 기울기 센서, 착용자의 속도 변화량을 감지하는 가속도 센서를 통해 낙상이 감지 되었을 시 어느정도 시간이 지날 때 까지(현재 15초로 지정) 대처가 되지 않았을 경우 기기 자체에서 1차적으로 사이렌을 울린다. 그리고 시간이 더 지날 때까지도 대처가 되지 않을 시엔 보호자에게 현재 위치와 함께 낙상 감지 문자가 보내진다, 그리고 사고 발생 후 30초가 지날 때 까지도 대처 되지 않았을 시 119에 자동 문자 신고가 접수된다.

3.2. 기존 유사 사례 및 차별화 포인트
가. 유사사례

58 ict 라이프벨 (5)

· 기존에 우리와 유사한 제품으론 바이탈밴드와 낙상 폰이 있다. 하지만 두 기기 모두 팔의 궤적으로 낙상을 감지한다. ▶ 어깨가 굳어 팔의 움직임이 자유롭지 못한 노인분들의 낙상은 감지하지 못한다.
· 낙상폰은 40만원 이상, 바이탈밴드는 50만원 이상의 고가로 책정되어 있고 사용법이 너무 어렵다. ▶ 실직적으로 사용하기가 번거롭고 어렵다. 그리고 가격으로 인해 구매하기가 부담스럽다
· 기기 형태가 제한 ▶ 기기 형태가 제한된 웨어러블 디바이스의 가장 큰 특징은 점점 더 사용빈도가 낮아진다는 점이다.

나. 차별점

58 ict 라이프벨 (4)

· 우리가 만든 기기, Life Bell은 몸의 중심축의 기울기 변화를 통해 낙상을 감지한다. ▶ 정말 낙상 여부 감지가 필요한 노인분들의 낙상을 감지할 수 있다.
· 낙상 감지 기능에 집중하여 가격을 크게 낮추었다.
· 기술력을 바탕으로 노인분들이 일상생활에서 사용하는 지팡이, 휠체어, 보행 도구, 자전거, 모자 신발 등에 적용하여 사용할 수 있어서 사용빈도가 줄지 않는다. 그 외 안전사고가 일어날 수 있는 수많은 곳들에 적용할 수 있다.

3.3. 정확한 낙상 감지 방법

58 ict 라이프벨 (6)

그림에서 볼 수 있듯이 앉았을 때와 누웠을 때와는 다르게 넘어졌을 때 기울기의 변화 값이 3배이상 크게 감지되었다. 이 구별 방법을 통해서 낙상을 정확하게 감지 할 수 있었다.

4. 전체 시스템

‘Life Bell’은 크게 감지부, 관제부, 전력 공급부로 이루어져 있다.

58 ict 라이프벨 (7)

4.1. 구성품

58 ict 라이프벨 (8)

58 ict 라이프벨 (9)

4.2. 구성요소
· 감지부 : mpu6050 기울기센서와 가속도 센서를 통해 이상 움직임을 감지한다. 기울기 센서는 착용자의 몸의 중심축의 기울기 변화를 측정하고, 가속도 센서는 착용자의 몸의 속도 변화를 감지한다. 이 2가지 변수로 낙상을 정확하게 감지한다.
· 관제부 : 사이렌과 통신부로 이루어져 있고, 이곳에서는 위급한 상황이 유지될 시 사이렌을 울리고, 블루투스 통신을 어플리케이션을 통해 문자 기능과 GPS기능을 활성화시켜 보호자과 119에 현재 상황과 위치를 알린다.
· 전력 공급부 : 감지부와 관제부가 역할을 잘 할 수 있도록 전력을 공급하여 준다.

4.3. 개발환경

58 ict 라이프벨 (10)

‘Life Bell’의 기기는 아두이노 나노를 기반으로 PCB를 제작하였으며, 모든 명령어 및 코드는 C언어로 코딩되어 있다. 또한 ‘Life Bell’ 어플리케이션은 자바 이클립스로 코딩을 하여 제작을 하였다.

5. 로드맵

58 ict 라이프벨 (11)

우리는 기술의 유효성, 실효성, 시장성을 인정받아 특허를 등록하였고, 이 기술을 바탕으로 프로토타입을 개발하였다. 그리고 현재는 한동대학교 IDEA 랩실에 지원을 받아 제품의 소형화 단계에 있다. 그리고 제품의 소형화 후 병원, 요양원 등 시설과 B2B마케팅을 통해 시장에진입할 것이고, 그 후엔 보험사, 일인 이용 수단 회사들과 콜라보레이션 마케팅을 통해 시장을 더더욱 확대해 나갈 것이다.

6. 기타

58 ict 라이프벨 (12)

6.1. 기기 소스코드

라이브러리 선언 및 함수 정의
// 라이브러리 선언
#include <Wire.h> // I2C통신 설정 – 가속도 측정하기 위함
#include “MPU6050.h” // 가속도 라이브러리 선언(가속도 측정 관련 라이브러리)
#include <SoftwareSerial.h> // 소프트 시리얼 라이브러리 선언(블루투스 통신하기 위함)

// 핀 번호 설정
#define BUZZER 7 // 부저 핀 번호
#define RESET 4 // 가속도센서(mpu6050) RESET 핀 번호
int TxPin = 5; // 블루투스 통신 TX단자
int RxPin = 6; // 블루투스 통신 RX단자
SoftwareSerial BTSerial(TxPin, RxPin);

// (중요)(중요)
int NOMAL_ANGLE = 20; // 정상기울기 범위, 기울기가 ‘NOMAL_ANGLE’ 안에 들어 올 경우 정상처리
long CRASH_VALUE = 700; // 충돌 값(충돌 판단하는 값, 가속도 변화량 값)

// 구동 변수
long ac_x, ac_y, ac_z, gy_x, gy_y, gy_z ; //acc, gyro data (acc, gyro 계산 수식)
double angle1 = 0, deg ; // angle, deg data (각도계산)
double angle2 = 0;
double dgy_x ;
long mapping_value = 1000;
long normal_x,normal_y,normal_z, deltha_x[3],deltha_y[3],deltha_z[3], deltha, angle_1[3], angle_2[3] ;
long event_value = 1000;

// 처리 변수
const int delay_main = 1; // 전체 시스템 구동하는 데, 걸리는 시간 (즉 구동 시간)이다. (ex) 1000 = 1000ms = 1s = 1초
const int sum_count = 4;
long delay_config = 6000; // 이벤트 발생 후 딜레이
boolean ACCESS_ACCEL = false;
long TIEMR_BLESEND = 0;
bool WARN_STATE = false;
long TIMER_WARN_STATE = 0;
bool buzzer_state2 = true;

// 함수 선언
int ACTION_config();
void value_init();

통신 설정
void setup() {

// 시리얼통신 & 소프트시리얼 통신 설정
Serial.begin(115200); BTSerial.begin(9600);

// 핀모드 및 초기 설정
pinMode(BUZZER, OUTPUT);pinMode(RESET, OUTPUT); // 출력으로 사용
tone(BUZZER, 1000, 100); delay(200); tone(BUZZER, 1000, 100); // 부저 울리기
digitalWrite(RESET, LOW); // RESET 초기화

// 가속도 센서 설정
delay(100);
mpu6050_init(); // 가속도 센서 초기 설정
ACCESS_ACCEL = ACCEL_ACCESS(); // 가속도 센서 값 맞게 나오는지 확인하기
}

블루투스 통신
void loop() {

// 1. 정해진 시간마다 블루투스 통신으로 ‘a’값 보내기 (부팅 되었는지 확인하기 위해)
if(TIEMR_BLESEND < millis()){
BTSerial.print(“a”); // 블루투스 데이터 보내기
TIEMR_BLESEND = millis() + 10000; // 10초 간격으로 데이터 보내기
}

// 2. 블루투스 데이터 감지하기
if (BTSerial.available()){ // 블루투스 데이터를 감지했을 경우 안에 while문이 동작함
int timeout = 50;
String response = “”; long int time = millis();
while( (time+timeout) > millis()) { // 50ms동안 문자열 세는 방식
while(BTSerial.available()) { // 블루투스 통신이 끝날 때 까지
char c = BTSerial.read(); // c에 읽어 response에 저장
response+=c; }}

String DATA = response; // 컨트롤 데이터에 읽은 데이터 넣기
Serial.println( “DATA : “ + DATA); // 컨트롤 데이터 출력

if(DATA.substring(0,2) == “HI”){ // 블루투스 데이터가 “HI”인가? 그럼 ‘a’데이터 보내기
BTSerial.print(“a”);
}
}

[비상모드] 비상모드에서 정상상태로 돌아가는지 확인하기
if(WARN_STATE){

// 0.5초마다 확인 하기
if(TIMER_WARN_STATE < millis()) { TIMER_WARN_STATE = millis() + 100;

// 0.5초 마다 부저 키고 끄기 (띠띠띠 소리 내기)
if(buzzer_state2) { tone(BUZZER, 1000); buzzer_state2 = false; } else { noTone(BUZZER); buzzer_state2 = true;}

// 각도 측정하기
value_init(); // 변수 초기화
accel_calculate(); // 가속도 측정 -> 각도계산
angle1 = abs(angle1); // 각도 변수에 저장
angle2 = abs(angle2); // 각도 변수에 저장

// Serial.print( “ ANGLE1 : “ + String(angle1)); Serial.println( “ ANGLE2 : “ + String(angle2));

if ( (angle1 < NOMAL_ANGLE ) && (angle2 < NOMAL_ANGLE ) ){ // 정상 상태에 돌아왔을 경우 (각도가 안정상태일 경우)

noTone(BUZZER); // 부저 끄기
WARN_STATE = false; // 비상모드 끄기
BTSerial.print(“x”); // 블루투스 데이터 ‘x’보내기

가속도 변화량(충격량) 감지하기
value_init();
//첫번째 센싱
for (int i=0; i < sum_count; i++){ accel_calculate();
deltha_x[1] = deltha_x[1]+(normal_x); deltha_y[1] = deltha_y[1]+(normal_y); deltha_z[1] = deltha_z[1]+(normal_z); delay(5);}
deltha_x[1] = int(deltha_x[1]/sum_count); deltha_y[1] = int(deltha_y[1]/sum_count); deltha_z[1] = int(deltha_z[1]/sum_count);

//두번째 센싱
for (int i=0; i < sum_count; i++){ accel_calculate();
deltha_x[2] = deltha_x[2]+(normal_x); deltha_y[2] = deltha_y[2]+(normal_y); deltha_z[2] = deltha_z[2]+(normal_z); delay(5);}
deltha_x[2] = int(deltha_x[2]/sum_count); deltha_y[2] = int(deltha_y[2]/sum_count); deltha_z[2] = int(deltha_z[2]/sum_count); //3축 변화량 비교가속도 변화량 측정하기
deltha_x[0] = abs(deltha_x[1]-deltha_x[2]); deltha_y[0] = abs(deltha_y[1]-deltha_y[2]); deltha_z[0] = abs(deltha_z[1]-deltha_z[2]);
deltha = deltha_x[0] + deltha_y[0] + deltha_z[0];

가속도 변화량 비교를 통한 낙상 감지
if(deltha > CRASH_VALUE){ // 충격이 감지 되었을 경우 내부 함수 동작하기
ACTION_config(); // 기울기를 통해 비상모드인지 판단함
}

< 비상모드 시 사이렌 알람과 블루투스를 통해 이뤄지는 통신 부분>
// 비상모드인지 판단하는 함수
int ACTION_config(){

tone(BUZZER, 1000,1000); // 부저 키기
delay(3000); // 3초간 대기
long TIMER1 = (long) millis() + 12000; // 12초간 대기하는 구간
long TIMER_buzzer = 0; bool buzzer_state = true;
int WARN = 0;
// 시작 Flow chart
// 충격감지(가속도변화감지) -> 3초간 대기 -> 12초간 기울기 감지

// 비상모드 인가? 정상모드 인가? 판단하기
while( (TIMER1 > millis())&&(WARN == 0)){

// 부저 울리기 : 띠띠띠
// if(TIMER_buzzer < millis()) { TIMER_buzzer = millis() + 500;
// if(buzzer_state) { tone(BUZZER, 1000); buzzer_state = false; } else { noTone(BUZZER); buzzer_state = true;}
// }

// 각도 측정하기
value_init(); accel_calculate();
angle1 = abs(angle1);
angle2 = abs(angle2);

// 정해진 각도 내에 들어가는지 확인하기 (12초 내의 정해진 각도에 들어 갈 경우 정상임)
if ( (angle1 < NOMAL_ANGLE ) && (angle2 < NOMAL_ANGLE ) ){
// tone(BUZZER, 1000, 100); delay(200); tone(BUZZER, 1000, 100);
noTone(BUZZER); WARN = 1; // WARN = 1이면 while에 나갈 수 있음
}

Serial.print( “ ANGLE1 : “ + String(angle1)); Serial.println( “ ANGLE2 : “ + String(angle2));
delay(100);
}
//—————————————//

// 정상 일 경우 return 시키기
if(WARN == 1) { return 0; }

// 비상모드 일 경우 부저 6초간 울리고 블루투스 데이터 보내기
TIMER1 = (long) millis() + 6000;
while( TIMER1 > millis() ){
tone(BUZZER, 1000); delay(100); noTone(BUZZER); delay(100);
}
noTone(BUZZER);
BTSerial.print(“w”); // ‘w’ 블루투스데이터 보내기

가속도 연산 및 각도 계산 함수
void accel_calculate() {

ac_x = 0; ac_y = 0; ac_z = 0;

Wire.beginTransmission(mpu_add) ; // 번지수 찾기
Wire.write(0x3B) ; // 가속도 데이터 보내달라고 컨트롤 신호 보내기
Wire.endTransmission(false) ; // 기달리고,
Wire.requestFrom(mpu_add, 6, true) ; // 데이터를 받아 처리

// Data SHIFT
ac_x = Wire.read() << 8 | Wire.read() ;
ac_y = Wire.read() << 8 | Wire.read() ;
ac_z = Wire.read() << 8 | Wire.read() ;

// Serial.println( “ X : “ + String(ac_x) + “ Y : “ + String(ac_y) + “ Z : “ + String(ac_z) );
if(ACCESS_ACCEL) { } else { return; }

//맵핑화 시킨 것 – 즉 10000으로 맵핑시킴
normal_x = map(int(ac_x), -16384, 16384, 0, mapping_value);
normal_y = map(int(ac_y), -16384, 16384, 0, mapping_value);
normal_z = map(int(ac_z), -16384, 16384, 0, mapping_value);

float accel_xz, accel_yz;
const float RADIANS_TO_DEGREES = 180/3.14159;

// 각도1 계산하기
accel_yz = sqrt(pow(ac_x, 2) + pow(ac_y, 2));
angle1 = atan(-ac_z / accel_yz)*RADIANS_TO_DEGREES;

// 각도2 계산하기
accel_xz = sqrt(pow(ac_z, 2) + pow(ac_y, 2));

에러를 줄이기 위한 변수 초기화
void value_init(){
normal_x = 0; normal_x = 0; normal_x = 0;
for (int i=0; i < 3; i++){ deltha_x[i]=0; deltha_y[i]=0; deltha_z[i] = 0; angle1 = 0;angle2 = 0; }

 

 

Leave A Comment

*