Código Morse com Arduíno UNO

Olá, como estão? Hoje iremos desenvolver um decodificador de código Morse sensível ao toque, para este projeto usamos o KIT iniciante com Arduíno UNO da WJ Componentes.

Componentes Utilizados


OU

Funcionamento do Projeto Código Morse


Primeiramente como foi comentado acima iremos desenvolver um decodificador de Código Morse, onde o usuário irá passar o código Morse para o Arduíno UNO através do toque. E o Arduíno UNO vai retornar a mensagem enviada decodificada, porém não iremos utilizar o modulo de touch ao invés disso iremos utilizar o método capacitivo para identificar o toque através de um jumper.

Obs.: Não é recomendo utilizar esse método para projetos finais, pois ele possui uma alta latência e pode gerar resultados inesperados, é recomendado apenas para teste em protoboard.

Código Morse

Primeiramente precisamos entender o que é o Código Morse. Ele é um sistema de representação de algarismo, números e pontuação, através de um sinal codificado de modo impermanente, ou seja, não é contínuo. Além disso ele é constituído apenas por pontos e traços, e foi desenvolvido por Samuel Morse em 1985. Com o proposito principal de utilizar para transmitir mensagens e para ser usado na sua mais invenção o telegrafo. Contudo uma mensagem em Morse pode ser transmitida de diversas formas sendo elas pulsos elétricos, ondas mecânicas(também conhecida como Morse acústico), sinais visuais e ondas eletromagnéticas. Elas foram muito importantes em guerras, porém hoje raramente são usados, mas é sempre bom saber, pois nunca se sabe quando vai ser útil.

O Código Morse possui uma tabela com cada letra e seu código para que assim possamos consultar quando necessário.

código Morse
Figura 1 – Tabela Código Morse

Montagem do Projeto Código Morse


Logo após compra dos componentes na WJ Componentes, vamos à montagem! Agora será conectado os LEDs na protoboard com os resistores que ligamos nos catodos dos LEDs, e para finalizar os LEDs ligamos o anodo nos pinos 2 e 3 do Arduíno UNO, em seguida conectamos um jumper no pino A5 do Arduíno UNO, ele será responsável por identificar o toque usando a carga elétrica. Por exemplo a pele, pois configuramos o pino como input pull-up.

Contudo segue abaixo uma imagem que demonstrando a montagem do circuito.

Pinout LED Código Morse
Pinout LED
Montagem do Circuito Eletrônico na protoboard - Código Morse

Diagrama Esquemático do Projeto Código Morse


Diagrama do Circuito Eletrico - Código Morse

Código-fonte do Projeto Código Morse


Em seguida segue abaixo o código completo do projeto decodificador.

//Definições -----------------------------------------------------------------------------------------
#define led 2                                                         // Define LED nova letra
#define led2 3                                                        // Define LED novo comando
 
//Variáveis Globais ----------------------------------------------------------------------------------
unsigned long mili;                                                   // Armazena Tempo
int cont = 0;                                                         // Variável de controle
byte codi[5] = {};                                                    // Armazena código codificado
String msg;                                                           // Armazena MSG
byte i = 0;                                                           // Variável de controle
	 
//Funções Auxiliares ---------------------------------------------------------------------------------
void decodifica();                                                    // Responsável por Decodificar
 
//Setup ----------------------------------------------------------------------------------------------
void setup() {
    Serial.begin(9600);                                               // Inicializa a Serial
    pinMode(A5, INPUT_PULLUP);                                        // Configura A5 como INPUT_PULLUP
    pinMode(led, OUTPUT);                                             // Configura LED como OUTPUT
    pinMode(led2, OUTPUT);                                            // Configura led2 como OUTPUT
}
	 
//Loop -----------------------------------------------------------------------------------------------
void loop() {
    digitalWrite(led, HIGH);                                          // Sinaliza nova letra
    digitalWrite(led2, HIGH);                                         // Sinaliza novo comando
    int le = analogRead(A5);                                          // Atribui a le o valor de A5
    mili = millis();                                                  // Atribui mili o valor de millis
    while (le < 950) {                                                // Loop até le ser menor que 950
        digitalWrite(led, LOW);                                       // Apaga LED
        if (analogRead(A5) < 950) {                                   // Verifica se A5 é menor que 950
            digitalWrite(led2, LOW);                                  // Apaga led2
            cont++;                                                   // Incrementa +1 a cont
        }
        if (mili + 2000 < millis()) {                                 // Verifica se mili+2000 < millis
            if (cont > 1000) {                                        // Verifica se cont > 1000
                codi[i] = 2;                                          // Atribui a codi[i] o valor 2
                i++;                                                  // Incrementa +1 a i
            }
            else if (cont != 0) {                                     // Verifica se cont != 0
                codi[i] = 1;                                          // Atribui a codi[i] o valor 2
                i++;                                                  // Incrementa +1 a i
            }
            else {
                Serial.println();                                     // Imprime Quebra linha na Serial
                decodifica();                                         // Chama função decodifica()
                le = 1024;                                            // Atribui a le = 1024;
                for (i = 0; i < 5; i++) {                             // Loop de 5 vezes
                  codi[i] = 0;                                        // Atribui a codi[i] o valor de 0
                }
                i = 0;                                                // Atribui a i o valor de 0
                Serial.println(msg);                                  // Imprime mensagem na Serial
            }
            digitalWrite(led2, HIGH);                                 // Sinaliza novo comando
            delay(100);                                               // Espera 0,1s
            cont = 0;                                                 // Atribui a cont o valor de 0
            mili = millis();                                          // Atribui millis a mili
        }
    }
}
	 
//Decodifica -----------------------------------------------------------------------------------------
void decodifica() {
    if (codi[0] == 1) {                                               // Verifica se codi[0] = ponto
        if (codi[1] == 1) {                                           // Verifica se codi[1] = ponto
            if (codi[2] == 1) {                                       // Verifica se codi[2] = ponto
                if (codi[3] == 1) {                                   // Verifica se codi[3] = ponto
                    if (codi[4] == 1) {msg += "5";}                   // Verifica se codi[4] = ponto
                    else if (codi[4] == 2) {msg += "4";}              // Verifica se codi[4] = traço
                    else {msg += "H";}                                // Se não incrementa H a msg
                }
                else if (codi[3] == 2) {                              // Verifica se codi[3] = traço
                    if (codi[4] == 2) {msg += "3";}                   // Verifica se codi[4] = traço
	                else if (codi[4] == 0) {msg += "V";}                // Verifica se codi[4] = null
                }
                else {msg += "S";}                                    // Se não atribui S a msg
            }
            else if (codi[2] == 2) {                                  // Verifica se codi[2] = traço
                if (codi[3] == 1) {msg += "F";}                       // Verifica se codi[3] = ponto
                else if (codi[3] == 2 && codi[4] == 2) {msg += "2";}  // Verifica se codi[3, 4] = traço
                else {msg += "U";}                                    // Se não atribui U a msg
            }
    	    else {msg += "I";}                                          // Se não atribui I a msg
        }
        else if (codi[1] == 2) {                                      // Verifica se codi[1] = traço
            if (codi[2] == 1) {                                       // Verifica se codi[2] = ponto
                if (codi[3] == 1 && codi[4] == 0) {msg += "L";}       // Verifica se é ponto e null
                else if (codi[3] == 0) {msg += "R";}                  // Verifica se codi[3] = null
            } 
            else if (codi[2] == 2) {                                  // Verifica se codi[2] = traço
                if (codi[3] == 1 && codi[4] == 0) {msg += "P";}       // Verifica se é ponto e null
                else if (codi[3] == 2) {                              // Verifica se codi[3] = traço
                    if (codi[4] == 2) {msg += "1";}                   // Verifica se codi[4] = traço
                    else if (codi[4] == 0) {msg += "J";}              // Verifica se codi[4] = null
                }
               else {msg += "W";}                                     // Se não atribui W a msg
            } 
            else {msg += "A";}                                        // Se não atribui A a msg
        }
        else {msg += "E";}                                            // Se não atribui E a msg
    }
    else if (codi[0] == 2) {                                          // Verifica se codi[0] = traço
        if (codi[1] == 1) {                                           // Verifica se codi[1] = ponto
            if (codi[2] == 1) {                                       // Verifica se codi[2] = ponto
                if (codi[3] == 1) {                                   // Verifica se codi[3] = ponto
                    if (codi[4] == 1) {msg += "6";}                   // Verifica se codi[4] = ponto
                    else if (codi[4] == 0) {msg += "B";}              // Verifica se codi[4] = null
                }
                else if (codi[3] == 2 && codi[4] == 0) {msg += "X";}  // Verifica se é traço e null
                else {msg += "D";}                                    // Se não incrementa D a msg
            }
            else if (codi[2] == 2) {                                  // Verifica se codi[2] = traço
                if (codi[3] == 1 && codi[4] == 0) {msg += "C";}       // Verifica se é ponto e null
                else if (codi[3] == 2 && codi[4] == 0) {msg += "Y";}  // Verifica se é traço e null
                else {msg += "K";}                                    // Se não incrementa K a msg
	        }
            else {msg += "N";}                                        // Se não incrementa N a msg
        }
        else if (codi[1] == 2) {                                      // Verifica se codi[1] = traço
            if (codi[2] == 1) {                                       // Verifica se codi[2] = ponto
                if (codi[3] == 1) {                                   // Verifica se codi[3] = ponto
                    if (codi[4] == 1) {msg += "7";}                   // Verifica se codi[4] = ponto
                    else if (codi[4] == 0) {msg += "Z";}              // Se não incrementa Z a msg
	            }
                else if (codi[3] == 2 && codi[4] == 0) {msg += "Q";}  // Verifica se é traço e null
                else {msg += "G";}                                    // Se não incrementa G a msg
            }
            else if (codi[2] == 2) {                                  // Verifica se codi[2] = traço
                if (codi[3] == 1 && codi[4] == 1) {msg += "8";}       // Verifica se codi[3, 4] = ponto
                else if (codi[3] == 2 && codi[4] == 1) {msg += "9";}  // Verifica se é traço e ponto
                else if (codi[3] == 2 && codi[4] == 2) {msg += "10";} // Verifica se codi[3, 4] = traço
                else if (codi[3] == 0) {msg += "O";}                  // Verifica se codi[3] = null
            }
            else {msg += "M";}                                        // Se não incrementa M a msg
        }
        else {msg += "T";}                                            // Se não incrementa T a msg
    }
}

Vamos dar uma olhada mais de perto no código:

Definições de Pinos

Primeiramente teremos que estar realizar as definições dos pinos que estamos usando em nosso projeto.

//Definições -----------------------------------------------------------------------------------------
#define led 2                                                         // Define LED nova letra
#define led2 3                                                        // Define LED novo comando

Variáveis Globais

Em seguida iremos declarar 5 variáveis globais, sendo elas mili que é responsável por armazenar o tempo, cont e i que são variáveis de controle, também declaramos uma variável do tipo byte com o nome de codi[5] para assim armazenar o código morse do caráter. Por fim uma variável do tipo String com o nome de msg que será responsável em armazenar a mensagem.

//Variáveis Globais ----------------------------------------------------------------------------------
unsigned long mili;                                                   // Armazena Tempo
int cont = 0;                                                         // Variável de controle
byte codi[5] = {};                                                    // Armazena código codificado
String msg;                                                           // Armazena MSG
byte i = 0;                                                           // Variável de controle

Funções Auxiliares

Agora declaramos também uma função auxiliar para que assim possamos dividir nosso código. A função possui o nome de decodifica, ela é responsável por decodificar a mensagem enviada pelo usuário.

//Funções Auxiliares ---------------------------------------------------------------------------------
void decodifica();                                                    // Responsável por Decodificar

Funções Setup

Então vamos para a função setup, onde iremos iniciar a serial com velocidade de 9600. Logo depois configuramos o pino A5 como INPUT_PULLUP e outros dois pinos como OUTPUT sendo eles o LED e o led2.

//Setup ----------------------------------------------------------------------------------------------
void setup() {
    Serial.begin(9600);                                               // Inicializa a Serial
    pinMode(A5, INPUT_PULLUP);                                        // Configura A5 como INPUT_PULLUP
    pinMode(led, OUTPUT);                                             // Configura LED como OUTPUT
    pinMode(led2, OUTPUT);                                            // Configura led2 como OUTPUT
}

Funções Loop

Agora na função loop, será ligado os dois LEDs para indicar que pode ser escrito uma nova letra, após isso lemos o pino A5 e atribuímos a le. Em seguida iremos utilizar a função millis() e atribuímos o retorno a mili.

//Loop -----------------------------------------------------------------------------------------------
void loop() {
    digitalWrite(led, HIGH);                                          // Sinaliza nova letra
    digitalWrite(led2, HIGH);                                         // Sinaliza novo comando
    int le = analogRead(A5);                                          // Atribui a le o valor de A5
    mili = millis();                                                  // Atribui mili o valor de millis

Em seguida criamos um loop até que le seja maior ou igual a 950, dentro do loop desligamos o LED. E Então será verificado se o que retornar da leitura do pino A5 é maior que 950, se for desligamos o led2 e incrementamos +1 a cont. Após isso saímos dessa verificação e realizamos outra verificação se mili mais 2000 (para assim conseguir contar 2 segundos) é menor que millis(), se for realizamos mais três verificações, sendo elas cont maior que 1000, se for atribuímos a codi um traço, se não for verificamos se é diferente de 0, se for atribuímos a codi um ponto. Caso não seja nenhum dos dois chamamos a função decodifica, atribuímos a le 1024 para que assim possamos sair do loop, criamos um for para limpar a variável codi e imprimimos a mensagem.

while (le < 950) {                                                    // Loop até le ser menor que 950
        digitalWrite(led, LOW);                                       // Apaga LED
        if (analogRead(A5) < 950) {                                   // Verifica se A5 é menor que 950
            digitalWrite(led2, LOW);                                  // Apaga led2
            cont++;                                                   // Incrementa +1 a cont
        }
        if (mili + 2000 < millis()) {                                 // Verifica se mili+2000 < millis
            if (cont > 1000) {                                        // Verifica se cont > 1000
                codi[i] = 2;                                          // Atribui a codi[i] o valor 2
                i++;                                                  // Incrementa +1 a i
            }
            else if (cont != 0) {                                     // Verifica se cont != 0
                codi[i] = 1;                                          // Atribui a codi[i] o valor 2
                i++;                                                  // Incrementa +1 a i
            }
            else {
                Serial.println();                                     // Imprime Quebra linha na Serial
                decodifica();                                         // Chama função decodifica()
                le = 1024;                                            // Atribui a le = 1024;
                for (i = 0; i < 5; i++) {                             // Loop de 5 vezes
                  codi[i] = 0;                                        // Atribui a codi[i] o valor de 0
                }
                i = 0;                                                // Atribui a i o valor de 0
                Serial.println(msg);                                  // Imprime mensagem na Serial
            }

Contudo para finalizar o loop dentro da verificação de mili mais 2000 é menor que millis, ligamos o led2 (vermelho), esperamos 0,1 segundo, limpamos a variável cont e atribuímos millis a mili.

            digitalWrite(led2, HIGH);                                 // Sinaliza novo comando
            delay(100);                                               // Espera 0,1s
            cont = 0;                                                 // Atribui a cont o valor de 0
            mili = millis();                                          // Atribui millis a mili
        }
    }
}

Funções descodifica

Por fim na função descodifica, será onde iremos descodificar os códigos, para isso fazemos uma verificação passo a passo seguindo uma estrutura de arvore com o código.

Código Morse Arvore

Agora voltando para o código iremos verificar se o primeiro valor da variável é um ponto ou um traço. Em seguida faremos mesmo passo a passo repetidas vezes até finalizar todas as verificação. Após isso incrementamos com letra correta a variável msg, não irei aprofundar muito, pois é só if e else aninhados seguindo o padrão de arvore com o código morse.

//Decodifica --------------------------------------------------------------------------------------
void decodifica() {
    if (codi[0] == 1) {                                               // Verifica se codi[0] = ponto
        if (codi[1] == 1) {                                           // Verifica se codi[1] = ponto
            if (codi[2] == 1) {                                       // Verifica se codi[2] = ponto
                if (codi[3] == 1) {                                   // Verifica se codi[3] = ponto
                    if (codi[4] == 1) {msg += "5";}                   // Verifica se codi[4] = ponto
                    else if (codi[4] == 2) {msg += "4";}              // Verifica se codi[4] = traço
                    else {msg += "H";}                                // Se não incrementa H a msg
                }
                else if (codi[3] == 2) {                              // Verifica se codi[3] = traço
                    if (codi[4] == 2) {msg += "3";}                   // Verifica se codi[4] = traço
	                else if (codi[4] == 0) {msg += "V";}                // Verifica se codi[4] = null
                }
                else {msg += "S";}                                    // Se não atribui S a msg
            }
            else if (codi[2] == 2) {                                  // Verifica se codi[2] = traço
                if (codi[3] == 1) {msg += "F";}                       // Verifica se codi[3] = ponto
                else if (codi[3] == 2 && codi[4] == 2) {msg += "2";}  // Verifica se codi[3, 4] = traço
                else {msg += "U";}                                    // Se não atribui U a msg
            }
    	    else {msg += "I";}                                          // Se não atribui I a msg
        }
        else if (codi[1] == 2) {                                      // Verifica se codi[1] = traço
            if (codi[2] == 1) {                                       // Verifica se codi[2] = ponto
                if (codi[3] == 1 && codi[4] == 0) {msg += "L";}       // Verifica se é ponto e null
                else if (codi[3] == 0) {msg += "R";}                  // Verifica se codi[3] = null
            } 
            else if (codi[2] == 2) {                                  // Verifica se codi[2] = traço
                if (codi[3] == 1 && codi[4] == 0) {msg += "P";}       // Verifica se é ponto e null
                else if (codi[3] == 2) {                              // Verifica se codi[3] = traço
                    if (codi[4] == 2) {msg += "1";}                   // Verifica se codi[4] = traço
                    else if (codi[4] == 0) {msg += "J";}              // Verifica se codi[4] = null
                }
               else {msg += "W";}                                     // Se não atribui W a msg
            } 
            else {msg += "A";}                                        // Se não atribui A a msg
        }
        else {msg += "E";}                                            // Se não atribui E a msg
    }
    else if (codi[0] == 2) {                                          // Verifica se codi[0] = traço
        if (codi[1] == 1) {                                           // Verifica se codi[1] = ponto
            if (codi[2] == 1) {                                       // Verifica se codi[2] = ponto
                if (codi[3] == 1) {                                   // Verifica se codi[3] = ponto
                    if (codi[4] == 1) {msg += "6";}                   // Verifica se codi[4] = ponto
                    else if (codi[4] == 0) {msg += "B";}              // Verifica se codi[4] = null
                }
                else if (codi[3] == 2 && codi[4] == 0) {msg += "X";}  // Verifica se é traço e null
                else {msg += "D";}                                    // Se não incrementa D a msg
            }
            else if (codi[2] == 2) {                                  // Verifica se codi[2] = traço
                if (codi[3] == 1 && codi[4] == 0) {msg += "C";}       // Verifica se é ponto e null
                else if (codi[3] == 2 && codi[4] == 0) {msg += "Y";}  // Verifica se é traço e null
                else {msg += "K";}                                    // Se não incrementa K a msg
	        }
            else {msg += "N";}                                        // Se não incrementa N a msg
        }
        else if (codi[1] == 2) {                                      // Verifica se codi[1] = traço
            if (codi[2] == 1) {                                       // Verifica se codi[2] = ponto
                if (codi[3] == 1) {                                   // Verifica se codi[3] = ponto
                    if (codi[4] == 1) {msg += "7";}                   // Verifica se codi[4] = ponto
                    else if (codi[4] == 0) {msg += "Z";}              // Se não incrementa Z a msg
	            }
                else if (codi[3] == 2 && codi[4] == 0) {msg += "Q";}  // Verifica se é traço e null
                else {msg += "G";}                                    // Se não incrementa G a msg
            }
            else if (codi[2] == 2) {                                  // Verifica se codi[2] = traço
                if (codi[3] == 1 && codi[4] == 1) {msg += "8";}       // Verifica se codi[3, 4] = ponto
                else if (codi[3] == 2 && codi[4] == 1) {msg += "9";}  // Verifica se é traço e ponto
                else if (codi[3] == 2 && codi[4] == 2) {msg += "10";} // Verifica se codi[3, 4] = traço
                else if (codi[3] == 0) {msg += "O";}                  // Verifica se codi[3] = null
            }
            else {msg += "M";}                                        // Se não incrementa M a msg
        }
        else {msg += "T";}                                            // Se não incrementa T a msg
    }
}

Assim finalizamos todo o código com a explicação sobre o projeto de Código Morse com Arduíno UNO.

Resultado do Projeto Código Morse


Por fim esse foi o resultado obtido com o projeto do Código Morse.

Serial Código Morse
Serial Código Morse

Agradecemos sua Presença


Por fim, espero que tenham gostado e aprendido. Compartilhe com seus colegas e deixe um comentário de qual projeto deveria ser o próximo aqui no Blog da WJ Componentes!!
Enfim estarei deixando o arquivo Arduíno e Fritzing, link dos posts anteriores referentes ao projeto e software e sites utilizados.
Fique à vontade para tirar suas dúvidas nos comentários.

Software e Sites Utilizados

Post Relacionados

Posts mais Recentes

Julio Cesar Bonow Manoel

Julio Cesar Bonow Manoel

Cursando Engenharia da Computação pelo Centro Universitário Facens e atua no desenvolvimento de projetos na WJ Componentes. Participante da equipe de robótica Omegabotz.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *