--- /dev/null
+/*
+ * Copyright (c) 2008, Titanium Mirror, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - Neither the name of Titanium Mirror, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Anemometer definitions
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+#ifndef AEROVANE_H
+#define AEROVANE_H
+
+/* Angular units are in sectors; see AeroVaneC for the number in use.
+ * Speed units are in mph.
+ */
+
+typedef struct {
+ uint16_t dir;
+ uint16_t speed;
+} aerovector_t;
+
+typedef struct {
+ aerovector_t avg; /* average wind vector, taking into acct dir & speed */
+ uint8_t ccw; /* most counter-clockwise vane position seen */
+ uint8_t cw; /* most clockwise vane position seen */
+ uint8_t min; /* minimum speed seen */
+ uint8_t max; /* max speed seen */
+} aerovane_t;
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2008, Titanium Mirror, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - Neither the name of Titanium Mirror, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Reads the physical sensors and notifies every read period an aerovane average
+ * vector.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+#include "AeroVane.h"
+
+configuration AeroVaneReadC {
+ provides interface Notify<aerovector_t>;
+}
+implementation {
+#if 0
+ components new AeroVaneReadP(28800U);
+#else
+ components new AeroVaneReadP(900);
+#endif
+ Notify = AeroVaneReadP;
+
+#if 0
+ components new Alarm32khz16C();
+ AeroVaneReadP.Alarm -> Alarm32khz16C;
+#else
+ components new TimerMilliC();
+ AeroVaneReadP.Timer -> TimerMilliC;
+#endif
+
+ components WindVaneReadC;
+ AeroVaneReadP.Read -> WindVaneReadC;
+
+ components AnemometerReadC;
+ AeroVaneReadP.AnemometerControl -> AnemometerReadC.StdControl;
+ AeroVaneReadP.Count -> AnemometerReadC;
+
+ components new StateC();
+ AeroVaneReadP.State -> StateC;
+}
--- /dev/null
+/*
+ * Copyright (c) 2008, Titanium Mirror, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - Neither the name of Titanium Mirror, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Reads the physical sensors and notifies every read period an aerovane average
+ * vector.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+#include "AeroVane.h"
+
+generic module AeroVaneReadP(uint16_t period) {
+ provides interface Notify<aerovector_t>;
+ uses {
+#if 0
+ interface Alarm<T32khz, uint16_t>;
+#else
+ interface Timer<TMilli>;
+#endif
+ interface Read<uint16_t>;
+ interface StdControl as AnemometerControl;
+ interface AsyncGet<uint16_t> as Count;
+ interface State;
+ }
+}
+implementation {
+ enum {
+ S_IDLE,
+ S_RUN,
+
+ PHYS_PER_READ = 4, /* # of physical reads per reading */
+ };
+
+ uint16_t m_count;
+ int m_vane;
+ int m_sum;
+
+ task void readVane();
+
+ void init()
+ {
+ m_count = 0;
+ m_vane = 0;
+ m_sum = 0;
+ }
+
+ command error_t Notify.enable()
+ {
+ if (call State.requestState(S_RUN) != SUCCESS)
+ return EBUSY;
+
+ init();
+ call AnemometerControl.start();
+ /* FIXME: First alarm should be synced to top of the next second. How? */
+#if 0
+ call Alarm.start(call Alarm.getNow() + period);
+#else
+ call Timer.startPeriodic(period);
+#endif
+ return SUCCESS;
+ }
+
+ command error_t Notify.disable()
+ {
+ call State.toIdle();
+#if 0
+ call Alarm.stop();
+#else
+ call Timer.stop();
+#endif
+ call AnemometerControl.stop();
+ return SUCCESS;
+ }
+
+#if 0
+ async event void Alarm.fired()
+#else
+ event void Timer.fired()
+#endif
+ {
+ //call Alarm.start(call Alarm.getAlarm() + period);
+ post readVane();
+ }
+
+ task void readVane()
+ {
+ //call Alarm.start(call Alarm.getAlarm() + period);
+ if (!(call State.isIdle()))
+ call Read.read();
+ }
+
+ int distance(int angle1, int angle2)
+ {
+ int d = angle2 - angle1;
+
+ if (d <= -180)
+ d += 360;
+ else if (d > 180)
+ d -= 360;
+ return d;
+ }
+
+ event void Read.readDone(error_t error, uint16_t result)
+ {
+ int newVane;
+
+ if (error != SUCCESS)
+ return;
+
+ newVane = m_vane + distance(m_vane, result);
+ m_sum += result;
+ m_vane = newVane;
+ if (++m_count == PHYS_PER_READ) {
+ norace aerovector_t vector;
+
+ /* Get speed average */
+ atomic vector.speed = call Count.get();
+
+ /* Complete direction average */
+ vector.dir = m_sum / PHYS_PER_READ;
+ while (vector.dir < 0)
+ vector.dir += 360;
+ vector.dir %= 360;
+ init();
+
+ /* Inform the consumer of the vector */
+ if (!(call State.isIdle()))
+ signal Notify.notify(vector);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2008, Titanium Mirror, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - Neither the name of Titanium Mirror, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Instantaneous anemometer read; depends upon prior call for correct timing.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+#include "Anemometer.h"
+
+configuration AnemometerReadC {
+ provides {
+ interface StdControl;
+ interface AsyncGet<uint16_t> as Count;
+ }
+}
+implementation {
+ components MainC;
+ MainC.SoftwareInit -> AnemometerReadP.Init;
+
+ components AnemometerReadP;
+ StdControl = AnemometerReadP;
+ Count = AnemometerReadP;
+
+ components Msp430CounterMicroC;
+ AnemometerReadP.SpinCounter -> Msp430CounterMicroC;
+}
--- /dev/null
+/*
+ * Copyright (c) 2008, Titanium Mirror, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - Neither the name of Titanium Mirror, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Instantaneous anemometer read; depends upon prior call for correct timing.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+#include "Anemometer.h"
+
+module AnemometerReadP {
+ provides {
+ interface Init;
+ interface StdControl;
+ interface AsyncGet<uint16_t> as Count;
+ }
+ uses
+ interface Counter<TMicro,uint16_t> as SpinCounter;
+}
+implementation {
+ uint16_t m_count;
+
+ command error_t Init.init()
+ {
+ atomic {
+ /* Initialize Timer A, clock source is IO pin P1.0. SpinCounter's clock
+ * is Timer A.
+ */
+ TACTL = 0;
+ TACTL = TACLR | ID_0 | TASSEL_0;
+ P1SEL |= 1;
+ }
+ return SUCCESS;
+ }
+
+ command error_t StdControl.start()
+ {
+ atomic {
+ TACTL |= MC_2;
+ m_count = call SpinCounter.get();
+ }
+ return SUCCESS;
+ }
+
+ command error_t StdControl.stop()
+ {
+ atomic TACTL &= ~(MC1|MC0);
+ }
+
+ async command uint16_t Count.get()
+ {
+ atomic {
+ uint16_t newCount;
+ uint16_t speed;
+
+ newCount = call SpinCounter.get();
+ speed = newCount - m_count;
+ m_count = newCount;
+ return speed;
+ }
+ }
+
+ async event void SpinCounter.overflow() {}
+}