Tenki yoho LED kit2

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include <string.h>
00003 
00004 Serial wifi(dp16, dp15); // ESP-WROOM-02 tx, rx 
00005 DigitalOut wifiRst(dp17); // /ESP-WROOM-02 RESET
00006 
00007 DigitalOut sunny(dp1);    //dp1を晴れのLEDにつなぎます
00008 DigitalOut cloudy(dp2);  //dp2を曇りのLEDにつなぎます
00009 DigitalOut rainy(dp4);  //dp4を雨のLEDにつなぎます
00010 DigitalOut snowy(dp6);  //dp6を雪のLEDににつなぎます
00011 
00012 #define baudrate 115200
00013 
00014 static char rxbuff[1000];   //ネットから取得するデータの格納場所
00015 int buffAdr = 0;
00016 const char SSID[] = "your SSDI";  //アクセスポイントのSSID
00017 const char PASS[] = "password";    //アクセスポイントのパスワード
00018 const char ZIP[] = "100-0000"; //天気予報を調べる郵便番号(半角XXX-XXXX形式)
00019 const char CITY[] = "";         //天気予報を調べる地名(郵便番号か地名どちらかを設定すればOK)
00020 const char APIKEY[] = "apiKey";  //OpenWeatherMapのAPI Key
00021 
00022 //データを受信する(1秒くらいは受信する)
00023 bool recvData(int throwDataSize)
00024 {
00025     bool ret = false;
00026     buffAdr = 0;
00027     rxbuff[0] = '\0';
00028         
00029     int headerCount = 0;
00030      
00031     //700000回ループしたらタイムアウトする(約1秒)
00032     for( int i = 0; i < 700000 ; i++ )
00033     {
00034         if( wifi.readable() != 0 )
00035         {
00036             rxbuff[buffAdr++] = wifi.getc(); //Serial.getc()
00037             headerCount++;
00038             if( headerCount <= throwDataSize )   //最初のthrowDataSize文字捨てる
00039                 buffAdr=0;
00040             if( buffAdr >= sizeof(rxbuff)-1 )   //バッファ溢れしたら終了
00041             {
00042                 ret = true;
00043                 i=700000;  //loopを早く終わらすために
00044                 break;
00045             }
00046 
00047         }
00048     }
00049     
00050     //文字列の最後を終端
00051     buffAdr = '\0';
00052     rxbuff[sizeof(rxbuff)-1] = '\0';
00053     return ret;
00054 } 
00055 
00056 //文字列から予報天気を抽出
00057 bool getWeather( char* str , int* weatherCord , float* tempLow , float* tempHi )
00058 {
00059         //文字列探索
00060     char *forecast;
00061     if ( (forecast = strstr(str, "cod\":\"200\"") ) == NULL )
00062     {
00063         //取得できず
00064         weatherCord = 0;
00065         tempLow = 0;
00066         tempLow = 0;
00067         return false;
00068     }
00069     
00070     //最低気温を抽出
00071     char *lowStart,*lowEnd;
00072     lowStart = strstr(forecast, "temp_min\":");
00073     lowStart = strchr( lowStart , ':' );
00074     lowStart++; //"の次の文字のポインタ
00075     lowEnd = strchr( lowStart , ',' );
00076     *lowEnd = '\0';
00077     *tempLow =  atof( lowStart );    //最低気温を数字に変換
00078     //wifi.printf("Start:%d End:%d Low Temp is %s\n",lowStart,lowEnd,lowStart);
00079 
00080     //最高気温を抽出
00081     char *hiStart,*hiEnd;
00082     hiStart = strstr(lowEnd+1, "temp_max\":");
00083     hiStart = strchr( hiStart , ':' );
00084     hiStart++; //"の次の文字のポインタ
00085     hiEnd = strchr( hiStart , ',' );
00086     *hiEnd = '\0';
00087     *tempHi =  atof( hiStart );    //最高気温を数字に変換
00088     //wifi.printf("Start:%d End:%d Hi Temp is %s\n",hiStart,hiEnd,hiStart);
00089   
00090     //天気コードを抽出
00091     char *codeStart,*codeEnd;
00092     codeStart = strstr(hiEnd+1, "{\"id\":");
00093     codeStart = strchr( codeStart , ':' );
00094     codeStart++; //"の次の文字のポインタ
00095     codeEnd = strchr( codeStart , ',' );
00096     *codeEnd = '\0';
00097     *weatherCord =  atoi( codeStart );    //最高気温を数字に変換
00098     //wifi.printf("Start:%d End:%d Code is %s\n",codeStart,codeEnd,codeStart);
00099     
00100     //天気を抽出
00101     char *textStart,*textEnd;
00102     char weatherText[32];
00103     textStart = strstr(codeEnd+1, "description\":");
00104     textStart = strchr( textStart+13 , '\"' );
00105     textStart++; //"の次の文字のポインタ
00106     textEnd = strchr( textStart , '\"' );
00107     *textEnd = '\0';
00108     strncpy( weatherText, textStart , 32);
00109     //wifi.printf("Start:%d End:%d Code is %s\n",textStart,textEnd,textStart);
00110     
00111     return true;
00112 }
00113 
00114 //LEDを順番に光らせる
00115 void ledIlluminationWait()
00116 {
00117     snowy = 0;
00118     sunny = 1;
00119     wait(0.5);
00120     
00121     sunny = 0;
00122     cloudy = 1;
00123     wait(0.5);
00124     
00125     cloudy = 0;
00126     rainy = 1;
00127     wait(0.5);
00128     
00129     rainy = 0;
00130     snowy = 1;
00131     wait(0.5);
00132 
00133 }
00134 
00135 
00136 //OKの文字列を受信するまで待つ timeが0なら永久に待つ
00137 //time*1[秒]待つ (time=10は10秒待つ)
00138 bool waitOk(int time)
00139 {
00140     bool ret = false;
00141     int addNumber = 1;
00142     if( time == 0 )
00143     {
00144         addNumber = 0;
00145         time = 1;
00146     }
00147     for( int i = 0 ; i<time ; i+=addNumber )
00148     {
00149         recvData(0);
00150         if( strstr(rxbuff, "OK") != NULL )
00151         {
00152             ret = true;
00153             break;
00154         }
00155     }
00156     return ret;
00157 }
00158 
00159 int main() {
00160 
00161     //天気情報
00162     bool sun = 0;
00163     bool rain = 0;
00164     bool cloud = 0;
00165     bool snow = 0;
00166     
00167     wifi.baud(baudrate);    //ビットレートを設定
00168 
00169     while(1)
00170     {
00171         //無線LANモジュールをリセット
00172         wifiRst = 0;
00173         wait_ms(100);
00174         wifiRst = 1;
00175         
00176         //無線LANモジュールが安定するのを待つ
00177         ledIlluminationWait();
00178         ledIlluminationWait();
00179         ledIlluminationWait();
00180         ledIlluminationWait();
00181         ledIlluminationWait();
00182         
00183         //最初にlanモジュールから出力される文字列を捨てる
00184         char temp;
00185         while( wifi.readable() == true )
00186              temp = wifi.getc();
00187              temp = temp++;
00188         
00189         //ATコマンドで無線LANモジュールをクライアントモードにする
00190         sunny = 1; cloudy = 1; rainy = 0; snowy = 0; //晴れと曇りが光っぱなしの場合はwifiジュールと通信できていない
00191         wifi.printf("AT\r\n");    
00192         waitOk(0);
00193 
00194         wifi.printf("AT+CWMODE=1\r\n");
00195         waitOk(0);
00196 
00197         //アクセスポイントに接続
00198         sunny = 0; cloudy = 0; rainy = 1; snowy = 1; //雨と雪が光っぱなしの場合はアクセスポイントにつながらない
00199         wifi.printf("AT+CWJAP=\"%s\",\"%s\"\r\n",SSID,PASS);
00200         waitOk(0);
00201 
00202         while(1)
00203         {
00204             //LEDを消灯
00205             sunny = 0; cloudy = 0; rainy = 0; snowy = 0; //全てが消え続ける場合はサーバーにつながらない
00206 
00207             //サーバに接続
00208             wifi.printf("AT+CIPSTART=\"TCP\",\"api.openweathermap.org\",80\r\n");
00209            if( waitOk(3600) == false )
00210                 break;  //1時間待っても返事が無ければ最初からやり直し
00211          
00212             //サーバに天気データを要求
00213             char str[250];
00214             if( sizeof(CITY) <= 1 )
00215                 //郵便番号で天気を検索
00216                 sprintf(str , "GET http://api.openweathermap.org/data/2.5/forecast?&zip=%s,JP&units=metric&cnt=1&appid=%s\r\nHost:api.openweathermap.org\r\nConnection:close\r\n\r\n",ZIP,APIKEY);
00217             else
00218                 //地名で天気予報を検索
00219                 sprintf(str , "GET http://api.openweathermap.org/data/2.5/forecast?&q=%s,JP&units=metric&cnt=1&appid=%s\r\nHost:api.openweathermap.org\r\nConnection:close\r\n\r\n",CITY,APIKEY);
00220             
00221             wifi.printf("AT+CIPSEND=%d\r\n",strlen(str));
00222             if( waitOk(3600) == false )
00223                 break;  //1時間待っても返事が無ければ最初からやり直し
00224         
00225             wifi.printf("%s",str);
00226             recvData(1); //データの受信(最初の1500文字を捨てる)
00227             
00228             //*** デバッグ用 *** バッファの内容を出力
00229             //wait(1);
00230             //wifi.printf("%s\r\n",rxbuff);   
00231         
00232             //文字列探索
00233             int weatherCord;
00234             float tempHi , tempLow;
00235             if( getWeather( rxbuff , &weatherCord , &tempLow , &tempHi ) == false ) //データの受信
00236             {
00237                 //予報の文字列がない
00238                 wait(30);
00239                 break;  //30秒待って最初からやり直す
00240             }
00241             
00242             //*** ↓デバッグ用 *** 受信したデータから抽出した天気情報を出力 
00243             //wifi.printf("weatherCord:%d tempLow:%f tempHi:%f\r\n",weatherCord , tempLow , tempHi);
00244         
00245        
00246             //天気コードから天気をLEDの色に変換する
00247  
00248             if( weatherCord < 600 ){ //雨
00249                 sun = 0;
00250                 rain = 1;
00251                 cloud = 0;
00252                 snow = 0;                
00253             }else if( weatherCord < 700 ){  //雪
00254                 sun = 0;
00255                 rain = 0;
00256                 cloud = 0;
00257                 snow = 1;                
00258             }else  if( weatherCord < 800 ){ //曇り
00259                 sun = 0;
00260                 rain = 0;
00261                 cloud = 1;
00262                 snow = 0;                
00263             }else if( weatherCord <= 802 ){ //晴れ
00264                 sun = 1;
00265                 rain = 0;
00266                 cloud = 0;
00267                 snow = 0;                
00268             }else{  //曇り
00269                 sun = 0;
00270                 rain = 0;
00271                 cloud = 1;
00272                 snow = 0;                
00273             }
00274             
00275             //LEDを点滅させながら30分待つ
00276             for(int i=0 ; i<30*60 ; i++)
00277             {
00278                 //LEDを点灯
00279                 sunny = sun;
00280                 rainy = rain;
00281                 cloudy = cloud;
00282                 snowy = snow;
00283                 wait(0.5);
00284                     
00285                 //LEDを消灯
00286                 sunny = 0;
00287                 rainy = 0;
00288                 cloudy = 0;
00289                 snowy = 0;
00290                 wait(0.5);
00291             }
00292         }
00293     }
00294 }