Remove last 6 bit from unsigned char

Hey guys,

I have this unsigned char as bit and need to remove the last 6 bit:

current is:

unsigned char databits[MAX_BITS];    // stores all of the data bits
  if (bitCount > 0 && flagDone) {
    unsigned char i;
    Serial.print("Raw Binary = ");
    for (i=0; i<bitCount; i++) 
     {
       Serial.print(databits[i]); //output is 00111100111110100010010100000011
     }
    Serial.print("\nBits = ");
    Serial.print(bitCount);

the output databits is 00111100111110100010010100000011 and need to make it like this: 00111100111110100010010100

Any help please

uint32_t input = 0b00111100111110100010010100000011;

void setup()
{
  Serial.begin(115200);
  Serial.println(input, BIN);
  Serial.println(input >> 6, BIN);
}

void loop()
{
}

Output

111100111110100010010100000011
111100111110100010010100

Thanks for the solution, but how can I add 0b at the beginning, because my code without 0b?

Why do you need 0b at the beginning ?
What are you actually doing with the output ?

Srsly?

  Serial.begin(115200);
  Serial.print("anything you want to print 0b");
  Serial.println(input, BIN);
  Serial.print("again, any prefix you desire 0b");
  Serial.println(input >> 6, BIN);

HTH

a7

Because in your example there is 0b at the beginning! and the output in my code without 0b?

And Imma guess you don't see that you could also just

    for (i=0; i < bitCount - 6; i++) 

leave off the last 6 bits of the araray that the for loop iterates over.

a7

My example has 0b at the beginning to indicate to the compiler that it is a binary number

1023026435 would work just as well

What exactly are you going to do with the output ?

My output is 32 bit and need to make it 26 bit by remove the last 6 bit!

What are you going to do with the 26 bits

Note, that in my example there are still 32 bits in the output as shown by this example

uint32_t input = 0b00111100111110100010010100000011;
uint32_t output;

void setup()
{
  Serial.begin(115200);
  output = input >> 6;
  printBin(input);
  printBin(output);
}

void loop()
{
}

void printBin(uint32_t number)
{
  for (int b = 31; b >= 0; b--)
  {
    Serial.print(bitRead(number, b));
  }
  Serial.println();
}

Note that there is no such thing as a 26 bit variable in C/C++ but you can choose to only use any range of bits within a variable and ignore the rest if that is what you want

uint32_t input = 0b00111100111110100010010100000011;

void setup()
{
  Serial.begin(115200);
  printBin(input, 31, 0);
  printBin(input, 31, 6);
}

void loop()
{
}

void printBin(uint32_t number, int start, int end)
{
  for (int b = start; b >= end; b--)
  {
    Serial.print(bitRead(number, b));
  }
  Serial.println();
}

is there any reason why you store your 32bit in a char array with 32 byte?

if this is really your intend @alto777 gave a solution in #7 already. Have you tried it? What happend?

Actually I am reading the bit from HID reader and I want if the reading is 26 bit will send it out as wiegand value but if 32 i want to remove last 6 bit to make it 26 bit then send it out as wiegand number.

Actually I am reading the bit from HID reader and I want if the reading is 26 bit will send it out as wiegand value but if 32 i want to remove last 6 bit to make it 26 bit then send it out as wiegand number.

Where is last 6 bits? The last 6 high bits printed on the left end or the last 6 low bits on the right end?

In RAM all the bits are 0 or 1 but we don't print the high zeros.

RAM with 00000011 would print binary value as 11 but leading zeros could be printed.
It could also print as 3.
What do you send, text or binary?

I am going to test it tonight....the reader is far a way from me...i have to drive 35 min to reach there :sweat_smile:

To me it seems that he needs to send 26 bit values to something.
That might be 32 bits with the top 6 bits masked off,

unsigned long data = 0xFFFF;

data &= 0x3FFF; // top 6 bits masked

What are you reading are not a bits, it are chars. It is a problem. Why do you reading it as chars?
Please show the code how do you read it,

This code to read the bits from cards:

#define MAX_BITS 100                 // max number of bits 
#define WEIGAND_WAIT_TIME  3000      // time to wait for another weigand pulse.  
 
unsigned char databits[MAX_BITS];    // stores all of the data bits
unsigned char bitCount;              // number of bits currently captured
unsigned char flagDone;              // goes low when data is currently being captured
unsigned int weigand_counter;        // countdown until we assume there are no more bits
 
unsigned long facilityCode=0;        // decoded facility code
unsigned long cardCode=0;            // decoded card code

int LED_GREEN = 11;
int LED_RED = 12;
int BEEP_BEEP = 10;

// interrupt that happens when INTO goes low (0 bit)
void ISR_INT0() {
  bitCount++;
  flagDone = 0;
  weigand_counter = WEIGAND_WAIT_TIME;  
 
}
 
// interrupt that happens when INT1 goes low (1 bit)
void ISR_INT1() {
  databits[bitCount] = 1;
  bitCount++;
  flagDone = 0;
  weigand_counter = WEIGAND_WAIT_TIME;  
}
 
void setup() {
  pinMode(LED_RED, OUTPUT);  
  pinMode(LED_GREEN, OUTPUT);  
  pinMode(BEEP_BEEP, OUTPUT);  
  digitalWrite(LED_RED, HIGH); // High = Off
  digitalWrite(BEEP_BEEP, HIGH); // High = off
  digitalWrite(LED_GREEN, LOW);  // Low = On

  //Make sure the mode is INPUT_PULLUP for Software House SWH 5100 Model.
  pinMode(2, INPUT_PULLUP);     // DATA0 (INT0) 
  pinMode(3, INPUT_PULLUP);     // DATA1 (INT1)
 
  Serial.begin(9600);
  Serial.println("RFID Readers");
 
  // binds the ISR functions to the falling edge of INTO and INT1
  attachInterrupt(0, ISR_INT0, FALLING);  
  attachInterrupt(1, ISR_INT1, FALLING);
 
 
  weigand_counter = WEIGAND_WAIT_TIME;
}
 
void loop()
{ 
  // This waits to make sure that there have been no more data pulses before processing data
  if (!flagDone) {
    if (--weigand_counter == 0)
      flagDone = 1; 
  }
 
  // if we have bits and we the weigand counter went out
  if (bitCount > 0 && flagDone) {
    unsigned char i;
    Serial.print("Raw Binary = ");
    for (i=0; i<bitCount; i++) 
     {
       Serial.print(databits[i]);
     }
    Serial.print("\nBits = ");
    Serial.print(bitCount);

      if (bitCount == 32) {

       Serial.print(databits[i]-6);
     
     
   //Serial.println(databits[i], BIN);
  //Serial.println(databits[i] >> 6, BIN);
  
      }

    
    if (bitCount == 35) {
      Serial.print("\nCard format: HID Corporate 1000");
      // facility code = bits 2 to 14
      for (i=2; i<14; i++) {
         facilityCode <<=1;
         facilityCode |= databits[i];
      }
 
      // card code = bits 15 to 34
      for (i=14; i<34; i++) {
         cardCode <<=1;
         cardCode |= databits[i];
      }
 
      printBits();
    }
    else if (bitCount == 26) {
      Serial.print("\nCard format: Standard 26 bit format");
      // facility code = bits 2 to 9
      for (i=1; i<9; i++) {
         facilityCode <<=1;
         facilityCode |= databits[i];
      }
 
      // card code = bits 10 to 23
      for (i=9; i<25; i++) {
         cardCode <<=1;
         cardCode |= databits[i];
      }
      printBits();
    }
    else if (bitCount == 40) {
      Serial.print("\nCard format: Casi-Rusco 40 Bit");
      Serial.print("\n\n**************************\n\n"); 
      
    }else{

     // you can add other formats if you want!
     Serial.print("\nUnable to decode.");
     Serial.print("\n\n**************************\n\n"); 
    }
     // cleanup and get ready for the next card
     bitCount = 0;
     facilityCode = 0;
     cardCode = 0;
     for (i=0; i<MAX_BITS; i++) 
     {
       databits[i] = 0;
     }
  }
}
 
void printBits(){

      Serial.print("\nFacility Code = ");
      Serial.print(facilityCode);
      Serial.print("\nCard Code = ");
      Serial.print(cardCode);
      Serial.print("\n\n**************************\n\n");

      // Now lets play with some LED's for fun:
      digitalWrite(LED_RED, LOW); // Red
      if(cardCode == 432279){
        // If this one "bad" card, turn off green
        // so it's just red. Otherwise you get orange-ish
        digitalWrite(LED_GREEN, HIGH); 
      }else {
      digitalWrite(LED_GREEN, LOW); 
      digitalWrite(LED_RED, HIGH); 
      delay(100);
      digitalWrite(LED_RED, LOW); 
      delay(100); 
      digitalWrite(LED_RED, HIGH); 
      delay(100);
      digitalWrite(LED_RED, LOW);
      delay(100);// Red Off
      digitalWrite(LED_RED, HIGH);
      delay(300);// Red Off  
 
      // Lets be annoying and beep more
      digitalWrite(BEEP_BEEP, LOW);
      delay(500);
      digitalWrite(BEEP_BEEP, HIGH);
      delay(500);
      digitalWrite(BEEP_BEEP, LOW);
      delay(500);
      digitalWrite(BEEP_BEEP, HIGH);
      }
}

then I will recognize which one is 32 and 26, if 26 will send it as Wiegand and if 32 I will trim the last 6 bits then send it out as Wiegand using another code

And what is the problem? You already have a code which convert your char array to bits, for example:

If you need to convert your array to bits - use the similar code. if you need only 26 chars of 32 - just do not convert the last six.

If you need to print it only, just to change for loop limits :slight_smile:
To print 32 bits:

for (i=0; i<32; i++) 
     {
       Serial.print(databits[i]); 
     }

and to print 26

for (i=0; i<26; i++) 
     {
       Serial.print(databits[i]); 
     }