X-Git-Url: https://oss.titaniummirror.com/gitweb/?p=tinyos-2.x.git;a=blobdiff_plain;f=tos%2Fplatforms%2Ftmirws%2Fsensors%2FWindVaneP.nc;h=4042470e241704a7d22fbc33c91024bbd508bf6c;hp=a6976e951ef646011dc62fc67ad0e2eb50d17462;hb=108ff439d63ddb1413efe5e9830392bab56e001b;hpb=0363ad37d44a5331c716d6890697e65f8f03ba91 diff --git a/tos/platforms/tmirws/sensors/WindVaneP.nc b/tos/platforms/tmirws/sensors/WindVaneP.nc index a6976e95..4042470e 100644 --- a/tos/platforms/tmirws/sensors/WindVaneP.nc +++ b/tos/platforms/tmirws/sensors/WindVaneP.nc @@ -39,11 +39,17 @@ module WindVaneP { provides interface ReadRef; uses { interface Tick as Second; - interface AsyncGet as Vane; + interface Read as Vane; } } implementation { -#define COMPASS_COUNT 32 + enum { + /* Compass count should ideally be a power of 2, or at least even */ + COMPASS_COUNT = 36, + ADC_PER_HEADING = (4096 + COMPASS_COUNT - 1) / COMPASS_COUNT, + ADC_OFFSET = (ADC_PER_HEADING + 1) / 2, + ADC_BITMASK = 0x0fff, + }; wind_vane_t* m_data; /* compass[0] = North, 0 degrees, @@ -156,22 +162,26 @@ implementation { /*** Method implementations ***/ + task void startRead() + { + call Vane.read(); + } async event void Second.fired() { - const static uint8_t lookup[] = { - 0x01, 0x03, 0x02, 0x06, 0x04, 0x0c, 0x08, 0x18, - 0x10, 0x30, 0x20, 0x60, 0x40, 0xc0, 0x80, 0x81 - }; - uint8_t wind; - uint8_t i = 0; - - wind = call Vane.get(); - for (i = 0; i < sizeof(lookup); i++) { - if (lookup[i] == wind) { - compass[i]++; - return; - } + post startRead(); + } + + event void Vane.readDone(error_t error, uint16_t value) + { + if (error == SUCCESS) { + /* Convert the adc value (0...4095) to a compass heading + * (0...COMPASS_COUNT - 1). + */ + value = (value + ADC_OFFSET) / ADC_PER_HEADING; + while (value >= COMPASS_COUNT) + value -= COMPASS_COUNT; + compass[value]++; } } @@ -213,10 +223,12 @@ implementation { /* m_data's left, avg and right fields are currently represented in * compass positions. We must now convert those fields into units of - * angular degrees. + * angular degrees. The order of calculations is to maximize precision + * using integer arithmetic. Note that using a 16-bit unsigned field + * for calculations, the largest value of COMPASS_COUNT is 37. */ - m_data->left = 1800U / COMPASS_COUNT * m_data->left / 10; - m_data->right = 1800U / COMPASS_COUNT * m_data->right / 10; + m_data->left = 1800U * m_data->left / COMPASS_COUNT / 10; + m_data->right = 1800U * m_data->right / COMPASS_COUNT / 10; } m_data = 0;