kohacraft Lab
/
kc_tenkiyoho_LED3
Tenki yoho LED kit2
Embed:
(wiki syntax)
Show/hide line numbers
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 }
Generated on Sat Jul 16 2022 15:49:45 by 1.7.2