Search code examples
cmorse-code

Trouble with manipulating bits and Bytes with C - Morse code


I'm having trouble figuring out how manipulting bits work with C. Was wondering if someone could clear up something for me.

declaration :

const  unsigned  char  asciiToMCTable [] = {0x30, 0x31 , 0x32 , 0x33 , 0x34 , 0x35 , 0x36 , 0x37 , 0x38 , 0x39 , 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47 ,0x42 , 0x84 , 0xA4 , 0x83 , 0x01 , 0x24 ,0xC3 , 0x04 , 0x02 , 0x74 , 0xA3 , 0x44 ,0xC2 , 0x82 , 0xE3 , 0x64 , 0xD4 , 0x43 ,0x03 , 0x81 , 0x23 , 0x14 , 0x63 , 0x94 , 0xB4 , 0xC4};

this is the function that works perfectly with Alphabet (from A to Z) , but not with numeric :

unsigned  char  asciiToMC(unsigned  char  ascii){
        return  asciiToMCTable[ascii  - 48];
}

I think that something is wrong with these instructions :

void  MCSendChar(unsigned  char ch){
    unsigned  char a = asciiToMC(ch);
    unsigned  char n = a & 0x07 , j;

    printf("\n %u \n", n);
    for(j = 0; j < n; j++) {
        if((0x80 & a) != 0)
            MCendDash ();
        else
            MCSendDot ();

        a = a << 1;
        Sleep(10*MC_DOT_TIME);
    }

execution :

unsigned  char  ascii = '4';
    MCSendChar(ascii);
    printf("\n");

print : ..-- , which is not correct (should print : ....-)

    ascii = 'G';
    MCSendChar(ascii);
    printf("\n");

print : --. , correct


Solution

  • The ASCII values for digits 0 to 9 span the range 0x30 to 0x39 (48 to 57) inclusive. asciiToMC(ascii) returns asciiToMCTable[ascii-48], or equivalently asciiToMCTable[ascii-0x30]. Therefore, the first 10 elements of asciiToMCTable[] should contain the MC encodings for the ASCII digits 0 through 9.

    The Morse code encoding of an ASCII character in asciiToMCTable[] includes a morse sequence length n from 1 to 5 encoded in the bottom three bits, and the sequence of dots (0) and dashes (1) encoded in bits 7 downwards with bit 7 being the first Morse bit in transmission order.

    In Morse code, the digits 0 to 9 all have a sequence length of 5, so the top 5 bits should contain the sequence of dots (0) and dashes (1) for the particular digit, and the bottom 3 bits should contain the length 5.

                      MMMMMnnn
    0 = "-----" ==> 0b11111101 = 0xFD
    1 = ".----" ==> 0b01111101 = 0x7D
    2 = "..---" ==> 0b00111101 = 0x3D
    3 = "...--" ==> 0b00011101 = 0x1D
    4 = "....-" ==> 0b00001101 = 0x0D
    5 = "....." ==> 0b00000101 = 0x05
    6 = "-...." ==> 0b10000101 = 0x85
    7 = "--..." ==> 0b11000101 = 0xC5
    8 = "---.." ==> 0b11100101 = 0xE5
    9 = "----." ==> 0b11110101 = 0xF5
    

    (The 0b prefix above is being used for illustrative purposes only (since they are non-standard) to represent binary constants.)

    Currently, the first 10 elements of asciiToMCTable[] in OP's code contain the ASCII codes for the digits, which is not correct, leading to incorrect Morse code output for the ASCII digits. They need to be replaced with the Morse encodings listed above.