Convert 4 Boolean values to grey code to decimal

I am working on a project in which I am making an encoder demonstration for an arduino based class. The assembly consists of a stepper motor, 3D printed interchangeable encoder discs, and ITR20001/T Reflective IR Optical Sensors. The sensors output either a 1 or a 0 depending on whether or not they are positioned over the gaps in the encoder wheel. I currently have a prototype demo in which I can read all of the sensors and detect the encoder changes accurately.

I have 2 questions regarding the code:

  1. I need to flip all of the bits from 0 to 1 and 1 to 0. Is there a simple, more efficient way to do this other than conditional statements for each individual sensor reading ie. if(x==1){x=0}
  2. I need to combine the individual readings into grey code and then convert that to a decimal value representing the current angle.

I currently read the individual sensors and Serial print them in a string. This was just a way to test the accuracy of the sensors. I’m assuming a string is not the best way to combine the individual bits, but I do not know any other way as of now. Everything that I have found online so far is for converting stings of words into binary code.

I have attached an image of the encoder disc that I am using with the grey code values for each angle listed next to the disc, my current sketch, an image of the assembly, the data sheet for the sensors, and a pinout diagram of the sensor. In my circuit, I have A 470 ohm resistor to 5V.

ITR20001/T Datasheet:

gray_code.png

OpticalIRCode.ino (661 Bytes)

ITR20001 Pins.PNG

  1. I need to flip all of the bits from 0 to 1 and 1 to 0. Is there a simple, more efficient way to do this other than conditional statements for each individual sensor reading ie. if(x==1){x=0}
value = digitalRead(pin) ^ 1;

Will apply an exclusive or mask of 1 which will invert the bit.

  1. I need to combine the individual readings into grey code and then convert that to a decimal value representing the current angle.

Use the bitWrite instruction to get it into a single variable and a look up table to get your angle. A look up table is simply and array, the index being the grey code number and the contents being the angle.

I’m assuming a string is not the best way to combine the individual bits, but I do not know any other way as of now

You are actually currently using a String (uppercase S) not a string (lowercase s) but neither is necessary or desirable, particularly the String

Start by looking at the bitWrite() function and put the input pin numbers in an array so that you can iterate over them rather than repeating code

byte inputPins[] = {2, 3, 4, 5, 6};

void setup()
{
  Serial.begin(115200);
  for (int p = 0; p < 5; p++)
  {
    pinMode(inputPins[p], INPUT_PULLUP);
  }
}

void loop()
{
  byte output = 0;
  for (int p = 0; p < 5; p++)
  {
    bitWrite(output, p, digitalRead(inputPins[p]));
  }
  Serial.println(output, BIN);
}

To invert the bit values use

    bitWrite(output, p, !digitalRead(inputPins[p]));  //invert the value read from the pin

It really isn't necessary to invert the bit values when using them as an index into a lookup table, only for your convenience when printing the values.

jbelardi:

  1. I need to flip all of the bits from 0 to 1 and 1 to 0. Is there a simple, more efficient way to do this other than conditional statements for each individual sensor reading ie. if(x==1){x=0}
x = !x;

That only works if x has been declared as boolean.

Grumpy_Mike:
That only works if x has been declared as boolean.

false

oqibidipo:
false

No, using x = !x will make any non zero value into a zero. It won't flip all the bits.

If you want to flip all the bits in a byte then:

x ^= 255;

Grumpy_Mike:
That only works if x has been declared as boolean.

Grumpy_Mike:
That only works if x has been declared as boolean.

So declare x as a boolean then. If it is only expected to contain either of the values 0 or 1 then he may as well make it a boolean.

x = ~x;