September 22, 2018

디바이스마트 미디어:

[46호]똑똑이

Cap 2017-10-18 13-15-49-260

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

똑똑이

: 노크 패턴을 통한 적외선 방식의 가전 제품을 
  간단한 설치에 의해 IoT제품으로 전환해주는 디바이스

글 | 가천대학교 강동수

1. 심사평
칩센 소비자(사용자)의 관점에서 접근을 시작한 부분은 매우 높이 평가 할만하다고 생각합니다. 다만 작품의 구성에 들어가는 블루투스 및 적외선 통신 부분에 대한 기술적 이해도가 부족한 것으로 보입니다. 기술적인 부분에 대한 보완이 이루어진다면, 간단하지만 사용자에게는 유용한 제품으로 어필할 수 있을 것입니다.

뉴티씨 요즘 추세에 맞게 IoT를 잘 살린 작품이라고 생각됩니다. 노크 패턴 이외에 박수나 목소리로 실내의 가전제품의 상태를 알거나 변경할 수 있으면 더 좋을것이라 생각됩니다.

위드로봇 아이디어가 돋보이는 작품입니다. 보고서 만으로는 작품이 잘 동작하는지 확인하기 어려운데, 이 부분이 추가되면 좋을 것 같습니다.

2. 작품 목적 및 개요
2.1. 시대적 가전제품의 특성

46 feature ict 똑똑이 (1)
인간의 기술이 발전함에 따라 가전제품에서의 기술 또한 발전했다. 인터넷을 통해서 가전제품들을 조작할 수 있으며, 스마트폰 어플리케이션으로 제품의 상태를 확인한다. 이러한 편리한 세상이 다가오는 만큼 그 환경을 이용할 소비자의 측면에서 기술적 차별이 발생하게 될 것으로 예상한다. 금전적 여유가 있어 부담 없이 이용가능한 사람과 여유가 없어 신기술 이용을 이용함에 있어 부담을 가지는 사람이 발생하여 기술적 빈부차가 발생할 것이다. 이러한 문제점을 극복하고자 누구나 저렴하게 IoT(Internet Of Thing, 사물인터넷) 가전제품을 이용할 기회를 주는 것이 주된 목적이다.

2.2. 편의성 증대
취침을 위해 침대에 누었는데 불이 켜져 있는 경우, 방 안에 있는데 거실의 TV 볼륨이 시끄러운 경우, 에어컨을 켜두고 신발을 신은 경우 등 많은 사람들이 일상생활에서 겪어본 문제점들이다. 우리는 이러한 문제점들을 실감하고 해결방안을 생각해 보았다. 침대에 누워 벽을 두드리면 방의 전등이 꺼지고, 리모컨을 사용하지 않고 방 안의 벽을 두드리면 TV가 꺼지고, 외출을 하면 자동으로 TV나 에어컨이 꺼지면 일상은 더욱 편해질 것이다.

2.3. 비용적인 부담감 저하

46 feature ict 똑똑이 (2)

근래에 출시되는 신제품은 스마트 에어컨 등 인터넷으로 이용되는 제품들이다. IoT형 가전제품을 이용하길 원하나 사용가능한 기존 제품을 보유하고 있는 저소득층 소비자에게는 IoT제품을 새로 구매하는 것은 현실적으로 불가능하다. 비용적인 측면에서 보나 환경적인 측면에서 보았을 때 새 제품 구입은 소비적으로 낭비라 할 수 있다. 큰 비용을 들이지 않아도 마치 IoT 제품인 것처럼 이용할 수 있는 방법을 고안해내게 되었다.

2.4. 새로운 방식의 조작법
기존의 제품들은 직접 제품의 버튼을 눌러 조작하거나 원거리에서는 리모컨의 버튼을 눌러 조작해야한다. 스마트 가전제품의 경우 스마트폰의 어플리케이션으로 제품을 조작하는 방식이 대부분이다. 무언가를 항상 소지하고 있어야만 조작할 수 있다는 번거로움을 없애는 것이 타 제품과의 큰 차이점을 만드는 것이라 판단하여, 벽걸이 액자 및 미술품 등 장식만으로 이용되는 벽을 노크하여 가전제품을 조작하는 방법을 생각했다.

3. 작품 내용
3.1. 세부내용
제품은 크게 ‘노크 디바이스’, ‘적외선 디바이스’, ‘스위치 디바이스’, ‘HID 디바이스’ 이렇게 4가지로 구분하며, 통합적으로 ‘똑똑이’라 칭하겠다.

3.1.1. 노크 패턴 인식 (노크 디바이스)

46 feature ict 똑똑이 (3)

사물의 노크를 인식하기 위해 microphone과 같은 공기 중의 진동을 받는 센서가 아닌 물체의 표면 진동을 감지하는 piezo형 transducer 센서를 이용한다. 공기 중의 진동인 음파를 받지 않고 물체의 표면 진동만 받아내는 특성이 있다.
진동 인식을 위해 주파수적인 측면으로 접근하면 탈부착 식으로 사용하는 노크 디바이스에서는 부착되는 사물의 재질이 모두 다르므로 주파수 분해가 노크 인식 상 오류의 원인이 된다. 또한 FFT와 같은 고속연산에 있어서 MCU 단가 상승 원인도 불가피하다. 그러나 고유의 알고리즘을 활용해 재질과 무관하게 노크 인식이 가능하다.
단순히 노크 횟수만을 알아내는 것이 아닌 노크사이 간격의 시간을 측정하여 박자를 이용한 패턴설정 및 인식이 가능하다

3.1.2. 적외선 통신 (적외선 디바이스)
적외선은 기존 가전제품을 IoT방식의 제품으로 전환해주기 위한 매개체이다. 40kHz의 주파수로 32bit의 데이터 통신을 하는데, 회사명, 제품명에 따라 코드는 규칙성을 띈다. prototype 제품에서는 제품 리모컨의 적외선 코드를 직접 수신기로 알아내었으나, 이는 시중의 제품 다양성으로 인해 직접 처리하는 방식은 무리이다. 데이터베이스를 구축하여 회사별, 제품별로 적외선 코드 값을 사용한다.

3.1.3. Servo Motor를 이용한 전등 스위치 제어 (스위치 디바이스)
prototype제품에서는 무게가 9g이며, 출력 토크가 1.6kg/cm인 servo모터를 사용하였으나 물리적 구조상 전등 스위치를 누를만한 힘을 내지 못한다. 회전의 힘을 수직적으로 바꾸기 위해, servo모터를 중심 회전축으로 하여 막대를 이용해 전등 스위치를 수직으로 누를 수 있도록 설계한다. 왼쪽에서 전등스위치를 막대로 누르면 오른쪽에서는 스위치가 올라와 servo모터의 토크가 적은 힘으로 끄고 켜기가 가능하다.
원격 조정뿐 아니라 기존의 방식처럼 전등 스위치를 수동적으로 끄고 켤 수 있도록 터치센서를 이용한다.

46 feature ict 똑똑이 (4)

3.1.4. HID(Human Interface Device)를 이용한 컴퓨터 제어 (HID 디바이스)
학교 강의실 및 강연장에서 발표 자료를 이용한 발표를 할 경우, 대부분 소형 리모컨을 이용한다. 리모컨 또한 분실의 위험성이 존재한다. HID 프로토콜을 이용하여 노크에 의해 페이지를 넘겨 발표의 퍼포먼스를 더해준다.
가정에서 영상파일을 재생중일 때 잠시 멈추어야 할 경우, 일반적으로는 리모컨을 찾아 버튼을 확인한 후 버튼을 눌러 영상을 일시 정지한다. ‘똑똑이’를 사용하는 소비자라면 간단히 테이블을 노크하여 일시 정지할 수 있는 간편함이 있다.

3.1.5. Bluetooth 4.0 Beacon
노크 신호를 받아 명령을 내리는 디바이스는 하나지만, 명령을 받는 디바이스는 적외선 송신 디바이스, 전등 스위치를 제어하는 디바이스, 컴퓨터 제어 신호를 보내주는 디바이스 등 여러개다. 이는 1:N 통신의 네트워크를 구축하는데 단시간의 충전으로 오랜 시간동안 이용하려면 저전력의 Bluetooth 4.0 BLE Beacon을 사용하는 것이 가장 적합하다. Beacon은 3v의 코인 건전지 하나로 1년의 지속시간을 가진다.
Beacon은 Broadcaster모드이며, Scanner모드 디바이스와의 페어링을 요구하지 않는다. 그러므로 노크 디바이스 한 개당 수신 가능한 부가적인 디바이스는 개수의 제한이 없다.

3.1.6. 사용자에게 초점을 맞춘 인터페이스 구성

46 feature ict 똑똑이 (5)

제어될 가전제품의 적외선 코드를 일일이 리모컨으로 입력해두지 않아도 어플리케이션의 데이터베이스를 기반으로 제품의 회사와 제품코드를 검색 및 입력하는 방식으로 적외선 코드를 이용할 수 있다.
어플리케이션을 이용하여 사용자 임의대로 노크 패턴을 설정하여 사용한다.
일반적으로는 하나의 적외선 디바이스로 하나의 가전제품을 제어하지만 적외선 신호의 유효한 각도 범위는 약 120˚이므로 같은 방향으로 유효범위 안에 여러 가전제품들이 있다면 하나의 적외선 디바이스로 여러 제품을 제어할 수 있다. Smart home, Smart classroom 조성을 위해 사용이 가능하다.
또한 가정에서는 스마트폰의 신호를 주기적으로 받아내고, 일정시간 이상 신호를 받지 못하면 실내에 아무도 없다는 것으로 간주하여 미처 끄지 못한 가전제품들을 모두 끄게 해주는 시스템을 도입한다.

3.2. 작품의 경쟁력 및 독창성
3.2.1. 노크의 인식률

46 feature ict 똑똑이 (6)

현재까지 발전되어 온 음성인식 서비스들은 정확하게 음성을 인식하지만, 여러 사람이 섞여서 말을 할 때에는 인식률이 떨어진다. 또한 오디오나 비디오 등 디지털 음원에 의한 음성까지 받아들이는 상태이다.
공기 중의 소리를 이용한 서비스와는 다르게 표면 진동을 이용한 시스템이므로 정확성 면에서 확연한 차이를 볼 수 있다.

3.2.2. 기존 가전제품과의 호환성
새로 출시되는 IoT형 가전제품들은 WiFi를 통해 인터넷에 접속하여 스마트폰으로 제어된다. 이와 달리 기존의 가전제품들은 적외선 통신을 이용한 리모컨으로 제어된다. 기존 제품들도 마치 IoT제품인 것처럼 이용할 수 있도록 고안해내었다.

3.2.3. 신체적 결함의 차이 극복
버튼을 누르는 것이 아닌 ‘똑똑이’를 부착한 면의 어느 부분을 두드려도 작동하기 때문에 키가 닿지 않는 어린이도 쉽게 사용할 수 있다.
거동이 불편한 장애인 및 노인들에게 있어서도 ‘똑똑이’는 일반인들과의 차이를 좁혀준다.

3.2.4. 오프라인 상태에서의 사용
‘똑똑이’는 다른 IoT제품들과는 다르게 WiFi가 아닌 Bluetooth를 이용하기 때문에 중계기로 사용되는 공유기가 필요하지 않을뿐더러 Bluetooth가 이용 가능한 범위에만 있다면 인터넷이 되지 않는 장소에서도 사용가능하다.

3.2.5. 국내 유사 제품과의 비교
국내에서는 크라우드 펀딩에 성공한 사례인 ‘스위처’라는 제품이 있다. 전등 스위치 부분에 탈부착 식으로 간단히 설치되며 스마트폰과 블루투스 페어링이 가능하다. 원격으로 전등의 끄고 켜기가 가능하다.
페어링을 한다는 점에 있어서 ‘똑똑이’와 차이점을 보이는데, ‘똑똑이’는 페어링을 하지 않고 Beacon을 이용하므로 여러 제품을 동시에 제어가능하다.

3.2.6. 해외 유사 제품과의 비교
국외 유사제품으로는 기술적 및 퍼포먼스적 측면으로 보았을 때는 해외 크라우드 펀딩에서 성공적으로 마감한 ‘Knocki’라는 제품이 있다. 이 제품은 노크를 인터페이스로 이용한다는 점에서 ‘똑똑이’와 매우 유사하다.
Knocki는 스마트 기기만을 위한 제품이다. 노크를 인식하는 센서만을 판매하는 중이며, WiFi에 연결되지 않는 기존 적외선 방식 제품들은 이 제품과 연동시킬 수 없다.

4. 환경분석
4.1. 시장성 분석
4.1.1. WiFi를 사용하지 않는 IoT 제품
현재 똑똑이와 같은 노크형식의 값을 받아 사용하는 Knocki라는 제품이 해외에 존재하지만 Knocki는 WiFi를 이용하는 IoT 제품, 똑똑이와 센싱하는 방법만 같을 뿐 WiFi가 가능하지 않은 지역이거나 IoT 제품이 아닌 일반 제품에서는 사용할 수 없다는 문제점이 존재한다.
똑똑이는 현재 사용되는 기존 제품들을 적외선 값을 이용하여 제어할 수 있다는 점에서 호환성을 띈다.

4.1.2. 접근성 용이
똑똑이는 노크 강도의 민감도 조절이 가능하기 때문에 부착하는 벽이나 사물의 재질과는 상관없다. 따라서 어느 곳에서든 사용 가능하다.
음성인식을 통한 인공지능 형태가 아니고 노크를 통해 제어하는 방식이기 때문에 사용자의 임의대로 형식을 지정해 사용할 수 있다.

4.1.3. 다양한 제품에 적용 가능
에어컨, TV, 빔 프로젝터 등 리모컨을 사용하여 적외선통신을 하는 모든 전자기기들을 컨트롤할 수 있다.

4.1.4. 보안문제 해결
최근 IoT제품의 시대가 다가옴에 따라 데이터와 네트워크 연결이 빈번히 노출될수록 개인 보안문제에 대한 심각성이 두드러지게 되었다.
똑똑이는 블루투스에 의한 인트라넷 서비스를 이용하므로 외부로부터의 침범 확률이 낮다.

4.2. 경제적/사회적 파급효과
4.2.1. 저비용 IoT 디바이스
기존의 스마트홈은 브랜드마다 호환되는 제품이 한정적이고 사용자는 매달 지속적으로 요금을 납부해야 한다.
전등 스위치 제어를 위한 스위치 디바이스의 경우 릴레이를 이용한 별도의 배선 공사를 하지 않고 단지 부착하는 것만으로 사용가능하다.
리모컨을 대체할 수 있으므로 리모컨 분실시 재구매가 필요하지 않다.

4.2.2. 수업 또는 회의의 질 향상
수업이나 회의 중간, 빔 프로젝터 혹은 에어컨을 온오프하려고 리모컨을 찾는 경우, 학생이나 관중들의 집중이 흐트러진다. 똑똑이는 교수 혹은 발표자에게 집중도를 향상시켜 수업 및 회의의 효율을 높일 수 있다.

4.2.3. 남녀노소 사용자 불문
접근성이 용이하기 때문에 어린아이, 시각장애인, 거동이 불편한 노인들도 쉽게 사용가능하다.

5. 기타 (소스코드 및 외형)
5.1 노크 패턴 설정

#include <Adafruit_NeoPixel.h>
// Pin definitions
const int knockSensor = A0; // Piezo sensor on pin 0.
//const int greenLED = 13; // Status LED
const int PIOpin0 = 11;
const int PIOpin1 = 10;
const int PIOpin2 = 9;

#define StripLEDpin 3
#define NUMPIXELS 12
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, StripLEDpin, NEO_GRB + NEO_KHZ800);

// Tuning constants. Could be made vars and hoooked to potentiometers for soft configuration, etc.
const int threshold = 10; // Minimum signal from the piezo to register as a knock
const int rejectValue = 25; // If an individual knock is off by this percentage of a knock we don’t unlock..
const int averageRejectValue = 15; // If the average timing of the knocks is off by this percent we don’t unlock.
const int knockFadeTime = 150; // milliseconds we allow a knock to fade before we listen for another one. (Debounce timer.)

const int maximumKnocks = 20; // Maximum number of knocks to listen for.
const int knockComplete = 1200; // Longest time to wait for a knock before we assume that it’s finished.

// Variables.
int CinderellaCode[maximumKnocks] = {25, 25, 25, 25, 100, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // Cinderella Knock Pattern
int FrozenCode[maximumKnocks] = {100, 50, 25, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // Frozen Knock Pattern
int TrippleCode[maximumKnocks] = {25, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int KoreanCode[maximumKnocks] = {80, 40 ,80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

int knockReadings[maximumKnocks]; // When someone knocks this array fills with delays between knocks.
int knockSensorValue = 0; // Last reading of the knock sensor.

void setStripLED(int r, int g, int b)
{
for(int i=0;i<12;i+=2)
{
pixels.setPixelColor(i, pixels.Color(r, g, b)); // Moderately bright green color.
pixels.show(); // This sends the updated pixel color to the hardware.
}
}
void correctStripLED(int r, int g, int b)
{
for(int i=0;i<NUMPIXELS;i++)
{
pixels.setPixelColor(i, pixels.Color(r, g, b)); // Moderately bright green color.
pixels.show(); // This sends the updated pixel color to the hardware.
delay(30);
}
for(int i=0;i<NUMPIXELS;i++)
{
pixels.setPixelColor(i, pixels.Color(0, 0, 0)); // Moderately bright green color.
pixels.show(); // This sends the updated pixel color to the hardware.
delay(20);
}
for(int i=0;i<NUMPIXELS;i++)
{
pixels.setPixelColor(i, pixels.Color(r, g, b)); // Moderately bright green color.
pixels.show(); // This sends the updated pixel color to the hardware.
delay(10);
}
for(int i=0;i<NUMPIXELS;i++)
{
pixels.setPixelColor(i, pixels.Color(0, 0, 0)); // Moderately bright green color.
pixels.show(); // This sends the updated pixel color to the hardware.
delay(20);
}
}

// Sees if our knock matches the secret.
// returns true if it’s a good knock, false if it’s not.
// todo: break it into smaller functions for readability.
boolean validateKnock(int *secretCode)
{
// simplest check first: Did we get the right number of knocks?
int currentKnockCount = 0;
int secretKnockCount = 0;
int maxKnockInterval = 0; // We use this later to normalize the times.

for (int i=0;i<maximumKnocks;i++)
{
if (knockReadings[i] > 0)
currentKnockCount++;

if (*(secretCode+i) > 0) //todo: precalculate this.
secretKnockCount++;

if (knockReadings[i] > maxKnockInterval) // collect normalization data while we’re looping.
maxKnockInterval = knockReadings[i];
}

if (currentKnockCount != secretKnockCount)
return false;

int totaltimeDifferences = 0;
int timeDiff = 0;
for (int i=0;i<maximumKnocks;i++) // Normalize the times
{
knockReadings[i] = map(knockReadings[i], 0, maxKnockInterval, 0, 100);
timeDiff = abs(knockReadings[i] – *(secretCode+i));

if(timeDiff > rejectValue) // Individual value too far out of whack
return false;

totaltimeDifferences += timeDiff;
}
// It can also fail if the whole thing is too inaccurate.
if(totaltimeDifferences/secretKnockCount > averageRejectValue)
return false;

return true;
}

void triggerPIO(int *secretCode, int setPIOpin1, int setPIOpin2)
{
if (validateKnock(secretCode) == true)
{
correctStripLED(100, 200, 100);
Serial.println(“Secret knock correct.”);
digitalWrite(setPIOpin1, LOW);
digitalWrite(setPIOpin2, LOW);
delay(1000);
digitalWrite(setPIOpin1, HIGH);
digitalWrite(setPIOpin2, HIGH);
}
else
{
Serial.println(“Secret knock failed.”);
}
}

// Records the timing of knocks.
void listenToSecretKnock()
{
Serial.println(“knock starting”);

for (int i=0;i<maximumKnocks;i++)
knockReadings[i] = 0;

int currentKnockNumber = 0; // Incrementer for the array.
int startTime = millis(); // Reference for when this knock started.
int now = millis();

setStripLED(200, 100, 100); // we blink the LED for a bit as a visual indicator of the knock.
delay(knockFadeTime); // wait for this peak to fade before we listen to the next one.
setStripLED(0, 0, 0);

while ((now-startTime < knockComplete) && (currentKnockNumber < maximumKnocks))
{
//listen for the next knock or wait for it to timeout.
knockSensorValue = analogRead(knockSensor);
if (knockSensorValue >= threshold) //got another knock…
{
//record the delay time.
Serial.println(“knock.”);
now = millis();
knockReadings[currentKnockNumber++] = now-startTime;
startTime = now;

// and reset our timer for the next knock
setStripLED(200, 100, 100);
delay(knockFadeTime); // again, a little delay to let the knock decay.
setStripLED(0, 0, 0);
}
now = millis();
}
}

void setup()
{
// pinMode(greenLED, OUTPUT);
pinMode(PIOpin0, OUTPUT);
pinMode(PIOpin1, OUTPUT);
pinMode(PIOpin2, OUTPUT);

Serial.begin(9600); // Uncomment the Serial.bla lines for debugging.
Serial.println(“Program start.”); // but feel free to comment them out after it’s working right.

pixels.begin(); // This initializes the NeoPixel library.
setStripLED(0, 0, 0);
digitalWrite(PIOpin0, HIGH);
digitalWrite(PIOpin1, HIGH);
digitalWrite(PIOpin2, HIGH);
}

void loop()
{
// Listen for any knock at all.
knockSensorValue = analogRead(knockSensor);
if (knockSensorValue >=threshold)
{
listenToSecretKnock();
triggerPIO(FrozenCode, PIOpin0, PIOpin0);
triggerPIO(CinderellaCode, PIOpin1, PIOpin1);
triggerPIO(TrippleCode, PIOpin2, PIOpin2);
triggerPIO(KoreanCode, PIOpin0, PIOpin1);
setStripLED(0, 0, 0);
}
}

5.2. 적외선 수신 / 송신 부문

if (irrecv.decode(&results)) {
Serial.println(results.value, HEX);
irrecv.resume(); // Receive the next value }

irsend.sendNEC(0xFF19E6, 32);

5.3 3D 프린트로 만든 디바이스의 외형모습

46 feature ict 똑똑이 (1)

46 feature ict 똑똑이 (7)

Leave A Comment

*