Search code examples
carduinoembeddedmicrocontroller

Is there a way to implement Morse code inside an array?


I'm making my microcontroller display letters of the alphabet in Morse code using LEDS (dot == short blink, dash == long blink).

I could make a switch statement and do it like this :

switch (input)
case "a | A" 
.... 
case "b | B "
....

but then I'd have a 27+ long switch statement, so I guess that's not very good?

I was thinking of making an array with all the Morse code inside but how do I implement this concept, that the first entry of the array equals a or A, ... ?


Solution

  • If we assume that your platform uses a character-encoding system in which the 26 Latin alphabet letters have consecutive values (the most common system used, ASCII, does, but it's not guaranteed by the C Standard), then we can define an array of strings for the Morse code for each letter and index into that array using the value of a given letter from which the value of 'A' has been subtracted.

    We can also do a similar thing for digits (these are guaranteed by the Standard to have contiguous codes).

    Here's a sample code (we convert all letters to uppercase before indexing into the Morse array):

    #include <stdio.h>
    #include <ctype.h>
    
    int main()
    {
        const char* Alpha[26] = {
            ".-",   // A
            "-...", // B
            "-.-.", // C
            "-..",  // D
            ".",    // E
            ".._.", // F
            "--.",  // G
            "....", // H
            "..",   // I
            ".---", // J
            "-.-",  // K
            ".-..", // L
            "--",   // M
            "-.",   // N
            "---",  // O
            ".--.", // P
            "--.-", // Q
            ".-.",  // R
            "...",  // S
            "-",    // T
            "..-",  // U
            "...-", // V
            ".--",  // W
            "-..-", // X
            "-.--", // Y
            "--.."  // Z
        };
        const char* Digit[10] = {
            "-----",// 0
            ".----",// 1
            "..---",// 2
            "...--",// 3
            "....-",// 4
            ".....",// 5
            "-....",// 6
            "--...",// 7
            "---..",// 8
            "----.",// 9
        };
        char input[256];
        do {
            printf("Enter text ($ to quit): ");
            scanf("%255s", input);
            printf("Morse code...\n");
            for (char *c = input; *c; ++c) {
                if (isalpha(*c)) printf("%s", Alpha[toupper(*c) - 'A']);
                else if (isdigit(*c)) printf("%s", Digit[*c - '0']);
                else if (*c != '$') printf("<error>");
                printf("\n");
            }
        } while (input[0] != '$');
        return 0;
    }
    

    If we can not rely on contiguous codes for the letters (or choose not to, for a more robust implementation), we can determine the index by calling the strchr function (we must then #include <string.h>) to get our letter's position in a list of all letters:

        //...
        const char* Letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        //...
            if (isalpha(*c)) printf("%s", Alpha[strchr(Letters,toupper(*c)) - Letters]);
    

    Please feel free to ask for any further clarification and/or explanation.