Project in progress
ArduWeather

ArduWeather © GPL3+

Aviation meteorology station with Arduino.

  • 2,440 views
  • 0 comments
  • 12 respects

Components and supplies

About this project

ArduWeather is a meteorological station for small aiports. Nowadays, these airports doesn't have a meteorological station for pilot's consulting before flying to these destinations. This project is a cheap, stable and small, perfect for this situation. Some parameters are related with the closest aiport to bring the most accurate value, like cloud's height and visibility.

This project have also a LiveMETAR, that is a codified message that brings the meteorological conditions, but live! It's Second per second updated! Also get METAR and TAF (meteorological forecast) from the organ responsible for Aeronautical Meteorology of the country.

Another functionality is LiveReport, it create a meteorology report of a few hours selected in graphics, enabling the studying of longtime weather conditions of that area and see the weather change trend

Other point is the big data. All values are stored in the database, in Cloud, every second. This is good for the meteorologists for studying the area's weather and if have an accident or incident near or at the airport, the organ responsible for the air crash investigation can get the weather parameters in the exact moment of crash/incident.

It written in .NET 4.5.2, SQL Server and, obviously, Arduino IDE

Code

ArduWeather Arduino CodeArduino
Arduino code of the project
// Cdigo fonte ArduWeather
// Code by : Renan W. Paiva
//v3.0
// LM35 = 5V ---  BMP085 = 3.3V --- DHT11 = 5V --- LDR = 5V / 3.3V --- DS1302 = 5V - 2V
// Adicionado EEPROM
//Variao de valores dos sensores e delay's na placa ajustados
// Adicionado controle da placa/sensores por cdigos.
//v4.0
//Adicionado controle e configurao do DS1302 via software.
//Adicionado monitoramento das linhas 3.3v e 5v
//Adicionado controle e sistema automtico de proteo aos sensores por rels
//Adicionado controle de carga inicial aos capacitores por meio de transstores
#include <EEPROM.h>
#include <idDHT11.h>
#include <DS1302.h>
#include <Adafruit_BMP085.h>
#include <Wire.h>
#include <avr/power.h>
#include <avr/sleep.h>
#include <HMC5883L.h>
#include <Streaming.h>
#include <math.h>
MagnetometerRaw raw;
int MilliGauss_OnThe_XAxis;
DS1302 rtc(3, 4, 5);
float heading;
double Vcc;
unsigned int ADCValue;
String data, dia, horario;
float headingDegrees;
double ChuvaTemp, ChuvaValue;
MagnetometerScaled scaled;
float declinationAngle;
int idDHT11intNumber = 0, luzsensor = A1, luz, i, anemometro = A10, idDHT11pin = 2, result, error = 0;
String tempoInicial, statusDHT11, code, readString;
float rawX, rawY, rawZ, scaledX, scaledY, scaledZ, proaRad, proaGraus;
float tempBMP, tempDHT, totalTemp, orvalho, umidade, pressao, voltagem5, voltagem3, altitude, luminosidade, altimetria, velocidade, Bussola, eixoX, eixoY, eixoZ, luz2, chuvaAnalogRaw, chuvaAnalog, valorAnemometro;
bool erroBMP085 = false, BMP085 = true, DHT11Bool = true, LDR = true, Anemometro = true, fahrenheit = false, celsius = true, kelvin = false, erroHMC;
Adafruit_BMP085 bmp;
void dht11_wrapper();
HMC5883L compass;
float tempBMPSum, totalTempSum, orvalhoSum, pressaoSum, voltagemSum, altitudeSum, luzSum, altimetriaSum, velocidadeSum;
double rawXSum, rawYSum, rawZSum, scaledXSum, scaledYSum, scaledZSum, headingSum, headingDegreesSum;
int a;
boolean RTCConfig = false, finish = false, sleepMode = false;
idDHT11 DHT11(idDHT11pin, idDHT11intNumber, dht11_wrapper);
void setup()
{
  Serial.begin(38400);
  Wire.begin();
  pinMode(luzsensor, INPUT);
  pinMode(A10, INPUT);
  pinMode(A7, INPUT);
  pinMode(A5, INPUT);
  pinMode(40, INPUT);
  pinMode(41, INPUT);
  pinMode(42, INPUT);
  pinMode(53, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  compass = HMC5883L();
  error = compass.SetScale(1.3);
  if (error != 0)
  {
    erroHMC = true;
    error = compass.SetMeasurementMode(Measurement_Continuous);
    if (error != 0)
    {
      erroHMC = true;
    }
    else
    {
      erroHMC = false;
    }
  }
  else
  {
    erroHMC = false;
  }
  tempoInicial += rtc.getTimeStr();
  tempoInicial += " ";
  tempoInicial +=  rtc.getDOWStr();
  tempoInicial += " ";
  tempoInicial += rtc.getDateStr() ;
  if (!bmp.begin())
  {
    erroBMP085 = true;
  }
  else
  {
    erroBMP085 = false;
  }
  ParametrosEEPROM();
  Volt();
}


void dht11_wrapper() {
  DHT11.isrCallback();
}
void loop()
{
  int inic = millis();
  limpaVar();
  orvalho = 0;
  umidade = 0;
  tempDHT = 0;
  while(a < 10)
  {
    orvalho += DHT11.getDewPoint();
    umidade += DHT11.getHumidity();
    tempDHT += DHT11.getCelsius();
    a++;
  }
  orvalho = orvalho / a;
  umidade = umidade /a;
  tempDHT = tempDHT /a;
  limpaVar();
  while (a < 10)
  {
    raw = compass.ReadRawAxis();
    scaled = compass.ReadScaledAxis();
    MilliGauss_OnThe_XAxis = scaled.XAxis;// (or YAxis, or ZAxis)
    heading = atan2(scaled.YAxis, scaled.XAxis);
    declinationAngle = 0.35918875965;
    heading += declinationAngle;
    if (heading < 0)
    {
      heading += 2 * PI;
    }
    if (heading > 2 * PI)
    {
      heading -= 2 * PI;
    }
    headingDegrees = heading * 180 / M_PI;
    rawXSum += raw.XAxis;
    rawYSum += raw.YAxis;
    rawZSum += raw.ZAxis;
    scaledXSum += scaled.XAxis;
    scaledYSum += scaled.YAxis;
    scaledZSum += scaled.ZAxis;
    headingSum += heading;
    headingDegreesSum += headingDegrees;
    a++;

  }
  Bussola = headingDegreesSum / a;
  eixoX = scaledXSum / a;
  eixoY = scaledYSum / a;
  eixoZ = scaledZSum / a;
  Serial << "Compass" << Bussola << endl;
  Serial << "AxisX" << eixoX << endl;
  Serial << "AxisY" << eixoY << endl;
  Serial << "AxisZ" << eixoZ << endl;
  limpaVar();
  Codigo();
  Volt();
  DHT11.acquire();
  while (DHT11.acquiring());
  result = DHT11.getStatus();
  if (result == IDDHTLIB_OK)
  {
    statusDHT11 = "OK";
  }
  else if (result == IDDHTLIB_ERROR_CHECKSUM)
  {
    statusDHT11 = "IDDHTLIB_ERROR_CHECKSUM";
  }
  else if (result == IDDHTLIB_ERROR_ISR_TIMEOUT)
  {
    statusDHT11 = "IDDHTLIB_ERROR_ISR_TIMEOUT";
  }
  else if (result == IDDHTLIB_ERROR_RESPONSE_TIMEOUT)
  {
    statusDHT11 = "IDDHTLIB_ERROR_RESPONSE_TIMEOUT";
  }
  else if (result == IDDHTLIB_ERROR_DATA_TIMEOUT)
  {
    statusDHT11 = "IDDHTLIB_ERROR_DATA_TIMEOUT";
  }
  else if (result == IDDHTLIB_ERROR_ACQUIRING)
  {
    statusDHT11 = "IDDHTLIB_ERROR_ACQUIRING";
  }
  else if (result == IDDHTLIB_ERROR_DELTA)
  {
    statusDHT11 = "IDDHTLIB_ERROR_DELTA";
  }
  else if (result == IDDHTLIB_ERROR_NOTSTARTED)
  {
    statusDHT11 = "IDDHTLIB_ERROR_NOTSTARTED";
  }
  if (Anemometro == true)
  {
    valorAnemometro = (analogRead(anemometro)) / 10;
  }
  else
  {
    valorAnemometro = -1;
  }
  Serial << "DHTStatus" << statusDHT11 << endl;
  Serial << "Humidity" << umidade << endl;
  Serial << "DHTTemp" << tempDHT << endl;
  Serial << "DewPoint" << orvalho << endl;
  limpaVar();
  tempBMP = 0;
  pressao = 0;
  altitude = 0;
  
 while(a < 10)
 {
  tempBMP +=  bmp.readTemperature();
  pressao += bmp.readPressure();
  altitude += bmp.readAltitude(101500);
  a++;
 }
 
 tempBMP = tempBMP / a;
 pressao = pressao /a;
 altitude = altitude /a;
 limpaVar();
  Serial << "BMPTemp" << tempBMP << endl;
  Serial << "Pressure" << pressao << endl;
  Serial << "realAltitude" << altitude << endl;
  Serial << "Wind" << valorAnemometro << endl;
  data = rtc.getDateStr();
  dia = rtc.getDOWStr();
  horario = rtc.getTimeStr();
  Serial << "Day" << dia << endl;
  Serial << "Date" << data << endl;
  Serial << "Time" << horario << endl;
  luz = mediaLDR();
  Serial << "Light" << luz << endl;
  //Serial << statusDHT11 << ";" << umidade << ";" << tempDHT << ";" << orvalho << ";" << "0" << ";" << valorAnemometro << ";" << dia << ";" << data << ";" << horario << ";" << luz << ";" << "0" << ";" << "0" << ";" << "0" << ";" << "0" << ";" << "0" << ";" << "0" << ";" << "0" << ";" << "0" << ";" << tempBMP << ";" << pressao << ";" << "0" << ";" << altitude << ";" << voltagem5 << ";" << voltagem3 << ";" << "0" << ";" << "0" << ";" << "0" << ";" << "0" << ";" << "0" << ";" << "0" << ";" << "0" << ";" << Bussola << ";" << "0" << ";" << ChuvaValue << endl;
  /*int count = millis();
  int final = 1000 - (count - inic);
  if (final >= 0)
  {
    delay(final);
  }
  else
  {
  }
  **/
}

static double mediaLDR()
{
  int b = 0;
  double raw1 = 0, Vout1 = 0, Lux1 = 0;
  while (b <= 10)
  {
    raw1 = analogRead(luzsensor);
    Vout1 = (5.0 / 1023.0) * raw1 ;
    Lux1 += 500 / (10.0 * ((5 - Vout1) / Vout1));
    b++;
  }
  return Lux1 / 10;
}
void Codigo ()
{
  while (Serial.available()) {
    delay(10);
    if (Serial.available() > 0) {
      char c  = Serial.read();
      readString += c;
    }
  }
  //reinicia a placa
  if (readString.equals("cod0"))
  {
    //PROGRAMAR
  }
  //limpa EEPROM
  if (readString.equals("cod1-1"))
  {
    while (i <= 512)
    {
      EEPROM.write(i, 0);
    }
    EEPROM.write(3, 50);
    EEPROM.write(4, 50);
    EEPROM.write(5, 50);
  }
  if (readString.equals("BMP-1"))
  {
    BMP085 = false;
  }
  if (readString.equals("DHT-1"))
  {
    DHT11Bool = false;
  }
  if (readString.equals("LDR-1"))
  {
    LDR = false;
  }
  if (readString.equals("Anem-1"))
  {
    Anemometro = false;

  }
  if (readString.equals("BMP+1"))
  {
    BMP085 = true;
  }
  if (readString.equals("DHT+1"))
  {
    DHT11Bool = true;
  }
  if (readString.equals("LDR+1"))
  {
    LDR = true;
  }
  if (readString.equals("Anem+1"))
  {
    Anemometro = true;

  }
  if (readString.equals("Cel+1"))
  {
    celsius = true;
    fahrenheit = false;
    kelvin = false;
  }
  if (readString.equals("Fah+1"))
  {
    celsius = false;
    fahrenheit = true;
    kelvin = false;
  }
  if (readString.equals("Kel+1"))
  {
    celsius = false;
    fahrenheit = false;
    kelvin = true;
  }
  




  readString = "";
}
//unsigned int horaRTC, minutoRTC, segundoRTC, diaRTC, mesRTC, anoRTC, semanaRTC;

void ParametrosEEPROM()
{
  if (EEPROM.read(10) == 11)
  {
    BMP085 = true;
  }
  else if (EEPROM.read(10) == 10)
  {
    BMP085 = false;
  }
  if (EEPROM.read(11) == 21)
  {
    DHT11Bool = true;
  }
  else if (EEPROM.read(11) == 20)
  {
    DHT11Bool = false;
  }
  if (EEPROM.read(12) == 31)
  {
    LDR = true;
  }
  else if (EEPROM.read(12) == 30)
  {
    LDR = false;
  }
  if (EEPROM.read(13) == 41)
  {
    Anemometro = true;
  }
  else if (EEPROM.read(13) == 40)
  {
    Anemometro = false;
  }
  if (EEPROM.read(14) == 51)
  {
    celsius = true;
  }
  else if (EEPROM.read(14) == 50)
  {
    celsius = false;
  }
  if (EEPROM.read(15) == 61)
  {
    fahrenheit = true;
  }
  else if (EEPROM.read(15) == 60)
  {
    fahrenheit = false;
  }
  if (EEPROM.read(16) == 71)
  {
    kelvin = true;
  }
  else if (EEPROM.read(16) == 70)
  {
    kelvin = false;
  }




  /*erroBMP085 = false;
   BMP085 = true;
   DHT11Bool = true;
   LDR = true;
   Anemometro = true;
   fahrenheit = false;
   celsius = true;
   kelvin = false;
   */
}
// voltagemDHT, voltagemBMP,voltagemLDR, voltagemAnem, voltagemLinha;

void Volt()
{
  while (a < 10)
  {
    Vcc = readVcc() / 1000.0;
    ADCValue = analogRead(A5);
    voltagem5 += (ADCValue / 1023.0) * Vcc;
    a++;
  }
  voltagem5 = voltagem5 / a;
  limpaVar();
  while (a < 10)
  {
    Vcc = readVcc() / 1000.0;
    ADCValue = analogRead(A7);
    voltagem3 += (ADCValue / 1023.0) * Vcc;
    a++;
  }
  voltagem3 = voltagem3 / a;
  limpaVar();
  while (a < 10)
  {
    Vcc = readVcc() / 1000.0;
    ADCValue = analogRead(A2);
    ChuvaTemp += (ADCValue / 1023.0) * Vcc;
    a++;
  }
  ChuvaValue = ChuvaTemp / a;
  limpaVar();
  Serial << "voltage5v" << voltagem5 << endl;
  Serial << "voltage3v" << voltagem3 << endl;
  Serial << "Pluviometer" << ChuvaValue << endl;
}

void limpaVar()
{
  a = 0;
  headingDegreesSum = 0;
  ChuvaTemp = 0;
  scaledXSum = 0;
  scaledYSum = 0;
  scaledZSum = 0;
  rawXSum = 0;
  rawYSum = 0;
  rawZSum = 0;
  headingSum = 0;
}
long readVcc() {
  // Read 1.1V reference against AVcc
  // set the reference to Vcc and the measurement to the internal 1.1V reference
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
  ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
  ADMUX = _BV(MUX3) | _BV(MUX2);
#else
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif

  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Start conversion
  while (bit_is_set(ADCSRA, ADSC)); // measuring

  uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH
  uint8_t high = ADCH; // unlocks both

  long result = (high << 8) | low;

  result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
  return result; // Vcc in millivolts
}

Comments

Similar projects you might like

Arduino Environmental Monitoring

Project showcase by Prajay Basu

  • 14,538 views
  • 1 comment
  • 28 respects

Magic in the Bedroom

Project in progress by Randa El Ali and Jesse Laprad

  • 2,103 views
  • 0 comments
  • 3 respects

Rube Goldberg Weather Station with Internet Data Storage

Project in progress by randtekk

  • 6,027 views
  • 6 comments
  • 40 respects

Personal Weather Station (Arduino+ ESP8266 + Thingspeak)

Project tutorial by Jayraj Desai

  • 51,541 views
  • 32 comments
  • 107 respects

Temperature + Humidity on LCD

Project showcase by interpeo

  • 19,657 views
  • 11 comments
  • 49 respects

AWS - Arduino Weather Station

Project tutorial by GilettaStefano

  • 19,317 views
  • 13 comments
  • 63 respects
Add projectSign up / Login