sexta-feira, 29 de junho de 2018

Arduino - #05 Introdução à Programação (Estruturas de Controle - Parte 2)

Estruturas de controlo de fluxo e tomada de decisão

No seguimento da ultima publicação iremos hoje continuar a falar das estruturas de controlo de fluxo e tomada de decisão.
Estes são conceitos de grande importância no mundo da programação, não só do Arduino mas de todos os sistemas e softwares.



A execução normal dos comandos do código de um programa é executados uns depois do outros de cima para baixo na mesma sequência em que foram escritos. Isto é chamado de execução sequencial.

No entanto nas linguagens de programação existem vários comandos que permitem alterar a ordem de execução do código, este permitem ao programador indicar qual o próximo comando a ser executado que pode ser outro que não o próximo da sequência.

Para tal recorremos as estruturas de controlo que são blocos de instruções que alteram o fluxo de execução do código de um programa. Sendo possível executar comandos diferentes de acordo com uma determinada condição ou repetir uma série de comandos várias vezes, por exemplo.

Nesta segunda e ultima parte do estudo das estruturas de controlo, iremos falar das estruturas de tomada de decisão mais comuns usadas nas linguagens de programação em geral. Iremos ainda alterar o nosso programa de teste para demonstrar na prática cada um destas para entendermos melhor o seu funcionamento.

Estruturas de Controlo:


Parte 2 - Tomada de decisão


If


O If é uma das estruturas mais básicas da programação em geral. If é uma expressão inglesa que significa "se", e é exatamente isso que esta faz, esta verifica uma expressão e, apenas se esta expresão for verdadeira, executa um conjunto de comandos. Em linguagem natural, ele executa uma lógica do tipo "se isso for verdadeiro, então faça aquilo".


Declara-se da seguinte forma:

   if(condição) 
   { 
         ...
   } 


A lógica deste é muito simples, sempre que a condição for verdadeira, os comandos entre chavetas serão executados, caso contrário o programa prossegue sem executar os mesmos.  
Para demonstrarmos o seu funcionamento vamos, modificar o nosso programa de exemplo o programa Blink para que ele faça piscar o LED 3 vezes seguido de uma pausa de 5 segundo tal como na última publicação onde para tal recorremos ao While e ao For, porém agora vamos recorrer ao comando If.

Iremos então alterar o código da função loop() para o seguinte código:

   // Variável para contar o número de vezes que o LED piscou 
   int i = 0; 

   void loop() 

   { 
        digitalWrite(led, HIGH); // Atribui nível lógico alto ao pino do LED, ligado
        delay(1000); // Espera 1000 milissegundos (um segundo)
        digitalWrite(led, LOW); // Atribui nível lógico baixo ao pino do LED, desligado
        delay(1000); // Espera 1000 milissegundos (um segundo)
        i++; // Incrementa o número de vezes que o LED piscou

        if(i == 3)

        { 
             delay(5000); // Espera 5 segundos para piscar o LED de novo
             i = 0; // Reinicia o contador do número de vezes que o LED piscou
        } 
   }

Sendo que a lógica nesta é um pouco diferente do que vimos com os comandos While e For, pois aqui iremos manter a função loop() a piscar o LED como no programa original, porém vamos inserir uma espera adicional de 5 segundos após o LED piscar 3 vezes. Para isso, criamos uma variável i fora da função loop(), sendo que esta tem de ser declarada fora da função para poder manter o seu valor entre cada execução da função loop(). Chamando a este tipo de variáveis, variáveis globais. Quando a variável é declarada dentro do corpo da função, ela não retém o valor entre cada execução, sendo reiniciada cada vez que a função é re-executada. Chamando a este tipo de variáveis, variáveis locais.

A variável global i é utilizada para contar o número de vezes que o LED acendeu e apagou. Na declaração da variável, esta é inicializada com o valor 0 para indicar que o LED ainda não piscou nenhuma vez. Durante a execução da função loop() o LED acende e apaga e por cada vez que isto se verifica a variável i é incrementada de uma unidade recorrendo ao código “i++”.

Em seguida através do comando If verifica-se o valor da variável i, sendo este menor que 3 a execução continua sem executar os códigos dentro das chavetas. Para isso, usamos a expressão i == 3 na condição do if. Se essa expressão for verdadeira, tendo o LED já piscado 3 vezes, ao se verificar i igual a 3 o código entre chavetas é executado sendo assim feita a pausa de 5 segundos com a chamada do comando “delay(5000)” e reiniciamos a variável i a 0 mais uma vez para se voltar a iniciar o ciclo.

A partir daqui a função loop() continua a ser chamada e o ciclo vai-se inicia novamente.

If-Else


O if-else, também conhecido como “if-then-else”, pode ser visto como uma extensão do comando if. A expressão Else em inglês significa "caso contrário", e esta faz exatamente o que o seu significado diz "se isto for verdadeiro, então faça aquilo, caso contrário, faça outra coisa".

Declara-se da seguinte forma:

   if(condição) 
   { 
         ...
   } 
   else
   { 
         ...
    }

Para demostrarmos esta estrutura vamos usar o programa de teste Blink que foi alterado para a estrutura For na última publicação desta rubrica, sendo que desta vez vamos fazer o LED piscar quatro vezes em vez de três vezes antes de se fazer a pausa de cinco segundos. Em seguida iremos fazer com que na terceira de cada uma dessas quatro vezes que o LED piscar este vai acender por um período de tempo mais curto. 

Iremos então alterar o código da função loop() para o seguinte código:

   // Variável para contar o número de vezes que o LED pisca
   int i;

   loop()
   {
         // Pisca o LED três vezes
         for(i = 0; i < 3; i++)
         {

              if(i == 2)
              {
                  digitalWrite(led, HIGH); // Atribui nível lógico alto ao pino do LED, LED ON
                  delay(500); // Espera 500milissegundos (meio segundo)
                  digitalWrite(led, LOW); // Atribui nível lógico baixo ao pino do LED, LED OFF
                  delay(2000); // Espera 2000 milissegundos (dois segundos)
               }
               else
               {
                   digitalWrite(led, HIGH); // Atribui nível lógico alto ao pino do LED,  LED ON
                   delay(1000); // Espera 1000 milissegundos (um segundo)
                   digitalWrite(led, LOW); // Atribui nível lógico baixo ao pino do LED, LED OFF
                   delay(1000); // Espera 1000 milissegundos (um segundo)
              }
        }

       delay(5000); // Espera 5 segundos para piscar novamento o LED
    }

Neste caso sempre que o LED acender, verificar se é a terceira vez que isso acontece, por meio do comando if com a condição i == 2. Se essa expressão for verdadeira, significa que o LED já piscou 2 vezes estando preste a piscar pela terceira vez.

Nesse caso altera-se o tempo que o LED fica aceso para um valor menor, de 0,5 segundos e o tempo que ele fica apagado para um valor maior, de 2 segundos.

No entanto se esta não for a terceira vez que o LED pisca? É neste caso que entra o else se a condição do if for verdadeira, o bloco de comandos entre chavetas logo após o if é executado, caso contrário, o bloco entre chavetas após o else é executado. Isso quer dizer que no nosso exemplo o LED vai piscar com tempos de 1 segundo para a primeira, segunda e quarta vez, sendo os tempos diferentes apenas quando este pisca pela terceira vez.

switch


O switch é uma estrutura de tomada de decisão que avalia o valor de uma variável de controlo e direciona o código para um caso específico. 

Declara-se da seguinte forma:

   Switch(variável) 
   {
        case 1:
        breack; 

        case 2:
        breack; 

       default: 
   }

Na estrutura que mostramos acima, a variável é que controla a tomada de decisão. Se o valor desta for igual a 1, o código vai para linha Case 1. Se desta for igual a 2, Case 1 é ignorado e o código executado é o que se segue em Case 2. O número de casos é indefinido, mas recomenda-se que não seja mais de uma dezena e não menos que três.

Na eventualidade de não existir nenhum Case correspondente ao valor da variável de controlo, o código executado é o Default, geralmente escrito ao final do Switch.

Os breaks no meio do Switch servem para informar o compilador para sair do switch, continuando o código que vem logo abaixo do feche das chavetas que delimitam o Switch.  São colocados depois de cada Case para evitar que sejam feitas avaliações desnecessárias.

   // Variável para contar o número de vezes que o LED piscou
   int i=1;
   loop()
   {
        switch (i)
        {
             case(1):
             {
                digitalWrite(led, HIGH); // Atribui nível lógico alto ao pino do LED, LED ON
                delay(1000); // Espera 1000 milissegundos (um segundo)
                digitalWrite(led, LOW); // Atribui nível lógico baixo ao pino do LED, LED OFF 
                delay(1000); // Espera 1000 milissegundos (um segundo)
              }
             breack;

             case(2):
             {
               digitalWrite(led, HIGH); // Atribui nível lógico alto ao pino do LED, LED ON
               delay(1000); // Espera 1000 milissegundos (um segundo)
               digitalWrite(led, LOW); // Atribui nível lógico baixo ao pino do LED, LED OFF 
               delay(1000); // Espera 1000 milissegundos (um segundo)
             }
            breack;

            case(3):
            {
               digitalWrite(led, HIGH); // Atribui nível lógico alto ao pino do LED, LED ON
               delay(500); // Espera 500 milissegundos (meio segundo)
               digitalWrite(led, LOW); // Atribui nível lógico baixo ao pino do LED, LED OFF
               delay(2000); // Espera 2000 milissegundos (dois segundo)
           }
           breack; 

           case(4):
           {
               digitalWrite(led, HIGH); // Atribui nível lógico alto ao pino do LED, LED ON
               delay(1000); // Espera 1000 milissegundos (um segundo)
               digitalWrite(led, LOW); // Atribui nível lógico baixo ao pino do LED, LED OFF 
               delay(1000); // Espera 1000 milissegundos (um segundo)
            }
            breack;

            default:
            {
                 delay(5000); // Espera 5 segundos para piscar o LED de novo
                 i=1;
            }

            i++;
           
       }
   }

Neste exemplo o led pisca enquanto o valor de “i” for maior que 1 e igual a 4, sendo que quando o valor de “i” for igual a 5 a variável “i” o recolocada a 1 e faz-se uma pausa de 5 segundos.


Considerações Finais

As estruturas de controlo são peças fundamentais na elaboração de qualquer programa, pois embora a função loop possa fazer o nosso código ser executado de forma cíclica esta não chega para colmatar todas as necessidades ao longo da elaboração dos projetos mais ou menos complexos.
Como podemos constatar a estrutura de Tomada de decisão if, if-else e switch são estruturas básicas que nos permitem controlar facilmente a execução do código.
Estas são três estruturas de grande importância no mundo da programação.



Esperamos que este artigo tenha sido útil e se gostaram comentem e partilhem. Alguma dúvida ou questão deixem em comentário ou utilizem o formulário de contatos.


Um bom dia em nome da TecnoDomos.




Conteúdo redigido ao abrigo do novo Acordo Ortográfica

Sem comentários:

Enviar um comentário