Need assistance reading values the size of one or more bits from a single byte

Attempting to read variables of different sizes stored in a single byte. What I've done is attempted to use a nested for loop which iterates as many times as there are bits in the variable to be read. To get a variable that is the size of 4 bits, the loop is intended to iterate 4 times, which uses the array "sizeOfEachVariableInBits". The index of 'sizeOfEachVariableInBits' is determined by the outer for loop.

Upon each iteration "variablesReadFromBits" is supposed to accumulate by adding the next read bit to the previous bit which has been shifted using the >> (or should it be the <<?) operator.

However, I cannot figure out how to do this. The formula probably looks like nonsense and you'd be correct. It's only the most recent of things I've tried while troubleshooting. If I've made my goal clear enough, how do I achieve this with the method I'm attempting to use? Otherwise I'm happy to answer any questions.

This is part of a larger project where the number of bits used are in many different sizes, and orders, for example the array "sizeOfEachVariableInBits", etc. will be a 2D array, so using bit fields, while effective, is impractical given the number of elements to account for, which is why I've chosen this method instead. Thanks!

uint8_t numOfStoredVariables = 4;

uint8_t sizeOfEachVariableInBits[] = {4, 2, 1, 1};

uint8_t variablesToBeStored[] = {12, 2, 0, 1}; //unused, for display

uint8_t bitMask[] = {0, 2, 4, 6, 8, 16, 32, 64, 128};

void setup() {

  Serial.begin(9600);
  while (!Serial) {};

  uint8_t variousBitSizedVariablesStoredInAByte = 201;

  Serial.println(variousBitSizedVariablesStoredInAByte, BIN);

  for (int i = (numOfStoredVariables - 1); i >= 0; i--) {

    uint8_t variablesReadFromBits[numOfStoredVariables];

    for (int j = (sizeOfEachVariableInBits[i] - 1); j >= 0; j--) {

      variablesReadFromBits[i] =
        
        (variablesReadFromBits[i] >> j) + (variousBitSizedVariablesStoredInAByte & bitMask[i]);

    }

    Serial.println(variablesReadFromBits[i]);

  }

}

void loop() {


}

That don’t look right. It can’t be helping.

a7

All variables stored in a byte will be the same size, ie 8 bits, so I don't know what you mean by this

For a field of size n, the mask for the field is ((1<<n)-1)

Or, you can name bit fields:

struct bitfields
{
  // Bits are assigned right to left
  byte first : 4,  // Rightmost 4 bits
   second : 2,
   third : 1,
   fourth : 1; // Leftmost bit
} myData;

void setup()
{
  Serial.begin(115200);
  delay(200);

  *(byte*)&myData = 0b10101010;  // Trick the compiler into letting us store a byte here

  Serial.println(sizeof myData);
  Serial.println(*(byte*)&myData, BIN);

  Serial.println(myData.first, BIN);  // Rightmost 4 bits
  Serial.println(myData.second, BIN);
  Serial.println(myData.third, BIN);
  Serial.println(myData.fourth, BIN); // Leftmost bit
}

void loop() {}

Hello

Here is one possible solution : 6knDFu - Online C++ Compiler & Debugging Tool - Ideone.com

Another way to do it if the original value of 'testValue' is no longer needed:

	for ( uint8_t i = 0; i < numOfStoredVariables; i++ )
	{
		variablesReadFromBits[i] = testValue & ((1 << sizeOfEachVariableInBits[i]) - 1);
                testValue >>= sizeOfEachVariableInBits[i];
	}

This was the solution, thank you very much! The missing piece was the rshCounter, and the nested for loop was flat out wrong.

Curious, what does rsh stand for?

Right shift... :slight_smile: