November 25, 2024

디바이스마트 미디어:

[66호] 원하는 색상으로 제어가 가능한 아두이노 IoT 스마트 무드등 키트 -

2021-06-25

★2021 ICT 융합 프로젝트 공모전 결과 발표! -

2021-05-12

디바이스마트 국내 온라인 유통사 유일 벨로다인 라이다 공급! -

2021-02-16

★총 상금 500만원 /2021 ICT 융합 프로젝트 공모전★ -

2021-01-18

디바이스마트 온라인 매거진 전자책(PDF)이 무료! -

2020-09-29

[61호]음성으로 제어하는 간접등 만들기 -

2020-08-26

디바이스마트 자체제작 코딩키트 ‘코딩 도담도담’ 출시 -

2020-08-10

GGM AC모터 대량등록! -

2020-07-10

[60호]초소형 레이더 MDR, 어떻게 제어하고 활용하나 -

2020-06-30

[60호]NANO 33 IoT보드를 활용한 블루투스 수평계 만들기 -

2020-06-30

라즈베리파이3가 드디어 출시!!! (Now Raspberry Pi 3 is Coming!!) -

2016-02-29

MoonWalker Actuator 판매개시!! -

2015-08-27

디바이스마트 레이저가공, 밀링, 선반, 라우터 등 커스텀서비스 견적요청 방법 설명동영상 입니다. -

2015-06-09

디바이스마트와 인텔®이 함께하는 IoT 경진대회! -

2015-05-19

드디어 adafruit도 디바이스마트에서 쉽고 저렴하게 !! -

2015-03-25

[29호] Intel Edison Review -

2015-03-10

Pololu 공식 Distributor 디바이스마트, Pololu 상품 판매 개시!! -

2015-03-09

[칩센]블루투스 전 제품 10%가격할인!! -

2015-02-02

[Arduino]Uno(R3) 구입시 37종 센서키트 할인이벤트!! -

2015-02-02

[M.A.I]Ahram_ISP_V1.5 60개 한정수량 할인이벤트!! -

2015-02-02

[64호]EYESHOE (시각 장애인을 위한 신발과 이와 연동된 상황별 안내 어플리케이션)

66 ict 아이슈 (1)

2020 ICT 융합 프로젝트 공모전 장려상

EYESHOE (시각 장애인을 위한 신발과 이와 연동된 상황별 안내 어플리케이션)

글 | 이화여자대학교 황시은, 오지영, 박지은, 김가연

 

1. 심사평
칩센 시각 장애인을 위한 보조 장치는 여러 가지 방법으로 늘 제안되는 작품 주제 중 하나입니다. 지원자(팀)께서 개발하신 작품과 같이 초음파 센서를 이용하여 지형 또는 장애물을 파악하는 방안 또한 자주 제시되는 기술 방안이긴 하지만, 이 장치를 신발 안에 넣겠다는 발상이 신선합니다. 테스트 진행한 시제품의 경우 일반 상용 부품을 사용하여 조금 둔탁한 구조를 가지긴 하지만, 동등 이상의 소형 부품으로 구성한다면 신발의 심미적인 면 또한 어느 정도 개선이 가능할 것으로 보입니다. 다만 구조적으로 신발과 일체형이 되어야 할 소지가 보여, 일체형을 의도한 것이 아니라면 이 부분에 대하여 쉽게 적용 가능한 방안을 찾는 것은 필요할 것으로 보이고, 장애물을 좀 더 정확하고 정밀하게 확인할 수 있는 알고리즘 보완을 기대합니다. 재미있는 작품과 시연 잘 보았습니다.

펌테크 세심한 관찰력이 반영된 실생활과 밀접한 아이디어와 실용성이 우수한 작품이라고 생각합니다. 기획의도에 맞게 전체 시스템을 안정적이고 완성도 높게 구현하였다고 판단이 되고 전체적으로 기획의도, 기술 구현도, 완성도 등에서 우수한 작품으로 생각됩니다.

위드로봇 초음파 센서 여러 파형의 융합을 어떻게 처리할 것인지 고민이 좀 더 필요해 보입니다.

2. 작품 개요
장애인은 사회 공동체와 단절되지 않고 비장애인과 더불어 다 같이 행복한 삶을 누릴 자격이 있다. 그러므로 장애인과 같은 사회적 약자들도 비장애인 같이 평등한 권리를 보장받아야 한다. 그러기 위해 인간의 가장 기본적인 권리인 이동의 자유를 보장해 줄 수 있는 보조공학기기가 그들의 생계 유지와 더불어 중요한 문제임을 인식해야 한다. 그리고, 기술 개발을 통한 이러한 기기들의 업그레이드가 필수적이다.

시각장애인은 흔히 점자블록의 도움을 받거나 보행 보조 수단으로 시각장애인용 지팡이와 장애인 보조견을 사용한다. 그러나 시각장애인이 이러한 기존의 방법에만 의지하며 복잡한 도심 속에서 보행하기에는 여러 가지 어려움들이 있다. 먼저, 도로에 점자블록이 있다고 하더라도 시각장애인이 장애물의 거리와 위치를 완벽하게 인지하기에는 무리가 있다. 또한, 일반 보도블록도 울퉁불퉁한 경우가 많아 점자블록과 구분하기 어려운 경우가 많다. 뿐만 아니라, 2020-03-18에 작성된 ‘연합뉴스’의 기사에 따르면, 서울시가 장애인 보행환경 개선을 위해 강북권 보도만을 전수 조사했음에도 보도의 점자블록이 제대로 설치되어 있지 않은 경우 등의 이상이 총 1만6천268건이나 발견되었다고 밝혔다. 두 번째로, 지팡이는 직접 장애물과 닿아야 시각장애인이 장애물이 있음을 인지할 수 있기 때문에 ‘지팡이의 길이’라는 한계점을 지닌다. 이에 우리는 ‘지팡이의 길이’라는 한계점에서 벗어나, 시각장애인이 장애물과 일정거리 떨어져 있어도 장애물의 존재와 지형의 변화를 미리 알고 대비할 수 있도록 하는 시각장애인용 보행 보조 수단을 개발하고자 하였다. 물론, 요즘에는 시각장애인을 위해 전방에 장애물이 있으면 진동으로 알리는 스마트 지팡이도 개발되었다. 그러나 실제 시각장애인의 경우 일반인이 느끼는 진동모터의 진동을 수십 배 이상으로 느끼기 때문에 지팡이를 조금만 사용해도 손의 감각이 쉽게 피로해지는 현상을 호소할 수 있다. 다음으로 안내견은 장기간의 훈련을 필요로 하여 많은 시간과 비용이 소모된다. Eyeshoe를 사용하면 안내견을 훈련하는 사회적 복지 비용과 시각장애인 개인이 안내견을 키우는 데 드는 비용과 어려움을 절감할 수 있을 것으로 예상된다.

국내에는 시각장애인을 위한 신발이 전무하고 해외에는 적은 수가 존재하나, 단순하게 전방의 장애물의 유무를 알려주는 정도에 그쳤다. 그러나 사실 사용을 위해서는 다양한 상황에 대한 알림이 필수적이라 생각한다. 따라서 일상생활에서 가장 자주 접하고, 시각장애인에게 불편을 줄 수 있는 상황들에 대한 알림을 주고자 한다. 또한, 신발에서 직접적으로 소리가 나면, 주변 소음이 더 커서 소리를 듣지 못하거나 정숙을 유지해야 하는 상황에서 소리가 나서 당황하는 경우가 생길 수 있다. 이에 우리는 아두이노를 스마트폰 애플리케이션과 연동하여 사용자가 직접 이어폰을 착용하거나 볼륨을 조절하며 사용할 수 있도록 한다. 이는 EyeShoe를 사용하기에 훨씬 직관적이고 편리한 환경을 제공할 것이다.

3. 작품설명
EyeShoe에는 초음파 센서가 부착되어 있어 장애물까지의 거리를 측정한다. 단순 장애물 뿐만 아니라 오르막길, 내리막길, 계단, 벽 등을 구분하여 시각장애인이 자신이 나아갈 경로가 시각적으로 보이지 않더라도 미리 대비하여 안전하게 통행할 수 있도록 하였다. 더 나아가 우리는 이 신발을 안드로이드 스튜디오를 통해 직접 제작한 스마트폰 애플리케이션과 블루투스 모듈을 이용하여 연동하였다. 앱은 시작 화면에서 사용자의 발 사이즈를 입력받고 이를 토대로 보폭을 계산하여 장애물과의 거리를 안내한다. 이 과정은 화면을 읽지 못하는 사용자를 고려하여 음성으로 들을 수 있게 하였다. 첫 이용 시 발 사이즈 값을 입력하면 자동으로 저장되며 이에 따라 개인 맞춤형 알림을 받을 수 있다.

3.1 사용한 부품
· 아두이노 UNO R3 호환보드: 초음파 센서와 블루투스 모듈을 코딩을 통해 구동시키기 위해 사용
· 초음파 거리 센서(HC-SR04P): 신발과 장애물 및 계단 사이의 거리를 측정
· 블루투스 모듈 HC-06: 아두이노에서 안드로이드 스튜디오로 초음파 센서 값을 전송
· 9V 망간 배터리 (6F22): 아두이노 보드에 전원을 공급
· 배터리 배럴잭 어댑터 클립: 아두이노에 배터리를 이용하여 전원공급할 때 사용
· 전기인두: 점퍼 케이블들을 서로 접합시킴
· 땜납: 땜질에 사용
· 브레드 보드: 점퍼 케이블을 이용하여 초음파 센서, 아두이노 보드, 그리고 블루투스 모듈 사이를 연결
· 아두이노우노 통신 케이블: 아두이노 보드와 PC 사이를 연결
· 점퍼 케이블 (MM): 양쪽이 M 타입 커넥터로 브레드 보드, 아두이노, F 타입 헤더핀에 연결
· 점퍼 케이블 (FM): 한쪽은 F 타입 커넥터로, 초음파센서, M 타입 헤더핀과 연결하였고, 반대편은 M 타입 커넥터로 브레드보드, 아두이노, 그리고 F 타입 헤더핀에 연결

우리는 EyeShoe를 작동시키는 것뿐만 아니라 실제로 상용화되었을 때의 가격과 무게를 예상해 보았다. 먼저 신발 한 짝을 기준으로 예상하는 단가는 약 18,230원으로, 충분한 상업적 가치가 있다. EyeShoe에 부착된 기기들은 비교적 가벼워서, 기기들을 부착하지 않은 상태와 비교했을 때 무게가 거의 달라지지 않았다. Eyeshoe를 직접 신고 테스트도 시행해보았는데, 현재 시중에 판매되고 있는 신발과 무게가 비슷하여 걷기에 불편함이 없었다. 다양한 실전 테스트(첨부 영상 참고)로 신뢰성을 확보한 상태에서 이와 같이 저렴하고 가볍게 보급된다면 유익한 제품이라 생각된다.

3.2 주요 동작 및 특징
1) 스마트폰 애플리케이션의 첫 화면에서 사용 안내 버튼을 누르면 시각장애인용 신발과 이와 연동된 애플리케이션에 대한 설명이 팝업창에 뜬다. 스마트폰에 기본으로 탑재되어 있는 기능인 Voice Assistant 모드를 켠 후 이 팝업창을 누르면 음성으로 안내 받을 수 있다.

66 ict 아이슈 (2)

다음은 음성 안내의 내용이다.
· “이 앱은 시각장애인 분들을 위해 제작한 신발과 함께 사용하는 앱입니다. 앱 시작 시 발 사이즈를 입력해주세요. 전방의 장애물을 보폭 기준 세 걸음 전에 안내합니다. 오르막, 내리막, 벽에 접근 시 각각 안내합니다. 15cm 이내로 접근 시 경보음이 울립니다. START 버튼을 누른 후 연결 버튼을 눌러 블루투스(THIS)를 연결해주세요.”

2) 전방 장애물 알림
스마트폰 애플리케이션의 첫 화면에서 자신의 발 사이즈를 입력한 후 연결 버튼을 누르면, 자동으로 보폭이 계산되고 신발과 안드로이드가 블루투스로 연동되어 장애물이 사용자의 보폭 기준 약 세 걸음 전에 있을 때 안내 음성이 나온다. 발 사이즈를 입력하고 save 체크박스에 체크하면 발 사이즈가 자동으로 저장되어 다음에 어플을 실행할 경우 다시 입력하지 않아도 된다.

66 ict 아이슈 (3)

다음은 음성 알림의 내용이다: “장애물 조심“
장애물과의 거리가 15cm 이하이면 근접 경보를 울린다.

3) 벽 알림
벽이 사용자의 보폭 기준 약 세 걸음 전에 있을 때 안내한다.
다음은 음성 안내의 내용이다: “벽 조심”
벽과의 거리가 15cm 이하이면 근접 경보를 울린다.

4) 오르막길(계단) 알림
오르막길이 가까워지면 음성 알림을 시작한다.
다음은 음성 안내의 내용이다: “오르막 조심”

5) 내리막길(계단) 알림
내리막길 및 계단이 가까워지면 음성 알림을 시작한다.
다음은 음성 안내의 내용이다: “내리막 조심”

3.3 전체 시스템 구성

66 ict 아이슈 (4)

신발에는 총 4개의 초음파 센서가 부착되어 있다. 먼저 발바닥으로부터 지면의 거리를 측정하는 센서이다. 발이 공중에 떠 있을 때는 측정을 멈추기 위해 발바닥 가운데에 있는 센서를 사용한다. 초음파 센서값이 3.0cm일 때, 즉 발바닥 전체가 지면과 맞닿을 때 전체적인 값 측정을 시작하게 한다. 나머지 3개의 초음파 센서는 각각 전방 장애물, 오르막길, 내리막길을 감지한다. 측정한 초음파 센서 값은 블루투스 모듈을 통해 안드로이드 스튜디오로 전송된다.
안드로이드 스튜디오에 업로드 된 코드에는 측정한 3개의 센서값을 이용해 알림 설정을 하는 알고리즘이 구성되어 있다. 먼저, 사용자가 앱 실행 시 발 사이즈(mm)를 입력하게 한 후, 이를 cm 단위로 만들어주기 위해 이에 10을 나누고, 2.5를 곱해 일반적인 보폭 값을 계산한다. 이를 이용하여 전방 초음파 센서값이 세 걸음 이내일 때 앱을 통해 “장애물 조심” 알림을 한다. 다음은 여러 지형 변화에 따른 센서 감지 모습을 나타낸 그림이다.

66 ict 아이슈 (5)

벽 : 전방 센서값과 오르막 센서값이 직각 삼각형을 이룰 경우 벽에 근접했다고 인식한다.

오르막: 벽이 아닐 경우(전방 센서값과 오르막 센서값이 직각 삼각형을 이루지 않을 경우) 오르막이라고 인식한다.
내리막: “Eyeshoe” 앞코에 부착된 내리막 센서는 약 65°의 기울기로 아래를 향하고 있다. 사용자가 평지를 걷는 중에 내리막 센서에는 일정한 값이 나오지만, 내리막 접근 시 기존에 나오던 값(약 20cm)보다 큰 값이 나오게 된다. 이때 사용자가 내리막(계단)에 근접했다고 인식하고 알림을 준다.
안드로이드 스튜디오에서 위의 알고리즘을 적용했다.

3.4 기존 지팡이와의 차이점

66 ict 아이슈 (6)

3.5 개발 환경(개발 언어, Tool, 사용 시스템 등)

개발 언어: C언어(Arduino), Java(Android Studio)
사용 tool: Arduino Uno, Fritzing(아두이노 회로도 작성 프로그램), Android Studio, 3D CAD Solidworks(설계도 제작)

4. 단계별 제작 과정
4.1 아이디어 회의
시각장애인이 기존 지팡이만으로는 거리에 있는 장애물들을 피하며 지형을 예측하는 것에 어려움을 느낀다는 것을 깨닫고 보다 안전하고 사용하기 편리한 보행 보조 장치를 만들고자 했다. 이에 기능을 신발에 직접 넣어 시각장애인이 더욱 안전하게 이동할 수 있도록 했다. 최대 4m까지 물체감지가 가능한 초음파 센서가 이에 적합하다고 생각하여 신발의 내/외부에 센서를 부착하고 상황별 센서값 처리 방법에 대해 의논했다. 또한, 효과적인 알림을 주기 위해 사용이 편리한 애플리케이션을 제작하기로 결정했다.

4.2 시각장애인용 신발 및 애플리케이션 제작

66 ict 아이슈 (1)
먼저 브레드보드와 초음파센서, 블루투스 모듈, 그리고 아두이노 보드를 연결한 후 아두이노에 코드를 업로드했다.

66 ict 아이슈 (2)

본격적으로 신발을 제작하기 전에 3D CAD Soild Works를 활용하여 설계도를 그렸다.

66 ict 아이슈 (3)

테스트용 신발을 제작하여 우리가 구상한 알고리즘이 정상적으로 작동하는지 확인해 보았다.

66 ict 아이슈 (4)

본격적으로 신발을 제작하였다. 왼쪽 사진은 납땜을 하는 모습이다.

66 ict 아이슈 (5)

Android Studio를 통해 알고리즘을 구상하고 어플 개발을 하였다.

66 ict 아이슈 (7)

우리가 제작한 애플리케이션의 아이콘이다.

4.3 제품 테스트

66 ict 아이슈 (6)

EyeShoe를 신고 다양한 지형(장애물, 벽, 오르막길, 내리막길)에서 테스트를 했다. 테스트 영상은 따로 첨부하였다.(영상은 어플로 거리 값이 잘 전달되는 것을 확인시켜 드리기 위해 어플 화면의 Textview 부분을 늘린 상태입니다.)

5. 기타
5.1. 주요 소스코드
5.1.1 Arduino

#include <SoftwareSerial.h>
int Tx=2; //블루투스 전송
int Rx=3; //블루투스 수신
SoftwareSerial btSerial(Tx, Rx);
void setup() {
Serial.begin(9600);
btSerial.begin(9600);
//오르막길 센서(distance4)
pinMode(9, OUTPUT);
pinMode(8, INPUT);
//발바닥 센서(distance1)
pinMode(7,OUTPUT);
pinMode(6,INPUT);
//전방 센서(distance2)
pinMode(5, OUTPUT);
pinMode(4, INPUT);
//내리막길 센서(distance3)
pinMode(13,OUTPUT);
pinMode(12, INPUT);
}
void loop() {
//발바닥 센서 측정 시작한 후, 거리값 계산
digitalWrite(7, LOW);
digitalWrite(6, LOW);
delayMicroseconds(2);
digitalWrite(7,HIGH);
delayMicroseconds(10);
digitalWrite(7,LOW);
unsigned long duration1 = pulseIn(6, HIGH);
float distance1 = ((float)(340L*duration1)/10000)/2.0;

//발바닥 센서에서 측정한 값이 3.8cm 이하일 때, 나머지 센서(전방 센서, 오르막길 센서, 내리막길 센서) 측정 시작한 후 거리값 계산
if(distance1<3.8f){
Serial.println(“Under 10cm”);
digitalWrite(9, LOW);
digitalWrite(8, LOW);
delayMicroseconds(2);
digitalWrite(9, HIGH);
delayMicroseconds(10);
digitalWrite(8,LOW);
unsigned long duration4 = pulseIn(8, HIGH);
float distance4 = ((float)(340L*duration4)/10000)/2.0;

digitalWrite(5, LOW);
digitalWrite(4, LOW);
delayMicroseconds(2);
digitalWrite(5, HIGH);
delayMicroseconds(10);
digitalWrite(5,LOW);
unsigned long duration2 = pulseIn(4, HIGH);
float distance2 = ((float)(340L*duration2)/10000)/2.0;

digitalWrite(13, LOW);
digitalWrite(12, LOW);
delayMicroseconds(2);
digitalWrite(13, HIGH);
delayMicroseconds(10);
digitalWrite(13,LOW);
unsigned long duration3 = pulseIn(12, HIGH);
float distance3 = ((float)(340L*duration3)/10000)/2.0;
Serial.println(distance2);
Serial.println(distance3);
Serial.println(distance4);
//센서가 측정 가능한 거리값을 과도하게 벗어나는 오류값을 받지 않기 위해 3500cm 이하의 값만 안드로이드 스튜디오로 전송
if (distance2<3500&&distance3<3500&&distance4<3500){
btSerial.print(distance2);
btSerial.print(‘,’);
btSerial.print(distance3);
btSerial.print(‘,’);
btSerial.print(distance4);
btSerial.println();
}
}
else{

}
delay(1000);
}

5.1.2 Android Studio

Mainactivity.java
package com.example.sinbal;
import android.app.Activity;
import android.content.Intent;
import android.widget.TextView;
import android.widget.Toast;
import app.akexorcist.bluetotohspp.library.BluetoothSPP;
import app.akexorcist.bluetotohspp.library.BluetoothState;
import app.akexorcist.bluetotohspp.library.DeviceList;
import android.media.MediaPlayer;
import android.bluetooth.BluetoothAdapter;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
private BluetoothSPP bt;
int size;
boolean blockDetected = false;
boolean wallDetected = false;
boolean downhillDetected = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = getIntent(); //변수 받아오기 추가 부분
size = intent.getIntExtra(“size”,0);
bt = new BluetoothSPP(this); //Initializing
if (!bt.isBluetoothAvailable()) { //블루투스 사용 불가
Toast.makeText(getApplicationContext()
, “Bluetooth is not available”
, Toast.LENGTH_SHORT).show();
finish();
}
bt.setOnDataReceivedListener(new BluetoothSPP.OnDataReceivedListener() {
TextView distance22 = findViewById(R.id.distance2); //텍스트뷰를 통해 초음파 센서 값 받아오기
TextView distance33 = findViewById(R.id.distance3);
TextView distance44 = findViewById(R.id.distance4);
double finalSize = MainActivity.this.size/10*2.5*3; // final size를 사용자의 보폭 기준 3걸음으로 설정
public void onDataReceived(byte[] data, String message) { //데이터 수신용 코드 추가
String[] array = message.split(“,”);
distance22.setText(array[0].concat(“cm”));
distance33.setText(array[1].concat(“cm”));
distance44.setText(array[2].concat(“cm”));
double distance2 = Double.parseDouble(array[0]); //초음파센서값 3개 array 형식으로 안드로이드 스튜디오에 받아오기
double distance3 = Double.parseDouble(array[1]);
double distance4 = Double.parseDouble(array[2]);
double hypotenuse = distance2/0.93969; //오르막센서 각도를 20도로 설정. 밑변 길이를 cos20으로 나눈 값, 대각선 길이
//벽 & 오르막
if(distance4<400){
if(distance4>hypotenuse){ //오르막 센서값과 전방센서값이 직각삼각형 형성하지 않을 경우 오르막으로 인식
//오르막
final MediaPlayer mp = MediaPlayer.create(MainActivity.this, R.raw.uphill);
mp.start();
}
else{ // 오르막 센서값과 전방센서값이 직각삼각형 형성할 경우 벽으로 인식
//벽
if(distance2 < finalSize){
if(!wallDetected) { //벽 중복 알람 방지
wallDetected = true;
final MediaPlayer mp = MediaPlayer.create(MainActivity.this, R.raw.wall);
mp.start();
}
if(distance2 < 15) { //근접 경보
final MediaPlayer mp = MediaPlayer.create(MainActivity.this, R.raw.close);
mp.start();
}
}
else {
wallDetected = false;
}
}
}
//장애물
else{ // 오르막 센서가 감지되지 않을 경우, 전방센서값은 측정되는 경우.
if(distance2< finalSize){
if(!blockDetected) { //장애물 중복 알람 방지
blockDetected = true;
final MediaPlayer mp = MediaPlayer.create(MainActivity.this, R.raw.block);
mp.start();
}
if(distance2<15) { //근접 경보
final MediaPlayer mp = MediaPlayer.create(MainActivity.this, R.raw.close);
mp.start();
}
}
else {
blockDetected = false;
}
}
//내리막센서가 일정 값 이상이 나올 경우
//내리막
if(distance3>100) {
if (!downhillDetected) {
downhillDetected = true; //내리막길 중복 알람 방지
final MediaPlayer mp = MediaPlayer.create(MainActivity.this, R.raw.downhill);
// mp.start();
}
else {
downhillDetected = false;
}
}
});
bt.setBluetoothConnectionListener(new BluetoothSPP.BluetoothConnectionListener() { //연결됐을 때
public void onDeviceConnected(String name, String address) {
Toast.makeText(getApplicationContext()
, “Connected to ” + name + “\n” + address
, Toast.LENGTH_SHORT).show();
}
public void onDeviceDisconnected() { //연결해제
Toast.makeText(getApplicationContext()
, “Connection lost”, Toast.LENGTH_SHORT).show();
}
public void onDeviceConnectionFailed() { //연결실패
Toast.makeText(getApplicationContext()
, “Unable to connect”, Toast.LENGTH_SHORT).show();
}
});
Button btnConnect = findViewById(R.id.btnConnect); //연결시도
btnConnect.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (bt.getServiceState() == BluetoothState.STATE_CONNECTED) {
bt.disconnect();
} else {
Intent intent = new Intent(getApplicationContext(), DeviceList.class);
startActivityForResult(intent, BluetoothState.REQUEST_CONNECT_DEVICE);
}
}
});
}
public void onDestroy() {
super.onDestroy();
bt.stopService(); //블루투스 중지
}
public void onStart() {
super.onStart();
if (!bt.isBluetoothEnabled()) { //
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, BluetoothState.REQUEST_ENABLE_BT);
} else {
if (!bt.isServiceAvailable()) {
bt.setupService();
bt.startService(BluetoothState.DEVICE_OTHER); //DEVICE_ANDROID는 안드로이드 기기 끼리
setup();
}
}
}
public void setup() {
Button btnSend = findViewById(R.id.btnSend); //데이터 전송
btnSend.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
bt.send(“Text”, true);
}
});
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == BluetoothState.REQUEST_CONNECT_DEVICE) {
if (resultCode == Activity.RESULT_OK)
bt.connect(data);
} else if (requestCode == BluetoothState.REQUEST_ENABLE_BT) {
if (resultCode == Activity.RESULT_OK) {
bt.setupService();
bt.startService(BluetoothState.DEVICE_OTHER);
setup();
} else {
Toast.makeText(getApplicationContext()
, “Bluetooth was not enabled.”
, Toast.LENGTH_SHORT).show();
finish();
}
}
super.onActivityResult(requestCode, resultCode, data);
} }

Initial.java
package com.example.sinbal;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import androidx.appcompat.app.AppCompatActivity;
public class initial extends AppCompatActivity {
Button button;
EditText userSize;
CheckBox checkSize;
SharedPreferences UserInfo;
SharedPreferences.Editor editor;
public static final int sub = 1001; /*다른 액티비티를 띄우기 위한 요청코드(상수)*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_initial);
button = (Button) findViewById(R.id.alert);
userSize = (EditText) findViewById(R.id.inputSize);
checkSize = (CheckBox) findViewById(R.id.checkSize);
checkSize.setChecked(true);
UserInfo = getSharedPreferences(“UserInfo”, 0);
editor = UserInfo.edit();
//사용자에게 발사이즈 입력받는 변수 설정
final int inputSizeValue = UserInfo.getInt(“inputSize”, 0);
if (inputSizeValue > 0) {
userSize.setText(Integer.toString(inputSizeValue));
}
Button button = findViewById(R.id.start); /*페이지 전환버튼*/
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(), MainActivity.class); //변수 받아오기 추가 부분
// Intent intent = new Intent(this, MainActivity.class);
String SizeValue = userSize.getText().toString();
if (!SizeValue.isEmpty()) {//Empty 아닐 때만 실행
int inputSizeValue = Integer.parseInt(SizeValue);
intent.putExtra(“size”, inputSizeValue);
startActivity(intent);//액티비티 띄우기
}
}
});
}
public void onPause() {
super.onPause();
if (checkSize.isChecked()) {
String sSize = userSize.getText().toString();
if (!sSize.isEmpty()) {
editor.putInt(“inputSize”, Integer.parseInt(sSize));
}
} else {
editor.putInt(“inputSize”, 0);
}
editor.commit();
}
public void onStart(){
super.onStart();
button.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
Intent intent = new Intent(initial.this, PopupActivity.class);
startActivity(intent);
}
});
}
}

5.2 참고문헌
· https://www.yna.co.kr/view/AKR20200317176900004?input=1195m
· http://www.kbuwel.or.kr/Blind/What
· http://mechasolution.com/shop/goods/goods_view.php?goodsno=119&category=
· https://blog.codejun.space/13

5.3 회로도

66 ict 아이슈 (8)

5.4 Flow Chart

66 ict 아이슈 (9)

 

 

 

Leave A Comment

*