Renan Willian Paiva
Published © GPL3+

ArduWeather

Aviation meteorology station with Arduino.

AdvancedWork in progress4,124
ArduWeather

Things used in this project

Hardware components

Arduino Mega 2560
Arduino Mega 2560
×1
DHT11 Temperature & Humidity Sensor (4 pins)
DHT11 Temperature & Humidity Sensor (4 pins)
×1
Pressure/Altitude/Temperature Sensor
Adafruit Pressure/Altitude/Temperature Sensor
×1
DC motor (generic)
×1
Photo resistor
Photo resistor
×1
Temperature Sensor
Temperature Sensor
×1

Story

Read more

Code

ArduWeather Arduino Code

Arduino
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
}

Credits

Renan Willian Paiva
1 project • 4 followers
.NET Junior programmer, 2.5 years of experiencing in Arduino and Eletronics. Projects mostly for aviation area
Contact

Comments

Please log in or sign up to comment.