Go Down

Topic: Indoor weather station (Read 8051 times) previous topic - next topic

carl47

I have constructed an indoor weather station using an Arduino 2009.

It has a temperature sensor:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1259616399

It has a humidity sensor:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1264143673

It has a air pressure sensor:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1264823064/0#0

I can store up to 3 years of data on a 1Gb sd card.
I have used a sd card library class:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1259789744/0#0

The arduino code :

Code: [Select]
/*  On restart sends serial "ready" and current sd sector number.
   Current sd sector number held in EEPROM.
   Repeat every 10 seconds
   PC sends sd sector number to use and we start to get samples.
   Every 10 secs sample temperature humidity and airpressure.
   Send samples to PC and store in RAM.
   If 85 samples(255 bytes)in RAM save in sd card.
   If receive "u" and number from PC send requested sd sectors
   and RAM to the PC.
   If error in read/write to sd card stay in a loop and
   send "error" to PC every 10 seconds.
*/    
#include <EEPROM.h>
#include <SDCARD.h>    //read write 512 blocks to sd card
#include <stdlib.h>    // C utility functions
volatile unsigned char buffer[512] ;  //RAM store for samples
unsigned long lastmillis = 0;        // will store last time we looked
unsigned int tempsample = 0;  //adc temp averaged each 10 seconds
const int tempadc = 1;  // Analog input pin for temperature
const int pin = 7;   // digital input pin for humidity
const int sensor_offset = 1889;  //the offset to give correct RH value
unsigned long duration;  //pulse time of HCH-1000 timer
unsigned int humidsample = 0;  //humid  averaged each 10 seconds
unsigned int airsample =0;  //adc air averaged each 10 seconds
const int airadc = 0;  // Analog input pin for air pressure
unsigned int ramaddress =0;  //address of next storage location in RAM
unsigned long currentblock = 0; //the current block number in the sd card
unsigned long loadblocks = 0;  //the start upload sector from computer
int inbyte = 0;  // character input from computer in ASCII
char restartblock[8];  //the computer inputs the startblock number
boolean restarted = false;   //set when the computer restarts the avr

void setup()
{
 Serial.begin(9600);  // initialize serial communication with computer
 pinMode(9, OUTPUT);      // sets the digital pin as output for sample flash
 pinMode(8, OUTPUT);      // sets the digital pin as output for sd card error
 pinMode(pin, INPUT);  //humidity input
 digitalWrite(8, LOW);    //start  with sd card error led off
}

void loop()
{
 if ( ! restarted)  // if not restarted
 {
 while (Serial.available() == 0) //wait until computer is connected
   {
    ready();  //after restart send ready message
   }//end of wait till computer connected
  getcurrentblock();  //get the current block from computer
 }//end of not restarted
 
 if (millis() < lastmillis)
 lastmillis = 0;  //have a rollover every 52 days
 if (millis() - lastmillis > 10000)  //every 10 seconds
 {
   lastmillis += 10000;   // update the timer
   digitalWrite(9, HIGH);    //flash the led to show sampling
   
   if (Serial.available() > 0)   //do we have a computer command
   {
    inbyte = Serial.read();  //get the command
    if (inbyte  == 'u')   //download all the stored samples
    {   // computer sends "r4444" to upload all RAM and sd blocks from 4444
   
     byte j = 0;   // for start counter enter digits
     for (j = 0; j < 8 ; j +=1)
     restartblock[j] = '0';  //clear the buffer before read
     while (Serial.available() != 0)   //input the sd card start block
     {
      restartblock[j] = Serial.read();
      j +=1;   //next digit position
     }//end of input sd card start block
     loadblocks = strtoul(restartblock,0,10);   //this is requested atarting block
     if (loadblocks > currentblock)
     loadblocks = currentblock;   //we must never have or runs through whole card
     
     uploadbuffer(ramaddress);  //upload the current sample that are in ram
     Serial.println("r");  //tell computer all RAM samples are sent
     uploadsdblocks();  //upload the requested sd blocks
     Serial.println("e");  //tell computer all samples are sent      
    }//end of download all stored sample samples  
   }//end of we have a computer command
   
   tempsample = adc(tempadc);   //get the analog sample for temperature
   airsample = adc(airadc);  //get analog sample for air pressure
   humidity();  //get the sample for the humidity
   sendsample(); //send a sample to the computer
   
   if (ramaddress == 510)  //have we have filled the ram buffer
   {      
    lastblocksave();  //saved full ram to sd card so save block number
   }//end of have we filled the ram buffer
   
 }//end of every 10 seconds
 digitalWrite(9, LOW);  //turn led off  
}//end of loop

inline unsigned int adc(int pin)
{
unsigned int sample = 0;   //reset the sample value
//tempsample = 0;  //reset the average
int i = 0;
for(i; i<=64; i++)
sample += analogRead(pin);  //get 64 samples added together 1024 x 64 max
sample = sample / 64;  //get the average of 64 samples
return sample;
//tempsample +=sample;  //add the 10 second sample
}//end of adc


The arduino 2009 acts as a standalone weather station.
It does not display the data.It can operate independantly for months.
It samples the sensors until the RAM is full then The ram samples
are stored on a sector of a sd card.
Eventually a 3 years weather samples could be on on the 1Gb sd card.

Each time the PC is connected any unstored sectors are uploaded to
files on the PC's hard drive.
It then can be displayed using all the facilities of the PC's display.

The central idea is that the PC has a file copy of each sd card sector
stamped with the datetime it was recorded.

I have used visual basic for the PC program.
I find it easy to use when constructing GUI applications.
It does lock you in to windows but I can live with that.

Microsoft has a free download:

http://www.microsoft.com/express/Downloads/Download-2008.aspx#2008-Visual-Basic

If you have visual basic on your PC you can try my program.
You dont need an arduino it has 4 days of example data.


The programs and other files are at the site given below.
Download indoorweather.zip

http://sourceforge.net/projects/arduinoweather/files/

neels

Very nice.
I'm working on an outdoor wstation :), with weather meters from Sparkfun.indoor serial lcd, rtc and logging to usb.

is you time stamp quite accurate ? in a nutshell how did you do it?
do you record each sector with its ms time and then the vb program keeps track and works out the actual time?
Ciao
N

e12pilot

Very cool, I think I am going to try and get the SD card working with my project too.  Awesome to have some code to reference!

carl47

Thanks for the replies.

Quote
Neels


If you download indoorweather.zip you will see
a complete explaination of datestamping the sectors.

Its in a PDF file.

The PC clock is used as the RTC for the datestamps.

You are right the vb program does the work of datestamping and
display.

carl47

I finally found out how to get pictures on to the forum.
Reading the help page it says to use the "browse button".
I never found one.

This is the overall setup of the weather station:



This is the circuit of the station:






novice

Hi,
nice work.
Would you mind documenting which files do what?.

carl47

#6
Mar 05, 2010, 07:48 am Last Edit: Mar 05, 2010, 08:11 am by carl47 Reason: 1
You are right.

It's all getting a bit messy.

I'll work on something ...... any ideas?

I can put a label on each file as I have for the lightningpdf.pdf
file .

If I did that for each file would that be enough?

Go Up