Manchester Encoding & Decoding Algorithm

Hi there,

I’ve been stuck on a manchester encoding / decoding problem for quite some time now, I understand that there are libraries to perform this task for me, however I would like to locally encode and store the data, and this is a function that the libraries don’t seem to provide. I have put together a little algorithm that takes a byte and masks it into a 16 bit encoded byte array with 2 parts. However my output is skewed and I’m not getting what I want…
I’m not the best at bit shifting and would really appreciate some help!

Here’s the algorithm ripped from my sketch with only the key variables required to perform it.

const byte SLAVE_A = 0x2; // Slave A
byte encodedArray[2]; // Encoded array to send
uint16_t ENCODED_BLOCK; // 8 bit receive
uint8_t DECODED_BLOCK;  // 8 bit result

void setup() {
  
  Serial.begin(9600);
  Serial.println("Manchester Debug Program");
  delay(2000);
}

void loop() {
  
  Serial.println(" ");
  Serial.println("Encoding SLAVE_A (i.e '1' or 00000001)");
  manchesterEncode(SLAVE_A); // encode the number one
  Serial.println("The output is:");
  Serial.print(encodedArray[0], BIN); Serial.print(encodedArray[1], BIN);
  Serial.println(" ");
  
  delay(3000);
  
}

byte * manchesterEncode(byte data) {  // Will encode the given byte
  
  byte mask = 1; // Bit Mask
  uint16_t ENCODED_BLOCK = 0; // storage an encoded "block"

  for (mask = 00000001; mask>0; mask <<=1) {  // Iterate through the bitmask
    if (data & mask) {  // If a 1
      
        ENCODED_BLOCK += 0b10; // Add "1" "0"
        ENCODED_BLOCK <<= 2; // Shift to the left twice
      
    } else {  // If a 0
      
        ENCODED_BLOCK += 0b01; // Add "0" "1"
        ENCODED_BLOCK <<= 2; // Shift to the left twice
    }
  }
  
   encodedArray[1] = (byte) ENCODED_BLOCK;  // Fit first part
   ENCODED_BLOCK >>= 8; // shift by 8
   encodedArray[0] = (byte) ENCODED_BLOCK;  // Fit second part
   
  return encodedArray; // Return the array
   
}

uint8_t manchesterDecode(byte encodedArray[2]) { // Will decode the given 2 bytes
  
  uint16_t ENCODED_BLOCK = 0; // 8 bit receive
  uint8_t DECODED_BLOCK = 0;  // 8 bit result
  uint16_t mask = 0xC000; // mask 2 sig bits set

  int count = 0; // Counter
  
        encodedArray[0] = (byte) ENCODED_BLOCK;  // Store the first part
        ENCODED_BLOCK >>= 8; // Shift by 8
        encodedArray[1] = (byte) ENCODED_BLOCK; // Store the last part
               
         for (;count<8; count++) {  // Start decoding

           DECODED_BLOCK <<= 1;
           
          if (ENCODED_BLOCK && mask == 0x8000) {  // If the bit "1" "0"
            
            DECODED_BLOCK |= 0x01; // add a 1
            
          } else if (ENCODED_BLOCK && mask == 0x4000) {  // If the bit is a "0" "1"
             
            DECODED_BLOCK &= ~ 0x01; // add a 0
            
          } else {

            // Error occured    
            
          }
          
       ENCODED_BLOCK <<= 2; // shift left by 2 bits
    } 
    
    return DECODED_BLOCK;  // Return this!
}

My output from encoding the number 1… or 00000001 is this:
101010010010101

Which certainly isn’t right :confused:

it’s cutting off a ‘0’ at the start… how do I go about stopping that?
& what’s wrong with my ‘for’ loop?

Cheers - Mike

Is it cutting off the 0, or just not printing the 0…?

Do you write $7.38 or $07.38?

The leading 0 is meaningless when printing a number, so it isn’t printed. But, as it’s a 16-bit value you can rest assured that the 16th bit will be there.

Also note that a number represented in the code as 0nnnnn is actually an octal number, not a binary number, so the number 011 is not 3, but 9. Use 0bnnnn for binary.

byte value = 0b00000001;
unsigned int encoded = 0;

for (byte b = 0; b < 8; b++) {
  encoded <<= 2;
  if (value & 0b1000000) {
    encoded |= 0b10;
  } else {
    encoded |= 0b01;
  }
  value <<= 1;
}

// Print each bit *including leading zeros*
for (byte b = 0; b < 16; b++) {
  if (encoded & (1<<(15-b))) {
    Serial.print("1");
  } else {
    Serial.print("0");
  }
}
Serial.println();