From: smckown Date: Wed, 4 Nov 2009 03:55:05 +0000 (+0000) Subject: WindVaneReadC gives instantaneous compass heading reading from the wind vane. X-Git-Tag: release/2.1.0-2~24 X-Git-Url: https://oss.titaniummirror.com/gitweb/?p=tinyos-2.x.git;a=commitdiff_plain;h=0af086c5bf6a9038446bb804d9a463fd32b4aa77 WindVaneReadC gives instantaneous compass heading reading from the wind vane. --- diff --git a/tos/platforms/tmirws/sensors/WindVaneReadC.nc b/tos/platforms/tmirws/sensors/WindVaneReadC.nc new file mode 100644 index 00000000..3b467349 --- /dev/null +++ b/tos/platforms/tmirws/sensors/WindVaneReadC.nc @@ -0,0 +1,56 @@ +/* + * 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. + */ + +/** + * Take an instantaneous reading of the wind vane position, in degrees. + * + * @author R. Steve McKown + */ + +configuration WindVaneReadC { + provides interface Read; +} +implementation { + components WindVaneReadP; + Read = WindVaneReadP; + + components new MultiSampleC(uint16_t, 4); + WindVaneReadP.Count -> MultiSampleC; + WindVaneReadP.SubRead -> MultiSampleC; + + components WindVaneAdcP; + MultiSampleC.AdcConfigure -> WindVaneAdcP; + + components HalWindVaneC; + WindVaneReadP.WPower -> HalWindVaneC.WPower; + WindVaneReadP.WDead -> HalWindVaneC.WDead; + + components new StateC(); + WindVaneReadP.State -> StateC; +} diff --git a/tos/platforms/tmirws/sensors/WindVaneReadP.nc b/tos/platforms/tmirws/sensors/WindVaneReadP.nc new file mode 100644 index 00000000..2076e239 --- /dev/null +++ b/tos/platforms/tmirws/sensors/WindVaneReadP.nc @@ -0,0 +1,134 @@ +/* + * 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. + */ + +/** + * Take an instantaneous reading of the wind vane position. + * + * @author R. Steve McKown + */ + +module WindVaneReadP @safe() +{ + provides interface Read; + uses { + interface Get as Count; + interface Read as SubRead; + interface GeneralIO as WPower; + interface GeneralIO as WDead; + interface State; + } +} +implementation +{ + enum { + S_IDLE = 0, + S_READ, + S_CHECK, + S_OUTPUT, + + /* The wind vane has a dead zone where it returns an ADC value that also + * represents another angular location. Therefore, we implement special + * dead zone checking over a certain range of return values from the + * wind vane. + * + * Note: the wind vane's dead zone is probably 5-10 degrees. We would be + * more accurate if we took the ADC range over 350 or 355 degrees, then + * added 1/2 of the dead zone as an offset. However, without this logic, + * the wind vane appears more than accurate enough. It is less accurate + * within the dead zone, of course, but would be even if we did implement + * the extra logic. + */ + DEAD_BEGIN = 6000, /* 4 12-bit ADC readings; about 120 degrees */ + DEAD_END = 9000, /* About 198 degrees */ + DEAD_THRESH = 14472, /* > when checking means in dead zone */ + }; + + char m_msg[80]; + + command error_t Read.read() + { + if (!(call State.isIdle())) + return EBUSY; + + call WPower.set(); + if (call SubRead.read() == SUCCESS) { + call State.forceState(S_READ); + return SUCCESS; + } else { + call WPower.clr(); + return FAIL; + } + } + + void signalReadDone(error_t error, uint16_t value) + { + call WDead.makeInput(); + call WPower.clr(); + + /* Value is the sum of multiple 12-bit ADC acquisitions, per the attached + * MultiSampleC component. Convert the value to degrees. Note, the values + * 360 and 0 (zero) represent the same angular position. We don't do a + * modulus operation here because we fully expect the client will do + * additional processing that will likely involve a modulus function anyway. + */ + value = (uint16_t)(((uint32_t)(value / call Count.get()) * 360 + 2047) / + 4096); + + call State.toIdle(); + signal Read.readDone(error, value); + } + + event void SubRead.readDone(error_t error, uint16_t result) + { + static uint16_t m_value; + + if (error != SUCCESS) { + signalReadDone(error, 0); + return; + } + + switch (call State.getState()) { + case S_READ: + if (result < DEAD_BEGIN || result > DEAD_END) + signalReadDone(SUCCESS, result); + else { + m_value = result; + call WDead.makeOutput(); + if (call SubRead.read() == SUCCESS) + call State.forceState(S_CHECK); + else + signalReadDone(FAIL, 0); + } + break; + case S_CHECK: + signalReadDone(SUCCESS, (result > DEAD_THRESH) ? 0 : m_value); + break; + } + } +}