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 Get<uint16_t> as Revolutions;
+ interface Average<uint16_t>;
interface State;
}
}
PHYS_PER_READ = 4, /* # of physical reads per reading */
};
- uint16_t m_count;
- int m_vane;
- int m_sum;
+ uint8_t m_count;
+ uint16_t m_speed;
- void init()
+ inline void init()
{
m_count = 0;
- m_vane = 0;
- m_sum = 0;
+ call Average.reset();
}
command error_t Notify.enable()
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
+ /* FIXME: How to get first Timer.fired() synced with top of hour? */
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
- task void readVane();
-
- async event void Alarm.fired()
- {
- call Alarm.start(call Alarm.getAlarm() + period);
- post readVane();
- }
-
- task void readVane()
- {
- //call Alarm.start(call Alarm.getAlarm() + period);
-#else
event void Timer.fired()
{
-#endif
- if (!(call State.isIdle()))
- call Read.read();
- }
-
- int distance(int angle1, int angle2)
- {
- int d = angle2 - angle1;
+ if (++m_count == PHYS_PER_READ) {
+ /* Get anemometer revolutions for the period */
+ m_speed = call Revolutions.get();
+ }
- if (d <= -180)
- d += 360;
- else if (d > 180)
- d -= 360;
- return d;
+ if (!(call State.isIdle())) {
+ /* Avoid notifying if the user has disabled */
+ call Read.read();
+ }
}
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() * 2.25) / (period * 4 / 1024) +
- 0.5;
-
- /* 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()))
+ if (error == SUCCESS)
+ call Average.submit(result);
+
+ if (m_count == PHYS_PER_READ) {
+ if (call State.isIdle()) {
+ /* Avoid notifying if the user has disabled */
+ init();
+ } else {
+ aerovector_t vector;
+
+ vector.dir = call Average.average();
+ vector.speed = m_speed;
+ init();
signal Notify.notify(vector);
+ }
}
}
}