Thanks DB. I would like to try out the vector averaging/summing method you described. Can you please elaborate a little more? (i do not know what vector averaging/summing is). Maybe a sketch of how the code would look?
A vector is a quantity comprising two parts: a
magnitude and a
direction. For now let's assume all magnitudes are the same non-zero value (e.g. 1 or 1000 or 32767).
In the Dreaded ASCII Graphics below, imagine the blue and red vectors (on the right) point to the direction the wind is coming from, SSE and SSW, over two successive samples (not the wind velocities themselves, which have the arrows pointing in the opposite directions).
The black vector (on the left) is the
sum of the red and blue vectors, which is the result of putting them nose to tail i.e. the nose of the first SSE vector is at the tail of second SSW vector, and drawing a vector from the tail of the first (SSE) to the head of the second (SSW). One way to think about it is to consider how a massless balloon would move with the wind. When the first SSE sample occurs, the balloon would move NNW; when the second SSW sample occurs, the balloon would move NNE; the net movement of the balloon over the two samples would be North, because the mean wind was from the South (assume constant wind speed for all samples).
If we expand that concept to sum 300 sample vectors over ten minutes, the direction of the summed result will be a representation of the overall* wind direction during that period.
* "overall wind direction" is probably a better phrase than "mean wind direction" here.
Code:
[COLOR=Red][B] [COLOR=Black]|[/COLOR] [COLOR=Blue]\[/COLOR][/B][/COLOR]
[COLOR=Red][B][COLOR=Red][B] [COLOR=Black]|[/COLOR][/B][/COLOR] [COLOR=blue]\[/COLOR][/B][/COLOR]
[COLOR=Red][B][COLOR=Red][B] [COLOR=Black]|[/COLOR][/B][/COLOR] [COLOR=blue] \[/COLOR]
[/B][/COLOR][COLOR=Red][B][COLOR=Red][B] [COLOR=Black]|[/COLOR][/B][/COLOR] [COLOR=blue] \ [/COLOR] [/B] [COLOR=blue]<- SSE sample vector[/COLOR][/COLOR]
[COLOR=Red][B][COLOR=Red][B][COLOR=black]vector [/COLOR] [COLOR=Black]|[/COLOR][/B][/COLOR] [COLOR=Red][COLOR=Blue]_\|[/COLOR][/COLOR][/B][/COLOR]
[COLOR=Red][B][COLOR=Red][B][COLOR=Black] sum ->[/COLOR] [COLOR=Black]|[/COLOR][/B][/COLOR] /[/B][/COLOR]
[COLOR=Red][B][COLOR=Red][B] [COLOR=Black]|[/COLOR][/B][/COLOR] /[/B][/COLOR]
[COLOR=Red][B][COLOR=Red][B] [COLOR=Black]|[/COLOR][/B][/COLOR] /[/B][/COLOR]
[COLOR=Red][B][COLOR=Red][B] [COLOR=Black]|[/COLOR][/B][/COLOR] / [/B]<- SSW sample vector[/COLOR]
[COLOR=Red][B][COLOR=Red][B] [COLOR=Black]v[/COLOR][/B][/COLOR]|/_[/B][/COLOR]
The individual vectors can be further broken down into a sum of orthogonal components; see DAG below. The SSE sample vector (blue) has a North-South (black, positive to the North, negative to the South) component and an East-West component (red, positive to the East, negative to the West).
Code:
[COLOR=Red][B][COLOR=Black]+[/COLOR][/B][/COLOR]
[COLOR=Red][B][COLOR=Black]|[/COLOR][COLOR=Blue]\[/COLOR][/B][/COLOR]
[COLOR=Red][B][COLOR=Red][B][COLOR=Black]|[/COLOR][/B][/COLOR] [COLOR=blue]\[/COLOR][/B][/COLOR]
[COLOR=Red][B][COLOR=Red][B][COLOR=Black]|[/COLOR][/B][/COLOR] [COLOR=blue] \[/COLOR]
[/B][/COLOR][COLOR=Red][B][COLOR=Red][B][COLOR=black]o[/COLOR][/B][/COLOR] [COLOR=blue] \ [/COLOR] [/B] [COLOR=blue]<- SSE sample vector; + are tail[/COLOR][/COLOR]
[COLOR=Red][B][B]+[/B]-[COLOR=Red]---o[/COLOR][/B][/COLOR]
So we can say a SSE vector of magnitude 1 comprises two components: -0.924 North; +0.382 East; in shorthand [-0.924,+0.382]. And a SSW vector of magnitude 1 comprises similar components: -0.824 North; -0.382 East; [-0.924,-0.382]. If we sum those Northerly components separately from the Easterly components,
[-0.924,+0.382] + [-0.924,-0.382]
= [(-0.924 + -0.924), (+0.382 + -0.382)]
= [-1.848, 0.000]
we get a pair of components that represents the sum of the SSE and SSW vectors: -1.848 North; 0.000 East; [-1.848, -0.000].
Since the sum has no net Easterly component, and the Northerly component is negative, the summed vector is pointing South.
It should be intuitive to extend this to three or 300 vector samples; keeping the 300 NS sampled components in one FIFO and the 300 EW sampled components in another FIFO, then adding the newest sample components and subtracting the oldest sample from two running sums of the components as each new sample comes in.
The only thing left is to determine the wind direction of the current 300-vector sum e.g. [-273.123, +65.456]. We could use arc tangent to get a numeric angle and select the compass point based on which range that angle falls into e.g. in degrees, 168.75 to 146.25 is SSE. Or, since we have pre-calculated the components for each compass point, we can take the dot (a.k.a. scalar a.k.a. inner) product of each compass point's vector with the summed vector, and the compass point's product that is the most positive is the closest compass point to that wind direction.
The dot product of two vectors, [A,B] . [c,d] is the quantity (A*c + B*d); note that that result is a scalar i.e. not a vector. E.g. if our summed vector is [-273.123, +65.456], then it should be obvious that the closest compass point will be either S or SSE:
- South: [-273.123, +65.456] . [-1.0, 0.0] = [-273.123*-1.0, +65.456*0.0] = +273.123 + 0.0 = +273.123
- SSE: [-273.123, +65.456] . [-0.924,+0.382] = [-273.123*-0.924, +65.456*+0.382] = +252.365 + 25.004 = +277.370
277.370 is greater than 273.123, the overall direction would be SSE.
For the purposes of this exercise it would be adequate to perform all of these calculations using DINTs instead of REALs, since the scaling is constant.