Framework Arduino Básico Aula 11: POO III

 Imagem meramente ilustrativa

Adaptando uma Classe a novas situações

    Já vimos exemplos simples para criação de classes com Leds e Botões. Um dos conselhos que passei era que você tentasse generalizar o funcionamento da classe para facilitar a sua criação. Porém, teremos situações onde precisaremos incorporar a classe elementos que desafiam a definição de um construtor.

    Para ilustrar melhor vamos carregar um outro projeto de piano com mais botões para você entender do que estou falando. Peço que abra o link abaixo e salve uma cópia com o nome de Framework Arduino Básico Aula 11: Piano PE com sustenidos.

    Link: https://wokwi.com/projects/412310757498017793

    Esse projeto é bem semelhante ao piano básico da aula passada feito com programação estruturada, mas como possui mais botões, foi necessário utilizar um pino analógico do Arduino. Olhando pra ele você deve estar se perguntando, mas porque ele usou o analógico sendo que os pinos digitais 1 e 0 ainda estavam disponíveis?

    Se você reparou nisso deve ter reparado também que esses pinos possuem em sua descrição as siglas RX e TX, podendo ser utilizados para comunicação serial entre dispositivos. Sendo assim, é mais conveniente utilizá-los para esse propósito do que como entradas digitais, já que ainda temos entradas analógicas disponíveis.

    Esse piano tem botões brancos para as notas naturais (do, ré, mi, fá, sol, lá e si) e botões pretos para as notas em sustenido, isto é, que possuem uma frequência meio tom acima das notas naturais. Assim como fizemos na aula passada, também configuramos as teclas de atalho ALT + Z, X, C, V, B, N e M para as notas naturais e agora ALT+S, D, G, H e J para os sustenidos.

    Na aula passada também comentei que o atributo estado utilizado para um botão, poderia ser uma variável inteiro ou booleana, está lembrado? Nesse Sketch você verá que fica mais fácil trabalhar com ela como inteiro, já que as entradas analógicas foram utilizadas. Vamos ao Sketch.

Vendo o Sketch do piano em programação estruturada

   Em relação ao piano de programação estruturada da aula passada, a novidade aqui é o processo de leitura do botão A0 que exige um analogRead() no lugar do digitalRead() utilizado nos demais botões, além disso ele varia de 0 a 1023.

    Sendo assim eu não testo ele para ver se é igual a 1 como os demais. Eu testo para ver se ele é diferente de zero. Outra coisa, por ser necessariamente uma entrada, não há configuração como INPUT como nos pinos digitais. Isso tudo vai gerar alguns desafios na hora de transformá-lo em POO.

Veja como fica o Sketch e teste a simulação:

  1. #define  Do  261
  2. #define  Do_  277
  3. #define  Re  293
  4. #define  Re_  311
  5. #define  Mi  329
  6. #define  Fa  349
  7. #define  Fa_  369
  8. #define  Sol  391
  9. #define  Sol_  415
  10. #define  La  440
  11. #define  La_  466
  12. #define  Si  493

  13. void setup() {
  14.   pinMode(2, OUTPUT);
  15.   pinMode(3, INPUT);
  16.   pinMode(4, INPUT);
  17.   pinMode(5, INPUT);
  18.   pinMode(6, INPUT);
  19.   pinMode(7, INPUT);
  20.   pinMode(8, INPUT);
  21.   pinMode(9, INPUT);
  22.   pinMode(10, INPUT);
  23.   pinMode(11, INPUT);
  24.   pinMode(12, INPUT);
  25.   pinMode(13, INPUT); 
  26. }

  27. void loop() {
  28.   if (digitalRead(13)==HIGH){
  29.     tone(2,Do,100);  
  30.   }
  31.   if (digitalRead(12)==HIGH){
  32.     tone(2,Do_,100);    
  33.   }
  34.   if (digitalRead(11)==HIGH){
  35.     tone(2,Re,100);    
  36.   }
  37.   if (digitalRead(10)==HIGH){
  38.     tone(2,Re_,100);    
  39.   }
  40.   if (digitalRead(9)==HIGH){
  41.     tone(2,Mi,100);    
  42.   }
  43.   if (digitalRead(8)==HIGH){
  44.     tone(2,Fa,100);    
  45.   }
  46.   if (digitalRead(7)==HIGH){
  47.     tone(2,Fa_,100);    
  48.   }
  49.   if (digitalRead(6)==HIGH){
  50.     tone(2,Sol,100);    
  51.   }
  52.   if (digitalRead(5)==HIGH){
  53.     tone(2,Sol_,100);    
  54.   }
  55.   if (digitalRead(4)==HIGH){
  56.     tone(2,La,100);    
  57.   }
  58.   if (digitalRead(3)==HIGH){
  59.     tone(2,La_,100);    
  60.   }
  61.   if (analogRead(14)!=0){
  62.     tone(2,Si,100);    
  63.   }
  64. delay(100);
  65. noTone(2);
  66. }
 Quais a mudanças serão necessárias na classe?

    Examine a classe Botão usada na aula passada:

class Botao {
      //atributos
    private:
      int pino;
      int estado;
    public:
      //construtor 
      Botao(int pino) {
        setPino(pino);
      }
      //setter
      void setPino(int pino){
        this->pino = pino;
        pinMode(pino, INPUT);
      }
       //getter
      int getPino(int pino){
        this->estado=estado;
        estado=digitalRead(pino);
        return estado;
      }
};


    Repare que seu construtor utiliza um setter chamado setPino() que configura pino digital como entrada, mas agora eu tenho que adaptá-lo ao pino A0 que não precisa disso. Da mesma forma o seu getter chamado getPino() utiliza o digitalRead() e eu preciso também do analogRead(). E agora?

    A solução para o setter é simples, basta colocar um bloco if para executar uma instrução somente se o pino for digital, isto é, o pino for menor ou igual a 13. No caso do getter teremos o mesmo raciocínio só que além do if teremos um else para uma segunda instrução. Veja como ficaria a classe:

class Botao {
    private:
      int pino;
      int estado;
    public:
      Botao(int pino) {
        setPino(pino);
      }
      void setPino(int pino){
        this->pino = pino;
        if (pino<=13){
          pinMode(pino, INPUT);
        }
      }
      int getPino() {
        this->estado=estado;
        if (pino<=13){
          estado=digitalRead(pino);
        }
        else{
          estado=analogRead(pino);
        }
        return estado;
      }
};

    Vamos aproveitar que essa aula está bem fácil e relembrar o conceito de biblioteca visto nos cursos de C e C++ que era quando eu criava um arquivo externo ao código e incluía ele no programa principal. No caso vou colocar nesse arquivo a minha classe.

    Aqui no Wokwi quando eu quero um arquivo externo eu clico no botão de seta do lado direito da opção de menu LIBRARY MANAGER e clico em NEW FILE. Eu posso digitar como nome do novo arquivo biblioteca.hpp, já que ele vai armazenar classes é um arquivo de cabeçalho em C++.

    Alguns autores prefererem chamar esse arquivo de pacote ou de coleção já que armazena classes. É nesse arquivo que vou colocar esse código acima.

Tela de criação de novo arquivo no Wokwi
Tela de criação de novo arquivo no Wokwi

Dando um nome para o arquivo
Dando um nome para o arquivo

Tela mostrando o arquivo criado no menu superior
Tela mostrando o arquivo criado no menu superior

O Sketch em POO

    Depois dessas explicações segue abaixo o Sketch do piano modificado para POO, mas sugiro que você abra o link de projeto que estou disponibilizando abaixo dele, porque nele eu já criei um novo arquivo de biblioteca conforme mostrei acima. Sendo assim o Sketch precisa ter um #include "biblioteca.hpp" no seu início.

  1. #include "biblioteca.hpp"
  2. #define  Do  261
  3. #define  Do_  277
  4. #define  Re  293
  5. #define  Re_  311
  6. #define  Mi  329
  7. #define  Fa  349
  8. #define  Fa_  369
  9. #define  Sol  391
  10. #define  Sol_  415
  11. #define  La  440
  12. #define  La_  466
  13. #define  Si  493

  14. Botao Botao14(14);
  15. Botao Botao3(3);
  16. Botao Botao4(4);
  17. Botao Botao5(5);
  18. Botao Botao6(6);
  19. Botao Botao7(7);
  20. Botao Botao8(8);
  21. Botao Botao9(9);
  22. Botao Botao10(10);
  23. Botao Botao11(11);
  24. Botao Botao12(12);
  25. Botao Botao13(13);

  26. void setup() {
  27.   pinMode(2, OUTPUT);
  28. }

  29. void loop() {
  30.   if (Botao13.getPino()==1){
  31.     tone(2,Do,100);  
  32.   }
  33.   if (Botao12.getPino()==1){
  34.     tone(2,Do_,100);    
  35.   }
  36.   if (Botao11.getPino()==1){
  37.     tone(2,Re,100);    
  38.   }
  39.   if (Botao10.getPino()==1){
  40.     tone(2,Re_,100);    
  41.   }
  42.   if (Botao9.getPino()==1){
  43.     tone(2,Mi,100);    
  44.   }
  45.   if (Botao8.getPino()==1){
  46.     tone(2,Fa,100);    
  47.   }
  48.   if (Botao7.getPino()==1){
  49.     tone(2,Fa_,100);    
  50.   }
  51.   if (Botao6.getPino()==1){
  52.     tone(2,Sol,100);    
  53.   }
  54.   if (Botao5.getPino()==1){
  55.     tone(2,Sol_,100);    
  56.   }
  57.   if (Botao4.getPino()==1){
  58.     tone(2,La,100);    
  59.   }
  60.   if (Botao3.getPino()==1){
  61.     tone(2,La_,100);    
  62.   }
  63.   if (Botao14.getPino()!=0){
  64.     tone(2,Si,100);    
  65.   }
  66. delay(100);
  67. noTone(2);
  68. }

    Link: https://wokwi.com/projects/412579536490835969

     Com isso eu encerro esse Minicurso básico de Framework Arduino e começo um novo minicurso para explorar sensores e componentes importantes para o estudante de Sistemas Embarcados. Vou utilizar ainda a Framework Arduino porque ela facilita esse aprendizado.

    No entanto o estudante tem que ter em mente que projetos profissionais não são feitos nessa framework, mas isso é assunto para uma outra etapa desse site que será iniciada em Janeiro de 2026.


Próxima Aula                                                                                                                        Aula Anterior

Referências

ARDUINO DOCS. Arduino Documentation. Disponível em: <https://docs.arduino.cc/> Acesso em 05 ago. 2024.

OLIVEIRA, Cláudio Luis Vieira et al. Aprenda Arduino: Uma abordagem prática. Duque de Caixas: Katzen Editora, 2018. 181p. Disponível em: <https://www.fatecjd.edu.br/fatecino/material/ebook-aprenda-arduino.pdf> Acesso em 05 ago. 2024.

OLIVEIRA, Cláudio Luis Vieira. Arduino Descomplicado - Como Elaborar Projetos de Eletrônica. São Paulo: Editora Érica, 2015. 287p. 

TINKERCAD. Centro de Aprendizagem. Disponível em: <https://www.tinkercad.com/learn> Acesso em 05 ago. 2024.

WOKWI. Referência do wokwi-arduino-uno. Disponível em: <https://docs.arduino.cc/> Acesso em 05 ago. 2024.