코코아팹은 누구나 창의적 아이디어를 현실로 만들어 낼 수 있도록
만들고, 공유하고, 배울 수 있는 터전이
되고자 합니다.
아이디와 비밀번호를 잊으셨나요?아이디 / 비밀번호 찾기
코코아팹 회원이 아니신가요? 회원가입
2015-06-02 15:16:36
지난 시간 Light Application [Part 1]에 이어 이번엔 블루투스 기능을 추가하여 제어해 보도록 하겠습니다.
처음 보시는 분들은 꼭!!!! PART 1을 보고 오시기 바랍니다.^^
AVR로 제작한 작품 원본은 다음 링크로 보시면 됩니다.
(Light Application ATmega128 ver) Kocoafab
(Light Application ATmega128 ver) Naver Cafe
[PART 1] 온도, 습도, 조도 값을 받아 실내 환경 데이터를 수집하고 그에 알맞게 블라인드와 조명을 제어합니다.
[PART 2] 자동제어 외 스마트폰을 이용한 수동제어를 이용하여 직접 블라인드와 조명을 제어합니다.
No | PART | QTY | ETC |
1 | Light Application Part 1 | 1 | |
2 | Bluetooth Module | 1 | HC-06 or HC-05 |
<브레드 보드 레이아웃>
사실 회로 부분은 PART1과 크게 다르지 않습니다. 블루투스 모듈 HC-05만 추가된 모습입니다.
블루투스 모듈 사용법은 Tutorial : 블루투스 통신 기초 를 참고하시면 됩니다.
이 프로젝트에서 가장 중요한 부분인 커튼입니다. 별도의 블라인드로 구현 가능하지만 좀 더 간소하게 만들기 위해
커튼봉과 천을 구입하여 직접 붙였습니다. 붙이는 부분이 다소 지저분해지긴 하지만 시간을 투자하여 손질하면
충분히 깔끔한 커튼 모양을 만들 수 있습니다.
사실 이 부분이 가장 애를 많이 먹었습니다.....ㅠ_ㅇ 모터 반대편에서 커튼을 지지해줄 무언가가 필요했지만
좀 처럼 마땅한게 없었습니다. 결국 스티로폼 재질의 블럭에 커튼봉이 걸쳐질 만한 구멍을 내어 부착하였습니다.
#include <DHT11.h>
// 온도센서 라이브러리
#include <Adafruit_NeoPixel.h>
// 네오픽셀 라이브러리
#include <SoftwareSerial.h>
// 소프트웨어 씨리얼 라이브러리(블루투스용)
#define PIN A3
DHT11 dht11(5); // 온도센서 데이터 핀
SoftwareSerial BTSerial(2, 3); // 블루투스 통신전용 핀 (RX, TX)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(30, PIN, NEO_GRB + NEO_KHZ800);
int BA = 9;
int DA = 12;
int PA = 3;
int light;
int i;
int sum;
int a,b;
int flag = 0;
int address = 0;
int err;
int BT;
float temp, humi;
char data;
void setup()
{
strip.begin();
strip.show();
Serial.begin(115200);
BTSerial.begin(9600);
pinMode(PA, OUTPUT);
pinMode(DA, OUTPUT);
pinMode(BA, OUTPUT);
strip.begin();
strip.show();
light = analogRead(A4);
if(light < 500){flag = 0;}
else if(light >= 500){flag = 1;}
Serial.println("Mode Select!!");
}
void loop()
{
if(BTSerial.available()) // 블루투스로 자동모드와 수동모드 설정
{
Serial.println((char)BTSerial.read());
if(BTSerial.read() == '1') // 블루투스로 '1'의 값이 들어올 경우
{
Serial.println("Auto Mode"); // 라이트어플리케이션 자동모드 사용
while(1)
{
Serial.println("Type,\tstatus,\tHumi(%),\tTemp(C),\tBrg");
data = BTSerial.available();
Sensing();
Auto_Mode();
Led_Control();
if(data == '1')break; // 블루투스로 '1'의 값이 또 들어올 경우 자동모드 해제
}
}
else if(BTSerial.read() == '2') // 블루투스로 '2'의 값이 들어올 경우
{
Serial.println("Hand Mode"); // 라이트어플리케이션 수동모드 사용
while(1)
{
Serial.println("Type,\tstatus,\tHumi(%),\tTemp(C),\tBrg");
data = BTSerial.available();
Led_Control();
Sensing();
Hand_Mode();
if(data == '2')break; // 블루투스로 '2'의 값이 또 들어올 경우 수동모드 해제
}
}
}
}
void Sensing()
{
// READ DATA
if((err=dht11.read(humi, temp))==0)
{
Serial.print("temperature:");
Serial.print(temp);
Serial.print(" humidity:");
Serial.print(humi);
Serial.print("");
}
else
{
Serial.println();
Serial.print("Error No :");
Serial.print(err);
Serial.println("");
}
Serial.print(" ");
Serial.print(analogRead(A4));
Serial.print(" ");
delay(1000);
}
void Hand_Mode() // 라이트 어플리케이션 수동모드
{
while(!BTSerial.available()) // 블루투스 데이터 값이 들어올 때까지 동작 대기
if(BTSerial.available()) // 블루투스 데이터가 수신 될 경우
{
BT = BTSerial.read(); // 블루투스로 수신된 데이터를 BT 변수에 저장
if(BT == 'd'&& flag == 0) // BT에 저장된 값이 d이며, 플래그가 0일 경우
{
Cutton_On(); // 커튼 동작 함수
flag = 1; // 플래그 SET
}
else if(BT == 'u'&& flag == 1) // BT에 저장된 값이 u이며, 플래그가 1일 경우
{
Cutton_Off(); // 커튼 동작 함수
flag = 0; // 플래그 RESET
}
else
{
}
}
}
void Auto_Mode()
{
light = analogRead(A4);
//brightness control
if(light < 500 && flag == 0)
{
Cutton_On();
flag = 1;
Serial.println(flag);
}
else if(light >= 500 && flag == 1)
{
Cutton_Off();
flag = 0;
Serial.println(flag);
}
}
void Led_Control()
{
if(humi <= 39)
{
i = analogRead(A4);
if(temp < 23)
{
for(a=0; a<strip.numPixels(); a++)
{
strip.setPixelColor(a,strip.Color(0, 0, i));
}
strip.show();
}
else if(temp >= 23 && temp < 26)
{
for(a=0; a<strip.numPixels(); a++)
{
strip.setPixelColor(a,strip.Color(0, i, 0));
}
strip.show();
}
else if(temp >= 26)
{
for(a=0; a<strip.numPixels(); a++)
{
strip.setPixelColor(a,strip.Color(i, 0, 0));
}
strip.show();
}
}
else if(humi > 39)
{
type2();
}
}
void Cutton_On()
{
digitalWrite(DA,HIGH);
digitalWrite(PA,HIGH);
digitalWrite(BA,LOW);
delay(7000);
digitalWrite(BA,HIGH);
}
void Cutton_Off()
{
digitalWrite(DA,LOW);
digitalWrite(PA,HIGH);
digitalWrite(BA,LOW);
delay(7000);
digitalWrite(BA,HIGH);
}
void type2()
{
uint16_t i, j;
for(j=0; j<256; j+=1)
{
for(i=0; i<strip.numPixels(); i++)
{
int sum = i+j;
map(sum,0,300,120,190);
strip.setPixelColor(i, Wheel(sum),Wheel(sum),Wheel(sum));
}
strip.show();
delay(10);
}
}
uint32_t Wheel(byte WheelPos)
{
WheelPos = 255 - WheelPos;
if(WheelPos < 85)
{
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
else if(WheelPos < 170)
{
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
else
{
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
}
PART 1에서 제작한 소스에 Hand_Mode()함수를 추가하였습니다. 한 가지 염두해 두셔야 하는건 커튼 수동제어와 LED 제어는 별개의 동작입니다.
즉, 커튼은 수동으로 제어하더라도 LED는 자동 모드와 같이 온도, 습도 값에 의해 조절됩니다. 사용자의 편의에 따라 수동모드에 LED 역시 스마트 폰으로
제어 할 수 있도록 만들면 더욱 유용한 프로젝트가 될 수 있습니다.
SaBo