Relembrando
No início do nosso curso comentamos que o framework Arduino é baseado em C++ e uma das características que diferenciava o C++ do C era ser uma linguagem que utilizava o paradigma da Programação Orientada a Objetos. Lembra?
Nas noções de POO que vimos no curso de C++ tínhamos o conceito de classes e objetos que eram abstrações do mundo real, isto é, elementos do mundo real eram representados como classes e objetos nos programas.
As classes eram como modelos a partir dos quais instanciávamos objetos que possuíam atributos e métodos. Os atributos eram as características da classe e os métodos seus comportamentos. Isso tudo é para relembrá-lo de conceitos que hoje vamos por em prática no Arduino.
Programação Estruturada vs POO
Até agora vimos toda a resolução dos nossos projetos utilizando o paradigma da Programação Estruturada onde o fluxo dos dados seguem um sentido, sendo executado linha por linha e tendo, eventualmente, esse fluxo sendo alterado por um laço ou por uma instrução de controle como if.
Pensar em uma lógica linear como essa é fácil e se adequa muito bem a problemas simples dos sistemas embarcados, mas eventualmente podem não ser o melhor caminho em questões mais complexas. Para esses casos existe a POO.
Migrar para uma lógica POO quando nos habituamos a resolver tudo com programação estruturada pode não ser fácil e deve ser praticada no começo com questões simples até se tornar algo cristalizado no raciocínio do estudante. Por isso vamos começar com um exemplo simples com leds.
Se você não lembra direito desses conceitos, recomendo rever as seguintes aulas do curso anterior antes de seguir adiante. Isso vai te ajudar a compreender o nosso Sketch:
Pensando no Led como uma Classe
Eu posso representar qualquer componente eletrônico como uma classe na POO, mas ela fica mais vantajosa quando esse componente é muito utilizado em um projeto. Nos nossos projetos do curso utilizamos muitos leds, assim o trabalho que eu tiver para criar uma classe led será recompensado pelo seu muito uso.
E o que eu preciso para utilizar um led? Basicamente eu preciso estabelecer um pino para ele. Apesar desse pino poder ser digital ou pwm, na maioria das vezes eu trabalho com leds em pinos digitais e um bom caminho para criar uma classe para um componente é generalizar o seu uso. Sendo assim eu vou criar uma classe led para usar um pino digital.
Como eu definia o pino para o led? Eu criava uma variável para ele, correto? Nós já vimos no curso de C++ que variáveis em uma classe eram chamadas de atributos da classe e se você pensar bem, o pino é um atributo do led, pois é uma característica que o diferencia de outros leds.
O led como Classe teria outro atributo? Você poderia dizer que a cor é um atributo do led e não estaria errado, mas nos leds comuns a cor é algo físico que eu não altero por código. Sendo assim, por enquanto nosso led tem apenas o atributo pino. Então temos:
class Led {private:int pino;};
Devemos lembrar que além dos atributos da classe vimos em C++ que haviam os métodos. Um era usado para construir a classe e se os atributos estivessem protegidos, precisávamos de setters e getters para acessar os seus membros. Está lembrado? Logo:
//construtorLed(int pino) {Pino(pino);}//setter para setar o pinovoid Pino(int pino){this->pino = pino;pinMode(pino, OUTPUT);}
Métodos são comportamentos, mas o led pode ter diferentes comportamentos? Sim. Um led conectado a um pino digital pode estar aceso ou apagado, correto? Os comportamentos de uma classe eram definidos por métodos da classe que eram funções criadas dentro dela. Sendo assim eu vou precisar de um método para acender o led e outro para apagá-lo:
//método para acendervoid acende() {digitalWrite(pino, HIGH);}//método para apagarvoid apaga() {digitalWrite(pino, LOW);}
Agora que relembramos esses conceitos e os abstraímos para o problema da manipulação dos leds, vamos por a mão na massa com um projeto.
Montagem
Como eu falei antes, quanto mais leds no projeto melhor, então traga para o Wokwi o projeto dos dois semáforos de carros ou abra o link do nosso projeto abaixo para ganhar tempo. Depois salve uma cópia do projeto com o nome Framework Arduino Básico Aula 09: POO 1
Link: https://wokwi.com/projects/412094021094529025
![]() |
Montagem anterior que será reutilizada |
O Sketch
Você pode copiar e colar o Sketch abaixo na sua montagem ou ir direto para o nosso projeto pelo link que está logo abaixo:
- class Led {
- private:
- int pino;
- public:
- Led(int pino) {
- Pino(pino);
- }
- void Pino(int pino){
- this->pino = pino;
- pinMode(pino, OUTPUT);
- }
- void acende() {
- digitalWrite(pino, HIGH);
- }
- void apaga() {
- digitalWrite(pino, LOW);
- }
- };
- Led vermelho(13);
- Led amarelo(12);
- Led verde(11);
- Led vermelho2(10);
- Led amarelo2(9);
- Led verde2(8);
- void setup() {
- }
- void loop() {
- vermelho.apaga();
- amarelo.apaga();
- verde.acende();
- vermelho2.acende();
- amarelo2.apaga();
- verde2.apaga();
- delay(4000);
- amarelo.acende();
- verde.apaga();
- delay(2000);
- verde2.acende();
- vermelho2.apaga();
- vermelho.acende();
- amarelo.apaga();
- delay(4000);
- amarelo2.acende();
- verde2.apaga();
- delay(2000);
- }
Das linhas de 1 a 18 tenho a criação da classe Led que estou colocando na mesma tela de Sketch para não criar um arquivo externo de biblioteca e complicar ainda mais a explicação. Veja que na linha 2 e 3 eu encapsulei o atributo pino com private. Sendo assim, vou precisar de Setters e Getters para acessá-lo.
Da linha 5 a 7 eu criei um método construtor Led que será usado para instanciar os futuros objetos leds que serão os leds vermelho, amarelo, verde. Esse construtor está utilizando um Setter chamado Pino() definido das linhas 8 a 11 que acessa o atributo pino de cada objeto a ser criado e o define como saída. Veja que está sendo utilizado um ponteiro para se referir ao pino.
Das linhas 12 a 17 eu tenho dois métodos: acende() e apaga() que poderiam ser apenas um método setter para ajustar o estado do pino como HIGH ou LOW, mas eu preferi criar dois métodos com nomes bem explicativos para facilitar o uso da classe.
Saindo das chaves da classe Led {}, eu tenho da linha 20 a 25 o instanciamento dos objetos leds utilizando essa classe. Veja que o pino é passado como parâmetro e dentro da classe acaba indo para o método Pino() onde vai se estabelecer um ponteiro. É esse ponteiro que permite que os métodos acende() e apaga() funcionem, pois eles se referem também ao pino.
Veja que esse instanciamento é feito fora da função setup() porque se fizermos dentro dela, os objetos passam a ser internos dessa função, não sendo enxergados ou alcançados pela função loop(). Por isso setup acaba ficando vazia.
Depois temos finalmente a função loop() com praticamente a mesma lógica usada no programa original, porém com os métodos de acender e apagar o led sendo utilizados.
Poderíamos ter colocado mais elementos nessa classe, mas a ideia era simplificar para que esses conceitos ficassem claros e na aula que vem daremos mais um exemplo um pouco mais aprofundado.
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.