kohacraft Lab
/
kc_tenkiyoho_LED3
Tenki yoho LED kit2
main.cpp
- Committer:
- kohacraft
- Date:
- 2019-06-08
- Revision:
- 3:40e16b6da0ea
- Parent:
- 2:4ae4d4564c44
File content as of revision 3:40e16b6da0ea:
#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[1000]; //ネットから取得するデータの格納場所 int buffAdr = 0; const char SSID[] = "your SSDI"; //アクセスポイントのSSID const char PASS[] = "password"; //アクセスポイントのパスワード const char ZIP[] = "100-0000"; //天気予報を調べる郵便番号(半角XXX-XXXX形式) const char CITY[] = ""; //天気予報を調べる地名(郵便番号か地名どちらかを設定すればOK) const char APIKEY[] = "apiKey"; //OpenWeatherMapのAPI Key //データを受信する(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 , float* tempLow , float* tempHi ) { //文字列探索 char *forecast; if ( (forecast = strstr(str, "cod\":\"200\"") ) == NULL ) { //取得できず weatherCord = 0; tempLow = 0; tempLow = 0; return false; } //最低気温を抽出 char *lowStart,*lowEnd; lowStart = strstr(forecast, "temp_min\":"); lowStart = strchr( lowStart , ':' ); lowStart++; //"の次の文字のポインタ lowEnd = strchr( lowStart , ',' ); *lowEnd = '\0'; *tempLow = atof( lowStart ); //最低気温を数字に変換 //wifi.printf("Start:%d End:%d Low Temp is %s\n",lowStart,lowEnd,lowStart); //最高気温を抽出 char *hiStart,*hiEnd; hiStart = strstr(lowEnd+1, "temp_max\":"); hiStart = strchr( hiStart , ':' ); hiStart++; //"の次の文字のポインタ hiEnd = strchr( hiStart , ',' ); *hiEnd = '\0'; *tempHi = atof( hiStart ); //最高気温を数字に変換 //wifi.printf("Start:%d End:%d Hi Temp is %s\n",hiStart,hiEnd,hiStart); //天気コードを抽出 char *codeStart,*codeEnd; codeStart = strstr(hiEnd+1, "{\"id\":"); codeStart = strchr( codeStart , ':' ); codeStart++; //"の次の文字のポインタ codeEnd = strchr( codeStart , ',' ); *codeEnd = '\0'; *weatherCord = atoi( codeStart ); //最高気温を数字に変換 //wifi.printf("Start:%d End:%d Code is %s\n",codeStart,codeEnd,codeStart); //天気を抽出 char *textStart,*textEnd; char weatherText[32]; textStart = strstr(codeEnd+1, "description\":"); textStart = strchr( textStart+13 , '\"' ); textStart++; //"の次の文字のポインタ textEnd = strchr( textStart , '\"' ); *textEnd = '\0'; strncpy( weatherText, textStart , 32); //wifi.printf("Start:%d End:%d Code is %s\n",textStart,textEnd,textStart); 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() == true ) temp = wifi.getc(); temp = temp++; //ATコマンドで無線LANモジュールをクライアントモードにする sunny = 1; cloudy = 1; rainy = 0; snowy = 0; //晴れと曇りが光っぱなしの場合はwifiジュールと通信できていない wifi.printf("AT\r\n"); waitOk(0); wifi.printf("AT+CWMODE=1\r\n"); waitOk(0); //アクセスポイントに接続 sunny = 0; cloudy = 0; rainy = 1; snowy = 1; //雨と雪が光っぱなしの場合はアクセスポイントにつながらない 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\",\"api.openweathermap.org\",80\r\n"); if( waitOk(3600) == false ) break; //1時間待っても返事が無ければ最初からやり直し //サーバに天気データを要求 char str[250]; if( sizeof(CITY) <= 1 ) //郵便番号で天気を検索 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); else //地名で天気予報を検索 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); wifi.printf("AT+CIPSEND=%d\r\n",strlen(str)); if( waitOk(3600) == false ) break; //1時間待っても返事が無ければ最初からやり直し wifi.printf("%s",str); recvData(1); //データの受信(最初の1500文字を捨てる) //*** デバッグ用 *** バッファの内容を出力 //wait(1); //wifi.printf("%s\r\n",rxbuff); //文字列探索 int weatherCord; float tempHi , tempLow; if( getWeather( rxbuff , &weatherCord , &tempLow , &tempHi ) == false ) //データの受信 { //予報の文字列がない wait(30); break; //30秒待って最初からやり直す } //*** ↓デバッグ用 *** 受信したデータから抽出した天気情報を出力 //wifi.printf("weatherCord:%d tempLow:%f tempHi:%f\r\n",weatherCord , tempLow , tempHi); //天気コードから天気をLEDの色に変換する if( weatherCord < 600 ){ //雨 sun = 0; rain = 1; cloud = 0; snow = 0; }else if( weatherCord < 700 ){ //雪 sun = 0; rain = 0; cloud = 0; snow = 1; }else if( weatherCord < 800 ){ //曇り sun = 0; rain = 0; cloud = 1; snow = 0; }else if( weatherCord <= 802 ){ //晴れ sun = 1; rain = 0; cloud = 0; snow = 0; }else{ //曇り sun = 0; rain = 0; cloud = 1; snow = 0; } //LEDを点滅させながら30分待つ for(int i=0 ; i<30*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); } } } }