Go Down

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


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 :

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:


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



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?


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


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:


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


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

Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

via Egeo 16
Torino, 10131