// ESP12-wm10-ver1 //風向風速計 v1.0 2023/08/25 #include #include #define ESP8266_USE_SOFTWARE_SERIAL #define WM10_RX D7 // GPIO13 (RXD2) <---> conect to TX pin of WM10 #define WM10_TX D8 // GPIO15 (TXD2) <---> conect to RX pin of WM10 //////define wm10 SoftSerial wmSerial ////////////// SoftwareSerial wmSerial(WM10_RX,WM10_TX); // Aterm Wp1800 @ iida #ifndef STASSID #define STASSID "*********-g" #define STAPSK "********62" #endif const char* ssid = STASSID; const char* password = STAPSK; const char* host = "********.ne.jp"; //Averaging counter unsigned int AvrCounter = 0; float AvrTemperature = 0; float AvrWindSpeed = 0; float AvrWindAngle = 0; float WindAngleX = 0; float WindAngleY = 0; float WindAngle ; float WindSpeed ; float MaxWindSpeed = 0; float MaxWindAngle = 0; /*********************************************** split string with delimiter int = split(, , , ) ; */ int split(String data, char delimiter, String *dst, int arraySize) { // clear the array for (int i = 0; i < arraySize; i++) { dst[i] = "\0" ; } int index = 0; int datalength = data.length(); for (int i = 0; i < datalength; i++) { char tmp = data.charAt(i); if ( tmp == delimiter ) { index++; if ( index > (arraySize - 1)) return -1; } else dst[index] += tmp; } return (index + 1); } void CalcWindAngle (float WindAngle) { //Convert degree angle to 16 cardinal direction String str ; if ( WindAngle > 11.25 * 1 && WindAngle <= 11.25 * 3 ) { str = "NNE" ;WindAngleX=0.33;WindAngleY=0.86;} if ( WindAngle > 11.25 * 3 && WindAngle <= 11.25 * 5 ) { str = " NE" ;WindAngleX=0.66;WindAngleY=0.66;} if ( WindAngle > 11.25 * 5 && WindAngle <= 11.25 * 7 ) { str = "ENE" ;WindAngleX=0.86;WindAngleY=0.33;} if ( WindAngle > 11.25 * 7 && WindAngle <= 11.25 * 9 ) { str = " E" ;WindAngleX=1.0;WindAngleY=0.0;} if ( WindAngle > 11.25 * 9 && WindAngle <= 11.25 * 11 ) { str = "ESE" ;WindAngleX=0.86;WindAngleY=-0.33;} if ( WindAngle > 11.25 * 11 && WindAngle <= 11.25 * 13 ) { str = " SE" ;WindAngleX=0.66;WindAngleY=-0.66;} if ( WindAngle > 11.25 * 13 && WindAngle <= 11.25 * 15 ) { str = "SSE" ;WindAngleX=0.33;WindAngleY=-0.86;} if ( WindAngle > 11.25 * 15 && WindAngle <= 11.25 * 17 ) { str = " S" ;WindAngleX=0.0;WindAngleY=-1.0;} if ( WindAngle > 11.25 * 17 && WindAngle <= 11.25 * 19 ) { str = "SSW" ;WindAngleX=-0.33;WindAngleY=-0.86;} if ( WindAngle > 11.25 * 19 && WindAngle <= 11.25 * 21 ) { str = " SW" ;WindAngleX=-0.66;WindAngleY=-0.66;} if ( WindAngle > 11.25 * 21 && WindAngle <= 11.25 * 23 ) { str = "WSW" ;WindAngleX=-0.86;WindAngleY=-0.33;} if ( WindAngle > 11.25 * 23 && WindAngle <= 11.25 * 25 ) { str = " W" ;WindAngleX=-1.0;WindAngleY=0.0;} if ( WindAngle > 11.25 * 25 && WindAngle <= 11.25 * 27 ) { str = "WNW" ;WindAngleX=-0.86;WindAngleY=0.33;} if ( WindAngle > 11.25 * 27 && WindAngle <= 11.25 * 29 ) { str = " NW" ;WindAngleX=-0.66;WindAngleY=0.66;} if ( WindAngle > 11.25 * 29 && WindAngle <= 11.25 * 31 ) { str = "NNW" ;WindAngleX=-0.33;WindAngleY=0.86;} if ( WindAngle > 11.25 * 31 || WindAngle <= 11.25 * 1 ) { str = " N" ;WindAngleX=0.0;WindAngleY=1.0;} //Serial.print(str) ; //Serial.printf(" 風向:%3.0f° X=% 1.2f Y=% 1.2f ",WindAngle,WindAngleX,WindAngleY); } String Direction ; void ShowWind (float WindAngle) { //Convert degree angle to 16 cardinal direction if ( WindAngle > 11.25 * 1 && WindAngle <= 11.25 * 3 ) { Direction = "NNE" ;} if ( WindAngle > 11.25 * 3 && WindAngle <= 11.25 * 5 ) { Direction = "NE" ;} if ( WindAngle > 11.25 * 5 && WindAngle <= 11.25 * 7 ) { Direction = "ENE" ;} if ( WindAngle > 11.25 * 7 && WindAngle <= 11.25 * 9 ) { Direction = "E" ;} if ( WindAngle > 11.25 * 9 && WindAngle <= 11.25 * 11 ) { Direction = "ESE" ;} if ( WindAngle > 11.25 * 11 && WindAngle <= 11.25 * 13 ) { Direction = "SE" ;} if ( WindAngle > 11.25 * 13 && WindAngle <= 11.25 * 15 ) { Direction = "SSE" ;} if ( WindAngle > 11.25 * 15 && WindAngle <= 11.25 * 17 ) { Direction = "S" ;} if ( WindAngle > 11.25 * 17 && WindAngle <= 11.25 * 19 ) { Direction = "SSW" ;} if ( WindAngle > 11.25 * 19 && WindAngle <= 11.25 * 21 ) { Direction = "SW" ;} if ( WindAngle > 11.25 * 21 && WindAngle <= 11.25 * 23 ) { Direction = "WSW" ;} if ( WindAngle > 11.25 * 23 && WindAngle <= 11.25 * 25 ) { Direction = "W" ;} if ( WindAngle > 11.25 * 25 && WindAngle <= 11.25 * 27 ) { Direction = "WNW" ;} if ( WindAngle > 11.25 * 27 && WindAngle <= 11.25 * 29 ) { Direction = "NW" ;} if ( WindAngle > 11.25 * 29 && WindAngle <= 11.25 * 31 ) { Direction = "NNW" ;} if ( WindAngle > 11.25 * 31 || WindAngle <= 11.25 * 1 ) { Direction = "N" ;} } void setup() { // initialize both serial ports: Serial.begin(115200); delay(500); wmSerial.begin(9600); //wm10 シリアル受信用 delay(500); //////// connecting to a WiFi network //Serial.print("Program Name "); //Serial.println( program_name ); Serial.print("Connecting to "); Serial.println(ssid); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); Serial.println("Program Start"); } void loop(){ /******************************************************************************** * WM10 Transmission format(NMEA0183 compliant) * * 'c' represents single ascii character, 'd' represents decimal number and 'h' * represents one digit of hexadecimal code in capital letter. *------------------------------------------------------------------------------ * 1 2 3 4 5 6 * | | | | | | * $WIMWV,d,c,d.d,c,c*hh *------------------------------------------------------------------------------ * *1. Wind Angle, 0 to 359 degrees *2. Reference, R = Relative, T = True (fixed to R) *3. Wind Speed *4. Wind Speed Units, K/M/N (fixed to M) *5. Status, A = Data Valid, V = Data Invalid *6. Checksum *------------------------------------------------------------------------------ * 1 2 3 * | | | * $WIMTA,d.d,c*hh *------------------------------------------------------------------------------ * *1. Temperature *2. Units, C = Celsius (fixed to C) *3. Checksum */ //check serial //Serial.println("----------------"); //int var=0; //while(var<4){ if (wmSerial.available()) { //read 1 line from WM10 String str = wmSerial.readStringUntil('\n'); //discard CR code str.trim(); //Serial.println(str); String items[6] ; // array for store the divided strings split(str, ',', items, 6) ; if ( items[0].equals("$WIMTA") ) { //copy temperature to buffer /* String strtemp=items[1]; Serial.print("temperature: "); Serial.println(strtemp); */ float Temperature = items[1].toFloat(); Serial.printf("No:%2d 気温:%2.1f ℃ ",AvrCounter+1,Temperature); // temperature AvrTemperature += Temperature; } else if ( items[0].equals("$WIMWV") ) { String SubItems[2] ; split(items[5], '*', SubItems, 2) ; /* String str_windangle = items[1]; Serial.print("WindAngle(degree): "); Serial.println(str_windangle); String str_windspeed = items[3]; Serial.print("WindSpeed(m/s): "); Serial.println(str_windspeed); */ //If the status is "V"(invalid) then initialize averaging buffer. if ( SubItems[0].equals("V") ) { AvrCounter = 0; AvrWindSpeed = 0; } else { //convert wind speed and direction to floating value WindAngle = items[1].toFloat() ; WindSpeed = items[3].toFloat(); //Keep maximum wind speed and direction if ( WindSpeed > MaxWindSpeed ) { MaxWindSpeed = WindSpeed ; MaxWindAngle = WindAngle ; } //Show instantaneous wind direction and speed CalcWindAngle (WindAngle); // wind_direction,windangle Serial.printf(" 風速:%2.1f m/s\n",WindSpeed); // windspeed AvrWindAngle += WindAngle; AvrWindSpeed += WindSpeed; ShowWind (WindAngle); Serial.print("WindDirection: "); Serial.println(Direction); } AvrCounter++; } if ( AvrCounter >= 20 ) { //3秒サイクル x 20回 = 60秒毎 送信 Serial.println(); Serial.println("-------- 60sec --------"); float AvrTP=(AvrTemperature/20.0); Serial.printf("aveTemp(degC)= %2.1f",AvrTP); Serial.println(); float AvrWA= (AvrWindAngle/20.0); Serial.printf("aveAngle(degree)= %2.1f",AvrWA); Serial.println(); float AvrWS=(AvrWindSpeed/20.0); Serial.printf("aveWind(m/s)= %2.1f",AvrWS); Serial.println(); WindAngle=AvrWA; ShowWind (WindAngle); Serial.print("Ave_WindDirection: "); Serial.println(Direction); /// convert average float data to string data String ave_temp, ave_angle, ave_wind, ave_direction; ave_temp = String( AvrTP ); ave_angle = String( AvrWA ); ave_wind = String( AvrWS ); ave_direction = Direction; Serial.printf("Max Wind Speed = %2.1f",MaxWindSpeed); Serial.println(); Serial.printf("Max Wind Angle = %2.1f",MaxWindAngle); Serial.println(); WindAngle=MaxWindAngle; ShowWind (WindAngle); Serial.print("Max_WindDirection: "); Serial.println(Direction); /// convert maxe float data to string data String max_angle, max_wind, max_direction; max_angle = String( MaxWindAngle ); max_wind = String( MaxWindSpeed ); max_direction = Direction; Serial.println("-------- 60sec --------"); Serial.println(); ////////////////////////////////////////////////////////////////////// /// wifi connect & HTTP GET action execute Serial.print("connecting to "); Serial.println(host); ///////connect to sakura ////////////////// // Use WiFiClient class to create TCP connections WiFiClient client; const int httpPort = 80; if (!client.connect(host, httpPort)) { Serial.println("connection failed"); return; } // We now create a URI for the request // ave_temp, ave_angle, ave_wind, ave_direction, max_angle, max_wind, max_direction; String url = "/logdata/wm10/wm10.php?temp=" + ave_temp + "&angle=" + ave_angle + "&wind=" + ave_wind + "&direction=" + ave_direction + "&maxangle=" + max_angle + "&maxwind=" + max_wind + "&maxdirection=" + max_direction; Serial.print("Requesting URL: "); Serial.println(url); // This will send the request to the server client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n"); //Serial.println(); Serial.println("closing connection"); Serial.println(); ////////disconnect to sakura ///////////////////////////////////// AvrCounter = 0; AvrTemperature=0; AvrWindAngle=0; AvrWindSpeed=0; //MaxWindAngle = 0; MaxWindSpeed = 0; } } //if (wmSerial.available()) //var++; delay (100) ; //} //delay (10000) ; } //void loop()