October 20, 2017

디바이스마트 미디어:

[41호] Project H – 스마트홈

2016 ictmain

2016 ICT 융합 프로젝트 공모전 입선

Project H – 스마트홈

 

글 | 고려대학교 최윤형

 

심사평
JK전자 모터로 제어되는 기구부와 집 모형, 마이크로컨트롤러와 안드로이드 앱 개발까지 다양한 분야의 지식이 필요한 작품이네요. 시스템적으로 구현이 어려운 기술들은 아니지만 서로 다른 분야의 기술들을 적절히 잘 활용하여 완성도도 높고, 곧 다가올 사물인터넷 시대의 한 분야인 홈 케어 시스템에서 필요로 하는 요소들을 1개의 작품에 잘 적용하였습니다.
뉴티씨 스마트홈을 주제로 잡고 실제로 스마트한 환경을 구현하려 매우 노력한 흔적이 보여서 보고서 완성도면에서 20점을 주었으며, 전반적으로 좋은 점수를 받았다. 하지만, 아직 실용성이 부족하며, 조금만 더 창의적인 아이디어를 나만의 것으로 소화하여 만들었다면 더 좋은 점수를 받았을 것이다. 작품의 기대효과가 높지는 않으나, 전체적인 완성도나 기술성은 높은 점수를 주었다.
칩센 20년 전부터 나오던 홈오토메이션이 IoT라는 개념으로 다시 나오는 것 같다. 그만큼 주제는 식상하다. 하지만 구현 완성도와 보고서의 내용이 뛰어나고 노력한 흔적이 보인다.
위드로봇 모형으로 집을 만들고 그 안에서 발생할 수 있는 여러 상황을 시뮬레이션하여, 핸드폰으로 각 상황에 알맞게 조치를 취할 수 있음을 보여주는 재미있는 작품입니다. 다양한 센서를 인터페이스하는 측면에서 많은 공부가 되었을 것 같습니다. 작품 전체의 완성도가 높은 수작입니다.

1. 작품 개요

지난해 국내 스마트 홈 시장 규모 6조9천억 원11.8%↑ -부산일보
구글, ‘홈 오토메이션’ 분야 신생 업체 32억 달러에 인수 -연합뉴스
애플, 인텔리전트홈 원격제어…특허 -zdnet korea

뉴스에서 보도된 내용이다. 애플 구글같은 대기업들이 관심을 보이는 분야이고 국내 스마트 홈시장은 매년 늘어갈 것이라는 전망이다. 대기업이 진출한다는 것은 그만큼 가치가 있는 종목이고 홈 오토메이션이라는 것이 중요한 기술이 될 것임을 알 수 있다.
홈 오토메이션은 스마트폰과 블루투스를 이용한 AVR과의 통신으로 모터및 센서 제어를 해보는 것이므로 JAVA를 이용한 APP개발, 또한 블루투스 통신 구현, AVR을 이용한 모터 및 센서 제어 등 기초적인 기술들이 대부분 사용되었다. 그래서 이 프로젝트의 경험을 바탕으로 할 수 있는 일들이 다양해질 것이라고 생각한다.

2. 작품 설명
2.1. 전체 시스템 구성 – 시스템 구성도(Block diagram)

Cap 2017-05-30 10-05-14-551

2.2. 주요 동작 및 특징

2.2.1. 조도량에 따라 커튼 열고 닫힘

개요: 아침에는 햇볕이 들어오도록 자동으로 열리고 날씨가 좋지 않거나 밤에는 사생활 보호를 위해 자동으로 닫히도록 한다.
작동: GL5516(조도 센서)를 이용하여 빛의 양을 감지하고 빛의 양이 적으면 커튼을 닫히도록 하고 빛의 양이 많으면 커튼이 열리도록 한다.

2.2.2. 썬루프 원격 조절
개요: 스마트폰을 이용하여 원격으로 썬루프를 조정한다.
작동:
1. 스마트폰으로 썬루프가 열리는 정도를 조절할 수 있게 한다.
2. 날씨가 좋지 않을 시 어두운 정도를 GL5516(조도 센서)를 이용하여 측정하고 조도가 낮아 비가 오기 전 스마트폰으로 명령을 주지 않아도 자동으로 썬루프를 닫는다. 만약 구름이 있어도 썬루프를 열겠다는 신호를 보내면 “Warning: 썬루프를 여시겠습니까?”라는 문구를 띄우고 “예”를 누르면 작동한다.

2.2.3. 방범 시스템
개요 : 밤에 늦게 누군가가 집에 침입하였을 때 빠르게 112에 신고할 수 있다.
작동 :
1. 스마트폰으로 방범 시스템 작동 유무 설정
2. 방범시스템을 작동시키면 GP2D120(광 센서)을 이용해 사람 유무 판단.
3. 사람이 있다고 감지되었을 때 스마트폰으로 감지되었다고 메시지와 진동으로 표시. 그 후 112에 신고하시겠습니까?라는 문구를 띄우고 예를 누르면 112에 연결

2.2.4. 우편함 알림 시스템
개요: 밖에 있는 우편함에 우편이 있는지 없는지 직접 확인을 하지 않아도 센서를 통해 자동적으로 스마트폰 메일 알람 시스템으로 알려준다.
작동:
1. GP2D120(광 센서)를 우편함 아래쪽에서 거리를 잴 수 있도록 배치하고 우편이 놓였을 때 거리 값이 작아지는 것을 이용하여 우편 유무 확인
2. 우편이 있을 때 스마트폰으로 우편이 왔다고 메일 알림으로 표시한다.

2.3. 등각 외관도 및 작품 사진

Cap 2017-05-30 10-07-16-702

Cap 2017-05-30 10-07-24-767

Cap 2017-05-30 10-07-29-001

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

Cap 2017-05-30 10-11-58-501

2.5. 세부 구성
기구부

Cap 2017-05-30 10-13-01-118

회로부 및 센서부

Cap 2017-05-30 10-13-06-286

Cap 2017-05-30 10-13-16-004

Cap 2017-05-30 10-13-16-004

Cap 2017-05-30 10-13-27-335

2.6. 소프트웨어 주요 코드
2.6.1. Atmega128 소프트웨어 주요 코드

==================================================
// Function: 외부 인터럽트를 사용하기 위한 설정
// Descriptions: 하강엣지일때 계속해서 발생
==================================================
DDRD &= ~(_BV(DDD0)|_BV(DDD1)); //INT0(PD0), INT1(PD1) 핀을 디지털 입력 포트로 설정
PORTD |= _BV(PD0)|_BV(PD1); //풀업저항 있는 입력
// 하강 일시 작동 PD0 INT0 PD1 INT1 사용
EICRA &= ~(_BV(ISC00)|_BV(ISC01)|_BV(ISC10)|_BV(ISC11));
// 하강 일시 계속 인터럽트 발생
EIMSK |= _BV(INT0)|_BV(INT1); //개별적 인터럽트 허용

창 리미트스위치를 눌렀을 때 인터럽트가 실행되도록 초기화 설정

==================================================
// Function: adc 사용하기 위한 설정(GP2D120) 거리 센서 0~3.3출력
// Descriptions: PF0(ADC0) ~PF7(ADC7)까지 있음
==================================================
DDRF=0; //풀업저항 없는 입력 사용
PORTF =0;
ADMUX |= _BV(REFS0); ADMUX &= ~_BV(REFS1);
//5v AVCC연결된 전압 AREF에 연결된 커패시터사용
ADCSRA |= _BV(ADPS2)|_BV(ADPS1)|_BV(ADPS0);
//AVR 16000KHz 80 <= X <= 160설정해야함 따라서 분주비 128 설정 125KHz
// ADC 클럭을 결정하는 비트입니다. 분주비가 작으면 변환이 빨리 되지만 사용상 문제가 없는 범위에서 최대한 느리게 변환 하는 것이 노이즈 영향이 줄어든다.
ADCSRA |= _BV(ADEN); //인에이블비트

거리 센서의 아날로그값을 디지털값으로 변화하기 위하여 ADC컨버터 초기값 설정

==================================================
// Function: cds광전도셀에서 받은 op앰프 출력을 입력시킬때 쓰는 핀
// Descriptions: cds셀 입1/0 상태 입력단자. 어두울 때 1 밝을 때 0
==================================================
DDRG &= ~_BV(DDG4);//cds셀 상태 입력단자. 어두울 때 1 밝을 때 0
PORTG &= ~_BV(PG4);//풀업저항 없는 입력

PD4에 CDS셀의 조도 값을 받아들이기 위하여 입력 설정

==================================================
// Function: 연기 센서
// Discriptions: 연기 센서 작동되면 PING2에서 5v 출력이 PING3 에 입력된다.
==================================================
DDRG |= _BV(DDG2); //출력으로 사용 사용된 곳 없음
PORTG |= _BV(PG2);
DDRG &= ~_BV(DDG3); //풀업있는 입력 사용
PORTG |= _BV(PG3);
DDRG &= ~_BV(DDG0)|_BV(DDG1); //리밋스위치용 풀업저항 있는 입력
PORTG |= _BV(PG0)|_BV(PG1);
//사용시 Pxn핀 HIGHT 전압 출력
//PORTx 레지스터의 Pxn 비트를 1로
DDRF |= _BV(DDF2);
PORTF |= _BV(PF2);

PG3에 연기센서값을 받아들이기 위하여 입력 설정

==================================================
// Function: ch 0~7중 하나를 선택해 0~5V로 변환하는 함수
// Descriptions: PF0(ADC0) ~PF7(ADC7)까지 있음
// 예를 들어 ATmega128 ADC의 reference 전압을 2.5V로 만든다면,
// ADC의 resolution은 1/1024
// 2500mV / 1024 = 약 2.44 mV
// 즉, ADC에 0V가 입력되면 0이라는 변환 값이 나오고,
// 2.44mV가 입력되면 1,
// 4.88mV가 입력되면 2, …..
// 2500mV가 입력되면 1023 이라는 ADC 변환 값이 출력됩니다.
==================================================
uint16_t GetAdv(uint8_t ch) //ch 0~7중 하나를 선택해 A/D 변환하는 함수
{
uint16_t Ain;
ADMUX = (ADMUX&0xf8)|(ch&0×7); //하위 3비트로 채널 선택
ADCSRA |= _BV(ADSC); //ADSC에 1을 넣어 S/H후 A/D 변환 시작
while(!(ADCSRA&_BV(ADIF))); //ADSC의 ADIF가 1이 되면 A/D변환 종료
//val = ADC;
//ADC로부터 변환된 값 저장
///참고: 이렇게 하면 실제로는 ADIF가 0이됨
Ain = ((uint32_t)ADC*50 + (1<<9))>>10; //Ain은 실제 전압의 10배
//Ain = ADC *5.0/1023.0;
ADCSRA |= _BV(ADIF);
return Ain;
}

ADC n번을 이용하고 그 값을 10배하여 받아들임 ex) 100값을 받았다면 10V입력

//- Wireless Module를 통해 수신된 데이터 패킷이 있으면 받아서 데이터에 따라 모터 구동
if (uwIsPacket()==UW_PACKET0)
{
if (uwGetData0(&data))
{
mtrDrive0(data);
lswPutLed(0×1); //확인용 LED 점멸
}
t_prev = tm2Getms();
}

수신한 Data 값을 가지고 모터를 PWM 제어

if(data==PROTECTON) //방범기능용
{
protectflag=0;
}
if(data==PROTECTONOFF)
{
protectflag=1;
}

방범 기능 On/Off 기능 수행

==================================================
// Function: DS_SD_002 연기 센서에 0×30 데이터 전송
// Discriptions: PING3 에서 5V입력이 확인되면
==================================================
if(!(PING & _BV(PING3)))
{
if(DS_SD_002_Flag==0){
uartPutc(DS_SD_002);
lswPutLed(0×2); //확인용 LED 점멸
DS_SD_002_Flag=1;
DS_SD_002_t_prev = tm2Getms();
}
}
else if ((tm2Getms()-DS_SD_002_t_prev)>6000) // 일정시간지나면 입력 받아들임
{
DS_SD_002_Flag=0;
}

연기 센서에 연기가 감지되면 그것을 확인하는 코드

==================================================
// Function: cds광전도셀에서 받은 op앰프 출력을 입력시킬때 쓰는 핀
// Discriptions: cds셀 입1/0 상태 입력단자. 어두울 때 1 밝을 때 0
==================================================
if(PING & _BV(PING4))

{
if(CDS_Flag==0){
uartPutc(CDS);
lswPutLed(0×4); //확인용 LED 점멸
CDS_Flag=1;
CDS_t_prev = tm2Getms();
mtrDrive0(0×4); //아니면 ox2 닫기는 left
}
}

CDS 셀에서 AVR로 입력된 값을 확인하여 선루프를 자동으로 열고 닫는다.

==================================================
// Function: adc입력상태를 확인하여 출력 0번은 MAIL
// Descriptions: 0번은 메일함 꼭대기까지 5cm 2.3정도 탐지 거리 7mm 물건이 있을 경우 1cm기준으로 잡는다. 1.8
==================================================
if(GetAdv(myAdc0)>5) //adc0번이 입력 전압이 1.8V보다 작을때
{
if(GP2D120Mail_Flag==0){
uartPutc(MAIL);
lswPutLed(0×8); //확인용 LED 점멸
GP2D120Mail_Flag=1;
GP2D120Mail_t_prev = tm2Getms();

}
}

우편함에서 우편이 감지되면 AVR로 신호를 준다.

if(protectflag==0)
{
lswPutLed(0xaa);
==================================================
// Function: adc 입력 상태를 확인하여 출력 GP2D120
// Descriptions: 추후 감지 범위 바꿔가며 정밀하게 만들 예정
==================================================
if(GetAdv(myAdc1)>20) //adc0번이 입력 전압이 2.5V보다 작을 때 30cm
{
if(GP2D120_1_Flag==0){
uartPutc(GP2D120_0);
lswPutLed(0×81); //확인용 LED 점멸
GP2D120_1_Flag=1;
GP2D120_1_t_prev = tm2Getms();
}
}

==================================================
if(GetAdv(myAdc2)>15) //adc0번이 입력 전압이 2.5V보다 작을 때 우체통
{
if(GP2D120_2_Flag==0){
uartPutc(GP2D120_1);
lswPutLed(0×90); //확인용 LED 점멸
GP2D120_2_Flag=1;
GP2D120_2_t_prev = tm2Getms();
}
}
else if((tm2Getms()-GP2D120_2_t_prev)>5000)
{
GP2D120_2_Flag=0;
}
==================================================
if(GetAdv(myAdc3)>15) //adc0번이 입력 전압이 2.5V보다 작을 때
{
if(GP2D120_3_Flag==0){
uartPutc(GP2D120_2);
lswPutLed(0×84); //확인용 LED 점멸
GP2D120_3_Flag=1;
GP2D120_3_t_prev = tm2Getms();
}
}
==================================================
if(GetAdv(myAdc4)>15) //adc0번이 입력 전압이 2.5V보다 작을 때
{
if(GP2D120_4_Flag==0){
uartPutc(GP2D120_3);
lswPutLed(0×90); //확인용 LED 점멸
GP2D120_4_Flag=1;
GP2D120_4_t_prev = tm2Getms();
}
}

Cap 2017-05-30 10-14-13-878

각각의 센서에서 받은 값을 확인하여 방범 기능을 수행한다.

==================================================
// Function: mtrDrive0
// Descriptions: CP-RC가 전송한 Data에 따른 모터 구동
==================================================
void mtrDrive0(uint16_t Data)
{
if (Data&MTR_LEFT)
{
if(!(PING&_BV(PING0)))
{
pwmSet(PWM_CH0, 0);
}
else pwmSet(PWM_CH0, MTR0_HIGH); //CH_0모터 255 고속 값으로
}
else if (Data&MTR_RIGHT)
{
if(!(PING&_BV(PING1)))
{
pwmSet(PWM_CH0, 0);
}
else pwmSet(PWM_CH0, -MTR0_HIGH);
}
else if (Data&MTR_GOLEFTALL)
{
while((PING&_BV(PING0)))
{
pwmSet(PWM_CH0, MTR0_HIGH);//CH_0모터 255 고속 값으로
}
}
else if (Data&MTR_GORIGHTALL)
{
while((PING&_BV(PING1)))
{
pwmSet(PWM_CH0, -MTR0_HIGH);//CH_0모터 255 고속 값으로
}
}
else //모터 정지
{
pwmSet(PWM_CH0, 0);
}
}
void pwmSet(uint8_t ch, int16_t Val)
{
if (Val<-255) Val=-255;
if (Val>255) Val=255;

if (ch==PWM_CH0) // CH0 모터인 경우
{
#if PWM_EN_DIP_REVERSE
if (lswGetSwitch() & LSW_DIP1) Val = -Val;
#endif
if (Val>0) // 정방향이면,
{
PORTE&=~_BV(PE4); // L298 1A1를 LOW로
OCR3A=Val;
}
else
{
PORTE|=_BV(PE4); // L298 1A1을 High로
OCR3A=255+Val;
}
}
}

모터 제어를 위한 PWM 코드

==================================================
// Function: uwGetData0
// Description: 패킷으로부터 2바이트 데이터 추출
==================================================
uint8_t uwGetData0(uint16_t* data)
{
uint8_t sreg;
uint16_t result=0;

if (((uwData[1]+uwData[2])&0x7f)==uwData[3])
{
*data=uwData[1]+((uint16_t)uwData[2]<<8);
result=1;
}
sreg=SREG;
cli();
uwFlag=0;
SREG=sreg;

return result;
}

2바이트를 추출하기 위한 USART 소켓 통신 코드

==================================================
// Function: uwIsPacket
// Description: 패킷 전송 유무 확인, 패킷 전송시 1
==========================
uint8_t uwIsPacket(void)
{
uint8_t sreg, result;
sreg=SREG;
cli();
result=uwFlag;
SREG=sreg;
return result;
}

패킷 전송 유무 확인, 패킷 전송 시 1 리턴

2.6.2. 스마트폰 안드로이드 소프트웨어 주요 코드

if(read()==”cloud”){
Intent intent = new Intent(getApplicationContext(),
Cloudalert.class);
startActivity(intent);
}

if(read()==”fire”){
Intent intent = new Intent(getApplicationContext(),
Firealert.class);
startActivity(intent);
}
Button Call119 = (Button)findViewById(R.id.call119yesbtn);
Call119.setOnClickListener(new OnClickListener(){
public void onClick(View v){
Intent in = new Intent(Intent.ACTION_CALL);
in.setData(Uri.parse(“tel:01090577489″));
startActivity(in);
}
});

if(read()==”protect”){
Intent intent = new Intent(getApplicationContext(),
Protectalert.class);
startActivity(intent);
}
Button Call112 = (Button)findViewById(R.id.call112yesbtn);
Call112.setOnClickListener(new OnClickListener(){
public void onClick(View v){
Intent in = new Intent(Intent.ACTION_CALL);
in.setData(Uri.parse(“tel:01090577489″)); //암시적 인텐트로 전화를 건다. 매니페스트에 추가해줘야함
startActivity(in);
}
});

AVR에서 블루투스로 보내준 데이터에 따라 인텐트 생성하여 알림 창을 띄운다.

private class TransmitThread extends Thread {

int pauseCnt = 0;
byte[] packet0 = new byte[4];

public void run() {
setName(“RepeatThread”);
while (true) {

if (mBtnStatusChanged==true)
{
if (mSerialService.getState() == BluetoothSerialService.STATE_CONNECTED) {
packet0[0] = (byte) PACKET0_START;
packet0[1] = (byte) (mBtnStatus&0xff);
packet0[2] = (byte) (mBtnStatus>>8);
packet0[3] = (byte) ((packet0[1]+packet0[2]) & 0xff);
mSerialService.write(packet0);
}
if (mBtnStatus==0) {
if (++pauseCnt >= 10) {
pauseCnt = 10;
mBtnStatusChanged = false;
}
} else {
pauseCnt = 0;
}
try {
Thread.sleep(TRANSMIT_INTERVAL-1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

AVR에서 스마트폰으로 온 데이터를 받기 위한 통신 쓰레드

private String read() {
int length = buffer.length();
String data = buffer.substring(0, length);
buffer.delete(0, length);
return data;
}

스마트폰에 수신된 데이터를 buffer에 저장하고 읽어오는 함수

public void write(byte[] buffer) {
try {
mmOutStream.write(buffer);

// Share the sent message back to the UI Activity
mHandler.obtainMessage(BluetoothSerial.MESSAGE_WRITE, -1, -1, buffer)
.sendToTarget();
} catch (IOException e) {
Log.e(TAG, “Exception during write”, e);
}
}

스마트폰에서 AVR로 데이터를 보내기 위한 함수

2.7. 스마트폰 제어 화면
2.7.1. 메인 화면

Cap 2017-05-30 10-20-10-726
ProjectH 앱을 실행하면 첫 화면에서 방범 시스템 On/Off, 썬루프 닫기/열기 기능을 설정할 수 있다.
썬루프 닫기/열기는 누르고 있는 동안 열고 닫히는 버튼이고 썬루프 전부 닫기 / 전부 열기는 한번 누르면 전부 열고 닫는 버튼이다. 방범 시스템 On/Off기능은 GP2D120 센서로 움직이는 물체를 감지하여 켜고 끌 때 사용하는 버튼이다.
그 외에 사용된 센서는 감지하는 신호를 받아 팝업 창을 띄우게 된다.

2.7.2. 화재알림기능_DS-SD-002(연기 센서)

Cap 2017-05-30 10-20-16-341
연기 센서는 제작 업체에 따르면 일반 화장실 크기의 공간에서 담배를 태우면 연기가 감지되도록 설계되었다고 한다. 연기가 감지되었을 때 릴레이의 접점을 이용하여 신호로 전달한다. 연기가 감지되었을 때는 AVR에서 신호를 받아들여 스마트폰으로 위험을 알리는 팝업 창을 띄우고 센서 부분에서 버져가 울리게 된다.
“집에 연기가 감지되었습니다. 119에 신고하시겠습니까?”라는 문구에서 Yes를 누를 경우 바로 119에 전화가 걸리게 되고 아닐 경우 No를 누르면 메인화면으로 돌아가게 된다.

2.7.3. 방범 기능_GP2D120

Cap 2017-05-30 10-24-01-934
GP2D120 센서의 거리에 따른 값을 0~3.3V 범위의 아날로그로 받아 AVR에서 0~5V의 디지털 값으로 바꾸어 어느 정도에 거리에 있는 물체들만 감지하도록 하였고, 화재 알림 기능과 동일하게 Yes를 누르면 112에 바로 통화가 가능하며 No를 누르면 빠져나가 메인화면으로 돌아가게 된다. 스마트폰 메인 화면에 Protect On/Off기능으로 켜고 끌 수 있다. 감지되는 위치에 따라 감지 위치 화면을 띄운다.
아래 그래프는 거리에 따른 전압의 출력 값을 나타내는 데이터시트이다. 이것을 정리해보면 두번째 표와 같다.

Cap 2017-05-30 10-24-12-395

Cap 2017-05-30 10-25-00-310

 

Cap 2017-05-30 10-25-06-145

2.7.4. 우편 기능_GP2D120
우편이 우체통으로 들어왔을 때 센서를 가리게 된다. 그러면 GP2D120 센서의 출력 전압이 0V가 된다. 이 원리를 이용하여 전압이 0V가 되었을 때 AVR에서 스마트폰으로 신호를 전달하게 되고 노티피케이션을 통하여 사용자에게 보여주게 된다.

Cap 2017-05-30 10-25-11-114

1) 화면 노티피케이션을 누르면
2) 화면이 뜨고 노티피케이션은 사라진다.

스마트폰에서 메시지가 오면 상단에 메시지 알림이 뜨고 클릭하면 메시지를 보는 동시에 상단 메세지알림이 사라진다. 이와 같이 최대한 메시지와 알림 및 확인 방식을 유사하게 해 직관적으로 알아볼 수 있도록 제작하였다.

2.7.5. 조도감지센서(GL5516)

Cap 2017-05-30 10-26-33-052
조도가 자신이 원하는 정도에 기준을 정하기 위해서 OP앰프를 사용했고, -쪽(Reference 전압)으로 들어가는 전압을 조절하기 위하여 10KΩ의 가변저항을 넣었다. 이 회로는 어느 정도 어두워지면 HIGHT 값을 AVR에 전달한다. 우리 시스템에서는 우천 시 집안으로 비나 눈이 들어오는 것을 방지하기 위해 어두워지면 자동으로 창을 닫는 것으로 설정하였다.

Cap 2017-05-30 10-26-40-751
위 회로에서 -쪽을 살펴보면 R1이 1.8k, R2가 0~10KΩ이다. 만약 CDS가 밝을 때 5KΩ이 나온다면 +에 들어가는 전압은 5/(10+5), 즉 VCC에 약 1/3 1.6V정도가 된다. 가변 저항의 값은 1.6 =< 가변저항값/(1.8+가변저항값)으로 최소값을 결정해주면 된다.

2.7.6. 썬루프 창 부분 (KGU-3429(DC 12V))
회전운동을 직선운동으로 바꾸어줄 리니어모터를 사용하였다. 메인 화면에서 썬루프 닫기나 썬루프 열기를 누르고 있을 때 닫히거나 열리게 되고, 썬루프 전부 닫기나 전부 열기를 한 번 눌렀을 시 전부 닫히거나 열리게 된다. 리니어모터가 지정된 범위에서만 움직이도록 양 끝단에 리밋스위치를 달아 범위를 제한했다.

3. 단계별 제작 방법
3.1. 모터 기구부 제작

Cap 2017-05-30 10-26-46-002
모터가 일직선상으로 직선운동을 원활하게 하기 위해서 직선의 홈을 만들어 그 직선을 따라 이동하도록 제작하였다. 빨간색 부분에 파여진 홈에 모터의 신호에 따라 좌우로 작동을 한다. 파란색 사각형 부분은 리미트센서가 들어가도록 홈을 제작하였다. ‘썬루프 전체 열기’를 실행하면 모터가 이 두 리밋센서 사이에서만 움직이도록 제한하였다.

3.2. 전체 외형 제작

Cap 2017-05-30 10-29-06-184
위와 같이 SolidWorks 2010으로 레이저 가공을 위한 1:1 도면을 만들었다. 나사 구멍과 지붕의 기울기를 고려하며 시스템상 충돌이 나지않고 어셈블리가 되도록 하였다. 어셈블리가 되지 않으면 도면을 따라 레이저 프린터 가공을 하였을 때 나사구멍이 맞지 않아 조립이 되지 않으므로, 신중을 가했다.

Cap 2017-05-30 10-29-15-534

Cap 2017-05-30 10-29-27-370

다음으로는 솔리드웍스의 1:1 도면을 각각 부품에 대하여 CAD 파일로 내보내기를 한다. 내가 사용한 레이저 가공기가 Solid Work는 지원하지 않고 AutoCAD를 통한 1:1 도면 프린트만 가능했기 때문이다. 아래는 실제로 레이저 프린터로 아크릴을 가공했을 때 사용했던 AutoCAD 도면이다.

Cap 2017-05-30 10-29-37-268

3.3. 소프트웨어
안드로이드 앱 프로그래밍은 처음이라 참고할 도서를 선정하여 공부하며 따라했다. 대표적인 책으로 ‘Do it 안드로이드 앱 프로그래밍’ 책이 있었고 Bluetooth chat 부분의 통신 부분을 가지고 블루투스 부분을 구현하게 되었다. 블루투스를 구현한 후 AVR에서 스마트폰으로 넘어오는 데이터 값에 따라 서로 다른 화면을 띄워줄 필요가 있었고 그 화면 구성을 인텐트로 각각의 Layout을 지정해주었다. 송수신 데이터 값이 중간에 변경되지 않고 정확하게 전달하기 위해서 public static final int 값으로 지정하고 문자로 지정해줌으로써 쉽게 통신하도록 해주었다. 데이터 송수신을 소켓통신 방법을 사용하고 오류검정코드 packet0[3] = (byte) ((packet0[1]+packet0[2]) & 0xff);를 통해 각각의 비트를 검사하며 데이터의 손실이 일어나도 그 데이터는 버리도록 만들어 통신 신뢰도를 높였다. AVR에서는 ADC 변환, 모터 제어를 위한 PWM, USART, 센서값 받기 등 센서 처리와 통신을 위한 코드를 만들었다.

4. 참조 자료
• Do it 안드로이드 앱 프로그래밍 젤리빈 4.2.2판
• 기적을 부르는 안드로이드 통신 프로그래밍

 

 

 

Leave A Comment

*