weatherstation v5.0

edit, its now sending floats, which would be the correct way. image update. shutdown adc to try to get more bat life and added bmp085 so all sensors now digital. updated code below.

im sure theres tons of these around, and im really interested in weather stations since taking these readings would be the first step in learning how to control the weather and take over the world. i wish i knew how to optimize code, thats my next step. this station sits outside and uses a dht11 and a mpx4115 pressure sensor and transmits data wireless using the rf24 library. it also writes the data to an eeprom to dump later for spreadsheet usage. i get temperature, humidity, barometer, heat index and dew point. ive put together a serial reader using micro visual studio as a finishing touch for reading out on a laptop. i had a lot of fun making this and now im gonna see how it can be better, especially since i got my 18b20 in the mail today. suggestions appreciated. code below.

im running this entire project off a cellphone battery using an mcp1253 boost/buck ic, at 3.3v, with the atmega328p at 8Mhz ext crystal @ 3.3v.
board file for atmega

##############################################################

pro328.name=Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega328

pro328.upload.protocol=stk500
pro328.upload.maximum_size=32256
pro328.upload.speed=57600

pro328.bootloader.low_fuses=0xFF
pro328.bootloader.high_fuses=0xDE
pro328.bootloader.extended_fuses=0x05
#pro328.bootloader.path=optiboot
#pro328.bootloader.file=optiboot_atmega328_pro_8MHz.hex
pro328.bootloader.path=atmega
pro328.bootloader.file=ATmegaBOOT_168_atmega328_pro_8MHz.hex
pro328.bootloader.unlock_bits=0x3F
pro328.bootloader.lock_bits=0x0F

pro328.build.mcu=atmega328p
pro328.build.f_cpu=8000000L
pro328.build.core=arduino

here is the clock im using, totally compatible with rtc library, sends interupt every minute to wake the system, takes samples, then goes back to sleep for a minute.

//WeatherStation v4. Lou Rose. 07/04/2013.
/* 07/04/2013: added typedef struct to send floating values
 added support for BMP085 to replace MPX4115 pressure sensor to eliminate
 ADC. 
 has support for onewire DS18B20.
 License info below. */
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
//#include <OneWire.h>
//#include <DallasTemperature.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/power.h>
#include <Wire.h>
#include <RTClib.h>
#include <dht.h>
#include <Adafruit_BMP085.h>
//#define ONE_WIRE_BUS 7
RF24 radio(9,10);
const uint64_t pipe = 0xE8E8F0F0E1LL;
//variables
typedef struct{ 
  float T; //temperature
  float RH;
  float HI;
  float DP;
  float pressure;
} 
payload;
payload ard1;

//int payload[5];

//======================================================
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
//OneWire oneWire(ONE_WIRE_BUS);
RTC_DS1307 RTC;
Adafruit_BMP085 bmp;
dht DHT;
#define DHTPIN 8 
#define DHTTYPE DHT22
// Pass our oneWire reference to Dallas Temperature. 
//DallasTemperature sensors(&oneWire);
//DeviceAddress insideThermometer;
//======================================================
void setup(void)
{
  ADCSRA = 0; //disable adc: so it can
  PRR = 0x01; // shutdown   
  radio.begin();
  radio.openWritingPipe(pipe);
  // start serial port
  Serial.begin(9600);
  bmp.begin(); //Serial.print(bmp.readPressure()); pa
  Wire.begin();
  RTC.begin();
  Wire.beginTransmission(0x68); //config register
  Wire.write(0x0E); 
  Wire.write(0x1e);
  Wire.endTransmission();
  Wire.beginTransmission(0x68);
  Wire.write(0x0b); //alarm2 addr
  Wire.write(0x80); //data to 0x0b
  Wire.write(0x80); //data to 0x0c
  Wire.write(0x80); //data to 0x0d
  Wire.endTransmission();

  clearAlarm();
  delay(100);
  //  sensors.begin(); // one wire code
  //  sensors.isParasitePowerMode();
  //    if (!sensors.getAddress(insideThermometer, 0))  
  //    {
  //      Serial.println( "Unable to find address for Device 0" ); 
  //    }

  //  Serial.print("Device 0 Address: ");
  //  printAddress(insideThermometer);
  //  Serial.println();
  //  sensors.setResolution(insideThermometer,12);

  //  Serial.print(sensors.getResolution(insideThermometer),DEC);
  //  Serial.println(" bit-resolution");

  pinMode(2, INPUT);
  digitalWrite(2,HIGH);
  attachInterrupt(0, alarmTriggered, FALLING); 
  interrupts();
  Serial.println( "Mission in one minute" );
  delay(2000);
}

void loop(void)
{ 
  clearAlarm();
  getSample();
  enterSleep();
}

void getSample(){
  int chk = DHT.read22(DHTPIN);
  //  sensors.requestTemperatures(); // Send the command to get temperatures
  //  Serial.print("Temperature for Device 1 is: ");
  //
  //  T=(sensors.getTempF(insideThermometer)); 
  //  Serial.println(T);
  ard1.T=(Fahrenheit(DHT.temperature));
  ard1.pressure=(bmp.readPressure()*.0002961);
  //  ard1.pressure=analogRead(0);
  //  ard1.pressure=analogRead(0);
  //  ard1.pressure = ((ard1.pressure * .0049 / 5) + .095) / .009; 
  //  ard1.pressure = ard1.pressure *.2952997;

  ard1.RH=DHT.humidity;
  //Serial.println((float)DHT.humidity, 2);
  ard1.DP=Fahrenheit(dewPoint(DHT.temperature, DHT.humidity));
  //Serial.println(DP);
  ard1.HI=heatIndex(ard1.T, ard1.RH);
  //Serial.println(HI);

  radio.write( &ard1, sizeof(ard1) );



}

double Fahrenheit(double celsius)
{
  return 1.8 * celsius + 32;
}


//void printAddress(DeviceAddress deviceAddress)
//{
//  for (uint8_t i = 0; i < 8; i++)
//  {
//    // zero pad the address if necessary
//    if (deviceAddress[i] < 16) Serial.print("0");
//    Serial.print(deviceAddress[i], HEX);
//  }
//
//}

void enterSleep(void)
{
  //  Serial.println("sleeping...");
  /* Setup pin2 as an interrupt and attach handler. */

  attachInterrupt(0, alarmTriggered, LOW);
  delay(100);

  set_sleep_mode(SLEEP_MODE_PWR_DOWN);

  sleep_enable();

  sleep_cpu();

  /* The program will continue from here. */

  /* First thing to do is disable sleep. */
  sleep_disable(); 

}

void alarmTriggered()
{
  //  Serial.println("** ALARM WENT OFF! **");
  detachInterrupt(0);
}
void clearAlarm(){
  Wire.beginTransmission(0x68); // clear alarm af2 bit
  Wire.write(0x0F); //addr
  Wire.write(0x80);
  Wire.endTransmission();
}

// 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);
}

//heat index function
//reference http://www.hpc.ncep.noaa.gov/htl/heatindex_equation.shtml 
double heatIndex(double T, double RH)
{
  double result;
  result= -42.379 + 2.04901523*T + 10.14333127*RH - .22475541*T*RH - 
    .00683783*T*T - .05481717*RH*RH + .00122874*T*T*RH + .00085282*T*RH*RH - 
    .00000199*T*T*RH*RH;
  return result;
}

/*
<Weather Station>
  <2013>  <L.C. ROSE>
 
 
 */

weatherstation.png

Cool project, ive been toying with the idea to make a weather station too.

thank you, still working on it. id really like to make this a function (heat index) but i keep getting errors.

HI = -42.379 + 2.04901523*T + 10.14333127*RH - .22475541*T*RH - 
    .00683783*T*T - .05481717*RH*RH + .00122874*T*T*RH + .00085282*T*RH*RH - 
    .00000199*T*T*RH*RH;

heat index function.

seems to be working

NOTE. variable is labeled celcius. i made a mistake for this example, it should be farenheit .

double HI;
float celcius=75.14; //test value
float humidity=49.23; //test value
void setup(){
  Serial.begin(9600);
}

void loop(){
HI=heatIndex(celcius, humidity);
Serial.println(HI);
delay(2000);
}

 
 //heat index function
  //reference http://www.hpc.ncep.noaa.gov/html/heatindex_equation.shtml 
 double heatIndex(double celcius, double humidity)
{
  double result;
 result= -42.379 + 2.04901523*celcius + 10.14333127*humidity - .22475541*celcius*humidity - 
 .00683783*celcius*celcius - .05481717*humidity*humidity + .00122874*celcius*celcius*humidity + .00085282*celcius*humidity*humidity - 
 .00000199*celcius*celcius*humidity*humidity;
return result;
}