Alert.png

Notice: This page contains information for the legacy Phidget21 Library.

Phidget21 is out of support. Bugfixes may be considered on a case by case basis.

Phidget21 does not support VINT Phidgets, or new USB Phidgets released after 2020. We maintain a selection of legacy devices for sale that are supported in Phidget21.

We recommend that new projects be developed against the Phidget22 Library.


Click on the 2phidget22.jpg button in the menu bar to go to the Phidget22 version of this page.

Alert.png

Weather Station: Difference between revisions

From Phidgets Legacy Support
No edit summary
 
(56 intermediate revisions by 3 users not shown)
Line 8: Line 8:
[[Category:weatherproofing]]
[[Category:weatherproofing]]
[[Category:mounting]]
[[Category:mounting]]
[[Category:Application Guides]]
The project described here is a simple weather station that measures air temperature, humidity, and surface temperature of the ground below the weather station.   
The project described here is a simple weather station that measures air temperature, humidity, and surface temperature of the ground below the weather station.   
{|
{|
|Practical concepts covered are:
|Practical concepts covered are (click on links to see other projects on that topic):
* [[Powering your Phidget]]
* Powering your Phidget
** Battery power  
** [[:Category:BatteryPower|Battery power]]
** Solar power
** [[:Category:SolarPower|Solar power]]
* [[Using the SBC]]
* [[:Category:PhidgetsSBC|Using the SBC]]
** Using analog sensors
** Using analog sensors
** Using LEDs
** Using LEDs
** Using USB sensors
** Using USB sensors
* [[Data Logging]]
* Data Logging
** Recording samples at a certain time
** Recording samples at a certain time
** Writing to a text file
** [[:Category:FileIO|Writing to a text file]]
** Writing to a USB key
** [[:Category:RemovableStorage|Writing to a removable USB key]]
** Using the SBC cron scheduler
** [[:Category:Scheduler|Using the SBC cron scheduler]]
** Using Phidgets with Python
** Using Phidgets with Python
* [[Fixed Structures]]
* Fixed Structures
** Weather resistance
** [[:Category:Weatherproofing|Weather resistance]]
** General planning and assembly
** [[:Category:Mounting|General planning and assembly]]
|width="45px"| 
|width="45px"| 
|[[Image:app_guide_weatherstn_introphoto.jpg|500px|link=|alt=]]
|[[Image:app_guide_weatherstn_introphoto.jpg|500px|link=|alt=]]
|}
|}


As with any of our [[Application Guides|described projects]], Phidgets takes care of the electrical component design.  Still, a project of this magnitude require a time investment in addition to a monetary investment.  Designing projects like these is hard.


But the reward is deep - and very real.  A full, functional outdoor sensor system that you can build to whatever specifications you like... ask any hobbyist and you may see their eyes light up remembering their latest project.  Building such things is a special kind of freedom!
{| style="border:1px solid darkgray;" cellpadding="5px;"
|'''Time:'''
| About 6 full days of work, including gathering components, writing code, and drilling/assembling
|-
|'''Special Needed Tools:'''
|Drill, soldering iron, small screwdriver, socket and wrench set
|-
|'''Other Useful Tools:'''
|Hammer, tin snips for pipe strapping
|-
|'''Materials and Phidgets:'''
|Extensive lists are provided in this guide
|}
 


'''Time:''' About 6 full days of work, including gathering components, writing code, and drilling/assembling
As with any of our [[:Category:Application Guides|described projects]], Phidgets takes care of the electrical component design.  Still, a project of this magnitude require a time investment in addition to a monetary investment.  Designing projects like these is hard.


'''Special Needed Tools:''' Drill, soldering iron, small screwdriver, socket and wrench set
But the reward is deep - and very real.  A full, functional outdoor sensor system that you can build to whatever specifications you like... ask any hobbyist and you may see their eyes light up remembering their latest project.  Building such things is a special kind of freedom!


'''Other Useful Tools:''' Hammer, tin snips for pipe strapping


__TOC__
__TOC__
Line 49: Line 61:
On this page, we describe this particular setup to get you started:
On this page, we describe this particular setup to get you started:


[[File:app_guide_weatherstn_station.png|800px|link=|alt=]]
[[File:app_guide_weatherstn_station.png|900px|link=|alt=]]


We start with all of the pieces (the Phidgets, the power supply, the main structure, and the code) and then put it all together.
We start with all of the pieces (the Phidgets, the power supply, the main structure, and the code) and then put it all together.
Line 55: Line 67:
==Phidgets==
==Phidgets==


At the core of this weather logging station is the [[1072 - PhidgetSBC2|Phidget Single Board Computer (SBC)]].  The sensors and other attachments from Phidgets could include:
At the core of this weather logging station is the [{{SERVER}}/products.php?product_id=1072 Phidget Single Board Computer (SBC2)].  The sensors and other attachments from Phidgets could include:


{| style="border:1px solid darkgray;" cellpadding="5px;"
{| style="border:1px solid darkgray;" cellpadding="5px;"
Line 67: Line 79:
* Control the USB Phidget (IR sensor)
* Control the USB Phidget (IR sensor)
* Run the code
* Run the code
|[[1072 - PhidgetSBC2]]
|[{{SERVER}}/products.php?product_id=1072 1072 - PhidgetSBC2]
|- style="background: #efefef;"
|- style="background: #efefef;"
|
|
* Read surface temperature of ground, without touching it
* Read surface temperature of ground, without touching it
* Provide ambient air temperature at board location
* Provide ambient air temperature at board location
|[[1045 - PhidgetTemperatureSensor IR]]
|[{{SERVER}}/products.php?product_id=1045 1045 - PhidgetTemperatureSensor IR]
|- style="background: #efefef;"
|- style="background: #efefef;"
|
|
* Measure ambient air temperature
* Measure ambient air temperature
* Measure ambient air humidity
* Measure ambient air humidity
|[[1125 - Humidity/Temperature Sensor]]
|[{{SERVER}}/products.php?product_id=1125 1125 - Humidity/Temperature Sensor]
|- style="background: #efefef;"
|- style="background: #efefef;"
|
|
* Control the analog-in [[1125 - Humidity/Temperature Sensor]]
* Read the analog-in [{{SERVER}}/products.php?product_id=1125 Humidity/Temperature Sensor]
* Control LEDs to display status
* Control LEDs to display status
|
|
[[1018 - PhidgetInterfaceKit 8/8/8]] <br>
[{{SERVER}}/products.php?product_id=1018 PhidgetInterfaceKit 8/8/8] <br>
(included on-board with the [[1072 - PhidgetSBC2]])
(included on-board with the [{{SERVER}}/products.php?product_id=1072 1072 PhidgetSBC2])
|- style="background: #efefef;"
|- style="background: #efefef;"
|
|
* Take pictures
* Take pictures
|[[3402 - USB Webcam]]
|[{{SERVER}}/products.php?product_id=3402 3402 USB Webcam]
|- style="background: #efefef;"
|- style="background: #efefef;"
|
|
* Display Status
* Display Status
| 3601 - 10mm Green LED / 3600 - 10mm Red LED
| [{{SERVER}}/products.php?product_id=3601 3601 - 10mm Green LED] / [{{SERVER}}/products.php?product_id=3600 3600 - 10mm Red LED]
|- style="background: #efefef;"
|- style="background: #efefef;"
|
|
Line 99: Line 111:
|}
|}


The SBC has the ability to run both USB-based Phidgets (such as the [[1045 - PhidgetTemperatureSensor IR]]) and analog-based Phidgets (such as the [[1125 - Humidity/Temperature Sensor]]).  But we have a variety of different environmental sensors that you could use on your system.  The included [[1018 - PhidgetInterfaceKit 8/8/8]] on board the SBC can handle up to 8 analog sensors, and 8 digital in sensors like switches.
The SBC has the ability to run both USB-based Phidgets (such as the [{{SERVER}}/products.php?product_id=1045 1045 - PhidgetTemperatureSensor IR]) and analog-based Phidgets (such as the [{{SERVER}}/products.php?product_id=1125 1125 - Humidity/Temperature Sensor]).  But we have a variety of different environmental sensors that you could use on your system.  The included [{{SERVER}}/products.php?product_id=1018 1018 - PhidgetInterfaceKit 8/8/8] on board the SBC can handle up to 8 analog sensors, and 8 digital in sensors like switches.
 
Take note that the rated temperature range for the SBC is 0-70&deg;C.  You will also notice that it looks substantially colder in most of the pictures than 0&deg;C!  There are a few reasons for this.  The first is that the SBC is being kept in a sealed container with some (admittedly minor) insulation.  Also keep in mind that the SBC will generate heat just like any electronics that have power flowing through them; the SBC is essentially a 1W heater all by itself which, when inside the case, keeps the temperature up significantly above the outside temperature.  That said the temperature inside the case is still below 0 on a fairly regular basis.  This just goes to show you that the temperature range is not a hard limit and the board will function below it, however there are no guarantees at this point, the SBC could stop functioning at basically any time.  It would start up again as the temperature increased but it is very likely that the board seizes up and remains inoperable for long periods of time if it is not being monitored.  This was a risk we took and luckily we didn't run into any issues.  For the record the coldest temperatures we recorded during the operation of this weather station were between -10 and -15&deg;C.  I would not recommend attempting to run it in a colder environment than that without steps being taken to actively heat the board. 


Using these components requires a bit of care, so the next sections give some suggestions on how to use each Phidget.
Using these components requires a bit of care, so the next sections give some suggestions on how to use each Phidget.
Line 109: Line 123:
The IR board should be:
The IR board should be:
* Encased and sealed (such as with a Phidget Enclosure and low-temperature caulk) against the weather
* Encased and sealed (such as with a Phidget Enclosure and low-temperature caulk) against the weather
* Suspended at the right height for the sample size of ground needed (see the [[1045 - PhidgetTemperatureSensor IR]] specifications for the degrees of view you have)
* Suspended at the right height for the sample size of ground needed (see the [{{SERVER}}/products.php?product_id=1045 1045 - PhidgetTemperatureSensor IR] specifications for the degrees of view you have)
* Suspended far enough away from the station that it is measuring only ground, and not measuring the base of the station
* Suspended far enough away from the station that it is measuring only ground, and not measuring the base of the station
* Reasonably protected from solar heating (having a large station arm above it and shading it will probably do it)
* Reasonably protected from solar heating (having a large station arm above it and shading it will probably do it)
Line 115: Line 129:
Note that you will need to calibrate the data received from this sensor.  When you can control all of the variables around what you are using the IR board to measure, you can get very accurate measurements.  But in the out-of-doors with a weather station, you will use the board temperature, any shaded temperatures you get from the [[#Phidget Temperature and Humidity Sensor|second temperature sensor]], and thermal measurement theory to correct the value the sensor receives.  Error includes:
Note that you will need to calibrate the data received from this sensor.  When you can control all of the variables around what you are using the IR board to measure, you can get very accurate measurements.  But in the out-of-doors with a weather station, you will use the board temperature, any shaded temperatures you get from the [[#Phidget Temperature and Humidity Sensor|second temperature sensor]], and thermal measurement theory to correct the value the sensor receives.  Error includes:
* Warming of the IR board itself (i.e. you may need corrections based on board temperature)
* Warming of the IR board itself (i.e. you may need corrections based on board temperature)
* Emissivity of your subject being less than 1.0 (for more information on emissivity, see the [[1045 - PhidgetTemperatureSensor IR]] product page)
* Emissivity of your subject being less than 1.0 (for more information on emissivity, see the [{{SERVER}}/products.php?product_id=1045 1045 - PhidgetTemperatureSensor IR] product page)
* Measurement of any reflected heat in addition to emitted heat (this also depends on the emissivity)
* Measurement of any reflected heat in addition to emitted heat (this also depends on the emissivity)


Line 191: Line 205:
* ''70 Amp hours'' - this battery probably only has 42 amp hours, but you can call the manufacturer to make sure
* ''70 Amp hours'' - this battery probably only has 42 amp hours, but you can call the manufacturer to make sure


The battery will probably be a higher cost than the solar panel.  A 60-70 usable amp-hour lead acid battery will be about $100 and 50 lbs.  When choosing a battery, the 'buy in bulk' philosophy can come into play.  For example, this station ended up using a 110 amp-hour battery, which was $115 and 65 lbs.  This is not much weight or price difference for nearly double the power capacity.  And extra power capacity will give you extra buffer for when your wires wiggle loose, or when you are testing your system at the beginning.
The battery will probably be a higher cost than the solar panel.  A 60-70 usable amp-hour lead acid battery will be about $100 and 50 lbs.  When choosing a battery, the 'buy in bulk' philosophy can come into play.  For example, this station ended up using a 110 amp-hour battery, which was $115 and 65 lbs.  This is not much weight or price difference for nearly double the power capacity.  And extra power capacity will give you extra buffer when you are testing your system at the beginning.


There are many different types of deep cycle batteries - not just lead acid - and they vary in price significantly.  There are resources all over the Internet about different battery types to use with solar panels, so we will not describe them here.  The key deciding factor is how long the installation is designed to last.  Lead acid batteries have a lifespan of about three years.  Longer than that, and you will need to purchase a more expensive battery.
There are many different types of deep cycle batteries - not just lead acid - and they vary in price significantly.  There are resources all over the Internet about different battery types to use with solar panels (as well as [[Electricity Primer#Battery Power|a primer that we have]]), so we will not describe them here.  The key deciding factor is how long the installation is designed to last.  Lead acid batteries have a lifespan of about three years.  Longer than that, and you will need to purchase a more expensive battery.


[[File:app_guide_weatherstn_battery.jpg|800px|link=|alt=]]
[[File:app_guide_weatherstn_battery.jpg|800px|link=|alt=]]
Line 203: Line 217:
{| style="border:1px solid darkgray;" cellpadding="5px;"
{| style="border:1px solid darkgray;" cellpadding="5px;"
|- style="background: #c0c0c0;"
|- style="background: #c0c0c0;"
! Component
! Components
|-  
|-  
| Station Tripod
| Station Tripod
Line 258: Line 272:
We will be writing our Phidget code in Python.  This code will then be scheduled to run - via [[OS - Phidget SBC#Via Cron|cron]] on the SBC - to sample data once per minute and take a webcam photo once every thirty minutes.
We will be writing our Phidget code in Python.  This code will then be scheduled to run - via [[OS - Phidget SBC#Via Cron|cron]] on the SBC - to sample data once per minute and take a webcam photo once every thirty minutes.


Since the weather station runs autonomously - on its own, in the wild - you will need to write code that runs on the SBC itself, as you will have no external computer to control the SBC.  This depends on the SBC being set up as described in the [[1072 - Getting Started]] page, and then additionally as described in the [[OS - Phidget SBC]] page.  Namely, to follow along with this particular station design, you will need:
Since the weather station runs autonomously - on its own, in the wild - you will need to write code that runs on the SBC itself, as you will have no external computer to control the SBC.  This depends on the SBC being set up as described in the [[1072 User Guide]] page, and then additionally as described in the [[OS - Phidget SBC]] page.  Namely, to follow along with this particular station design, you will need:
* [[OS - Phidget SBC#SSH|SSH]] enabled
* [[OS - Phidget SBC#SSH|SSH]] enabled
* [[OS - Phidget SBC#Installing Python|Python installed]]
* [[OS - Phidget SBC#Installing Python|Python installed]]


Of course, there are many, many other ways to design this code - in Java, to run at boot rather than as a cron job, and so on - and many of these alternatives are outlined on the [[OS - Phidget SBC]] page.
Of course, there are many, many other ways to design this code - in Java, to run at boot rather than as a cron job, and so on - and many of these alternatives are outlined on the [[OS - Phidget SBC]] page.
For this example, we have two [[Language - Python|Python scripts]]: {{Code|station.py}} which runs the sensors once per minute and saves the data, and {{Code|webcam.py}} which saves a webcam picture once per minute. You can download the files [http://www.instructables.com/files/orig/FZF/K2QV/HW1M9HIP/FZFK2QVHW1M9HIP.zip here].


===Station===
===Station===


The station program has three jobs:
The station code in {{Code|station.py}} has three jobs:
* Reading data, which is the gathering and saving of the weather data,
* Reading data, which is the gathering and saving of the weather data,
* Displaying status via the Interface Kit and LEDs, and
* Displaying status via the Interface Kit and LEDs, and
* Moving data onto a second USB key (optional)
* Moving data onto a second USB key (optional)


====Reading Data====
====Reading and Recording Data====
 
This station handles two USB Phidgets (the Interface Kit on the SBC board, and the IR Temperature sensor), and two analog Phidgets (air temperature, and humidity).
 
We have code snippets for using more than one USB Phidget on the [[General Phidget Programming#Using Multiple Phidgets|General Phidget Programming page]].  To use more than one analog sensor, you simply use the port number it is plugged in to.  As shown on the general programming page, you can automatically detect which USB Phidgets are attached, without knowing their serial number.  But you cannot detect which analog ports are being used, unless create an ad-hoc method, such as assuming a value of 0 means no sensor is attached, and any other value indicates an attached sensor.
 
After we read the data from the Phidgets, we want to save it on the USB data key.  We can either hard-code the location or automatically detect where the key is plugged in.  Using USB keys with the SBC is discussed in detail on the [[OS - Phidget SBC#Using USB Data Keys|SBC operating system page]].  We will hard-code the location in this section's code, but we show how to automatically detect a USB key in the [[#Moving USB Data|Moving USB Data]] section.
 
Here we open the two USB Phidgets, read the IR temperature state, read the two analog in sensors, write the data to an existing file on the USB data key, and turn on and off an LED looks like:
 
<div class="source">
<syntaxhighlight lang=python>
#! /usr/bin/python
 
from Phidgets.PhidgetException import *
from Phidgets.Events.Events import *
from Phidgets.Devices.InterfaceKit import *
from Phidgets.Devices.TemperatureSensor import *
from time import sleep
from datetime import *
 
errors = ""
fileLocation = "/media/usb0/data.txt"
weatherLED = 0  # Digital out port position
 
def close():
    global interfaceKit
    global temperatureSensor
    global errors
    try:
        interfaceKit.setOutputState(weatherLED,0)
    except PhidgetException as e:
        errors = errors + "Phidget Exception on turning off LED\n"
    temperatureSensor.closePhidget()
    interfaceKit.closePhidget()
 
try:
    temperatureSensor = TemperatureSensor()
    interfaceKit = InterfaceKit()
except RuntimeError as e:
    errors = errors + "Runtime Exception on object creation\n"
 
try:
    # Replace these serial numbers with your own
    temperatureSensor.openPhidget(142768)
    interfaceKit.openPhidget(48498)
except PhidgetException as e:
    errors = errors + "Phidget Exception on Open\n"
 
try:
    interfaceKit.waitForAttach(1000)
    temperatureSensor.waitForAttach(1000)
except PhidgetException as e:
    errors = errors + "Phidget Exception on Attach\n"
 
try:
    # Turn the LED on
    interfaceKit.setOutputState(weatherLED,1)
    # Temperature and humidity are both ratiometric
    interfaceKit.setRatiometric(1)
except PhidgetException as e:
    errors = errors + "Phidget Exception on Ratiometric turn on\n"
 
# To let the LED stay on for a visually detectable amount of time
sleep(0.5)
 
try:
    # These conversions are in the product manual
    currentTemp = (interfaceKit.getSensorValue(0) * 0.22222) - 61.11
    currentRH = (interfaceKit.getSensorValue(1) * 0.1906) - 40.2
except PhidgetException as e:
    errors = errors + "Phidget Exception on reading Temperature and RH\n"
 
try:
    currentIRTemp = temperatureSensor.getTemperature(0)
    boardTemp = temperatureSensor.getAmbientTemperature()
except PhidgetException as e:
    errors = errors + "Phidget Exception on reading IR Temperature" 
 
outputLine = ""
outputLine = outputLine + str(datetime.now()) + ","
outputLine = outputLine + "T=" + str(currentTemp) + ","
outputLine = outputLine + "RH=" + str(currentRH) + ","
outputLine = outputLine + "IR-T=" + str(currentIRTemp) + ","
outputLine = outputLine + "IR-Brd=" + str(boardTemp) + "\n"
 
appendFile = open(fileLocation, 'a')
appendFile.write(outputLine)
if errors is not "":
    appendFile.write(str(datetime.now()) + ":\n" + errors)
appendFile.close()
 
close()
exit(0)
</syntaxhighlight>
</div>
 
This code snippet shows only one LED in use to show status, attached to digital output port 0 (short LED wire goes into the ground '''G''' terminal).  For ideas on using other LEDs to display the status of the SBC and your program, see the [[#Status|status section]].


After this, you will have a file {{Code|data.txt}} full of lines that look like this:
After running this a number of times, you will have a file {{Code|data.txt}} full of lines that look like this:


<div class="source">
<div class="source">
Line 281: Line 394:
</div>
</div>


Show how to attach Phidgets without knowing their serial numbers
This can be written differently to start with, or parsed later into whatever data analysis program you want to use.


====Moving USB Data====
====Moving USB Data====


The station was visited once per week to obtain the data.  With this setup, you can either:
The station was visited once per week to obtain the data.  On these visits, we would simply change out the old USB key for a new one on every visit, and reboot the SBC.
# Write some extra code to copy all of the latest data to a second USB key when it is plugged in, or
# Simply change out the old USB key for a new one on every visit, and reboot the system


After experimenting with both, it turned out that the second option worked well and was the simplest.  Rebooting the station at every visit was no problem because the cron job simply restarts as soon as the SBC restarts.  Having only one key with the data on it for the week, and then installing a fresh one created only one key to keep track of at a time.
We also considered the alternative of writing some extra code to detect when a second USB key is plugged in and copy all of the latest data to it.


However, if you wish to use the copy method instead, you can use the mount table to detect a second USB key like this:
After experimenting with both, it turned out that the change-and-reboot option worked well and was the simplest.  Rebooting the station at every visit was no problem because the cron job simply restarts as soon as the SBC restarts.  Having only one key with the data on it for the week, and then installing a fresh one, created only one key to keep track of at a time.


However, the copy method may be useful in other instances.  You can use the mount table to detect a second USB key and write to it like this (the mount  and cp shell commands are discussed on the [[OS - Phidget SBC]] page):
<div class="source">
<syntaxhighlight lang=python>
#! /usr/bin/python
from time import sleep
from datetime import *
import shlex, subprocess
# If this code might start again via cron, we want to ensure only one process writing to the USB key
# The file contains a "1" to denote a process is using the second key, and "0" otherwise
lockFile = "/root/WeatherStation/semaphore.txt"
# The shell command to check the location of a second USB key
checkUSBcommand = "mount | grep sdb1"
# Spawn a command line process, and obtain the output (e.g. the lines from "mount" with "sdb1" in them)
checkUSBprocess = subprocess.Popen(checkUSBcommand, shell=True,
                            stdin=subprocess.PIPE, stdout=subprocess.PIPE)
output = checkUSBprocess.communicate()[0]
usbLocation = None  # A default value
if len(output) > 3:  # If we have more than a newline, key is attached
    outputArray = output.split("usb")
    usbLocation = outputArray[1][0]  # Get the number right after "usb"
# If there is no usb key, remove any locks - especially useful for multiple cron processes
if usbLocation is None:
    file = open(lockFile, "w")
    file.write("0\n")
    file.flush()
    file.close
    exit(0)
file = open(lockFile, "r")
lock = file.readline().rstrip()
if lock is not "0":  # If another process is already writing
    exit(0)
# If we've gotten this far, there is a key and we need to write to it.
# Lock the semaphore
file = open(lockFile, "w")
file.write("1\n")
file.flush()
file.close
usbLocation = "/media/usb" + usbLocation + "/"
# Copy the data file via a spawned shell process
copyDataCommand = "cp /media/usb0/data.txt " + usbLocation
dataProcess = subprocess.Popen(copyDataCommand,
shell=True, stdout=subprocess.PIPE)
# The copy might take a while, so check every so often and sleep until done
while dataProcess.poll() != 0:
        sleep(0.1)
# Copy any webcam images via a spawned shell process
copyImagesCommand = "cp /media/usb0/*.jpg " + usbLocation
imageProcess = subprocess.Popen(copyImagesCommand,
                        shell=True, stdout=subprocess.PIPE)
# Again, the copy might take a while, so check every so often and sleep until done
while imageProcess.poll() != 0:
        sleep(0.1)
# Unlock the semaphore
file = open(lockFile, "w")
file.write("0\n")
file.close
exit(0)
</syntaxhighlight>
</div>


====Status====
====Status====
Line 309: Line 497:


===Webcam===
===Webcam===
There is a lot of information on the [[#OS - Phidget SBC#Taking Pictures With the Webcam|SBC operating system page]] on using UVC compatible webcams. That section describes how to install the {{Code|opencv}} supporting library, which was used to control the webcam.
The code {{Code|webcam.py}} run once every 30 minutes to take a picture was:
<div class="source">
<syntaxhighlight lang=python>
#! /usr/bin/python
import cv
from datetime import *
webcam = cv.CaptureFromCAM(0)
image = cv.QueryFrame(webcam)
# Compose a fixed-width date label for the file
now = datetime.now()
filename = str(now.year)
if len(str(now.month)) == 1:
    filename += "0" + str(now.month)
else:
    filename += str(now.month)
if len(str(now.day)) == 1:
    filename += "0" + str(now.day)
else:
    filename += str(now.day)
filename += "-" + str(now.hour) + "-" + str(now.minute) + ".jpg"
# This results in something like /media/usb0/20120224-30.jpg
filename = "/media/usb0/" + filename
if image:
    cv.SaveImage(filename, image)
    print filename
else:
    # Throw an error, now just an empty placeholder
    print ""
exit(0)
</syntaxhighlight>
</div>


===Scheduling===
===Scheduling===


You can schedule your Python scripts as cron jobs by following the [[OS - Phidget SBC#Via Cron|cron section]] on the SBC operating system page.
You can schedule your Python scripts the same way we did - as cron jobs by following the [[OS - Phidget SBC#Via Cron|cron section]] on the SBC operating system page.  Both files were saved in the default home directory {{Code|/root}}.


The line used to schedule the weather station every minute was:
The line used to schedule the weather station every minute was:
Line 329: Line 559:
</syntaxhighlight>
</syntaxhighlight>
</div>
</div>
===Data===
When visiting this weather station, we could perform any upkeep.  Then, as above, we could get the data off the weather station by simply removing the USB key drive from the SBC and rebooting the SBC.  As mentioned earlier, the reboot helped keep our code stable over time by resetting and fully cleaning out any script instances which had hung due to unforeseen circumstances. The USB key would then have a week of data on it at a time.  Here is a week with air temperature in <span style="color:green;">green</span> and (partially corrected) snow surface temperature in <span style="color:blue;">blue</span>:
[[File:app_guide_weatherstn_plot.jpg|800px|link=|alt=]]


==Putting it All Together==
==Putting it All Together==


Field installation will always be harder than you think.  But at the same time it will be fun, seeing your hard work come together.  Some tips:
Field installation will always be harder than you think.  But at the same time it will be fun, seeing your hard work come together.  Make sure you have permission to set up your station in its new home if the land is not yours.  Some day-of-assembly tips:
* Pick a day with reasonable weather for the installation, so you can slow down and do things carefully.   
* Pick a day with reasonable weather for the installation, so you can slow down and do things carefully.   
* Assemble the pieces for practice at home, or better yet run them in your backyard before installing elsewhere
* Assemble the pieces for practice at home, or better yet run them in your backyard before installing elsewhere
* Bring basic tools into the field with you when you install (a solar setup tester, hammer, penetrating oil, some wrenches and sockets, caulk)  
* Bring basic tools into the field with you when you install (a solar setup tester, hammer, penetrating oil, some wrenches and sockets, caulk)  
It is good to check your code very carefully before installing, but if something doesn't go right, you can always remove the SBC, transport it home, fix it, and reinstall relatively easily.


[[File:app_guide_weatherstn_sbc_box_lables.png|800px|link=|alt=]]
[[File:app_guide_weatherstn_sbc_box_lables.png|800px|link=|alt=]]
Line 341: Line 579:
When you check on the station, things you may not expect can happen in the interim, so consider bringing a small repair kit each time as you work the bugs out.
When you check on the station, things you may not expect can happen in the interim, so consider bringing a small repair kit each time as you work the bugs out.


[[File:app_guide_weatherstn_snow.png|500px|link=|alt=]]
[[File:app_guide_weatherstn_snow.jpg|500px|link=|alt=]]


==Extra Credit==


It is good to check your code very carefully before installing, but if something doesn't go right, you can always remove the SBC, transport it home, fix it, and reinstall relatively easily.
===Faster Sampling===


==Extra Credit==
The ports can sample at any time interval up to the maximum data rate of the [{{SERVER}}/products.php?product_id=1018 Phidget Interface Kit] attached to the SBC.  So you can also write fast-sampling code that runs constantly from [[OS - Phidget SBC#Via a Boot Script|the SBC boot time]] and samples very quickly.  With fewer than four analog sensors, you can sample up to 1000 times per second.


The ports can sample at any time interval up to the maximum data rate of the [[1018 - PhidgetInterfaceKit 8/8/8]] attached to the SBC.  So you can also write fast-sampling code that runs constantly from [[
===A Smarter Station===


The Single Board Computer is just that - a computer!  So you could install something like the [http://www.r-project.org R Statistical Package] (you can do this by using [[OS - Phidget SBC#apt|apt-get install r-base]] over [[OS - Phidget SBC#SSH|SSH]] on the SBC) and do analysis on the data as it comes in.


The Single Board Computer is just that - a computer!  So you could
[[File:app_guide_weatherstn_farshot.jpg|500px|link=|alt=]]

Latest revision as of 13:38, 5 June 2014

The project described here is a simple weather station that measures air temperature, humidity, and surface temperature of the ground below the weather station.

Practical concepts covered are (click on links to see other projects on that topic):  


Time: About 6 full days of work, including gathering components, writing code, and drilling/assembling
Special Needed Tools: Drill, soldering iron, small screwdriver, socket and wrench set
Other Useful Tools: Hammer, tin snips for pipe strapping
Materials and Phidgets: Extensive lists are provided in this guide


As with any of our described projects, Phidgets takes care of the electrical component design. Still, a project of this magnitude require a time investment in addition to a monetary investment. Designing projects like these is hard.

But the reward is deep - and very real. A full, functional outdoor sensor system that you can build to whatever specifications you like... ask any hobbyist and you may see their eyes light up remembering their latest project. Building such things is a special kind of freedom!


Introduction

A remote station project can monitor and log weather and other environmental conditions using Phidgets.

On this page, we describe this particular setup to get you started:

We start with all of the pieces (the Phidgets, the power supply, the main structure, and the code) and then put it all together.

Phidgets

At the core of this weather logging station is the Phidget Single Board Computer (SBC2). The sensors and other attachments from Phidgets could include:

Task Phidget
  • Schedule the samples
  • Split and Provide power to devices
  • Control the USB Phidget (IR sensor)
  • Run the code
1072 - PhidgetSBC2
  • Read surface temperature of ground, without touching it
  • Provide ambient air temperature at board location
1045 - PhidgetTemperatureSensor IR
  • Measure ambient air temperature
  • Measure ambient air humidity
1125 - Humidity/Temperature Sensor

PhidgetInterfaceKit 8/8/8
(included on-board with the 1072 PhidgetSBC2)

  • Take pictures
3402 USB Webcam
  • Display Status
3601 - 10mm Green LED / 3600 - 10mm Red LED
  • Allow for far sensor placement
3004 - Sensor Cable 350cm

The SBC has the ability to run both USB-based Phidgets (such as the 1045 - PhidgetTemperatureSensor IR) and analog-based Phidgets (such as the 1125 - Humidity/Temperature Sensor). But we have a variety of different environmental sensors that you could use on your system. The included 1018 - PhidgetInterfaceKit 8/8/8 on board the SBC can handle up to 8 analog sensors, and 8 digital in sensors like switches.

Take note that the rated temperature range for the SBC is 0-70°C. You will also notice that it looks substantially colder in most of the pictures than 0°C! There are a few reasons for this. The first is that the SBC is being kept in a sealed container with some (admittedly minor) insulation. Also keep in mind that the SBC will generate heat just like any electronics that have power flowing through them; the SBC is essentially a 1W heater all by itself which, when inside the case, keeps the temperature up significantly above the outside temperature. That said the temperature inside the case is still below 0 on a fairly regular basis. This just goes to show you that the temperature range is not a hard limit and the board will function below it, however there are no guarantees at this point, the SBC could stop functioning at basically any time. It would start up again as the temperature increased but it is very likely that the board seizes up and remains inoperable for long periods of time if it is not being monitored. This was a risk we took and luckily we didn't run into any issues. For the record the coldest temperatures we recorded during the operation of this weather station were between -10 and -15°C. I would not recommend attempting to run it in a colder environment than that without steps being taken to actively heat the board.

Using these components requires a bit of care, so the next sections give some suggestions on how to use each Phidget.

Phidget Infrared Temperature Sensor (IR Sensor)

Measuring the temperature of the ground is useful for things such as highway temperature in the summer, or snow surface temperature in the winter. The IR board can face downward to do this without contacting the surface itself.

The IR board should be:

  • Encased and sealed (such as with a Phidget Enclosure and low-temperature caulk) against the weather
  • Suspended at the right height for the sample size of ground needed (see the 1045 - PhidgetTemperatureSensor IR specifications for the degrees of view you have)
  • Suspended far enough away from the station that it is measuring only ground, and not measuring the base of the station
  • Reasonably protected from solar heating (having a large station arm above it and shading it will probably do it)

Note that you will need to calibrate the data received from this sensor. When you can control all of the variables around what you are using the IR board to measure, you can get very accurate measurements. But in the out-of-doors with a weather station, you will use the board temperature, any shaded temperatures you get from the second temperature sensor, and thermal measurement theory to correct the value the sensor receives. Error includes:

  • Warming of the IR board itself (i.e. you may need corrections based on board temperature)
  • Emissivity of your subject being less than 1.0 (for more information on emissivity, see the 1045 - PhidgetTemperatureSensor IR product page)
  • Measurement of any reflected heat in addition to emitted heat (this also depends on the emissivity)

These concepts and terms should help you get started in your research on how to correct the data specific to your needs - or if you need to do so at all - but a full course in correction is beyond our scope here.

Phidget Temperature and Humidity Sensor

Temperature sensors need to be protected from heating by the sun. Both humidity and temperature sensors need to be protected from snow accumulating on them so that they can interact with the ambient air.

A standard, suspended, white plastic Stephenson-type screen can provide this kind of protection. Plastic ones are inexpensive, and available from specialized weather stores. The photo in the Introduction shows a typical shield screen of this type.

Webcam

Whatever webcam you choose, you should test it outside to properly set the exposure and focus. Most webcams are not weatherproof. Your webcam can either be housed in a weather resistant housing such as those designed for outdoor floodlights, or sealed directly (except the lens) with thick, low-temperature caulk.

Communication

Because of the power requirements (as discussed further in the power section), we chose not to include a wireless connection to transfer data and check on status. Rather, this task can be split up into two parts:

  • LEDs can provide visible status
  • USB keys can store and transfer data

Performing both of these tasks during normal field operation is covered in the code section. However, for development and debugging, we did use a wireless connection:

Power

From the Phidget documentation, we know that the Single Board Computer (SBC) will run at 1.2 watts with no power consumed by devices in its USB ports, and 2.5 watts maximum if all USB port devices are drawing power to maximum specification. Because the power to all sensors and USB devices is included in this estimate, this is what we use to pick a battery and a solar panel.

Although we chose our Phidgets first, and are now designing a power system to support them, the Phidget selection also included some power concerns. With a little forethought, we can guess that the wireless internet adaptor is probably the most power hungry thing that we can plug into a Phidget SBC. A wireless adaptor has two important benefits:

  1. You can download data over the network
  2. You can change code, settings, and scheduling of data gathering as the station is operating

You don't necessarily need an internet connection to use the wireless, as you can connect to it via its phidgetsbc.local local link address.

On the other hand, without a wireless adaptor, the SBC is essentially running autonomously. You can save a lot of power this way, but if the SBC gets into an undesirable state (extreme weather causes it to reboot, a USB Phidget wiggles loose and doesn't properly attach in software, etc) your only options are to either reboot, or add a network connection to log in and change things.

As we do not use wireless here, but do use a webcam, we use an estimate of 2.0 watts to run the SBC.

Solar Panel

We would like to have a power setup that will operate continuously, rather than having to replace the battery. This involves solar power, and it also involves knowing something about the expected weather (namely, the sunshine) in the installation location. Your solar watt capacity should be big enough that in periods of sun it can recharge the battery much faster than the SBC will drain it.

To take an example as to why this matters, imagine installing a 2.0 watt solar panel into your system. If there were sunshine 100% of the time, this would be a closed, self-refreshing system because the SBC would draw 2.0 watts from the battery, and the solar panel would put 2.0 watts back in. But with only a short period of dark, the battery will be drained slightly and never refreshed. So we need to consider all of the factors that could cause darkness (or relative darkness) and determine from them how big a solar panel we need.

We start with choosing amorphous solar panels because of their low cost, and (more importantly) their ability to charge a battery in low or indirect light conditions.

Then, we account for nightfall. This at least doubles our solar needs, especially in winter when nights are long. We assume 3/5 dark time, as twilight conditions are poor for power generation, and the station will be installed in a valley with high ridges blocking the sun for morning and evening. So even assuming every day is sunny, we will only receive 2/5 charge time, and will need 5/2 (5 watts) of power via the solar cell simply due to location and season.

Then, we account for weather. An average long storm for the interior Rocky mountains is about two weeks. Although we chose amorphous solar panels for their low-light performance, the conservative assumption is that the battery will get little recharge during such a storm. Therefore, we want to recharge quickly between storms. In late winter, the mountain sky is cloudy about 2/3 of the time, leaving us one week to top off the battery after two weeks of drain. From our more general power needs section, we can learn that our 2.0 watt SBC will draw 0.17 amps if we use a 12 V battery. So our drain - at worst - will be:

  • Two weeks = 24 hours per day x 14 days = 336 hours
  • 336 hours at 0.17 amps = 57 amp-hours

To recharge 57 amps at 12 V, with a 10 watt panel this would take (the concepts are from the more general power needs section):

  • 57 amps * N hours = 10 watts / 12 V
  • N = 68

...68 hours. At 2/5 charge time from the nightfall calculation (giving ten hours a day of charge), a 10 watt panel would recharge in the expected week (6.8 days). This gives us an idea of what class of solar panel we are looking for, and from here we can examine 10 watt and larger panels with respect to cost and size.

After examining cost, a 10-watt panel was nearly the same size and cost as an 18-watt panel ($80), and so an 18-watt panel was used here. The 18-watt panel also would help add a buffer when - even on non-storm days - high mountain clouds form and further reduce the available sun.

Whatever you choose for your solar panel, you should include a charge limiter, and a way to reliably attach the wires to a battery (clips are for testing only, the post clamps are a more permanent install). The cable on the right is outdoor grade power hookup wire:

Battery

Your battery amp capacity should be big enough that the SBC can run continuously, with reserves, in times of cloudy weather. Even with a proper type of battery, if your SBC completely drains your battery, depending on the battery type it has a chance of dying completely (which is called bricking) and will lose its capacity to recharge.

We have an in-depth description of how to choose batteries in a more general power needs section. From the information in that section, we can determine that we will probably be using a 12 V battery, and that the SBC will draw 0.17 amps with a 12 V battery.

Using this in the solar power section, we calculated that the drain on the battery during a long storm would be, at worst, 57 amp-hours, and so this is the minimum usable capacity we need for the battery.

At more than about 30 amp-hours, the battery that makes the most sense is the large car-battery type lead acid battery. However, typical car batteries won't work as they are not deep cycle that is, they are designed to stay fully charged most of the time. Drawing current from this type of battery continuously will only damage and eventually destroy it. Batteries for RVs, boats, electric golf carts, and the like are designed to be used up through most of their amperage capacity, recharged, and used again and again - these batteries are deep cycle batteries.

Most batteries list this usable capacity for their specification, but if not, consider only 60% of the capacity to be usable. Some example specifications are:

  • 70 Amp-hours (110 reserve) - this battery has 70 usable amp hours
  • 70 Amp hours - this battery probably only has 42 amp hours, but you can call the manufacturer to make sure

The battery will probably be a higher cost than the solar panel. A 60-70 usable amp-hour lead acid battery will be about $100 and 50 lbs. When choosing a battery, the 'buy in bulk' philosophy can come into play. For example, this station ended up using a 110 amp-hour battery, which was $115 and 65 lbs. This is not much weight or price difference for nearly double the power capacity. And extra power capacity will give you extra buffer when you are testing your system at the beginning.

There are many different types of deep cycle batteries - not just lead acid - and they vary in price significantly. There are resources all over the Internet about different battery types to use with solar panels (as well as a primer that we have), so we will not describe them here. The key deciding factor is how long the installation is designed to last. Lead acid batteries have a lifespan of about three years. Longer than that, and you will need to purchase a more expensive battery.

Structural System

The list of major components for this weather station is:

Components
Station Tripod
Commercial lightweight tripod
Extension masts
Protective screen for temperature and humidity sensor
Wires
Exterior-grade power cable
Hookup wire for LEDs and Long Phidget Sensor wires
Solder and heatshrink
Misc Hardware
Horizontal arm for measuring surface temperature (Pipe plus U-bolts and pipe strapping)
Solar panel and SBC case mounting (Metal frame or wide clamps with locks, with U-bolts)
Battery box to keep snow off the terminals
Pelican 1200 waterproof case for SBC
Battery post mounts, protectors, and charge limiter

Although most of these components individually are inexpensive, put them together and the Phidgets are only a small portion of the overall system cost.

With these types of projects, it is easy to lose track of all the little details. Even in something contained like a weather station there are lots, including:

  • Zip ties (black exterior type) for cable management
  • Cold weather silicone caulk for sealing the case wire holes
  • Silica gel packets for desiccant within the SBC case
  • Penetrating oil (WD-40) and a hammer for working with the tripod and masts
  • Foam to pad the U-bolt ends from the solar panel
  • Bolts and angle brackets for the Pelican case mounting

And so on. So plan to spend a while working your particular system out with diagrams, lists, or whatever works for you.

The details of each major connecting part (e.g. mounting the solar panel on the mast, mounting the SBC within the case and to the mast, mounting the horizontal arm, etc) will depend on many different details specific to your application, such as:

  • Snow depth, expected winds, and primary weather
  • Length of the horizontal arm and any sensors also on the end

We found U-bolts to be sufficient for most mounting needs, and quick grip clamps to be sufficient for the solar panel (a person could hang on them), which made the station easier to maintain. This station was designed to be run for a few months and then moved or taken down; a more permanent installation may have a different design.

Depending on your expected forces, you can enhance this basic system design. For example, adding some stakes and plastic coated galvanized guy wires can enable your weather station masts to withstand winds of 70 kph with minimal vibration:

Code

We will be writing our Phidget code in Python. This code will then be scheduled to run - via cron on the SBC - to sample data once per minute and take a webcam photo once every thirty minutes.

Since the weather station runs autonomously - on its own, in the wild - you will need to write code that runs on the SBC itself, as you will have no external computer to control the SBC. This depends on the SBC being set up as described in the 1072 User Guide page, and then additionally as described in the OS - Phidget SBC page. Namely, to follow along with this particular station design, you will need:

Of course, there are many, many other ways to design this code - in Java, to run at boot rather than as a cron job, and so on - and many of these alternatives are outlined on the OS - Phidget SBC page.

For this example, we have two Python scripts: station.py which runs the sensors once per minute and saves the data, and webcam.py which saves a webcam picture once per minute. You can download the files here.

Station

The station code in station.py has three jobs:

  • Reading data, which is the gathering and saving of the weather data,
  • Displaying status via the Interface Kit and LEDs, and
  • Moving data onto a second USB key (optional)

Reading and Recording Data

This station handles two USB Phidgets (the Interface Kit on the SBC board, and the IR Temperature sensor), and two analog Phidgets (air temperature, and humidity).

We have code snippets for using more than one USB Phidget on the General Phidget Programming page. To use more than one analog sensor, you simply use the port number it is plugged in to. As shown on the general programming page, you can automatically detect which USB Phidgets are attached, without knowing their serial number. But you cannot detect which analog ports are being used, unless create an ad-hoc method, such as assuming a value of 0 means no sensor is attached, and any other value indicates an attached sensor.

After we read the data from the Phidgets, we want to save it on the USB data key. We can either hard-code the location or automatically detect where the key is plugged in. Using USB keys with the SBC is discussed in detail on the SBC operating system page. We will hard-code the location in this section's code, but we show how to automatically detect a USB key in the Moving USB Data section.

Here we open the two USB Phidgets, read the IR temperature state, read the two analog in sensors, write the data to an existing file on the USB data key, and turn on and off an LED looks like:

#! /usr/bin/python

from Phidgets.PhidgetException import *
from Phidgets.Events.Events import *
from Phidgets.Devices.InterfaceKit import *
from Phidgets.Devices.TemperatureSensor import *
from time import sleep
from datetime import *

errors = ""
fileLocation = "/media/usb0/data.txt"
weatherLED = 0  # Digital out port position

def close():
    global interfaceKit
    global temperatureSensor
    global errors
    try:
        interfaceKit.setOutputState(weatherLED,0)
    except PhidgetException as e:
        errors = errors + "Phidget Exception on turning off LED\n"
    temperatureSensor.closePhidget()
    interfaceKit.closePhidget()

try:
    temperatureSensor = TemperatureSensor()
    interfaceKit = InterfaceKit()
except RuntimeError as e:
    errors = errors + "Runtime Exception on object creation\n"

try:
    # Replace these serial numbers with your own
    temperatureSensor.openPhidget(142768)
    interfaceKit.openPhidget(48498)
except PhidgetException as e:
    errors = errors + "Phidget Exception on Open\n"

try:
    interfaceKit.waitForAttach(1000)
    temperatureSensor.waitForAttach(1000)
except PhidgetException as e:
    errors = errors + "Phidget Exception on Attach\n"

try:
    # Turn the LED on
    interfaceKit.setOutputState(weatherLED,1)
    # Temperature and humidity are both ratiometric
    interfaceKit.setRatiometric(1)
except PhidgetException as e:
    errors = errors + "Phidget Exception on Ratiometric turn on\n"

# To let the LED stay on for a visually detectable amount of time
sleep(0.5)

try:
    # These conversions are in the product manual
    currentTemp = (interfaceKit.getSensorValue(0) * 0.22222) - 61.11
    currentRH = (interfaceKit.getSensorValue(1) * 0.1906) - 40.2
except PhidgetException as e:
    errors = errors + "Phidget Exception on reading Temperature and RH\n"

try:
    currentIRTemp = temperatureSensor.getTemperature(0)
    boardTemp = temperatureSensor.getAmbientTemperature()
except PhidgetException as e:
    errors = errors + "Phidget Exception on reading IR Temperature"  

outputLine = ""
outputLine = outputLine + str(datetime.now()) + ","
outputLine = outputLine + "T=" + str(currentTemp) + ","
outputLine = outputLine + "RH=" + str(currentRH) + ","
outputLine = outputLine + "IR-T=" + str(currentIRTemp) + ","
outputLine = outputLine + "IR-Brd=" + str(boardTemp) + "\n"

appendFile = open(fileLocation, 'a')
appendFile.write(outputLine)
if errors is not "":
    appendFile.write(str(datetime.now()) + ":\n" + errors)
appendFile.close()

close()
exit(0)

This code snippet shows only one LED in use to show status, attached to digital output port 0 (short LED wire goes into the ground G terminal). For ideas on using other LEDs to display the status of the SBC and your program, see the status section.

After running this a number of times, you will have a file data.txt full of lines that look like this:

2012-03-10 08:37:02.776500,T=-1.77726,RH=40.2,IR-T=-1.01,IR-Brd=-1.09

This can be written differently to start with, or parsed later into whatever data analysis program you want to use.

Moving USB Data

The station was visited once per week to obtain the data. On these visits, we would simply change out the old USB key for a new one on every visit, and reboot the SBC.

We also considered the alternative of writing some extra code to detect when a second USB key is plugged in and copy all of the latest data to it.

After experimenting with both, it turned out that the change-and-reboot option worked well and was the simplest. Rebooting the station at every visit was no problem because the cron job simply restarts as soon as the SBC restarts. Having only one key with the data on it for the week, and then installing a fresh one, created only one key to keep track of at a time.

However, the copy method may be useful in other instances. You can use the mount table to detect a second USB key and write to it like this (the mount and cp shell commands are discussed on the OS - Phidget SBC page):

#! /usr/bin/python
from time import sleep
from datetime import *
import shlex, subprocess

# If this code might start again via cron, we want to ensure only one process writing to the USB key
# The file contains a "1" to denote a process is using the second key, and "0" otherwise
lockFile = "/root/WeatherStation/semaphore.txt"

# The shell command to check the location of a second USB key
checkUSBcommand = "mount | grep sdb1"

# Spawn a command line process, and obtain the output (e.g. the lines from "mount" with "sdb1" in them)
checkUSBprocess = subprocess.Popen(checkUSBcommand, shell=True,
                            stdin=subprocess.PIPE, stdout=subprocess.PIPE)
output = checkUSBprocess.communicate()[0]

usbLocation = None  # A default value

if len(output) > 3:  # If we have more than a newline, key is attached
    outputArray = output.split("usb")
    usbLocation = outputArray[1][0]  # Get the number right after "usb"

# If there is no usb key, remove any locks - especially useful for multiple cron processes
if usbLocation is None:
    file = open(lockFile, "w")
    file.write("0\n")
    file.flush()
    file.close
    exit(0)

file = open(lockFile, "r")
lock = file.readline().rstrip()
if lock is not "0":  # If another process is already writing
    exit(0)

# If we've gotten this far, there is a key and we need to write to it.

# Lock the semaphore
file = open(lockFile, "w")
file.write("1\n")
file.flush()
file.close

usbLocation = "/media/usb" + usbLocation + "/"

# Copy the data file via a spawned shell process
copyDataCommand = "cp /media/usb0/data.txt " + usbLocation
dataProcess = subprocess.Popen(copyDataCommand, 
			shell=True, stdout=subprocess.PIPE)
# The copy might take a while, so check every so often and sleep until done
while dataProcess.poll() != 0:
        sleep(0.1)

# Copy any webcam images via a spawned shell process
copyImagesCommand = "cp /media/usb0/*.jpg " + usbLocation
imageProcess = subprocess.Popen(copyImagesCommand,
                        shell=True, stdout=subprocess.PIPE)

# Again, the copy might take a while, so check every so often and sleep until done
while imageProcess.poll() != 0:
        sleep(0.1)


# Unlock the semaphore
file = open(lockFile, "w")
file.write("0\n")
file.close

exit(0)

Status

There are many ways to use LEDs to communicate status, but a key way is to have the LEDs turn on when reading data, and turn off when finished successfully. Then, if they remain on at your next visit, you will know an error was triggered.

This shows that an error occurred, but not what error. You can also consider writing the details of the error to your data file along with time and date information so you know what surrounding conditions may have caused it. But depending on your method of moving (or copying) the USB data off of the board, you may want to have many LEDs for different states:

  • Data being measured
  • Data being copied
  • Error generated
  • Program exited normally

If you use more than one LED, especially of the same colour, make sure to label them!

The LED setup that was used in this particular station turned an LED on for measurement, and then off on successful program exit. Then, when the station SBC was rebooted in the field, a briefly flashing LED once per minute means the reboot of the station and software was successful.

Webcam

There is a lot of information on the SBC operating system page on using UVC compatible webcams. That section describes how to install the opencv supporting library, which was used to control the webcam.

The code webcam.py run once every 30 minutes to take a picture was:

#! /usr/bin/python

import cv
from datetime import *

webcam = cv.CaptureFromCAM(0)

image = cv.QueryFrame(webcam)

# Compose a fixed-width date label for the file
now = datetime.now()
filename = str(now.year)
if len(str(now.month)) == 1:
    filename += "0" + str(now.month) 
else: 
    filename += str(now.month)
if len(str(now.day)) == 1:
    filename += "0" + str(now.day)
else:
    filename += str(now.day)
filename += "-" + str(now.hour) + "-" + str(now.minute) + ".jpg" 

# This results in something like /media/usb0/20120224-30.jpg
filename = "/media/usb0/" + filename

if image:
    cv.SaveImage(filename, image)
    print filename
else:
    # Throw an error, now just an empty placeholder
    print ""

exit(0)

Scheduling

You can schedule your Python scripts the same way we did - as cron jobs by following the cron section on the SBC operating system page. Both files were saved in the default home directory /root.

The line used to schedule the weather station every minute was:

* * * * * /root/station.py

The line used to schedule the webcam every thirty minutes was:

0,30 * * * * /root/webcam.py

Data

When visiting this weather station, we could perform any upkeep. Then, as above, we could get the data off the weather station by simply removing the USB key drive from the SBC and rebooting the SBC. As mentioned earlier, the reboot helped keep our code stable over time by resetting and fully cleaning out any script instances which had hung due to unforeseen circumstances. The USB key would then have a week of data on it at a time. Here is a week with air temperature in green and (partially corrected) snow surface temperature in blue:

Putting it All Together

Field installation will always be harder than you think. But at the same time it will be fun, seeing your hard work come together. Make sure you have permission to set up your station in its new home if the land is not yours. Some day-of-assembly tips:

  • Pick a day with reasonable weather for the installation, so you can slow down and do things carefully.
  • Assemble the pieces for practice at home, or better yet run them in your backyard before installing elsewhere
  • Bring basic tools into the field with you when you install (a solar setup tester, hammer, penetrating oil, some wrenches and sockets, caulk)

It is good to check your code very carefully before installing, but if something doesn't go right, you can always remove the SBC, transport it home, fix it, and reinstall relatively easily.

When you check on the station, things you may not expect can happen in the interim, so consider bringing a small repair kit each time as you work the bugs out.

Extra Credit

Faster Sampling

The ports can sample at any time interval up to the maximum data rate of the Phidget Interface Kit attached to the SBC. So you can also write fast-sampling code that runs constantly from the SBC boot time and samples very quickly. With fewer than four analog sensors, you can sample up to 1000 times per second.

A Smarter Station

The Single Board Computer is just that - a computer! So you could install something like the R Statistical Package (you can do this by using apt-get install r-base over SSH on the SBC) and do analysis on the data as it comes in.