tenki yoho LED (with ESP-WROOM-02)

Dependencies:   mbed

main.cpp

Committer:
kohacraft
Date:
2016-05-04
Revision:
4:1c1fb59cf7d9
Parent:
3:5689bfb78c7b

File content as of revision 4:1c1fb59cf7d9:

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

Serial wifi(dp16, dp15); // ESP-WROOM-02 tx, rx 
DigitalOut wifiRst(dp17); // /ESP-WROOM-02 RESET
DigitalIn lightSensor(dp4); //loom light sensor(CdS:GL5528 conect to dp4 and GND)

PwmOut red(dp1);    //dp1を赤のLEDのPWM出力にします
PwmOut green(dp2);  //dp2を緑のLEDのPWM出力にします
PwmOut blue(dp18);  //dp18を青のLEDのPWM出力にします

#define baudrate 115200

static char rxbuff[1500];   //取得する文字列
int buffAdr = 0;

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

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

        }
    }
    
    //文字列の最後を終端
    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;
    //int weatherCord;
    codeStart = strstr(forecast, "code=");
    codeStart = strchr( codeStart , '\"' );
    codeStart++; //"の次の文字のポインタ
    codeEnd = strchr( codeStart , '\"' );
    *codeEnd = '\0';
    *weatherCord =  atoi( codeStart );    //最高気温を数字に変換
    
    //最高気温を抽出
    char *hiStart,*hiEnd;
    //int tempHi;
    hiStart = strstr(codeEnd+1, "high=");
    hiStart = strchr( hiStart , '\"' );
    hiStart++; //"の次の文字のポインタ
    hiEnd = strchr( hiStart , '\"' );
    *hiEnd = '\0';
    *tempHi =  atoi( hiStart );    //最高気温を数字に変換

    //最低気温を抽出
    char *lowStart,*lowEnd;
    //int tempLow;
    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;
}


int main() {

    //LEDのPWM周期
    red.period(5);
    green.period(5);
    blue.period(5);
    
    lightSensor.mode(PullUp);  //室内の明るさセンサをプルアップする
    wifi.baud(baudrate);    //ビットレートを設定

    while(1)
    {
        //無線LANモジュールをリセット
        wifiRst = 1;
        wifiRst = 0;
        wifiRst = 1;
        
        //無線LANモジュールが安定するのを待つ
        for( int i=0 ; i<10 ; i++ )
        {
            red = 0.9;  green = 1.0; blue = 0.0;
            wait( 0.5 );
            red = 0.0;  green = 0.0; blue = 0.0;
            wait( 0.5 );
        }
        
        //最初にlanモジュールから出力される文字列を捨てる
        char temp;
        while( wifi.readable() == 1 )
             temp = wifi.getc();
        
        //ATコマンドで無線LANモジュールをクライアントモードにする
        wifi.printf("AT\r\n");    
        wait(2);
        red = 0.9;  green = 1.0; blue = 0.0;
        wifi.printf("AT+CWMODE=1\r\n");
        wait(2);
        red = 0.6;  green = 0.8; blue = 0.3;
        //アクセスポイントに接続
        wifi.printf("AT+CWJAP=\"%s\",\"%s\"\r\n",SSID,PASS);
        red = 0.4;  green = 0.6; blue = 0.6;
        wait(3);
        red = 0.2;  green = 0.4; blue = 0.8;
        wait(3);
        red = 0.0;  green = 0.2; blue = 1.0;
    
    
        while(1)
        {
            //サーバに接続
            wifi.printf("AT+CIPSTART=\"TCP\",\"query.yahooapis.com\",80\r\n");
            wait(2);
         
            //サーバに要求
            char str[200];
            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));
            wait(1);
        
            //受信
            wifi.printf("%s",str);
            recvData();              
            
            //切断
            wifi.printf("AT+CIPCLOSE\r\n");
            wifi.printf("%s\r\n",rxbuff);
        
            //文字列探索
            int weatherCord , tempHi , tempLow;
            if( getWeather( rxbuff , &weatherCord , &tempLow , &tempHi ) == false ) //データの受信
            {
                //予報の文字列がない
                wifi.printf("Can not find strng:forecast\r\n");
                for( int i=0 ; i<5 ; i++ )
                {
                    red = 1.0;
                    wait(0.25);
                    red = 0.0;
                    wait(0.25);
                }
                break;  //最初からやり直す
            }
            wifi.printf("weatherCord:%d tempLow:%d tempHi:%d\r\n",weatherCord , tempLow , tempHi);
       
            //天気をLEDの色に変換する
            float rStart , gStart , bStart , rEnd , gEnd , bEnd;
            switch(weatherCord)
            {
                //雨
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                case 6:
                case 11:
                case 12:
                case 17:
                case 18:
                case 35:
                case 37:
                case 38:
                case 39:
                case 40:
                case 45:
                case 47:
                    rStart = 0.0;   gStart = 0.0;   bStart = 1.0;
                    rEnd = 0.0;     gEnd = 0.3;     bEnd = 0.8;
                    break;
                    
                //雪
                case 7:
                case 8:
                case 9:
                case 10:
                case 13:
                case 14:
                case 15:
                case 16:
                case 23:
                case 41:
                case 42:
                case 43:
                case 46:
                    rStart = 1.0;   gStart = 0.8;   bStart = 0.8;
                    rEnd = 0.8;     gEnd = 0.6;     bEnd = 0.6;
                    break;
               
                //曇り 
                case 19:
                case 20:
                case 22:
                case 26:
                case 27:
                case 28:
                case 44:
                    rStart = 0.6;   gStart = 0.4;   bStart = 0.4;
                    rEnd = 0.25;     gEnd = 0.2;     bEnd = 0.15;
                    break;
                
                //晴れ
                case 21:
                case 24:
                case 25:
                case 29:
                case 30:
                case 31:
                case 32:
                case 33:
                case 34:
                case 36:
                    rStart = 1.0;   gStart = 0.5;   bStart = 0.0;
                    rEnd = 1.0;     gEnd = 0.3;     bEnd = 0.2;
                    break;
                
                default:
                    rStart = 0.0;   gStart = 0.0;   bStart = 0.0;
                    rEnd = 1.0;     gEnd = 0.0;     bEnd = 1.0;
                    break;
            }
                    
            for(int j=0 ; j<30*60/2 ; j++)  //30分ループし続ける
            {
                //startの色からendの色へと1秒かけて色を変化させる
                for( float i=0 ; i<100 ; i++ )
                {
                    red = rStart + (rEnd-rStart)*i/100.0;
                    green = gStart + (gEnd-gStart)*i/100.0;
                    blue = bStart + (bEnd-bStart)*i/100.0;
                    if( lightSensor != 0 )
                    {
                        red = red*0.1; green = green*0.1; blue = blue*0.1;
                    }
                    wait(0.01);
                }
                //endの色からstartの色へと1秒かけて色を変化させる
                for( float i=0 ; i<100 ; i++ )
                {
                    red = rEnd + (rStart-rEnd)*i/100.0;
                    green = gEnd + (gStart-gEnd)*i/100.0;
                    blue = bEnd + (bStart-bEnd)*i/100.0;
                    if( lightSensor != 0 )
                    {
                        red = red*0.1; green = green*0.1; blue = blue*0.1;
                    }
                    wait(0.01);
                }
            }
        }
    }
}