ads

03 ianuarie 2015

Mini Meteo Station with Arduino Nano

I finished a complex project, a mini Meteo Station based on Arduino Nano.

On a 4x20 I2C LCD I can see the date, time, inside and outside temperature, relative humidity and air pressure (in hPa).


Main features are:
    -Low footprint
    -Precise Date and Time with a DS1307 RTC circuit
    -Humidity with a DHT-11 sensor
    -Baro pressure and interior temperature with a BMP-085
    -External temperature with a DS-18B20
    -Low power (40 mA from one Li-Ion cell with a DC-DC converter with LCD Backlight on, 30 mA).
    -LCD Backlight on demand by push button

Took me about 2 days but I made it!

I intend to make some averages and to compare the pressure over an variable inteval tohave a weather prediction.





Here is the code:


 /*

   Meteo station with Arduino Nano
   by Adrian, YO3HJV
   http://yo3hjv.blogspot.com
  
  
  
  -- LCD on I2C
  -- Barometer and temperature sensor BMP-085 on I2C
  -- Humidity sensor DHT-11 on pin D3
  -- Dallas DS-18B20 temperature sensor on OneWire, pin D2
  -- Backlight Push button on pin A3
 
  */


   #include <Wire.h>
   #include <LCD.h>
   #include <LiquidCrystal_I2C.h>
   #include <Time.h>
   #include <DS1307RTC.h>
   #include <Barometer.h>
   #include <OneWire.h>
   #include <DallasTemperature.h>
   #include <dht11.h>
  
                                          // Data wire is plugged into port 2 on the Arduino
    #define ONE_WIRE_BUS 2                                         
    OneWire oneWire(ONE_WIRE_BUS);                                       
    DallasTemperature sensors(&oneWire);
   
    #define DHT11PIN 3
   
    dht11 DHT11;

  
     
// I2C LCD DISPLAY
   #define I2C_ADDR    0x27
   #define BACKLIGHT_PIN     3
   #define En_pin  2
   #define Rw_pin  1
   #define Rs_pin  0
   #define D4_pin  4
   #define D5_pin  5
   #define D6_pin  6
   #define D7_pin  7

// ******************
 
 
       LiquidCrystal_I2C    lcd(I2C_ADDR, En_pin, Rw_pin, Rs_pin, D4_pin, D5_pin, D6_pin, D7_pin);

    // Variabilele pentru Barometru
       float temperature;  // FLOAT or INT
       float tempext;      // FLOAT or INT
       float pressure;
       float atm;
       float altitude;
   
       Barometer myBarometer;
      
      int BLpin = A3;   // choose the input pin (for a pushbutton)
      int val = 0;      // variable for reading the pin status


  void setup()
    {    
     myBarometer.init();    
     sensors.begin();   // External Temp sensor         
     lcd.begin (20,4);  // initialize the lcd
     lcd.setBacklightPin(BACKLIGHT_PIN, POSITIVE); 
     pinMode(BLpin, INPUT);    // declare pushbutton as input
    }

              void loop()
 {
            
              val = digitalRead(BLpin);  // test BLpin
             
                  if (val == LOW)
                  {        
                  lcd.backlight();  // Backlight ON and...
                  sens();  // ... execute "sens"
                  }
                 
                  else  // if not ...,
                  {
                  lcd.noBacklight();  // Backlight OFF and...
                  sens();  // ...execute "sens"
                  }
}

    void sens()   // Main function
    {
     
       tmElements_t tm;                        //DS1307 RTC
       sensors.requestTemperatures();          // Send the command to get ext temperature
       tempext = sensors.getTempCByIndex(0);  
      

   //BARO + TEMP PE I2C
   // we read all the values from barometric sensor but use only temperature and pressure
   // we might calculate Dew point!
       temperature = myBarometer.bmp085GetTemperature(myBarometer.bmp085ReadUT()); //Get the temperature, bmp085ReadUT MUST be called first
       pressure = myBarometer.bmp085GetPressure(myBarometer.bmp085ReadUP());       //Get the temperature
       altitude = myBarometer.calcAltitude(pressure);                              //Uncompensated caculation - in Meters
       atm = pressure / 101325;
 
 
   //Hygro sensor DHT-11
       int chk = DHT11.read(DHT11PIN);
      
              if (RTC.read(tm))
              {

                 // Hours, minutes, seconds
               
                     lcd.setCursor(12, 0);                                                 
                                lcd2digits(tm.Hour);
                            lcd.print(":");
                                lcd2digits(tm.Minute);
                            lcd.print(":");
                                lcd2digits(tm.Second);
                
                
                 // Only hours and minutes. Uncomment this and comment above
                               
                 /*    lcd.setCursor(14, 0);                                                 
                                lcd2digits(tm.Hour);
                            lcd.print(":");
                                lcd2digits(tm.Minute);
        
                 */
                     lcd.setCursor(0, 0);
                                 lcd.print(tm.Day);
                             lcd.print('/');
                                 lcd.print(tm.Month);
                             lcd.print('/');
                                 lcd.print(tmYearToCalendar(tm.Year));
                            
                     lcd.setCursor(0, 2);
                             lcd.print("In: ");
                                 lcd.print(temperature);  // we can use [lcd.print(int(temperature))] for value without decimals;
                             lcd.print(" *C ");           // otherwise, temp is with two decimals
            
                     lcd.setCursor(0, 3);
                             lcd.print("Ex: ");
                                 lcd.print(tempext);      // the same as above ...
                             lcd.print(" *C ");                          
                     
                     lcd.setCursor(0, 1);
                              lcd.print("P:");
                                 lcd.print(int((pressure) / 100)); // No decimals pressure
                              lcd.print(" hPa");
                             // lcd.print("  ");
   
                     lcd.setCursor(12, 1);
                              lcd.print("Hum. ");
                                 lcd.print((int)DHT11.humidity);
                              lcd.print("%");
   
   
                } else
                    
                  {
                    lcd.clear();
                    lcd.print("RTC HW ERROR!!!"); // This is for RTC comm error
                    delay(10000);
                  }
             
            delay(200);
 
    }  // END  "sens" function


//LCD nice time function

    void lcd2digits(int number)   {
     
        if (number >= 0 && number < 10) {
            lcd.print('0');             }
            lcd.print(number);                   
                                  }




 73 de Adrian, YO3HJV


3 comentarii:

YO3HJV, Adrian spunea...

O mica statie meteo bazata pe un Arduino Nano si un afisaj LCD 4x20 conectat pe I2C.
Un exercitiu util pentru invatarea modului in care se apeleaza din rutina principala subrutine secundare. Un fel de GOSUB de pe vremuri!

unixzoid spunea...

Hi (hola)!
Can I make a meteo (weather) station with Arduino Pro Mini clone 328 - 5V, 16MHz? Or a it is required Nano or higher Arduino for such task?
Thank you!

Adrian (YO3HJV) spunea...

Yes you can do it with any Arduino version. It is not a complicated task even for a, let's say, 4 MHz or less uC.

Postări populare

OnLine logbook YO3HJV

www.hrdlog.net