Você está na página 1de 163

Lógica e Programação

para grandes e pequenos

{ Alan, Cauan, Luan } Marotta

CEFETMG - Campus V Divinópolis

MECATRÔNICA

Fevereiro 2024.
Sumário

1 Apresentação 1
1.1 Introdução aos Sistemas Computacionais . . . . . . . . . . . 4
1.1.1 O Computador . . . . . . . . . . . . . . . . . . . . . 5
1.1.2 O microcontrolador . . . . . . . . . . . . . . . . . . . 5

2 Plataforma Arduino 7
2.1 Programação alto e baixo nível . . . . . . . . . . . . . . . . . 9
2.2 Interface de Desenvolvimento . . . . . . . . . . . . . . . . . 11
2.3 Como Carregar um Exemplo . . . . . . . . . . . . . . . . . . 12
2.4 Como configurar o Arduino . . . . . . . . . . . . . . . . . . . 14

3 Entendendo um programa básico 17


3.1 Analisando o programa blink . . . . . . . . . . . . . . . . . . 19
3.1.1 pinMode . . . . . . . . . . . . . . . . . . . . . . . . 20
3.1.2 digitalWrite . . . . . . . . . . . . . . . . . . . . . . . 21
3.1.3 delay . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.1.4 Interpretando o Blink.ino . . . . . . . . . . . . . . . . 22
3.2 Erros comuns ao compilar . . . . . . . . . . . . . . . . . . . 25
3.3 Atividades . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.3.1 Desafio . . . . . . . . . . . . . . . . . . . . . . . . . 26

4 Saídas Digitais 27
4.1 Indicadores luminosos - LEDs . . . . . . . . . . . . . . . . . 27
4.1.1 Atividades . . . . . . . . . . . . . . . . . . . . . . . 32
4.1.2 Desafio . . . . . . . . . . . . . . . . . . . . . . . . . 34

5 Saída sonora 37
5.1 Exemplo alarme . . . . . . . . . . . . . . . . . . . . . . . . . 38
5.2 Atividades . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

i
6 Saída pela porta de comunicação serial 41
6.1 Exemplo Serial OI . . . . . . . . . . . . . . . . . . . . . . . 42
6.2 Exemplo Serial Oi Mais . . . . . . . . . . . . . . . . . . . . . 43
6.3 Atividades . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

7 Identificadores - palavras reservadas, constantes, variáveis, co-


mandos e demais estruturas 45
7.1 Identificadores válidos e inválidos . . . . . . . . . . . . . . . 46
7.1.1 Exemplos de identificadores válidos . . . . . . . . . . 47
7.1.2 Exemplos de identificadores inválidos . . . . . . . . . 48
7.1.3 Exercícios Identificadores . . . . . . . . . . . . . . . 48
7.2 Constantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
7.2.1 Constantes - define . . . . . . . . . . . . . . . . . 49
7.2.2 Constantes com tipo - const . . . . . . . . . . . . . 49
7.2.3 Exercícios - Constantes . . . . . . . . . . . . . . . . . 49
7.3 Variáveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
7.3.1 Exemplo Contador . . . . . . . . . . . . . . . . . . . 50
7.3.2 Tipos de Variáveis . . . . . . . . . . . . . . . . . . . 51
7.3.3 Exercícios Variáveis . . . . . . . . . . . . . . . . . . 51
7.4 Comandos, procedimentos e funções . . . . . . . . . . . . . . 52

8 Operadores 55
8.1 Operadores matemáticos . . . . . . . . . . . . . . . . . . . . 56
8.2 Operadores relacionais . . . . . . . . . . . . . . . . . . . . . 56
8.3 Operadores lógicos . . . . . . . . . . . . . . . . . . . . . . . 57

9 Estrutura Condicional 59
9.1 Estrutura condicional simples . . . . . . . . . . . . . . . . . . 59
9.2 Estrutura condicional composta . . . . . . . . . . . . . . . . . 62
9.3 Estrutura condicional encadeada . . . . . . . . . . . . . . . . 64
9.4 Estrutura condicional encadeada com senão . . . . . . . . . . 67
9.5 Estrutura condicional de seleção . . . . . . . . . . . . . . . . 69

10 Entrada Digital Básica 73


10.1 Exercícios com botões . . . . . . . . . . . . . . . . . . . . . 77

11 Entrada pela porta de comunicação serial 79


12 Bibliotecas, classes e objetos 83
12.1 Incluindo uma biblioteca . . . . . . . . . . . . . . . . . . . . 83
12.2 Biblioteca softwareSerial . . . . . . . . . . . . . . . . 84
12.2.1 Controle remoto por cabo cruzado . . . . . . . . . . . 84
12.2.2 Comunicação por BlueTooth com celular . . . . . . . 87
12.3 Biblioteca keyboardPS2 . . . . . . . . . . . . . . . . . . . 90
12.3.1 Teclado Musical . . . . . . . . . . . . . . . . . . . . 92
12.4 Sensor de Distância HC-SR04 - biblioteca ultraSonic . . 95

13 Estruturas de Repetição 97
13.1 Repetição com teste no início . . . . . . . . . . . . . . . . . . 97
13.2 Repetição com teste no final . . . . . . . . . . . . . . . . . . 99
13.3 Repetição com variável de controle . . . . . . . . . . . . . . . 100
13.3.1 Exemplo barulho crescente . . . . . . . . . . . . . . . 102

14 Conjuntos - variáveis indexadas 103


14.1 Implementação de vetores . . . . . . . . . . . . . . . . . . . 104

15 Geração de Números Aleatórios 107


15.1 Dado eletrônico . . . . . . . . . . . . . . . . . . . . . . . . . 107
15.2 Bingo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108

16 Jogo Genius - Memória de Gênio 111

17 Memória não volátil 119


17.1 Escrita na Memória EEPROM . . . . . . . . . . . . . . . . . 119
17.2 Leitura da Memória EEPROM . . . . . . . . . . . . . . . . . 120
17.3 Exemplo Escrita e Leitura da Memória EEPROM . . . . . . . 121

18 Contagem de tempo sem atraso 123


18.1 Piscada sem delay . . . . . . . . . . . . . . . . . . . . . . . . 123
18.2 Latência e Serial simultâneo . . . . . . . . . . . . . . . . . . 125
18.3 Técnica antiruído Debboucing . . . . . . . . . . . . . . . . . 125

19 Saída Analógica por PWM 129


19.1 Programa chama da vela . . . . . . . . . . . . . . . . . . . . 131
19.2 Servo motor robótico . . . . . . . . . . . . . . . . . . . . . . 132
20 Entrada Analógica 137
20.1 Leitura Analógica para Porta Serial . . . . . . . . . . . . . . . 140
20.2 Controlando a intensidade de um LED com o potenciometro . 141
20.3 Controlando o servo motor com o potenciometro . . . . . . . 142
20.4 Sensor de luz . . . . . . . . . . . . . . . . . . . . . . . . . . 144
20.5 Sensor de temperatura . . . . . . . . . . . . . . . . . . . . . . 145

APÊNDICE 147

A Como Baixar e Instalar a Interface Arduino 149

Lista de Figuras 158


Capítulo 1

Apresentação

Este material tem por objetivo introduzir o leitor ao mundo da


programação embarcada, base para desenvolvimento de projetos
de robótica, de forma objetiva e direta. O material fornecido
permite a execução de programas a partir de exemplos. O enten-
dimento do funcionamento permitirá modificar os programas e
criar novas aplicações conforme novas necessidades.
O objetivo é aprender a programar elementos conectados ao
sistema microprocessado, através da plataforma Arduino (versão
Nano) utilizando o módulo GeniusINO, ao qual já estão ligados
indicadores luminosos (LEDs), teclas de toque e um emissor so-
noro.
Primeiramente é importante entender como os sistemas com-
putacionais funcionam e como podemos implementar programas
dedicados a fim de que executem tarefas de nosso interesse.

1
CAPÍTULO 1. APRESENTAÇÃO 2

Figura 1.1: Esquerda: placa Genius.ino com Arduino Nano. Direita: Dia-
grama com os elementos da placa Genius

Alguns dos principais projetos discutidos e implementados:


• Jogo da memória Genius
• Controle de servomotor robótico
• Músicas robóticas
• Monitoramento da temperatura com celular
• Barulhos e temas de jogos
• Dado eletrônico
• Palpiteiro da loteria
• Sorteador para BINGO
• Vela Eletrônica
• Controle por Celular com BlueTooth

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
3

• Teclado musical robótico


• Contador regressivo: BOOM!
• Relógio
• Gerador de tabuadas
• Mão firme
• Ambulância
• Alarme
• Menu de Opções
• Sequenciais de LEDS
• Semáforo
• Código Morse
• Sensor de Luminosidade - Robo seguidor linha
• Sensor de Temperatura - termômetroSerial e termômetro-
Celular

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 1. APRESENTAÇÃO 4

1.1 Introdução aos Sistemas Computacionais


O avanço da tecnologia nas últimas décadas permitiu a popu-
larização dos computadores e mais recentemente dos microcon-
troladores, com sistemas de processamento semelhantes e redu-
zidos em termos de custo e tamanho.
O uso de computadores como ferramentas de desenvolvimento
permitiu o projeto e implementação de programas em pequenos
sistemas, especialmente os robóticos.

Figura 1.2: Nosso mascote Robot.ino

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
5 1.1. INTRODUÇÃO AOS SISTEMAS COMPUTACIONAIS

É importante ter em mente, que os computadores, essencial-


mente executam as seguintes tarefas:
• Processamento - resolução de operações lógicas e aritméti-
cas.
• Armazenamento - escrita e leitura de valores e informações.
• Entrada e Saída de Dados - comunicação com outros dispo-
sitivos externos chamados de periféricos, como por exem-
plo, monitor, teclado, mouse, etc.

1.1.1 O Computador
Os PCs - Computadores Pessoais (do inglês Personal Compu-
ter) são amplamente utilizados na atualidade em sua versão de
mesa (desktop) e portátil (notebook), para uma variedade imensa
e diversificada de aplicações.

Figura 1.3: Diagrama de um computador básico - Placa Mãe

1.1.2 O microcontrolador
Processador, memória e o bloco de entradas e saídas são três
blocos básicos de um sistema computacional. Basicamente, o

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 1. APRESENTAÇÃO 6

funcionamento de um computador depende desses blocos - cha-


mado de computador mínimo.

Figura 1.4: Diagrama dos blocos do sistema

Assim os blocos principais que compõem o microcontrolodor


são:
• Memória: dispositivo que armazena os dados de trabalho e
os dados das instruções a serem executadas.
• Bloco E/S: entradas e saídas, são o meio de comunicação do
sistema com o exterior, através dessas chamadas portas ou
gates podemos ligar diversos outros dispositivos que podem
enviar informações para o sistema (ENTRADA) ou receber
informações do sistema (SAÍDA).
• Processador: executa comandos, manipula dados na memó-
ria, processa contas lógicas e aritméticas, lê e escreve infor-
mações nos dispositivos de entrada e saída.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
Capítulo 2

Plataforma Arduino

A ferramenta empregada para o desenvolvimento de progra-


mas é a IDE (interface development engine) do Arduino, que
trata-se de uma programa para computador (Windows, Linux ou
mac) no qual editamos e através deles conseguimos gerar o có-
digo a ser transferido para o microcontrolador, que também é
feito pelo intermédio da IDE.

Figura 2.1: Placa Mãe (PC) e Arduino Uno

7
CAPÍTULO 2. PLATAFORMA ARDUINO 8

O Arduino é uma iniciativa livre que desenvolveu o aplicativo


de desenvolvimento Arduino IDE e placas contendo o microcon-
trolador capazes de serem reprogramadas sem a necessidade de
dispositivos gravadores extras. Assim a placa arduino é capaz
de trocar seu próprio programa utilizando apenas um cabo USB
ligado ao computador, através do programa de interface do ar-
duino.

Figura 2.2: Esquema de ligação PC-Arduino

Existe uma grande variedade de placas originais Arduino e


outras similares disponíveis e podem ser adquiridas em sites de
venda na internet.

Figura 2.3: Arduinos Uno e Nano

As placas Arduino mais utilizadas são o Arduino Nano, Uno e


Mega, mostrado na figura 2.3, os tipos de Arduino estão listados
no Apêndice 1.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
9 2.1. PROGRAMAÇÃO ALTO E BAIXO NÍVEL

2.1 Programação alto e baixo nível


É considerado um programa de alto nível o qual é escrito na
linguagem mais próxima à linguagem humana, ao passo que um
programa em lingueagem de baixo nível é aquela na qual o pro-
cessador entende,sendo chamada de linguagem de máquina (ge-
ralmente composto de um código binário também chamado de
hexadecimal).

Figura 2.4: Compilador - Conversão do programa (código texto - alto nível)


para o arquivo de máquina (binário - baixo nível)

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 2. PLATAFORMA ARDUINO 10

Figura 2.5: Processo completo de compilação e gravação do programgra alto-


nível à gravação do código de máquina na placa Arduino.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
11 2.2. INTERFACE DE DESENVOLVIMENTO

2.2 Interface de Desenvolvimento


A interface de desenvolvimento arduino é um programa para
plataforma de computador (Windows, Linux e Mac) disponível
gratuitamente em: www.arduino.cc/download.
Como obter e instalar o Arduino é apresentado mais detalha-
damente no Apêndice 2.
Ao executar o aplicativo Arduino, uma tela inicial de boas
vindas é visualizada enquanto o ambiente é carregado, sendo vi-
sualizado então a interface inicial do Arduino:

Figura 2.6: Janela da interface de desenvolvimento e edição Arduino - Inter-


face Development Engenie - IDE

Na janela principal o código do último programa editado é


carregado, no caso da primeira vez que o aplicativo é executado,

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 2. PLATAFORMA ARDUINO 12

um código básico inicial é projetado, a partir do qual a solução


desejada pode ser desenvolvida.
As principais áreas da tela ilustrados na Figura 2.6 estão des-
critos a seguir:

• I - Barra Principal Superior, indica o nome e a versão do


programa.
• II - Barra de Menus, onde estão diversas funções deste soft-
ware, que serão amplamente utilizadas ao longo do mate-
rial.
• III - Barra de Ferramentas: estão presentes 6 ícones, o pri-
meiro, chamado "Verificar", corrige o seu programa e salva-
o, indicando um erro. O segundo, uma flecha para a direita,
chamado de "Carregar", faz o mesmo que o "Verificar"
• IV - Espaço de visualização e edição do texto do programa,
o espaço principal, onde são listados os comandos e fun-
ções, o "corpo"do programa.
• V - Área de mensagens de verificação e compilação: Ao
compilar o programa, algumas mensagens de erro - quando
há um erro - são escritas, indicando onde o erro ocorreu.
• VI - Rodapé: Barra de Informações, mostra qual o tipo de
Arduino está configurado para a gravação, e qual porta está
configurada.

2.3 Como Carregar um Exemplo


É comum iniciar sua solução a partir de um outro exemplo
ou mesmo unindo recursos de outros programas. Nesse sentido

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
13 2.3. COMO CARREGAR UM EXEMPLO

uma série de exemplos prontos e funcionais estão disponíveis e


podem ser carregados através do menu Arquivo, > Exemplos,
onde os programas, chamados de sketchs são agrupados por ca-
tegorias: digitais, analógico, serial, string...
Vamos carregar o programa mais simples possível, cujo pro-
pósito é fazer com que um LED (emissor de luz) passe a piscar,
ou seja, ficando intervalos de tempo aceso e apagado. Embora
seja o programa mais básico possível, ao fazer o LED piscar de-
monstra que o microcontrolador está operando. Na maioria dos
projetos é a primeira coisa que fazemos, pois com o LED pis-
cando sabemos que o sistema está funcionando. Esse simples
emissor de luz demonstra que o sistema está vivo, sendo assim
chamado de hearth (coração), que fica pulsando.

Figura 2.7: Tela com o caminho para carregar o programa Blink.ino - Ar-
quivo>Exemplos>01.Basics>Blink

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 2. PLATAFORMA ARDUINO 14

2.4 Como configurar o Arduino


Estando o drive instalado, ao contectar o cabo usb no PC e na
placa Arduino, uma porta COM do tipo Serial é disponibilizada
no sistema.
No Windows ela pode ser verificada acessando Painel de Con-
trole > Sistema > Portas Com, conforme ilustrado na Figura a
seguir.

Figura 2.8: Carregando o código do exemplo Blink

Na tela do Arduino (IDE), no menu Ferramentas, escolha a


placa correpondente ao seu kit Xplorer Genius Nano: Arduino
Nano, com tamanho e preço reduzidos. Uma placa UNO também
é uma boa escolha (kit Xplorer Genius Uno), cujo tamanho é
maior e permite a ligação de fonte de energia externa para que a
placa opere posteriormente à gravação sem a necessidade do PC.
Após escolher a placa utilizada, a configuração seguinte é a
porta, clicando em Menu > Ferramentas > Porta e então escolhendo-
se a porta instalada ao ligar a placa ao PC.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
15 2.4. COMO CONFIGURAR O ARDUINO

Figura 2.9: Configurando a porta de comunicação serial

Pronto, o sistema está configurado para após a compilação


do programa, realizar a transferência para a placa Arduino. A
compilação é o processo que converte o código do texto do pro-
grama que escrevemos para um código conhecido como código
de máquina, código hexa (decimal) ou código objeto, o qual efe-
tivamente pode ser executado pelo microcontrolador.
Experimente carregar o exemplo blink. Em seguida, estando
configurado o drive, a placa e a respectiva porta serial COM
de comunicação, o programa pode ser compilado e transferido
(carga) para a placa Arduino, clicando no ícone CARREGAR
(Seta) ou através do menu Ferramentas > Carregar.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 2. PLATAFORMA ARDUINO 16

Figura 2.10: Exemplo blink.ino

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
Capítulo 3

Entendendo um programa básico

Os programas para Arduino, chamados de sketchs*, são sequên-


cias de comandos a serem executados pelo microcontrolador do
sistema.
*Sketchs: texto contendo o código fonte de um programa na
linguagem de alto nível.
As partes básicas de um programa arduino são os blocos setup
e loop, ilustrado na forma de fluxograma, conforme a figura 3.1
.

Figura 3.1: Fluxograma de um programa básico.

17
CAPÍTULO 3. ENTENDENDO UM PROGRAMA BÁSICO 18

A inicialização do programa é feito pelo bloco setup, execu-


tado apenas quando o sistema é ligado (ou religado). Este bloco
é executado apenas uma vez no começo do programa.
O bloco loop é o corpo do programa, chamado de bloco
principal. Este bloco fica em constante execução, ou seja, quando
a última linha do programa é executado, o corpo principal reco-
meça na primeira linha.

void setup() {
// put your setup code here, to run once:

void loop() {
// put your main code here, to run repeatedly:

Figura 3.2: Novo sketch, blocos básicos

void setup() {
// comandos de inicialização
}
void loop() {
// comandos do bloco principal
}
Figura 3.3: Código de um programa com os blocos básicos setup e loop.

Para ficar bem claro sobre a sintaxe dos blocos principais, a


palavra void indica que os blocos setup e loop não retor-
nam nenhum valor, uma vez que tecnicamente são funções como
várias outras existentes e que também podemos criar, conforme

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
19 3.1. ANALISANDO O PROGRAMA BLINK

será visto adiante na seção sobre como criar comandos (procedi-


mentos e funções).
Só é possível compilar apenas um setup e um loop por
sketch, não teria sentido haver mais de um!

3.1 Analisando o programa blink


Analisando o programa exemplo BLINK.INO (os nomes dos
arquivos de programa para arduino terminam com a extensão
.INO) podemos encontrar o setup e o loop.

// the setup function runs once when you press


reset or power the board
void setup() {
// initialize digital pin LED_BUILTIN as an
output.
pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again


forever
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // turn the
LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the
LED off by making the voltage LOW
delay(1000); // wait for a second
}

Figura 3.4: Programa Blink.ino - Exemplos Arduino Basic

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 3. ENTENDENDO UM PROGRAMA BÁSICO 20

É importante observar que:


• no exemplo BLINK existem vários comentários, mensagens
que inserimos após duas barras de dividir → //.
• os comentários não são comandos, servem apenas para au-
xiliar no entendimento do programa.
• se todos os comentários forem retirados do código do pro-
grama, ele funcionará da mesma forma.

3.1.1 pinMode
No bloco setup o comando pinMode configura o pino de
saída ligado ao indicador luminoso na placa do Arduino, LED_
BUILTIN como sendo do tipo saída (OUTPUT). Isso é necessá-
rio porque os pinos podem ser utilizados tanto para saída quanto
para entrada.
Através das saídas podemos fazer a escrita que irá ativar ou
desetivar o dispositivo ligado ao pino de saída, no caso o mais
simples dos dispositivos de saída é o LED. A sintaxe do comando
pinMode está exibida a seguir.

pinMode(LED_BUILTIN, OUTPUT);

Figura 3.5: Sintaxe do comando pinMode, configurando o LED_BULTIN


(LED padrão) para OUTPUT (saída).

Deve estar se perguntando o que é um LED_BUILTIN. Este


LED, nada mais é que a referência usada pelo próprio Arduino
para se designar ao indicador luminoso que vem embutido na
placa, como o indicado.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
21 3.1. ANALISANDO O PROGRAMA BLINK

Figura 3.6: Exemplo de ligação de um LED ao arduino UNO

Este LED_BUILTIN é ligado internamente à porta 13, nos


Arduinos com ATmega328P (explicação detalhada pode ser en-
contrada no Apêndice A).

3.1.2 digitalWrite
Finalmente o corpo do programa, no bloco loop(), apenas
dois comandos específicos são utilizados: digitalWrite e
delay. O comando digitalWrite, como a tradução sugere, faz a
escrita do valor no pino de saída (nesse caso, onde há um LED
interligado). A sintaxe do comando utiliza dois parâmetros que
devem ser dispostos entre parênteses e separados por vírgulas.
O primeiro parâmetro é o pino no qual a escrita será feita, o
segundo parâmetro, o valor a ser escrito (HIGH ou LOW).
Seria possível passar como parâmetro o próprio número do
pino, no caso 13, mas o uso da constante com identificador LED_
BULTIN torna mais claro o entendimento e a modificação pos-
terior do pino utilizado.
Sintaxe do comando de escrita em um pino de saída:

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 3. ENTENDENDO UM PROGRAMA BÁSICO 22

digitalWrite( <pino> , <valor> )

Figura 3.7: Sintaxe comando digitalWrite

Ao indicar o LED como saída com o comando digitalWrite,


o ’pino’ deste deve ser inscrito. O LED já contido nas placas
Arduino está ligado ao pino 13, da mesma forma, se um LED
externo for conectado ao Arduino, o pino em que foi inserido
deve ser definido.
O ’valor’ descrito na sintaxe se refere à inscrição de ’HIGH’
ou ’LOW’ (sempre em letras maiúsculas). Normalmente, HIGH
indica que o LED deve ser ligado, e LOW, que deve ser desligado.

3.1.3 delay
O segundo comando utilizado, o delay, é bastante simples.
Sua função é fazer com que o sistema aguarde o tempo em mi-
lissegundos passado como parâmetro entre parênteses.
Sintaxe do comando delay:

delay( <tempo>);

3.1.4 Interpretando o Blink.ino


Para visualizar melhor o programa BLINK.INO vamos, sem
alterar a funcionalidade do programa, retirar todos os comentá-
rios, conforme a figura 3.8.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
23 3.1. ANALISANDO O PROGRAMA BLINK

void setup() {
pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
}

Figura 3.8: Programa Blink.ino sem comentários

Portanto, levando em consideração tudo o que já foi expli-


cado, o programa Blink.ino, mostrado logo acima, pode ser in-
terpretado da seguinte maneira:
• O LED presente no próprio Arduino é indicado como saída
no setup. Não há necessidade de realizar um pinMode mais
de uma vez, por isso é costumeiro colocá-lo no setup.
• Em seguida, no loop, o led é ligado, permanece 1 segundo
nesse estado (1000 milissegundos), depois é desligado, também
por 1 segundo. E, por estar no loop, permanecerá em constante
repetição.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 3. ENTENDENDO UM PROGRAMA BÁSICO 24

Figura 3.9: Fluxograma do programa BLINK.INO comparado com o fluxo-


grama dos blocos básico

Agora ficou simples, não?


Lembre-se de que:
• o valor colocado no delay é em milissegundos, ou seja,
uma milésima parte do segundo, sendo preciso 1000 milis-
segundos para se ter o tempo de 1 segundo.
• se colocar um número muito baixo no delay (menor
que 30 milissegundos), nossa vista não consegue perceber o
LED piscando, mas aparentemente aceso com uma intensi-
dade luminosa menor.
• é interessante experimentar valores próximos de 30 mi-
lissegundos, menores e maiores. A partir de qual valor é
possível enxergar piscando?

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
25 3.2. ERROS COMUNS AO COMPILAR

3.2 Erros comuns ao compilar


Se o programa não compilar devido a inconsistências, é pre-
ciso verificar a sintaxe do programa. Observe um erro comum,
logo após os comandos de Setup e Loop, há abre e fecha parên-
teses "()", e em seguida a abertura de chaves "{"marca o começo
do bloco, bem como o fecha chaves "}"encerra o bloco. Quando
colocamos o cursor sobre esses símbolos seus pares correspon-
dentes são marcados para ajudar a identificar seu início e fim.
Outro detalhe importante é que todo final de declaração ou
comando termina com um caractere ponto-e-vírgula. O Loop e
o Setup não tem ponto-e-vírgula em suas declarações pois não
são comandos e não fazem efetivamente nenhuma tarefa, e sim
apenas os blocos.
Quando ocorre um erro, na área de mensagens aparece a des-
crição do erro. Se algum comando é escrito de forma errada,
uma mensagem de “unknown identifier” é mostrada, indicando
que o comando não foi reconhecido.
É importante entender que o compilador faz distinção de le-
tras maiúsculas e minúsculas, assim, da forma que o comando é
declarado deve ser respeitado. Por exemplo, o comando digital-
Write começa com letra minúscula e apenas o “W” é maiúsculo,
então se o comando for escrito digitalwrite (com tudo minúsculo)
irá gerar uma mensagem de erro.
Uma sugestão é fazer com que esses erros aconteça para que
fique familiarizado com eles. Experimente escrever digitalWrite
com o “W” minúsculo e ao compilar veja o erro. Da mesma
forma, apague um dos pontos-e-vírgula no final de uma das li-
nhas e experimente compilar para ver o erro.
Tendo entendido todas as partes deste capítulo, teste sua ca-
pacidade:

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 3. ENTENDENDO UM PROGRAMA BÁSICO 26

3.3 Atividades
Exercício 1. A partir do programa Blink.ino, altere os tem-
pos de modo a piscar rápido.
Exercício 2. Uma piscada consiste em um tempo aceso e um
tempo apagado. Usando o sketch do exercício anterior, imple-
mente um programa que repita uma piscada longa e uma piscada
curta.
Exercício 3. Sabendo que o bloco setup é executado uma única
vez quando o programa inicia, modifique o sketch do exercício
anterior para que o LED

3.3.1 Desafio
Exercício 4. Implemente uma versão do programa blink.ino que
ao ligar o sistema dê duas piscadas longas e então fique dando
piscadas curtas com intervalos longos.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
Capítulo 4

Saídas Digitais

Vimos anteriormente o controle de um indicador luminoso


(LED), que é uma saída digital, pois através dele o programa
consegue passar ao usuário algum tipo de informação. Os dis-
positivos básicos de saída que serão vistos neste capítulo serão
além dos indicadores luminosos, o indicador sonoro (buzzer) e a
escrita pela porta de comunicação serial (via cabo USB e Serial
Monitor).

4.1 Indicadores luminosos - LEDs


Os LEDs são componentes luminosos que podem ser encon-
trados em várias cores: azul, verde, vermelho, laranja, amarelo e
branco. O termo é a abreviação de Light Emissor Diode, que em
português significa diodo emissor de luz.
O kit Genius.ino contém quatro LEDs: azul, verde, amarelo
e vermelho, os quais estão ligados nas saídas A0 , A1 , A2 e A3 ,
conforme a tabela a seguir:

27
CAPÍTULO 4. SAÍDAS DIGITAIS 28

LED Cor Pino


1 Azul A1
2 Verde A2
3 Vermelho A3
4 Amarelo A4
Caso você não tenha a placa com as ligaçõe prontas, você
pode fazer suas prórprias ligações, um exemplo é a figura na qual
ilustra as ligações dos leds à um Arduino Uno através de fio e
uma placa de protótipos - proto-board.

Figura 4.1: Esquema de ligação dos LEDS ao Arduino UNO

Dentro do texto do programa, sempre que um pino for utili-


zado, tem-se que inicializá-lo (configurar o pino do microcon-
trolador como entrada ou saída). A sintaxe do comando para

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
29 4.1. INDICADORES LUMINOSOS - LEDS

configurar os pinos pinMode é feito por dois parâmetros que


estão representados por <pino> e seu tipo, indicado pelo parâ-
metro <modo>.

pinMode(<pino> , <modo>);

Figura 4.2: Sintaxe do comando pinMode

No parâmetro <pino>, para uma saída digital, como por


exemplo a saída D4, basta colocar o número da saída digital, ou
seja, 4. Para as entradas analógicas (A0 até A5 no Arduino Uno
e de A0 até A7 no Arduino Nano), que podem ser configuradas
como sáidas digitais, deve-se colocar a letra A junto do número
da saida, veja os exemplos.

pinMode( 4 , OUTPUT );

Figura 4.3: Exemplo do comando pinMode para configurar a porta digital


D4 como saída

pinMode( A1 , OUTPUT );

Figura 4.4: Exemplo do comando pinMode para configurar a porta A1 como


saída digital

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 4. SAÍDAS DIGITAIS 30

Sobre as portas do Arduino, saiba que:


• as portas digitais vão de D0 a D13;
• as portas de entrada analógica vão de A0 a A7, podendo
serem configuradas como saídas digitais;
• as portas digitais assumem valores LOW e HIGH, enquanto
as analógicas podem representar valores intermediários en-
tre 0 volts (LOW) e 5 volts (HIGH).

Este comando inicializa a porta configurada de acordo com os


parâmetros do pinMode, mas não realiza nenhuma ação visível.
Para que o LED configurado acenda, outro comando é necessá-
rio:

digitalWrite( <pino>, <estado> )

Figura 4.5: Sintaxe do comando de escrita digitalWrite

Para acender o LED (referente à saída A1)

digitalWrite( A1 , HIGH );

Para apagar o LED

digitalWrite( A1 , LOW );

No Arduino, porém, o void loop() acontece tantas vezes


por segundo que parece que o LED está o tempo todo aceso,

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
31 4.1. INDICADORES LUMINOSOS - LEDS

e nada apagado, por isso é necessário um terceiro comando, o


delay.
Este comando, basicamente, pausa a execução do programa
pelo tempo determinado. Sendo assim, se um LED estiver aceso,
ele permanecerá aceso.

delay( <tempo em milissegundos> );

O programa básico do Arduino é chamado de "Blink", ou po-


pularmente conhecido como "Hello World", pois é o primeira
ação que o programador aprende. Consiste em fazer um LED
simplesmente piscar, uma reprentação de na forma de quadros
de histórico - history board é mostrado na figura 4.6.

Figura 4.6: History board do exemplo piscaAzul.ino

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 4. SAÍDAS DIGITAIS 32

void setup() {
pinMode(A1, OUTPUT);
}
void loop() {
digitalWrite(A1, HIGH)
delay(1000);
digitalWrite(A1, LOW);
delay(1000);
}

Figura 4.7: Código do programa piscaAzul.ino - LED A1

Copie esse código texto para o seu programa Arduino, e co-


necte o seu kit Genius e compile para ver. O LED fica um se-
gundo aceso e outro apagado, certo?
Para praticar, vamos fazer alguns exercícios.

4.1.1 Atividades
Conhecimentos à prova:
Exercício 5. Mude o programa de forma que o LED fique mais
tempo aceso e menos apagado.
Exercício 6. Do mesmo modo, deixe o LED menos tempo aceso
e mais tempo apagado.
Exercício 7. Agora faça-o ficar um segundo aceso, um segundo
apagado, meio segundo aceso e outro meio segundo apagado, e
assim continuamente.
Exercício 8. Implemente versões de programas que executem as
sequências de fases para os quadros de histórico das figuras a
seguir:
(a) piscaAntiHorario.ino

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
33 4.1. INDICADORES LUMINOSOS - LEDS

Figura 4.8: Quadro de histórico - piscaAntiHorario.ino

(b) piscaEnche.ino

Figura 4.9: Quadro de histórico piscaEnche.ino

(c) piscaDuploHorario.ino

Figura 4.10: Quadro de histórico piscaDuploHorario.ino

(d) piscaAcendeTudoApagaTudo.ino

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 4. SAÍDAS DIGITAIS 34

Figura 4.11: Quadro de histórico piscaAcendeTudoApagaTudo.ino

4.1.2 Desafio
Exercício 9. Conhece o Código Morse? Utilizado principal-
mente como meio de comunicação na Europa durante o final do
século XIX, se tratava de sinais longos e curtos, formando um
código de caracteres e uma mensagem.
A ·– M –– Y –·––
B –··· N –· Z ––··
C –·–· O ––– 1 ·––––
D –·· P ·––· 2 ··–––
E · Q ––·– 3 ···––
F ··–· R ·–· 4 ····–
G ––· S ··· 5 ·····
H ···· T – 6 –····
I ·· U ··– 7 ––···
J ·––– V ···– 8 –––··
K –·– W ·–– 9 ––––·
L ·–·· X –··– 0 –––––
Os pontos e traços são o LED aceso, mais ou menos tempo.
Para facilitar, podemos dizer que: o ponto fica 400 milissegun-

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
35 4.1. INDICADORES LUMINOSOS - LEDS

dos aceso e o traço, 1000. De acordo com a tabela, implemente


um programa que emita um código morse visual com as seguin-
tes mensagens:

(a) A inicial do seu nome.


(b) A sua idade.
(c) Um pedido de ajuda (SOS).
(d) Um horário, com hora e minuto.
(e) Uma palavra, por exemplo "AMOR".
(f) Uma frase, por exemplo: "MENSAGEM DA TERRA".

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 4. SAÍDAS DIGITAIS 36

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
Capítulo 5

Saída sonora

O BUZZER é um componente eletrônico que emite um si-


nal sonoro, pode reproduzir diversas frequências, com um som
metálico e robótico.
O componente precisa estar ligado a uma porta no Arduino,
assim como o LED. É necessário inicializá-lo nessa porta, utili-
zando o comando pinMode, já mostrado anteriormente:

pinMode( <porta> , OUTPUT );

O BUZZER emite som com o comando tone, com a seguinte


sintaxe:

tone( <porta> , <frequência> );

O valor colocado no parâmetro <porta> nos comandos pinMode


e tone deve ser o mesmo, correspondente à porta em que o com-
ponente está ligado. No caso da placa Genius, essa porta é a 10.
O segundo parâmetro no comando tone é um valor numé-
rico que determina a frequência do som emitido e, portanto, a

37
CAPÍTULO 5. SAÍDA SONORA 38

nota musical. A frequência de cada nota para a terceira oitava


(escala) está na tabela a seguir, sendo a terceira coluna Valor a
aproximação inteira ser utilizada:

Notas Frequência Valor


Dó 261,63 Hz 262
Ré 293,66 Hz 294
Mi 329,63 Hz 330
Fá 349,23 Hz 349
Sol 391,99 Hz 392
Lá 440,00 Hz 440
Si 493,88 Hz 494

5.1 Exemplo alarme


Começando com um exemplo bem simples, vamos imple-
mentar um alarme, que trata-se de um apito intermitente. A idéia
é bem parecida com o exemplo Blink.ino, a diferença será que ao
invés de ligar e desligar o LED, vamos ligar e desligar um tom
sonoro.
Experimente implementar e gravar o exemplo alarme.ino, mos-
trado a seguir:

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
39 5.2. ATIVIDADES

void setup() {
pinMode( 10 , OUTPUT );
}
void loop() {
tone( 10 , 1000);
delay(200);
noTone( 10 );
delay(800);
}

Figura 5.1: Exemplo alarme.ino

5.2 Atividades
Vamos praticar!
Exercício 10. A partir do exemplo ALARME.INO, implemente
um programa para fazer o barulho de uma ambulância. Utilize
dois tons, um grave e outro agudo em cada um dos dois tempos.
Exercício 11. Modifique o programa ALARME.INO para que os
leds pisquem dois a dois alternadamente conforme o quado de
histórico (history board) mostrado na figura.

Figura 5.2: Quadro de histórico contendo as fases dos indicadores luminosos

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 5. SAÍDA SONORA 40

Exercício 12. Implemente um código que seja executado apenas


na inicialização (setup) que emita três beeps com tempos 300,
100 e 50 milisegundos, com silêncio entre eles de 200 milisegun-
dos.
Exercício 13. Implemente um programa de quatro fases, con-
forme o quadro de histórico da figura em que cada uma delas
acenda um led diferente. Para cada fase execute um tom dife-
rente. Sugestão: utilize tons de 200, 600, 1000 e 2000 Hz.

Figura 5.3: Quadro de histórico contendo as fases dos indicadores luminosos

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
Capítulo 6

Saída pela porta de comunicação


serial

A porta de comunicação serial permite enviar mensagem e


informações para um outro arduino ou para o computador. No
bloco setup() fazemos a inicialização da porta, conforme mos-
trado a seguir:

Serial.begin( <taxa> );

A <taxa> é o parâmetro que define a velocidade de comuni-


cação. A velocidade mais comum é 9600 bps (dado em bits por
segundo). Então o comando de inicialização será:

Serial.begin( 9600 );

A porta precisa ser inicializada uma única vez, de forma que


iremos implementar sua inicialização no bloco setup().
A escrita da mensagem na porta de comunicação serial é feita
através do comando write, conforme mostrado a seguir:

41
CAPÍTULO 6. SAÍDA PELA PORTA DE COMUNICAÇÃO SERIAL 42

Serial.print( <mensagem> );

O parâmetro <mensagem> poderá ser um valor ou conjuntos


de caracteres alfanuméricos, chamados de string. A mensagem
deve ser delimitada por aspas duplas, que indicam o início e o
fim da mensagem. Veja o exemplo:

Serial.print("Ola!");

Figura 6.1: ola.ino

6.1 Exemplo Serial OI


O comando print envia a mensagem pela porta de saída se-
rial, podendo ser lida pelo programa Monitor Serial, disponível
na interface de edição do Arduino. O ícone para chamar o Moni-
tor serial é uma lupa e está no canto direito superior da tela. Veja
a figura 6.2.

void setup() {
Serial.begin(9600);
Serial.print("Oi!!");
}

void loop() {
}

Figura 6.2: Exemplo SerialOi.ino

Vale a pena ressaltar que no caso do exemplo serialOi.ino,

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
43 6.2. EXEMPLO SERIAL OI MAIS

a inicialização e a escrita na porta Serial estão no setup e não


existe nenhum comando no loop. Com isso, apenas uma única
vez a porta é inicializada e uma única mensagem é escrita.

6.2 Exemplo Serial Oi Mais


Vamos ver o resultado de colocar o comando para imprimir
a mensagem no loop. Experimente implementar e regravar no
Arduino o exemplo SerialOiMais.ino, listado a seguir:

void setup() {
Serial.begin(9600);
Serial.print("Oi!!");
}

void loop() {
Serial.print("Mais");
delay(200);
}

Figura 6.3: Exemplo SerialOiMais.ino

6.3 Atividades
Mãos à obra!
Exercício 14. Junte os exemplos BLINK.INO e SERIAL_OI.INO
de forma que ao acender e apagar o LED seja enviado pela porta
serial as palavras "ACESO"e "APAGADO".
Exercício 15. Implemente um programa que faça piscar separa-
damente cada um dos 4 LEDS da placa GENIUS de maneira que
para cada um deles seja enviado pela porta serial a cor corres-
pondente ao LED aceso.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 6. SAÍDA PELA PORTA DE COMUNICAÇÃO SERIAL 44

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
Capítulo 7

Identificadores - palavras
reservadas, constantes, variáveis,
comandos e demais estruturas

Na manipulação de informações, sejam valores numéricos ou


alfabéticos, fazemos uso de estruturas que permitem manipular
esses dados, associando um identificador à essas posições de me-
mória chamadas de variáveis, as quais podem armazenar e recu-
perar diferentes valores.
Caso haja necessidade de parâmetros fixos, utilizamos estru-
turas chamadas de constantes, através das quais fazemos referên-
cias através de nomes que criamos, chamados de identificadores,
que são usados durante a programação para estabelecer a associ-
ação com o conteúdo.
Os Identificadores são usados para nomear todas as estruturas
de programação, a seguir estão classificadas algumas das mais
importantes:
• Palavras reservadas: são todos os comandos e palavras uti-
lizadas na programação e reconhecidas pelo compilador.
• Contantes: valores fixos durante execução do programa.
• Variáveis: valores que são recebidos ou mudam durante o

45
CAPÍTULO 7. IDENTIFICADORES - PALAVRAS RESERVADAS,
CONSTANTES, VARIÁVEIS, COMANDOS E DEMAIS ESTRUTURAS 46

programa.
• Comandos: subrotinas, que podem ser mais especificamente
um procedimento (se não retornar nenhum valor) ou função (caso
retorne algum valor).
• Bibliotecas: arquivos de comandos ou classes.
• Classes, objetos, propriedades e métodos: a programação
para Arduino pode ser além de estruturada, também orientada a
objetos, nesses casos os Identificadore dão nome à classe e aos
objetos instanciados dessa classe, bem como às suas respectivas
propriedades e métodos associados.

7.1 Identificadores válidos e inválidos


Identificadores são todos os nomes criados para serem utiliza-
dos para nomear estruturas na linguagem de programação. Para
o manuseio de dados, utilizamos espaços de memória que podem
ser de dois tipos:
• valores fixos (contantes);
• valores que mudam (variáveis)
Para dar nomes à comandos e funções também devemos usar
identificadores que sejam aceito pelo compilador, assim é pre-
ciso estar atento às regras básicas para que um Identificador seja
válido.
Esses nomes que usamos como identificadores devem respei-
tar às seguintes regras:
• Serem compostos apenas por letras, números e o símbolo
sublinha ("_", chamado de underscore);
• Sempre começar com uma letra;
• Não utilizar um outro identificador já declarado ou próprio
da linguagem.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
47 7.1. IDENTIFICADORES VÁLIDOS E INVÁLIDOS

Não se pode usar espaços para criar identificado-


res, pois o compilador entende que o identificador
termina quando encontra o caractere espaço

O parâmetro <pino> deve conter um valor numérico, que


pode ser o próprio número do pino de saída, uma constante as-
sociada ao número do pino ou uma variável cujo conteúdo seja o
número do pino.
A seguir são mostradas outras três versões do programa onde
são utilizados o próprio valor numérico do pino (sem uso de
constantes ou variáveis), com a declaração de uma constante que
podemos criar e a terceira versão utilizando uma variável (cujo
conceito será visto adiante). Todas as versões do programa exe-
cutam a mesma tarefa, mas o uso de constante apresenta uma
melhor prática de programação, mais clara e mais fácil para pos-
teriores alterações.
Não se pode utilizar caracteres acentuados, como os da língua
portuguesa, nem outros símbolos ou o espaço, pois dessa forma
o compilador entende que o identificador terminou ao encontrar
um caractere de espaço.

7.1.1 Exemplos de identificadores válidos


São exemplos de identificadores válidos:
• valor1
• prim_nome
• numero
•n

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 7. IDENTIFICADORES - PALAVRAS RESERVADAS,
CONSTANTES, VARIÁVEIS, COMANDOS E DEMAIS ESTRUTURAS 48

7.1.2 Exemplos de identificadores inválidos


O uso de identificadores inválidos podem provocar erros di-
versos na compilação. Sempre que tiver um erro ao compilar um
programa, lembre-se das regras de compilação. A seguir temos
exemplos de Identificadores inválidos:
• 1oValor
•Valor 1
• int
• número

7.1.3 Exercícios Identificadores


Exercício 16. Separe os identificadores a seguir em dois grupos:
a) Identificadores válidos, os que serão reconhecidos pelo
compilador;
b) Identificadores inválidos, que desrespeitam as regras de
criação de Identificadores.

7.2 Constantes
Na implementação de programas é comum a necessidade de
definir valores fixos, como pinos de entrada e saída, frequencias
para tons, tempos de duração, etc. Uma vez que os valores não
mudam durante a execução do programa, o uso de contantes re-
laciona identificadores a seus respectivos valores.
Na prática, no processo de compilação do código fonte, o
compilador usa os valores associados contidos nos identificado-
res, ficando esses valores no código objeto do programa, que ao
fazer upload no Arduino, fica na memória de programa (do tipo
não volátil - EEPROM ou Flash).

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
49 7.2. CONSTANTES

O uso de constantes não ocupa memória de trabalho (RAM,


onde ficam variáveis).

7.2.1 Constantes - define


Podemos então associar os pinos ligados aos LEDs a identi-
ficadores significativos, e ao invés de usar os pinos físicos, utili-
zamos seus identificadores.
// Declaração de constantes - saídas
#define ledC A1 // Cima
#define ledE A2 // Esquerda
#define ledB A3 // Baixo
#define ledD A4 // Direita

Figura 7.1: Código de declaração de Constantes para saídas com define

7.2.2 Constantes com tipo - const

// Declaração de constantes - saídas


const int ledC = A1; // Cima
const int ledE = A2; // Esquerda
const int ledB = A3; // Baixo
const int ledD = A4; // Direita

Figura 7.2: Código de declaração de Constantes para saídas com const

7.2.3 Exercícios - Constantes


Exercício 17. Crie Identificadores significativos para as Cons-
tantes a seguir:
a) Saida D3 ligada em modo analógico ao led para o projeto
VELA.INO.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 7. IDENTIFICADORES - PALAVRAS RESERVADAS,
CONSTANTES, VARIÁVEIS, COMANDOS E DEMAIS ESTRUTURAS 50

b) Valor para o tempo ligado e valor para o tempo desligado


para o projeto ALARME.INO.
Exercício 18. Faça um programa de fases, que façam os LEDs
acenderem sequenciamente no sentido horário utilizando as Cons-
tantes ledC, ledE, ledB, ledE; conforme o Exemplo de Cons-
tantes.

7.3 Variáveis
As variáveis são estruturas de programção que permitem a
manipulação de dados, associando o seu espaço físico na memó-
ria a um identificador, através do qual se executam operações de
entrada e saída.

Figura 7.3: Ilustração da analogia de variáveis e uma caixa

7.3.1 Exemplo Contador


Exemplo contador:

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
51 7.3. VARIÁVEIS

byte numero=0;
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println( numero);
numero=numero+1;
delay(1000);
}

Figura 7.4: Código exemplo contador.INO

7.3.2 Tipos de Variáveis


As variáveis ocupam espaços relativos ao tamanho da infor-
mação que devem suportar. A menor informação é a de um bit,
cujo estado pode ser HIGH ou LOW. Esse tipo de informação é
chamada em inglês de boolean, cuja tradução é booleana. A sin-
taxe para esse tipo de informação mínima é a palavra reservada
bool.
Para informações de até 8 bits, temos o byte, capaz de ar-
mazenas valores entre 0 e 255.
Para valores numéricos inteiros maiores temos os tipos int
e double. A tabela a seguir mostra as faixas de valores para os
tipos inteiros que podem ser: sinalizados (que podem represen-
tar valores negativos, nulos e positivos) ou não sinalizados (que
representam apenas valores nulos e positivos).

7.3.3 Exercícios Variáveis


Exercício 19. Altere o programa contador, para que o tempo de
espera entre os laços do loop seja 200 mili segundos. Com-
pile e carregue, entre no terminal serial e responda, quando a

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 7. IDENTIFICADORES - PALAVRAS RESERVADAS,
CONSTANTES, VARIÁVEIS, COMANDOS E DEMAIS ESTRUTURAS 52

contagem recomeça?
Exercício 20. A partir do programa CONTADOR.INO, crie o
programa CONTATOR_REGR.INO cujo valor seja iniciado em
30 e faça a contagem regressiva, ou seja, decrescente.

7.4 Comandos, procedimentos e funções


Comandos são estruturas de programação que permitem as-
sociar subrotinas a Identificadores a fim de organizar, otimizar e
reaproveitar códigos dedicados.
Classificamos os Comandos em dois tipos:
• Procedimento: tipo de comando que executa sub comandos
e não retorna nenhum valor;
• Funções: tipo de comando que executa sub comandos e
retorna algum tipo de valor;
Por exemplo, podemos imaginar um comando que faz um
LED piscar. Par isso são necessários 4 subtarefas:
1) Ligar o LED;
2) Esperar o tempo aceso;
3) Desligar o LED;
4) Esperar o tempo apagado;

void pisca1() {
pinMode( A1, OUTPUT );
digitalWrite( A1, HIGH );
delay(1000);
digitalWrite( A1, LOW );
delay(1000);
}

Figura 7.5: Bloco de código do comando pisca1()

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
53 7.4. COMANDOS, PROCEDIMENTOS E FUNÇÕES

Os comandos devem ser implementados antes de serem uti-


lizados, geralmente antes do setup(). Por exemplo, um pro-
grama que pisca duas vezes ao ligar o sistema ficará como no
exemplo piscaInicio.ino.

void pisca1() {
pinMode( A1, OUTPUT );
digitalWrite( A1, HIGH );
delay(1000);
digitalWrite( A1, LOW );
delay(1000);
}
void setup() {
pisca1();
pisca1();
}
void loop() {
}

Figura 7.6: Exemplo completo piscaInicio.ino

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 7. IDENTIFICADORES - PALAVRAS RESERVADAS,
CONSTANTES, VARIÁVEIS, COMANDOS E DEMAIS ESTRUTURAS 54

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
Capítulo 8

Operadores

Os operadores são simbolos ou palavras reservadas capazes


de operar dois valores e retornar o resultado da operação. Por
exemplo, para somar o conteúdo de duas variáveis inteiras, n1 e
n2, sendo o resultado atribuido à variável nSoma, conforme o
código a seguir:

Figura 8.1: Exemplo Operador de Adição e operandos

55
CAPÍTULO 8. OPERADORES 56

void setup() {
int a=9;
int b=3;
int soma=a+b;
Serial.begin(9600);
Serial.println( soma );
}
void loop() {
}

Figura 8.2: Exemplo soma.ino

8.1 Operadores matemáticos


Os operadores matemáticos são responsáveis pelas operações
de soma, subtração, multiplicação, divisão e resto, conforme os
simbolos associados na tabela.
Precedência Operação Operador
1 Multiplicação *
1 Divisão /
2 Soma +
2 Subtração -
3 Resto %

8.2 Operadores relacionais


Os operadores relacionais comparam os operandos e seu re-
sultado é sempre um booleano LOW ou HIGH.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
57 8.3. OPERADORES LÓGICOS

Precedência Operação Operador


1 maior que >
1 menor que <
1 maior ou igual >=
1 menor ou igual <=
1 igual ==
2 diferente !=

8.3 Operadores lógicos

Tabela 8.1: Operações Lógicas e Operadores

Precedência Operação Operador


1 AND &&
1 OR ||
2 NOT !

Tabela 8.2: Tabela Verdade Operador AND - &&

A B A && B
0 0 0
0 1 0
1 0 0
1 1 1

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 8. OPERADORES 58

Tabela 8.3: Tabela Verdade Operador OR - ||

A B A || B
0 0 0
0 1 1
1 0 1
1 1 1

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
Capítulo 9

Estrutura Condicional

As estruturas condicionais permitem executar ou saltar deter-


minados partes (blocos) do programa a partir de contas e testes
realizados com variáveis.
Podemos dividir os tipos de estruturas condicionais em: sim-
ples, compostas, encadeadas e de seleção, explicadas, ilustradas
e exemplificadas a seguir.

9.1 Estrutura condicional simples


Na estruturas condicional simples apenas um bloco de coman-
dos é associado ao teste condicional, que em caso verdadeiro im-
plica na execução do bloco de comandos ou do contrário, a não
execução desses comandos.
Na figura a seguir é mostrado o fluxograma que ilustra o fun-
cionamento da estrutura condicional simples.

59
CAPÍTULO 9. ESTRUTURA CONDICIONAL 60

Figura 9.1: Fluxograma comando se - if

A implementação dessa estrutura é feita através do comando


if, seguido pela condição de teste delimitada por parênteses.

if ( <condicao> ) {
// bloco comandos
}
A seguir um exemplo básico no qual uma variável idade
pode ser modificada de forma a definir a mensagem que é envi-
ada para o terminal serial.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
61 9.1. ESTRUTURA CONDICIONAL SIMPLES

// experimentar trocar
byte idade=25;
void setup() {
Serial.begin(9600);
if (idade < 18) {
Serial.println( "Menor de idade");
}
if (idade >= 18) {
Serial.println( "Maioridade");
}
}
void loop() {
}

Figura 9.2: Exemplo ifIdade.ino

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 9. ESTRUTURA CONDICIONAL 62

9.2 Estrutura condicional composta

Figura 9.3: Fluxograma comando se - if

A implementação dessa estrutura é feita através do comando


if, seguido pela condição de teste delimitada por parênteses.
if ( <condicao> ) {
// bloco comandos SE
} else {
// bloco comandos SENAO
}

Figura 9.4: Sintaxe do comando condicional composto (if else)

A estrutura condicional composta é utilizada nos casos em


que se são necessários blocos de comandos para quando a con-
dição for verdadeira (1), ou falsa (0).

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
63 9.2. ESTRUTURA CONDICIONAL COMPOSTA

A seguir um exemplo básico no qual uma variável idade


pode ser modificada de forma a definir a mensagem que é en-
viada para o terminal serial, funciona da mesma forma que o
exemplo com estrutura condicional simples, se a condição não
for atendida o bloco relativo ao else é executado.
byte idade=25;
void setup() {
Serial.begin(9600);
if (idade < 18) {
Serial.println( "Menor de idade");
} else
{
Serial.println( "Maioridade penal");
}
}
void loop() {
}

Figura 9.5: Exemplo ifIdadeElse.ino - estrutura condicional composta.

Exercício 21. Imaginemos uma condição dupla, dependente de


duas comparações. Sabendo que no Brasil, maiores de 16 anos
votam opcionalmente, e que a partir dos 18 anos são obrigados,
a partir do exemplo maioridade, cuja mensagem seja "VOTO
OPCIONAL"atendendo à seguinte condição:
if ((idade>=16)&&(idade<18)) {
Os dois simbolos de e-comercial corresponde à operação ló-
gica "E", sendo necessário que as duas partes sejam verdadeiras
para que a operação "E"retorne verdadeiro e o bloco seja exe-
cutado.
Observe que existe um par de parenteses para o comando if
e outro par para cada parte da condição.
Experimente valores menores que 16 para a variável idade,

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 9. ESTRUTURA CONDICIONAL 64

ao resetar o sistema (botão reset ou ao entrar o terminal serial)


nada deve aparecer.
Experimente os valores 16 e 17 para a variável idade e con-
firme que ao resetar o sistema a mensagem seja recebida no ter-
minal serial.

9.3 Estrutura condicional encadeada

Figura 9.6: Fluxograma comando se - if else if

A implementação dessa estrutura é feita através do comando


if, seguido pela condição de teste delimitada por parênteses.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
65 9.3. ESTRUTURA CONDICIONAL ENCADEADA

if ( <condicao1 verdadeira> ) {
// bloco 1
} else if ( <condicao2 verdadeira> ) {
// bloco 2
}
}

Figura 9.7: Sintaxe estrutura condicional encadeada if else if

A estrutura condicional encadeada, por sua vez, é aplicada


quando se quer testar uma sequência de condições com coman-
dos únicos para cada teste considerando que os testes anteriores
não foram atendidos.
A seguir um exemplo básico no qual uma variável textttidade
pode ser modificada de forma a definir a mensagem que é en-
viada para o terminal serial, funciona da mesma forma que o
exemplo com estrutura condicional simples, se a condição não
for atendida, então um novo teste vinculado ao elseif é execu-
tado.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 9. ESTRUTURA CONDICIONAL 66

// experimentar trocar
byte idade=25;
void setup() {
Serial.begin(9600);
if (idade >= 18) {
Serial.println( "Eleitor");
} else if (idade >= 16)
{
Serial.println( "Possivel eleitor");
}
}
void loop() {
}

Figura 9.8: Programa ifIdadeElseIf.ino - exemplo estrutura condici-


onal encadeada

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
67 9.4. ESTRUTURA CONDICIONAL ENCADEADA COM SENÃO

9.4 Estrutura condicional encadeada com senão

Figura 9.9: Fluxograma comando se - if elseif

A implementação dessa estrutura é feita através do comando


if, seguido pela condição de teste delimitada por parênteses.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 9. ESTRUTURA CONDICIONAL 68

if ( <condicao 1> ) {
// bloco comandos 1
} else if ( <condicao 2> ) {
// bloco comandos 2
} else {
// bloco comandos SENAO
}
A adição do else na estrutura condicional faz com que, no es-
trito caso de a condição imediatamente anterior ser falsa, a se-
gunda condição é avaliada. E assim acontece por quantos testes
forem necessários.
A seguir um exemplo básico no qual uma variável textttidade
pode ser modificada de forma a definir a mensagem que é en-
viada para o terminal serial, funciona da mesma forma que o
exemplo com estrutura condicional simples, se a condição não
for atendida, então um novo teste vinculado ao elseif é execu-
tado.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
69 9.5. ESTRUTURA CONDICIONAL DE SELEÇÃO

// experimentar trocar
byte idade=25;
void setup() {
Serial.begin(9600);
if (idade > 60) {
Serial.println( "Voto opcional");
} else if (idade >= 18) {
Serial.println( "Voto obrigatorio");
} else if (idade >= 16) {
Serial.println( "Possivel eleitor");
} else {
Serial.println( "Não vota!");
}
}
void loop() {
}

Figura 9.10: Programa ifIdadeElseIfElse.ino - exemplo estrutura


condicional encadeada com else.

9.5 Estrutura condicional de seleção


A estrutura condicional de seleção, comando switch case,
avalia cada uma das situações, executando o bloco associado
quando a variável de escolha é igual ao valor do caso em cada
teste. Quando o bloco é executado, o comando break pode ser
chamado para interromper a busca.
Nos exemplos, dentro da plataforma do Arduino, item 05.Control,
há o sketch, cujo void loop() está demonstrado a seguir:

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 9. ESTRUTURA CONDICIONAL 70

const int sensorMin = 0;


const int sensorMax = 600;
void loop() {
// read the sensor:
int sensorReading = analogRead(A0);
// map the sensor range to a range of four
options:
int range = map(sensorReading, sensorMin,
sensorMax, 0, 3);

Figura 9.11: Exemplo switchCase.ino, parte 1

Nessa primeira parte do exemplo, a partir da leitura de um


sensor externo, é criada a variável range.
Utilizando o comando map(), o valor recebido na porta A0,
que vai de 0 a 600, como estabelecido, é transformado propor-
cionalmente em um valore de 0 a 3, representado, portanto, por
range.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
71 9.5. ESTRUTURA CONDICIONAL DE SELEÇÃO

switch (range) {
case 0: // your hand is on the sensor
Serial.println("dark");
break;
case 1: // your hand is close to the sensor
Serial.println("dim");
break;
case 2: // your hand is a few inches from
the sensor
Serial.println("medium");
break;
case 3: // your hand is nowhere near the
sensor
Serial.println("bright");
break;
}

Figura 9.12: Exemplo switch.ino, parte 2

Assim, a variável range estabelecida anteriormente é utili-


zada como escolha, entre os diversos case acima estabelecidos.
Dessa forma, se a leitura da porta analógica corresponder a 150,
por exemplo, range será estabelecida como 1, pois 150 é 25%
de 600.
E por isso, aparecerá na porta serial "dim", pois o caso cor-
respondente ao range exemplificado é o segundo, de número de
ordem 1.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 9. ESTRUTURA CONDICIONAL 72

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
Capítulo 10

Entrada Digital Básica

Os pinos disponíveis para serem programados no microcon-


trolador (ATmega328 ou ATMEGA168) nos Arduinos Uno e
Nano podem ser configurados para atuarem como visto na forma
de saídas digitais, podendo também ser configurado para entrada.
Uma entrada no sistema é obtido através de uma operação de lei-
tura. Assim, o estado do sinal contido na entrada do sistema pode
ser obtido.
O tipo mais básico de entrada é um botão: pode estar pressio-
nado ou liberado, constituindo uma informação mínima de 1 bit
(HIGH ou LOW) e serve para informar ao sistema uma ação feita
pelo usuário (apertar ou soltar, no caso de um botão de pressão –
push button).
Existem dois tipos de ligação para os botões. O tipo PULLUP,
com sinal fixo em nível alto (HIGH=+5v), onde o botão fornece
o nível lógico baixo (LOW=0v) quando pressionado. O segundo
tipo de ligação é com PULLDOWN, com sinal fixo em nível
lógico baixo e fornece nível lógico alto quando pressionado. Na
figura estão os esquemas de ligação dos dois tipos.

73
CAPÍTULO 10. ENTRADA DIGITAL BÁSICA 74

Figura 10.1: Ligações de botões com resistor de PULL-UP (esquerda) e


PULL-DOWN (direita)

Figura 10.2: Conexão arduino UNO com botões, ligações PULL-UP (es-
querda) e PULL-DOWN (direita)

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
75

Figura 10.3: Conexão arduino UNO com 4 botões modo PULL-UP

A seguir estão as declarações utilizando a palavra reservada


#define, onde são criados identificadores para os pinos nos
quais estão conectados os botôes.

// Constantes para os boto es ligados ’as


entradas
#define pinBotCima 4
#define pinBotEsquerda 5
#define pinBotBaixo 6
#define pinBotDireita 7

Figura 10.4: Declarando constantes com define

Funcionando da mesma forma, pode-se declarar as constantes


para os pinos dos botôes através do comando const, conforme
mostrado no exemplo.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 10. ENTRADA DIGITAL BÁSICA 76

// Constantes para os boto es ligados ’as


entradas
const int pinoBotaoCima = 4 ;
const int pinoBotaoEsquerda = 5 ;
const int pinoBotaoBaixo = 6 ;
const int pinoBotaoDireita = 7 ;

Figura 10.5: Declarando constantes com const

A leitura do valor digital no qual está ligado um botão de-


pende do estado lógico ao qual o botão irá se conectar caso aper-
tado. Também o estado lógico do botão solto deve ser observado.

<var> = digitalRead( <Nº do pino> );

Figura 10.6: Sintaxe do comando de leitura digitalRead

O parâmetro <Nº do pino> pode ser o próprio valor ou o


valor contido em uma constante ou variável. A função digitalRead
retorna o valor HIGH ou LOW que é atribuida através do operador
de atribuição igual à variável utilizada no parâmetro var.
A seguir é apresentado o exemplo buttonLed.INO, no qual
o valor lido de uma variável é atribuído à saída ao qual esttá in-
terligado o LED1.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
77 10.1. EXERCÍCIOS COM BOTÕES

const int ledCima = A1; // Azul


const int botCima = 4;

void setup() {
pinMode( ledCima, OUTPUT );
pinMode( botCima, INPUT_PULLUP );
}

void loop() {
// Leitura do botão (entrada)
// HIGH-solto LOW-apertado
bool estadoBotao = digitalRead( botCima);
// Escrita no LED (saida)
digitalWrite( ledCima, estadoBotao );
}

Figura 10.7: Exemplo apertaApagaSoltaAcende.INO, leitura e es-


crita digital

10.1 Exercícios com botões


Exercício 22. Implemente um código que teste o valor lido do
botão e a seguir incremente e mostre no terminal serial o valor
do contador.
Exercício 23. Implemente um programa que informe via porta
serial o estado lido pelo botão. Dica, use os conhecimentos de
inicialização e escrita na porta serial com o exemplo 10.7
Exercício 24. Visto que o operador de inversão é o sinal de ex-
clamação (!), insira o operador na atribuição de leitura ou es-
crita para que o exemplo apertaApagaSoltaAcende passe
a ser o programa apertaAcendeSoltaApaga, ou seja, o

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 10. ENTRADA DIGITAL BÁSICA 78

LED fica apagado, quando aperta ele acende, quando solta ele
apaga.
Exercício 25. Implemente um código que teste o valor lido do
botão e a seguir incremente e mostre no terminal serial o valor
do contador.
A seguir o exemplo de carregar o comando piscaAzul()
quando o botão é apertado. Observe que independente do tempo
que o botão fica pressionado, a piscada é executada. Após o
tempo da piscada, o loop recomeça e o estado do botão é então
conferido.
// Aperta -> pisca
const int ledCima = A1; // Azul
const int botCima = 4;

void pisca() {
digitalWrite( ledCima , HIGH );
delay(500);
digitalWrite( ledCima , LOW );
//delay(500);
}
void setup() {
pinMode( ledCima, OUTPUT );
pinMode( botCima, INPUT_PULLUP );
}
void loop() {
bool estadoBotao = digitalRead( botCima );
if ( estadoBotao == LOW ) {
pisca();
}
}

Figura 10.8: Exemplo programa apertaPisca.ino

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
Capítulo 11

Entrada pela porta de


comunicação serial

A porta de comunicação serial, a qual fazemos escrita através


do comando Serial.print("mensagem") também pode
ser lida a fim de obter valores enviados pelo Terminal Serial.
A função Serial.read() fornece o valor do caracter mais
antigo na fila de entrada da porta de comunicação serial. A seguir
a sintaxe do comando de leitura serial:

int <valor> = Serial.read();

Figura 11.1: Sintaxe do comando Serial.read()

O parâmetro <valor> deve ser atribuido a uma variável in-


teira (tipo int) ou como parâmetro de outro comando que irá
receber o valor que foi lido na porta serial como parâmetro.

int recebido = Serial.read();

Figura 11.2: Exemplo do comando Serial.read()

79
CAPÍTULO 11. ENTRADA PELA PORTA DE COMUNICAÇÃO SERIAL 80

Para que um valor possa ser lido na porta serial ele precisa ter
sido enviado pelo Terminal Serial (ou programa do tipo) e dessa
forma ser recebido e armazenado na fila de entrada. Logo se faz
necessário verificar se existem caracteres na fila de recepção para
então poder fazer a leitura.

if (Serial.available()) {
int recebido = Serial.read();
}

Figura 11.3: Exemplo de leitura serial Serial.read() com teste da fila


de entrada Serial.available()

A função Serial.available() retorna HIGH se houver


um ou mais caracteres recebidos pela entrada serial.

if (Serial.available()) {
int recebido = Serial.read();
estadoLed = !estadoLed;
digitalWrite( pinLed , estadoLed )
}

Figura 11.4: Exemplo de leitura serial Serial.read() e inversão do Led


a cada caracter recebido através do botão ENVIAR do terminal serial

Implemente funções pisca1(); e pisca2(); que façam


dois diferentes Leds piscarem, então experimente completar o
programa com o exemplo escolheLedSerial.INO.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
81

if ( Serial.available() ) {
int recebido = Serial.read();
if (recebido==’1’) { pisca1(); }
if (recebido==’2’) { pisca2(); }
}

Figura 11.5: Código para piscar o led de acordo com a escolha feita ao enviar
os números 1 e 2 pelo terminal serial

Exercício 26. Implemente um programa que receba os carac-


teres enviados pelo computador e para o número zero apague
todos os leds, e conforme os números de 1 a 4 acenda o led cor-
respondente.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 11. ENTRADA PELA PORTA DE COMUNICAÇÃO SERIAL 82

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
Capítulo 12

Bibliotecas, classes e objetos

Bibliotecas são arquivos contendo códigos prontos para se-


rem utilizados através de comandos que muitas vezes são orien-
tados a objeto, disponibilizando classes (com suas propriedades
e métodos) que implementamos através do uso de objetos que
herdam as propriedades da classe disponível na biblioteca. As-
sim, a classe contém as características do objeto e seus médodos
são seus comandos associados.

12.1 Incluindo uma biblioteca


Para incluir uma biblioteca, basicamente usa-se o comando
#include seguido do nome da biblioteca. A sintaxe é con-
forme mostrada a seguir:

#include <biblioteca>

Se ela fizer parte do pacote de instalação ao compilar o código

83
CAPÍTULO 12. BIBLIOTECAS, CLASSES E OBJETOS 84

ela vai ser reconhecida. Caso seja uma biblioteca externa, a pasta
da biblioteca deve ser copiada dentro da pasta arduino\libraries\.

12.2 Biblioteca softwareSerial


A porta Serial nativa do Arduino é feito através dos pinos
0 e 1. Quando estamos comunicando com o PC é através destes
pinos conectados ao chip (circuito integrado) de conversão se-
rial/usb. Caso o programa não use esses pinos, eles poderiam ser
utilizados para outros propósitos quando o circuito for alimen-
tado com fonte externa.
A biblioteca softwareSerial permite a implementação
de uma segunda porta de comunicação serial, que pode ser usada
para comunicar com outro arduino ou com outros módulos, como
por exemplo blueTooth e modem celular.

12.2.1 Controle remoto por cabo cruzado

// Ler os boto es e enviar pela serial


// receber a serial e ativar os leds
#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3); // RX, TX

Figura 12.1: Inclusão da biblioteca softwareSerial no programa botOutInLed

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
85 12.2. BIBLIOTECA SOFTWARESERIAL

void setup() {
pinMode( pinBotB , INPUT_PULLUP );
pinMode( pinBotC , INPUT_PULLUP );
pinMode( pinBotD , INPUT_PULLUP );
pinMode( pinBotE , INPUT_PULLUP );
pinMode( pinLedB , OUTPUT );
pinMode( pinLedC , OUTPUT );
pinMode( pinLedD , OUTPUT );
pinMode( pinLedE , OUTPUT );
Serial.begin( 9600 );
Serial.println( "Oi");
mySerial.begin(9600);
mySerial.println("OMy!");
}

Figura 12.2: Constantes (botões e LEDs) do programa botOutInLed.ino

long relogioAtual = 0;
long ultimoBot = 0;
long guardaRelogioAcende = 0;

Figura 12.3: Variáveis do programa botOutInLed

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 12. BIBLIOTECAS, CLASSES E OBJETOS 86

void setup() {
pinMode( pinBotB , INPUT_PULLUP );
pinMode( pinBotC , INPUT_PULLUP );
pinMode( pinBotD , INPUT_PULLUP );
pinMode( pinBotE , INPUT_PULLUP );
pinMode( pinLedB , OUTPUT );
pinMode( pinLedC , OUTPUT );
pinMode( pinLedD , OUTPUT );
pinMode( pinLedE , OUTPUT );
Serial.begin( 9600 );
Serial.println( "Oi");
mySerial.begin(9600);
mySerial.println("Oi My!");
}

Figura 12.4: Inicializações do programa botOutInLed.ino

void rodaComando( char com ) {


if ( com == ’O’ ) {
digitalWrite( pinLedB , LOW );
digitalWrite( pinLedC , LOW );
digitalWrite( pinLedD , LOW );
digitalWrite( pinLedE , LOW );
}
if ( com == ’B’ ) {
digitalWrite( pinLedB , HIGH ); }
if ( com == ’C’ ) {
digitalWrite( pinLedC , HIGH ); }
if ( com == ’D’ ) {
digitalWrite( pinLedD , HIGH ); }
if ( com == ’E’ ) {
digitalWrite( pinLedE , HIGH ); }
}

Figura 12.5: Procedimento rodaComando() - botOutInLed.ino.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
87 12.2. BIBLIOTECA SOFTWARESERIAL

void enviar( char c ){


Serial.println( c );
mySerial.println( c );
delay(200);
}

Figura 12.6: Inicializações do programa botOutInLed.ino

void loop() {
bool botB = digitalRead( pinBotB );
if (botB == LOW ) { enviar( ’B’ ); }
bool botC = digitalRead( pinBotC ); }
if (botC == LOW ) { enviar( ’C’ ); }
bool botD = digitalRead( pinBotD ); }
if (botD == LOW ) { enviar( ’D’ ); }
bool botE = digitalRead( pinBotE );
if (botE == LOW ) { enviar( ’E’ ); }

if (mySerial.available() ) {
int c = mySerial.read();
rodaComando( c );
}
if (Serial.available() ) {
int c = Serial.read();
rodaComando( c );
delay(500);
rodaComando( ’O’ );
}
}

Figura 12.7: Bloco principal loop() do programa botOutInLed

12.2.2 Comunicação por BlueTooth com celular


O módulo de BlueTooth HC-06 permite a conexão com o ce-
lular, com PC e até mesmo com outro módulo BlueTooth (HC-

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 12. BIBLIOTECAS, CLASSES E OBJETOS 88

05). Sua comnunicação é serial, podendo ser usado a biblioteca


SoftwareSerial para comunicar com ele. Da mesma forma
que os valores são lidos e enviados pelo computador pelo objeto
nativo Serial, também criando um objeto para criar uma segunda
porta pode ser usado para fazer a comunicação com o módulo
BlueTooth.
Devido seu modo de operação ser de 3.3v, é preciso fazer a
ligação de dois resistores, de 1k e 2k, para acoplar o nível de
tensão conforme a ligação mostrado na figura.

Figura 12.8: Conexão arduino nano com textitBlueTooth HC-06

No Celular, é possível utilizar aplicativos que permitem a lei-


tura e escrita através da porta BlueTooth, que uma vez pareado
com o módulo HC-06, torna-se uma comunicação transparente,
semelhante à comunicação com o Terminal Serial.
O pareamento com o Blue-Tooth deve ser feito pelo próprio
sistema de configuração do smartphone Android, que descobre o

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
89 12.2. BIBLIOTECA SOFTWARESERIAL

dispositivo e uma vez selecionado requer a senha. Para módulos


com as configurações de fábrica, o nome do dispositivo é HC-
06 e a senha padrão é 1234. O pareamento é feito uma única
vez, ficando disponível para efetivar a conexão por um aplicativo
apropriado para comunicação via BlueTooth.
Um app (aplicativo smartphone) sugerido é o BlueSerial, que
lista os dispositivos pareados e permite conectar com aquele es-
colhido.

Figura 12.9: Ícone do APP BlueSerial para Android.

A tela de entrada, na qual aparecem os dispositivos quando


o botão SEARCH FOR PAIRED DEVICES (listar os dispositi-
vos pareados). Quando o dispositivo é escolhido (click), o bo-
tão CONNECT efetiva a conexão caso o módulo esteja ligado,
entrando na tela onde podemos escrever mensagens e enviá-las
com o botão SEND.
Quando conectado, o celular ao módulos, as mensagens es-
critas com o comando SeriaBT.print() são recebidas no
celular e mostradas na janela do app.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 12. BIBLIOTECAS, CLASSES E OBJETOS 90

Figura 12.10: Telas do app BlueSerial para Android.

Exercício 27. Da mesma forma que o programa btOutInLed


funciona a partir da porta USB/Terminal Serial, copie e modifi-
que o programa de forma a existir uma segunda porta: SerialBT
que ao enviar para a porta serial nativa (Serial), também en-
vie pela porta criada através da biblioteca SoftwareSerial,
funcionando da mesma forma, porém ao mesmo tempo com o
smartphone.

12.3 Biblioteca keyboardPS2


O conector de comunicação da placa Genius comporta a liga-
ção com um conector do tipo mini DIN, utilizados nos computa-
dores de mesa - desktops.
A ligação se dá por quatro fios, sendo dois de alimentação do
teclado (+5v e GND) e dois fios de comunicação sincrona, sendo
um clock (CLK lidago ao pino 2) e DATA (DT ligado ao pino 3).

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
91 12.3. BIBLIOTECA KEYBOARDPS2

Tabela 12.1: Tabela da pinagem Din 6 pinos femea para o Arduino Nano e
Uno - &&

Pino Din Pino Arduino Descrição sinal


1 D3 Dado (DT)
2 - Não conectado (NC)
3 GND Referência negativa
4 +5v Alimentação positiva
5 D2 Clock/Sincronismo (CLK)
6 - Não conectado (NC)

Figura 12.11: Conector DIN 6 pinos femea - ordem dos pinos

Existem bibliotecas que implementam a programação dos si-


nais para o teclado de computador (101 teclas). Uma destas bi-
bliotecas é sugerida na página do arduino, no link:
https://playground.arduino.cc/Main/PS2Keyboard/
Após clicar no Link Last Version, baixe o arquivo da biblio-
teca, descompacte-o na pasta Arduino\Libraries.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 12. BIBLIOTECAS, CLASSES E OBJETOS 92

#include <PS2Keyboard.h>

const int DataPin = 2;


const int IRQpin = 3;

PS2Keyboard keyboard;

void setup() {
delay(1000);
keyboard.begin(DataPin, IRQpin);
Serial.begin(9600);
Serial.println("Keyboard Test:");
}

Figura 12.12: Exemplo Simple_Test.INO Keyboard PS2 - Inclusão da


biblioteca, criação do objeto e inicialização

void loop() {
if (keyboard.available()) {
// leitura da tecla
char c = keyboard.read();
Serial.print(c);
}

Figura 12.13: Exemplo Simple_Test.INO Keyboard PS2 - Loop - Leitura


da tecla

12.3.1 Teclado Musical


O projeto do tecladoMusical.ino faz uso da biblioteca keyboardPS2,
associando um tom sonoro (nota musical) a cada uma das teclas
do teclado. Antes do loop criamos o procedimento TOM, cuja
finalidade é reproduzir a nota musical desejada.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
93 12.3. BIBLIOTECA KEYBOARDPS2

const int pAudio = 10;

void tom( int freqNota) {


tone( pAudio , freqNota );
delay(250);
noTone( pAudio);
}

Figura 12.14: Procedimento tom() - dispara nota musical, espera e silencia

A implementação do tecladoMuscial é bastante simples, basta


declarar o procedimento TOM e no loop, após a leitura da tecla,
através do comando char c = keyboard.read(), testar
a variável com cada uma das letras e disparar a nota correspon-
dente.

void loop() {
if (keyboard.available()) {
// le a proxima tecla
char c = keyboard.read();
if ( c == ’a’) { tom( NOTE_C4 ); }
if ( c == ’s’) { tom( NOTE_D4 ); }
if ( c == ’d’) { tom( NOTE_E4 ); }
if ( c == ’f’) { tom( NOTE_F4 ); }
if ( c == ’g’) { tom( NOTE_G4 ); }
if ( c == ’h’) { tom( NOTE_A4 ); }
if ( c == ’j’) { tom( NOTE_B4 ); }
if ( c == ’k’) { tom( NOTE_C5 ); }
if ( c == ’l’) { tom( NOTE_D5 ); }
if ( c == ’;’) { tom( NOTE_E5 ); }
if ( c == ’\”) { tom( NOTE_F5 ); }
if ( c == ’\\’) { tom( NOTE_G5 ); }
}
}

Figura 12.15: Teclado Musical - associando teclas com tons

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 12. BIBLIOTECAS, CLASSES E OBJETOS 94

As notas musicais estão disponíveis através da biblioteca "pit-


ches.h", existente na pasta de exemplo do programa "toneMe-
lody", que deve ser copiado de sua pasta original:
Arduino\Exemplos \toneMelody\pitches.h
para
Documents\Arduino\meuTecladoMusical

#include <PS2Keyboard.h>
#include "pitches.h"

Figura 12.16: Exemplo SimpleTest.INO Inclusão do arquivo de defini-


ções "pitches.h"junto com a biblioteca do Keyboard PS2

Observe que o include do arquivo de definições é com as-


pas duplas, e o arquivo deve estar na mesma pasta o projeto do
arduino, em Documents. A bibliotecla PS2Keyboard.h encontra-
se na pasta Libraries, sendo declarado no include entre menor e
maior <>.
#define NOTE_C4 262
#define NOTE_D4 294
#define NOTE_E4 330
#define NOTE_F4 349
#define NOTE_G4 392
#define NOTE_A4 440
#define NOTE_B4 494
#define NOTE_C5 523
#define NOTE_D5 587
#define NOTE_E5 659
#define NOTE_F5 698
#define NOTE_G5 784
#define NOTE_A5 880
#define NOTE_B5 988

Figura 12.17: Definições usadas do pitches.h

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
95 12.4. SENSOR DE DISTÂNCIA HC-SR04 - BIBLIOTECA ULTRASONIC

12.4 Sensor de Distância HC-SR04 - biblioteca


ultraSonic

Figura 12.18: Ligações do sensor de distância ultrasônico HCSR04

#include <Ultrasonic.h>

#define TRIGGER_PIN 3
#define ECHO_PIN 2

Ultrasonic ultrasonic(TRIGGER_PIN, ECHO_PIN);

Figura 12.19: Declaração do objeto ultrasonic, conexão pinos 3 e 2

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 12. BIBLIOTECAS, CLASSES E OBJETOS 96

void loop() {
long microsec = ultrasonic.timing();
float cmMsec = ultrasonic.convert(
microsec, Ultrasonic::CM);
Serial.print("CM: ");
Serial.println(cmMsec);
delay(300);
}

Figura 12.20: Programa reguaSerial.ino

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
Capítulo 13

Estruturas de Repetição

As estruturas de repetição são mecanismos pelos quais uma


sequência de comandos (bloco) pode repetir por uma quantidade
fixa de vezes ou conforme uma condição.
O bloco do loop é uma repetição dita infinita, pois se repete
enquanto o sistema estiver ligado.
A primeira estrutura de repetição executa os comandos con-
tidos no seu bloco enquanto a condição imposta for verdadeira
(nível lógico 1 bináriot, ou HIGH). A estrutura "enquanto"é im-
plementada pelo comando while.

13.1 Repetição com teste no início


Comando enquanto: while

97
CAPÍTULO 13. ESTRUTURAS DE REPETIÇÃO 98

Figura 13.1: Fluxograma comando enquanto - while

void setup() {
Serial.begin(9600);
int tabuadado = 9;
Serial.print("Tabuada do ");
Serial.println(tabuadado);
int n=0;
while (n<=10) {
Serial.print(tabuadado);
Serial.print("x ");
Serial.print(n);
Serial.print("= ");
Serial.println(tabuadado*n);
n++;
}
}
void loop() {
}

Figura 13.2: Programa tabuadaWhile.ino

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
99 13.2. REPETIÇÃO COM TESTE NO FINAL

13.2 Repetição com teste no final


Comando faça/enquanto: do while

Figura 13.3: Fluxograma comando faça enquanto - do while

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 13. ESTRUTURAS DE REPETIÇÃO 100

void setup() {
Serial.begin(9600);
int tabuadado = 9;
Serial.print("Tabuada do ");
Serial.println(tabuadado);
int n=0;
do {
Serial.print(tabuadado);
Serial.print("x ");
Serial.print(n);
Serial.print("= ");
Serial.println(tabuadado*n);
n++;
} while (n<=10);
}
void loop() { }

Figura 13.4: Exemplo tabuda com estrutura do while

13.3 Repetição com variável de controle


Comando para: for

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
101 13.3. REPETIÇÃO COM VARIÁVEL DE CONTROLE

Figura 13.5: Fluxograma comando faça enquanto - do while

void setup() {
Serial.begin(9600);
int tabuadado = 9;
Serial.print("Tabuada do ");
Serial.println(tabuadado);
for (int n=0;n<=10;n++) {
Serial.print(tabuadado);
Serial.print("x ");
Serial.print(n);
Serial.print("= ");
Serial.println(tabuadado*n);
}
}
void loop() { }

Figura 13.6: Programa tabuada.ino

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 13. ESTRUTURAS DE REPETIÇÃO 102

13.3.1 Exemplo barulho crescente


Usando a função for podemos criar uma repetição que vai
mudando o valor do tom emitido pelo buzzer/autofalante conec-
tado. No programa barulhoFor.ino é mostrado uma apli-
cação contida no comando barulho(), o qual é chamado no
bloco setup(), acontecendo quando o sistema é ligado ou rei-
niciado (botão reset)

#define pinoAudio 10

void barulho() {
int cresce=20;
for (int oTom = 4000; oTom > 3000;
oTom-=cresce) {
// get a sensor reading:
tone(pinoAudio, oTom );
cresce = cresce+10;
delay(cresce);
noTone( pinoAudio );
}
}
void setup() {
pinMode(pinoAudio, OUTPUT);
barulho();
}
void loop() { }

Figura 13.7: Programa barulhoFor - Game lose!

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
Capítulo 14

Conjuntos - variáveis indexadas

Ao trabalharmos com uma série de informações de um mesmo


tipo e não utilizarmos uma grande quantidade de identificado-
res para uma infinidade de diferentes variáveis, podemos utilizar
uma estrutura de variável com várias dimensões.
Uma variável com uma dimensão e múltiplos elementos, é
conhecido como vetor, e uma maneira de ilustrá-lo pode ser visto
na figura a seguir. Cada variável é referenciada pela sua posição
numérica dentro do vetor

Figura 14.1: Conjuntos - variáveis indexadas ou vetores

103
CAPÍTULO 14. CONJUNTOS - VARIÁVEIS INDEXADAS 104

14.1 Implementação de vetores


Um exemplo existente na IDE Arduino, que faz uso de ve-
tores para armazenar as notas de uma música e reproduzi-la no
buzzer é o toneMelody.ino, que está no grupo de exemplos
02.Digital.

#include "pitches.h"

// notes in the melody:


int melody[] = {
NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3,
NOTE_G3, 0, NOTE_B3, NOTE_C4
};

// note durations: 4 = quarter note, 8 =


eighth note, etc.:
int noteDurations[] = {
4, 8, 8, 4, 4, 4, 4, 4
};

Figura 14.2: Variáveis do programa toneMelody.ino

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
105 14.1. IMPLEMENTAÇÃO DE VETORES

void setup() {
// iterate over the notes of the melody:
for (int thisNote = 0; thisNote < 8;
thisNote++) {

// to calculate the note duration, take one


second divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note
= 1000/8, etc.
int noteDuration = 1000 /
noteDurations[thisNote];
tone(8, melody[thisNote], noteDuration);

// to distinguish the notes, set a minimum


time between them.
// the note’s duration + 30% seems to work
well:
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// stop the tone playing:
noTone(8);
}
}

Figura 14.3: Inicialização onde todo o programa toneMelody.ino acontece

Exercício 28. O vetor v é criado e inicializado, conforme a linha


de código a seguir:
int v[5]={ 35 , 25 , 30 , 28, 32};
Crie programas que:
a) Mostre os valores pela porta serial para serem vistos atra-
vés do terminal serial.
b) Mostre apenas o maior deles.
c) Mostre a média desses valores, ou seja, a soma de todos
eles, dividido pela quantidade (igual a 5).

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 14. CONJUNTOS - VARIÁVEIS INDEXADAS 106

Explicação! Suponhamos que os valores listados no exercício


anterior sejam os valores dos produtos comprados no supermer-
cado, mostrar os valores é o procedimento feito para imprimir a
lista. Encontrar o maior deles ou algum deles em específico é
necessário para buscar e manusear algum deles. Calcular o va-
lor médio é uma operação repetitiva para o usuário, mas rápida e
precisa, fácil para o processador!
Exercício 29. Desafio: Implemente um código capaz de colocar
os elementos em ordem crescente, funcionando para quaisquer
valores para o vetor v.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
Capítulo 15

Geração de Números Aleatórios

A geração de números aleatóros, também chamados de randô-


micos, nos fornece um recurso útil e simples implementação de
aplicações dessa natureza, como sorteios, jogos e outras imple-
mentações que serão vistas neste capítulo.
Basicamente o comando que fornece um número inteiro alea-
tório, também chamado de randômico, é o comando random(),
para o qual deve-se passar o valor limite, sendo o maior número
igual ao limite menos 1, ou seja, nunca é retornado o próprio
valor do parâmetro.

15.1 Dado eletrônico


O dado eletrônico tem o mesmo objetivo de um dado conven-
cinal, fornecer a resposta de um sorteio cujo resultado seja um
número de 1 a 6.
A idéia é bastante simples: no loop faz-se a verificação do
estado do botão, que ao ser apertado sorteia um número e in-
forma através da porta serial.
Para visualizar o resultado é preciso estar com o Terminal Se-
rial aberto e apertar o botão de cima (botão C).

107
CAPÍTULO 15. GERAÇÃO DE NÚMEROS ALEATÓRIOS 108

Exercício 30. - Palpiteiro da mega-sena, cada vez que apertar


envia um número de 1 a 60 (loteria) ou de 1 a 99 (mega-sena).
Exercício 31. Cada vez que apertar o botão dispara um tom ale-
atório por 300 milisegundos.

15.2 Bingo
O jogo do bingo é bastante conhecido, os números de 1 a 75
são sorteados. Cada um tem uma cartela com cinco colunas e
cinco linhas. Na primeira coluna (da letra B) somente números
de 1 a 15, na segunda coluna (da letra I) somente números de
16 a 30, na coluna do meio (letra N) números de 31 a 45, na
quarta coluna (da letra G) números de 46 a 60) e na última coluna
(da letra O) números de 61 a 75. Na linha do meio da coluna
do meio não tem número nenhum, geralmente nas cartelas vem
desenhado um coringa. O jeito mais comum de se jogar é ir
sorteando os números até que o vencedor tenha todos os números
de sua cartela sorteados. Pode acontecer da última pedra sorteada
completar duas cartelas difentes. Quando o objetivo é atingido o
jogador de gritar Bingo! antes que a próxima pedra seja sorteada,
então os números da cartela são conferidos com as pedras que
foram sorteadas e confirma o vencedor ou vencedores (o prêmio
é dividido ou uma nova pedra para cada um é sorteado vencendo
que obtiver a maior pedra).

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
109 15.2. BINGO

// vetor dos numeros sorteados


// Ãndices de 0 a 75, 0 não usado
bool num [76];
// Quantidade de numeros sorteados
byte quant = 0;

Figura 15.1: Variáveis do programa bingo.INO

void setup() {
for(int i = 4; i<8; i++) pinMode(i,
INPUT_PULLUP);
Serial.begin(9600);
reinicio();
}

Figura 15.2: Inicialização - setup() do programa bingo.ino

void reinicio (){


// zera o vetor
for (int i=0; i<=75; i++){ num[i]=LOW; }
quant=0;
}

Figura 15.3: Comando reinicio() do programa bingo.ino

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 15. GERAÇÃO DE NÚMEROS ALEATÓRIOS 110

void loop() {
if (digitalRead(5)==LOW){
randomSeed(millis());
if (quant<75) sorteio();
else Serial.println("Todos os números
sorteados");
delay(300);
}
if (digitalRead(6)==LOW){
conferir();
delay(300);
}
if (digitalRead(7)==LOW){ reinicio();}
}

Figura 15.4: Bloco loop() do programa bingo.ino

void conferir (){


for (int i=0; i<=75; i++){
if (num[i] == 1){
Serial.print(i);
Serial.print();
}
if (i==0){ Serial.print("\n B "); }
if (i==15){ Serial.print("\n I "); }
if (i==30){ Serial.print("\n N "); }
if (i==45){ Serial.print("\n G "); }
if (i==60){ Serial.print("\n O "); }
}
Serial.println();
}

Figura 15.5: Comando conferir() do programa bingo.ino

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
Capítulo 16

Jogo Genius - Memória de Gênio

Todos os comandos e conceitos necessários para a implemen-


tação do jogo Genius foram apresentados e estamos prontos para
colocá-los em prática.
Como vocês bem devem saber, no jogo Genius, uma sequen-
cia de LEDS piscam e o jogador deve repetir a sequência aper-
tando as teclas correspondentes. Se a jogada não estiver certa
uma indicação de jogada errada e fim de jogo é apresentada e
o jogo recomeça. Para cada jogada certa, a sequência aumenta,
sendo apresentada ao jogador a nova sequência.
No início do jogo, uma indicação sonora e luminosa de todos
os LEDs apresenta as boas vindas ao jogador. A implementa-
ção do bloco de boas vindas é mostrado a seguir no comando
TocarSomDeInicio().

111
CAPÍTULO 16. JOGO GENIUS - MEMÓRIA DE GÊNIO 112

const int NOTA_RE = 294;


const int NOTA_SOL= 392;
const int NOTA_LA = 440;
const int NOTA_DO = 523;
const int pinosLeds[4] = { A2, A3, A4, A1 };
const int pinosBotoes[4] = { 7, 6, 5, 4 };
const int tons[4] = { NOTA_DO, NOTA_LA,
NOTA_SOL, NOTA_RE };
const int pinoAudio = 10;

Figura 16.1: Constantes usadas no programa genius.ino

byte sequencia[100] = {};


byte rodada_atual = 0;
byte passo_atual_na_sequencia = 0;
byte botao_pressionado = 0;
byte perdeu_o_jogo = false;

Figura 16.2: Variáveis usadas no programa genius.ino

void setup() {
for (int i = 0; i <= 3; i++) {
pinMode(pinosLeds[i], OUTPUT);
pinMode(pinosBotoes[i], INPUT_PULLUP);
}
pinMode(pinoAudio, OUTPUT);
randomSeed(analogRead(0));
Serial.begin(9600);
}

Figura 16.3: Inicialização do programa genius.ino

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
113

void loop() {
if (perdeu_o_jogo) {
perdeu_o_jogo = false;
reiniciaJogo();
}

if (rodada_atual == 0) {
rodaInicio();
delay(500);
}
proximaRodada();
reproduzirSequencia();
aguardarJogador();
}

Figura 16.4: Loop do programa genius.ino

void reiniciaJogo() {
rodada_atual = 0;
passo_atual_na_sequencia = 0;
}

Figura 16.5: Procedimento reiniciaJogo()

void proximaRodada() {
int numero_sorteado = random(0, 4);
sequencia[rodada_atual++] = numero_sorteado;
}

Figura 16.6: Procedimento proximaRodada()

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 16. JOGO GENIUS - MEMÓRIA DE GÊNIO 114

void reproduzirSequencia() {
for (int i = 0; i < rodada_atual; i++) {
tone(pinoAudio, tons[sequencia[i]]);
digitalWrite(pinosLeds[sequencia[i]], HIGH);
delay(500);
noTone(pinoAudio);
digitalWrite(pinosLeds[sequencia[i]], LOW);
delay(100);
}
noTone(pinoAudio);
}

Figura 16.7: Procedimento proximaRodada()

void aguardarJogador() {

for (int i = 0; i < rodada_atual; i++) {


aguardarJogada();
verificarJogada();
if (perdeu_o_jogo) { break; }
passo_atual_na_sequencia++;
}
passo_atual_na_sequencia = 0;
delay(1000);
}

Figura 16.8: procedimento aguardarJogador()

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
115

void aguardarJogada() {
boolean jogada_efetuada = false;
while (!jogada_efetuada) {
for (int i = 0; i <= 3; i++) {
if (digitalRead(pinosBotoes[i]) == LOW) {
botao_pressionado = i;
tone(pinoAudio, tons[i]);
digitalWrite(pinosLeds[i], HIGH);
delay(300);
digitalWrite(pinosLeds[i], LOW);
noTone(pinoAudio);
jogada_efetuada = true;
}
}
delay(10);
}
}

Figura 16.9: Procedimento aguardarJogada()

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 16. JOGO GENIUS - MEMÓRIA DE GÊNIO 116

void verificarJogada() {
if (sequencia[passo_atual_na_sequencia] !=
botao_pressionado) {
for (int i = 0; i <= 3; i++) {
tone(pinoAudio, tons[i]);
digitalWrite(pinosLeds[i], HIGH);
delay(200);
digitalWrite(pinosLeds[i], LOW);
noTone(pinoAudio);
}
tone(pinoAudio, tons[3]);
for (int i = 0; i <= 3; i++) {
digitalWrite(pinosLeds[0], HIGH);
digitalWrite(pinosLeds[1], HIGH);
digitalWrite(pinosLeds[2], HIGH);
digitalWrite(pinosLeds[3], HIGH);
delay(100);
digitalWrite(pinosLeds[0], LOW);
digitalWrite(pinosLeds[1], LOW);
digitalWrite(pinosLeds[2], LOW);
digitalWrite(pinosLeds[3], LOW);
delay(100);
}
noTone(pinoAudio);
perdeu_o_jogo = true;
}
}

Figura 16.10: Procedimento verificaJogada()

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
117

void rodaInicio() {
tone(pinoAudio, tons[0]);
for (int i=0;i<=3;i++) {
digitalWrite(pinosLeds[i], HIGH); }
delay(500);
for (int i=0;i<=3;i++) {
digitalWrite(pinosLeds[i], LOW); }
delay(500);
noTone(pinoAudio);
}

Figura 16.11: Procedimento rodaIniicio()

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 16. JOGO GENIUS - MEMÓRIA DE GÊNIO 118

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
Capítulo 17

Memória não volátil

O sistema Arduino dispõe de espaço de memória que retém os


dados mesmo quando o sistema está sem energia. Assim, entre
uma vez que o sistema é ligado e outra, pode-se gravar e recu-
perar (ler) os dados da memória não volátil, do tipo EEPROM
(memórias que podem ser reescritas eletricamente).
No arduino Nano e Uno a memória EEPROM é composta por
1024 endereços nos quais pode-se gravar um byte, equivalente
a um caracter. Números maiores que um byte precisam ocupar
espaços maiores conforme seu tipo.
Os comandos de acesso a memória são carregados utilizando-
se a biblioteca EEPROM, através da declaração a seguir:

#include <EEPROM.h>

Figura 17.1: Declaração biblioteca EEPROM.h

17.1 Escrita na Memória EEPROM


O processo de escrita na memória é o procedimento EEPROM.write()
cujos parâmetros são o endereço da memória e o valor ser gra-

119
CAPÍTULO 17. MEMÓRIA NÃO VOLÁTIL 120

vado nesse endereço. A seguir a sintaxe do comando de escrita


na memória EEPROM:

EEPROM.write( <endereço>,<valor>);

Figura 17.2: Sintaxe do comando de escrita na memória EEPROM

byte valor=10;
int endereco=0;
EEPROM.write(endereco,valor);

Figura 17.3: Exemplo do comando EEPROM.write() - escrita do valor 10


na posição de memória fixa com endereço 0.

17.2 Leitura da Memória EEPROM

<byte var> = EEPROM.read( <int endereço>);

Figura 17.4: Sintaxe do comando de leitura da memória EEPROM

byte valor = EEPROM.read( 0 );

Figura 17.5: Exemplo do comando EEPROM.read() - leitura do valor da po-


sição de memória fixa com endereço 0.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
121 17.3. EXEMPLO ESCRITA E LEITURA DA MEMÓRIA EEPROM

17.3 Exemplo Escrita e Leitura da Memória EE-


PROM
Um exemplo bastante simples e interessante é a implementa-
ção de um contador de filas que mesmo quando reiniciado (botão
RESET na placa do Arduino ou desligado e religado) não perca
a contagem.
Exercício 32. Implemente um programa onde cada botão acenda
o LED correspondente e que ao religar continue com o último
LED aceso.
Exercício 33. Suponhamos que cada LED corresponda a uma
quantidade escolhida pelo usuário de 1 até 4, que seja necessá-
rio um botão para incrementar a quantidade e outro botão para
decrentar. Quando o programa reiniciar o último valor deverá
ser mostrado pelo LED correspondente.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 17. MEMÓRIA NÃO VOLÁTIL 122

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
Capítulo 18

Contagem de tempo sem atraso

O microcontrolador utilizado no arduino dispõe de um cir-


cuito contador de tempo que fornece um número inteiro longo
com o tempo em milésimos de ssegudos que passou desde que o
sistema foi iniciado. A contagem em milisegundos do sistema é
obtido através da função millis().
O uso do comando delay faz com que o sistema fique ocupado
durante sua execução. A programação através dos milisegundos
permite que ao mesmo tempo que o tempo vai passando e sendo
testado, outros recursos do sistema estão disponíveis, cujo resul-
tado final é que uma tarefa não trave a outra.

18.1 Piscada sem delay


Exemplo blinkwithoutdelay.ino.

123
CAPÍTULO 18. CONTAGEM DE TEMPO SEM ATRASO 124

// Pino do led igual ao da placa (NANO=D13)


const int pinoLed = LED_BUILTIN;
// intervalo para contagem de tempo
const long intervalo = 1000;
// usado para ativar o LED
int estadoLed = LOW;
// para guardar o tempo da última acao
unsigned long tempoUltimaAcao = 0;

void setup() {
// set the digital pin as output:
pinMode(pinoLed, OUTPUT);
}

Figura 18.1: Programa piscaComMillis.ino - constantes, variáveis e


bloco de inicialização.

void loop() {
unsigned long tempoAtual = millis();

if (tempoAtual - tempoUltimaAcao >= intervalo)


{
// gravar o ultimo relogio
tempoUltimaAcao = tempoAtual;
// inverte o estado do led
if (estadoLed == LOW) {
estadoLed = HIGH;
} else {
estadoLed = LOW;
}
// Atualizar o nivel na saida
digitalWrite(pinoLed, ledState);
}
}

Figura 18.2: Programa piscaComMillis.ino - bloco principal.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
125 18.2. LATÊNCIA E SERIAL SIMULTÂNEO

18.2 Latência e Serial simultâneo


Um programa que usa o comando delay fica ocupado du-
rante o tempo de espera. Com o uso do millis isso pode ser
resolvido, fazendo o teste da contagem de tempo no loop, o
qual deixa o sistema livre para processar simultaneamente outros
comandos. Um exemplo disso é o desafio proposto no exercício
a seguir.
Exercício 34. Implemente um programa que faça o led da placa
(D13) piscar com intervalo de 2 segundos, enquanto a porta se-
rial é verificada e conforme sejam recebidos os caracteres de 1
a 4, cada um dos leds correspondentes acendam, e que todos
apaguem com o caracter 0.

18.3 Técnica antiruído Debboucing


O acionamento de botões mecânicos, como são as teclas, com-
postas por contatos metálicos estão sujeitos à um estado transi-
tório ao apertar e soltar um botão que pode ser visualizado con-
forme a figura.

// Pinos usados
const int buttonPin = 2;
const int ledPin = 13;

Figura 18.3: Constantes debounce.ino

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 18. CONTAGEM DE TEMPO SEM ATRASO 126

// the current state of the output pin


int ledState = HIGH;
// the current reading from the input pin
int buttonState;
// the previous reading from the input pin
int lastButtonState = LOW;
// the last time the output pin was toggled
unsigned long lastDebounceTime = 0;
// the debounce time;
unsigned long debounceDelay = 50;

Figura 18.4: Variáveis do exemplo debounce.ino

void setup() {
pinMode(buttonPin, INPUT);
pinMode(ledPin, OUTPUT);

// set initial LED state


digitalWrite(ledPin, ledState);
}

Figura 18.5: Inicialização Debounce.ino

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
127 18.3. TÉCNICA ANTIRUÍDO DEBBOUCING

void loop() {
// read the state of the switch into a local
variable:
int reading = digitalRead(buttonPin);
// check to see if you just pressed the button
// If the switch changed, due to noise or
pressing:
if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) >
debounceDelay) {
// if the button state has changed:
if (reading != buttonState) {
buttonState = reading;

// only toggle the LED if the new button


state is HIGH
if (buttonState == HIGH) {
ledState = !ledState;
}
}
}

// set the LED:


digitalWrite(ledPin, ledState);

// save the reading. Next time through the


loop, it’ll be the lastButtonState:
lastButtonState = reading;
}

Figura 18.6: Laço principal do exemplo debounce.ino

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 18. CONTAGEM DE TEMPO SEM ATRASO 128

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
Capítulo 19

Saída Analógica por PWM

As saídas PWM são responsáveis por entregar níveis interme-


diários de energia elétrica entre o 0v (LOW) e o 5v (HIGH). Este
resultando é obtido através da relação entre tempos em HIGH e
LOW que na prática faz com que uma porcentagem entre 0% e
100% da tensão nominal de 5v seja entregue à carga ligada no
respectivo pino PWM. Tabela de portas que suportam PWM

Figura 19.1: Formas de onda com modulação de pulso (PWM) conforme os


ciclos de trabalho (duty cycle)

129
CAPÍTULO 19. SAÍDA ANALÓGICA POR PWM 130

Veja o exemplo fading.ino, do grupo de exemplos 03.Ana-


log. Altere o valor conforme o pino no qual o led estiver conec-
tado. No kit GENIUS ele é ligado ao pino D3. Faça a alteração,
faça a compilação e gravação. Veja o resultado e observe que as
repetições nas estruturas for acontecem em intervalos de 5.

int led = 3;
// pinos PWM 3,5,6, 9, 10, 11

Figura 19.2: Programa fading.ino

void loop() {
// fade in from min to max in increments of 5
for (int fadeValue = 0 ; fadeValue <= 255;
fadeValue += 5) {
// sets the value (range from 0 to 255):
analogWrite(ledPin, fadeValue);
// wait for 30 milliseconds to see
delay(30);
}
// fade out from max to min in increments of 5
for (int fadeValue = 255 ; fadeValue >= 0;
fadeValue -= 5) {
// sets the value (range from 0 to 255):
analogWrite(ledPin, fadeValue);
// wait for 30 milliseconds to see
delay(30);
}
}

Figura 19.3: Laço principal do prrograma fading.ino

Devido a resolução das saídas analógicas serem de 8 bits, a


faixa de valores compreendidos é de 0 a 255, sendo estes os va-
lores mínimos e máximos.]

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
131 19.1. PROGRAMA CHAMA DA VELA

19.1 Programa chama da vela


Um programa bastante interessante que tem por base o fading.ino
é a simulação da luz de uma vela, que tem tempos e picos máxi-
mos e mínimos aleatórios .
// pinos PWM 3, 5, 6, 9, 10, 11
const int ledPin = 3;
int tempomax=25;
int tempo=0;
int amplitudemax=255;
int amplitudemin=0;

void setup() {
// nothing happens in setup
}

Figura 19.4: Variáveis e inicialização vela.ino

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 19. SAÍDA ANALÓGICA POR PWM 132

void loop() {
tempo = random( tempomax );
amplitudemax= 150 + random(100);
// fade in from min to max in increments of 5
for (int fadeValue = amplitudemin ; fadeValue
<= amplitudemax; fadeValue += 5) {
// sets the value (range from 0 to 255):
analogWrite(ledPin, fadeValue);
// wait for 30 milliseconds to see
delay(tempo);
}
tempo = random(tempomax);
amplitudemin= random(100);
// terminou
// fade out from max to min in increments of 5
for (int fadeValue = amplitudemax ; fadeValue
>= amplitudemin; fadeValue -= 5) {
// sets the value (range from 0 to 255):
analogWrite(ledPin, fadeValue);
// wait for 30 milliseconds to see
delay(tempo);
}
}

Figura 19.5: Laço principal vela.ino

19.2 Servo motor robótico


Um servo motor robótico é um tipo de motor que controla
a posição do eixo conforme o valor PWM usado para controlá-
lo. Assim, podemos ligar diretamente as saídas PWM em servo
motores robóticos.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
133 19.2. SERVO MOTOR ROBÓTICO

Figura 19.6: Ligação Servo Motor

O sinal que controla o servo motor é um tipo PWM (modula-


ção em largura de pulso) com as características do sinal apresen-
tado a seguir.

Figura 19.7: Sinal de controle da posição do servo motor

O controle acontece variando a largura do pulso em até 2ms,


ou sejam, para posições inferiores a máxima, a largura de pulso
deve ser menor que 2ms, em uma frequência de 50 Hz. Ou seja,
períodos de 20 ms.
Para nossa comodidade, existe uma biblioteca que implementa
a forma de onda para controle do servo motor.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 19. SAÍDA ANALÓGICA POR PWM 134

#include <Servo.h>

Figura 19.8: Inclusão da biblioteca servo.h

Servo myservo;
// create servo object to control a servo

Figura 19.9: Declaração do objeto myservo

void setup() {
myservo.attach(2); // attaches the servo on
pin 2 to the servo object
}

Figura 19.10: Inicialização do objeto myservo - associação com o pino fí-


sico.

int pos = 0;
// variable to store the servo position

Figura 19.11: Declaração de variável pos para manipular a posição do servo


motor

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
135 19.2. SERVO MOTOR ROBÓTICO

void loop() {
// goes from 0 degrees to 180 degrees
for (pos = 0; pos <= 180; pos += 1) {
// in steps of 1 degree
myservo.write(pos);
delay(15);
}
for (pos = 180; pos >= 0; pos -= 1)
myservo.write(pos);
delay(15);
}
}

Figura 19.12: Laço principal do exemplo sweep.ino

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 19. SAÍDA ANALÓGICA POR PWM 136

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
Capítulo 20

Entrada Analógica

As entradas analógicas (de A0 a A7) fornecem a leitura de va-


lores de tensão entre 0v e 5v, fornecendo como resposta valores
entre 0 e 1023 (resolução 10 bits).

Figura 20.1: Gráfico Conversor AD 10 bits - tensão analógica X valor digital


entregue pela função de leitura

Um dispositivo muito utilizado é uma resistência variável,


chamada de potenciômetro, mostrado na figura.

137
CAPÍTULO 20. ENTRADA ANALÓGICA 138

Figura 20.2: Potenciômetro comum rotativo: foto (à esquerda) e simbologia


(à direita)

Na figura a seguir temos o desenho com as dimensões mecâ-


nicas do potenciômetro exemplificado na foto.

Figura 20.3: Desenho das dimensões de um potenciômetro comum

Para cada modelo de potenciômetro é possível encontrar suas


dimensões em seu manual.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
139

Figura 20.4: Ligação do potenciômetro

Assim, conforme a figura 193, o pino central do potenciôme-


tro deve ser ligado à entrada analógica A0 ou A7 conforme a
montagem ou a placa Genius. Os pinos de extremidade devem
ser ligados em 0v e +5v. Isso resulta em um diversor de tensão
onde a soma das resistências é igual total do potenciômetro.

Figura 20.5: Potenciometro - simbologia (esquerda), circuito equivalente


(centro) e ligações (direita)

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 20. ENTRADA ANALÓGICA 140

Para não gerar perda de corrente, não use valores menores que
1KΩ (um quilo ohms ou mil ohms). São valores ideais a partir
de 10k. São exemplos também, de valores que podem ser usados
50kΩ, 100kΩ, 470kΩ, 1M Ω.

20.1 Leitura Analógica para Porta Serial


A entrada analógica pode ser verificada através do exemplo
analogSerial.ino. É o primeiro exemplo do grupo de exem-
plos 01.Basic.

const int pinoAD = A7;

void setup() {
// incicializando a comunicacao
//taxa 9600 bps
Serial.begin(9600);
}

Figura 20.6: Programa analogSerial.ino - pino da entrada analógica e


bloco de inicialização.

void loop() {
// faz a leitura da entrada analogica
int valorAD = analogRead(pinoAD);
Serial.print("Leitura: ");
Serial.println(valorAD);
delay(200); // aguarda p proxima
}

Figura 20.7: Laço principal do programa analogSerial.ino.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
20.2. CONTROLANDO A INTENSIDADE DE UM LED COM O
141 POTENCIOMETRO

20.2 Controlando a intensidade de um LED com


o potenciometro

const int analogInPin = A0; // Analog input pin


that the potentiometer is attached to
const int analogOutPin = 9; // Analog output
pin that the LED is attached to

Figura 20.8: constantes

int sensorValue = 0; // value read from the


pot
int outputValue = 0; // value output to the
PWM (analog out)

Figura 20.9: Variaveis

void setup() {
// initialize serial communications at 9600
bps:
Serial.begin(9600);
}

Figura 20.10: Inicialização

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 20. ENTRADA ANALÓGICA 142

void loop() {
// read the analog in value:
sensorValue = analogRead(analogInPin);
// map it to the range of the analog out:
outputValue = map(sensorValue, 0, 1023, 0,
255);
// change the analog out value:
analogWrite(analogOutPin, outputValue);

// print the results to the Serial Monitor:


Serial.print("sensor = ");
Serial.print(sensorValue);
Serial.print("output = ");
Serial.println(outputValue);
delay(2);
}

Figura 20.11: Laço principal do exemplo analogInOutSerial.ino

Exercício 35. Sabendo que o pino conectatdo ao BUZZER é o


D10, e conforme a entrada analógica conectado o potenciôme-
tro, implemente e teste um programa que controla a freqüência
do tom gerado pelo buzzer a partir do valor lido correspondente
à posição do potenciometro.

20.3 Controlando o servo motor com o potencio-


metro
O controle do servo motor, a partir da posição de comando
lido do potênciômetro, é um típico caso de leitura > processa-
mento > saída, idéia básica proposta pelo cientista Von Neuman.
A leitura da entrada analógica, correspondente à posição do po-
tenciômetro, fornece um valor entre 0 e 1023 (conversor AD 10
bits, explicado no começo deste capítulo). O valor que controla

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
143 20.3. CONTROLANDO O SERVO MOTOR COM O POTENCIOMETRO

a posição do servo motor entre 0 e 180 graus, então faz-se uso


do comando map(), responsável por fornecer um valor propor-
cional na saída a partir do valor lido na entrada.
No grupo de exemplos servo, o exemplo knob.ino é a
implementação dessa proposta. A seguir a versão traduzida, en-
titulada potServo.ino.

#include <Servo.h>

// criar objeto para controle do servo


Servo meuServo;

// Pino analogico = potenciometro


int pinoPot = 0;
// variavel para leitura = valor
int val;

Figura 20.12: Exemplo potServo.ino - declarações de biblioteca, objeto

void setup() {
// define o pino do servo
meuServo.attach(9);
}

Figura 20.13: Exemplo potServo.ino - inicialização do pino ligado ao


servo motor

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 20. ENTRADA ANALÓGICA 144

void loop() {
// leitura do valor do potenciometro
// (valores entre 0 e 1023)
val = analogRead(pinoPot);
// Conversao para o servo (value between 0 and
180)
val = map(val, 0, 1023, 0, 180);
// controlando a posicao do servo
myservo.write(val);
// espera proximo ciclo
delay(15);
}

Figura 20.14: Exemplo potServo.ino - laço principal: leitura analógica,


conversão, escrita PWM servo, espera.

20.4 Sensor de luz

Figura 20.15: Ligação do potenciômetro

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
145 20.5. SENSOR DE TEMPERATURA

20.5 Sensor de temperatura


O componente LM35 tem o mesmo acabamento (encapsula-
mento) de um transístor comum de uso geral (código TO-92),
diferindo visualmente apenas pela inscrição

Figura 20.16: Vista do sensor de temperatura LM35

Figura 20.17: Ligação do sensor de temperatura LM35

A resolução do sensor de temperatura LM35 é de 10mV para


cada grau Celcius. O degrau de variação perceptível pelo con-
versor AD de 10 bits será:
∆AD = 5/1023(V ) → ∆AD ∼ = 5.10−3 → ∆AD ∼ = 5mV

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 20. ENTRADA ANALÓGICA 146

Conforme as informações no manual do sensor de tempera-


tura LM35, cada variação de 10mv corresponde a um grau Cel-
cius. Assim, a cada grau o conversor conta 2 intervalos ∆A D (5
mv). Conclui-se então que é necessário dividir o valor por 2 e
encontrar a temperatura final a ser mostrada.

// Pino analógico = sensor LM35


const int pinoSensor = A7;

// valor lido
int val = 0;

Figura 20.18: Exemplo termometroSerial.ino - constante para o pino


e variável para leitura

void setup() {
// Liga porta S erial
Serial.begin(9600);
}

Figura 20.19: Exemplo termometroSerial.ino - inicialização da porta S erial

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
147 20.5. SENSOR DE TEMPERATURA

void loop() {
// leitura da entrada analogica
val = analogRead(pinoSensor);
// converte cada 2 x 5mv = 1 grau
temperatura = map(sensorValue,0,1023,0,511);

// envio pela porta serial


Serial.print("Temperatura: ");
Serial.println(temperatura);

// espera
delay(500);
}

Figura 20.20: Exemplo termometroSerial.ino - laço pricipal

Exercício 36. O projeto da programação do controle de uma


chocadeira de ovos compreende a aquisição da temperatura e o
acionamento de lâmpadas incandescentes para o aquecimento e
um ventilador de comnputador (cooler) para retirar o calor.
O sistema deve ligar a lâmpada quando a temperatura esti-
ver abaixo de um mínimo, e desligar quando estiver acima de um
máximo. Este tipo de técnica é conhecida como controle por es-
terese. Implemente o programa capaz de controlar a saída (pode
simular através de um dos LEDS, ou ligar através do conector
COM (pinos 2 e 3) um módulo de potência com rele para aci-
onar uma carga em tensão alternada). Sempre é bom lembrar
que ligações em corrente alternada 110v/220v são passíveis de
choques e precisam de um conhecimento técnico compatível. Ex-
perimente primeiro ligar cargas 12v que não representam perigo
de choque.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
CAPÍTULO 20. ENTRADA ANALÓGICA 148

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
Apêndice A

Como Baixar e Instalar a Interface


Arduino

Após baixar o arquivo, que no caso do Windows pode ser


através de instalador ou em arquivo compactado.
Na versão compactada, um único arquivo é baixado e deve
ser descompactado na pasta a ser escolhida a vontade. Um passo
a passo para a instalação em cada opção (instalador ou arquivo
compactado) para cada sistema operacional é mostrado no Apên-
dice 2, no final deste material.
Após o primeiro passo (instalação da ferramenta Arduino)
que permite carregar exemplos e scketchs anteriores, o passo se-
guinte é configurar o drive de comunicação que permitirá trans-
ferir o programa para o microcontrolador após sua compilação.
Para que o computador reconheça a sua placa arduina ligada
à porta USB é preciso instalar o drive (programa que configura o
sistema operacional para reconhecer as funcionalidades da porta
de comunicação usada para transferir os dados do PC para a
placa microcontrolada). O drive varia conforme o modelo da
sua placa Arduino. Os drives mais comuns são além do nativo
do arduino UNO e MEGA, o drive CH340 e o drive FTDI.
Os drivers originais e o FTDI estão disponíveis na pasta onde

149
APÊNDICE A. COMO BAIXAR E INSTALAR A INTERFACE ARDUINO150

o aplicativo IDE do Arduino foi instalado ou descompactado.


Execute o arquivo ftdi.exe para instalar o drive FTDI. Para o
drive original UNO e MEGA, execute o arquivo arduino.msi,para
baixar o drive CH340, bem como a instalação nos diferentes sis-
temas operacionais: Windows, Linux e MacOS.

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
Lista de Figuras

1.1 Esquerda: placa Genius.ino com Arduino Nano.


Direita: Diagrama com os elementos da placa
Genius . . . . . . . . . . . . . . . . . . . . . . . 2
1.2 Nosso mascote Robot.ino . . . . . . . . . . . . . 4
1.3 Diagrama de um computador básico - Placa Mãe 5
1.4 Diagrama dos blocos do sistema . . . . . . . . . 6
2.1 Placa Mãe (PC) e Arduino Uno . . . . . . . . . . 7
2.2 Esquema de ligação PC-Arduino . . . . . . . . . 8
2.3 Arduinos Uno e Nano . . . . . . . . . . . . . . . 8
2.4 Compilador - Conversão do programa (código
texto - alto nível) para o arquivo de máquina (bi-
nário - baixo nível) . . . . . . . . . . . . . . . . 9
2.5 Processo completo de compilação e gravação do
programgra alto-nível à gravação do código de
máquina na placa Arduino. . . . . . . . . . . . . 10
2.6 Janela da interface de desenvolvimento e edição
Arduino - Interface Development Engenie - IDE . 11
2.7 Tela com o caminho para carregar o programa
Blink.ino - Arquivo>Exemplos>01.Basics>Blink 13
2.8 Carregando o código do exemplo Blink . . . . . 14
2.9 Configurando a porta de comunicação serial . . . 15
2.10 Exemplo blink.ino . . . . . . . . . . . . . . . . . 16

151
LISTA DE FIGURAS 152

3.1 Fluxograma de um programa básico. . . . . . . . 17


3.2 Novo sketch, blocos básicos . . . . . . . . . . . 18
3.3 Código de um programa com os blocos básicos
setup e loop. . . . . . . . . . . . . . . . . . . 18
3.4 Programa Blink.ino - Exemplos Arduino Basic . 19
3.5 Sintaxe do comando pinMode, configurando o
LED_BULTIN (LED padrão) para OUTPUT (saída). 20
3.6 Exemplo de ligação de um LED ao arduino UNO 21
3.7 Sintaxe comando digitalWrite . . . . . . . 22
3.8 Programa Blink.ino sem comentários . . . . 23
3.9 Fluxograma do programa BLINK.INO compa-
rado com o fluxograma dos blocos básico . . . . 24
4.1 Esquema de ligação dos LEDS ao Arduino UNO 28
4.2 Sintaxe do comando pinMode . . . . . . . . . . 29
4.3 Exemplo do comando pinMode para configurar
a porta digital D4 como saída . . . . . . . . . . . 29
4.4 Exemplo do comando pinMode para configurar
a porta A1 como saída digital . . . . . . . . . . . 29
4.5 Sintaxe do comando de escrita digitalWrite 30
4.6 History board do exemplo piscaAzul.ino . . 31
4.7 Código do programa piscaAzul.ino - LED
A1 . . . . . . . . . . . . . . . . . . . . . . . . . 32
4.8 Quadro de histórico - piscaAntiHorario.ino 33
4.9 Quadro de histórico piscaEnche.ino . . . . 33
4.10 Quadro de histórico piscaDuploHorario.ino 33
4.11 Quadro de histórico piscaAcendeTudoApagaTudo.ino 34
5.1 Exemplo alarme.ino . . . . . . . . . . . . . . . . 39
5.2 Quadro de histórico contendo as fases dos indi-
cadores luminosos . . . . . . . . . . . . . . . . . 39

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
153 LISTA DE FIGURAS

5.3 Quadro de histórico contendo as fases dos indi-


cadores luminosos . . . . . . . . . . . . . . . . . 40
6.1 ola.ino . . . . . . . . . . . . . . . . . . . . . . . 42
6.2 Exemplo SerialOi.ino . . . . . . . . . . . . . . . 42
6.3 Exemplo SerialOiMais.ino . . . . . . . . . . . . 43
7.1 Código de declaração de Constantes para saídas
com define . . . . . . . . . . . . . . . . . . . 49
7.2 Código de declaração de Constantes para saídas
com const . . . . . . . . . . . . . . . . . . . . 49
7.3 Ilustração da analogia de variáveis e uma caixa . 50
7.4 Código exemplo contador.INO . . . . . . . . 51
7.5 Bloco de código do comando pisca1() . . . . 52
7.6 Exemplo completo piscaInicio.ino . . . . 53
8.1 Exemplo Operador de Adição e operandos . . . . 55
8.2 Exemplo soma.ino . . . . . . . . . . . . . . . 56
9.1 Fluxograma comando se - if . . . . . . . . . . . 60
9.2 Exemplo ifIdade.ino . . . . . . . . . . . . . . . 61
9.3 Fluxograma comando se - if . . . . . . . . . . . 62
9.4 Sintaxe do comando condicional composto (if else) 62
9.5 Exemplo ifIdadeElse.ino - estrutura con-
dicional composta. . . . . . . . . . . . . . . . . 63
9.6 Fluxograma comando se - if else if . . . . 64
9.7 Sintaxe estrutura condicional encadeada if else
if . . . . . . . . . . . . . . . . . . . . . . . . . 65
9.8 Programa ifIdadeElseIf.ino - exemplo es-
trutura condicional encadeada . . . . . . . . . . 66
9.9 Fluxograma comando se - if elseif . . . . . 67
9.10 Programa ifIdadeElseIfElse.ino - exem-
plo estrutura condicional encadeada com else. . . 69

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
LISTA DE FIGURAS 154

9.11 Exemplo switchCase.ino, parte 1 . . . . . . 70


9.12 Exemplo switch.ino, parte 2 . . . . . . . . . . . 71
10.1 Ligações de botões com resistor de PULL-UP
(esquerda) e PULL-DOWN (direita) . . . . . . . 74
10.2 Conexão arduino UNO com botões, ligações PULL-
UP (esquerda) e PULL-DOWN (direita) . . . . . 74
10.3 Conexão arduino UNO com 4 botões modo PULL-
UP . . . . . . . . . . . . . . . . . . . . . . . . . 75
10.4 Declarando constantes com define . . . . . . . . 75
10.5 Declarando constantes com const . . . . . . . . . 76
10.6 Sintaxe do comando de leitura digitalRead . 76
10.7 Exemplo apertaApagaSoltaAcende.INO,
leitura e escrita digital . . . . . . . . . . . . . . . 77
10.8 Exemplo programa apertaPisca.ino . . . . 78
11.1 Sintaxe do comando Serial.read() . . . . . 79
11.2 Exemplo do comando Serial.read() . . . . 79
11.3 Exemplo de leitura serial Serial.read() com
teste da fila de entrada Serial.available() 80
11.4 Exemplo de leitura serial Serial.read() e
inversão do Led a cada caracter recebido através
do botão ENVIAR do terminal serial . . . . . . . 80
11.5 Código para piscar o led de acordo com a escolha
feita ao enviar os números 1 e 2 pelo terminal serial 81
12.1 Inclusão da biblioteca softwareSerial no programa
botOutInLed . . . . . . . . . . . . . . . . . . . . 84
12.2 Constantes (botões e LEDs) do programa botOutInLed.ino 85
12.3 Variáveis do programa botOutInLed . . . . . 85
12.4 Inicializações do programa botOutInLed.ino 86
12.5 Procedimento rodaComando() - botOutInLed.ino. 86

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
155 LISTA DE FIGURAS

12.6 Inicializações do programa botOutInLed.ino 87


12.7 Bloco principal loop() do programa botOutInLed 87
12.8 Conexão arduino nano com textitBlueTooth HC-06 88
12.9 Ícone do APP BlueSerial para Android. . . . . . 89
12.10Telas do app BlueSerial para Android. . . . . . . 90
12.11Conector DIN 6 pinos femea - ordem dos pinos . 91
12.12Exemplo Simple_Test.INO Keyboard PS2 -
Inclusão da biblioteca, criação do objeto e inici-
alização . . . . . . . . . . . . . . . . . . . . . . 92
12.13Exemplo Simple_Test.INO Keyboard PS2 -
Loop - Leitura da tecla . . . . . . . . . . . . . . 92
12.14Procedimento tom() - dispara nota musical, es-
pera e silencia . . . . . . . . . . . . . . . . . . . 93
12.15Teclado Musical - associando teclas com tons . . 93
12.16Exemplo SimpleTest.INO Inclusão do arquivo
de definições "pitches.h"junto com a biblioteca
do Keyboard PS2 . . . . . . . . . . . . . . . . . 94
12.17Definições usadas do pitches.h . . . . . . . . 94
12.18Ligações do sensor de distância ultrasônico HCSR04 95
12.19Declaração do objeto ultrasonic, conexão pinos
3 e 2 . . . . . . . . . . . . . . . . . . . . . . . . 95
12.20Programa reguaSerial.ino . . . . . . . . . 96
13.1 Fluxograma comando enquanto - while . . . . 98
13.2 Programa tabuadaWhile.ino . . . . . . . . 98
13.3 Fluxograma comando faça enquanto - do while 99
13.4 Exemplo tabuda com estrutura do while . . . . . 100
13.5 Fluxograma comando faça enquanto - do while 101
13.6 Programa tabuada.ino . . . . . . . . . . . . . . . 101
13.7 Programa barulhoFor - Game lose! . . . . . . 102
14.1 Conjuntos - variáveis indexadas ou vetores . . . . 103

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
LISTA DE FIGURAS 156

14.2 Variáveis do programa toneMelody.ino . . . . . . 104


14.3 Inicialização onde todo o programa toneMelody.ino
acontece . . . . . . . . . . . . . . . . . . . . . . 105
15.1 Variáveis do programa bingo.INO . . . . . . . 109
15.2 Inicialização - setup() do programa bingo.ino109
15.3 Comando reinicio() do programa bingo.ino109
15.4 Bloco loop() do programa bingo.ino . . . 110
15.5 Comando conferir() do programa bingo.ino110
16.1 Constantes usadas no programa genius.ino . 112
16.2 Variáveis usadas no programa genius.ino . . 112
16.3 Inicialização do programa genius.ino . . . . 112
16.4 Loop do programa genius.ino . . . . . . . . 113
16.5 Procedimento reiniciaJogo() . . . . . . . 113
16.6 Procedimento proximaRodada() . . . . . . . 113
16.7 Procedimento proximaRodada() . . . . . . . 114
16.8 procedimento aguardarJogador() . . . . . . . . . 114
16.9 Procedimento aguardarJogada() . . . . . . 115
16.10Procedimento verificaJogada() . . . . . . 116
16.11Procedimento rodaIniicio() . . . . . . . . 117
17.1 Declaração biblioteca EEPROM.h . . . . . . . . 119
17.2 Sintaxe do comando de escrita na memória EE-
PROM . . . . . . . . . . . . . . . . . . . . . . . 120
17.3 Exemplo do comando EEPROM.write() - es-
crita do valor 10 na posição de memória fixa com
endereço 0. . . . . . . . . . . . . . . . . . . . . 120
17.4 Sintaxe do comando de leitura da memória EE-
PROM . . . . . . . . . . . . . . . . . . . . . . . 120

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
157 LISTA DE FIGURAS

17.5 Exemplo do comando EEPROM.read() - leitura


do valor da posição de memória fixa com ende-
reço 0. . . . . . . . . . . . . . . . . . . . . . . . 120
18.1 Programa piscaComMillis.ino - constan-
tes, variáveis e bloco de inicialização. . . . . . . 124
18.2 Programa piscaComMillis.ino - bloco prin-
cipal. . . . . . . . . . . . . . . . . . . . . . . . . 124
18.3 Constantes debounce.ino . . . . . . . . . . . 125
18.4 Variáveis do exemplo debounce.ino . . . . . 126
18.5 Inicialização Debounce.ino . . . . . . . . . . . . 126
18.6 Laço principal do exemplo debounce.ino . . 127
19.1 Formas de onda com modulação de pulso (PWM)
conforme os ciclos de trabalho (duty cycle) . . . 129
19.2 Programa fading.ino . . . . . . . . . . . . . 130
19.3 Laço principal do prrograma fading.ino . . . 130
19.4 Variáveis e inicialização vela.ino . . . . . . . 131
19.5 Laço principal vela.ino . . . . . . . . . . . . 132
19.6 Ligação Servo Motor . . . . . . . . . . . . . . . 133
19.7 Sinal de controle da posição do servo motor . . . 133
19.8 Inclusão da biblioteca servo.h . . . . . . . . . 134
19.9 Declaração do objeto myservo . . . . . . . . . 134
19.10Inicialização do objeto myservo - associação
com o pino físico. . . . . . . . . . . . . . . . . . 134
19.11Declaração de variável pos para manipular a po-
sição do servo motor . . . . . . . . . . . . . . . 134
19.12Laço principal do exemplo sweep.ino . . . . . 135
20.1 Gráfico Conversor AD 10 bits - tensão analógica
X valor digital entregue pela função de leitura . . 137

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta
LISTA DE FIGURAS 158

20.2 Potenciômetro comum rotativo: foto (à esquerda)


e simbologia (à direita) . . . . . . . . . . . . . . 138
20.3 Desenho das dimensões de um potenciômetro co-
mum . . . . . . . . . . . . . . . . . . . . . . . . 138
20.4 Ligação do potenciômetro . . . . . . . . . . . . 139
20.5 Potenciometro - simbologia (esquerda), circuito
equivalente (centro) e ligações (direita) . . . . . . 139
20.6 Programa analogSerial.ino - pino da en-
trada analógica e bloco de inicialização. . . . . . 140
20.7 Laço principal do programa analogSerial.ino.140
20.8 constantes . . . . . . . . . . . . . . . . . . . . . 141
20.9 Variaveis . . . . . . . . . . . . . . . . . . . . . . 141
20.10Inicialização . . . . . . . . . . . . . . . . . . . . 141
20.11Laço principal do exemplo analogInOutSerial.ino 142
20.12Exemplo potServo.ino - declarações de bi-
blioteca, objeto . . . . . . . . . . . . . . . . . . 143
20.13Exemplo potServo.ino - inicialização do pino
ligado ao servo motor . . . . . . . . . . . . . . . 143
20.14Exemplo potServo.ino - laço principal: lei-
tura analógica, conversão, escrita PWM servo,
espera. . . . . . . . . . . . . . . . . . . . . . . . 144
20.15Ligação do potenciômetro . . . . . . . . . . . . 144
20.16Vista do sensor de temperatura LM35 . . . . . . 145
20.17Ligação do sensor de temperatura LM35 . . . . . 145
20.18Exemplo termometroSerial.ino - cons-
tante para o pino e variável para leitura . . . . . . 146
20.19Exemplo termometroSerial.ino - inicialização da
porta S erial . . . . . . . . . . . . . . . . . . . . 146
20.20Exemplo termometroSerial.ino - laço pri-
cipal . . . . . . . . . . . . . . . . . . . . . . . . 147

Lógica e Programação para gds & pqns { Alan, Cauan, Luan } Marotta

Você também pode gostar