Hardware components | ||||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 |
This project About predicting weather by creating a PWS (Personal Weather Station) and send data to Wunderground. From Wunderground the predicted data is received by API. Everything done here is wireless by using GSM SIM800A module.
Step1:Making the connections ready.
# Mega to TFT: just fix the tft screen to Mega as shown below. (Using Adapter is optional)
# Mega to BMP280: To SDA and SCA of the Mega.
# Mega to DHT11: Pin 2 of Mega.
# GSM Module: RX and TX to RX1 and TX1 of Mega.
Step2:Create an account in Weather underground and add a PWS by registering. Then subscribe for API for receiving data.
Step3:After uploading the code you will find the results like listed below.
Thanks guys.
If you have any doubts or clarifications feel free to post it. The is too big and a little hard to understand it. Needs more time to work. Have a nice day.
#define TINY_GSM_MODEM_SIM800
#include <TinyGsmClient.h>
const char apn[] = "bsnlnet";
const char user[] = "";
const char pass[] = "";
#define SerialAT Serial1
TinyGsm modem(SerialAT);
#include <UTFT.h>
#include <tinyFAT.h>
#include <UTFT_tinyFAT.h>
UTFT myGLCD(CTE32HR,38,39,40,41);
UTFT_tinyFAT myFiles(&myGLCD);
extern uint8_t SmallFont[];
extern uint8_t BigFont[];
extern uint8_t SevenSegNumFont[];
extern uint8_t Grotesk16x32[];
extern uint8_t GroteskBold32x64[];
extern unsigned int logo[0x3F60];
#include <Wire.h>
#include <Adafruit_BMP085.h>
#include "DHT.h"
#define DHTPIN 2 // SO CONNECT THE DHT11/22 SENSOR TO PIN D4 OF THE NODEMCU
#define DHTTYPE DHT11 // DHT 11
DHT dht(DHTPIN, DHTTYPE);
Adafruit_BMP085 bmp; // BMP Pressure Sensor
//wunderground UPLOAD
char SERVER[] = "rtupdate.wunderground.com"; // Realtime update server - RapidFire
//char SERVER [] = "weatherstation.wunderground.com"; //standard server
char WEBPAGE [] = "GET /weatherstation/updateweatherstation.php?";
char ID [] = "ICOIMBAT6";
char PASSWORD [] = "e2us54xz";
const int port = 80;
int DEBUG = 0; // DEBUG counter; if set to 1, will write values back via serial
//wunderground download
#include <ArduinoJson.h>
const char server[] = "api.wunderground.com"; // name address for Weather Underground (using DNS)
const String myKey = "4e450941e7eee1eb"; //See: http://www.wunderground.com/weather/api/d/docs (change here with your KEY)
const String myFeatures = "forecast"; //See: http://www.wunderground.com/weather/api/d/docs?d=data/index&MR=1
const String myCountry = "IN"; //See: http://www.wunderground.com/weather/api/d/docs?d=resources/country-to-iso-matching
const String myCity = "Coimbatore"; //See: http://www.wunderground.com/weather/api/d/docs?d=data/index&MR=1
const int buffer_size = 300;
const int buffer=400;
char* conds[]={"\"local_epoch\":","\"weather\":","\"temp_c\":","\"relative_humidity\":","\"wind_dir\":","\"wind_kph\":","\"pressure_mb\":","\"feelslike_c\":"};
int num_elements = 8; // number of conditions you are retrieving, count of elements in conds
int num_elements_fr = 16; // number of forecast you are retrieving, count of elements in forecast
char* forecast[]={"\"celsius\":","\"celsius\":","\"icon\":","\"pop\":","\"celsius\":","\"celsius\":","\"icon\":","\"pop\":","\"celsius\":","\"celsius\":","\"icon\":","\"pop\":","\"celsius\":","\"celsius\":","\"icon\":","\"pop\":"};
char* forecast_rename[]={"\"celsius_h_0\":","\"celsius_l_0\":","\"icon_0\":","\"pop_0\":","\"celsius_h_1\":","\"celsius_l_1\":","\"icon_1\":","\"pop_1\":","\"celsius_h_2\":","\"celsius_l_2\":","\"icon_2\":","\"pop_2\":","\"celsius_h_3\":","\"celsius_l_3\":","\"icon_3\":","\"pop_3\":"}; //rename for same data name.
char* weekdayNames[]={"Sunday ", "Monday ", "Tuesday ", "Wednesday", "Thursday ", "Friday ", "Saturday "};
char close_brace ='}';
char comma = ',';
char* iconArray[]={"chancerain", "chancesleet", "chancetstorms", "clear", "cloudy", "partlycloudy", "flurries", "fog", "hazy", "mostlycloudy", "mostlysunny", "partlysunny", "rain", "sleet", "snow", "sunny", "tstorms"};
String sdFileName;
String sdFileName2;
String sdFileName3;
const char* iconName
;
const char* iconName2;
const char* iconName3;
unsigned long WMillis = 0;
void setup() {
// Set console baud rate
Serial.begin(115200);
delay(10);
// Set GSM module baud rate
SerialAT.begin(115200);
delay(300);
myGLCD.InitLCD(0);
file.initFAT();
// Restart takes quite some time
// To skip it, call init() instead of restart()
myGLCD.clrScr();
myGLCD.fillScr(VGA_WHITE);
myFiles.loadBitmap(10, 120, 300, 200, "w11.raw");
delay(5000);
myGLCD.clrScr();
myGLCD.fillScr(VGA_WHITE);
myGLCD.setBackColor(VGA_WHITE);
myGLCD.setFont(Grotesk16x32);
myGLCD.setColor(VGA_LIME);
myGLCD.print("Smart", CENTER, 160);
myGLCD.print("Weather Predictor", CENTER, 210);
delay(5000);
// Restart takes quite some time
// To skip it, call init() instead of restart()
Serial.println(F("Initializing Modem..."));
myGLCD.clrScr();
myGLCD.setColor(0, 255, 0);
myGLCD.fillScr(VGA_WHITE);
myGLCD.setFont(Grotesk16x32);
myGLCD.setBackColor(VGA_WHITE);
myGLCD.setColor(VGA_BLACK);
myGLCD.print("Initializing ", CENTER, 190);
myGLCD.print("Modem...", CENTER, 230);
delay(1000);
modem.restart();
String modemInfo = modem.getModemInfo();
Serial.print("Modem: ");
Serial.println(modemInfo);
Serial.print(F("Waiting for network..."));
myGLCD.clrScr();
myGLCD.setColor(0, 255, 0);
myGLCD.fillScr(VGA_WHITE);
myGLCD.setFont(Grotesk16x32);
myGLCD.setBackColor(VGA_WHITE);
myGLCD.setColor(VGA_BLACK);
myGLCD.print("Initializing ", CENTER, 190);
myGLCD.print("Network...", CENTER, 230);
delay(1000);
if (!modem.waitForNetwork()) {
Serial.println(" fail");
delay(10000);
return;
}
Serial.println(" OK");
myGLCD.print("CONNECTED!!!...", CENTER, 270);
myGLCD.clrScr();
myGLCD.setColor(0, 255, 0);
myGLCD.fillScr(VGA_WHITE);
myGLCD.setFont(Grotesk16x32);
myGLCD.setBackColor(VGA_WHITE);
myGLCD.setColor(VGA_BLACK);
myGLCD.print("Connecting to ", CENTER, 190);
myGLCD.print(apn, CENTER, 230);
delay(1000);
Serial.print(F("Connecting to "));
Serial.print(apn);
if (!modem.gprsConnect(apn, user, pass)) {
Serial.println(" fail");
delay(10000);
return;
}
Serial.println(" Apn connected");
myGLCD.print("CONNECTED!!!...", CENTER, 270);
wunderground();
//bmp
bmp.begin();
//dht
dht.begin();
}
void loop()
{
//upload
float tempc = bmp.readTemperature(); //Can read temp from bmp or dht sensors
float tempf = (tempc * 9.0)/ 5.0 + 32.0; //was dht.readTemperature, need to convert native C to F
float humidity = dht.readHumidity();
float baromin = bmp.readPressure()* 0.0002953;// Calc for converting Pa to inHg (wunderground)
float dewptf = (dewPoint(tempf, dht.readHumidity())); //Dew point calc(wunderground) //replaced dht.readtemp with converted temp
float f = dht.readTemperature(true);
float t = dht.readTemperature();
Serial.print("temp= ");
Serial.print(tempf);
Serial.println(" *F");
Serial.print("baro= ");
Serial.print(baromin);
Serial.println(" inHg");
Serial.print("dew point= ");
Serial.println(dewptf);
myGLCD.clrScr();
myGLCD.setColor(0, 255, 0);
myGLCD.fillScr(VGA_WHITE);
myGLCD.setFont(Grotesk16x32);
myGLCD.setBackColor(VGA_WHITE);
myGLCD.setColor(VGA_GREEN);
myGLCD.print("STATION", CENTER, 190);
myGLCD.print("DATA", CENTER, 230);
myGLCD.setFont(Grotesk16x32);
myGLCD.setColor(VGA_AQUA);
myGLCD.print("WEATHER PREDICTOR", CENTER, 430);
delay(2000);
myGLCD.clrScr();
myGLCD.setColor(0, 255, 0);
myGLCD.fillScr(VGA_WHITE);
myGLCD.setFont(Grotesk16x32);
myGLCD.setBackColor(VGA_WHITE);
myGLCD.setColor(VGA_BLACK);
myGLCD.print("STATION DATA", CENTER, 20);
myGLCD.print("Temperature:", LEFT, 70);
myGLCD.setColor(VGA_RED);
myGLCD.printNumI(tempf, LEFT, 120);
myGLCD.print("*F ", CENTER, 120);
myGLCD.setColor(VGA_BLACK);
myGLCD.print("Humidity:", LEFT, 170);
myGLCD.setColor(VGA_GREEN);
myGLCD.printNumI(humidity, LEFT, 230);
myGLCD.print("% ", CENTER, 230);
myGLCD.setColor(VGA_BLACK);
myGLCD.print("Pressure:", LEFT, 280);
myGLCD.setColor(VGA_FUCHSIA);
myGLCD.printNumI(baromin, LEFT, 320);
myGLCD.print("Hg ", CENTER, 320);
myGLCD.setColor(VGA_BLACK);
myGLCD.print("Dew Point:", LEFT, 370);
myGLCD.setColor(VGA_BLUE);
myGLCD.printNumI(dewptf, LEFT, 420);
myGLCD.print("*F ", CENTER, 420);
delay(5000);
TinyGsmClient client(modem);
if (client.connect(SERVER, 80)) {
if (DEBUG) {
Serial.println("Sending DATA ");
}
// Ship it!
Serial.println("Sending DATA ");
client.print(WEBPAGE);
client.print("ID=");
client.print(ID);
client.print("&PASSWORD=");
client.print(PASSWORD);
client.print("&dateutc=");
client.print("now"); //can use instead of RTC if sending in real time
client.print("&tempf=");
client.print(tempf);
client.print("&baromin=");
client.print(baromin);
client.print("&dewptf=");
client.print(dewptf);
client.print("&humidity=");
client.print(humidity);
//client.print("&action=updateraw");//Standard update
client.print("&softwaretype=Arduino%20UNO%20version1&action=updateraw&realtime=1&rtfreq=2.5");//Rapid Fire
client.print(" HTTP/1.0\r\n");
client.print("Accept: text/html\r\n");
client.print("Host: ");
client.print(SERVER);
client.print("\r\n\r\n");
client.println();
client.stop();
myGLCD.clrScr();
myFiles.loadBitmap(0, 0, 320, 480, "w14.raw");
delay(3000);
if (DEBUG) {
Serial.println("Upload complete");
}
}//End send loop
else {
if (DEBUG) { Serial.println(F("Connection failed")); }
return;
}
wunderground();
}
double dewPoint(double tempf, double humidity)
{
double A0= 373.15/(273.15 + tempf);
double SUM = -7.90298 * (A0-1);
SUM += 5.02808 * log10(A0);
SUM += -1.3816e-7 * (pow(10, (11.344*(1-1/A0)))-1) ;
SUM += 8.1328e-3 * (pow(10,(-3.49149*(A0-1)))-1) ;
SUM += log10(1013.246);
double VP = pow(10, SUM-3) * humidity;
double T = log(VP/0.61078);
return (241.88 * T) / (17.558-T);
}
void wunderground()
{
TinyGsmClient client(modem);
myGLCD.clrScr();
myFiles.loadBitmap(10, 120, 300, 179, "w12.raw");
myGLCD.setColor(0, 255, 0);
myGLCD.setBackColor(0, 0, 0);
delay(2000);
Serial.print("connecting to ");
Serial.println(server);
// Use WiFiClient class to create TCP connections
const int httpPort = 80;
if (!client.connect(server, httpPort)) {
Serial.println("connection failed");
return;
}
String html_cmd1 = "GET /api/" + myKey + "/" + myFeatures + "/q/" + myCountry + "/" + myCity + ".json HTTP/1.1";
String html_cmd2 = "Host: " + (String)server;
String html_cmd3 = "Connection: close";
Serial.println(" " + html_cmd1);
Serial.println(" " + html_cmd2);
Serial.println(" " + html_cmd3);
client.println(html_cmd1);
client.println(html_cmd2);
client.println(html_cmd3);
client.println();
delay(500);
unsigned int i = 0; //timeout counter
char json[buffer]="{"; // array for Json parsing
int n = 1; // character counter for json
while (!client.find("\"simpleforecast\": {")) {}
for (int j=0;j<num_elements_fr;j++){
while (!client.find(forecast[j])){} // find the part we are interested in.
String Str1 = forecast_rename[j];
for (int l=0; l<(Str1.length());l++)
{json[n] = Str1[l];
n++;}
while (i<60000) {
if(client.available()) {
char c = client.read();
if (c== ',') {break;}
if(c== '}') {n--;n--;n--;break;}
json[n]=c;
n++;
i=0;
}
i++;
}
if (j==num_elements_fr-1)
{
json[n]=close_brace;
}
else
{json[n]=comma;}
n++;
}
//Serial.println(json); // debugging json string
parseJSON(json); // extract the conditions
WMillis=millis();
}
void parseJSON(char json[400])
{
Serial.println(json);
StaticJsonBuffer<buffer> jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(json);
if (!root.success())
{
Serial.print("?fparseObject() failed");
//return;
}
const char* celsius_h_0 = root["celsius_h_0"];
const char* celsius_l_0 = root["celsius_l_0"];
const char* icon_0 = root["icon_0"];
int pop_0 = root["pop_0"];
const char* celsius_h_1 = root["celsius_h_1"];
const char* celsius_l_1 = root["celsius_l_1"];
const char* icon_1 = root["icon_1"];
int pop_1 = root["pop_1"];
const char* celsius_h_2 = root["celsius_h_2"];
const char* celsius_l_2 = root["celsius_l_2"];
const char* icon_2 = root["icon_2"];
int pop_2 = root["pop_2"];
const char* celsius_h_3 = root["celsius_h_3"];
const char* celsius_l_3 = root["celsius_l_3"];
const char* icon_3 = root["icon_3"];
int pop_3 = root["pop_3"];
String day1 = String(celsius_l_1) + "'/" + String(celsius_h_1) + "'";
String day2 = String(celsius_l_2) + "'/" + String(celsius_h_2) + "'";
String day3 = String(celsius_l_3) + "'/" + String(celsius_h_3) + "'";
String day0 = String(celsius_l_0) + "'/" + String(celsius_h_0) + "'";
Serial.println(day1);
Serial.println(day2);
Serial.println(day3);
Serial.println(day0);
myGLCD.clrScr();
myGLCD.setColor(0, 255, 0);
myGLCD.fillScr(VGA_WHITE);
myGLCD.setFont(Grotesk16x32);
myGLCD.setBackColor(VGA_WHITE);
myFiles.loadBitmap(10, 50, 300, 179, "w13.raw");
myGLCD.setColor(VGA_RED);
myGLCD.print("FORECAST", CENTER, 300);
myGLCD.setColor(VGA_AQUA);
myGLCD.print("WEATHER PREDICTOR", CENTER, 430);
delay(1500);
myGLCD.clrScr();
myGLCD.setColor(0, 255, 0);
myGLCD.fillScr(VGA_WHITE);
myGLCD.setFont(Grotesk16x32);
myGLCD.setBackColor(VGA_WHITE);
myGLCD.setColor(VGA_BLACK);
myGLCD.print("WUNDERGROUND DATA", CENTER, 20);
myGLCD.print("CITY:", LEFT, 170);
myGLCD.print("COIMBATORE", CENTER, 230);
myGLCD.setColor(VGA_AQUA);
myGLCD.setFont(Grotesk16x32);
myGLCD.print("WEATHER PREDICTOR", CENTER, 430);
delay(2000);
//day1
myGLCD.clrScr();
myGLCD.setColor(0, 255, 0);
myGLCD.fillScr(VGA_WHITE);
myGLCD.setFont(Grotesk16x32);
myGLCD.setBackColor(VGA_WHITE);
myGLCD.setColor(VGA_BLACK);
myGLCD.print("DAY 1", CENTER, 200);
delay(2000);
myGLCD.clrScr();
myGLCD.setColor(0, 255, 0);
myGLCD.fillScr(VGA_WHITE);
myGLCD.setFont(Grotesk16x32);
myGLCD.setBackColor(VGA_WHITE);
myGLCD.setColor(VGA_BLACK);
myGLCD.print("FORECAST:", LEFT, 20);
myGLCD.setColor(VGA_BLACK);
myGLCD.print("TEMPERATURE:", LEFT,370 );
myGLCD.setColor(VGA_RED);
myGLCD.print(day1, CENTER, 430);
iconName = (icon_1);
dayIconFix();
Serial.println(icon_1);
myFiles.loadBitmap(0, 70, 320, 220, (sdFileName));
myGLCD.setColor(VGA_GREEN);
myGLCD.print(icon_1, CENTER, 310);
delay(5000);
//day2
myGLCD.clrScr();
myGLCD.setColor(0, 255, 0);
myGLCD.fillScr(VGA_WHITE);
myGLCD.setFont(Grotesk16x32);
myGLCD.setBackColor(VGA_WHITE);
myGLCD.setColor(VGA_BLACK);
myGLCD.print("DAY 2", CENTER, 200);
delay(2000);
myGLCD.clrScr();
myGLCD.setColor(0, 255, 0);
myGLCD.fillScr(VGA_WHITE);
myGLCD.setFont(Grotesk16x32);
myGLCD.setBackColor(VGA_WHITE);
myGLCD.setColor(VGA_BLACK);
myGLCD.print("FORECAST:", LEFT, 20);
myGLCD.setColor(VGA_BLACK);
myGLCD.print("TEMPERATURE:", LEFT,370 );
myGLCD.setColor(VGA_RED);
myGLCD.print(day2, CENTER, 430);
iconName = (icon_2);
dayIconFix();
Serial.println(icon_2);
myFiles.loadBitmap(0, 70, 320, 220, (sdFileName));
myGLCD.setColor(VGA_GREEN);
myGLCD.print(icon_2, CENTER, 310);
delay(5000);
//day3
myGLCD.clrScr();
myGLCD.setColor(0, 255, 0);
myGLCD.fillScr(VGA_WHITE);
myGLCD.setFont(Grotesk16x32);
myGLCD.setBackColor(VGA_WHITE);
myGLCD.setColor(VGA_BLACK);
myGLCD.print("DAY 3", CENTER, 200);
delay(2000);
myGLCD.clrScr();
myGLCD.setColor(0, 255, 0);
myGLCD.fillScr(VGA_WHITE);
myGLCD.setFont(Grotesk16x32);
myGLCD.setBackColor(VGA_WHITE);
myGLCD.setColor(VGA_BLACK);
myGLCD.print("FORECAST:", LEFT, 20);
myGLCD.setColor(VGA_BLACK);
myGLCD.print("TEMPERATURE:", LEFT,370 );
myGLCD.setColor(VGA_RED);
myGLCD.print(day3, CENTER, 430);
iconName = (icon_3);
dayIconFix();
Serial.println(icon_3);
myFiles.loadBitmap(0, 70, 320, 220, (sdFileName));
myGLCD.setColor(VGA_GREEN);
myGLCD.print(icon_3, CENTER, 310);
delay(5000);
myGLCD.clrScr();
myGLCD.setColor(0, 255, 0);
myGLCD.fillScr(VGA_WHITE);
myGLCD.setFont(Grotesk16x32);
myGLCD.setBackColor(VGA_WHITE);
myGLCD.setColor(VGA_BLACK);
myGLCD.print("Forecast Summary", CENTER, 20);
myGLCD.print("Day 1:", LEFT, 70);
myGLCD.setColor(VGA_RED);
myGLCD.print(icon_1, LEFT, 120);
myGLCD.setColor(VGA_BLACK);
myGLCD.print("Day 2:", LEFT, 170);
myGLCD.setColor(VGA_GREEN);
myGLCD.print(icon_2, LEFT, 230);
myGLCD.setColor(VGA_BLACK);
myGLCD.print("Day 3 :", LEFT, 280);
myGLCD.setColor(VGA_FUCHSIA);
myGLCD.print(icon_3, LEFT, 320);
delay(7000);
}
void dayIconFix()
{
int i;
for (i = 0; i < 40; i++)
{
if (strcmp (iconName, iconArray[i])==0) {i=i+1; sdFileName = "w"; sdFileName +=i; sdFileName += ".raw"; break;}
}
}
Comments