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>
*/