정보나눔

오픈소스하드웨어 프로젝트에 대한 다양한 정보를 나누는 공간입니다.

구름조명 질문드립니다.
김성구 | 2016-07-02

수정한 코드를 사용해본 결과 두번째 파싱까지는 날씨정보를 잘받아왔는데

그 이후부턴 배드 리퀘스트가 뜨면서 쭉 에러가 납니다.

그리고 9번 핀에 연결되어 있는 파싱버튼은 어떤 역할을 하나요?

눌러봐도 반응이 없습니다.

지금 코드에는 날씨정보를 받고 날씨정보에 따른 날씨색을 표현해준다음 몇초간(6초쯤?) 무드등 상태가 되었다가 자동으로 날씨정보를 받는 형태인데..

날씨정보를 자동으로 받아오는게 아니라 9번핀의 파싱버튼을 눌러야 날씨정보를 받게 할수는 없나요?

9번핀의 파싱버튼을 누를 때만 날씨색을 표현해주고 누르지 않을때는 일반 무드등 상태가 되면 좋겠습니다.

매번 답변 달아주셔서 감사합니다.

 

#include <Adafruit_NeoPixel.h>
#include <avr/power.h>

#include "SPI.h"
#include "WiFi.h"

char ssid[] = "iptime";         //와이파이 ID
char pass[] = "password";     //와이파이 비밀번호
String location = "Newyork";          //날씨를 가져오고자 하는 지역 선택
                           
WiFiClient client;
char server[] = "api.openweathermap.org";

IPAddress hostIp;

//neopixel LED를 10번핀에 연결 
#define PIN 10                      
Adafruit_NeoPixel strip = Adafruit_NeoPixel(15, PIN, NEO_GRB + NEO_KHZ800);     //neopixel LED의 개수 설정 및 선언

String currentLine = "";            //서버에서 전송된 데이터 String 저장
String codeString = "";             //날씨 코드 저장 변수

boolean readingCode = false;        //코드 데이터가 있는지 여부 판단

int redVal;                         //RGB LED red 값 변수
int greenVal;                       //RGB LED green 값 변수
int blueVal;                        //RGB LED blue 값 변수

int weatherButton = 9;              //날씨 데이터 파싱 동작을 위한 버튼을 9번에 연결
int powerButton = 8;                //조명 on, off 동작을 위한 버튼을 8번에 연결

//on, off 버튼 토글 동작을 위한 변수
int oneTimeFlag;
boolean onOffStatus;

//날씨 파싱 동작을 위한 변수
boolean parsingStart = false;
int weatherCode;

int temp = 0; 

void setup() {
  //버튼 셋팅(INPUT 설정)f
  pinMode(powerButton,INPUT_PULLUP); 
  pinMode(weatherButton,INPUT_PULLUP);
  
  //neopixel setting
  #if defined (__AVR_ATtiny85__)
  if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
  #endif
  
  strip.begin(); 
  strip.show();
  
  //각 변수에 정해진 공간 할당
  currentLine.reserve(100); 
  codeString.reserve(10);
  
  Serial.begin(115200);
  
  //Wi-Fi 연결 시도
  delay(10); 
  Serial.println("Connecting to WiFi....");
  WiFi.begin(ssid,pass);
  Serial.println("Connect success!");
  Serial.println("Waiting for DHCP address");
  while(WiFi.localIP() == INADDR_NONE) {
    Serial.print(".");
    delay(300);
  }
  printWifiData();  //Wi-Fi 정보 출력
  readyLED();       //Wi-Fi 연결 후 준비가 완료되었다면 초록빛 dimming
  
}

void loop() {
/*on, off 버튼 토글 설정 
 off : onOffStatus = 0 
 on : onOffStatus = 1*/
    
 int i = digitalRead(weatherButton);            //날씨 버튼 상태를 변수 i에 저장
 
          if(digitalRead(powerButton)==LOW){    //power 버튼이 눌러지면 onOffstatus의 상태값 토글
                if(oneTimeFlag==0){
                        oneTimeFlag = 1;
                        onOffStatus = !onOffStatus;
                }
        }
       else{
                oneTimeFlag = 0;
        }
 

 if(onOffStatus==0){                                    //onOffStatus의 상태가 0이면
     for(int i=0; i<strip.numPixels(); i++){
       strip.setPixelColor(i,0,0,0);
       strip.show();
     }
 }
 
 //날씨 데이터 파싱 및 RGB led 색상 조절 모드
 else{
   if(i == 0){                                          //weatherButton의 상태가 0이라면
     parsingStart = true;     //parsingStart의 상태값 변경
   }
   
   while(parsingStart){        //parsingStart의 상태값이 참일동안
    
     connectToServer();                                  //서버 연결(openweathermap API에 날씨데이터 호출)
     if(client.connected()){       //클라이언트에 연결되어 있다면
       delay(3000); //**
       while(client.available()){          //클라이언트에 들어온 데이터가 있다면
         char inChar = client.read();                   //들어온 데이터를 inChar에 저장
         currentLine += inChar;                 //inChar에 저장된 char 변수는 currenLine에 저장됨
         Serial.print(inChar);
         if(inChar == '\n'){                            //줄바꿈(\n) 문자열이 전송되면 데이터를 저장하지 않음
           currentLine = "";
         }
         
         //날씨 코드 데이터가 전송되었는지 확인
         if(currentLine.endsWith("<weather number=")){  //currentLine의 string이 <weather number=로 끝났다면
         readingCode = true;                            //날씨 코드 데이터를 받을 준비를 한다
         codeString = "";

         
         }
         if(readingCode){
           if(inChar != 'v'){                           //inChar string에 v가 전송될 때까지
             codeString += inChar;                      //codeString에 저장
           }
           else{                                        //전송된 문자가 v라면
             readingCode = false;                       //저장 중지
             weatherCode = getInt(codeString);          //저장한 날씨 코드 string을 integer로 변환
             //Serial.print("weather : ");                //시리얼 모니터로 날씨 코드 출력
             //Serial.println(codeString);
           }
         }  
       }
     }
     else{
       Serial.println("connect fail");           //클라이언트에 연결되지 않았다면 시리얼 모니터창에 connect fail 출력
       errorLED();                               //클라이언트에 연결되지 않았다면 빨간빛 dimming                      
       //weatherCode=0;
     }
       
     //날씨 코드 분류
     if(weatherCode>299 && weatherCode<532){        //rainny
      rainnyLED();
     } 
     else if(weatherCode>599 && weatherCode<623){       //snow 
      snowLED();
     }
     else if(weatherCode>700 && weatherCode<782){       //mist
      cloudyMistLED();
     }
     else if(weatherCode >799 && weatherCode<802){      //clear and sunny
      clearweatherLED();
     }
     else if(weatherCode>801 && weatherCode<805){       //cloudy   
      cloudyMistLED();
     }
   
     parsingStart = false;             //날씨 데이터를 파싱하고 LED로 날씨를 표현한 후 상태값 변경
     weatherCode=0;
   }
   
  
   //조명모드
     redVal = map(analogRead(A0),0,1023,0,255); 
     greenVal = map(analogRead(A1),0,1023,0,255); 
     blueVal = map(analogRead(A2),0,1023,0,255); 
     
     for(int i=0; i<strip.numPixels(); i++){
       strip.setPixelColor(i,redVal,greenVal,blueVal);
       strip.show();
     }


 } 

//Wi-Fi 서버 연결 함수
void connectToServer() {
  client.stop();
  if (client.connect(server, 80)) {
    Serial.println("connecting...");
    // send the HTTP PUT request:
    client.println("GET /data/2.5/weather?q="+location+"&mode=xml&APPID=ece3f16628536ea9b95ea7adc2a5b595");
    client.println("HOST: api.openweathermap.org\n");
    client.println("User-Agent: ArduinoWiFi/1.1");
    client.println("Connection: close");
    client.println();
  }
  else {
    Serial.println("connection failed");
    errorLED();         //서버에 연결하지 못했다면 빨간빛 dimming
  }
}

//Wi-Fi data 출력
void printWifiData() {
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // Wi-Fi 쉴드 IP 주소 출력
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // 수신 신호 강도 출력
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

//정수 변환을 위한 함수
int getInt(String input){ 
  int i = 2;
  while(input[i] != '"'){
    i++;
  }
  input = input.substring(2,i);
  char carray[20];
  input.toCharArray(carray, sizeof(carray));
  temp = atoi(carray);
  return temp;
}


//LED 패턴 함수 
//clear and sunny, 무지개빛 출력
void clearweatherLED() {
  uint16_t i, j;
  for(j=0; j<256; j++) {
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
    }
    strip.show();
    delay(20);
  }
}


//cloudy and mist, 흰색빛으로 dimming
void cloudyMistLED(){
 uint16_t i, j;
  for(int k=0; k<3; k++){
    for(j=0; j<256; j++) {
      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(8);
    }
  }
}

//rainny and thunder, 노란색 빛으로 dimming후 blink
void rainnyLED(){
 uint16_t i, j;
  for(int k=0; k<2; k++){
    for(j=0; j<256; j++) {
      for(i=0; i<strip.numPixels(); i++) {
        int sum = i+j;
        map(sum,0,300,120,190);
       strip.setPixelColor(i, Wheel(sum),Wheel(sum),0);  
      }
      strip.show();
      delay(7);
    }
  }
  theaterChase(strip.Color(255, 255, 0), 40);
}

//snow, 흰색으로 theaterChase
void snowLED(){
  for (int j=0; j<7; j++) {  //do 10 cycles of chasing
    for (int q=0; q < 3; q++) {
      for (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, strip.Color(255, 255, 255));    //turn every third pixel on
        delay(30);
      }
      strip.show();     
      delay(30);     
      for (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
}

//connect error, 빨간색 빛으로 dimming
void errorLED(){
 uint16_t i, j;
  for(int k=0; k<3; k++){
    for(j=0; j<256; j++) {
      for(i=0; i<strip.numPixels(); i++) {
        int sum = i+j;
        map(sum,0,300,120,190);
       strip.setPixelColor(i, Wheel(sum),0,0);
      }
      strip.show();
      delay(2);
    }
  }
}

//ready, 녹색 빛으로 dimming
void readyLED(){
   uint16_t i, j;
    for(j=0; j<256; j++) {
      for(i=0; i<strip.numPixels(); i++) {
        int sum = i+j;
        map(sum,0,300,120,190);
       strip.setPixelColor(i, 0,Wheel(sum),0);
      }
      strip.show();
      delay(8);
    }
}


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);
  }
}

void theaterChase(uint32_t c, uint8_t wait) {
  for (int j=0; j<10; j++) {  //do 10 cycles of chasing
    for (int q=0; q < 3; q++) {
      for (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, c);    //turn every third pixel on
      }
      strip.show();
     
      delay(wait);
     
      for (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
}

이전글   |    안녕하세요 현재 개발중인 도어락에 관하여 질문할게 있습니다 ... 2016-06-30
다음글   |    질문입니다!!!! 2016-07-06