Replace my PC (which has been on 24-7 for 6 years) and weather station software with an Arduino – Lower power consumption, less maintenance and smaller physical footprint. Minimum PC functionality requiring duplication:
• Logging of weather data (wind speed, wind direction, outdoor humidity, outdoor temperature, rain, UV, cloud height, wind chill, pressure, forecast, indoor temperature/humidity (x3 channels) every hour
• House power usage (logged every hour)
• Web page update showing current data and 24/48 hour trends for all elements above
• Email alerts of extremes
Hardware to be monitored
• Oregon Scientific WMR628 wireless weather station
• OWL power monitor
Following some extensive research on the web, I established that there was nothing that quite met my objectives so if I wanted to do this, I had to do it myself! Before we get into the design/code, I need to stress that I am an engineer, and as my IT group tell me on regular occasions, engineers don’t make good software developers. This will become apparent as we go through this process – however what I’ve built works, meets my needs and I’m quite pleased with the overall outcome. That’s not to say that I am not open to feedback (constructive of course!). As I lead you through the development, if there is anything that I could do more efficiently or just better, please let me know as it’s the only way I can learn!
Note in order to view the web pages from the weather station external to your local network, you will need to open a port on your router. This is not covered here.
Step 1: Decode the Wireless Signals
Step 2: Hardware
• RF receiver for Oregon Scientific sensors and RTC
• RF receiver for Cresta sensors, RTC and BMP085 barometric/temperature sensor
• External LM35 temperature sensor (waterproofed and measure the temperature of the stream in our garden) and external stream depth monitor (not detailed here, but uses an I2C ultrasonic distance meter mounted on a bridge to assess height of stream – interestingly, the depth can vary from 30cm to 150cm during heavy rain!).
However any combination should work and code can be modified to log/web serve as appropriate.
Schematic shows the components on the shield, as I indicate above, not all need to be used, but options are there if wanted. Not shown is the Ethernet shield too that simply plugs into the MEGA.
Components you’ll need:
1. Arduino MEGA 2560
2. Ethernet shield (with micro SD card)
3. RF 433MHz receiver (Aurel RX-4M50RR30SF used and functions well from here)
5. DS3234 RTC breakout module
6. LM35 temperature sensor (up to 2, optional)
7. BMP085 pressure sensor (optional)
In order to mount the Arduino and ‘shield’ into a standard Arduino enclosure, I had to remove two of the locating pins, but these are easily snapped off and do not impact the secure mounting of the hardware. Note that on the PCB, the receiver module is located on the underside of the PCB (plenty of room) so that the memory card can still be ejected without interference.
I used a 433MHz whip aerial to make the device look neater (not connected in the photo, but shown mounted on the box in the 2nd picture) – not sure it responds any better than my test aerial – a piece of wire; but looks a lot neater and more professional!
Step 3: Code for Logging Data
I have added a checksum to those elements that required validation as occasionally, erroneous data would be processed and skew the maximum/minimum data. Decoding of the Oregon Scientific signals was based on info found on the internet here and for the Cresta devices here. Note that the RF decoding code is different for each the Oregon Scientific and the Cresta devices. Examples of both are included in the example sketch file.
Step 4: Code for Web Serving
Originally, the code was intended to work on an UNO, but I needed to store large arrays of data (48 values x 13 groups) for the trend graphs (see example web page) and although the compile size came in under the 32k mark, the Arduino failed due to memory ‘overload’… Going to the MEGA also allowed additional functionality to be added (such as emails, sunrise etc.) without issue. Feel free to optimise the code and squeeze it onto the UNO…
The example file (graphs.htm) creates the web page below and makes use of the Google Charts api to render the charts with simple hyperlink calls. Note that the code only works with 8.3 named files (due to the use of SDFat), hence the use of .htm named files. To view the processed page, simply type the Arduino IP code:Port followed by /graphs.htm.
The code also includes maths for calculating some derived parameters, such as cloud base height and wind chill. Two other actions are available via URL in addition to the normal page delivery:
• YourIP:Port/EEPROM – Forces the current maximum and minimum (and rain count) to be logged in EEPROM. Useful to do before powering down for any reason to ensure that the yearly data is maintained. Note: the EEPROM is only written too once per day, at midnight. This extends the life of the Arduino EEPROM and as this device is intended to be powered indefinitely I figured daily was sufficient.
• YourIP:Port /TIME&year&mo&day&hr&mi – although an RTC has been used, it seems to lose time over a period. This function allows the user to reset the RTC (via the web) to the ‘correct time’ and to update for summer time changes.
The basic logging and Server code is based on the tutorial here and modified to suit both my needs and changes to Arduino 1.0 compiler.
• TimeLord Library
• EEPROMWriteAnything Library
• RTCLib Library
• SDFat Library (and Ethernet/SD card tutorial)
Step 5: Code for Email
Weather Station Alert email php script:
// The following lines read the parameters from the URL
$TO = 'email address 1';
$TO .= ', email address 2';
$FROM = 'your email address';
$SUBJECT = 'Weather Station Update';
$TIME = $_REQUEST["TIME"];
$TEMPNOW = $_REQUEST["TEMPNOW"];
$WSNOW = $_REQUEST["WSNOW"];
$WDNOW = $_REQUEST["WDNOW"];
$RAIN = $_REQUEST["RAIN"];
$TEMPMAX = $_REQUEST["TEMPMAX"];
$TEMPMIN = $_REQUEST["TEMPMIN"];
$WSMAX = $_REQUEST["WSMAX"];
$TRIGGER = $_REQUEST["TRIGGER"];
$MESSAGE = 'Message from Weather Station
Timed at ' .$TIME. '
- Temperature now is' .$TEMPNOW. 'C
- Wind Speed now is ' .$WSNOW. 'mph at deg
- Rain Today ' .$RAIN. 'mm
- Max Temperature Today is ' .$TEMPMAX. 'C
- Min Temperature Today is ' .$TEMPMIN. 'C
- Max Wind Speed Today is ' .$WSMAX. 'mph
Email sent due to ' .$TRIGGER. ';
// This sends the message
mail($TO, $SUBJECT, $MESSAGE, "From: ".$FROM);
There is also an email issued if there is power loss and the system is rebooted.
Step 6: Known Limitations and Areas for Improvement
2. Some of the coding is poor (I could make better use of functions/procedures and possibly even some library work (which is beyond me)) and I am sure there are more efficient ways of achieving the same ends. The code works and it does what I want it to do reliably (been running several months with no issues), but any improvements/recommendation welcome.
Hope this information is useful.