# Circular Mapping of Values Question

I’m rebuilding an ex-CSIRO and interfacing it to an Arduino. I’m at a point where I need to map the analog output of the wind vane (0-1023) through to degrees (0-359). That part is easy with the “map” command.

The difficult bit now is to associate a text string (currently an array of strings in the form `char* myStrings[]={" N ", "NNE", " NE", ...)`
The problem here is that myStrings needs to cover the range 348 through 359 wrap to 0 through 11!

I can do it in M\$ xl using a cell like -
=ROUNDDOWN(IF((C3+12)>359,0,(C3+12)/22.5),0)
This gives a nice index into the array, but I can’t figure out how to do it in processing/wiring.

Help appreciated

There are two ways you can do this.

The first is with a switch statement or lots of if statements.

The second is to use modular arithmetic, that is an integer divide of the reading by the size of each increment range.

That is suppose you had a reading from 0 to 360 and you wanted to split it up into 10 degree segments. the simply index = reading / 36 would give you the value of the index into your string array.

If reading can go above 360 then put it in a while loop subtracting 360 from it until the result is less than 360.

If the index into the array and the 0 to 360 started at the same point, it would be easy. The problem is that the “N” text (for North) starts at 348degrees and finishes at 11degrees (ie one sixteenth of the circle) whereas the rest of the segments are 22.5 degrees for each array index portion.

I guess I could double the size of the array, 32 directoin text pieces looking like

``````myStrings[]={" N ", "NNE", "NNE", " NE", "NE"...
``````

finally arriving at

`````` ..."NW", "NW", "NNW", " NNW", "N")
``````

using `map[idx, 0,359,0,31]` to index into the array.

That way the last 11degrees (348 to 359), and the first 11degrees (0 to 11) would both map to an “N” value in the array.
That seems rather kludgy as well.

I’ve tried the “multiple if” solution, but it looks like very ugly code.

Thanks for the help so far…

starts at 348degrees and finishes at 11degrees

So you just have two instances of N in the string array and calculate the index into the array as if you had two instances of every entry. Then adjust the index by adding one and dividing by two.

Now THATS smart! Thanks Grumpy_Mike.

``````#define countof(a)  (sizeof(a)/sizeof(*(a)))

// Any number of evenly-spaced compass point names,
// always ending in N (which overlaps 0 degrees).
//
static const char* _compass[] = { "E", "S", "W", "N" };

// Return the compass rose name for a given degrees bearing.
//
const char* getCompassPoint(int degrees)
{
degrees = degrees + 360 - 180 / countof(_compass);
int index = degrees * countof(_compass) / 360;
index = index % countof(_compass);
return _compass[index];
}
``````

The array _compass can have 8, 16, 32, or any number of compass point names. The function returns the correct compass point name for an integer heading from 0 to 360.

First statement in the function rotates the given number of degrees by one half of one compass point area-- counterclockwise. We add positive degrees, almost a full 360, even if it means the answer goes over 360 degrees.

Second statement in the function scales the number of degrees down to the number of compass point names. A map() function could do this but it’s a simple ratio. With computer math, especially integers, always do a multiply before a divide, to maintain the best accuracy.

Third statement will “wrap around” the given index so it doesn’t exceed the number of compass point names. An index of eleven must be wrapped around to three. In grade school we learn that 11/8 is “one, with a remainder of three.” The % operator is how to find the remainder of integer division. It’s called the modulo operator. That’s what I thought Grumpy was going to teach with his mention of “modulo arithmetic.”

Fourth statement returns the static constant string name for the desired compass point.

That’s what I thought Grumpy was going to teach with his mention of “modulo arithmetic.”

Yes it was but I came up with the other solution as I typed it in. 