100% acharam este documento útil (1 voto)
98 visualizações159 páginas

Apostila Arduino

Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
100% acharam este documento útil (1 voto)
98 visualizações159 páginas

Apostila Arduino

Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd

R ESUMO DE A RDUINO, C ÓDIGOS ,

S ENSORES E ATUADORES

R OBERTO C AMPOS DOS R EIS J UNIOR

P ROF.D R . L EOPOLDO P ISANELLI R ODRIGUES DE O LIVEIRA

APOIO:

S ÃO C ARLOS , 2021
Sumário
1 Arduino 7
1.1 Definição . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.2 Criação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.3 Arduino UNO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.4 Arduino só é utilizado por iniciantes? . . . . . . . . . . . . . . . . . . . 9
1.5 Quando NÃO usar o Arduino? . . . . . . . . . . . . . . . . . . . . . . . 10

2 IDE 11
2.1 Introdução . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.2 Função void setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.3 Função void loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.4 ATMEGA 328p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

3 VARIÁVEIS 15
3.1 Introdução . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.2 Tipos de Variáveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.3 Variáveis Globais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.4 Variáveis Locais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.5 diretiva static . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.6 diretiva define . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

4 Escrita Digital 18
4.1 Introdução . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
4.2 comando pinMode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
4.3 comando digitalWrite . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
4.4 comando delay . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
4.5 exemplo 1 - semáforo . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

5 Leitura Digital 22
5.1 Introdução . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
5.2 comando digitalRead . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
5.3 exemplo 2 - leitura de botões . . . . . . . . . . . . . . . . . . . . . . . . 23
5.4 pull up interno . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

6 Leitura Analógica 27
6.1 Introdução . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
6.2 comando analogRead . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
6.3 Prática 3 - lendo potenciômetro . . . . . . . . . . . . . . . . . . . . . . 28

7 Escrita Analógica 31

1
7.1 Sinais e formas de onda . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
7.2 Valor RMS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
7.3 PWM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
7.4 comando analogWrite . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
7.5 prática 4 - variando luminosidade do LED . . . . . . . . . . . . . . . . 34

8 Monitor Serial 37
8.1 Monitor Serial do Arduino . . . . . . . . . . . . . . . . . . . . . . . . . 37
8.2 Vendo dados no monitor serial . . . . . . . . . . . . . . . . . . . . . . 37
8.3 Código do Monitor Serial . . . . . . . . . . . . . . . . . . . . . . . . . . 37
8.4 prática 4 com monitor serial . . . . . . . . . . . . . . . . . . . . . . . . 38
8.5 Usando Monitor serial como prompt de comando na IDE . . . . . . 41
8.6 Variável do tipo string . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
8.7 Prática 5 - Controlando Arduino pelo monitor serial . . . . . . . . . . 42

9 Bibliotecas 44
9.1 O que são bibliotecas? . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
9.2 Como importar bibliotecas . . . . . . . . . . . . . . . . . . . . . . . . . 45
9.2.1 Pasta Separada . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
9.2.2 arquivo .ZIP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
9.2.3 Importando dentro da IDE . . . . . . . . . . . . . . . . . . . . 49
9.3 Limpando EEPROM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
9.4 Outras informações . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

10 Protocolos de Comunicação do Arduino 51


10.1 O que são protocolos de comunicação . . . . . . . . . . . . . . . . . . 51
10.1.1 Comunicação SERIAL . . . . . . . . . . . . . . . . . . . . . . . 51
10.1.2 Comunicação PARALELA . . . . . . . . . . . . . . . . . . . . . 52
10.1.3 Taxa de Transferência de Dados . . . . . . . . . . . . . . . . . 52
10.1.4 Transmissão Síncrona . . . . . . . . . . . . . . . . . . . . . . . 52
10.1.5 Transmissão Assíncrona . . . . . . . . . . . . . . . . . . . . . . 52
10.1.6 Simplex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
10.1.7 Half-Duplex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
10.1.8 Full-Duplex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
10.2 Protocolos de comunicação no Arduino . . . . . . . . . . . . . . . . . 53
10.3 UART - Universal Asynchrounous Receiever/Transmiter . . . . . . . 53
10.4 I2C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
10.4.1 Prática 6 - exemplo de comunicação I2C entre Arduinos . . . 57
10.5 SPI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
10.5.1 MOSI - Master Out, Slave In . . . . . . . . . . . . . . . . . . . . 59

2
10.5.2 MISO - Master In, Slave Out . . . . . . . . . . . . . . . . . . . . 59
10.5.3 SCLK - Serial clock . . . . . . . . . . . . . . . . . . . . . . . . . 60
10.5.4 SSx - Slave Select . . . . . . . . . . . . . . . . . . . . . . . . . . 60
10.5.5 Prática 7 - exemplo de comunicação SPI entre 2 Arduinos . . 63
10.6 Prática 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
10.7 Prática 9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

11 Interrupções 67
11.1 O que são interrupções . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
11.2 Interrupção Externa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
11.3 Prática 10 - interrupção externa . . . . . . . . . . . . . . . . . . . . . . 68
11.4 Interrupção Interna ou por timer . . . . . . . . . . . . . . . . . . . . . 70
11.5 Prática 11 - Interrupção Interna . . . . . . . . . . . . . . . . . . . . . . 71

12 Displays e dispositivos visuais 73


12.1 Display de 7 segmentos . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
12.2 Pratica 12.1 - acionando 1 display de 7 segmentos com decodificador
CD4511 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
12.3 Pratica12.2 - Acionando 2 displays de 7 segmentos sem decodificador 78
12.4 Display LCD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
12.5 Prática 13.1 - Display LCD configuração 8 bits . . . . . . . . . . . . . 86
12.6 Prática 13.2 - Display LCD configuração 4 bits . . . . . . . . . . . . . 88

13 Matrizes 90
13.1 Matriz de LED . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
13.2 Prática 14.1 - Acionando matriz de leds 8x8 com multiplex . . . . . . 92
13.3 Matriz de botões . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
13.4 Prática 15 - Lendo teclado matricial . . . . . . . . . . . . . . . . . . . . 95

14 Sensores de Temperatura 98
14.1 Termistores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
14.1.1 NTC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
14.1.2 Método do fator β . . . . . . . . . . . . . . . . . . . . . . . . . 100
14.1.3 Método de Steinhart-Hart . . . . . . . . . . . . . . . . . . . . . 100
14.2 Prática 16.1 - NTC pelo método β . . . . . . . . . . . . . . . . . . . . . 100
14.3 Prática 16.2 - NTC pelo método de Steinhart Hart . . . . . . . . . . . 101
14.4 Termopar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
14.5 Prática 17 - Termopar tipo K com MAX6675 . . . . . . . . . . . . . . . 105
14.6 LM35 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
14.7 Prática 18 - LM35 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
14.8 DHT11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109

3
14.9 PRÁTICA 19 - DHT11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
14.10MLX90614 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
14.11Prática 20 - MLX90614 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
14.12DS18B20 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
14.13Prática 21 - DS18B20 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111

15 Sensores de Posição e Presença 112


15.1 Chaves de fim de curso . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
15.2 Sensores indutivos e capacitivos . . . . . . . . . . . . . . . . . . . . . . 113
15.3 Óptico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
15.4 ultrassônico - HC-SR04 . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
15.5 Pratica 22.1 - HC-SR04 - desenvolvendo algorítmo . . . . . . . . . . . 116
15.6 Prática 22.2 - HC-SR04 - com biblioteca . . . . . . . . . . . . . . . . . 119
15.7 PIR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
15.8 encoder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
15.8.1 Encoder do tipo Absoluto . . . . . . . . . . . . . . . . . . . . . 122
15.8.2 Encoder do tipo Incremental . . . . . . . . . . . . . . . . . . . 123
15.9 Prática 23.1 - Encoder Incremental KY-040 sem biblioteca . . . . . . 125
15.10Prática 23.2 - Encoder incremental com biblioteca . . . . . . . . . . . 129
15.11Acelerômetros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
15.11.1 ADXL335 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
15.11.2 Prática 24.1 - ADXL335 . . . . . . . . . . . . . . . . . . . . . . . 131
15.11.3 MPU6050 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
15.11.4 Prática 24.2 - MPU6050 . . . . . . . . . . . . . . . . . . . . . . 133

16 Extensômetros 136
16.1 Extensômetros, Strain Gauges e Células de Carga . . . . . . . . . . . . 136
16.2 Ponte de Wheatstone . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
16.3 Deformação do Strain Gauge . . . . . . . . . . . . . . . . . . . . . . . . 137
16.4 HX711 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
16.5 Célula de carga de 50kg da Sparkfun . . . . . . . . . . . . . . . . . . . 138
16.5.1 1 módulo de célula de carga, contendo 2 strain gauges . . . . 139
16.5.2 2 módulos de célula de carga, contendo 4 strain gauges . . . 141
16.5.3 4 módulos de célula de carga, contendo 8 strain gauges . . . 142
16.6 Prática 25 - lendo dados da célula de carga . . . . . . . . . . . . . . . 143

17 Motores 144
17.1 Motor DC universal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
17.2 Motor de passo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
17.3 Prática 26 - acionando motor de passo . . . . . . . . . . . . . . . . . . 152

4
17.4 Servo Motor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
17.5 Prática 27 - acionando servo motor SG90 . . . . . . . . . . . . . . . . 153

18 Referências Bibliográficas 154

5
Sobre esta apostila

Esta apostila foi criada para fins educacionais sendo PROIBIDA sua comercialização com
fins lucrativos. Cópias e distribuições gratuitas são autorizadas, dadas as devidas referên-
cias bibliográficas aos autores e colaboradores.

6
1 Arduino
SECTION

Este capítulo apresenta uma breve introdução ao Arduino, mais especificamente o Arduino UNO,
sua história, características e aplicações típicas.

1.1 Definição
O Arduino é um conjunto constituido de uma placa eletrônica composta de um controlador AT-
MEL AVR 8 bits, junto a um circuito de hardware de livre acesso, que varia para cada modelo
de Arduino, mas é composto basicamente de uma fonte de alimentação regulada, uma comu-
nicação USB e pinos de entrada e saída. Junto a placa eletrônica (Fig. 1), usa-se sua IDE que
permite a programação em C++ (com algumas adaptações para o usuário). Perceba então, que o
Arduino, não é somente o microcontrolador, é todo o conjunto de hardware junto a IDE ao qual
ele é programado. [4]

1.2 Criação
O Arduino foi desenvolvido 2005, em Ivrea na Itália. Seu objetivo era a criação de um micro-
controlador de baixo custo e fácil acesso, para que jovens pudessem aprender lógica de progra-
mação e eletrônica básica, sem necessitar de conhecimentos avançados de microcontroladores,
memórias, arquitetura de computadores e outros.[4]

7
Figura 1: Arduino UNO - Fonte: [Link]

1.3 Arduino UNO


Como mencionado, existem diversos tipos de Arduino, sendo o mais comum deles o Arduino
UNO. Este por sua vez, utiliza o microcontrolador ATMEGA 328, atualmente fabricado pela em-
presa Microchip (que comprou a criadora do chip - ATMEL) [28]. Este Arduino será implemen-
tado nas notas de revisão, porém dado os ajustes para os pinos referenciados, o código é com-
patível para qualquer outro tipo de Arduino.
As Figuras 2 e 3 mostram a pinagem do Arduino UNO e do microcontrolador ATMGA328, res-
pectivamente [21].

Figura 2: Arduino UNO pinagem - Fonte: [Link]

8
Figura 3: ATMEGA 328 pinagem - Fonte: [Link]

Como pode ser visto, a placa do Arduino já organiza os pinos de acordo com suas funções e
registradores e os autonomeia. Se você já trabalhou com algum outro microcontrolador, sabe
que devemos olhar pino a pino, ver qual registrador ele faz parte, verificar no datasheet qual as
funções daquele registrador e pino, quais outros registradores internos fazem parte, etc.
No caso do Arduino, o usuário não precisa fazer isso, já que a placa eletrônica já possui as liga-
ções feitas e agrupa os pinos por registradores e a IDE do programa, já pré configura os regis-
tradores e pinos, e os reconhece por meio de nomes simples que iremos abordar no próximo
capítulo. Caso você queira ajustar algum registrador interno, basta adicionar uma biblioteca ao
programa, que este registrador será reconhecido e pré configurado.

1.4 Arduino só é utilizado por iniciantes?


Definitivamente NÃO. O Arduino é muito indicado para quem está começando na área de ele-
trônica embarcada, porém é um recurso muito útil e flexível quanto a sua utilização. Empresas
de desenvolvimento de tecnologia embarcada passam por alguns estágios de desenvolvimento,
tanto do hardware como do software. Agora imagine o quão árduo seria você ter que criar um
software compatível com um hardware e ficar testando várias e várias vezes, hora identificando
problemas no circuito eletrônico, hora na programação. Isso ocorre muito, ainda mais quando
o microcontrolador possui uma complexidade e grande número de registradores internos que
se comunicam.
Desta forma, atualmente, é muito comum o desenvolvimento de equipamentos embarcados em
duas etapas distintas, uma de desenvolvimento do hardware e outra do software. O software é
desenvolvido na linguagem nativa e para os registradores do microcontrolador empregado no
projeto, já a validação do hardware é feita por um Arduino. Como os programas do Arduino são
open source, uma comunidade imensa de pessoas atualiza os códigos de referência, bibliotecas,
otimização, dentre outros, o que torna o código fonte muito confiável e praticamente da a cer-
teza que o erro está no hardware. Desta forma, após a validação do hardware do produto com
o programa feito pelo Arduino, está na hora de testar o software criado especialmente para o

9
projeto, e caso o produto final apresente erros, é praticamente certeza que o erro está na lógica
de programação do novo controlador.
Assim, o Arduino se tornou uma ferramente muito versátil nos dias atuais, servindo para acelerar
o processo de criação e validação de produtos em empresas, criar protótipos em curto prazo,
treinar e capacitar novos trabalhadores em um curto período e de forma mais simplificada, etc...

1.5 Quando NÃO usar o Arduino?


O Arduino, como mostrado anteriormente, já pré configura os registradores internos e autono-
meia os pinos do microcontrolador. Além disso, sua placa eletrônica já possui configurações de
hardware fixas, como frequência de operação e pinos que não podem ser utilizados pois são ne-
cessários para o funcionamento da eletrônica do equipamento. Por último, e mais grave, é o fato
dos registradores do Arduino não serem controlados diretamente pelo usuário e serem ativados
por meio de bibliotecas (na verdade você pode controlá-los, mas necessita de um conhecimento
bem mais avançado da IDE e da linguagem de programação que é uma adaptação do C++.
Desta forma, o usuário perde o controle total sobre o componente e sem perceber, configurações
pré definidas de registradores podem se conflitar e se sobrepor no código. Como o programador
não tem acesso a isso diretamente pela IDE, ele não controla certos parâmetros de biblioteca
o que limita a utilização dos recursos nos registradores, ou em casos mais graves, desconfigura
funções de pinos e registradores (mais comumente em programas mais complexos com muitas
bibliotecas). Além disso, há a questão da eletrônica envolvida. O Arduino não foi projetado
para ser robusto, muito menos identificar erros de hardware ou ruídos no sinal, o que o torna
(para aplicações críticas) um hardware pouco seguro e suscetível a erros. Pelo contrário, ele foi
desenvolvido para aplicações didáticas e de baixo custo, logo num ambiente agressivo como de
indústrias ou para aplicações críticas, de alto desempenho e estresse físico, ele não é a melhor
opção.
Todavia, optar por utilizar o microcontrolador ATMEGA não deve ser um problema, se ele aten-
der às necessidades de projeto. Se o software for modificado para ter controle sobre as funções
dos registradores e pinos, e o hardware desenvolvido para ser robusto o suficiente, o microcon-
trolador poderia ser utilizado nestas aplicações.

10
2 SECTION

IDE

Este capítulo apresenta o Ambiente de Desenvolvimento Integrado (IDE na sigla em inglês para
Integrated Development Environment) do Arduino, incluindo uma descrição básica e estrutura
de código.

2.1 Introdução
Visite o site [Link] e baixe o IDE do programa na aba downloads. Execute como
administrador e siga os passos de instalação. No final abra a IDE do programa. A Figura 4 mostra
o ambiente de programação, compilação e gravação do seu código no Arduino [4].
Para conectar o Arduino ao computador, primeiro você deve ir na aba "ferramentas"e depois na
opção "placa"(vide Fig. 5). Em seguida escolha a opção correspondente ao seu Arduino, que
neste caso deve ser o Arduino UNO.
Em seguida, conecte a sua placa ao computador por meio do cabo USB. Tome cuidado com a
superfície onde você coloca seu Arduino. Umidade e pedaços metálicos podem curto-circuitar
as ligações e soldas elétricas na parte inferior da placa, podendo ocasionar até a queima da porta
USB do seu computador!.

2.2 Função void setup


Ao abrir a IDE, a primeira função que surge é a void setup. Dentro dela podemos declarar va-
riáveis locais que serão utilizadas durante toda a execução do programa na função void loop.
Também podemos atribuir valores para essas variáveis (inicializar variáveis e contadores, por
exemplo) dentro da void setup, inclusive utilizar alguns comandos de preparação, dentre outras
ações que serão abordadas ao decorrer deste documento. Esta função é padrão da IDE, não

11
Figura 4: - Fonte: Autor

pode ser apagada e deve ser mantida na posição inicial em que surge, antes da função void loop.
Quando o comando estiver pronto e for carregado no controlador, ele executa inicialmente as
ações descritas na void setup e então parte para void loop que é repetida indefinidamente. Sendo
assim, você pode executar comandos dentro da função void setup, mas saiba que eles serão exe-
cutados uma única vez.

2.3 Função void loop


Após a função void setup, temos a função void loop. Tudo que será executado repetidamente
pelo programa deve estar contido dentro desta função. Nela, o código é lido e repetido durante
todo tempo que o Arduino fica ligado. Não é aconselhável, por exemplo, criar variáveis dentro
desta função.

2.4 ATMEGA 328p


Este será o microcontrolador usado no nosso Arduino UNO. Ele é um microcontrolador de ar-
quitetura RISC, 8 bits, tensão de operação de 1,8V a 5,5V (sendo no Arduino operado com 5V),
frequência máxima de operação de 20MHz, 28 pinos, dos quais 23 para I/O, 2 temporizadores/
contadores de 8 bits, 1 temporizador/contador de 16 bits, 1 interface USART, 1 interface SPI, 1
interface I2C, 1 watchdog timer, 6 canais PWM, 6 canais ADC, 2 interrupções externas e 1 in-
terna, dentre outras funções [28].
A programação desse microcontrolador é um tanto quanto mais complexa, pois a IDE padrão de
cada fabricante varia e com isso a necessidade ou não de configurar alguns parâmetros de regis-
tradores. Para nossa sorte, este resumo contém apenas a programação para o Arduino, porém
caso você queira se aventurar numa programação "old school", vale a pena procurar pela IDE
ATMEL STUDIO e utilizar o gravador indicado (possivelmente não mais comercializado hoje em

12
Figura 5: IDE Arduino - Fonte: Autor

dia).

A seguir temos a pinagem completa do Arduino UNO com todas as funções de cada pino (Fig.
6). Vale ressaltar que as configurações mudam de modelo para modelo, então sempre confira o
datasheet do seu Arduino, caso não seja o UNO (que é o utilizado neste resumo) [10].

13
Figura 6: IDE Arduino - Fonte: [Link]

14
3.1 Introdução
3VARIÁVEIS
SECTION

Este resumo pressupõe que você tenha alguma noção de linguagem C ou C++, pois todos os co-
mandos empregados no Arduino são baseados e adaptados dessas linguagens.
A própria ideia de variável também. Existem variáveis locais, globais e fixas, além de outros re-
cursos que nos auxiliam a armazenar dados na memória.
A variável será um espaço reservado na memória do microcontrolador, no qual você guarda uma
informação, podendo ser um número inteiro, com casa decimal, um caractere ou conjunto de-
les, um valor binário (booleano), etc...
Porém, tome cuidado, pois a memória de um microcontrolador é pequena e devemos aproveitar
sabiamente seu espaço de armazenamento a fim de não faltar ou comprometer a otimização do
código.

3.2 Tipos de Variáveis


A lista a seguir mostra a nomenclatura utilizada para definir o tipo de uma variável:

• int: variavel do tipo inteiro;

• boolean: valor verdadeiro (true) ou falso (false)

• float: ponto flutuante (aceita numeros com vírgula)

• boolean: variaveis booleanas (apenas TRUE ou FALSE)

15
• char: um caractere

• string: um vetor de caracteres ou sequência deles

Sempre declaramos primeiro o tipo de variável (se ela é inteira, ponto flutuante, caractere...)
e depois a nomeamos. Caso queira, você pode já armazenar um valor usando o símbolo de
atribuição ’=’.
Cuidado ao nomear a variavel, pois só é permitido um total de 31 caracteres na palavra que
a nomeia, sendo válido somente letras e números após o primeiro caractere. É vedado o uso
de acentos e caracteres especiais exceto o underline. As variáveis também são ’Case sensitive’,
então letras maiúsculas e minusculas também alteram o nome dela.
Veja os exemplos ERRADOS:

• int 12valor = 12;

• char palavrão[];

• float núMEros ;

• int [Link];

Veja os exemplos CORRETOS:

• int valor12 = 12;

• char palavrao[];

• float nuMEros ;

• int numeros_inteiros;

3.3 Variáveis Globais


São aquelas declaradas fora de uma função. Caso a variável seja declarada na função ’void se-
tup()’, ’void loop()’ ou qualquer outra, ela NÃO É GLOBAL, pois é vista apenas dentro dessas
funções e não por todo o programa. Este tipo de variável reserva um espaço fixo na memória do
micro e não é apagado ou realocado durante a executação do programa. Apesar do endereço de
memória ser fixo e visto em todo o programa, ela pode ter seu conteúdo modificado livremente.

3.4 Variáveis Locais


São aquelas declaradas dentro de uma função. Caso a variável seja declarada na função ’void
setup()’, ’void loop()’ ou qualquer outra, ela É LOCAL, pois é vista apenas dentro dessas funções.
Esse tipo de variável aloca memória durante seu uso e após término da função, a memória é
desalocada e as informações contidas são perdidas.

16
3.5 diretiva static
Esta diretiva acompanha um tipo de variável (ex: static int ’variavel’;).
Ela faz com que o valor contido na variável durante sua criação seja fixo, ou seja, estático. Desta
forma, mesmo que você tente associar outro valor aquela variável, ele não será alterado. É mais
comumente usado em variáveis globais para não ter que ficar reinicializando o valor da variável
via código, dentre outras aplicações.

3.6 diretiva define


esta diretiva é declarada no começo do programa, antes de qualquer função de inicialização. Ela
faz com que a palavra definida, seja trocada por outra coisa. Por exemplo, se eu quiser trocar a
palavra ’pi’ no meu código por 3,14, eu posso escrever ’pi’ no código todo e por meio do define,
o programa entende que ’pi’ é na verdade o número 3,14. Além de número, ela pode ser usada
para expressões e operadores lógicos também.
Perceba, que no caso dessa diretiva, não é criado nenhum espaço na memória, pois ela apenas
indica onde trocar as informações no código. Desta forma, podemos tornar o nosso código mais
fácil de ler e modificações são aplicadas a todas as palavras que estão numa diretiva define, o
que nos economiza tempo para mudanças no código.
Ela possui a seguinte sintaxe: DEFINE ’palavra a ser trocada’ ’troca’.
ex:

• #define pi 3,14 //troca todas as ocorrências de ’pi’ por ’3,14’

• #define COR Verde // troca todas as ocorrências de ’COR’ por ’Verde’

• #define soma a+b //troca todas as ocorrências de ’soma’ por ’a+b’

Obs: perceba que não utilizamos ’;’ no final da diretiva.

17
4
Escrita Digital
SECTION

Neste capítulo iremos entender como é feita a escrita digital no arduino, os comandos a serem
utilizados e faremos um exercício de treino.

4.1 Introdução
As portas são os nossos pinos que possuem registradores. Estes pinos com registradores podem
ser do tipo digital, ou seja, aceitam apenas valores binários ’1’ ou ’0’; Analógico, ou seja, aferem
valores analógicos e digitalizam para o microcontrolador; podem ser de comunicação, dentre os
quais temos a comunicação SERIAL (USART), I2C, SPI, USB, 1 Wire, etc...; e podemos ter o pino
sem registrador no qual serve para alguma parte do funcionamento do microcontrolador como
alimentação e pino de reset.
Vale ressaltar que alguns registradores operam com pinos individuais, enquanto que outros ne-
cessitam de vários pinos. Neste capítulo vamos entender como usar os pinos digitais do Arduino
UNO, tanto para escrita como leitura de dados, sem envolver protocolo de comunicação, o qual
será visto mais adiante [4].

4.2 comando pinMode


o comando pinMode não é exclusivo para portas digitais, porém ele é necessário para podermos
utilizar as portas do Arduino antes de definir quais registradores serão ativados. este comando
deve ser declarado dentro da função void setup e é por meio dele que definimos qual pino do
Arduino queremos usar e se ele será do tipo saída ou entrada de dados. Sua sintaxe é a seguinte:

18
• pinMode(’valor’ , ’tipo’);

Sendo ’valor’ um número inteiro positivo (0,1,2,3,...), referente ao pino do Arduino;


Sendo ’tipo’ a definição de entrada ou saída, no qual você substitui por ’INPUT’ ou ’OUTPUT’.

4.3 comando digitalWrite


Analisando o Arduino uno, vemos que ele possui 13 portas digitais, logo podemos utilizar estes
13 pinos como pinos digitais e escolher qual deles será entrada ou saída de dados. Uma vez que
o pino é escolhido como saída de dados, ele fornecerá valores binários ’1’ ou ’0’, nas tensões de
5V ou 0V, respectivamente. Neste modo, o pino possui baixa impedância e corrente máxima de
fornecimento de 20mA. Isto implica que devemos ter muito cuidado com a saída a ser ligada,
pois podemos danificar nosso microcontroldor, caso a ligação elétrica seja feita errada ou con-
suma mais de 20mA (corrente necessária para acender um LED).
Para que nosso pino faça esse acionamento devemos usar o comando pinMode para definir o
pino de interesse na configuração de saída, e depois devemos usar o comando digitalWrite, para
definir qual será o estado lógico do pino selecionado [1].
sintaxe:

• digitalWrite(’valor’ , ’estado’);

Sendo ’valor’ um número inteiro positivo (0,1,2,3,...), referente ao pino digital do Arduino;
Sendo ’estado’ o nível lógico do pino, no qual você substitui por ’HIGH’ ou ’LOW’.

4.4 comando delay


o comando ’delay’ é o que nós chamamos de ’pooling’ em programação para C/C++. Este tipo
de comando literalmente pausa a execução do código na linha em que é inserido, por um tempo
determinado no comando. Uma vez que o pooling é acionado, o programa não é mais respon-
sivo, ou seja, torna o microcontrolador incapaz de alterar suas saídas e ler suas entradas, além
de travar a comunicação. Este recurso é para aplicações mais simples em programas pequenos
e sem necessidade de comunicação ou monitoramento. Mais a frente iremos entender como
contornar este problema e conseguir fazer pausas no código [2].
sintaxe:

• delay(’tempo’);

Sendo ’tempo’ um valor inteiro positivo que será entendido pelo microcontrolador como o tempo
de pausa do programa em milissegundos.

4.5 exemplo 1 - semáforo


No seu software preferido (ou bancada) monte o circuito da figura 7 e depois digite o código da
figura 8:

19
Figura 7: diagrama elétrico prática 1 - Fonte: autor

Veja que este circuito é composto de três leds, representando as cores de um semáforo. O led
verde fica aceso por 3 segundos, o amarelo depois acende por 1 segundo e o vermelho acende
por último durante 2 segundos, então a sequência se reinicia. Quando um led está aceso os
outros estão apagados, assim como no funcionamento do semáforo normal. Os pinos 13,12,11
estão conectados aos Leds verde, amarelo e vermelho respectivamente, na configuração catodo
comum, ou seja, acendem com nivel lógico alto. Os resistores de 270R servem para limitar a cor-
rente em cada led. No código a seguir, teremos a diretiva ’define’ para nomear os pinos usados e
assim facilitar nossa leitura e atribuições no código. Usamos o comando ’pinMode’ para definir
os três pinos como saída de dados e o comando ’digitalWrite’ para escolher qual pino vai a nivel
lógico alto ou baixo.

20
Figura 8: código prática 1 - Fonte: autor

21
5
Leitura Digital
SECTION

Neste capítulo iremos entender como é feita a leitura digital no arduino, os comandos envolvi-
dos e faremos um exercício de fixação.

5.1 Introdução
Assim como é feita a escrita de dados digitais (binários) podemos fazer o mesmo com a leitura.
Neste caso iremos identificar apenas dois estados, ’1’ ou ’0’, ligado ou desligado, com energia ou
sem energia, etc...
Você também pode definir o tipo de lógica de acionamento, direta ou indireta, mas para o nosso
caso, vamos trabalhar só com lógica direta.
Para evitar problemas de ruído, devemos utilizar o sistema pull up ou pull down, assim asse-
gurando sempre o nível lógico. No momento, iremos efetuar isso fisicamente, ou seja, teremos
resistores no circuito para fazer essa configuração. Depois veremos uma forma de utilizar os
próprios registradores internos do Arduino para fazer isso. Veja a figura:

22
Figura 9: Ligação pull up e pull down - Fonte: [Link]

5.2 comando digitalRead


Este comando serve para ler entradas digitais pelo Arduino. Ele pode ser atribuido dos pinos 0
a 13 digitais e necessita previamente que o comando pinMode mude o pino para o modo en-
trada (INPUT). No modo de entrada, o pino possui alta impedância de entrada, drenando muito
pouca corrente. Tome cuidado, caso você faça a leitura de um sinal mas esqueça de configurar
o pino como entrada antes, e o deixe como saída, você vai danificar o pino do microcontrola-
dor (queimar), pois no estado saída ele possui baixa impedância [2]. A sintaxe do comando é a
seguinte:

• digitalRead(’pino’);

no qual ’pino’ é o valor de 0 a 13 dos pinos digitais.


O comando digitalRead não opera sozinho, ele necessita que o dado lido seja salvo em uma va-
riável ou usado em alguma lógica. O mais comum é salvar o dado numa variável mesmo, porém
podemos utilizar diretamente dentro de IF, WHILE, comparadores lógicos, etc..., otimizando o
código.

5.3 exemplo 2 - leitura de botões


monte o circuito conforme a figura 10 e depois insira o código mostrado na figura 11. Este pro-
grama mostra como ler os dados digitais de um botão (pressionado ou não) e a partir disso
acionar uma saída. Neste exemplo, o led será acionado apenas se os três botões forem pressi-
onados juntos. Perceba que estamos operando com lógica direta, logo usamos um sistema de
pull down:

23
Figura 10: pratica 2 - esquema de ligação - fonte: autor

Nesta prática há três botões conectados nos pinos 5,6 e 7 digitais. No pino 13 há um led co-
nectado para ser aceso. Para armazenar os valores lidos dos botões, temos que criar variáveis,
e neste caso, podem ser do tipo booleana, já que o microcontrolador irá guardar apenas dois
estados (1 - pressionado) ou (0 - despressionado). Quando os três botões são acionados, o led é
aceso.

24
Figura 11: pratica 2 - programação - Fonte: autor

5.4 pull up interno


O próprio registrador de entradas digitais do Arduino, possui a opção de pull up interno, ou seja,
não é necessário um resistor externo na configuração pull up para garantir o sinal. Então caso
não seja definido o nível lógico na entrada digital, o Arduino pré assume nivel lógico ALTO (1),
então devemos enviar nivel lógico BAIXO (0) para esta entrada, caso queiramos fazer o aciona-
mento de algo, ou seja, trabalhamos com lógica inversa. Infelizmente, ele não possui o modo
de pull down. Caso você queira o modo de pull up interno ativado para certo pino, basta usar o
comando pinMode como descrito [2]:

• pinMode(’pino’, INPUT_PULLUP);

Sendo ’pino’ o pino de 0 a 13 no qual você deseja ler o dado digital;


sendo INPUT_PULLUP literalmente o comando a ser inserido para que faça a leitura, porém já
com o registrador de pull up interno acionado. Veja como fica o exemplo 2, só que refeito com
pull up interno:

25
Figura 12: pratica 2 - circuito com pull up interno - Fonte: autor

No circuito da figura 12, não é necessário os resistores de pull down do exercício anterior, já que
nosso microcontrolador assume sempre nivel alto. Logo, os botões enviam nivel baixo ao serem
pressionados. Então, se seguirmos o algorítmo do programa anterior, em que o led só acendia
quando todos os botões fossem pressionados, enviando nivel alto, então para este código, te-
remos que o led sempre fica aceso, pois por padrão o pull up interno está ativado, e os leds só
apagam quando um botão é aceso. Veja as alterações necessárias no código da figura 13:

Figura 13: pratica 2 - código com pull up interno - Fonte: autor

26
6
Leitura Analógica
SECTION

Neste capítulo iremos entender o que é a leitura analógica, os comandos envolvidos e faremos
um exercício de fixação.

6.1 Introdução
Apesar do nosso microcontrolador operar com lógica binária, ele é capaz de ler valores analógi-
cos. Porém é necessário digitalizar esses valores por meio de um conversor A/D. Alguns pinos do
microcontrolador são capazes de realizar essa conversão, mas são os pinos analógicos, variando
do A0 ao A5 (no Arduino UNO). A partir da faixa de tensão que o microcontrolador afere (0V a
5V para Arduino uno), e a resolução máxima (10 bits = 1024 divisões), podemos obter a mínima
resolução do microcontrolar [1]:

5−0
Resol ução = = 0, 004882813V /d i v ≈ 0, 005V /d i v (1)
1024

Podemos perceber então que a cada 0,005V de aumento de tensão, o microcontrolador irá adi-
cionar 1 a sua contagem do conversor A/D, sendo que:

27
Tensão [V] Valor binário
0,000 0000000000
0,005 0000000001
0,010 0000000010
0,015 0000000011
* *
* *
* *
5,000 11111111111

6.2 comando analogRead


Assim como o comando digitalRead, o comando analogicRead necessita que os dados aferidos
nos pinos ao qual a função é aplicada, seja guardado numa variável e depois utilizado [2]. Sua
sintaxe é dada como:

• analogRead(’pino’);

no qual ’pino’ é o pino ao qual faz a conversão A/D, sendo possível do A0 ao A5 no Arduino UNO.
Perceba que no microcontrolador o valor aferido vai de 0 a 1023 (pois temos 1024 divisões), neste
caso, devemos guardar o valor aferido numa variavel INTEIRA e fazer os ajustes para a conversão
física da grandeza aferida.

6.3 Prática 3 - lendo potenciômetro


O esquemático da figura 14 e o código da figura 15 são referentes a um circuito que lê a ten-
são de um potenciômetro e aciona três leds. O potenciômetro tem um cursor que rotaciona
aproximadamente 180º. Neste caso, um led é aceso representando em qual faixa de ângulo o
eixo foi rotacionado. Então de 0º a 59º acendemos um led, de 60º a 119º acendemos outro led
e de 120º a 180º acendemos outro led. Perceba que é necessário realizar uma regra de três para
achar os valores de ângulo a partir das tensões aferidas. Veja que o primeiro passo é ler o valor
pelo pino analógico. A informação será um inteiro entre 0 e 1023. Depois precisamos converter
para tensão, já que temos a resolução do Arduino, e depois convertemos para ângulo, já que o
potenciômetro varia a tensão conforme giramos seu eixo. Desta forma temos:

t ensão = (r esol ução) ∗ (l ei t ur a A/D) = 0, 004882813 ∗ l ei t ur a A/D (2)

Depois para achar o valor do ângulo, se 180º = 5V, então por regra de três:

t ensão ∗ 180
âng ul o = (3)
5
Veja como isso é implementado no código e faça o experimento no software ou em bancada:

28
Figura 14: pratica 3 - circuito elétrico - Fonte: autor

Figura 15: pratica 3 - código - Fonte: autor

29
Uma coisa muito importante a salientar é que as conversões requerem números com ponto
flutuante (float), então para não haver perda de dados, devemos realizar o ’cast’, quando mis-
turamos int com float. Dependendo do cast realizado, você pode consumir mais memória e
aumentar a precisão dos seus dados (float), ou pode diminuir a memória consumida mas per-
der um pouco a precisão dos dados (int), então tome cuidado para não estourar a memória do
microcontrolador, nem perder precisão nos cálculos. Este algorítmo não está otimizado, tente
melhorá-lo como forma de treino e memorização dos comandos.

30
7
Escrita Analógica
SECTION

Neste capítulo iremos entender o que é escrita anlógica, os comandos necessários no arduino e
faremos um exercício de fixação.

7.1 Sinais e formas de onda


Existem diversos tipos de sinais analógicos. Como as nossas grandezas lidas ou enviadas pelo
microcontrolador são baseadas em tensão, então irei sempre me referir a um sinal de tensão e
sua forma de onda. Dentre os diversos tipos de sinais, temos suas formas de onda, que é o grá-
fico da amplitude (Volts) pelo tempo (segundos). Temos ondas quadradas, triangulares, dente
de serra, senoidais, constantes, senoidais retificadas, etc...
A figura 16 ilustra alguns tipos:

7.2 Valor RMS


O valor RMS é uma forma de comparação criada entre a forma de onda analisada e se ela fosse
substituída por contínua constante. Então, se esses dois sinais possuírem mesmo valor RMS
para corrente e tensão, é como se eu colocasse um resistor para dissipar a potência da fonte que
gera ambos os sinais, e esse resistor dissipasse a mesma potência nos dois casos. Ou explicando
de outra forma, o valor RMS é como seria o valor daquele sinal, caso eu quisesse substituir por
uma fonte contínua constante. Olhe a figura 17 comparativa [34]:

31
Figura 16: alguns tipos de forma de onda - Fonte: wikipedia

Figura 17: exemplo de valor RMS - Fonte: [Link]

32
Como exemplo clássico, temos a tensão da nossa tomada. Quando falamos que uma tomada
é 127V, na verdade ela náo é 127V, mas sim seu valor RMS. Os 127V seriam caso eu trocasse
a corrente alteranda sinusoidal da tomada, por uma corrente contínua constante de 127V. Na
realidade temos uma onda sinusoidal de amplitude máxima de 180V, como mostrado na figura.
Perceba então que o valor RMS é como se fosse uma média, no nosso caso de análise, uma tensão
média. Porém o RMS é uma forma de comparar, pois na realidade temos a tensão sinusoidal da
tomada. Caso você aplique um filtro e eletrônica correspondente, pode tornar a forma de onda
do sinal muito próxima a do RMS. É a partir desta observação que vamos conseguir trabalhar
com a saída analógica do Arduino [22].

7.3 PWM
O PWM é conhecido também como onda quadrada, isto porque é um sinal com forma de onda
no qual não temos variação no tempo, mas apenas dois valores bem definidos, baseados em
lógica digital. Então hora o sinal é ligado, hora desligado. Se eu considerar a tensão do Arduino
UNO, então sua saída PWM, hora envia 5V (ligado), hora envia 0V (desligado). Veja a figura 18:

Figura 18: PWM - fonte: retirado de [Link]

O PWM é criado a partir de dois parâmetros, o duty cicle e a frequência. A frequência é a quan-
tidade de vezes que o sinal se repetiu numa faixa de tempo. O duty cicle indica (em porcenta-
gem) quanto tempo o nivel lógico alto ficou ativo. A partir dessa combinação, podemos gerar
diferentes sinais PWM com diferentes valores RMS, só que no caso do PWM, o seu valor RMS é
diretamente proporcional ao duty cicle. Isto implica dizer que quanto mais tempo o pwm fica
em nível lógico alto (com tensão), maior é a média de tensão que ele gera, e quanto maior a
frequência, mais rápido essa onda se repete e mais próximo de um sinal médio emulado fica [1].
Veja a figura 19:

33
Figura 19: PWM com ajuste de duty cicle - Fonte: /[Link]

7.4 comando analogWrite


O Arduino possui o comando analogWrite, no qual tentamos emular um sinal analógico por
meio de um PWM, mas como o PWM é uma alternância de liga e desliga, então usamos os pinos
DIGITAIS do Arduino para tanto. O Arduino UNO possui PWM nos pinos 3,5,6,9,10 e 11. A reso-
lução do PWM é de 8 bits, ou seja 255 valores. Isto implica que podemos dividir o duty cicle em
256 unidades, a fim de gerar tensões RMS menores. A frequência de operação é de 980Hz para
os pinos 5 e 6, e de 490Hz para os demais [1].
Neste caso, podemos então controlar apenas o duty cicle do PWM do Arduino UNO, no qual sua
resolução será de aproximadamente 0,02V por bit de incremento no duty cicle. Veja a estrutura
do comando:

• analogWrite(’pino’,’duty cicle’);

Sendo ’pino’, os pinos de PWM do seu Arduino;


Sendo ’duty cicle’ o valor do duty cicle de 0 a 255;
obs: não esqueça de configurar o pino como saída.

7.5 prática 4 - variando luminosidade do LED


Alguns equipamentos necessitam de filtros que estabilizem a forma de onda e a tornem igual
o valor RMS, outros não necessitam disso e podem ser controlados diretamente pelo PWM sem
filtro, este é o caso do LED. Esta prática não afere nenhuma entrada, apenas envia sinal para dois
LEDs. Um ficará constantemente aceso e o outro irá variar seu brilho conforme o tempo passa.
Faça a montagem seguindo a figura 20 e utilize o código da figura 21:

34
Veja que no código, temos uma variável ao qual chamei de ’i’. Além de efetuar a contagem no
laço for, podemos usar ela para indicar qual o duty cicle no PWM.
No próximo capítulo vamos entender como usar o monitor serial do Arduino e o ploter; Desta
forma poderemos aferir os dados em tempo real e conferir se nosso algorítmo está operando cor-
retamente, se sensores e atuadores estão respondendo e até poderemos comunicar diretamente
do computador para o Arduino, enviando comandos em tempo real.

35
Figura 20: circuito prática 4 - Fonte: autor

Figura 21: código prática 4 - Fonte: autor

36
8
Monitor Serial
SECTION

Neste capítulo iremos entender o que é o monitor serial do arduino, como ele pode nos aju-
dar a "enxergar"o comportamento do nosso código e realizar uma comunicação simples com o
computador. Também faremos exercícios de fixação.

8.1 Monitor Serial do Arduino


O Arduino utiliza da própria IDE e conexão USB com o computador para transmitir os dados
e torna-los visíveis ao usuário, por meio de comunicação serial. Desta forma é possível, por
exemplo, visualizar o valor de uma variável, o gráfico e forma de onda do sinal de um sensor, co-
municar com o Arduino pelo seu computador dando comandos específicos e assim por diante.

8.2 Vendo dados no monitor serial


O monitor serial mostra tanto dados de variáveis, como também os plota automaticamente num
gráfico [2]. Se vocês estiver usando a IDE do Arduino, deverá clicar na opção como mostrado na
figura 22:

8.3 Código do Monitor Serial


Para podermos usar o monitor serial, precisamos inicializar ele via código em duas etapas. Se-
gue a sintaxe:

37
Figura 22: monitor serial e ploter - Fonte: autor

• [Link](9600);

OBS: o 9600 é a taxa de transmissão de bits por segundo. Este é um valor padrão, porém pode
ser modificado de acordo com a necessidade do projeto.
este código deve ser inserido dentro da função void setup para habilitar o monitor serial e os
pinos digitais 0 e 1 do seu Arduino devem estar livres para evitar problemas de conflito interno.
O comando anterior vai permitir que você ative a janela de monitor e ploter mas não vai mostrar
os dados, pois vc precisa indicar a variável a qual você deseja aferir e mostrar os valores, logo use
o comando:

• [Link](’variavel’);

No qual ’variável’ é o nome da variável que você quer monitorar. Coloque este código toda vez
que você quiser aferir o valor ou atualizálo. Faça o código como a seguir, para o exemplo 4:

8.4 prática 4 com monitor serial


Refaça a prática 4 do capítulo anterior, só que inserindo os códigos do monitor e ploter. Veja se
está similar a figura 23. Utilize o código da figura 24:

38
Figura 23: pratica 4 - monitor serial e ploter - Fonte: autor

Você perceberá no código que existe uma função um pouco diferente da print, e isso eu vou
explicar na próxima secção.

39
Figura 24: prática 4 - código com monitor Serial - Fonte: autor

40
8.5 Usando Monitor serial como prompt de comando na IDE
Para enviar comandos do monitor serial para o Arduino, temos que conhecer alguns comandos
possíveis, neste caso, vou pedir para você acessar o link [Link]
pt/language/functions/communication/serial/ e ler todos os comandos. Porém vou ex-
plicar de forma mais sucinta os mais usados [2]:

• [Link]();

escreve dados porém já convertendo para código ASCII, que no computador é lido como um
valor hexadecimal a partir da tabela ASCII, mas para o nosso monitor já é interpretado como
um caractere alfanumérico. Necessita aplicar para o texto lido e não pula linha automático,
sendo necessário o comando
n para pular linha.

• [Link]();

Mesma coisa do [Link], mas já pula linha automático.

• [Link]();

Retorna o valor lido pelo monitor serial, caractere a caractere já convertido para código ASCII.
Quando o comando [Link] é acionado e não digitamos nada, o serial monitor lê ’0’. Pode-
mos usar esse fato para controlar quando queremos que nosso monitor serial leia e grave numa
variável o valor, mas se atente que o valor passado é inteiro mas corresponde ao código ASCII
em DECIMAL. Então por exemplo, se você digitar ’0’ e mandar mostrar na tela, vai aparecer ’48’,
pois equivale ao número 0 na tabela ASCII.

• [Link]();

Igual a função anterior, mas neste caso já lê uma string completa e pode ser manipulada direta-
mente sem estar no formato ASCII.

• [Link]();

Este comando retorna quantos bytes estão sendo usados na leitura do monitor serial. O máximo
de bytes que podemos escrever e ler é 64 (não é um editor de texto, mas da pra escrever muita
coisa, ja que cada caractere alfanumérico ocupa 1 byte). Quando nada é lido no monitor serial,
esta função retorna 0. Use uma estrutura condicional no programa ex: ([Link] > 0), para
que você possa identificar quando nada é escrito no monitor serial por exemplo.

• [Link]();

Se você digitar números e enviar para o monitor serial, ele vai "zoar"tudo, pois como eu disse
anteriormente, o monitor converte para decimal, caractere a caractere. Então no lugar de Se-
[Link], você usa essa função para ler inteiros. Faça um teste e coloque diferentes inteiros,
positivos e negativos, letras e float. Veja o que acontece.

• [Link]();

Mesma função do [Link], só que para floats. Lembrando que no Arduino, a cada deci-
mal é separa por ’.’ e não por ’,’.

41
8.6 Variável do tipo string
O Arduino possui uma facilidade imensa para ler strings. Enquanto que num microcontorlador
normal você deve criar um vetor do tipo char para armazenar caractere a caractere e caso queira
mostrar a palavra escrita, você deve ler o vetor com laço for, no Arduino, basta você declarar a
variável como do tipo string.
Você pode fazer no método ’old school’ e criar um vetor char, mas na maioria dos casos não é
preciso.

8.7 Prática 5 - Controlando Arduino pelo monitor serial


Veja o código de exemplo da figura 26 para ler uma string no monitor serial e acender um led
quando a palavra correta for inserida. Faça o esquemático da figura 25:

Figura 25: prática 5 - circuito - Fonte: autor

42
Figura 26: prática 5 - código - Fonte: autor

Nessa prática, escreva ’ON’ no monitor serial e depois clique em ’enviar’, o LED irá acender em
seguida. Faça o mesmo para a palavra ’OFF’, o LED irá apagar. Você pode capturar dados na
forma de string com o comando [Link](), desta forma algumas lógicas de automação
e monitoramento pelo Arduino podem ser executadas, faça algo para você brincar e se acostu-
mar a essa funcionalidade do Arduino.

Se você quiser entender outras funções adicionais e comandos mais avançados, basta acessar
o link: [Link]

43
9Bibliotecas
SECTION

Neste capítulo iremos entender o que são bibliotecas, sua importância para o arduino e como
utilizá-las.

9.1 O que são bibliotecas?


Bibliotecas são códigos prontos que você importa para o seu programa, porém você não tem
acesso direto ao código mas sim a sua funcionalidade, acessando as funções geradas. Bibliote-
cas permitem que possamos utilizar equipamentos vinculados ao Arduino como: conversores,
protocolos de comunicação, leitura de sensores, envio de sinais para atuadores, programação
gráfica, etc... de forma simples e que não necessita de um domínio extremamente aprofundado
do programador.
Devido a característica de ser ’open source’, diversas pessoas contribuem para elaboração de bi-
bliotecas de diversos equipamentos, muitas vezes a própria empresa fabricante gera uma biblio-
teca para seu produto, a fim de tornar mais atrativo seu uso e disseminação. Usar bibliotecas não
é ’pecado’, pelo contrário, possibilita uma expansão no conhecimento e utilização do Arduino
para diversos problemas, porém, seu uso deve ser pensado e planejado, pois como bibliotecas
são códigos em que o usuário não tem o controle total, conflitos de alocação de memória, uso
de funções de pinos e registradores internos e até conflitos de variáveis podem ocorrer.
Minha sugestão é: use bibliotecas para aprender a utilizar o equipamento ao qual ela foi proje-
tada, porém, estude também a biblioteca e verifique quais registradores ela necessita. Somente
assim, você poderá integrar duas ou mais bibliotecas num mesmo programa, assegurando que
não haverá conflitos ou sobreposição de funções [5].

44
9.2 Como importar bibliotecas
Importar uma biblioteca é você trazer ela para o seu programa, deixando-a disponível na IDE do
Arduino e podendo defini-lá no cabeçalho do programa. Existem 3 formas:

9.2.1 Pasta Separada

Nessa forma, você deverá abrir o diretório do Arduino no seu computador e achar a pasta ’li-
braries’. Dentro desse diretório você coloca a pasta contendo a biblioteca que você baixou na
internet. Fontes confiáveis são do fabricante do equipamento, GitHub ou da página oficial do
Arduino. Fontes confiáveis, além de não trazerem virus para o seu computador, são asseguradas
que irão funcionar e estão otimizadas, muitas vezes possuindo várias versões, mas em todo caso
seu antivirus deve dar conta.
Para achar a pasta ’libraries’ com facilidade siga os passos dentro da sua IDE:

Figura 27: Achando pasta do Arduino no PC - Fonte: autor

Copie o link e vá no seu explorador de arquivos para encontrar a pasta raíz do Arduíno. Dentro
dela haverá a pasta ’libraries’, basta colar a pasta da biblioteca dentro:

Figura 28: Inserindo biblioteca - Fonte: autor

45
Para verificar se deu certo e acessar a biblioteca na IDE, basta seguir a imagem:

Figura 29: Usando biblioteca - Fonte: Autor

46
Depois de selecionar a biblioteca, ela será importada para o seu programa e no cabeçalho vai
aparecer a escrita padrão em C++ para inserção de biblioteca (#include <biblioteca.h>). Você
também pode ver exemplos de como usar a biblioteca:

Figura 30: Exemplos da biblioteca - Fonte: autor

47
Se você tiver preguiça de ler ou não entender algo, pode caçar na internet como usa determinada
biblioteca. Lembre-se sempre de incluir a biblioteca no cabeçalho do programa para poder usá-
la, mas somenete depois de adicioná-la a IDE, como mostramos. Agora os outros métodos de
fazer isso.

9.2.2 arquivo .ZIP

As vezes a biblioteca bem compactada num arquivo .ZIP, então basta adicionar. Neste caso,
acesse a IDE como mostrado e selecione o arquivo .ZIP da biblioteca. Este método automatica-
mente inclui uma cópia na pasta ’libraries’ e já deixa disponível a biblioteca na IDE:

Figura 31: incluir biblioteca .ZIP - Fonte: autor

48
9.2.3 Importando dentro da IDE

Este é o método mais confiável, pois busca diretamente do banco de dados online da página
oficial do Arduino. Basta acessar como na figura e procurar pelo nome da biblioteca ou compo-
nente desejado:

Figura 32: incluir biblioteca dentro da IDE - Fonte: autor

Depois é só instalar ou atualizar a biblioteca.

9.3 Limpando EEPROM


A memória EEPROM do arduino é preenchida conforme novos programas são gravados no mesmo.
Ela armazena dados não voláteis dos programas, normalmente vinculados a processos de gra-
vação e bibliotecas prontas. De tempos em tempos, procure utilizar a biblioteca ’EEPROM’ com
o código de exemplo ’EEPROM_CLEAR’. Este irá limpar toda memória do seu arduino e impedir
que erros possam ocorrer durante a gravação ou execução do código.

9.4 Outras informações


Se voce desejar analisar o código fonte de uma biblioteca, este estará disponível dentro da pasta
da biblioteca num arquivo de texto em C++ ou C. Nesta apostila o foco é a fácil utilização do

49
Arduino e suas funções e não a programação em si. Neste caso não irei explicar como criar bibli-
otecas, mas sugiro que tenha uma boa noção de C e C++ e POO, caso queira criar sua biblioteca.
Esse conteúdo você acha facilmente na internet. A partir de agora iremos fazer uso constante
de bibliotecas, lógico que tudo será detalhado, mas elas irão facilitar nosso entendimento sobre
outros conteúdos.

50
10
Protocolos de Comunicação

10.1 O que são protocolos de comunicação


do Arduino
S ECTION

Protocolos de comunicação são um conjunto de regras e diretrizes a serem seguidos tanto em


hardware como em software para que seja possível o envio e recebimento de dados entre dois
sistemas distintos. Desta forma, estamos a falar então de uma padronização na metologia de
comunicação. Cada sistema opera com um ou mais protocolos de comunicação mas para co-
municar entre diversos sistemas, um mesmo protocolo deve ser usado. Para cada caso/fabri-
cante, um protocolo é mais indicado e caso ocorra incompatibilidade, conversores podem ser
utilizados (como veremos). Antes de explicar os protocolos de comunicação que o Arduino UNO
opera, devemos entender alguns princípios básicos, porém peço que você tenha um mínimo de
noção sobre sistemas digitais, pois esta parte depende desse conteúdo [30].

10.1.1 Comunicação SERIAL

Neste tipo de comunicação, os dados (bits) são transmitidos sequencialmente por um mesmo
caminho (fio condutor, por exemplo), sendo necessário um tempo entre o envio do sinal pelo
emissor, até o recebimento e confirmação do receptor. Apesar desse protocolo ser mais lento,
pois são necessários vários envios até que toda informação seja transmitida, ele é mais seguro
e permite implementação de métodos mais eficazes contra ruídos e perda de informação, além
de ser mais barato e mais simples de utilizar pelo usuário final. Um exemplo de comunicação
serial é o cabo USB do seu computador, porém existem variações desse tipo que serão mostradas
adiante [30].

51
10.1.2 Comunicação PARALELA

Neste tipo de comunicação, os dados são transmitidos todos juntos em diferentes caminhos (vá-
rios fios condutores, por exemplo), desta forma uma mensagem maior ou até completa, pode
ser transmitida diretamente do emissor para o receptor em um tempo muito reduzido. Todavia,
esse método é mais suscetível a falhas por ruído e perda de informações, além de ser mais com-
plexo para o usuário final. Um exemplo, são os antigos cabos de impressora que utilizavam o
protocolo IEEE 448 (acho que hoje em dia isso virou lenda), no qual cada pino tinha uma função
de transmitir um sinal diferente. Para que fique mais claro, um pino servia para enviar um dado
de posição inicial da tinta de impressão, outro autorizava a impressão, outro pino indicava o
nível de tinta, outro autorizava a impressora a ligar, etc...
Se isso fosse feito em comunicação serial (o que foi feito com o protocolo RS232 depois), mesmo
tendo um conector parecido e cheio de pinos (por razões de adaptação dos conectores), nem
todos os pinos eram usados e ele já possuia os pinos de comunicação serial RX e TX (como
veremos), porém ainda possuia alguns pinos auxiliares mas não vinculados diretamente a co-
municação. Posteriormente se tornou um protocolo "100%"serial, quando foi substituido pelo
USB [30].

10.1.3 Taxa de Transferência de Dados

É a velocidade com a qual podemos transmitir a informação. Se o seu sistema for síncrono
(depende de clock) ela é dada em bits por segundo (bps). Se a comunicação for assíncrona,
ela é dada em Baud Rate (Bd), muitas vezes confundido ou nomeado como (bps). Todavia, a
informação assíncrona acaba sendo mais rápida que a síncrona, logo não podemos considerar
1bps sendo igual para ambos os sistemas [30].

10.1.4 Transmissão Síncrona

A transmissão síncrona não é exclusiva de sistemas seriais, porém como a comunicação para-
lela foi quase totalmente abandonada para protocolos de comunicação comerciais, os exemplos
dados são em 99% dos casos, com protocolo serial. No caso da transmissão síncrona, tanto o re-
ceptor como o emissor operam com um mesmo sinal mestre de sincronia chamado CLOCK. É
o clock que gerencia o tempo que cada componente tem para enviar e receber o sinal e man-
ter a coerência entre sinal lido e enviado, uma vez que na comunicação serial é necessário um
parâmetro para distinguir um sinal de outro. Na comunicação paralela, era usado apenas para
sincronizar o tempo de envio do de recebimento, não tendo a necessidade de separar os sinais,
já que eles eram enviados todos juntos por caminhos distintos (não no mesmo barramento) [30].

10.1.5 Transmissão Assíncrona

A transmissão assíncrona não depende de um CLOCK que comanda tanto o emissor como re-
ceptor, tendo cada um o seu próprio clock. Todavia, é necessário que o Baud Rate de ambos os
sistemas seja igual para não haver erro de comunicação [30].

52
10.1.6 Simplex

Neste caso, o dispositivo de comunicação só pode ou enviar ou receber o sinal, sendo impossível
que o receptor envie informação e o emissor receba informação [30].

10.1.7 Half-Duplex

Agora tanto o emissor como receptor podem inverter seus papéis, enviando e recebendo infor-
mações, porém um de cada vez. Enquanto um envia o sinal, o outro só pode receber [30].

10.1.8 Full-Duplex

Agora ambos, emissor e receptor podem inverter os papéis e podem enviar e receber informa-
ções ao mesmo tempo, sem ocorrer conflito [30].

10.2 Protocolos de comunicação no Arduino


Existem diversos protocolos de comunicação, alguns podem até ser inseridos no Arduino (como
o CAN), porém os originais que são usados na maioria dos Arduinos estão listados a seguir, bem
como uma explicação de uso:

10.3 UART - Universal Asynchrounous Receiever/Transmiter


• Tipo de Transmissão: Assíncrono

• Forma de Transmissão: Full - Duplex

• Tipo de comunicação: Serial

• Nº fios de comunicação usados: 2

• tensão de operação: 0V a 5V

• Nº dispositivos comunicados: 1 receptor e 1 emissor

• Taxa de Transmissão: 1200 a 115200 (Baud Rate)

Este protocolo é utilizado no Arduino UNO para fazer a comunicação entre o microcontrola-
dor e o computador, permitindo que possamos usar o monitor SERIAL e o ploter, como mos-
trado em capítulos anteriores. Também podemos usar para comunicação entre sensores que
usam esse protocolo e entre Arduinos. No Arduino UNO, os pinos digitais 0 e 1 estão vincu-
lados a este protocolo e não devem ser usados quando o mesmo estiver ligado ao computador,
pois podem causar problemas. Acesse [Link]
functions/communication/serial/ para entender mais sobre as funções desse protocolo na
placa, porém o método de inicialização dele já foi apresentado em capítulos anteriores, quando
aprendemos a manipular o monitor serial do Arduino na IDE e como ler strings e outras coisas
[30].
Esse protocolo possui 2 pinos de comunicação, o RX e o TX. PRESTE ATENÇÃO, o RX do emissor
vai ligado ao TX do receptor e o TX do emissor vai ligado ao RX do receptor, ou seja, faça a ligação

53
cruzada. Nunca esqueça de ligar os fios de GND entre os componentes. No Arduino UNO (a não
ser que você projete uma placa) não tem como mecher nisso, já que só tem 1 porta serial UART.
Porém outros tipos podem ter várias portas, por isso a explicação. Veja a figura 33:

Figura 33: Comunicação UART no Arduino UNO - Fonte: Autor

Não confunda, todos os protocolos apresentados aqui serão serial, porém a UART especifica-
mente, todo mundo chama de serial não sei o porquê. Mas quando você ver serial, procure
perceber se estão se referindo a qualquer protocolo ou especificamente a UART.

54
10.4 I2C
• Tipo de Transmissão: Síncrono

• Forma de Transmissão: Half - Duplex

• Tipo de comunicação: Serial

• Nº fios de comunicação usados: 2

• tensão de operação: 0V a 5V

• Nº dispositivos comunicados: 127 ou 1024

• Taxa de Transmissão: 100kbps ou 400kbps

Vamos explicar alguns aspectos desse protocolo para depois mostrar como utilizá-lo.
Em relação ao HARDWARE, este protocolo possui 1 MESTRE e os demais dispositivos são ES-
CRAVOS. O mestre envia o sinal de clock lido por todos, a partir do barramento SCL. entre todos
os componentes esse barramento é interligado, ou seja, você conecta o SCL de um no outro.
Para a comunicação, se usa o pino SDA, também compartilhado entre todos os componentes.
Apesar de ter 1 mestre por vez, você pode alterar entre qual dispositivo será o mestre, se este
permitir. Ambos os barramentos SCL e SDA necessitam que hajam resistores de pull up, no va-
lor próximo de 4.7K e os pinos de GND de todos os dispositivos devem estar conectados [30]. A
figura 34 mostra um esquema de ligação típico para I2C:

55
Figura 34: Esquema ligação protocolo I2C - Fonte: Autor

Uma vez que a comunicação ocorre, o mestre envia o sinal para todos os dispositivos simul-
taneamente, porém cada escravo só irá realmente receber a mensagem se seu endereço estiver
relacionado. O endereço é literalmente um endereço de memória fixo, no qual o hardware indica
um valor binário de 7 bits e que convertendo para hexadecimal, vão de 0x00 até 0x127, ou seja,
podemos comunicar 128 dispositivos distintos ao mestre, tudo no mesmo barramento. Alguns
hardwares possuem 8 bits, sendo o oitavo bit referente a leitura ou escrita fixos (0 para escrita,
1 para leitura). Caso seja de 7 bits, então o dispositivo pode ser usado tanto para leitura como
escrita OU possui uma função fixa que é definida via software. A maioria dos dispositivos é de
7 bits, gerando o endereço hexadecimal descrito anteriormente. É de suma importância que
os endereços não conflitem entre dispositivos, pois senão ocorrerá erro na comunicação, então
assegure que cada dispositivo está com o hardware configurado para um endereço único a ele
naquele barramento. Em próximos capítulos estudaremos componentes que usam I2C e desta
forma vou detalhar como selecionar o endereço no hardware. Não é obrigatório o uso sequen-

56
cial de endereços entre componentes (1,2,3.... pode ser 1,22,48,127, por exemplo) [30].

Agora falando sobre o software, a biblioteca para uso do protocolo I2C já vem previamente ins-
talada na sua IDE do Arduino, chamada de ’Wire’. Faça um #include <Wire.h> para importar a
biblioteca do protocolo I2C [5]. A seguir, eu listo alguns comandos úteis para usar a biblioteca:

• [Link]()
inicializa o protocolo I2C no Arduino

• [Link](’endereço’)
inicia a comunicação entre o Arduino e o periférico desejado. no lugar de ’endereço’, você
coloca o endereço real do componente em hexadecimal.

• [Link](’dado’)
Escreve (envia) um dado para o barramento. só será lido pelo escravo, caso seu endereço
tenha sido referenciado já com a função ’begintransmission’. No lugar de ’dado’ insira o
dado a ser enviado.

• [Link]()
esta função retorna um valor inteiro baseado em quantos bits estão sendo enviados no
barramento. Se for ’0’, então o barramento está livre e pronto para receber comunicação.

• [Link](’slave’,’bits’)
comando para requisitar informação do escravo. no lugar de ’slave’ coloque o valor do
endereço em hexadecimal do componente e no lugar de ’bits’ coloque quantos bits de
dados deseja receber.

• [Link]()
após o comanod anterior, pode-se usar este para salvar em alguma variável os valores
recebidos. faça uma atribuição de uma variável a este comando.

• [Link]()
finaliza a comunicação I2C entre o mestre e o escravo no endereço selecionado.

• Outros comandos podem ser aprofundados em [Link]


wire

10.4.1 Prática 6 - exemplo de comunicação I2C entre Arduinos

Vamos dar um exemplo de código comunicando dois Arduinos via I2C. O objetivo é que um Ar-
duino dê o comando para o outro acender um LED. Note que no Arduino UNO, os pinos SDA e
SCL são respectivamente os pinos ’A4’ e ’A5’. A seguir temos o esquema de ligação entre Ardui-
nos (com o barramento I2C) e o código de exemplo nas figuras 35, 36 e 37:

57
Figura 35: Esquemático entre Arduinos UNO para I2C - Fonte: Autor

Veja que no esquemático, os pinos SDA estão ligados entre si, bem como os SCL, ambos inter-
conectados a resistores de pull up de 4,7k. A alimentação de 5V fornece o nivel lógico alto para
o resistores e todos os negativos (GND) estão conectados entre si.
Na parte da programação se atente ao comando [Link](), pois seu parâmetro de en-
trada é uma função que executa uma rotina para o recebimento do sinal. sugiro estudar melhor
essa função para que você possa absorve-la, tudo disponível na página oficial do Arduino.

Figura 36: Programa I2C no Arduino MESTRE - Fonte: Autor

58
Figura 37: Programa I2C no Arduino ESCRAVO - Fonte: Autor

10.5 SPI
• Tipo de Transmissão: Síncrono

• Forma de Transmissão: Full - Duplex

• Tipo de comunicação: Serial

• Nº fios de comunicação usados: 3 (+1 para cada escravo adicional)

• tensão de operação: 0V a 5V

• Nº dispositivos comunicados: sem limite

• Taxa de Transmissão: 0 a 2Mbps

Este protocolo possui 4 barramentos principais:

10.5.1 MOSI - Master Out, Slave In

Este barramento é responsável pelo envio dos dados do mestre para o escravo. Todos os pinos
MOSI devem se interligar [30].

10.5.2 MISO - Master In, Slave Out

Este barramento é responsável pelo envio de dados do escravo para o mestre. Todos os pinos
MISO devem se interligar [30].

59
10.5.3 SCLK - Serial clock

Este barramento é responsável por enviar o sinal de clock síncrono do mestre para todos os
escravos. Todos os pinos SCLK devem estar interligados entre si [30].

10.5.4 SSx - Slave Select

Estes pinos são responsáveis pela seleção do escravo que vai comunicar com o mestre. Quando
o pino está em nível alto, o escravo IGNORA o mestre. quando o pino está em nível baixo, o
escravo COMUNICA com o mestre. Para cada escravo, devemos ter um barramento SSx sendo
ligado ao mestre, então para cada novo escravo, é adicionado um barramento [30]. Veja a figura
38:

Figura 38: Protocolo SPI - Fonte: [Link]/tutoriais

60
Para o Arduino, a figura 39 mostra a pinagem para comunicação SPI:

Figura 39: pinagem Arduino para SPI - Fonte: [Link]

Lembre-se de sempre conectar os GNDs de todos os componentes no circuito. Outra coisa im-
portante a salientar é que, como temos apenas 1 pino SSx, se precisarmos controlar mais de 1
dispositivo conectado ao barramento, devemos usar um multiplexador no pino do SSx e alguns
pinos digitais (depende do tamanho do multiplex) para selecionar qual componente escravo
será comunicado. Iremos fazer isso em práticas futuras quando precisarmos de mais de um
componente SPI.
Na parte da programação, devemos fazer a declaração da biblioteca SPI.h (#include <SPI.h>), já
padrão da sua IDE. Uma coisa importante a considerar é o modo de operação do barramento
SPI. Antes de explicar, vamos inserir um pouco de vocabulário necessário:

• CPOL - Polaridade do clock


indica qual o estado inicial que o clock deve assumir para começar a comunicação ou
autorizar o envio e recebimento de sinais [13].

61
• CPHA - Fase do clock
indica em qual borda os dados devem ser inseridos ou desativos no barramento, ou seja,
qual borda irá separar as informações seriais recebidas [13].

A figura 40 ilustra os 4 modos de operação que podem ser obtidos ajustando o CPOL e o CPHA:

Figura 40: Modos de operação do SPI - Fonte: [Link]

• MODE 0 e MODE 3: captura o dado na borda de subida, e o término do dado é indicado


pela borda de descida, estão defasados de 90º os sinais entre si, porém ambos operam da
mesma forma [13].

• MODE 1 e MODE 2: captura o dado na borda de descida e o término do dado é indicado


pela borda de subida, estão defasados de 90º os sinais entre si, porém ambos operam da
mesma forma [13].

Esses modos de operação são necessários para comunicar corretamente o escravo ao mestre e
são parâmetros da biblioteca a serem definidos.
A seguir eu listo algumas funções úteis que serão usadas, mas todos os comandos da biblioteca
você pode acessar em [Link]

• [Link]()
Inicializa o protocolo SPI

• [Link](’parâmetro’)
define se a leitura da mensagem partirá do bit mais signficativo ou do menos significativo.
Em ’parâmetros’ use ’LSBFIRST’ ou ’MSBFIRST’, para definir a leitura do menos significa-
tivo ou mais significativo, respectivamente.

62
• [Link](’parâmetro’)
Indica por quanto o clock do Arduino será dividido para ser usado na comunicação (clock
do barramento SCLK). Por padrão o Arduino usa um cristal de 16MHz e o mínimo é um
clock de 4MHz. Não use um clock maior do que o dispositivo a ser comunicado. Em ’pa-
râmetro’ use os comandos: ’SPI_CLOCK_DIV2’,’SPI_CLOCK_DIV4’, ’SPI_CLOCK_DIV8’,
’SPI_CLOCK_DIV16’ ... ’SPI_CLOCK_DIV128’.

• [Link](’parâmetro’)
Define o modo de operação da comunicação SPI. Em lugar de ’parâmetro’, use: ’SPI_MODE0’
ou ’SPI_MODE1’ ou ’SPI_MODE2’ ou ’SPI_MODE3’.

• [Link](’parametro’)
função para envio e recebimento de dados. Em ’parâmetros’ indica o dado a ser enviado.
esta função sempre recebe um retorno resultado da operação de envio.

• [Link](’bits’,’modo’)
indica em ’bits’ quantos bits de dados serão transferidos e em ’modo’ o modo de operação.

• [Link](’frequencia’)
indica a frequencia do SCLK (clock). O valor padrão é 1MHz.

• [Link](’dados’)
a mesma coisa da função transfer, pois envia o dado e retorna o valor lido, lembrando que
a comunicação é full duplex, por isso.

10.5.5 Prática 7 - exemplo de comunicação SPI entre 2 Arduinos

Nesta prática faremos algo análogo a prática 6, tendo um Arduino mestre, um escravo e envi-
ando o sinal do mestre para o escravo e assim acionando um led na saída. A seguir temos o
esquemático de ligação e os códigos de exemplo do mestre e do escravo:

63
Figura 41: prática 7 - comunicação SPI entre arduinos (hardware) - Fonte: adaptação do
autor

Para cada código na figura 42, grave em um arduino diferente e efetue a ligação elétrica como
mostrado na figura 41. Ligue os arduinos a duas entradas USB distintas do seu computador, não
esqueça de alterar a porta USB correta na IDE para alterar entre o mestre e o escravo. Após com-
pilar e gravar em cada arduino, seu respectivo código, você deve abrir o monitor serial do mestre
e digitar alguma coisa e enviar. Esse dado será lido pelo escravo e armazenado. O código da
figura 42 não realiza nenhuma outra ação além de receber dados pelo escravo, logo, você pode
criar alguma condição para verificar a transmissão de dados ou analisar pelo osciloscópio.
Infelizmente, a biblioteca SPI do arduino é muito mais desenvolvida para código de mestre já
que, normalmente, o arduino atua como o mestre, lendo os dados dos periféricos que são escra-
vos, desta forma, o código do escravo é um pouco mais "feio".

64
Figura 42: prática 7 - comunicação SPI entre arduinos(software) - Fonte: adaptação do
autor

65
10.6 Prática 8
Pesquise sobre outros protocolos de comunicação para arduino ou que possam ser adaptados
como CAN, Ethernet, 1 wire ...

10.7 Prática 9
Pesquise shields e periféricos utilizados no arduino com os protocolos estudados nesse capítulo.

66
11.1 O que são interrupções
11 Interrupções
S ECTION

Interrupções são paradas programadas no programa para realização de uma ação. As condições
de parada podem ser externas (sinal) ou internas (flag ou lógica). Uma interrupção não trava o
código em uma determinada linha (como o comando delay() ), mas sim o redireciona para uma
outra função ou trecho de código. Devido a isso, o microcontrolador não para sua execução e
não ocorrem conflitos de sincronização entre informações recebidas ou enviadas. Claro que o
microcontrolador executa uma tarefa de cada vez, mas as interrupções permitem que diversas
partes (tanto hardware como software) sejam monitoradas e analisadas sem perda na coerência
do processamento.O Arduino uno possui dois pinos de interrupção externa(int0 e int 1, respec-
tivamente pinos D2 e D3) e uma rotina para interrupção interna, vamos estuda-los com calma
[32].

11.2 Interrupção Externa


Para o caso do Arduino uno, temos a INT0 e INT1, nos pinos D2 e D3 respectivamente. Alguns
comandos abaixo podem ser usados para interrupção:

• attachInterrupt(’interrupção’, ’ISR’, ’modo’);


verifica se a condição para interrupção ocorreu e desvia o código para a função a ser exe-
cutada no caso da interrupção.
No lugar de ’interrupção’ indique 0 ou 1 para INT0 ou INT1 respectivamente;
No lugar de ’ISR’ indique o nome da função criada que será executada durante a interrup-

67
ção. A função deve ser do tipo void e não pode ter parâmetros de entrada;
No lugar de ’modo’, indique LOW (aciona quando pino em nivel baixo), CHANGE (aciona
quando houver uma transição de borda do sinal), RISING (aciona na borda de subida),
FALLING (aciona na borda de descida) [32].

• noInterrupts();
Função para desabilitar todas as interrupções.

• interrupts();
Função para habilitar todas as interrupções desabilitadas pelo noInterrupts.

11.3 Prática 10 - interrupção externa


Nesta prática vou te propor um desafio... Você precisa com o seu Arduino, enviar um sinal por
meio de um botão e quando o botão for acionado (pressiona e tira o dedo em seguida), um led
deve acender. Ao mesmo tempo, um outro led deve ficar piscando bem rápido. O desafio é que
quando você pressionar o botão, o led de acionamento deve agir imediatamente, respondendo
ao botão e o led auxiliar que pisca não pode travar ou perder o passo. Se você tentar isso com
pulling (delay) vai dar errado (experimente...).
Se você não conseguiu fazer o código, a figura 43 e 44 contém o circuito físico para montagem e
a programação usando interrupção externa:

Figura 43: Esquemático de montagem prática 10 - Fonte: autor

Perceba que a rotina de interrupção já trata o botão quando ocorre uma borda de descida, uma
vez que ele está ligado em pull down. Quando isso acontece, implica que o usuário pressionou

68
Figura 44: código prática 10 - Fonte: autor

e soltou o dedo do botão e por isso o led (neste caso escolhi o vermelho) deve inverter seu es-
tado. Logo a função, ao qual o código é desviado, para ser executada precisa tratar apenas do led.
essa função que dei o nome de ’rotina_interrupção’ possui um laço ’for’ inicial, para gastar um
pouco de tempo, isso porquê para botões, podem acontecer o efeito ’bouncing’ e o pino digital
interpretar vários pulsos. Para corrigir isso, você pode implementar um sistema antibouncing
(com seus conhecimentos de eletrônica digital) ou fazer o tratamento via software (igual o que
eu fiz). Neste caso, voce retem o software naquele ponto de execução até o transitório passar,
desta forma, como em 16MHz o tempo de operação do Arduino é de 250nS, um laço de 10000
repetições obrigaria o programa a realizar essa operação por 25mS, que normalmente é sufici-
ente para corrigir o efeito de bouncing, qualquer coisa pode-se aumentar o tamanho do laço.
Em seguida, eu fiz o comando para alterar o estado do led.
Perceba que, mesmo no laço loop havendo pooling para o led verde, como a interrupção tem
prioridade na execução, e não trava o código, isso não interfere na dinâmica do laço ao mesmo
tempo que o pooling não afeta a interrupção, logo se torna possível a execução do programa
como descrito.

69
11.4 Interrupção Interna ou por timer
Esse tipo de interrupção possui um contador interno que, quando atinge um valor pré definido
da contagem, desvia para uma função a parte do código princial que é uma função de interrup-
ção. Quando o contador atinge o valor pré definido, dizemos que ocorreu o ’estouro do timer’ e
normalmente usamos uma flag (sinal indicativo) de que isso aconteceu. Devemos sempre lem-
brar de reinicializar o contador e sempre limpar a flag, voltando para o estado original [3].
Para usar a interrupção interna, devemos baixar e incluir a biblioteca ’TimerOne’.Em seguida,
devemos utilizar os comandos listados a seguir [31]:

• [Link](’time’)
essa função inicializa a interrupção por tempo e no lugar de ’time’ voce indica o tempo
em microssegundos.

• [Link](’função’,’time’)
esse comando indica qual função será chamada quando o estouro do timer1 for realizado.
No lugar de ’função’ coloque o nome da função auxiliar que você criou para executar a ro-
tina de interrupção. O parâmetro ’time’ pode ser substituido pelo tempo que você deseja
que essa função seja executada. Vamos supor que sua função auxiliar seja executada em
1 segundo, mas pode acontecer alguma coisa que a faça demorar ou ocasione erro. Neste
caso você pode indicar esse tempo ’time’ para obrigar a sair da sua função auxiliar e re-
tornar ao programa original. Tome muito cuidado pois isso normalmente causa erros de
memória, não sendo muito aconselhado. Se nada for digitado em ’time’ o programa só
retorna ao laço loop, quando a função auxiliar terminar de ser executada.

• [Link]()
disabilita a interrupção do timer1.

• outro comandos disponíveis em detalhes em [Link]


Timer1/

• [Link]()
para o contador interno do timer1;

• [Link]()
se pausado o contador, este comando retoma a contagem de onde parou;

• [Link]()
recomeça a contagem

• [Link](’time’)
no lugar de ’time’ insira o tempo do contador em microssegundos. este comando sobres-
creve o valor inicial definido para o timer

70
11.5 Prática 11 - Interrupção Interna
Nesta prática vamos fazer um pisca pisca com led, mas usando o timer. Veja as figuras 45 e 46:

Figura 45: Prática 11 - circuito elétrico - Fonte: autor

Figura 46: Prática 11 - Código - Fonte: autor

71
Uma coisa muito importante e que confundo é: A INTERRUPÇÃO INTERNA NÃO PODE SER
INSERIDA DENTRO DA FUNÇÃO LOOP!!! Isso porque a função loop ira repetir os comandos
dentro dela. A interrupção por sua vez deve trabalhar a parte, sendo independente e não sendo
declarada todas as vezes. Desta forma, a função setup se torna a única opção. Caso necessite de
alguma lógica diferente, utilize variáveis de controle para armazenar os valores de contagem e
realizar ações, baseado no estouro de timer. Outra informação importante é que o timer1 pos-
sui 16 bits, enquanto os outros dois timers (0 e 2) do Arduino uno possuem 8 bits. Todavia esses
timers estão reservados a funções ou bibliotecas internas/ específicas e não serão abordados.
Lembrando que, estamos trabalhando com o Arduino uno, por isso essa parte se torna mais li-
mitada. Caso operassemos com o proprio atmega 328p, sofreríamos muito na programação que
seria em C e em outra IDE, mas daria para extrair mais do hardware, todavia, não é necessário
para as nossas aplicações nesta apostila e na grande maioria dos casos.

72
12
Displays e dispositivos
S ECTION

visuais

Chamamos de displays os dispositivos que transformam os sinais elétricos para sinais visuais
que possam ser lidos ou interpretados. Displays são compostos de vários elementos lumino-
sos que nos permitem enxergar a informação enviada. Um simples led, apesar de comunicar
uma informação visual, será somente um display de leds quando tivermos vários deles a ponto
de conseguirmos manipular a informação visual, criando códigos e padrões mais complexos.
Desta forma, existem diversos tipos de displays e nesse capítulo iremos estudar os mais comuns
usados no Arduino uno e sua programação [33].

12.1 Display de 7 segmentos


Como solicitado no início da apostila, eu preciso que você tenha um mínimo de conhecimento
de eletrônica digital e analógica para que você compreenda alguns conceitos. Não iremos nos
aprofundar tanto no hardware, mas um mínimo é necessário para entender o funcionamento.
Um display de 7 segmentos é um conjunto de 7 leds (as vezes 8, no qual o oitavo representa um
ponto decimal), posicionados de forma a representar o número 8 (vide figura a seguir). A partir
disso, acionamos os leds de tal forma a representar um dos 10 algarismos (0 a 9) e podemos re-
presentar algumas letras ’a’,’b’,’c’,’d’... mas nem todas são possíveis.
Em alguns modelos, um mesmo invólucro comporta vários displays, tendo os 7 pinos para liga-
ção do dispositivo e formação dos números e pinos para selecional qual display será acionado
por vez.

Como o display é composto de leds, devemos nos preocupar com a configuração, se é catodo
comum (todos os leds estão ligados em comum pelo catodo, então nivel alto aciona cada led) ou

73
Figura 47: Display de 7 segmentos - fonte: ’diversas lojas de eletrônicos online’

são anodo comum (todos os leds estão ligados em comum pelo anodo, então nivel baixo aciona
cada led). Também não podemos esquecer dos resistores limitadores de corrente. Para 5V, use
por padrão 220Ω a 470Ω em c ad a l ed .

Figura 48: Configurações do display - fonte: não identificado

74
Podemos ligar diretamente 7 pinos digitais do Arduino aos 7 pinos do display (não esqueça dos
resistores), porém isso não é prático, pois usamos muitos pinos. Porém, podemos usar um de-
codificador para reduzir a apenas 4 pinos necessários ao funcionamento do display.
Nessa etapa eu preciso que você tenha conhecimento sobre codificadores e decodificadores,
pois para podermos usar o display de 7 segmentos necessitados de um decodificador de código
binário para display de 7 segmentos. Uma vez que o Arduino envia os sinais em binário a partir
dos seus pinos digitais, podemos com 4 bits representar os 10 algarismos no display. No total,
temos 16 possibilidades, porém como só precisamos de 10, ourtas 6 ficam livres para represen-
tar qualquer outra coisa. A maioria dos decodificadores de binário para display de 7 segmentos
assumem a respectiva tabela a seguir: No datasheet de cada decodificador você precisa iden-
tificar se ele serve para display de anodo comum ou catodo comum e também encontrará em
qual pino deve ligar os pinos do Arduino de envio de sinal e em quais pinos serão ligados aos do
display. Normalmente a sequência binária segue a decimal baseado no código BCD8421, mas
sempre é importante conferir no manual do fabricante essas informações [25].

Figura 49: Tabela verdade decodificador CD4511 - fonte: datasheet

75
12.2 Pratica 12.1 - acionando 1 display de 7 segmentos com decodifi-
cador CD4511
A seguir temos um esquemático com a montagem do Arduino para acionamento de um display
de 7 segmentos junto ao decodificador e a programação. Como a programação é mais complexa,
dividimos por bloco explicativo:

Figura 50: Esquemático pratica 12.1 - fonte: autor

No hardware, lembre-se de ligar os GNDs de todos os componentes entre si. Nesta montagem o
decodificador CD4511 é compatível com display catodo comum.

Figura 51: Código prática 12.1 (1ª parte) - fonte: autor

76
Figura 52: Código prática 12.1 (2ª parte) - fonte: autor

Vamos entender esse projeto: Na parte do HARDWARE, basta voce ligar dos pinos 8 a 11 digitais
nos pinos D,C,B,A que são respectivamente do MSB ao LSB. Depois basta ligar no display as saí-
das do decodificador: a,b,c,d,e,f,g. A figura 46 mostra qual pino é qual do display para ser ligado
ao decodificador. Use os resistores de 220R e uma tensão de 5V para alimentar o conjunto, pode
usar a mesma do Arduino.
Sobre o SOFTWARE, vamos entender o código, que por uma questão de tamanho e didática di-
vidi em 2 partes, mas que são sequencia direta uma da outra.
Na PARTE 1, começo definindo os pinos do Arduino e o nome bit1,..,bit4 como alusão a posição
MSB ou LSB. No void SETUP, defino todos como saídas e começam em nível baixo (display apa-
gado), e inicializo a serial pois iremos ver o monitor dela.
Na PARTE 2, antes da função LOOP, temos uma função auxiliar declarada que tem como parâ-
metro de entrada uma variável que servirá para contagem (0 a 9). Existem várias formas de você
indicar qual número será mostrado, mas eu preferi a mais simples (e menos otimizada), que é
criar uma matriz de 10 posições (linhas), contendo 4 bits (colunas). Veja que em cada linha es-

77
tão definidos (em binário) dos números 0 a 9. Quando dermos a posição da linha, estaremos nos
referindo ao número a ser acionado e quando selecionamos a coluna estamos escolhendo o bit
a ser mostrado (bit4 ao bit 1).
Tome cuidado pois na nossa nomenclatura, o bit4 é o MSB, mas para acessar a matriz nesse
ponto, você precisa da posição ’0’ na coluna e para o bit1 LSB, você precisa da posição ’3’.
Depois de declarado essa matriz, veja que na escrita digital em seguida, eu referencio qual pino
será acionado e qual será a sua coluna respectiva, sendo a variável ’cont’ o parâmetro de entrada
na linha para indicar qual número será mostrado no momento. Faço a mesma coisa para o mo-
nitor serial, porém mostrando qual número está sendo vinculado no momento, você pode ver
isso no seu monitor.

Dentro da função LOOP, a variável ’i’ irá de 0 a 9 e será o parâmetro de entrada da função ’con-
versao’, ou seja, ’i’ será ’cont’ dentro da função. Desta forma, um ’if’ é usado para garantir que
sempre que ’i’ for passar de 9 ele retorne a 0.

Existem várias formas de mostrar dados no display e essa é uma das mais comuns, embora não
muito otimizada. Na próxima prática, veremos como acionar mais de um display ao mesmo
tempo.

12.3 Pratica12.2 - Acionando 2 displays de 7 segmentos sem decodifi-


cador
Antes de continuarmos queria deixar um adendo, não é obrigatório fazer com decodificador, ele
apenas economiza pinos, porém eu quero mostrar como faz sem decodificador pois é o mesmo
processo. Neste caso, precisaremos de 7 pinos apenas para o display e mais 2 pinos para seleção
do display. A figura a seguir, mostra qual led devemos acender para formar o número desejado,
a partir disso iremos criar uma matriz semelhante a do exercício anterior.
Para que possamos acionar os displays "ao mesmo tempo"para vermos ambos os números, na
verdade usamos o efeito da persistência da visão humana, no qual a partir de uma frequência de
30Hz, não é mais possível detectar a falta da imagem. Desta forma, vamos hora ligar um display
e mostrar um número e hora ligar outro display e mostrar outro número, só que como vamos
fazer isso muito rápido (mínimo de 33ms) teremos a sensação de que ambos os displays estão
acesos e podemos ver eles.

78
Figura 53: tabela de acionamento do display de 7 segmentos -
fonte:[Link]

79
Figura 54: esquemático prática 12.2 - fonte: autor

80
Figura 55: código prática 12.2 (1ª parte) - fonte: autor

81
Figura 56: código prática 12.2 (2ª parte) - fonte: autor

82
Figura 57: código prática 12.2 (3ª parte) - fonte: autor

83
12.4 Display LCD
O display LCD, apesar de utilizar outra tecnologia, sua forma de operação é similar ao display
de 7 segmentos. A diferença agora é que ao invés de controlar apenas 7 elementos luminosos,
nos displays nós temos uma matriz deles. Vamos trabalhar com o display 16x2 (16 linhas por 2
colunas), no qual iremos repassar informações para ele, porém a lógica é a mesma para outros
tipos, sendo necessário implementar apenas a biblioteca respectiva ao seu display. Se você for
trabalhar com microcontroladores mais avançados que não possuem biblioteca, neste caso terá
de programar manualmente as configurações iniciais a serem enviadas ao display (ele possui
um microcontrolador interno que se comunica com o seu) e os dados. No Arduino, temos a bi-
blioteca ’LiquidCrystal.h’, ela já é padrão do Arduino, mas você pode baixar versões modificadas
para displays diferentes do LCD. A seguir temos a pinagem do nosso display [14]:

Figura 58: Pinagem Display LCD - fonte: [Link]

84
Usando a nossa biblioteca ’LiquidCrystal.h’devemos, baseado em suas funções de inicialização,
definir o hardware a ser usado compatível com a programação [6]. A seguir eu vou listar as prin-
cipais funções usadas para você entender:

• LiquidCrystal lcd(rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7)
os nomes dos parâmetros da função, são relacionados aos pinos do display que serão
controlados. Você então deve substituir pelo pino do Arduino que irá enviar o sinal para
o respectivo pino do LCD. Se o seu pino ’rs’ for controlado pelo pino D13 do Arduino,
por exemplo, você substitui por ’rs’ por ’13’ no código e assim por diante. Uma coisa
importante são os modos de operação do LCD. Ele envia 1 byte (8 bits) por vez, de forma
paralela, ou seja, dos pinos d0 a d7. Se usarmos os 8 pinos, estaremos na configuração de
8 bits e a sintaxe da função é a descrita neste parágrafo.

• LiquidCrystal lcd(rs, rw, enable, d4, d5, d6, d7)


Esta função é a mesma do item anterior porém na configuração de 4 bits. Veja que agora,
graças a nossa biblioteca, o Arduino irá enviar 1 bytem em 2 etapas, enviando primeiro
4 bits e depois mais 4 bits, utilizando apenas os pinos do display de d4 a d7. Apesar de
dobrar o tempo de comunicação para envio e quaduplicar o tempo para envio + resposta,
como operamos em altas frequências, isso é imperceptível na maioria das aplicações. Po-
rém esse método poupa muitos pinos do Arduino.

• LiquidCrystal lcd(rs, enable, d4, d5, d6, d7)


igual aos comandos anteriores, mas como na maioria das vezes não lemos informações
do display e apenas enviamos a ele, muitas vezes não usamos o pino ’rw’, aterrando ele, o
que indica sempre escrita de dados e nunca leitura, desta forma, omitimos da programa-
ção. ATENÇÃO! TODOS OS PINOS DE DADOS DO DISPLAY NÃO USADOS, DEVEM SER
ATERRADOS.

• [Link](’colunas’, ’linhas’)
inicializa o display e no lugar de ’linhas’ você substitui o número de linhas do seu display
e no lugar de ’colunas’ você põe o número de colunas.

• [Link]()
limpa o display

• [Link]()
volta o cursor do display para a posição inicial

• [Link](data)
no lugar de ’data’, coloque a informação a ser mostrada no display. Lembre-se o número
de colunas expressa quantos caracteres você pode escrever por linha.

• [Link]("palavra")
essa função mostra palavras (strings) diretamente no display. Substitua ’palavra’ pela
frase que você quer.

85
• [Link](’coluna’, ’linha’)
indica em qual posição o cursor irá começar

• Para outros comandos e mais informações acesse: [Link]


LiquidCrystal

12.5 Prática 13.1 - Display LCD configuração 8 bits


Vamos agora entender as configurações de hardware e software para a configuração de 8 bits. O
programa é bem simples, só irá mostrar alguns dados no display:
Uma coisa importante a se notar, no HARDWARE, é que existem os pinos de anodo e catodo e
dem ser ligados respectivamente ao +5V e GND. O potenciômetro ajusta a luminosidade do dis-
play. Veja que o RW está aterrado.
falando sobre o SOFTWARE, eu explico nos comentários a definição dos pinos mas você pode
gerar a sua definição personalizada, desde que altere o hardware de acordo. Uma coisa impor-
tante é que você sempre tem que indicar a posição do cursor depois de limpar o display! caso
contrário, nada será mostrado na tela.

Figura 59: Prática 13.1 - diagrama elétrico - fonte: autor

86
Figura 60: Prática 13.1 - código - fonte: autor

87
12.6 Prática 13.2 - Display LCD configuração 4 bits
Como estamos usando menos pinos agora, usamos a configuração da biblioteca para 4 bits. Os
pinos do display não usados devemos aterrar. O resto da programação não se altera

Figura 61: Prática 13.2 - diagrama elétrico - fonte: autor

Para outros tipos de display lcd, basta alterar as configurações de linha e coluna. Outros tipos de
dispositivos visuais seguem os mesmos principios dos dispositivos vistos neste capítulo, basta
utilizar a biblioteca correta.

88
Figura 62: Prática 13.2 - código - fonte: autor

89
13 Matrizes
S ECTION

Matrizes são arrays bidimensionais, mas neste caso estamos nos referindo ao software. Em todo
caso a definição também vale para o hardware e componentes que atuam com coordenadas
para linhas e colunas. Iremos entender como enviar dados para uma matriz de LED e sua lógica,
ao mesmo tempo que iremos entender como ler dados de uma matriz de botões e sua lógica.
A grande vantagem de trabalhar com matrizes é que podemos lidar com um número grande de
elementos e combinações sem necessitar de muitas entradas do microcontrolador, todavia, o
processamento de hardware torna-se mais pesado e uma boa otimização economiza espaço.

13.1 Matriz de LED


Existem diversas matrizes de led e cada uma possuirá uma configuração (pinagem) específica.
Todavia seu funcionamento é o mesmo para todas. Você deve enviar um sinal para a linha que
deseja acionar e outro para a coluna. Esses sinais por sua vez são de níveis lógicos opostos pois
enquanto um sinal positivo vai para o anodo o outro sinal negativo vai para o catodo e com isso
conseguimos acender o led. Neste caso, é necessário verificar o datasheet do componente para
saber se linha ou coluna é catodo ou anodo e assim enviar o sinal correto .

Para os exemplos desta seção, eu utilizei a matriz de led 1088AS, porém você precisa verificar o
modelo que tem com você. A figura a seguir mostra a disposição dos leds na matriz baseado na
linha e coluna, porém os pinos não estão na mesma sequência então, assim como no lcd, você
precisa definir cada pino no Arduino/hardware de controle e ligar corretamente na matriz.

90
Figura 63: Matriz de LED 1088AS - fonte: [Link]

Figura 64: Matriz de LED 1088AS (ligação) - fonte: datasheet 1088AS

A grande questão é, não podemos usar 16 pinos para acionar uma matriz 8x8, na verdade, no
Arduino uno nem temos essa quantidade de pinos digitais disponíveis. Cabe a nós então usar-
mos nossas mentes e pensarmos num hardware capaz de resolver nosso problema. Uma forma
simples de resolver isso é usando 2 demultiplexadores de 8 bits. Desta forma, usaremos 3 pinos
do Arduino para ligar ao demultiplexador que controla as linhas e 3 pinos para controlar o de-
multiplexador que controla as colunas, totalizando 6 pinos digitais usados.
Tendo os demultiplexadores, podemos fazer uma combinação BCD de 000b até 111b (b = biná-
rio), tendo 8 combinações e podendo selecionar individualmente uma das 8 linhas e 8 colunas.
Neste modelo de matriz, as COLUNAS são ANODO (ativa em 5V) e as LINHAS são CATODO
(ativa em 0V). Desta forma, o demultiplex das colunas precisar estar com o barramento de dado
ligado ao 5V e o demultiplex das linhas precisa estar ligado ao 0V. Por sua vez o Arduino comanda
o barramento de controle (combinações) para acionar os leds [24].

91
13.2 Prática 14.1 - Acionando matriz de leds 8x8 com multiplex
Para esta prática você pode usar o demultiplexador que desejar, porém eu utilizei o modelo
74HC238, por questão de comodidade. Ele possui os pinos ABC (A = MSB e C = LSB) de con-
trole da demultiplexação. Como o demultiplex da coluna precisa enviar positivo e o da linha
enviar sinal negativo a matriz, esse CI possui as entradas de sinal E1, E2! e E3! (vide datasheet).
Sendo assim, como a linha recebe negativo, basta aterrar todos os pinos de sinal e para a coluna,
aterrar E2! e E3!, sendo E1 responsável por receber um sinal do Arduino e assim ligar a matriz.
Conforme o Arduino faz a seleção de ABC para linha e coluna, os leds vão sendo acessos. OBS:
os pinos da matriz não são sequenciais! vide datasheet para fazer a ligação correta entre matriz
e demultiplex.

Figura 65: Prática 14 - Esquemático - fonte: autor

No código não temos muitas novidades. Defini cada pino do Arduino ligado ao respectivo pino
do demultiplex. Das variáveis, uma iria controlar o número da linha e o outro o número da co-
luna, lembrando que os pinos D2 a D4 controlam as colunas e os pinos D5 a D7 controlam as
linhas, pois estao ligados ao demultiplex. A função ’controle_matriz’ é uma rotina que analisa
um parâmetro de entrada (que pode ser a linha ou a coluna) e vai atribuindo valores de 0 a 7,
incrementando de 1 em 1, ou seja, aciono, por exemplo, a linha 1, depois a 2, depois a 3 ... até a
7. o mesmo é feito para as colunas. O pulo do gato nessa função está na recursividade.
Quando fazemos a recursividade da função, chamamos a rotina dela, para ser executada no-

92
vamente antes de terminar a rotina anterior. Desta forma, olhando a função LOOP, quando eu
chamo a rotina da função ’controle_matriz’ e dou parâmetro de entrada a ’linha’, eu irei acionar
linha a linha, porém como eu faço recursividade chamando o parâmetro ’coluna’, esta será efe-
tuada primeiro. Sendo assim, quando minha variável linha recebe 0, ela ativa o case 0 que ativa
a primeira linha da matriz. Só que antes de terminar essa rotina e ir para coluna = 1, eu ativo
novamente a função só que usando a coluna. Neste caso a variável coluna irá de 0 a 7, ligando
as colunas 1 a 8 da matriz.
Resumindo, neste caso eu estou acionando uma linha e depois cada coluna em sequencia, aci-
onando outra linha e depois cada coluna em sequencia novamente. Na matriz, você verá led
a led acionando da esquerda para a direita, de cima para baixo. Apesar de um pouco confuso
inicialmente, a recursividade nos auxilia muito a varrer matrizes desse tipo.

Figura 66: Prática 14 - código - fonte: autor

Existem alguns módulos prontos de Arduino baseados no CI MAX7219 e diversas bibliotecas


para sua utilização. Internamente o algorítmo é similar, porém esse CI possui um registrador de
deslocamento interno no qual é possível enviar pacotes menores de dados e ele envia para o dis-
play tudo junto, facilitando assim a criação do algorítmo e manipulação de várias matrizes. Cada
biblioteca possui sintaxe própria, com suas funções e parâmetros internos, por isso deixarei este

93
link: [Link] para que você possa estudar uma das biblio-
tecas existentes para essa funcionalidade chamada ’LedControl’. Porém, caso você não tenha o
módulo pronto e apenas a matriz, já sabe como realizar a lógica para controlar o sistema.

13.3 Matriz de botões


As matrizes de botões são algo muito análogo a de leds. Sendo bem sincero, será mais comum
você manipular matriz de botões do que de leds, visto que displays são mais vantajosos nesse
quesito. Cada matriz de botões possui um hardware diferente, você também pode fazer o seu,
mas sempre consulte o datasheet do componente. Neste exemplo, iremos usar o teclado matri-
cial do Arduino 4x4. Este é um módulo no qual o diagrama interno está representado a seguir:

Figura 67: Teclado Matricial 4x4 para Arduino - fonte: não identificado

Veja que este teclado que estamos usando é do tipo 4x4, mas a lógica sempre será a mesma para
qualquer tipo. Veja nas linhas verdes que são os conectores do display, que elas estão ligadas as
linhas da matriz. Por sua vez, as linhas amarelas estão ligadas as colunas da matriz. Seguindo a
nomenclatura, caso você envie um sinal HIGH para ’L1’, os botões ’1’,’2’,’3’ e ’A’ podem ser pres-
sionados e caso isso ocorra, o caminho será fechado e o sinal irá passar para a coluna do botão
que for pressionado. Se, por exemplo, pressionarmos o botão ’A’, o pino ’C4’ receberá o sinal
vindo da linha ’L1’. Você pode efetuar a mesma lógica enviando sinal na coluna e recebendo na
linha, o importante é que algumas portas do seu Arduino serão de saída, já que vão enviar sinal
para a matriz e outras portas serão de entrada, pois recebem os sinais vindos da matriz. Fazendo
esse cruzamento de informação sobre quem envia e quem recebe, conseguimos identificar qual

94
botão foi pressionado.

13.4 Prática 15 - Lendo teclado matricial


Este programa será bem simples, iremos identificar qual botão foi pressionado e baseado no
seu caractere, iremos mostrar no monitor serial do Arduino. Nesta lógica iremos enviar sinal em
LOW para as colunas e caso seja apertado um botão, sua linha respectiva receberá o sinal. Ire-
mos atuar em lógica inversa pois, internamente, o Arduino possui resistores de pull up, sendo
assim, o envio de sinal é indicado por LOW. Você não precisa usar esse recurso e trabalhar com
lógica direta, mas teria que, externamente a matriz, implementar o resistores de pull up ou pull
down.

Figura 68: Prática 15 - Diagrama elétrico - fonte: autor

95
Figura 69: Prática 15 - código - fonte: autor

96
Neste código, primeiro inicializei uma matriz 4x4 contendo, na sua respectiva posição, os ca-
racteres das teclas do teclado. Em seguida, criar uma função auxiliar que iria fazer a leitura das
teclas e mostrar no monitor serial. Nesta etapa preste atenção ao hardware! O Arduino nomeia
os pinos digitais de 1 a 13, desta forma, para poupar escrita, podemos fazer uma lógica para vin-
cular esses números aos das variáveis de controle que vão varrer a linha e a coluna da matriz.
A variável ’linha’ e ’coluna’ respectivamente vão ler as linhas e colunas da matriz do programa
(do índice 0 ao 3). Olhando o esquemático, vemos que os pinos 8,7,6,5 são os responsáveis por
enviar o sinal, logo controlam as colunas. Quando eu faço a lógica ’8-coluna’ dentro da função
digitalWrite, eu nada mais estou fazendo do que referenciando diretamente o pino do Arduino
com a coluna a ser acionada. Se na matriz o índice da coluna for ’0’, eu terei ’8-0 = 8’, logo digi-
talWrite no pino 8, que no hardware está ligado a primeira coluna da matriz! O mesmo vale para
os demais pinos. A mesma lógica é aplicada quando utilizo ’12-linha’, mas nesse caso eu leio a
linha que recebe sinal, pois os pinos responsáveis são 12,11,10 e 9.
O programa então executa 2 laços ’for’, um para controlar a linha e outro para controlar a coluna
da matriz, sendo que na coluna eu envio sinal pelo Arduino e na linha eu tenho que ler. Caso
alguma tecla seja pressionada, isso é mostrado no monitor serial. Toda vez que uma nova varre-
dura inicia, todos os pinos de envio de sinal, voltam ao nível lógico original para evitar que haja
cruzamento de informações de uma tecla anteriormente acionada e uma nova tecla.
Dentro de pinMode, o parâmetro INPUT_PULLUP aciona o pull up interno do Arduino e não ne-
cessita de resistor externo ao circuito. Na função LOOP é executado a rotina de leitura de botão e
um delay de 250ms é aplicado depois para reter o dado na tela e evitar bouncing. Você pode usar
interrupções internas caso queira prioridade na leitura do teclado e um sistema antibouncing
por código ou hardware.

97
14
Sensores de Temperatura
S ECTION

Sensores de temperatura indicam a temperatura do objeto ao qual foram projetados e possuem


diversos princípios de funcionamento. Alguns analisam o espector infravermelho do corpo, ou-
tros efetuam a troca térmica de temperatura por contato, alguns necessitam de um material
específico, com certas características, outros são de uso geral e possuem uma faixa de operação,
etc...
Todavia, a forma de manipular esses sensores é muito similar. Neste capítulo, vamos entender
a lógica de conversão A/D para sensores de temperatura analógicos e como comunicar com al-
guns sensores digitais. Lembrando que eu irei utilizar alguns dos tipos mais comuns, porém
sempre deve-se procurar pelo datasheet do componente.

14.1 Termistores
Os termistores são resistores que variam significativamente sua resistência elétrica com a varia-
ção da temperatura sem serem danificados (na faixa de valores a que foram projetados). Existem
os sensores NTC (que diminui a resistência com o aumento da temperatura) e o PTC (que au-
menta a resistência com o aumento da temperatura). O mais comum e mais econômico de ser
encontrado é o NTC, porém a lógica é similar para ambos. Por ser um resistor, podemos utilizar
um divisor de tensão para efetuar a lógica de aferição de tensão, já que a resistência varia com a
temperatura, logo a tensão irá variar com a resistência [18].

98
14.1.1 NTC

Por ser o tipo mais comum e econômico, iremos utilizar este termistor como exemplo. A figura
a seguir mostra o diagrama elétrico para um NTC de 10kΩ

Figura 70: Ligando NTC ao Arduino com divisor de tensão - fonte: autor

No divisor de tensão estaremos aferindo a tensão sobre o resistor auxiliar e não sobre o NTC.
Este esquema de ligação será o mesmo para as duas práticas adiante. Lembre-se de que vamos
usar agora os pinos analógicos do Arduino para leitura de dados.
Antes de prosseguirmos, devemos entender como será feita a conversão de temperatura para
tensão e definir alguns parâmetros iniciais de projeto. Os NTCs para módulo de Arduino, nor-
malmente são de 10k, a partir disso escolhemos o valor do resistor auxiliar que para facilitar
nossos cálculos é do mesmo valor do NTC. A tensão de operação também afeta, logo vamos
operar com 5V. Nunca esqueça de interligar todos os GNDs dos circuitos.
Quando aferimos a tensão do divisor, podemos encontrar a resistência de cada elemento. Como
a resistência do resistor auxiliar é fixa em 10k, devemos usar a equação do divisor de tensão para
encontrar a resistência do NTC [18]. A seguir eu deixo a equação pronta para você:

V f ont e × R f i xo
R nt c = − R f i xo (4)
Va f er i d o

No qual nosso resitor fixo é o que tem sua tensão aferida. A tensão da fonte é a da alimentação.
Achado o valor de resistência do termistor, por se tratar de um equipamento não linear, deve-
mos encontar uma equação que relacione a temperatura com a resistência. Para isso, podemos
optar por dois métodos, que são descritos nos próximo tópicos.

99
14.1.2 Método do fator β

Neste método, a partir do coeficiente beta de temperatura, especificado no datasheet do compo-


nente, nós podemos relacionar resistência e temperatura do NTC [20]. Este fator varia de acordo
com a temperatura adotada, então sempre especificamos para um valor ambiente ou de refe-
rência. Analisando o NTC do exemplo e utilizado em meus testes, a temperatura ambiente era
de 25ºC, para uma resistência de 10k do NTC, e o beta adotado de 3977. Estes são os parâmetros
de referência. Uma vez definidos, usamos a seguinte equação de aproximação:

1 1 1 R nt c
= +( × l n( )) (5)
T a f er i d a Tr e f er ênci a β R r e f er ênci a

Veja que os valores de referência foram especificados anteriormente e a resistência do NTC nós
vimos no tópico anterior como calcular. Ao final encontraremos a temperatura aferida real.

14.1.3 Método de Steinhart-Hart

Alguns fabricantes sugerem outro método, que conterá 3 constantes fixas, A,B e C. Neste caso,
basta calcularmos a resistência do NTC e com a equação de Steinhart-Hart e os coeficientes in-
dicados, calcular a temperatura aferida:

1
= A + B × l n(R nt c ) +C × (l n(R nt c ))3 (6)
T a f er i d a

Basta usar a equação no algorítmo para encontrar a temperatura aferida.

14.2 Prática 16.1 - NTC pelo método β


O esquemático elétrico é o mesmo que utilzamos para entender como o NTC funcionava (figura
70). A figura 71 contém o algorítmo, pelo método beta, para encontrarmos a temperatura ambi-
ente e mostrar no monitor serial. Eu apenas segui o passo a passo explicado anteriormente:

100
Figura 71: Prática 16.1 - código - fonte: autor

No código se atente as diretivas define que serão usadas para substituir valores de constantes.
Para facilitar a diferenciação do que é constante e o que é variável a ser manipulada, deixei todas
as constantes com um underline ’_’ no nome. Em C e C++ caso você opere duas variáveis de tipos
distintos, o compilador terá preferência por um tipo, mas só efetuará o ’cast’ no final quando
for salvar na variável de destino. No nosso código, todas as constantes aparecem com ponto
decimal para indicar que são float. Caso não tivesse isso, seriam tratadas como inteiros e nas
operações, apesar das variáveis serem double (float com o dobro do tamanho), os calculos entre
’float’ e ’int’ teriam resultado com truncamento das casas decimais, e no final seria convertido
p um float, porém é o resultado errado. Se atente a isso pois, são fontes de erro. Para efetuar
operações além das convencionais (+,-,*,%), devemos usar a biblioteca ’math.h’ e os parâmetros
são variáveis ’double’.
Neste código cada etapa é mostrada. A primeira etapa é pegar o valor em bits da conversão A/D e
passar para nossa tensão real (vide capítulo 7). Em seguida, usamos a equação do tópico anterior
para calcular o valor de resistência do termistor e por último aplicamos esses parâmetros na
equação desse tópico para calcular a temperatura ambiente. Lembre-se que todos os calculos
de temperatura devem estar em kelvin e depois passados para ºC.

14.3 Prática 16.2 - NTC pelo método de Steinhart Hart


Este método segue o mesmo padrão do anterior, o que muda é a equação para se alcançar a
temperatura aferida [20]. Porém, o Arduino possui uma biblioteca para isso, chamada ’Thermis-
tor.h’. Por não ser oficial do Arduino original, ela precisa ser baixada e instalada (como mostrado
no capítulo 9). Neste caso, ela já opera com alguns parâmetros fixos e "imutáveis"que atendem

101
a maioria dos NTC (já que as constantes são muito proximas da maioria dos modelos). Caso
você tenha de alterar os valores das constantes, você precisa entrar no código fonte do arquivo
original (que está na pasta da biblioteca num arquivo em formato C ou C++) e alterar os valores
das constantes no código, depois salvar. No nosso caso só será preciso usar a biblioteca. A seguir
temos um exemplo, com o mesmo hardware de antes, usando a biblioteca para ler thermistores:

Figura 72: Prática 16.2 - código - fonte: autor

102
14.4 Termopar
Termopares são sensores de temperatura por contato, que internamente possuem um bimetá-
lico, no qual ao serem aquecidos geram um diferença de potencial em seus terminais. Existem
diferentes tipos (tipo K,J,N...) no qual essas letras indicam a composição da liga metálica no qual
é feito.
Esse sensor possui uma boa faixa de operação, podendo operar em temperaturas negativas e po-
sitivas elevadas. Todavia, sua utilização é um pouco mais trabalhosa pois seus sinais de tensão
gerados, com a variação da temperatura, são da ordem milivolts (mV) ou microvolts (uV). Logo,
uma aferição direta se torna impossível, sendo necessário o uso de amplificadores de sinal para,
no nosso caso, termos uma variação de 0V a 5V para ser lida no Arduino.
O termopar, ao contrário do NTC, possui uma característica linear de operação, sendo assim,
muitos fabricantes não fornecem o equacionamento para se obter a relação tensão/tempera-
tura, mas sim uma tabela com diversas medições. Desta forma é muito mais comum utilizar
matrizes com valores fixos e para cada valor de tensão lido relacionar a um valor de temperatura
da tabela. Isso se torna ainda mais vantajoso por ser uma curva de tenmperatura/tensão, muito
linear, então para o sinal amplificado, basta relacionar a constante de ganho [12].
Por exemplo: Se para 1mV, você tem um aumento de 1ºC, então se você tiver um ganho no seu
amplificador de 100, o seu Arduino irá ler 100mV para cada 1ºC.

Figura 73: Exemplo ilustrativo de curvas de diferentes termopares - fonte:


[Link]

Perceba algo muito importante. Quanto menor a relação tensão/temperatura, mais preciso é o
termopar, porém mais dificil de aferir o sinal, precisando de valores de amplificação maiores.
Porém, quanto mais amplificado, menor a faixa que pode ser aferida para o Arduino, que opera
de 0V a 5V. Logo, este sensor também é muitas vezes utilizado em tensões maiores de aferição
como 0V a 24V, o que aumenta a resolução, sendo muito usado em CLPs na indústria.
A seguir eu dou um código exemplo (figura 75), fictício, de um termopar. Os valores da tabela
são inventados, mas servem de exemplo para a situação real. O circuito amplificador (figura 74)
é real e pode ser adaptado para o seu projeto:

103
Figura 74: Circuito buffer para sinal de termopar genérico

Neste circuito, temos o ’TERMOPAR’ (que é o componente mesmo), no qual o pino de menor
potencial vai aterrado e o de maior potencial vai ligado a entrada não inversora de um amp op
(no caso usei o LM324 pois não necessita de fonte simétrica de alimentação). Como o ganho e
a relação de corrente nesse CI são medianos, ao invés de um único buffer, utilizei dois, por isso
a saída do primeiro amplificador entra no segundo, sendo dois estágios de ganho, controlados
pelos respectivos trimpots. A saída do amp op ’TERMOPAR’ é de onde você retira o sinal de ten-
são amplificado. Para o amplificador de ganho não inversor, mostrado na figura, temos que a
relação de ganho é dada como:

R f i xo
G anho = +1 (7)
R a j ust ável
G anho t ot al = G anho 1 ×G anho 2 (8)

Veja que o ganho de cada amplificador é a razão do resistor fixo (superior) e o resistor ajustável
(inferior), acrescido de um, no qual por padrão você pode adotar uns 10k para ambos. Quando
se possui vários estágios de ganho, o ganho final é a multiplicação entre ganhos individuais.

O código de exemplo já está autoexplicativo. Vamos agora fazer uma prática usando o conversor
MAX6675, com módulo pronto para termopar tipo K (de aprendizagem) e Arduino com a bibli-
oteca ’max6675.h’.

104
Figura 75: Código exemplo para termopar genérico - fonte: autor

14.5 Prática 17 - Termopar tipo K com MAX6675


Baixe a biblioteca ’max6675.h’ ou alguma similar para utilizar o módulo MAX 6675 com o termo-
par tipo K. A seguir temos a montagem física e depois o código exemplo que vem na biblioteca
(que é bem simples).
Veja que esse CI possui comunicação SPI com o Arduino no qual só usamos o pino MISO.

105
Figura 76: Prática 17 - esquemático - fonte: autor

106
Figura 77: Prática 17 - código - fonte: autor

14.6 LM35
Este sensor é uma versão ’mini’ do termopar. O princípio de funcionamento é diferente mas a
operação é similar. Eles possui três pinos: Vcc, GND e sinal analógico, não necessitando de am-
plificação, opera de 0ºC a 100ºC e possui resolução de 10mV/1ºC. A seguir temos o esquemático
e código para operar o componente [23].

107
14.7 Prática 18 - LM35

Figura 78: Prática 18 - código e esquemático - fonte: autor

108
14.8 DHT11
Este sensor mede temperatura ambiente (0ºC a 50ºC) e umidade relativa do ar (20% a 90%). Este
componente possui no mesmo invólucro um NTC e um medidor de umidade, conectados a um
microcontrolador de 8bits que envia o sinal para o Arduino. Apesar de 4 pinos, só utilizamos
3 deles, sendo: Vcc, GND e sinal. O pino de sinal é conectado ao pino analógico do Arduino
e devemos usar uma biblioteca para manipular o sensor. Como não se trata de uma biblioteca
oficial, mas criada pela comunidade, ela pode variar dependendo do modelo que você encontra,
então sempre confira o código de exemplo. Existem os modelo DHT11, DHT21 e DHT22. Neste
tópico utilizei o DHT11, mas você pode usar qualquer um deles, desde que mecha nas configu-
rações indicadas pela biblioteca [15].

14.9 PRÁTICA 19 - DHT11

Figura 79: Prática 19 - código e esquemático - fonte: autor

109
14.10 MLX90614
Este sensor é um pouco diferente dos anteriores pois não necessita de contato direto. Ele é um
sensor que capta a radiação infravermelha do objeto. Também possui internamente um termis-
tor para aferir a temperatura ambiente, no qual sua faixa de operação varia de -40ºC a 120ºC. A
grande vantagem está na facilidade de uso, pois não é necessário contato, afere duas tempera-
turas distintas (corpo e ambiente) o que melhora a precisão e análise de dados e seu protocolo
de comunicação é I2C [17].

14.11 Prática 20 - MLX90614


Instale a biblioteca "Adafruit_MLX90614.h"na sua IDE. A figura a seguir mostra o esquemático
de montagem e o código base para utilização do sensor:

Figura 80: Prática 20 - código e esquemático - fonte: autor

110
14.12 DS18B20
Este sensor é muito utilizado para medição de temperatura em ambientes líquidos pois possui
um invólucro a prova dágua, além de uma faixa de medição de -55ºC a 125ºC. Além disso, opera
com protocolo de comunicação 1-Wire, o que diminui muito a quantidade de pinos necessários
para seu funcionamento. Entre o terminal Vcc e o de sinal, deve-se instalar um resistor de 4,7k
em paralelo para garantir o pull up [16].

14.13 Prática 21 - DS18B20


Faça a instalação da biblioteca "DallasTemperature.h"e siga o esquemático da prática. É neces-
sário ter o protocolo 1Wire instalado também.

Figura 81: Prática 21 - código e esquemático - fonte: autor

111
15
Sensores de Posição e
Presença
S ECTION

Sensores de posição identificam a localização espacial (em um ou mais eixos) de um objeto,


sendo normalmente analógicos, enquanto que sensores de presença identificam apenas a exis-
tência do objeto, sendo normalmente digitais. Ambos possuem aplicações e podem ser com-
binados para diversas aplicações, cada um tendo suas vantagens e desvantagens. Nesta seção
iremos estudar os principais tipos e como você utiliza eles no Arduino.

15.1 Chaves de fim de curso


Existem diversos tipos de chaves de fim de curso, com diversas formas de operação, porém o
importante a notar é que seu funcionamento é igual ao de um botão. Um contato é fechado
ou aberto quando o sensor é acionado mecanicamente. Ele pode ser do tipo NF (normalmente
fechado), ou seja, a chave começa com o contato fechado e quando é acionada, ela abre o con-
tato e interrompe a passagem de sinal; e temos o tipo NA (normalmente aberto) que mantem o
contato aberto e quando acionada, fecha o contato permitindo envio de sinal [36].
Perceba que as chaves de fim de curso são qualquer elemento mecânico que mudam a posição
do contato, permitindo abrir ou fechar o circuito elétrico, logo podemos em um estado enviar
nivel lógico alto e no outro estado podemos enviar nivel lógico baixo. A programação desse tipo
de dispositivo você já é mais do que capaz de realizar, pois basta aferir uma simples leitura digi-
tal.
Vamos nos focar a uma lógica ’antibouncing’ uma vez que precisamos aferir o sinal e muitas
vezes ele possui ruído devido a vibração mecânica, gerando o famoso ’bouncing’.
Esta lógica pode ser adaptada para uma função de rotina específica e normalmente é colocada
num timer (sem delay), mas por ser um exemplo, eu usei delay entre uma repetição e outra.

112
Figura 82: Rotina antibouncing - fonte: autor

O ruído mecânico do botão irá mudar o nível lógico que você quer aferir por um tempo muito
curto. Isso pode fazer com que seu programa interprete um nível lógico errado ou faça várias
aferições diferentes do mesmo pino. Para evitar isso, criamos 2 variáveis, uma auxiliar e uma
que queremos salvar o sinal vindo do botão. No exemplo, ’temp’ é a variável temporária e ’botao’
a variável final.
Você inicia a leitura digital do sinal normalmente, porém é necessário conferir depois de um
pequeno tempo (suficiente para o bouncing passar, mas que o sensor ainda esteja acionado) se
o sinal aferido continua sendo o mesmo. Caso o sinal aferido antes e depois do bouncing forem
iguais, então podemos salvar na variável final o dado colhido.
Na parte do hardware, podemos adicionar um capacitor (na ordem de nanofarads em paralelo
ao botão para reduzir o bouncing ainda mais.

15.2 Sensores indutivos e capacitivos


Apesar de serem sensores com princípios de acionamento diferentes, eles operam iguais as cha-
ves de fim de curso. Uma vez detectado um objeto ele envia um sinal digital indicando isso. Os
sensores indutivos irão identificar metais ferromagnéticos e os sensores capacitivos irão identi-
ficar qualquer tipo de objeto sólido. Estes sensores, normalmente, já possuem uma eletrônica
interna que remove o ruído, porém a lógica antibouncing pode ser aplicada pois ruído eletro-
magnético pode ser inserido nos condutores dependendo da distância dos cabos [36].

Esses sensores podem ser do tipo NPN (envia nivel lógico alto no acionamento) ou PNP (envia
nível lógico baixo no acionamento), não necessitando de resistores de pull up ou pull down
(a não ser que indicado pelo fabricante). Existem diversos tipos, muitos usados na indústria,
porém o Arduino possui alguns módulos como o sensor touch capacitivo, que funciona igual os
outros sensores, só tem aparência diferente. Em resumo, este tipo de sensor sempre téra 3 pinos,
um para Vcc, GND e sinal.

113
Figura 83: Exemplos de sensores indutivos e capacitivos - fonte: diversos fabricantes

15.3 Óptico
Sensores ópticos funcionam de forma similar aos apresentados anteriormente nesta seção, po-
rém utilizam de emissores e receptores luminosos que enviam um sinal luminoso (normalmente
infravermelho) até o objeto. Para se identificar a presença, existem dois tipos, os que operam
com reflexão da luz e os que operam com passagem de luz.
Os que operam com reflexão enviam o sinal luminoso do emissor até o objeto e este reflete a
luz, sendo captada pelo receptor. Este tipo é indicado para objetos de cores metálicas ou de su-
perfícies reflexivas e que não absorvam o espectro de luz vermelho (não é indicado para objetos
escuros ou translúcidos/transparentes). Sua vantagem está no tamanho do sensor, já que no
mesmo invólucro possui o emissor de luz e o receptor, tendo tamanho reduzido. Quanto mais
reflexivo o objeto, maior a distância que podemos posicionar entre o sensor e o objeto [36].

Para os tipos que operam com passagem de luz é necessário o emissor separado do receptor,
isto porque o objeto tem que barrar a luz enviada do emissor para o receptor. Esse tipo de sen-
sor permite uma distância maior de separação entre suas partes (emissor/recepctor) e só não
é aconselhado contra objetos translúcidos/transparentes. Um sensor que veremos ainda nesta
seção é o encoder e normalmente ele opera com o mesmo princípio de funcionamento do sen-
sor luminoso com passagem de luz, porém com algumas adaptações.

114
Figura 84: Exemplo sensor luminoso reflexivo para Arduino - fonte: shield arduino

Figura 85: Exemplo sensor luminoso do tipo passagem de luz - fonte: desconhecido

15.4 ultrassônico - HC-SR04


Os sensores ultrassônicos enviam ondas sonoras que se propagam pelo meio identificando ob-
jetos. Medindo o tempo entre o envio de uma onda sonora e o recebimento da reflexão dessa
onda por parte de um objeto atingido, podemos calcular a distância entre o sensor e o objeto
detectado.
O principal módulo utilizado em Arduino, e para demais microcontroladores, é o HC-SR04, no
qual é composto de um emissor sonoro de alta frequência (não conseguimos ouvir as ondas
sonoras que são da faixa de 40kHz) e um receptor sonoro para captar o retorno da onda. Inter-
namente, ele possui um microcontrolador responsável por receber um sinal de disparo e fazer
a operação de envio de pulsos a 40kHz para acionar o emissor sonoro e temporizar essa ação.
No Arduino, apenas enviamos o sinal para acionar o módulo e outro para captar a resposta do
sensor. Comparando o tempo de envio do sinal com o tempo de recebimento, podemos calcular
a distância [hcsr04].

Veja que o pino ’trigger’, do módulo, precisa receber um pulso ’HIGH’ (por 10us no mínimo) e

115
Figura 86: Funcionamento HC-SR04 - fonte: [Link]/blog

após isso, internamente o módulo envia 8 pulsos de 40kHz para excitar o emissor. A partir disso
o sinal sonoro é enviado e começamos a contar o o tempo. Esse tempo entre o envio da onda
sonora e o recebimento é dado pelo pino ’echo’ que fica em nível ’HIGH’ todo este período.
Logo, no Arduino, precisamos apenas enviar o pulso de trigger e verificar quanto tempo o echo
fica em nível alto. Como o tempo total é de envio e recebimento e queremos a distância até o
objeto, levamos em conta apenas o tempo de envio (basta dividir o tempo total por 2).

Tempo em nível al t o d o pi no echo


Tempo = (9)
2
Di st ânci a = Tempo × V el oci d ad e d o Som (10)

15.5 Pratica 22.1 - HC-SR04 - desenvolvendo algorítmo


Vamos primeiro desenvolver o algorítmo para manuseio do sensor ultrassônico. Uma coisa im-
portante a se notar é que necessitamos usar algum tipo de interrupção. A rotina ’delay’ pode
travar o programa e se nosso algorítmo estiver na função ’LOOP’ corremos sério risco de perda
de informação e com isso aferir o tempo e distância, do sensor ao objeto, de forma errada. Neste
exemplo, eu converti as unidades para ’cm’ e ’ms’, mas você pode deixar nas unidades do SI ’m’
e ’s’.

116
Figura 87: esquemático HC-SR04 - fonte: autor

Para esta prática, usamos a interrupção interna (escolhi o timer1, pino digital 2 do Arduino).
Pelo prino 13 enviamos o pulso digial de 10us e aguardamos a resposta do módulo ultrassônico.
quando ele enviar nível lógico alto no echo, significa que a onda sonora foi enviada e quando
esse pulso cair para nível lógico baixo, significa que a onda sonora foi recebida. Então o tempo
que o pino echo fica alto, é o tempo de envio e recebimento da onda, ou seja, duas vezes o tempo
que a onda leva para chegar ao objeto.
Fazendo uma interrupção por transição de borda, sabemos que toda vez que echo tem borda
de subida devemos começar a contagem do tempo e quando tem borda de descida devemos
parar a contagem. O Arduino, ao contrário de outros microcontroladores, possui uma função
que afere tempo: millis(), para milisegundos ou micros() (para microsegundos). Como o tempo
de envio é na ordem de microsegundos, usamos a função micros(). Salvando o tempo em que
começa e termina o envio do sinal echo, podemos calcular o tempo até o objeto e a distância.
Veja no código que a função ’ultrassom’ analisa a interrupção externa por borda de subida e des-
cida e para cada caso toma uma ação. Caso a borda seja de subida, temos o inicio da contagem
de tempo, caso seja de descida, temos o fim da contagem e processamento do algorítmo para
cálculo da distância e tempo. Tudo é mostrado no monitor serial. Na função ’LOOP’, a cada 1s
enviamos um novo pulso de trigger para o módulo, ou seja, acionamos ele.
Vale salientar que esse sensor é bem preciso e que a velocidade do som no ar interfere muito.
Neste caso, fica como desafio, você usar algum sensor de temperatura com o módulo HC-SR04 e
aferir com a variação da temperatura do ar a nova velocidade do som. Você verá como pequenas
variações de velocidade afetam muito o resultado final !

117
Figura 88: código HC-SR04 (1) - fonte: autor

118
15.6 Prática 22.2 - HC-SR04 - com biblioteca
Existem algumas bibliotecas que controlam esse módulo. Baixe a mais comum que é a ’Ultra-
sonic.h’. Se atente a pinagem do programa pois é diferente entre bibliotecas e do nosso código
anterior. A seguir temos um código de exemplo que faz a mesma coisa que o anterior (afere
distância e tempo até o objeto).

Figura 89: código HC-SR04 (2) - fonte: autor

119
15.7 PIR
Este sensor é bem peculiar. Ele detecta radiação infravermelha dentro de um alcance de até 7m
porém o objeto precisa estar em movimento. Caso o mesmo esteja imóvel, o sensor não irá atuar.
Este sensor possui um trimpot para ajuste da sensibilidade e envia nível lógico alto quando de-
tecta algo [8]. Ele nada mais é do que um sensor luminosos porém, por ser ’diferentão’ do que
estamos acostumados a ver, irei mostrar o esquemático e o código (que são bem simples, nada
diferente do que já foi visto):

Figura 90: Acionamento de LED do Arduino com sensor PIR - fonte: autor

120
15.8 encoder
Encoderes são sensores de posicão extremamente precisos. Muito similares a potenciômetros
(devido a sua cosntrução mecânica) são facilmente confundidos com um, tanto que recebem a
errônea nomenclatura de potenciômetros digitais. Os mesmos podem ser do tipo rotativo (mais
comum) e linear, porém operam de forma totalmente diferente a de um potenciômetro. Os en-
coderes não são aparelhos resistivos, mas sim equipamentos que internamente possuem um
sistema de discos perfurados. Dependendo do alinhamento e posição desses discos, podemos
(por meio luminoso) ter ou não a passagem de luz. Podemos usar dessa técnica para definir
níveis lógicos, como por exemplo, 1 = iluminado e 0 = apagado. Como o mesmo possui um eixo
que rotaciona livremente, esses sinais luminosos que digitalizamos podem ser enviados sem li-
mite de giros. Com um simples circuito de optoacoplamento, podemos transformar esse sinal
luminoso num pulso elétrico ou sinal de tensão e com isso convertemos o giro mecânico em
sinais elétricos digitalizados, sem a limitação do manuseio do componente (como ocorre em
potenciômetros que tem um curso máximo de rotação). Para os equipamentos com desliza-
mento linear, ainda ocorre a limitação mecânica, mas a maioria são rotativos [27].

Figura 91: Exemplo de encoderes - fonte: fabricantes diversos

O princípio de funcionamento do encoder é o mesmo para o tipo rotativo e linear, porém como
vamos trabalhar nessa seção com um exemplo rotativo, irei me referir a ele especificamente.
Basicamente, um encoder possui um sistema de disco perfurado, no qual passa ou não luz. A
partir disso, um emissor luminoso do tipo passagem fica posicionado de um lado do disco e do
outro seu receptor. Nessa hora você precisa olhar o datasheet do componente, mas vamos supor
que ’1’ seja a luz passando e ’0’ a luz não passando. Dessa forma eu consigo converter os sinais
luminosos em sinais elétricos, já digitalizados e com alta precisão e velocidade [27].

121
Figura 92: encoder internamente - fonte: fabricantes diversos

Na figura 92 note que há um disco estriado, com pequenos furinhos, esse é o disco perfurado do
encoder. Alguns modelos podem vir sem esse disco, necessitando comprá-lo a parte.
Existem dois tipos principais de encoderes que são explicados a seguir

15.8.1 Encoder do tipo Absoluto

Este encoder é o mais fácil de se utilizar e também possui preço mais elevado. Ele já possui em
seu disco perfurado a sequência binária (ou outro código) para ser lido diretamente. Alguns mo-
delos, mais caros, já até apresentam um sistema de comunicação serial interno para facilitar o
envio de dados ao usuário.
O encoder possui uma resolução, ou seja, existe um ângulo mínimo a ser movimentado para que
ele detecte um deslocamento. Se você girar o eixo, verá que ele possui pequenos passos e quanto
maior a resolução dele, menor essa sensação de passos. No caso do absoluto, esses passos já in-
dicam qual a posição absoluta dele. Vamos supor que eu tenha um encoder com resolução de
8bits, isso implica que ele irá da contagem de 0 ao 255 (lembrando que será lido em binário, mas
eu estou convertendo para decimal). Como ele irá dar uma volta para ler todos esses bits, se
fizermos a divisão pelos 360º de giro, teremos uma resolução de aproximadamente 1,4º/bit ou
1,4º/passo. Então, se por exemplo, o seu encoder absoluto te indicar o valor 10, você só lerá o va-
lor 11 ou 9 se rotacionar em 1,4º o eixo, para a direita ou esquerda. No caso desse equipamento,
ele pode rotacionar tanto no sentido horário como antihorário, dessa forma (você precisa ver o
datasheet) sabendo se o código lido é maior ou menor que o anterior, podemos saber a posição

122
do eixo. Se analisarmos somente o tempo entre transição de informações, podemos saber a ve-
locidade de rotação. Quando ele executa uma volta completa, a contagem reinicia.
A grande vantagem do encoder absoluto está no fato dele já indicar o código pronto para você,
bastando apenas ler e comparar com o sinal anterior. Normalmente estamos acostumados a
lidar com código binário, mas no encoder, na maioria dos casos, é tratado o código gray, que é
uma adaptação do binário para que apenas 1 bit varie seu estado entre um número e outro. No
próximo tipo de encoder, você entenderá melhor a importância do código gray [27].

Figura 93: Exemplo de disco interno de encoder absoluto em código gray - fonte: Easy-
trom Labs

Veja na tabela da figura 93 que o código gray (e que indica a posição) varia apenas 1 bit por vez.

15.8.2 Encoder do tipo Incremental

Este encoder é mais difícil de trabalhar que o anterior, porém seu custo é muito menor e neces-
sita de no máximo 3 pinos de sinal. Neste caso, possuímos o mesmo princípio do disco perfu-
rado, mas agora possuímos dois discos e que possuem furos igualmente espaçados. Entretando,
esses discos estão estrategicamente defasados entre si. Essa defasagem entre um disco e outro
é proposital para gerar uma defasagem de 90º entre o sinal de um disco e o sinal de outro disco.
Para facilitar a lógica, vamos supor que eu tenho o disco A e o disco B e que a posição inicial
deles é o 00.
Se eu rotacionar no sentido horário, por exemplo, o disco A irá enviar primeiro a informação da
mudança de nível lógico (de 0 para 1). Por sua vez, se eu rotacionar no sentido antihorário, o
disco B irá enviar essa informação de mudança de estado primeiro. Perceba que agora, como
não temos mais uma posição instantânea dada pelo código do encoder, precisamos avaliar a
mudança de nível lógico e quem mudou primeiro. No datasheet do componente é dado o grá-
fico de quadratura de sinais, no qual indica o sentido de rotação e qual disco muda de estado
primeiro. A figura 93 exemplifica o esquema de quadratura:

Como este tipo é o mais confuso, iremos estudar bem ele.


Vamos tomar como exemplo o modelo KY-040, mas as informações referidas no exemplo devem

123
Figura 94: Exemplo de disco interno de encoder incremental - fonte: Easytrom Labs

sempre ser adaptadas para o datasheet do componente que você usar. Este encoder rotativo in-
cremental possui 5 pinos: Vcc, GND, SW, CLK e DT. O pino SW é um botão que envia nível lógico
baixo quando pressionado (sim, você pode pressionar o eixo desse encoder já que ele possui um
botão, e mesmo depois de 7 anos estudando elétrica eu também não sabia disso até fazer essa
apostila...), Os pinos CLK e DT são a mesma coisa dos pinos A e B que eu dei de exemplo anterior
[27].
Olhando o datasheet, ele irá indicar que se o pino CLK mudar primeiro seu estado, o sentido de
giro é horário. Se o pino DT mudar seu estado primeiro, o sentido de giro é antihorário. Uma
coisa que você tem que prestar atenção (e as vezes necessita de ensaio prático pois não fica claro
no datasheet) é com relação a mudança de posição do sinal do encoder em relação ao passo do
eixo. No caso do KY-040, ele envia 4 sinais diferentes para cada passo que o eixo dá. Esses sinais
por sua vez, estão em código gray, contando de 0 a 3 (4 sinais) [26]. Veja a figura 95 a seguir:

Figura 95: Operação por passo do encoder KY-040 - fonte: Easytrom Labs

Na figura 95 está representado os sinais que serão enviados pelos pinos CLK e DT quando mo-
vimentados no sentido horário ou antihorário. Esse encoder possui 20 passos, ou seja, para
cada passo, iremos rotacionar 18º. Porém, para cada passo, o encoder enviará esses 4 pulsos em
sequência!!!
Isso é uma coisa que confunde muito. Dependendo do encoder, para cada passo, ele irá enviar

124
um sinal apenas, então por exemplo: para o passo 1(18º), ele envia 00, para o passo 2 (36º), ele
envia 01, etc...
Porém, há encoderes que enviam os 4 sinais em sequência para um mesmo passo completo,
então no caso do KY-040, quando você der o passo 1(18º), ele envia: 00,01,11,10. Ai no passo
2 (36º) ele fará o mesmo, enviando: 00,01,11,10. Se você quiser aferir apenas 1 sinal, deve dar
1/4 de passo. Então, cuidado com esse princípio de funcionamento que varia de componente a
componente.
Agora, uma vez que você entendeu como funciona a transição dos sinais, perceba que a tabela
de sentido horário está defasada de 90º do sentido antihorário e uma opera na sequência oposta
da outra. Lembra que eu falei do código gray e que ele permite variar apenas 1bit por vez? en-
tão, essa é a vantagem aqui para definir qual o sentido de rotação também. Ao invés de termos
que aferir quem variou primeiro, podemos observar a sequência da tabela e como sabemos que
apenas 1bit varia por vez, podemos usar de interrupções que analisam o sinal toda vez que uma
mudança de estado ocorre! Então, como cada contagem é feita por sinal que variou, mas ape-
nas 1 bit varia por contagem, a interrupção identifica quando houve mudança na contagem e
analisando o dado atual e o anterior podemos comparar para dizer se o encoder rotacionou no
sentido horário ou antihorário. No seu esquemático, você define quem é o sinal A ou B. Para o
exemplo da próxima prática, utilizei CLK sendo A e DT sendo B, no qual uma interrupção ex-
terna analisa o A (CLK).

15.9 Prática 23.1 - Encoder Incremental KY-040 sem biblioteca


Nessa prática vamos desenvolver o algorítmo de aferição do encoder KY-040. Existem diversos
algorítmos, aliás muito mais otimizados que o meu, porém o código que você irá ver nada mais
é do que um exercicício do que foi explicado anteriormente. Para isso, iremos salvar o valor do
CLK e DT anterior a uma mudança do encoder e depois da mudança do encoder. Para detectar
a mudança do encoder, uma interrupção externa por mudança de borda monitora o pino CLK.
Desta forma, sempre capturamos a mudança de bit e por meio de vários IFs, testamos a condição
que representa a posição atual do encoder. A posição atual do encoder é mostrada no monitor
serial. O baud rate está em 115,200.

125
Figura 96: Prática 23.1 - esquemático - fonte: autor

126
Figura 97: Prática 23.1 - código (1ª parte) - fonte: autor

127
Figura 98: Prática 23.1 - código (2ª parte) - fonte: autor

128
15.10 Prática 23.2 - Encoder incremental com biblioteca
Vamos usar a biblioteca ’[Link]’. O esquemático é o mesmo da prática anterior. Para en-
tender a fundo a biblioteca e seus comandos, acesse [Link]
en/libraries/rotaryencoder/

Figura 99: Prática 23.2 - código - fonte: exemplo biblioteca ’RotaryEncoder.h’

129
15.11 Acelerômetros
Acelerômetros são sensores que consegue converter a intensidade da aceleração num valor de
tensão. Existem diversos métodos de fabricação, mas a maioria se baseia na construção de um
capacitor interno com a capacitância variável. Conforme o sensor é acelerado a distância entre
as placas dos capacitores varia e com isso podemos relacionar a deformação (distância) entre
as placas, com a aceleração gerada. Os acelerômetros podem medir acelerações nos três eixos
base e com a combinação desses dados podemos aferir rotações também. Alguns módulos já
vem com essas funções embutidas e prontas para uso, com comunicação I2C ou SPI, outros são
analógicos e recebemos apenas o sinal proporcional de tensão.
Quando você necessitar de um acelerômetro, escolha um que seja compatível com a sua aplica-
ção e que esteja dentro da faixa de aceleração desejada. Utilizar o componente para aferir uma
aceleração maior que a limite, pode danificá-lo [7].
Além disso, alguns acelerômetros possuem um giroscópio embutido. O giroscópio dará sempre
a referência da aceleração gravitacional. Assim fica mais fácil saber se estamos com uma acele-
ração no sentido de elevar ou descer o corpo, ou se essa aceleração está sendo na horizontal ou
em plano inclinado.
Além de capturar a aceleração, se usarmos métodos de controle, podemos aferir a variação da
velocidade e deslocamento do objeto também [19].

Figura 100: Exemplo de acelerômetro modelo MPU6050 - fonte: diversos fabricantes

Nessa seção iremos trabalhar com dois tipos de acelerômetros: ADXL 335 e MPU 6050.

15.11.1 ADXL335

Este acelerômetro é totalmente analógico e avalia a aceleração nos três eixos (X,Y e Z). Não pos-
sui giroscópio nem protocolo de comunicação serial. Apesar de operar com 3,3V, o mesmo pos-
sui um regulador que permite alimentação de 5V pelo Arduino. Sua aceleração máxima é de 3G
(cada G equivale a uma aceleração gravitacional de 9,8m/s2̂) [7].
Sua sensibilidade é de 0,3V / G, tendo valor de base (0G) igual a 1,5V.

130
Figura 101: ADXL335 - fonte: diversos fabricantes

Por possuir uma alta sensibilidade porém baixa faixa de aferição (apenas 3G máximo), o ADXL335
é muito utilizado para aplicações de robótica no qual se deseja aferir a posição do objeto (ex: se
um robô está em pé, deitado, tombado,etc...). Veja que, por ser analógico e sem giroscópio, o
valor de tensão enviado pelos pinos Zout,Yout e Xout, irá alterar de acordo com a aceleração do
corpo e da gravidade. Se, por exemplo, estivermos com o sensor parado e o eixo Z paralelo a
vertical, o eixo Z estará sofrando aceleração gravitacional de 1G. Caso o sensor fique com o eixo
X na vertical, então quem irá mostrar um valor de tensão diferente será o eixo X, pois agora ele
que afere a aceleração gravitacional e não mais o eixo Z. Com essa lógica, podemos identificar a
posição do objeto no espaço. Também podemos aplicar outras lógicas ao mesmo sensor.

15.11.2 Prática 24.1 - ADXL335

Nesta prática iremos ler os três pinos analógicos do sensor e aferir o valor de cada um no moni-
tor serial. Conforme você movimentar, o mesmo mostrará variações. Utilize dos valores aferidos
(ou uma faixa deles) para criar lógicas de posição (objeto tombado, objeto invertido, objeto pa-
rado, etc...).

131
Figura 102: Prática 24.1 - fonte: autor

15.11.3 MPU6050

Este acelerômetro é mais refinado que o anterior, possuindo comunicação I2C, módulo acelerô-
metro com giroscópio, conversor de 16bits e operando até 16G. Pode ser alimentado com 5V,
pois possui regulador no módulo para 3,3V.

O pino AD0 é o de endereço I2C, no qual vale 0x68.

132
Figura 103: MPU6050 - fonte: diversos fabricantes

15.11.4 Prática 24.2 - MPU6050

Nesta prática iremos ler os valores da aceleração e rotação emprega sobre o módulo. Necessita-
mos da biblioteca ’Wire.h’ que já está apta a lidar com o módulo.

133
Figura 104: Prática 24.2 - esquemático - fonte: autor

Neste código inicializamos a biblioteca e definimos o endereço a ser lido. Depois para cada dado
aferido (aceleração em X,Y,Z, temperatura e aceleração rotacional), temos a declaração de variá-
veis e a inicialização do sensor. Como este sensor opera com 16bits, mas a função [Link], re-
cebe apenas 8bits por vez, usamos o comando ’«’ para realizar um deslocamento de 8bits. Desta
forma, lemos os primeiros 8bits MSB, deslocamos para esquerda e lemos os outros 8bits LSB,
vindos do sensor. Para realizar as duas leituas e guardar os valores na mesma variável, utilize a
sintaxe mostrada. O acelerômetro irá enviar em sequência as informações, como mostrado no
código.

134
Figura 105: Prática 24.2 - código - fonte: autor

135
16 Extensômetros
S ECTION

Extensômetros são dispositivos que podem aferir deformações mecânicas e relacionar a outras
grandezas físicas. Neste capítulo iremos nos focar a um tipo específico de extensômetro que é a
célula de carga.

16.1 Extensômetros, Strain Gauges e Células de Carga


Dispositivos que podem correlacionar a deformação mecânica a uma outra grandeza são cha-
mados extensômetros. Quando o mesmo consegue relacionar a deformação mecânica a uma
grandeza elétrica (resistência elétrica) este passa a ser denominado Strain Gauge. O tipo mais
comum de strain gauge são as células de carga, no qual aferem deformações mecânicas de dife-
rentes tipos e com isso a resistência do sensor varia. Podemos dizer que as células de carga são
resistores com resistência variável por deformação mecâ[Link] o projeto que deseja realizar,
você deve ter ideia do tipo de deformação mecânica que deseja aferir e como posicionar a célula
de carga sobre a superfície a ser medida a deformação. Tome cuidado pois células de carga são
extremamente sensíveis [9].

16.2 Ponte de Wheatstone


Antes de prosseguirmos, iremos revisar um arranjo elétrico chamado Ponte de Wheatstone.
Neste arranjo, temos 2 divisores de tensão, resistivos, em paralelo. Aferindo a tensão no cen-
tro de cada divisor, podemos calcular a resistência de cada resistor que o compõe [35].

136
Figura 106: Exemplo de célula de carga - fonte: fabricantes diversos

Figura 107: Ponte de wheatstone - fonte: wikipedia

A seguir temos a equação geral da ponte. Veja que a tensão entre C e B é nula caso ambos os
divisores possuirem a mesma resistência:

R3 R4
VC B = ( − ) × V AD (11)
R1 + R3 R4 + R2
A tensão A e D é a da fonte de alimentação.
Se substituirmos um dos resistores por uma célula de carga, teremos uma tensão CB variável e
com isso podemos calcular o valor da resistência da célula de carga e correlacionar a deformação
mecânica.

16.3 Deformação do Strain Gauge


A grande vantagem de utilizar um strain gauge é o fato dele operar no regime elástico de de-
formação. Isso é o mesmo que dizer que ele opera linearmente com relação a deformação do
material, então a resistência aumenta/diminui, proporcionalmente ao aumento/diminuição da
deformação [9]. Quanto mais deformado, maior a resistência, quando menos deformado, me-
nor a resistência. Se considerarmos o fio condutor de comprimento L e resistência R do strain
gauge, então, temos a relação:

∆R/R
K= (12)
∆L/L

137
K é a constante de deformação (e proporcionalidade) entre resistência e comprimento, desde
que o material esteja na fase elástica. A equação anterior relaciona a variação (delta) com o
valor inicial de referência. Perceba que o strain gauge selecionado deve estar na mesma região
elástica que o material aferido, ou seja, uma célula de carga para 100N não deve ser usara para
um material que sofrerá esforço de 200N !!!

16.4 HX711
Para facilitar nossa vida, existe um módulo amplificador de sinal chamado HX711. Nele é pos-
sível ligar as células de carga e aferir o valor de até 4 delas simultaneamente. Os dados já são
convertidos de analógicos para digital e enviados ao Arduino por comunicação serial. Neste
caso, precisamos apenas instalar a biblioteca ’HX711.h’ e efetuar a ligação correta do hardware.
Ao longe dessa seção iremos entender como usar melhor esse amplificador junto ao sensor [9].

Figura 108: Módulo HX711 - fonte: fabricantes diversos

16.5 Célula de carga de 50kg da Sparkfun


Existe um modelo comercial muito utilizado de célula de carga que foi desenvolvido pela fabri-
cante de componentes eletrônicos Sparkfun.

Figura 109: Célula de Carga 50kg modelo sparkfun

138
Ela é composta internamente de 2 células de carga, por isso possui três fios. Lembre-se de que
a célula de carga é um tipo de resistor. A figura 110 exemplifica o diagrama interno com as
referidas cores para os fios (branco, preto e vermelho).

Figura 110: Representação interna célula de carga

Os valores de resistência na figura são apenas simbólicos, porém a posição e coloração dos fios
são reais. Veja que podemos usar tanto uma célula de carga, como as duas para fazer a ponte de
wheatstone, porém elas se encontram no mesmo invólucro. Para a criação da ponte, podemos
usar 1, 2 ou 4 células de carga, que será o próximo tópico explorado.

16.5.1 1 módulo de célula de carga, contendo 2 strain gauges

Para não confundir os nomes, temos o nosso sensor de célula de carga de 50kg, que é o invólu-
cro metálico composto , ai sim, de duas células de carga que são os resistores. Como os nomes
confundem, eu vou chamar o sensor de 50kg de ’módulo de célula de carga’ e as células de carga
internas de ’resistores strain gauge’, então a gente sabe que, apesar de receberem nomes iguais,
eu tenho 1 módulo contendo 2 resistores internos,ok?
Veja na figura 111 os dois esquemáticos possíveis para formar a ponte, usando apenas 1 módulo
com 2 strain gauges. Podemos usar os dois strain gauges internos ou apenas um deles, depen-
dendo da configuração adotada e dos números de resistores auxiliares (R1,R2 ou R3) necessários.

139
Figura 111: esquemático para 1 módulo de célula de carga - fonte: autor

140
16.5.2 2 módulos de célula de carga, contendo 4 strain gauges

Neste caso, podemos usar apenas 2 strain gauges, um de cada módulo, ou podemos usar os 4
strain gauges dos 2 módulos. Veja a figura 112:

Figura 112: esquemático para 2 módulos de célula de carga - fonte: autor

141
16.5.3 4 módulos de célula de carga, contendo 8 strain gauges

Neste caso teremos de aproveitar apenas 1 resistor strain gauge de cada módulo.

Figura 113: esquemático para 4 módulos de célula de carga - fonte: autor

142
16.6 Prática 25 - lendo dados da célula de carga
Independente da configuração que você escolha, será necessário efetuar um processo de amos-
tragem vindo do HX711 que amplificou e processou os dados. A figura 114 exemplifica de ma-
neira simples como mostrar no monitor serial do arduino os dados aferidos. Existem outros
comandos vinculados a biblioteca, porém o intuito aqui é apenas familiarizar com o sensor.
Abrindo o monitor serial, vários valores, porém próximos serão mostrados. Para efetuar alguma
lógica é necessário criar uma relação entre os valores mostrados no monitor e a deformação
aferida. Neste caso, você pode criar um algorítmo de proporção linear a partir de algumas aferi-
ções feitas com diferentes pesos e valores aferidos ou pode usar comandos prontos da biblioteca
(necessário pesquisar a parte).

Figura 114: Prática 25 - código - fonte: autor

143
17 Motores
S ECTION

Motores são máquinas elétricas capazes de converter energia elétrica em energia mecânica ro-
tativa. Existem diversos tipos de motores com as mais diferentes aplicações, mas neste capítulo
iremos entender os três principais tipos usados em robótica: o motor DC universal, o motor de
passo e o servo motor.

17.1 Motor DC universal


Os motores DC operam em corrente contínua, devido a este fato, possuem dois terminais. Ao
inserir uma polaridade de tensão o motor rotacionará para num sentido e se invertermos a po-
laridade da tensão aplicada, o sentido de giro é invertido. Existem classes de motores DC (série,
paralelo, misto...), mas por regra geral, nunca acione eles sem uma carga em seu eixo pois, na
maioria dos casos, sua rotação irá aumentar muito e isso pode danificá-lo. O mesmo vale se uma
carga muito pesada for ligada ao eixo do motor de forma a travá-lo [29]. Olhe sempre o manual
de instruções do motor e acople uma carga mínima para seu bom funcionamento ou que esteja
dentro de seus limites.

144
Figura 115: Exemplo de motor DC - fonte: fabricantes diversos

Além disso,o nível de tensão ou a corrente drenada por esses motores, normalmente, é maior
que os níveis de operação do Arduino, sendo necessário uma interface de controle e alimen-
tação. Como esta apostila não é focada nisso, não irei me extender muito a este conceito do
hardware, porém irei dar exemplos de como integrar esses componentes. Para o acionamento
dos motores, podemos usar um relé, um transistor, mas o dispositivo mais comum é a ponte H.

Figura 116: Esquemático básico de uma ponte H - fonte: blog eletrogate

A ponte H é composta, basicamente, de 4 transistores, dois do tipo NPN e dois do tipo PNP, no
qual de cada lado temos uma cascata PNP - NPN. No centro fica o motor. Quando enviamos sinal
alto para uma cascata e baixo para a outra, acionamos o motor para rotacionar em um sentido.
Caso a sequência seja invertida, o motor rotaciona no outro sentido. Se ambas as entradas de
sinal forem 0 ou 1 simultaneamente, então o motor fica parado, sendo no caso 0, energizado e
com resistência a rotação mecânica do eixo e no caso 1, sendo desenergizado e com eixo solto
??.
A ponte deve ser escolhida/projetada para suportar os parâmetros de operação e sobrecarga do
motor e em modelos mais modernos, possui sistemas optoacoplados ou CIs específicos que iso-
lam a entrada do Arduino, evitando a queima acidental do microcontrolador. Como você pode
perceber, basta enviar um sinal digital para acionar o motor, só que devido a sua característica
de linearidade e facilidade de uso, podemos usar um sinal PWM para controlar a velocidade do

145
Figura 117: Exemplo de acionamento da ponte H - fonte: adaptação blog eletrogate

motor.
Um modelo bem comum de ponte H para Arduino é a L298H, com capacidade para operar até 2
motores DC entre 6V a 35V, com potência máxima (dos dois somados) de 25W. Como controlam-
se 2 motores, teremos quatro entradas [11]. Olhando de cima p baixo a figura, os dois primeiro
pinos, das entradas, controlam o sentido de rotação do motor A e os outros dois do motor B,
como expliquei.

Figura 118: Explicação da pinagem L298H - fonte: blog eletrogate

146
Como temos pinos de liga/desliga para o motor A e B (chamados de ATIVA MA e MB na figura),
se você deixar o jumper conectado, os motores sempre estarão prontos para serem acionados.
Caso você queira remover os jumpers e conectar um pino do Arduino para efetuar um controle
por PWM faça o seguinte:

• 1 - DELIGUE!!! a alimentação da placa (remova todos os fios de preferência);

• 2 - remova o jumper;

• 3 - Com o auxílio do multímetro, Verifique continuidade entre o pino 5V e os pinos do


jumper do ATIVA MA e ATIVA MB. Aquele pino que NÃO DER continuidade com a ali-
mentação é o que você conecta ao Arduino, nos pinos analógicos, para enviar um sinal
PWM e com isso controlar a velocidade de acionamento do motor.

Se não quiser controlar a velocidade do motor, apenas mantenha o jumper no local.


Sobre a alimentação PRESTE ATENÇÃO!, o pino GND vai interligado tanto ao da fonte, como
do Arduino, como do módulo, todos precisam estar na mesma referência (não erre isso ou verá
fogos de artifício antes do ano novo). Existe, também, um jumper chamado ATIVA 5V, na figura.
caso você utilize a mesma fonte de alimentação tanto para o módulo (que irá acionar os moto-
res) como para o Arduino, deverá REMOVER O JUMPER, e interligar o pino de alimentação de
5V com o de 6-35V. Perceba que neste caso, a fonte de alimentação precisa ser de 5V para coin-
cidir com a tensão de operação do Arduino, ficando limitado a tensão de operação de 5V para os
motores [11].

Figura 119: L298H com mesma fonte de alimentação para Arduino - fonte: autor

NAO RECOMENDO este método, pois efeitos de chaveamento dos motores podem elevar o ní-
vel de tensão muito rapidamente, mas sendo possível a queima do Arduino. Caso o Arduino
seja ligado a uma alimentação distinta do módulo, então você MANTEM O JUMPER, e NÃO IN-
TERLIGA o 5V com o 6-35V. Desta forma, o sinal recebido em 6-35V é rebaixado para 5V (do

147
regulador interno que é ligado pelo jumper) e fornece a alimentação de 5V para a placa e de 6-
35V ao motor. Apesar do módulo permitir até 35V, não é recomendado ultrapassar de 20V, pois
irá sobrecarregar o regulador interno.

Figura 120: L298H com fonte de alimentação distinta para Arduino - fonte: autor

Apesar do hardware, dessa ponte, ser um pouco mais trabalhoso de lidar, o acionamento é sim-
ples. Você já é capaz (depois de ter lido tudo nessa apostila) de acionar o motor tanto sem con-
trole de velocidade como com controle de velocidade, já que são sinais PWM e digitais simples.
Uma recomendação minha é: sempre teste a lógica em leds antes de passar para motores com o
módulo, pois caso você erre alguma coisa na lógica, saberá distinguir de uma montagem errada
do hardware. Os próximos dois tipos de motores eu terei de dar exemplos de código, já que são
mais "complexos".

17.2 Motor de passo


Motores de passo são um conjunto de eletroímas que quando acionados atraem um eixo mag-
netizado. Dessa forma, cada bobina acionada em sequência, atrai o eixo magnetizado de forma
a alinharem os pólos magnéticos. Como existem várias bobinas internas para fazer isso (aumen-
tando o torque) devemos efetuar vários acionamentos em sequência, pois cada acionamento de
bobina individual irá movimentar um pouco o rotor. Esse pequeno movimento damos o nome
de passo.
Cada motor possui uma resolução que indica quantos passos são necessários para ele efetuar
uma volta completa. Motores de passo são muito mais lentos se comparados aos DC, porém
muito mais precisos, tendo aplicações distintas [29].

148
Figura 121: exemplo motor de passo 28BYJ-48 para Arduino 5V - fonte: fabricantes di-
versos

A figura 121 ilustra o funcionamento básico de um motor de passo. Na prática, existem várias
bobinas que estão espaçadas entre si e recebendo o mesmo sinal de tensão, para em conjunto,
movimentar com precisão o eixo do motor (efetuar o passo), mas para o acionamento real, só
precisamos entender a figura a seguir:

Figura 122: metodologia básica para acionamento de motor de passo - fonte: autor

Em resumo, todo motor de passo é composto de 4 conjuntos de bobinas principais. Seguindo a


sequência, acionando a bobina A, o rotor fica alinhado com ela, depois acionando a bobina B,
o rotor se alinha novamente, depois acionando a bobina C o mesmo ocorre e por ultimo acio-
nando a bobina D terminamos o ciclo. Ao reacionar a bobina A, efetuamos uma volta completa
com o rotor. A invertermos a sequência (DCBA), iremos inverter o sentido de rotaçã[Link] mé-
todo de acionamento é chamado de FULL STEP, pois estamos acionando uma bobina por vez
[29].
Existem outros métodos de acionamento, como o HALF STEP, no qual o acionamento é mos-
trado a seguir:

149
Figura 123: Acionamento meio passo - fonte: autor

Veja que para um acionamento de meio passo, triplicamos o número de acionamentos entre
bobinas. Enquanto que no passo completo (FULL STEP) acionamos a bobina A e desligamos as
outras, para depois acionar a bobina B e desacionar as outras, no meio passo (HALF STEP) de-
vemos inserir um acionamento intermediário, acionando A e B ao mesmo tempo. Desta forma,
conseguimos aumentar a precisão do passo e suavizar o movimento. Este método de aciona-
mento torna mais lento o acionamento, porém o torque [Link] efetuar uma volta com-
pleta, você precisa repetir o processo.
Existe o acionamento por micropasso, no qual cada bobina tem sua intensidade modulada por
PWM. Neste caso, por ser bem mais complexa a lógica, não entraremos em detalhes.

Também temos as formas construtivas dos motores de passo que são duas: Os motores uni-
polares e os bipolares.
Os motores bipolares não possuem uma derivação central na bobina que é aterrada, desta forma,
existem 2 conjuntos principais de bobinas, no qual o motor nos force acesso aos 4 terminais (2
de cada bobina). Para efetuar o acionamento, devemos energizar uma bobina em sequência da
outra, num sentido, e depois efetuar a mesma sequência, mas energizando a bobina com pola-
rização inversa. A figura a seguir explica isso de forma visual. Perceba que temos os terminais
A,B,C e D, no qual uma bobina tem terminais A e C e na outra terminais B e D. Desta forma aci-
onamos (no exemplo um full step mas a lógica do half step permanece) A,B,C e D, mas perceba
que quando acionamos A e mais pra frente C, estamos acionando a mesma bobina, porém com
polaridade diferente [29].

150
Figura 124: Exemplo motor bipolar - fonte: autor

Já o motor unipolar possui um conjunto principal de 2 bobinas com uma derivação central que é
aterrada. Você também pode imaginar como 4 conjuntos de bobinas, no qual cada bobina tem
um terminal aterrado. Alguns motores já possuem todos os aterramentos interligados, outros
possuem apenas um par aterrado, devido a corrente nominal ser maior. Neste motor a grande
vantagem é a lógica de acionamento mais simples, já que você só precisa enviar sinal em nível
lógico alto na bobina que deseja acionar e não ter que ficar raciocinando qual inverte o sentido
ou qual envia sinal direto. No final das contas, as sequências de acionamentos são iguais para
ambos os modelos (veja que no unipolar também é A,B,C e D), só que para o processo de apren-
dizado ele é mais simples de entender [29].

151
Figura 125: Exemplo motor unipolar - fonte: autor

17.3 Prática 26 - acionando motor de passo


Vamos acionar o motor de passo 28BYJ-48. Este motor de passo opera com 5V e 500mA. Po-
rém, devemos usar uma interface de chaveamento entre o motor e o Arduino, assim como no
motor DC. Para este caso, iremos usar o módulo ULN2004, que efetua a interface entre o pino
do Arduino que acionará uma bobina respectiva no motor. No link [Link]
resource/en/datasheet/[Link] e [Link]
28BYJ-48/1 você tem acesso aos datasheets desses componentes.
Conecte o motor ao módulo e utilize alimentações separadas para o motor e para o Arduino.
Não esqueca de interligar a os pinos GND entre todos os componentes.
O programa a seguir realiza o acionamento full step para o motor girar num sentido. O driver
ULN2003 opera em lógica inversa.

152
17.4 Servo Motor
Servomotores são motores DC com um sistema de controle eletrônico acoplado. Desta forma,
o controlador que comanda o motor recebe sinais PWM no qual a frequência e duty cicle serão
aferidos e convertidos para um valor de ângulo a partir da referência inicial. Desta forma, os
servomotores possuem uma altíssima precisão, porém limitação no movimento, operando en-
tre ângulos máximos de 90º a 270º (alguns modelos mais sofisticados consegue exercer voltas
completas). Por possuírem um sistema de redução, possuem alto torque também, porém sua
velocidade é muito lenta comparada aos outros modelos. Para a prática dessa seção, iremos
usar o servo motor SG90, que opera em 5V e com baixa corrente, podendo ser alimentado pelo
Arduino. Como a interface de controle é dentro do motor, basta apenas enviarmos o sinal PWM
conhecendo seus parâmetros (vide: [Link]
SG90/1).
Este motor opera entre 0º a 180º, nos respectivos duty cicles de 0,6ms a 2,4ms, com valor mí-
nimo de incremento no duty cicle de 10us ou 0,01ms. Cada ciclo completo do PWM deve ter
20ms, o que fixa a velocidade de rotação. Como o pwm do Arduino não possui exatamente esse
período de operação, teremos de fazer manualmente o controle, porém você pode usar a bibli-
oteca ’Servo.h’ se quiser facilidade [29].

17.5 Prática 27 - acionando servo motor SG90


O código a seguir fica movimentando o rotor do servo motor de um lado para o outro de 0º a
180º e um retorno para 45º e reinicia a sequência. Veja que nosso período de operação deve ser
sempre de 20ms, porém a posição do eixo varia de 0º a 180º, com você controlando o tempo em
nível alto de 0,6ms a 2,4ms, respectivamente. Se você fizer uma regra de três simples, verá que
são necessários 0,01ms/grau deslocado.
Na sua lógica você deve enviar sinal alto para o motor pelo tempo referente ao ângulo e deixar o
pino em sinal baixo até completar os 20ms restantes. Então se você quiser posicionar o rotor no
ângulo 0º, deverá deixa 0,6ms em nível alto e 19,4ms em nível baixo e ficar reenviando esse sinal
para o motor ficar com o eixo travado na posição.

153
18 Referências
Referências Bibliográficas
S ECTION

[1] Arduino. Arduino Analog IO. URL: [Link]


language/functions/analog-io/analogread/.
[2] Arduino. Arduino functions. URL: [Link]
functions.
[3] Arduino. Arduino Interruption. URL: [Link]
language/functions/external-interrupts/attachinterrupt/.
[4] Arduino. Arduino: Description. URL: https : / / www . arduino . cc / en / Guide /
Introduction.
[5] Arduino. Libraries. URL: [Link]

[6] Arduino. liquid crystal library. URL: [Link]


LiquidCrystal.
[7] arduinoportugal. ADXL355. URL: [Link]
acelerometro-3-eixos-adxl335-arduino/.
[8] Arduino e CIA. PIR. URL: [Link]
arduino-modulo-pir-dyp-me003/.
[9] blog curto circuito. strain gauge. URL: [Link]
blog/balanca-com-celula-de-carga-e-hx711.

154
[10] [Link]. Arduino Pinout. URL: [Link]
uno-pinout/.
[11] blog eletrogate. ponte H. URL: [Link]
de-uso-da-ponte-h-l298n/.
[12] Mundo da eletrônica. termopar. URL: [Link]
br/termopar-o-que-e-funcionamento-tipos-aplicacoes/.
[13] embarcados. SPI. URL: [Link]

[14] filipeflop. display lcd 16x2. URL: [Link]


um-lcd-16x2-com-arduino/.
[15] Felipe flop. DHT11. URL: [Link]
temperatura-e-umidade-com-o-sensor-dht11/.
[16] Felipe flop. DS18B20. URL: [Link]
temperatura-ds18b20-arduino/.
[17] Felipe flop. MLX90614. URL: [Link]
temperatura-mlx90614-arduino/.
[18] felipe flop. termistor ntc. URL: [Link]
ntc-arduino/.
[19] filipe flop. MPU6050. URL: [Link]
acelerometro-mpu6050-arduino/.
[20] Laboratório de Garagem. como aferir termistor ntc. URL: [Link]
com/profiles/blogs/tutorial- como- utilizar- o- termistor- ntc- com-
arduino.
[21] [Link]. Arduino Pinout. URL: [Link]
com/.
[22] IFPR. RMS value. URL: [Link]
Corrente_Cont%C3%ADnua_e_Corrente_Alternada.
[23] Usina info. lm35. URL: [Link] de-
temperatura-lm35-primeiros-passos/.
[24] usina info. matriz led. URL: [Link]
arduino-matriz-de-led-8x8-construindo-um-letreiro-luminoso/.
[25] Texas Instruments. CD4511 datasheet. URL: [Link]
datasheet-pdf/view/26905/TI/[Link].
[26] Joy-IT. KY-040. URL: [Link]
040/1.
[27] Easytrom Labs. encoder. URL: [Link]
lab-09-leitura-de-um-encoder-industrial-heidenhain-com-o-arduino/.
[28] microchip. ATMEGA328P: Owner. URL: [Link]
en/ATmega328P.

155
[29] N1. Fritzgerald e N2. Kingsley e N3. Stephen D. Umans. Máquinas Elétricas. Vol. 1.
Mc Graw Hill, 7ªed, 2014.

[30] Robocore. protocolos de comunicação e comparação. URL: [Link]


net/tutoriais/comparacao-entre-protocolos-de-comunicacao-serial.
html.
[31] autocore robótica. Arduino e interrupções. URL: [Link]
[Link]/realizando-interrupcao-no-arduino/.
[32] Portal vida de silício. Interrupções Arduino. URL: [Link]
[Link]/usando-a-interrupcao-externa-no-seu-arduino/.
[33] Wikipedia. displays. URL: [Link]

[34] Wikipedia. Wave form. URL: [Link]


onda.
[35] wikipedia. Ponte de Wheatstone. URL: https : / / pt . wikipedia . org / wiki /
Ponte_de_Wheatstone.
[36] wikipedia. sensores de posição. URL: [Link]
de_posi%C3%A7%C3%A3o.

156
Figura 126: Prática 26 - fonte: autor

157
Figura 127: Prática 27 - fonte: autor

158

Você também pode gostar