I have a wind direction sensor with 4 phototransistors and LEDs that uses a round disc to encode a gray code output to indicate direction. I'm trying to find a way to convert the 4 bits to 16 directions like N, ENE, E, ESE and so on for display.
Using pinmode, I was able to connect the output of the 4 phototransistors to the Uno and see the inputs going high and low when turning the disc shaft.
I have a chart that lists each of the 16 directions as it relates to the high/low status of the phototransistors.
What is the best way to do this? I thought about using if statements tying each of the 16 directions to the 4 bit code but that seems like the long way around.
Why not take a few moments to provide some actually useful information about your setup, like what wind sensor you have, how you are reading it now, what Arduino you have, how you are currently displaying the wind direction, etc.?
For instructions and suggestions, take a look at the "How to get the best out of this forum" post.
To address "breaking solutions down", the link I posted featured this function to convert Gray code to binary.
int grayToBinary(int gray)
{
int binary=0;
for(;gray;gray=gray>>1)
{
binary^=gray;
}
return binary;
}
This sensor of yours is probably an absolute encoder.
But as I don't have any references about it, it's just a guess.
If you post more information about your sensor, (Datasheet, link, photo, etc.), perhaps we can help you better.
The sensor is a Heathkit ID5001 wind direction sensor. Currently using an Uno. That's what I am intending to do, display the direction on a LCD or TFT. No display now except to see the 4 bit code displayed in the serial monitor using a simple pinmode sketch.
Heathkit published a table showing how the 4 bit code works showing the high/low status of the 4 input lines and the wind direction it represents.
N : HHHH
NNW : LHHH
NW : LLHH
WNW : HLHH
W : HLLH
etc......
I'm not sure why I would want to convert to binary since my desire is to convert to a wind direction for display?
The Gray code is not friendly in the sense that you need to translate that to a direction.
By convert to binary, we understand it to mean convert Gray code to its sequential equivalent.
By converting the Gray code to regular binary, you will end up directly having a numbe 0..15 that will be one of the 16 possible wind directions sensible, in order from (say) 0, North all the way 'round to 15 almost North again.
The function @jremington provides does that with code. The other suggestions, a table or if/else statements or a switch/case would all be commuting the same result.
Once you have a number 0..15, you can use that to, for example, print of of 16 character array strings to give the wind direction a nice name. Or change to degrees. Or whatever.
// digital pin 2 has a pushbutton attached to it. Give it a name:
int pushButton2 = 2;
int pushButton3 = 3;
int pushButton4 = 4;
int pushButton5 = 5;
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
// make the pushbutton's pin an input:
pinMode(pushButton2, INPUT);
pinMode(pushButton3, INPUT);
pinMode(pushButton4, INPUT);
pinMode(pushButton5, INPUT);
}
// the loop routine runs over and over again forever:
void loop() {
// read the input pin:
int buttonState2 = digitalRead(pushButton2);
int buttonState3 = digitalRead(pushButton3);
int buttonState4 = digitalRead(pushButton4);
int buttonState5 = digitalRead(pushButton5);
// print out the state of the button:
Serial.print("Input 2 ");
Serial.println(buttonState2);
Serial.print("Input 3 ");
Serial.println(buttonState3);
Serial.print("Input 4 ");
Serial.println(buttonState4);
Serial.print("Input 5 ");
Serial.println(buttonState5);
Serial.println();
delay(3000); // delay in between reads for stability
}
You can make a four bit Gray code from the results of the digital reads as follows:
byte index = 0;
if (buttonState2) index = index|1; //bitwise OR to set bit 0 for HIGH
if (buttonState3) index = index|2; //bit 1
if (buttonState4) index = index|4;
if (buttonState5) index = index|8;
A lookup table can convert the Gray code directly to printable ASCII compass directions. It might look something like this (but certainly NOT in this order):
The table order will depend on how you wired the switches, how those switch values translate to digital signals, and how the resulting Gray code relates to compass directions, which you failed to mention.
Which is why I liked the idea of converting the Gray code to its sequence number.
I don't wanna figure out the order of things, even once, as it wouldn't be just once but take some errors.
With the index made linear, you only have to know that 0 means North, or whatever, and which way around the compass CW or CCW the NWSE names are arranged.
I don't either, but if the OP is happy doing the trial and error grunt work, rather than adopting the three-code-line translation approach, problem solved.