Library for interfacing to Sparkfun Weather Meters.

Dependents:   WeatherStation Deneme testgeneral ... more

Files at this revision

API Documentation at this revision

Comitter:
AdamGreen
Date:
Sat Feb 25 03:23:51 2012 +0000
Commit message:

Changed in this revision

Anemometer.cpp Show annotated file Show diff for this revision Revisions of this file
Anemometer.h Show annotated file Show diff for this revision Revisions of this file
DebouncedFallingEdgeCounter.cpp Show annotated file Show diff for this revision Revisions of this file
DebouncedFallingEdgeCounter.h Show annotated file Show diff for this revision Revisions of this file
RainGauge.h Show annotated file Show diff for this revision Revisions of this file
WeatherMeters.cpp Show annotated file Show diff for this revision Revisions of this file
WeatherMeters.h Show annotated file Show diff for this revision Revisions of this file
WindVane.cpp Show annotated file Show diff for this revision Revisions of this file
WindVane.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Anemometer.cpp	Sat Feb 25 03:23:51 2012 +0000
@@ -0,0 +1,60 @@
+/* Copyright 2012 Adam Green (http://mbed.org/users/AdamGreen/)
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+/* Implementation of class to interface for anemometer sensor with Sparkfun Weather Meters: 
+    http://www.sparkfun.com/products/8942
+*/
+#include <mbed.h>
+#include "Anemometer.h"
+
+
+#define REV_PER_SECOND_TO_KMPH  2.4f
+
+
+CAnemometer::CAnemometer(PinName AnemometerPin, unsigned int IgnoreTimeForDebounceInMicroSeconds)
+    : CDebouncedFallingEdgeCounter(AnemometerPin, IgnoreTimeForDebounceInMicroSeconds)
+{
+    m_CurrentWindSpeed = 0.0f;
+    ResetMaximumWindSpeed();
+    m_OneSecondTicker.attach_us<CAnemometer>(this, &CAnemometer::OneSecondTickerISR, 1000000);
+}
+
+
+void CAnemometer::ResetMaximumWindSpeed()
+{
+    m_MaximumWindSpeed = m_CurrentWindSpeed;
+}
+
+
+void CAnemometer::OneSecondTickerISR()
+{
+    unsigned int GetCurrentCount = GetCountAndZero();
+    
+    m_CurrentWindSpeed = (float)GetCurrentCount * REV_PER_SECOND_TO_KMPH;
+    if (m_CurrentWindSpeed > m_MaximumWindSpeed)
+    {
+        m_MaximumWindSpeed = m_CurrentWindSpeed;
+    }
+}
+
+float CAnemometer::GetCurrentWindSpeed()
+{
+    return m_CurrentWindSpeed;
+}
+
+
+float CAnemometer::GetMaximumWindSpeed()
+{
+    return m_MaximumWindSpeed;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Anemometer.h	Sat Feb 25 03:23:51 2012 +0000
@@ -0,0 +1,48 @@
+/* Copyright 2012 Adam Green (http://mbed.org/users/AdamGreen/)
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+/* Header file for class to interface with anemometer sensor of Sparkfun Weather Meters: 
+    http://www.sparkfun.com/products/8942
+*/
+#ifndef _ANEMOMETER_H_
+#define _ANEMOMETER_H_
+
+#include "DebouncedFallingEdgeCounter.h"
+
+
+namespace AFP
+{
+
+class CAnemometer : protected CDebouncedFallingEdgeCounter
+{
+protected:
+    Ticker          m_OneSecondTicker;
+    float           m_CurrentWindSpeed;
+    float           m_MaximumWindSpeed;
+
+public:
+    CAnemometer(PinName AnemometerPin, unsigned int IgnoreTimeForDebounceInMicroSeconds = 1000);
+    
+    float GetCurrentWindSpeed();
+    float GetMaximumWindSpeed();
+    void  ResetMaximumWindSpeed();
+
+protected:
+    void OneSecondTickerISR();
+};
+
+} // namespace AFP
+using namespace AFP;
+
+#endif // _ANEMOMETER_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DebouncedFallingEdgeCounter.cpp	Sat Feb 25 03:23:51 2012 +0000
@@ -0,0 +1,100 @@
+/* Copyright 2012 Adam Green (http://mbed.org/users/AdamGreen/)
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+/* Implementation for wrapper class of InterruptIn used for counting falling edge
+   events with specified hold off time for the purpose of debouncing.
+*/
+#include <mbed.h>
+#include "DebouncedFallingEdgeCounter.h"
+
+
+CDebouncedFallingEdgeCounter::CDebouncedFallingEdgeCounter(PinName InterruptInPin, unsigned int IgnoreTimeForDebounceInMicroSeconds) 
+    : m_FallingEdgeInterruptIn(InterruptInPin)
+{
+    m_Timer.start();
+    m_IgnoreTimeForDebounce = IgnoreTimeForDebounceInMicroSeconds;
+    InitLastFallingEdgeTime();
+
+    ZeroCount();
+
+    m_FallingEdgeInterruptIn.mode(PullUp);
+    m_FallingEdgeInterruptIn.fall<CDebouncedFallingEdgeCounter>(this, &CDebouncedFallingEdgeCounter::FallingEdgeISR);
+}
+
+
+void CDebouncedFallingEdgeCounter::InitLastFallingEdgeTime()
+{
+    InitLastFallingEdgeTime((unsigned int)m_Timer.read_us());
+}
+
+
+void CDebouncedFallingEdgeCounter::InitLastFallingEdgeTime(unsigned int CurrentTime)
+{
+    m_LastFallingEdgeTime = CurrentTime - m_IgnoreTimeForDebounce;
+}
+
+
+void CDebouncedFallingEdgeCounter::FallingEdgeISR()
+{
+    // UNDONE: Can I just use whatever timer the m_Timer uses under the covers?
+    unsigned int CurrentTime = (unsigned int)m_Timer.read_us();
+    
+    if (TimeSinceLastFallingEdge(CurrentTime) >= m_IgnoreTimeForDebounce)
+    {
+        m_FallingEdgeCount++;
+        m_LastFallingEdgeTime = CurrentTime;
+    }
+}
+
+
+unsigned int CDebouncedFallingEdgeCounter::TimeSinceLastFallingEdge(unsigned int CurrentTime)
+{
+    return CurrentTime - m_LastFallingEdgeTime;
+}
+
+
+unsigned int CDebouncedFallingEdgeCounter::GetCountAndZero()
+{
+    unsigned int CurrentCount;
+    
+    CurrentCount = GetCount();
+    ZeroCount();
+    return CurrentCount;
+}
+
+
+unsigned int CDebouncedFallingEdgeCounter::GetCount()
+{
+    RefreshTimers();
+    
+    return m_FallingEdgeCount;
+}
+
+
+void CDebouncedFallingEdgeCounter::ZeroCount()
+{
+    m_FallingEdgeCount = 0;
+}
+
+
+void CDebouncedFallingEdgeCounter::RefreshTimers()
+{
+    unsigned int CurrentTime = (unsigned int)m_Timer.read_us();
+    
+    if (TimeSinceLastFallingEdge(CurrentTime) > m_IgnoreTimeForDebounce)
+    {
+        // Protect from timer overflow.
+        InitLastFallingEdgeTime(CurrentTime);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DebouncedFallingEdgeCounter.h	Sat Feb 25 03:23:51 2012 +0000
@@ -0,0 +1,52 @@
+/* Copyright 2012 Adam Green (http://mbed.org/users/AdamGreen/)
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+/* Header file for wrapper class of InterruptIn used for counting falling edge
+   events with specified hold off time for the purpose of debouncing.
+*/
+#ifndef _DEBOUNCED_FALLING_EDGE_COUNT_H_
+#define _DEBOUNCED_FALLING_EDGE_COUNT_H_
+
+namespace AFP
+{
+
+class CDebouncedFallingEdgeCounter
+{
+protected:
+    InterruptIn     m_FallingEdgeInterruptIn;
+    // UNDONE: Run for over 30 minutes and make sure that this rolls over as expected.
+    Timer           m_Timer;
+    unsigned int    m_IgnoreTimeForDebounce;
+    unsigned int    m_LastFallingEdgeTime;
+    unsigned int    m_FallingEdgeCount;
+
+public:
+    CDebouncedFallingEdgeCounter(PinName InterruptInPin, unsigned int IgnoreTimeForDebounceInMicroSeconds);
+    
+    unsigned int GetCountAndZero();
+    void         ZeroCount();
+    unsigned int GetCount();
+
+protected:
+    void          InitLastFallingEdgeTime();
+    void          InitLastFallingEdgeTime(unsigned int CurrentTime);
+    void          FallingEdgeISR();
+    void          RefreshTimers();
+    unsigned int  TimeSinceLastFallingEdge(unsigned int CurrentTime);
+};
+
+} // namespace AFP
+using namespace AFP;
+
+#endif // _DEBOUNCED_FALLING_EDGE_COUNT_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RainGauge.h	Sat Feb 25 03:23:51 2012 +0000
@@ -0,0 +1,52 @@
+/* Copyright 2012 Adam Green (http://mbed.org/users/AdamGreen/)
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+/* Header file for class to interface with the rain gauge sensor of the Sparkfun Weather Meters: 
+    http://www.sparkfun.com/products/8942
+*/
+#ifndef _RAIN_GAUGE_H_
+#define _RAIN_GAUGE_H_
+
+#include "DebouncedFallingEdgeCounter.h"
+
+
+#define MILLIMETERS_OF_RAIN_PER_COUNT 0.2794f
+
+
+namespace AFP
+{
+
+class CRainGauge : protected CDebouncedFallingEdgeCounter
+{
+public:
+    CRainGauge(PinName RainGaugePin, unsigned int IgnoreTimeForDebounceInMicroSeconds = 1000)
+        : CDebouncedFallingEdgeCounter(RainGaugePin, IgnoreTimeForDebounceInMicroSeconds)
+    {
+    }
+    
+    void  Reset()
+    {
+        ZeroCount();
+    }
+    
+    float GetRainfall()
+    {
+        return (float)GetCount() * MILLIMETERS_OF_RAIN_PER_COUNT;
+    }
+};
+
+} // namespace AFP
+using namespace AFP;
+
+#endif // _RAIN_GAUGE_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WeatherMeters.cpp	Sat Feb 25 03:23:51 2012 +0000
@@ -0,0 +1,59 @@
+/* Copyright 2012 Adam Green (http://mbed.org/users/AdamGreen/)
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+/* Implementation of class to interface with Sparkfun Weather Meters: 
+    http://www.sparkfun.com/products/8942
+*/
+#include <mbed.h>
+#include "WeatherMeters.h"
+
+
+CWeatherMeters::CWeatherMeters(PinName AnemometerPin,
+                               PinName RainGaugePin,
+                               PinName WindVanePin,
+                               float   WindVaneSeriesResistance) : m_Anemometer(AnemometerPin),
+                                                                   m_RainGauge(RainGaugePin),
+                                                                   m_WindVane(WindVanePin, WindVaneSeriesResistance)
+{
+}
+
+
+void CWeatherMeters::GetMeasurements(SMeasurements* pMeasurements)
+{
+    pMeasurements->WindDirectionString = m_WindVane.GetWindDirectionAsString();
+    pMeasurements->WindDirectionAngle  = m_WindVane.GetWindDirectionAsAngle();
+    pMeasurements->WindSpeed = m_Anemometer.GetCurrentWindSpeed();
+    pMeasurements->MaximumWindSpeed = m_Anemometer.GetMaximumWindSpeed();
+    pMeasurements->Rainfall = m_RainGauge.GetRainfall();
+}
+
+
+void CWeatherMeters::Reset()
+{
+    ResetRainfall();
+    ResetMaximumWindSpeed();
+}
+    
+    
+void CWeatherMeters::ResetRainfall()
+{
+    m_RainGauge.Reset();
+}
+    
+
+void CWeatherMeters::ResetMaximumWindSpeed()
+{
+    m_Anemometer.ResetMaximumWindSpeed();
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WeatherMeters.h	Sat Feb 25 03:23:51 2012 +0000
@@ -0,0 +1,130 @@
+/* Copyright 2012 Adam Green (http://mbed.org/users/AdamGreen/)
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+/* Header file for class to interface with Sparkfun Weather Meters: 
+    http://www.sparkfun.com/products/8942
+*/
+#ifndef _WEATHER_METERS_H_
+#define _WEATHER_METERS_H_
+
+#include "WindVane.h"
+#include "RainGauge.h"
+#include "Anemometer.h"
+
+
+namespace AFP
+{
+
+/** A class to interface with the Sparkfun Weather Meters.
+    http://www.sparkfun.com/products/8942
+    
+    This set of weather meters from Sparkfun includes anemometer (wind speed),
+    wind vane, and rain gauge.  All of the sensors use reed switches so that
+    the electronics can detect motion/location in the sensor hardware via 
+    magnets placed in the sensors without actually exposing the electonic
+    switches themselves to the elements.  A reed switch closes as the 
+    anemometer spins and the rain gauge empties.  The wind vane includes 
+    8 reed switches, each with a different valued resistor attached so that
+    the voltage will vary depending on where the magnet in the vane is
+    located.
+ * Example:
+ * @code
+#include <mbed.h>
+#include "WeatherMeters.h"
+
+int main() 
+{
+    CWeatherMeters WeatherMeters(p9, p10, p15);
+    for (;;)
+    {
+        CWeatherMeters::SMeasurements   Measurements;
+        
+        WeatherMeters.GetMeasurements(&Measurements);
+        
+        printf("Direction: %s\n", Measurements.WindDirectionString);
+        printf("Depth: %f\n",Measurements.Rainfall);
+        printf("Current speed: %f\n", Measurements.WindSpeed);
+        printf("Maximum speed: %f\n", Measurements.MaximumWindSpeed);
+
+        wait(1.0f);
+    }
+}
+ * @endcode
+ */
+class CWeatherMeters
+{
+protected:
+    CAnemometer     m_Anemometer;
+    CRainGauge      m_RainGauge;
+    CWindVane       m_WindVane;
+
+public:
+     /** A structure in which the current measurements registered by the weather
+         meters are returned from the GetMeasurements() method.
+     */
+     struct SMeasurements
+     {
+        const char* WindDirectionString;    /**< String representing current wind direction.  Example: "North" */
+        float       WindDirectionAngle;     /**< Wind direction in degrees from north. */
+        float       WindSpeed;              /**< Current wind speed in km/hour. */
+        float       MaximumWindSpeed;       /**< Maximum wind speed measured since last reset.  Measured in km/hour. */
+        float       Rainfall;               /**< Amount of rainfall since last reset.  Measured in mm. */
+     };
+     
+     /** Create a CWeatherMeters object, binds it to the specified input pins,
+         and initializes the required interrupt handlers.
+         
+         @param AnemometerPin The mbed pin which is connected to the anemometer
+                sensor.  Must be a pin on which the mbed supports InterruptIn.
+         @param RainGauagePin The mbed pin which is connected to the rain gauge
+                sensor.  Must be a pin on which the mbed supports InterruptIn.
+         @param WindVanePin The mbed pin which is connected to the wind vane
+                sensor.  Must be a pin on which the mbed supports AnalogIn.
+         @param WindVaneSeriesResistance The value of the resistance which is
+                in series with the wind vane sensor and along with the
+                varying resistance of the wind vane sensor itself, acts as a
+                voltage divider.
+    */
+    CWeatherMeters(PinName AnemometerPin,
+                   PinName RainGaugePin,
+                   PinName WindVanePin,
+                   float   WindVaneSeriesResistance = 10000.0f);
+    
+    /** Gets current weather meter measurements.
+    
+        NOTE: Should call this method on a regular basis (every 15 minutes or 
+        less) to keep internal timers from overflowing.
+    
+     @param pMeasurements points to the measurement structure to be filled in
+            with the current measurement from the sensors.  The historical
+            values in this structure such as rainfall and maximum wind
+            speed can be reset by calls to ResetRainfall(), 
+            ResetMaximumWindSpeed(), and Reset().
+    */
+    void GetMeasurements(SMeasurements* pMeasurements);
+    
+    /** Resets all historical measurements: rainfall and maximum wind speed. */
+    void Reset();
+    
+    /** Resets the cumulative rainfall measurement. */
+    void ResetRainfall();
+    
+    /** Resets the maximum wind speed measurement. */
+    void ResetMaximumWindSpeed();
+};
+
+} // namespace AFP
+using namespace AFP;
+
+#endif // _WEATHER_METERS_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WindVane.cpp	Sat Feb 25 03:23:51 2012 +0000
@@ -0,0 +1,96 @@
+/* Copyright 2012 Adam Green (http://mbed.org/users/AdamGreen/)
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+/* Declaration of class to interface with wind vane sensor Sparkfun Weather Meters: 
+    http://www.sparkfun.com/products/8942
+*/
+#include <mbed.h>
+#include "WindVane.h"
+
+
+#define REV_PER_SECOND_TO_KMPH  2.4f
+#define PARALLEL_R(R1, R2) (((R1) * (R2)) / ((R1) + (R2)))
+#define ARRAY_SIZE(X) (sizeof(X)/sizeof(X[0]))
+
+struct SDescription
+{
+    const char* DirectionString;
+    float       DirectionAngle;
+    float       SensorResistance;
+};
+
+
+static SDescription g_WindVaneDescriptionTable[16] = {
+    { "North",            0.0f,  33.0f * 1000.0f },
+    { "North North East", 22.5f, PARALLEL_R(33.0f * 1000.0f, 8.2f * 1000.0f) },
+    { "North East",       45.0f, 8.2f * 1000.0f },
+    { "East North East",  67.5f, PARALLEL_R(8.2f * 1000.0f, 1000.0f) },
+    { "East",             90.0f, 1000.0f },
+    { "East South East",  112.5f, PARALLEL_R(1000.0f, 2.2f * 1000.0f) },
+    { "South East",       135.0f, 2.2f * 1000.0f },
+    { "South South East", 157.5f, PARALLEL_R(2.2f * 1000.0f, 3.9f * 1000.0f) },
+    { "South",            180.0f, 3.9f * 1000.0f },
+    { "South South West", 202.5f, PARALLEL_R(3.9f * 1000.0f, 16.0f * 1000.0f) },
+    { "South West",       225.0f, 16.0f * 1000.0f },
+    { "West South West",  247.5f, PARALLEL_R(16.0f * 1000.0f, 120.0f * 1000.0f) },
+    { "West",             270.0f, 120.0f * 1000.0f },
+    { "West North West",  292.5f, PARALLEL_R(120.0f * 1000.0f, 64.9f * 1000.0f) },
+    { "North West",       315.0f, 64.9f * 1000.0f },
+    { "North North West", 337.5f, PARALLEL_R(64.9f * 1000.0f, 33.0f * 1000.0f) }
+};
+
+
+CWindVane::CWindVane(PinName WindVanePin, float WindVaneSeriesResistance)
+    : m_WindVaneAnalogIn(WindVanePin)
+{
+    for (size_t i = 0 ; i < ARRAY_SIZE(g_WindVaneDescriptionTable) ; i++)
+    {
+        SDescription* pDescription = &g_WindVaneDescriptionTable[i];
+
+        m_WindVaneVoltageTable[i] = pDescription->SensorResistance /
+                                    (pDescription->SensorResistance + WindVaneSeriesResistance);
+    }
+}
+
+const char* CWindVane::GetWindDirectionAsString()
+{
+    return g_WindVaneDescriptionTable[DetermineWindDirectionIndex()].DirectionString;
+}
+
+float CWindVane::GetWindDirectionAsAngle()
+{
+    return g_WindVaneDescriptionTable[DetermineWindDirectionIndex()].DirectionAngle;
+}
+
+size_t CWindVane::DetermineWindDirectionIndex()
+{
+    float WindVaneSensorVoltage = m_WindVaneAnalogIn.read();
+
+    // Default to the first entry being closest.
+    size_t ClosestIndex = 0;
+    float  ClosestDelta = fabs(m_WindVaneVoltageTable[0] - WindVaneSensorVoltage);
+    
+    // Walk the rest of the entries to see if there is another which is closer.
+    for (size_t i = 1 ; i < ARRAY_SIZE(m_WindVaneVoltageTable) ; i++)
+    {
+        float Delta = fabs(m_WindVaneVoltageTable[i] - WindVaneSensorVoltage);
+        if (Delta < ClosestDelta)
+        {
+            ClosestDelta = Delta;
+            ClosestIndex = i;
+        }
+    }
+    
+    return ClosestIndex;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WindVane.h	Sat Feb 25 03:23:51 2012 +0000
@@ -0,0 +1,43 @@
+/* Copyright 2012 Adam Green (http://mbed.org/users/AdamGreen/)
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+/* Implementation of class to interface with wind vane sensor Sparkfun Weather Meters: 
+    http://www.sparkfun.com/products/8942
+*/
+#ifndef _WIND_VANE_H_
+#define _WIND_VANE_H_
+
+namespace AFP
+{
+
+class CWindVane
+{
+protected:
+    AnalogIn            m_WindVaneAnalogIn;
+    float               m_WindVaneVoltageTable[16];
+
+public:
+    CWindVane(PinName WindVanePin, float WindVaneSeriesResistance = 10000.0f);
+    
+    const char* GetWindDirectionAsString();
+    float       GetWindDirectionAsAngle();
+    
+protected:
+    size_t      DetermineWindDirectionIndex();
+};
+
+} // namespace AFP
+using namespace AFP;
+
+#endif // _WIND_VANE_H_