Weather Station Data logger

#include <SFE_BMP180.h>
#include <MechaQMC5883.h>
#include "DHT.h"
#include <SD.h>
#include <Wire.h>
#include "RTClib.h"
#include <SPI.h>

SFE_BMP180 pressure;
float temperature;

#define ALTITUDE 241.05        // Altitude at my location

#define DHTPIN 2                // what pin we're connected DHT11 to
#define DHTTYPE DHT11   
DHT dht(DHTPIN, DHTTYPE);

#define LOG_INTERVAL 1000         // mills between entries (reduce to take more/faster data)
      
#define SYNC_INTERVAL 10000        // mills between calls to flush() - to write data to the card
uint32_t syncTime = 0;            // time of last sync()
#define ECHO_TO_SERIAL 1            // Echo data to serial monitor (Setting it to 0 will turn it off)
#define WAIT_TO_START 0           // Wait for serial input in setup() (Setting it to 1 you have to send a character to the Arduino´s Serial port to start the logging)
      
#define redLEDpin 4                 // the digital pins that connect to the LEDs (green and red)
#define greenLEDpin 3
      
#define windSpeedPin A0             // The analog pin connected to the Anemometer voltage divider

#define rainPin A3
int rainset=145;

MechaQMC5883 qmc;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
RTC_DS1307 RTC;                     // define the Real Time Clock object
     
const int chipSelect = 10;         // for the data logging shield, we use digital pin 10 for the SD cs line
        
File logfile;                      // the logging file  

void setup(void)
{
 Serial.begin(57600);
 Serial.println();
pinMode(rainPin,INPUT);
      // use debugging LEDs
 pinMode(redLEDpin, OUTPUT);
 pinMode(greenLEDpin, OUTPUT);

#if WAIT_TO_START
 Serial.println("Type any character to start");
 while (!Serial.available());
#endif          //WAIT_TO_START
      // initialize the SD card
 Serial.print("Initializing SD card...");
        // make sure that the default chip select pin is set to
        // output, even if you don't use it:
 pinMode(10, OUTPUT);

 // see if the card is present and can be initialized:
 if (!SD.begin(chipSelect)) 
 {
 error("Card failed, or not present");
 }
 Serial.println("card initialized.");

 // create a new file
 char filename[] = "LOGR000.CSV";
 for (uint8_t i = 0; i < 1000; i++) 
 {
 filename[4] = (i/100)%10 + '0';
 filename[5] = (i/10)%10 + '0';
 filename[6] = i%10 + '0';
 if (! SD.exists(filename)) 
 {
 // only open a new file if it doesn't exist
 logfile = SD.open(filename, FILE_WRITE);
 break; // leave the loop!
 }
 }

 if (! logfile)
 {
 error("couldnt create file");
 }

 Serial.print("Logging to: ");
 Serial.println(filename);
 
 Wire.begin();
 
 if (!RTC.begin())                // connect to RTC
 {
  logfile.println("RTC failed");
 #if ECHO_TO_SERIAL
  Serial.println("RTC failed");
 #endif //ECHO_TO_SERIAL
 }
 if (! RTC.isrunning())                 
  {
    error("RTC is NOT running, let's set the time!");
    RTC.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }  
  qmc.init();                            // Initialize GY273 Compass sensor  
  dht.begin();                           // Initialize DHT11 sensor
 
if (!pressure.begin())
  {
  error("Could not find a valid BMP085 sensor, check wiring!");
  while (1) {}
  }
 logfile.println("Date, Day, Time, WindSpeed,  WindDir, Raining, TempBMP,  PressureBMP,   HumidityDHT");
#if ECHO_TO_SERIAL
 Serial.print("Date");
 Serial.print("\t");
 Serial.print("\t");
 Serial.print("Day");
 Serial.print("\t");
 Serial.print("Time");
 Serial.print("\t");
 Serial.print("WindSpeed");
 Serial.print("\t");
 Serial.print("WindDir");
 Serial.print("\t");
 Serial.print("RainStatus");
 Serial.print("\t");
 Serial.print("TempBMP");
 Serial.print("\t");
 Serial.print("PressBMP");
 Serial.print("\t");
 Serial.println("HumDHT");
#endif //ECHO_TO_SERIAL
 }
  
void loop(void)
{
 DateTime now;
 
 delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));        // delay for the amount of time we want between readings
 digitalWrite(greenLEDpin, HIGH);
 
 uint32_t m = millis();           // log milliseconds since starting
 
 
 now = RTC.now();                 // fetch the time
 // log time
 logfile.print(now.day(), DEC);
 logfile.print("-");
 logfile.print(now.month(), DEC);
 logfile.print("-");
 logfile.print(now.year(), DEC);
 logfile.print(",");
 logfile.print(daysOfTheWeek[now.dayOfTheWeek()]);
 logfile.print(",");
 logfile.print(now.hour(), DEC);
 logfile.print(":");
 logfile.print(now.minute(), DEC);
 logfile.print(":");
 logfile.print(now.second(), DEC);
 logfile.print(",");
 #if ECHO_TO_SERIAL
    Serial.print(now.day(),DEC);
    Serial.print("-");
    Serial.print(now.month(),DEC);
    Serial.print("-");
    Serial.print(now.year(),DEC);
    Serial.print(",  ");
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(",  ");
    Serial.print(now.hour(), DEC);
    Serial.print(":");
    Serial.print(now.minute(), DEC);
    Serial.print(":");
    Serial.print(now.second(), DEC);
    Serial.print(",   ");
#endif //ECHO_TO_SERIAL

 int windSpeed = (analogRead(windSpeedPin)/1024.0)*5.0;         // Read an analog input A0  and converting the value of windSpeed to actual speed
 logfile.print(windSpeed);
 logfile.print(",");
 #if ECHO_TO_SERIAL
    Serial.print(windSpeed);
    Serial.print(",   ");
 #endif //ECHO_TO_SERIAL
  // Read GY273 compass sensor data
  int x, y, z;
  int azimuth;
  qmc.read(&x, &y, &z,&azimuth);                  
  int windDirection = azimuth;
 logfile.print(windDirection);
 logfile.print("Deg N");
 logfile.print(",");
 #if ECHO_TO_SERIAL
    Serial.print(windDirection);
    Serial.print("Deg N");
    Serial.print(",   ");
#endif //ECHO_TO_SERIAL
 //Read an analog input A3
  String rain="";    
  int rainValue = analogRead(rainPin);                // Read Rain sensor data and calculate
  rainValue = map(rainValue,0,1023,225,0);
  if(rainValue>=rainset)
  {
  rain="Raining";
  }
  else
  {
  rain="Clear";
  }
 logfile.print(rain);
 logfile.print(",");
#if ECHO_TO_SERIAL
    Serial.print(rain);
    Serial.print(",   ");
#endif //ECHO_TO_SERIAL
   
 float pressure = readPressureAndTemperature();       // Read BMP180 sensor data by calling function
 logfile.print(temperature);
 logfile.print(", ");
 logfile.print(pressure);
 logfile.println(",");
 #if ECHO_TO_SERIAL
    Serial.print(temperature);
    Serial.print(",   ");
    Serial.print(pressure);
    Serial.println(",   ");
 #endif //ECHO_TO_SERIAL
 
/* float humidity = dht.readHumidity()+10.0f;       //whole code stopped working if this code is uncommented. Need solution. please help
 logfile.print(humidity);
 #if ECHO_TO_SERIAL
    Serial.println(humidity);
#endif //ECHO_TO_SERIAL*/

// At the end of data logging the green LED is turned off
digitalWrite(greenLEDpin, LOW);
 
 //Now we write data to disk! Don't sync too often - requires 2048 bytes of I/O to SD card which uses a bunch of power and takes time
 if ((millis() - syncTime) < SYNC_INTERVAL) return;   
 syncTime = millis();

 // blinking Red LED to show we are syncing data to the card & updating FAT!
 digitalWrite(redLEDpin, HIGH);
 logfile.flush();
 digitalWrite(redLEDpin, LOW);

} 
// Functions called in the loop

void error(char *str)
{
 Serial.print("error: ");
 Serial.println(str);

      // red LED indicates error
 digitalWrite(redLEDpin, HIGH);
 while(1);
}

float readPressureAndTemperature()
{
  char status;
  double T,P,p0,a;

  status = pressure.startTemperature();
  if (status != 0)
  {
    delay(status);
    status = pressure.getTemperature(T);
    if (status != 0)
    { 
      temperature = T;
      status = pressure.startPressure(3);
      if (status != 0)
      {
        delay(status);
        status = pressure.getPressure(P,T);
        if (status != 0)
        {
          p0 = pressure.sealevel(P,ALTITUDE);       
          return p0;
        }
      }
    }
  }
}

i am new to arduino code. i have learned about many sensors. So i have planned to use them here in my code to create a data logger for weather report . There is a problem with this code. If i uncomment the code for DHT11 sensor for reading humidity. The whole loop stopped working further and also stopped from logging data to SD card. Please help me with code. Thanks and Regard in advance.

The function readHumidity() is not included in this code. Obviously the program is hanging there. You should test this function in a separate sketch.

Thank you SupArdu for your response. ''dht.readHumidity()" is included in DHT library. But as per your advice i have run the code separately. All works fine.

#include "DHT.h"
#include <SFE_BMP180.h>
#include <Wire.h>

SFE_BMP180 pressure;

float temperature;

#define ALTITUDE 241.05 // Altitude at my location
#define DHTPIN 2     // what pin we're connected to

#define DHTTYPE DHT11   

DHT dht(DHTPIN, DHTTYPE);


void setup(void) {
  Serial.begin(57600);
  dht.begin();
  pressure.begin();
}

void loop() 
{
  
 float humidity = dht.readHumidity()+10.0f;
 float pressure = readPressureAndTemperature();
 

 //Printing Temperature
 Serial.print("T:"); 
 Serial.print(temperature);
 Serial.print(" C");
 Serial.print("\t");

 //Printing Pressure

 Serial.print("P: ");
 Serial.print(pressure);
 Serial.print(" hPa");
 Serial.print("\t");
 
 //Printing Humidity
 Serial.print("H: ");
 Serial.print(humidity);
 Serial.println("%");
 
 delay(2000);
}

float readPressureAndTemperature()
{
  char status;
  double T,P,p0,a;

  status = pressure.startTemperature();
  if (status != 0)
  {
    delay(status);
    status = pressure.getTemperature(T);
    if (status != 0)
    { 
      temperature = T;
      status = pressure.startPressure(3);
      if (status != 0)
      {
        delay(status);
        status = pressure.getPressure(P,T);
        if (status != 0)
        {
          p0 = pressure.sealevel(P,ALTITUDE);       
          return p0;
        }
      }
    }
  }
}

Really? It is... #include<DHT.h>

float DHT::readHumidity(bool force);

The un-commented section involves the SD card. Do you have enough power for the SD card read/write and the other devices?

Thank you for your concern. I have separate 5v suply for the whole setup beyond the arduino output power. But no luck at all. output stuck here just reading before 'float humidity = dht.readHumidity()'


But if i comment out the DHT sensor code only then the all works fine. Shows on Serial and also write on SD card with the same setup.
Serial out put is as

and SD logged data as

Maybe the Serial.print() is interfering... try only comment-out the Serial.println(humidity); line

i have made this changes without reading DHT actually. Serial.println() is working fine. But if i uncomment this line the code stopped working

//float humidity = dht.readHumidity()+10.0f;      
 logfile.println("humidity");
 #if ECHO_TO_SERIAL
    Serial.println("humidity");
#endif //ECHO_TO_SERIAL

thinking maybe it returns a nan..
try taking out the math in the read..
read humidity then check if(!isnan(humidity)) then add the 10.0f..

good luck.. ~q

Hello @qubits-us - This looks strange to me, but it is shown in the examples of the library.
I can not find my library reference... I must have seen it in a random project (that probably has the same issue)

doesn't mean it's correct..

float DHT::readHumidity(bool force) {
  float f = NAN;

result starts out as a nan..
DHT.cpp

just saying might want to add a check..

~q

1 Like

Thank you all for responding. In my other code of audio play from SD card and run servo accordingly. "TMRpcm.h"(audio Library) and "servo.h" have some timer issue. So i replaced servo library with "ServoTimer2.h". So timer issue is resolved and code is working fine.
i thought if there is some timer issue in this code too....
What do you think?

while I did not check all the libs used, I don't think so..
Now pcm and servos, i have seen that before..

did you try adding a check for nan (Not A Number)??
dht11 needs about 2 seconds between reads..
if code from post 4 works, try slowing down code in post 1..

but yes, the trouble could be something else completely..

good luck.. ~q

No luck. i have tried slowing down the code in post 1.
Then i have changed code for other DHT libraries. Like https://github.com/adafruit/DHT-sensor-library. But this totally block SD card from creating new file.
:roll_eyes:

Hi, @all_practically

What model Arduino controller are you using?

Thanks.. Tom.. :grinning: :+1: :coffee: :australia:

Arduino Uno

In a former sketch of mine I had a hang up because of interrupts continuously firing leaving no time for running the rest of the program. After commenting one line deleting the interrupt flag was omitted. Therefore the interrupt was firing continuously.
Are interrupts involved reading DHT sensor?

Waiting for a flag which is not coming up also may get a program hanging.

Perhaps there is some incompatibility between your libraries used. One library may use some internal hardware (timer, I/O pins, SPI, etc.) configuring it in a way which another library cannot work with...

Another idea:
check the available RAM after compilation. The Uno has very limited RAM. Nested function calls e.g. require more and more RAM. If there is not sufficient RAM for the stack then crazy program behaviour may occur.

1 Like

Could be an idea. In that case, #define ECHO_TO_SERIAL 0 may be enough to solve your problem...