Tenki yoho LED kit2

Dependencies:   mbed

main.cpp

Committer:
kohacraft
Date:
2016-05-17
Revision:
0:82aac34e1141
Child:
1:1c83ef47372a

File content as of revision 0:82aac34e1141:

#include "mbed.h"
#include <string.h>

Serial wifi(dp16, dp15); // ESP-WROOM-02 tx, rx 
DigitalOut wifiRst(dp17); // /ESP-WROOM-02 RESET

DigitalOut sunny(dp1);    //dp1を晴れのLEDにつなぎます
DigitalOut cloudy(dp2);  //dp2を曇りのLEDにつなぎます
DigitalOut rainy(dp4);  //dp4を雨のLEDにつなぎます
DigitalOut snowy(dp6);  //dp6を雪のLEDににつなぎます

#define baudrate 115200

static char rxbuff[1500];   //ネットから取得するデータの格納場所
int buffAdr = 0;

const char SSID[] = "your SSDI";  //アクセスポイントのSSID
const char PASS[] = "password";    //アクセスポイントのパスワード
const char WOEID[] = "1118370";    //天気を調べる場所 http://woeid.rosselliot.co.nz/ で郵便番号で検索して得られる番号

//データを受信する(1秒くらいは受信する)
bool recvData(int throwDataSize)
{
    bool ret = false;
    buffAdr = 0;
    rxbuff[0] = '\0';
        
    int headerCount = 0;
     
    //700000回ループしたらタイムアウトする(約1秒)
    for( int i = 0; i < 700000 ; i++ )
    {
        if( wifi.readable() != 0 )
        {
            rxbuff[buffAdr++] = wifi.getc(); //Serial.getc()
            headerCount++;
            if( headerCount <= throwDataSize )   //最初のthrowDataSize文字捨てる
                buffAdr=0;
            if( buffAdr >= sizeof(rxbuff)-1 )   //バッファ溢れしたら終了
            {
                ret = true;
                i=700000;  //loopを早く終わらすために
                break;
            }

        }
    }
    
    //文字列の最後を終端
    buffAdr = '\0';
    rxbuff[sizeof(rxbuff)-1] = '\0';
    return ret;
} 

//文字列から予報天気を抽出
bool getWeather( char* str , int* weatherCord , int* tempLow , int* tempHi )
{
        //文字列探索
    char *forecast;
    if ( (forecast = strstr(str, "yweather:forecast") ) == NULL )
    {
        //取得できず
        weatherCord = 0;
        tempLow = 0;
        tempLow = 0;
        return false;
    }
    
    //天気コードを抽出
    char *codeStart,*codeEnd;
    codeStart = strstr(forecast, "code=");
    codeStart = strchr( codeStart , '\"' );
    codeStart++; //"の次の文字のポインタ
    codeEnd = strchr( codeStart , '\"' );
    *codeEnd = '\0';
    *weatherCord =  atoi( codeStart );    //最高気温を数字に変換
    
    //最高気温を抽出
    char *hiStart,*hiEnd;
    hiStart = strstr(codeEnd+1, "high=");
    hiStart = strchr( hiStart , '\"' );
    hiStart++; //"の次の文字のポインタ
    hiEnd = strchr( hiStart , '\"' );
    *hiEnd = '\0';
    *tempHi =  atoi( hiStart );    //最高気温を数字に変換

    //最低気温を抽出
    char *lowStart,*lowEnd;
    lowStart = strstr(hiEnd+1, "low=");
    lowStart = strchr( lowStart , '\"' );
    lowStart++; //"の次の文字のポインタ
    lowEnd = strchr( lowStart , '\"' );
    *lowEnd = '\0';
    *tempLow =  atoi( lowStart );    //最低気温を数字に変換
  
    //天気を抽出
    char *textStart,*textEnd;
    char weatherText[32];
    textStart = strstr(lowEnd+1, "text=");
    textStart = strchr( textStart , '\"' );
    textStart++; //"の次の文字のポインタ
    textEnd = strchr( textStart , '\"' );
    *textEnd = '\0';
    strncpy( weatherText, textStart , 32);
    
    return true;
}

//LEDを順番に光らせる
void ledIlluminationWait()
{
    snowy = 0;
    sunny = 1;
    wait(0.5);
    
    sunny = 0;
    cloudy = 1;
    wait(0.5);
    
    cloudy = 0;
    rainy = 1;
    wait(0.5);
    
    rainy = 0;
    snowy = 1;
    wait(0.5);

}


//OKの文字列を受信するまで待つ timeが0なら永久に待つ
//time*1[秒]待つ (time=10は10秒待つ)
bool waitOk(int time)
{
    bool ret = false;
    int addNumber = 1;
    if( time == 0 )
    {
        addNumber = 0;
        time = 1;
    }
    for( int i = 0 ; i<time ; i+=addNumber )
    {
        recvData(0);
        if( strstr(rxbuff, "OK") != NULL )
        {
            ret = true;
            break;
        }
    }
    return ret;
}

int main() {

    //天気情報
    bool sun = 0;
    bool rain = 0;
    bool cloud = 0;
    bool snow = 0;
    
    wifi.baud(baudrate);    //ビットレートを設定

    while(1)
    {
        //無線LANモジュールをリセット
        wifiRst = 0;
        wait_ms(100);
        wifiRst = 1;
        
        //無線LANモジュールが安定するのを待つ
        ledIlluminationWait();
        ledIlluminationWait();
        ledIlluminationWait();
        ledIlluminationWait();
        ledIlluminationWait();
        
        //最初にlanモジュールから出力される文字列を捨てる
        char temp;
        while( wifi.readable() == 1 )
             temp = wifi.getc();
        
        //ATコマンドで無線LANモジュールをクライアントモードにする
        sunny = 1; cloudy = 0; rainy = 0; snowy = 0; //晴れが光っぱなしの場合はwifiジュールと通信できていない
        wifi.printf("AT\r\n");    
        waitOk(0);

        sunny = 0; cloudy = 1; rainy = 0; snowy = 0;
        wifi.printf("AT+CWMODE=1\r\n");
        waitOk(0);

        //アクセスポイントに接続
        sunny = 0; cloudy = 0; rainy = 1; snowy = 0; //雨が光っぱなしの場合はアクセスポイントにつながらない
        wifi.printf("AT+CWJAP=\"%s\",\"%s\"\r\n",SSID,PASS);
        waitOk(0);

        while(1)
        {
            //LEDを消灯
            sunny = 0; cloudy = 0; rainy = 0; snowy = 0; //全てが消え続ける場合はサーバーにつながらない

            //サーバに接続
            wifi.printf("AT+CIPSTART=\"TCP\",\"query.yahooapis.com\",80\r\n");
            if( waitOk(3600) == false )
                break;  //1時間待っても返事が無ければ最初からやり直し
         
            //サーバに天気データを要求
            char str[250];
            sprintf(str , "GET http://query.yahooapis.com/v1/public/yql?q=SELECT%%20*%%20FROM%%20weather.forecast%%20WHERE%%20woeid%%3D%%22%s%%22%20and%%20u%%3D%%22c%%22\r\nHost: query.yahooapis.com\r\nConnection: close\r\n\r\n\r\n",WOEID);
            wifi.printf("AT+CIPSEND=%d\r\n",strlen(str));
            if( waitOk(3600) == false )
                break;  //1時間待っても返事が無ければ最初からやり直し
        
            wifi.printf("%s",str);
            recvData(1500); //データの受信(最初の1500文字を捨てる)
            //wifi.printf("%s\r\n",rxbuff);   //*** デバッグ用 *** バッファの内容を出力
        
            //文字列探索
            sunny = 0; cloudy = 0; rainy = 0; snowy = 1; //雪が光っぱなしの場合は天気情報が得られてない
            int weatherCord , tempHi , tempLow;
            if( getWeather( rxbuff , &weatherCord , &tempLow , &tempHi ) == false ) //データの受信
            {
                //予報の文字列がない
                wait(30);
                break;  //30秒待って最初からやり直す
            }
            
            //*** ↓デバッグ用 *** 受信した天気情報を出力 
            //wifi.printf("weatherCord:%d tempLow:%d tempHi:%d\r\n",weatherCord , tempLow , tempHi);
        
       
            //天気をLEDの色に変換する
            switch(weatherCord)
            {
                //晴れ
                case 24:
                case 25:
                case 31:
                case 32:
                case 36:
                case 29:
                case 30:
                case 33:
                case 34:
                case 44:
                    sun = 1;
                    rain = 0;
                    cloud = 0;
                    snow = 0;                
                    break;
                
                //曇り
                case 19:
                case 21:
                case 22:
                case 23:
                case 26:
                case 27:
                case 28:
                    sun = 0;
                    rain = 0;
                    cloud = 1;
                    snow = 0;                
                    break;

                //雨
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                case 6:
                case 12:
                case 17:
                case 38:
                case 39:
                case 40:
                case 45:
                case 47:
                case 5:
                case 10:
                case 18:
                case 35:
                case 9:
                case 11:
                case 20:
                case 37:
                    sun = 0;
                    rain = 1;
                    cloud = 0;
                    snow = 0;                
                    break;
                                
                //雪
                case 7:
                case 8:
                case 13:
                case 14:
                case 15:
                case 16:
                case 41:
                case 42:
                case 43:
                case 46:
                    sun = 0;
                    rain = 0;
                    cloud = 0;
                    snow = 1;                
                    break;
                                
                
            }
            
            //LEDを点滅させながら1時間待つ
            for(int i=0 ; i<60*60 ; i++)
            {
                //LEDを点灯
                sunny = sun;
                rainy = rain;
                cloudy = cloud;
                snowy = snow;
                wait(0.5);
                    
                //LEDを消灯
                sunny = 0;
                rainy = 0;
                cloudy = 0;
                snowy = 0;
                wait(0.5);
            }
        }
    }
}

/* weather Cords
0   tornado
1   tropical storm
2   hurricane
3   severe thunderstorms
4   thunderstorms
5   mixed rain and snow
6   mixed rain and sleet
7   mixed snow and sleet
8   freezing drizzle
9   drizzle
10  freezing rain
11  showers
12  showers
13  snow flurries
14  light snow showers
15  blowing snow
16  snow
17  hail
18  sleet
19  dust
20  foggy
21  haze
22  smoky
23  blustery
24  windy
25  cold
26  cloudy
27  mostly cloudy (night)
28  mostly cloudy (day)
29  partly cloudy (night)
30  partly cloudy (day)
31  clear (night)
32  sunny
33  fair (night)
34  fair (day)
35  mixed rain and hail
36  hot
37  isolated thunderstorms
38  scattered thunderstorms
39  scattered thunderstorms
40  scattered showers
41  heavy snow
42  scattered snow showers
43  heavy snow
44  partly cloudy
45  thundershowers
46  snow showers
47  isolated thundershowers
*/