loading
I did this project because I often climb mountains like the one in the picture and I need to know the altitude, the temperature, and also changes in the weather, sometimes in just minutes the weather get very bad, with hail, snow and a very dense mist.

All you need are a DHT11 Sensor, a BMP085 barometric Sensor, a Serial enabled LCD and of course an arduino.





Step 1: Step 1: Get the Parts

Materials:

1 Arduino
1 DHT11 Sensor (Temperature and Humidity Sensor)
1 BMP085 Sensor (Barometric Sensor) // Note: I have a GY-65 Modue it can handle 5v
1 Serial enabled LCD
1 10k resistor


Step 2: Build the Circuit

1 Attach the BMP085 to Arduino
Arduino 5v Pin to VCC Pin on BMP085(Important!! some Modules only support 3.3 v!! use the 3.3v Pin instead!)
Arduino GND Pin to GND Pin on BMP085
Arduino A5 Pin to SCL Pin on BMP085 (Analog 5 Pin to Clock Pin)
Arduino A4 Pin to SDA Pin on BMP085(Analog 4 Pin to Data Pin)

2 Attach the DHT11 Sensor to Arduino
Arduino 5V Pin to VCC Pin on DHT11
Arduino GND Pin to GDN Pin on DHT11
Arduino Digital Pin 2 to Data Pin on DHT11 and 10k resistor to GND on Arduino

3 Attach the serial enabled LCD to Arduino
Arduino 5v Pin to VCC Pin on Serial enabled LCD
Arduino GND Pin to GND Pin on Serial enabled LCD
Now the tricky part we will use the same ports as the BMP085
Arduino A5 Pin to the same line of the breadboard on the SCL Pin on BMP085
Arduino A4 Pin to the same line of the breadboard on the SDA Pin on BMP085



Step 3: Upload the Code to the Arduino


/*Based largely on code by  Jim Lindblom

 Get pressure, altitude, and temperature from the BMP085.
 Serial.print it out at 9600 baud to serial monitor.
 */
#include <dht11.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);
dht11 DHT11;
#define DHT11PIN 2

#define BMP085_ADDRESS 0x77  // I2C address of BMP085

const unsigned char OSS = 0;  // Oversampling Setting

// Calibration values
int ac1;
int ac2;
int ac3;
unsigned int ac4;
unsigned int ac5;
unsigned int ac6;
int b1;
int b2;
int mb;
int mc;
int md;

// b5 is calculated in bmp085GetTemperature(...), this variable is also used in bmp085GetPressure(...)
// so ...Temperature(...) must be called before ...Pressure(...).
long b5; 

void setup(){
  Serial.begin(9600);
  Wire.begin();
  
  lcd.init();                      // initialize the lcd 
  lcd.backlight();

  bmp085Calibration();
}

void loop()
{
  float temperature = bmp085GetTemperature(bmp085ReadUT()); //MUST be called first
  float pressure = bmp085GetPressure(bmp085ReadUP());
  float atm = pressure / 101325; // "standard atmosphere"
  float altitude = calcAltitude(pressure); //Uncompensated caculation - in Meters 
  
  Serial.println("\n");

  int chk = DHT11.read(DHT11PIN);

  Serial.print("Read sensor: ");
  switch (chk)
  {
    case 0: Serial.println("OK"); break;
    case -1: Serial.println("Checksum error"); break;
    case -2: Serial.println("Time out error"); break;
    default: Serial.println("Unknown error"); break;
  }

  Serial.print("Humidity (%): ");
  Serial.println((float)DHT11.humidity, 2);

  Serial.print("Temperature (oC): ");
  Serial.println((float)DHT11.temperature, 2);
  
    lcd.print("Hum(%): ");
  lcd.print((float)DHT11.humidity, 2);
    lcd.setCursor(0,1);
  lcd.print("Temp(C): ");
  lcd.print((float)DHT11.temperature, 2);
  delay(2000);
  lcd.clear();

  Serial.print("Temperature (oF): ");
  Serial.println(Fahrenheit(DHT11.temperature), 2);

  Serial.print("Temperature (K): ");
  Serial.println(Kelvin(DHT11.temperature), 2);
  
    lcd.print("Temp(F): ");
  lcd.print(Fahrenheit(DHT11.temperature), 2);
    lcd.setCursor(0,1);
  lcd.print("Temp(K): ");
  lcd.print(Kelvin(DHT11.temperature), 2);
  delay(3000);
  lcd.clear();

  Serial.print("Dew Point (oC): ");
  Serial.println(dewPoint(DHT11.temperature, DHT11.humidity));

  Serial.print("Dew PointFast (oC): ");
  Serial.println(dewPointFast(DHT11.temperature, DHT11.humidity));
  
  lcd.print("DewP(C): ");
  lcd.print(dewPoint(DHT11.temperature, DHT11.humidity));
  lcd.setCursor(0,1);
  lcd.print("DewPF(C): ");
  lcd.print(dewPointFast(DHT11.temperature, DHT11.humidity));
  delay(3000);
  lcd.clear();
  
  
  
  Serial.print("Temperature2: ");
  Serial.print(temperature, 2); //display 2 decimal places
  Serial.println("deg C");

  Serial.print("Pressure: ");
  Serial.print(pressure, 0); //whole number only.
  Serial.println(" Pa");
  
  lcd.print("Temp2: ");
  lcd.print(temperature, 2); //display 2 decimal places
  lcd.print(" C");
  lcd.setCursor(0,1);
  lcd.print("Pres: ");
  lcd.print(pressure, 0);
  lcd.print(" PA");
  delay(3000);
  lcd.clear();
  

  Serial.print("Standard Atmosphere: ");
  Serial.println(atm, 4); //display 4 decimal places

  Serial.print("Altitude: ");
  Serial.print(altitude, 2); //display 2 decimal places
  Serial.println(" M");
  
  lcd.print("Std Atm: ");
  lcd.print(atm, 4); //display 2 decimal places
  lcd.setCursor(0,1);
  lcd.print("Alt: ");
  lcd.print(altitude, 2);
  lcd.print(" M");
  delay(3000);
 
  lcd.clear();

  Serial.println();//line break

  delay(100); //wait a second and get values again.
}

/*-----( Declare User-written Functions )-----*/
//
//Celsius to Fahrenheit conversion
double Fahrenheit(double celsius)
{
        return 1.8 * celsius + 32;
}

//Celsius to Kelvin conversion
double Kelvin(double celsius)
{
        return celsius + 273.15;
}

// dewPoint function NOAA
// reference: http://wahiduddin.net/calc/density_algorithms.htm 
double dewPoint(double celsius, double humidity)
{
        double A0= 373.15/(273.15 + celsius);
        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);   // temp var
        return (241.88 * T) / (17.558-T);
}

// delta max = 0.6544 wrt dewPoint()
// 5x faster than dewPoint()
// reference: http://en.wikipedia.org/wiki/Dew_point
double dewPointFast(double celsius, double humidity)
{
        double a = 17.271;
        double b = 237.7;
        double temp = (a * celsius) / (b + celsius) + log(humidity/100);
        double Td = (b * temp) / (a - temp);
        return Td;
        
}        
// Stores all of the bmp085's calibration values into global variables
// Calibration values are required to calculate temp and pressure
// This function should be called at the beginning of the program
void bmp085Calibration()
{
  ac1 = bmp085ReadInt(0xAA);
  ac2 = bmp085ReadInt(0xAC);
  ac3 = bmp085ReadInt(0xAE);
  ac4 = bmp085ReadInt(0xB0);
  ac5 = bmp085ReadInt(0xB2);
  ac6 = bmp085ReadInt(0xB4);
  b1 = bmp085ReadInt(0xB6);
  b2 = bmp085ReadInt(0xB8);
  mb = bmp085ReadInt(0xBA);
  mc = bmp085ReadInt(0xBC);
  md = bmp085ReadInt(0xBE);
}

// Calculate temperature in deg C
float bmp085GetTemperature(unsigned int ut){
  long x1, x2;

  x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15;
  x2 = ((long)mc << 11)/(x1 + md);
  b5 = x1 + x2;

  float temp = ((b5 + 8)>>4);
  temp = temp /10;

  return temp;
}

// Calculate pressure given up
// calibration values must be known
// b5 is also required so bmp085GetTemperature(...) must be called first.
// Value returned will be pressure in units of Pa.
long bmp085GetPressure(unsigned long up){
  long x1, x2, x3, b3, b6, p;
  unsigned long b4, b7;

  b6 = b5 - 4000;
  // Calculate B3
  x1 = (b2 * (b6 * b6)>>12)>>11;
  x2 = (ac2 * b6)>>11;
  x3 = x1 + x2;
  b3 = (((((long)ac1)*4 + x3)<>2;

  // Calculate B4
  x1 = (ac3 * b6)>>13;
  x2 = (b1 * ((b6 * b6)>>12))>>16;
  x3 = ((x1 + x2) + 2)>>2;
  b4 = (ac4 * (unsigned long)(x3 + 32768))>>15;

  b7 = ((unsigned long)(up - b3) * (50000>>OSS));
  if (b7 < 0x80000000)
    p = (b7<<1)/b4;
  else
    p = (b7/b4)<<1;

  x1 = (p>>8) * (p>>8);
  x1 = (x1 * 3038)>>16;
  x2 = (-7357 * p)>>16;
  p += (x1 + x2 + 3791)>>4;

  long temp = p;
  return temp;
}

// Read 1 byte from the BMP085 at 'address'
char bmp085Read(unsigned char address)
{
  unsigned char data;

  Wire.beginTransmission(BMP085_ADDRESS);
  Wire.write(address);
  Wire.endTransmission();

  Wire.requestFrom(BMP085_ADDRESS, 1);
  while(!Wire.available())
    ;

  return Wire.read();
}

// Read 2 bytes from the BMP085
// First byte will be from 'address'
// Second byte will be from 'address'+1
int bmp085ReadInt(unsigned char address)
{
  unsigned char msb, lsb;

  Wire.beginTransmission(BMP085_ADDRESS);
  Wire.write(address);
  Wire.endTransmission();

  Wire.requestFrom(BMP085_ADDRESS, 2);
  while(Wire.available()<2)
    ;
  msb = Wire.read();
  lsb = Wire.read();

  return (int) msb<<8 | lsb;
}

// Read the uncompensated temperature value
unsigned int bmp085ReadUT(){
  unsigned int ut;

  // Write 0x2E into Register 0xF4
  // This requests a temperature reading
  Wire.beginTransmission(BMP085_ADDRESS);
  Wire.write(0xF4);
  Wire.write(0x2E);
  Wire.endTransmission();

  // Wait at least 4.5ms
  delay(5);

  // Read two bytes from registers 0xF6 and 0xF7
  ut = bmp085ReadInt(0xF6);
  return ut;
}

// Read the uncompensated pressure value
unsigned long bmp085ReadUP(){

  unsigned char msb, lsb, xlsb;
  unsigned long up = 0;

  // Write 0x34+(OSS<<6) into register 0xF4
  // Request a pressure reading w/ oversampling setting
  Wire.beginTransmission(BMP085_ADDRESS);
  Wire.write(0xF4);
  Wire.write(0x34 + (OSS<<6));
  Wire.endTransmission();

  // Wait for conversion, delay time dependent on OSS
  delay(2 + (3<> (8-OSS);

  return up;
}

void writeRegister(int deviceAddress, byte address, byte val) {
  Wire.beginTransmission(deviceAddress); // start transmission to device 
  Wire.write(address);       // send register address
  Wire.write(val);         // send value to write
  Wire.endTransmission();     // end transmission
}

int readRegister(int deviceAddress, byte address){

  int v;
  Wire.beginTransmission(deviceAddress);
  Wire.write(address); // register to read
  Wire.endTransmission();

  Wire.requestFrom(deviceAddress, 1); // read a byte

  while(!Wire.available()) {
    // waiting
  }

  v = Wire.read();
  return v;
}

float calcAltitude(float pressure){

  float A = pressure/101325;
  float B = 1/5.25588;
  float C = pow(A,B);
  C = 1 - C;
  C = C /0.0000225577;

  return C;
}

Step 4: Test the Code

Once you Upload the code you can watch in the screen:

1 Humidity %
2 Temperature Celsius (From the DHT11)
3 Temperature Farenheit
4 Temperature Kelvin
5 Dew Point
6 Dew Point Fast
7 Temperature 2 Celsius (From the BMP085)
8 Pressure in Pascals
9 Standard Atmosphere
10 Altitude in Meters

You can also see the same info if you use the Serial Monitor of your arduino IDE

Step 5: Make It Portable

You can use a 9v battery or 5 AA NiH rechargeable batteries, solder a compatible plug for your arduino and then just find a case to protect your weather monitor, you can use a transparent tupperware case, or you can build yourself a plexiglass case,and you are ready to climb any mountain you want.
<p><strong>Hello! I am getting this error. Would you kindly take a look and give me an advice? Thank you!</strong></p><p>sketch_jul24b.ino: In function 'long int bmp085GetPressure(long unsigned int)':</p><p>sketch_jul24b:234: error: expected primary-expression before '&gt;' token</p><p>sketch_jul24b:234: error: expected ')' before ';' token</p><p>sketch_jul24b:234: error: expected ')' before ';' token</p><p>sketch_jul24b.ino: In function 'long unsigned int bmp085ReadUP()':</p><p>sketch_jul24b:326: error: expected primary-expression before '&gt;' token</p><p>sketch_jul24b:326: error: expected ')' before ';' token</p><p>expected primary-expression before '&gt;' token</p>
<p>hello, can you help me please?</p><p>i found this error, what should i do? </p><p>sketch_jan16a:14: error: 'dht11' does not name a type</p><p>sketch_jan16a.ino: In function 'void loop()':</p><p>sketch_jan16a:57: error: 'DHT11' was not declared in this scope</p>
<p>seems like you dont have the library installed</p>
<p>Hello,</p><p>I have these errors, I'm the librarie &quot;versalino.h.&quot;</p><p>This report would have more information with<br> &quot;Show verbose output during compilation&quot;<br> enabled in File &gt; Preferences.<br>Arduino: 1.0.6 (Windows Vista), Board: &quot;Arduino Uno&quot;<br>In file included from dht11.cpp:43:<br>dht11.h:66: error: 'VersalinoBUS' does not name a type<br>dht11.h:67: error: 'VersalinoBUS' has not been declared<br>dht11.h:73: error: 'VersalinoBUS' has not been declared<br>dht11.h:76: error: 'VersalinoBUS' has not been declared<br>dht11.h:80: error: 'VersalinoBUS' has not been declared<br>dht11.h:93: error: 'VersalinoBUS' does not name a type<br>dht11.cpp:59: error: 'VersalinoBUS' has not been declared<br>dht11.cpp:66: error: 'VersalinoBUS' has not been declared<br>dht11.cpp: In member function 'void dht11::attach(int, int)':<br>dht11.cpp:69: error: '_myBUS' was not declared in this scope<br>dht11.cpp: At global scope:<br>dht11.cpp:81: error: 'VersalinoBUS' does not name a type<br>dht11.cpp:91: error: variable or field 'setBUS' declared void<br>dht11.cpp:91: error: 'VersalinoBUS' was not declared in this scope<br>dht11.cpp: In member function 'int dht11::read()':<br>dht11.cpp:111: error: '_myBUS' was not declared in this scope<br>dht11.cpp: At global scope:<br>dht11.cpp:116: error: 'VersalinoBUS' has not been declared<br>dht11.cpp: In member function 'int dht11::read(int, int)':<br>dht11.cpp:118: error: request for member 'PINS' in 'myBUS', which is of non-class type 'int'</p>
<p>Hello,</p><p>I forgot, I have the right DHT11 Versalino.</p><p>&quot;Library for the Virtuabotix DHT11 Sensor&quot;</p>
<p>Hola! Nuevo en Arduino y aprendiendo. Me interesa la meteorolog&iacute;a y estoy haciendo tu proyecto y he encontrado algunos errores en el c&oacute;digo, algunos ya resueltos y otros persistentes. El BMP085 arroja lecturas err&oacute;neas cuando interact&uacute;a con el DHT11 y el LCD, sin embargo funciona bien con el sketch de prueba. He intentado los siguiente: Distintas librer&iacute;as, resistencias pull down, 3.3 v y 5v de alimentaci&oacute;n, etc. &iquest;Alguna idea? Gracias y saludos.</p>
That's pretty neat! Have you considered shrinkifying it with a ATTiny85?
<p>the pull up resistor must be connected between data and Vcc. Actually the code is for arduino 1.0, I had to modify line 14 with : </p><p>LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);</p><p>plus some others lines regarding dht 11 I had to erase &quot;11&quot;</p>
<p>Hello, I am Annoy Chatterjee. I am making a multipurpose weather balloon for my school science fair project. I cannot understand that should the NC pin on DHT11 sensor not be connected to any wire and stay blank. Also I cannot understand that to which pin on DHT11 sensor is the 10K resistor connected to. Please help me. </p>
<p>Hello, i am trying to download the code, but I get many errors. Hopefully you can help me. Here are the errors: </p><p>sketch_may07a:10: error: 'LiquidCrystal_I2C' does not name a type</p><p>sketch_may07a:11: error: 'dht11' does not name a type</p><p>sketch_may07a.ino: In function 'void setup()':</p><p>sketch_may07a:39: error: 'lcd' was not declared in this scope</p><p>sketch_may07a.ino: In function 'void loop()':</p><p>sketch_may07a:54: error: 'DHT11' was not declared in this scope</p><p>sketch_may07a:71: error: 'lcd' was not declared in this scope</p><p>sketch_may07a.ino: In function 'long int bmp085GetPressure(long unsigned int)':</p><p>sketch_may07a:236: error: expected primary-expression before '&gt;' token</p><p>sketch_may07a:236: error: expected `)' before ';' token</p><p>sketch_may07a:236: error: expected `)' before ';' token</p><p>sketch_may07a.ino: In function 'long unsigned int bmp085ReadUP()':</p><p>sketch_may07a:328: error: expected primary-expression before '&gt;' token</p><p>sketch_may07a:328: error: expected `)' before ';' token</p>
<p>you need to download the libraries, google dht11 arduino libraries, </p><p>LiquidCrystal_I2C arduino libraries, etc</p>
<p>what dht library did you use?</p>

About This Instructable

44,965views

99favorites

License:

More by animes25:Arduino Portable Weather Monitor, altimeter, temperature, humidity, using DHT11 and BMP85 with LCD using only 3 pins GoPro Ultrasonic Motion Sensor HC-SR04 controled by arduino Full Color electroluminescent decals with El Panel 
Add instructable to: