Astro Arduino – part II – weather monitor

So, in the previous part we learned some basics – how to switch pin on and off, and then relays that can control power for devices, or for example DSLR shutter. In this part we will try to monitor environmental conditions – pressure, temperature, humidity and calculate dew point temperature. We use BME280 universal sensor, Arduino Uno board and Arduino LCD shield.

Whole code is listed in one piece below. To compile it we need to fetch some libraries (unless we already have it). Use menu Sketch -> Include library -> Manage libraries and find and install there LiquidCrystal and both Adafruit libraries. Defined LCD, backlight and keypad pins are for most common version of LCD shield, but it may differ for some less popular constructions. BME280 sensor uses for communication I2C protocol, so it needs to be connected to corresponding I2C pins in Adrduino. Since LCD shield covers all Arduino pins, sensor connections need to be made to LCD shield pins that are accessible on the top of the shield. The pinout of BME280 is (we use I2C interface):

  • VIN is the power – connect to 5V of Arduino board
  • GND is common ground – connect to GND of Arduino board
  • SCK is I2C clock signal – connect to Arduino A5 pin
  • SDI is I2C data signal – connect to Arduino A4 pin

In the code we have usual things at the top – we include required libraries. Then we define pin assignments, and declare objects to control LCD and to read from the sensor. Then one more variable to hold the delay (in ms) between readings. In setup section we start Serial port communication, and then initiate LCD display. In the next step code checks if BME280 sensor is connected and working. At the end of setup block we set reading frequency to every 1000ms.
Loop block starts with reading values from the sensor. Then all values are provided to the serial port, so when we have Arduino connected to the computer and serial port opened in any terminal, we will see all values there. Sensor provides three values: current pressure, temperature and relative humidity. There is one more value calculated – that is dew point temperature, which is quite useful information for astronomy amateur. Next thing to do is update LCD display with the values, and then delay of specified time is declared at the end of loop method, so the subsequent readings will be done every some time (one second in this example).

Working weather monitor
#include <LiquidCrystal.h>
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#define LCD_BACKLIGHT_PIN 10
#define KEYPAD_PIN        A0

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
Adafruit_BME280 bme;

unsigned long delayTime;

void setup() {
  Serial.begin(9600);
  Serial.println("*** SENSORS ***");

  lcd.begin(16, 2);               // start the library
  lcd.setCursor(0, 0);            // set the LCD cursor position
  lcd.print("*** SENSORS ***");

  bool status;
  status = bme.begin();
  if (!status) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }

  delayTime = 1000;
}

void loop() {
  float temperature = bme.readTemperature();
  float humidity = bme.readHumidity();
  float pressure = bme.readPressure();

  Serial.print("Temperature = ");
  Serial.print(temperature);
  Serial.println(" *C");

  Serial.print("Pressure = ");
  Serial.print(pressure / 100.0F);
  Serial.println(" hPa");

  Serial.print("Humidity = ");
  Serial.print(humidity);
  Serial.println(" %");

  double dewPoint = dewPointFast(temperature, humidity);
  Serial.print("Dew point = ");
  Serial.print(dewPoint);
  Serial.println(" *C");

  /**
   *  01234567890123456
   *  T: -12.3C H: 100%
   *  D: -23.1C P: 1023 
   * */
  lcd.clear();
  lcd.setCursor(0, 0); lcd.print("T: "); lcd.print(temperature, 1); 
  lcd.setCursor(8, 0); lcd.print("C H:"); lcd.print(humidity, 0); lcd.print("%");
  lcd.setCursor(0, 1); lcd.print("D: "); lcd.print(dewPoint, 1);
  lcd.setCursor(8, 1); lcd.print("C P:"); lcd.print(pressure / 100.0F, 0);

  delay(delayTime);
}


// 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 * 0.01);
  double Td = (b * temp) / (a - temp);
  return Td;
}
Serial port output

And this is mostly it 🙂 Our circuit measures temperature, humidity and pressure, then calculates dew point temperature and feeds this data to both LCD display and serial port output. In the next part we will start to use keyboard on our LCD shield and add automated controller for dew cap heater to our weather station.

Stay tuned!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.