Hi All,
So been working on this weather station for the past few weeks.
I have a few things I need help with. First, the I need the rainin to reset 60 minutes after the last rain fall event. The windgustmph needs to reset every ten min. Secondly, their is a huge amount of global variables (85% of the dynamic variables). I want to move some to the PROGMEM not sure how to accomplish this and then to recall the variable again. So I somebody can help me with an example I will appreciate it. Thank you
int DEBUG = 1;
#include <Wire.h>
#include <SoftwareSerial.h>
#include <SparkFunESP8266WiFi.h>
#include "DHT.h"
#include <Adafruit_BMP085.h>
#include "RTClib.h"
#define DHTTYPE DHT11
#define DHTPIN 4 // DHT 11
// analog I/O pins
const byte LIGHT = A0;
// digital I/O pins
const byte STAT1 = 7;
const byte RAIN = 2;
const int anemometer = 3;
// Constants
char SERVER[] = "rtupdate.wunderground.com";// Realtime update server - RapidFire
char WEBPAGE [] = "GET /weatherstation/updateweatherstation.php?";
char ID [] = "wuId";
char PASSWORD [] = "pw";
const char mySSID[] = "ssid";
const char myPSK[] = "pw";
// Global Variables
ESP8266Client client;
RTC_DS3231 rtc;
DHT dht(DHTPIN, DHTTYPE);
Adafruit_BMP085 bmp;
unsigned int connections = 0;
unsigned int timeout = 30000;
volatile float rainHour[60]; //60 floating numbers to keep track of 60 minutes of rain
float rainin = 0; // [rain inches over the past hour)] -- the accumulated rainfall in the past 60 min
volatile float dailyrainin = 0; // [rain mm so far today in local time]
volatile unsigned long raintime, rainlast, raininterval, rain;
long lastSecond; //The millis counter to see when a second rolls by
byte seconds; //When it hits 60, increase the current minute
byte second_2m; //Keeps track of the "wind speed/dir avg" over last 2 minutes array of data
byte minutes; //Keeps track of where we are in various arrays of data
byte minute_10m; //Keeps track of where we are in wind gust/dir
unsigned int counter = 0; // pulse count for wind sensor
unsigned int RPM = 0; // Revolutions per minute for wind sensor
unsigned int winddir = 0.0; // Wind direction for anemometer
float windspeedmph = 0/ 0.445; // Wind speed (m/s) for wind sensor
float windgustmph = 0; // Max wind speed for wind sensor
const float pi = 3.14159265; //RPM Calcs
const unsigned long period = 2500;
const int radio = 70;
void rainIRQ()
{
raintime = millis(); // grab current time
raininterval = raintime - rainlast; // calculate interval between this and last event
if (raininterval > 29) // ignore switch-bounce glitches less than 10mS after initial edge
{
dailyrainin += 0.011; //Each dump is 1.6mm of water
rainHour[minutes] += 0.011; //Increase this minute's amount of rain
rainlast = raintime; // set up for next event
}
}
void setup(void){
//Turn everything on
int status;
Serial.begin(9600);
Wire.begin(); //For I2C
rtc.begin(); //Hardware rtc
bmp.begin(); //Pressure sensor
dht.begin(); //Humidity Sensor
pinMode(RAIN, INPUT);
attachInterrupt(0, rainIRQ, FALLING);
pinMode(anemometer, INPUT); //Anemometer input(spins like mad when the wind blows).
digitalWrite(anemometer, HIGH); // set this high so when it detects a change it records it via INT(0)
interrupts();
seconds = 0;
lastSecond = millis();
// Turn the Wifi on
Serial.print(F("\nInitializing...v1"));
status = esp8266.begin();
if (status <= 0)
{
Serial.println(F("Unable to communicate with shield. Looping"));
while(1) ;
}
esp8266.setMode(ESP8266_MODE_STA); // Set WiFi mode to station
if (esp8266.status() <= 0)
{
if (esp8266.connect(mySSID, myPSK) < 0)
{
Serial.println(F("Error connecting"));
while (1) ;
}
}
}//End of Setup
//Loop
void loop(void){
//Lets see what time the RTC is set at! -- If RTC is used
DateTime now = rtc.now();
//Get sensor data
float tempc = bmp.readTemperature(); //Can read temp from bmp or dht sensors
float temp2f = dht.readTemperature(true);
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
if ((now.hour()==23) && (now.minute()==59) && (now.second() < 10 )){
dailyrainin = 0;
rainin = 0;
windgustmph = 0;
}
//Keep track of which minute it is
if(millis() - lastSecond >= 1000)
{
digitalWrite(STAT1, HIGH); //Blink stat LED
lastSecond += 1000;
if(++seconds > 59)
{
seconds = 0;
//Roll over 60 seconds then update the arrays for rain
if(++minutes > 59) minutes = 0;
if(++minute_10m > 9) minute_10m = 0;
rainHour[minutes] = 0; //Zero out this minute's rainfall amount
}
}
// max wind speed holder(wunderground)
if (windspeedmph > windgustmph) { //
windgustmph = windspeedmph;
}
//Total rainfall for the day is calculated within the interrupt
//Calculate amount of rainfall for the last 60 minutes
rainin = 0;
for(int i = 0 ; i < 60 ; i++)
rainin += rainHour[i];
windvelocity();
RPMcalc();
WindSpeed();
if (DEBUG) {
// Debug, or you can sit up all night watching it.
Serial.println("+++++++++++++++++++++++++");
/*
//If you are using Real Time Clock (RTC)
Serial.println("RTC TIME ");
Serial.print("&dateutc=");
Serial.print(now.year());
Serial.print("-");
Serial.print(now.month());
Serial.print("-");
Serial.print(now.day());
Serial.println("+");
Serial.print(now.hour());
Serial.print(":");
Serial.print(now.minute());
Serial.print(":");
Serial.println(now.second());
*/
Serial.print("temp= ");
Serial.print(tempf);
Serial.println(" *F");
// Serial.print("temp2f= ");
// Serial.print(temp2f);
// Serial.println(" *F");
Serial.print("windspeedmph=");
Serial.println(windspeedmph);
Serial.print("windgustmph=");
Serial.println(windgustmph);
Serial.print("windgustmph_10m=");
Serial.println(windgustmph);//[mph past 10 minutes wind gust mph
Serial.print("baro= ");
Serial.print(baromin);
Serial.println(" inHg");
Serial.print("dew point= ");
Serial.println(dewptf);
Serial.print("humidity= ");
Serial.println(humidity);
Serial.print("rain= ");
Serial.println(rainin);
Serial.print("daily= ");
Serial.println(dailyrainin);
}//End debug loop
//Send data to Weather Underground
if (client.connect(SERVER, 80)) {
if (DEBUG) {
Serial.println(F("Sending DATA "));
}
// Ship it!
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
//removed some to make code shorter
client.print("&softwaretype=Arduino%20UNO%20version1&action=updateraw&realtime=1&rtfreq=2.5");//Rapid Fire
client.println();
if (DEBUG) {
Serial.println F(("Upload complete"));
}
}//End send loop
else {
if (DEBUG) { Serial.println(F("Connection failed")); }
return;
}
delay(2500); // --If plugged in send every 2.5 seconds
}//End loop
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);
}
//Wind Speed Trigger/timer
void windvelocity(){
windspeedmph = 0;
counter = 0;
attachInterrupt(1, addcount, FALLING);//anemometer
unsigned long millis();
long startTime = millis();
while(millis() < startTime + period) {
}
}
//RPM calc needed for wind speed calc
void RPMcalc(){
RPM=((counter*1)*60)/(period/1000); // Calculate revolutions per minute (RPM)
}
void WindSpeed(){
windspeedmph = ((2 * pi * radio * RPM)/60) / 1000;
}
void addcount(){
counter++;
}