Indoor weather station

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

It has a temperature sensor:

It has a humidity sensor:

It has a air pressure sensor:

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

The arduino code :

/*  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 =;  //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] =;
       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:

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.

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

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!

Thanks for the replies.


If you download 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

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:

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

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?