Você está na página 1de 89

1.1.

Introdução ao Arduino

O Arduino é uma plataforma de prototipagem eletrônica open-source que se baseia em


hardware e software flexíveis e fáceis de usar. É destinado a artistas, designers, hobbistas e
qualquer pessoa interessada em criar objetos ou ambientes interativos.
O Arduino pode sentir o estado do ambiente que o cerca por meio da recepção de sinais de
sensores e pode interagir com os seus arredores, controlando luzes, motores e outros
atuadores. O microcontrolador na placa é programado com a linguagem de programação
Arduino, baseada na linguagem Wiring, e o ambiente de desenvolvimento Arduino,
baseado no ambiente Processing. Os projetos desenvolvidos com o Arduino podem ser
autônomos ou pode comunicar-se com um computador para a realização da tarefa, com uso
de software específico (ex: Flash, Processing, MaxMSP).
As placas podem ser construídas de forma caseira (manualmente) ou adquiridas já
montadas e o software pode ser baixado gratuitamente. O projeto do hardware (arquivos de
CAD) está disponível sob licença open-source e você é livre para adaptá-lo para as suas
necessidades.
O Arduino recebeu uma menção honrosa na categoria Comunidades Digitais do prêmio Ars
Electronica Prix do ano de 2006.

1.2. Arduino Duemilanove

Geral
O Arduino Duemilanove ("2009") é uma placa de microcontrolador baseada no
ATmega328. Ele possui 14 pinos de entrada/saída digitais (dos quais 6 podem ser usados
como saídas analógicas PWM), 6 entradas analógicas, um cristal oscilador de 16 MHz, uma
conexão USB, uma entrada para alimentação, um conector ICSP e um botão de reset. Ele
contém tudo que é necessário para que o microcontrolador funcione; para começar, apenas
faça a conexão com um computador através de um cabo USB ou use uma fonte de
alimentação de corrente contínua ou uma bateria.
"Duemilanove" significa 2009 em italiano e o nome foi escolhido pelo ano de lançamento.
O Duemilanove é a mais recente de uma série de placas Arduino USB.

Características
Microcontrolador ATmega328
Voltagem operacional 5V
Voltagem de alimentação (recomendada) 7-12V
Voltagem de alimentação (limites) 6-20V
14 (dos quais 6 podem ser saídas
Pinos I/O digitais
PWM)
Pinos de entrada analógica 6
Corrente contínua por pino I/O 40 mA
Corrente contínua para o pino 3.3V 50 mA

Memória flash 32 KB (2KB usados para o


bootloader)
SRAM 2 KB
EEPROM 1 KB
Velocidade de clock 16 MHz

Alimentação
O Arduino Duemilanove pode ser alimentado pela conexão USB ou por qualquer fonte de
alimentação externa. A fonte de alimentação é selecionada automaticamente.
Alimentação externa (não-USB) pode ser tanto de uma fonte ou de uma bateria. A fonte
pode ser conectada com um plug de 2,1mm (centro positivo) no conector de alimentação.
Cabos vindos de uma bateria podem ser inseridos nos pinos Gnd (terra) e Vin (entrada de
voltagem) do conector de alimentação.
A placa pode operar com uma alimentação externa de 6 a 20 volts. Entretanto, se a
alimentação for inferior a 7 volts o pino 5V pode fornecer menos de 5 volts e a placa pode
ficar instável. Se a alimentação for superior a 12 volts o regulador de voltagem pode super-
aquecer e avariar a placa. A alimentação recomendada é de 7 a 12 volts.
Os pinos de alimentação são:

VIN. Entrada de alimentação para a placa Arduino quando uma fonte externa for utilizada.
Você pode fornecer alimentação por este pino ou, se usar o conector de alimentação,
acessar a alimentação por este pino.

5V. A fonte de alimentação utilizada para o microcontrolador e para outros componentes da


placa. Pode ser proveniente do pino Vin através de um regulador on-board ou ser fornecida
pelo USB ou outra fonte de 5 volts.

3V3. Alimentação de 3,3 volts fornecida pelo chip FTDI. A corrente máxima é de 50 mA.

GND. Pino terra.

Memória
O ATmega328 tem 32 KB de memória flash para armazenar código (dos quais 2 KB são
utilizados pelo bootloader), além de 2 KB de SRAM e 1 KB de EEPROM (que pode ser
lida e escrita através da biblioteca EEPROM ).

Entrada e Saída
Cada um dos 14 pinos digitais do Duemilanove pode ser usado como entrada ou saída,
usando as funções de pinMode(), digitalWrite(), e digitalRead(). Eles operam com 5 volts.
Cada pino pode fornecer ou receber um máximo de 40 mA e tem um resistor pull-up
interno (desconectado por padrão) de 20-50 kOhms. Além disso, alguns pinos têm funções
especializadas:
Serial: 0 (RX) e 1 (TX). Usados para receber (RX) e transmitir (TX) dados seriais TTL.
Estes pinos são conectados aos pinos correspondentes do chip serial FTDI USB-to-TTL.
External Interrupts: 2 and 3. Estes pinos podem ser configurados para disparar uma
interrupção.
PWM: 3, 5, 6, 9, 10, e 11. Fornecem uma saída analógica PWM de 8-bit com a função
analogWrite().
SPI: 10 (SS), 11 (MOSI), 12 (MISO), 13 (SCK). Estes pinos suportam comunicação SPI
(Motorola), que embora compatível com o hardware, não está incluída na linguagem do
Arduino.
LED: 13. Há um LED já montado e conectado ao pino digital 13. Quando o pino está no
valor HIGH, o LED acende; quando o valor está em LOW, ele apaga.
O Duemilanove tem 6 entradas analógicas e cada uma delas tem uma resolução de 10 bits
(i.e. 1024 valores diferentes). Por padrão, elas medem de 0 a 5 volts, embora seja possível
mudar o limite superior usando o pino AREF e um pouco de código de baixo nível.
Adicionalmente alguns pinos têm funcionalidades especializadas:
I2C: 4 (SDA) and 5 (SCL). Suportam comunicação I2C (TWI)-Philips- usando a biblioteca
Wire.
Há ainda alguns outros pinos na placa:
AREF. Referência de voltagem para entradas analógicas. Usados com analogReference().
Reset. Envie o valor LOW para resetar o microcontrolador. Tipicamente utilizados para
adicionar um botão de reset aos shields que bloqueiam o que há na placa.

Comunicação
Com o Arduino Duemilanove a comunicação com um computador, com outro Arduino ou
com outros microcontroladores é muito simplificada. O ATmega328 permite comunicação
serial no padrão UART TTL (5V), que está disponível nos pinos digitais 0 (RX) e 1 (TX).
Um chip FTDI FT232RL na placa encaminha esta comunicação serial através do USB e os
drives FTDI (incluído no software do Arduino) fornece uma porta COM virtual para o
software no computador. O software Arduino inclui um monitor serial que permite que
dados simples de texto sejam enviados à placa Arduino. Os LEDs RX e TX da placa piscam
quando os dados estão sendo transferidos ao computador pelo chip FTDI e a conexão USB
(mas não quando há comunicação serial pelos pinos 0 e 1).
A biblioteca SoftwareSerial permite comunicação serial por quaisquer dos pinos digitais do
Duemilanove.
O ATmega328 também oferece suporte aos padrões de comunicação I2C (TWI) e SPI. O
software do Arduino inclui uma biblioteca Wire para simplificar o uso do bus I2C;

Programação
O Arduino Duemilanove pode ser programado com o software Arduino. O ATmega328 no
Arduino Duemilanove vem pré-gravado com um bootloader que permite enviar novos
programas sem o uso de um programador de hardware externo. Ele se comunica utilizando
o protocolo original STK500.
Você também pode programar o ATmega328 através do ICSP (In-Circuit Serial
Programming) header;

Reset automático (Software)


Algumas versões anteriores do Arduino requerem um reset físico (pressionando o botão de
reset na placa) antes de carregar um sketch. O Arduino Duemilanove é projetado de modo a
permitir que isto seja feito através do software que esteja rodando no computador
conectado. Uma das linhas de controle de hardware (DTR) do FT232RL está conectada ao
reset do ATmega328 via um capacitor de 100 nanofarads . Quando esta linha é resetada
(ativo baixo) o sinal cai por tempo suficiente para resetar o chip. O software Arduino usa
esta característica para permitir carregar o programa simplesmente pressionando o botão
"upload" no ambiente Arduino. Isto significa que o "bootloader" pode ter um "timeout"
mais curto, já que a ativação do DTR (sinal baixo) pode ser bem coordenada com o início
do "upload".
Esta configuração tem outras implicações. Quando o Duemilanove está conectado a um
computador rodando Mac OS X ou Linux, ele reseta toda vez que a conexão é feita por
software (via USB). No próximo meio segundo aproximadamente, o bootloader estará
rodando no Duemilanove. Considerando que é programado para ignorar dados espúreos
(i.e. qualquer coisa a não ser um "upload" de um novo código), ele interceptará os
primeiros bytes de dados sendo enviados para a placa depois que a conexão é aberta. Se um
"sketch" rodando na placa recebe configuração de uma vez ou outros dados ao inicializar,
assegure-se que o software que esteja comunicando espere um segundo depois de aberta a
conexão antes de enviar estes dados.
O Duemilanove tem uma trilha que pode ser cortada para desabilitar o auto-reset e pode ser
ressoldada para reativá-lo. É chamada de "RESET-EN". Você pode também desabilitar o
auto-reset conectando um resistor de 110 ohms dos +5V até o sinal de reset;

Proteção contra sobrecorrente USB


O Arduino Duemilanove tem um polifusível resetável que protege a porta USB do seu
computador contra curto-circuito e sobrecorrente. Apesar da maioria dos computadores
possuírem proteção interna própria, o fusível proporciona uma proteção extra. Se mais de
500mA foram aplicados na porta USB, o fusível irá automaticamente interromper a
conexão até que o curto ou a sobrecarga seja removida.

Abaixo, tem-se o mapeamento dos pinos do microcontrolador AVR ATmega 328 utilizado
no Arduino Duemilanove.
1.3. Esquema eletrônico e características do Arduino Duemilanove

Resumo das características do Arduino Duemilanove

Microcontroller ATmega
Operating Voltage 5V
Input Voltage
7-12V
(recommended)
Input Voltage (limits) 6-20V
Digital I/O Pins 14 (of which 6 provide PWM output)
Analog Input Pins 6
DC Current per I/O Pin 40 mA
DC Current for 3.3V Pin 50 mA

16 KB (ATmega168) or 32 KB (ATmega328) of which 2 KB


Flash Memory
used by bootloader

SRAM 1 KB (ATmega168) or 2 KB (ATmega328)


EEPROM 512 bytes (ATmega168) or 1 KB (ATmega328)
Clock Speed 16 MHz

O diagrama eletro-eletrônico abaixo representa o Hardware do Arduino Duemilanove.


1.4. Ambiente de desenvolvimento Integrado (IDE)

1.4.1. Instalação no Windows

Como rodar o Arduino no Windows

Este documento explica como conectar a placa Arduino ao computador e enviar o seu
primeiro programa.
Estes são os passos que seguiremos.

 Consiga uma placa Arduino e um cabo.


 Faça o download do ambiente de desenvolvimento do Arduino.
 Instale os drivers USB.
 Conecte a placa.
 Conecte um LED.
 Rode o ambiente de desenvolvimento integrado (IDE) do Arduino.
 Envie um programa.
 Veja o LED piscando.
 Aprenda a usar o Arduino.

 Consiga uma placa Arduino e um cabo.


Neste tutorial nós assumimos que você está usando um Arduino Diecimila.
O Arduino Diecimila é uma placa simples que contém tudo o que você precisa para
começar a trabalhar com eletrônica e programação de microcontroladores. Este diagrama
ilustra os principais componentes da placa.

Você também vai precisar de um cabo USB padrão (plugue A para plugue B): o mesmo tipo
que você usaria para conectar uma impressora USB, por exemplo.
 Faça o download do ambiente de desenvolvimento integrado (IDE) do Arduino
Para programar uma placa Arduino você precisa do ambiente de desenvolvimento integrado
(IDE).
Faça o download da última versão a partir da página de downloads (www.arduino.cc).
Quando o download terminar descompacte (unzip) os arquivos. Certifique-se de preservar a
estrutura das pastas. Abra a pasta. Dentro você vai encontrar alguns arquivos e sub-pastas.

Localize os drivers USB

Se você está usando um Arduino USB então vai precisar instalar o driver para o chip FTDI
da placa. Este driver pode ser encontrado na pasta drivers/FTDI USB Drivers da
distribuição do Arduino. No próximo passo ("Conecte a placa"), você vai apontar o
Assistente para adcionar novo Hardware do Windows para estes drivers.
A versão mais atual do driver pode ser encontrada no site da FTDI.

Conecte a placa

No Diecimila, a fonte de energia é selecionada por um jumper entre o USB e o plugue de


energia. Para alimentar a placa pela porta USB (bom para controlar aparatos de baixa
potência como os LEDs), coloque o jumper nos dois pinos mais próximos ao plugue do
USB. Para alimentar a placa a partir de uma fonte externa (6 a 12V), coloque o jumper nos
dois pinos mais próximos ao plugue de energia. No Duemilanove, a fonte de energia é
selecionada automaticamente (não há o jumper). De qualquer modo conecte a placa à porta
USB no seu computador.
O LED do power deve acender.

O Assistente para adicionar novo Hardware vai abrir. Escolha não se conectar ao site do
Windows e clique em avançar.
Selecione então instalar de uma lista ou local específico (avançado) e clique em avançar.

Certifique-se de escolher "Procurar o melhor driver nestes locais", desmarque "Pesquisar


mídia removível", e marque em "Incluir este local na pesquisa:" e navegue até a pasta em
que você descompactou os arquivos do driver USB no passo anterior. Clique em Avançar.
O assistente vai procurar o driver e dizer a você que um "Conversor Serial USB" foi
encontrado. Clique em finalizar.

O assistente vai aparecer de novo. Siga os mesmos passos. Desta vez uma "Porta Serial
USB" vai ser encontrada.
Conecte um LED (se você estiver usando uma placa antiga)
O primeiro esquema que você vai enviar à placa Arduino faz um LED piscar. O Arduino
Diecimila (e o Arduino NG original) têm incorporado um resistor e um LED no pino 13.
No Arduino NG Rev. C e nas placas Arduino pre-NG, entretanto, o pino 13 não tem um
LED incorporado. Nestas placas, você vai precisar conectar o terminal anodo (terminal
mais longo) do LED no pino 13 e o catodo (terminal mais curto) ao terra (marcado como
"GND"). O LED tipicamente é plano do lado do terminal catodo. Normalmente você
também precisa de um resistor junto com o LED, mas nestas placas há um resistor
incorporado no pino 13.

Rode o ambiente de desenvolvimento do Arduino

Abra a pasta do Arduino e dê um clique duplo na aplicação do Arduino.

Envie um programa

Abra o exemplo de piscar o LED: File > Sketchbook > Examples > Digital > Blink.
A figura abaixo mostra a janela do ambiente integrado do arduino, com o programa
exemplo.
Selecione o dispositivo da placa Arduino no menu Tools | Serial Port. No Windows deveria
ser COM1 ou COM2 para uma placa Arduino serial. ou COM3, COM4 ou COM5 para uma
placa USB. Para descobrir qual é, abra o Gerenciador de Dispositivos do Windows (na aba
Hardware do painel de controle do sistema). Procure por "USB Serial Port" na seção de
Portas; esta é a da placa Arduino.
Certifique-se que o "Arduino Diecimila" está selecionado em Tools > Board menu.

Agora simplesmente clique no botão "Upload" do ambiente. Espere alguns segundos - você
deve ver os LEDs RX e TX piscando. Se o envio foi correto a mensagem "Done
uploading." vai aparecer na barra de status. (Nota: Se você tem um Arduino Mini, NG, ou
outra placa, você vai ter que apertar o botão de reset diretamente na placa imediatamente
antes de clicar no botão de upload.)
Veja o LED piscando

Alguns segundos após o término do envio você deverá ver o LED amarelo da placa
começar a piscar. Se isto acontecer, você está com o Arduino instalado e funcionando.
Capítulo 2

Referências da Linguagem Arduino

1. setup()

A função setup() é chamada quando um programa começa a rodar. Use esta função para
inicializar as sua variáveis, os modos dos pinos, declarar o uso de bibliotecas, etc. Esta
função será executada apenas uma vez após a placa Arduino ser ligada ou ressetada.

Exemplo

int buttonPin = 3;

void setup()
{
Serial.begin(9600);
pinMode(buttonPin, INPUT);
}

void loop()
{
// ...
}

2. loop()

Após criar uma fução setup() que declara os valores iniciais, a função loop() faz exatamente
o que seu nome sugere, entra em looping (executa sempre o mesmo bloco de código),
permitindo ao seu programa fazer mudanças e responder. Use esta função para controlar
ativamente a placa Arduino.

Exemplo

int buttonPin = 3;

// setup inicializa a comunicação serial e configura o pino 3 (buttonPin) como saída;


void setup()
{
beginSerial(9600);
pinMode(buttonPin, INPUT);
}

// loop checa o botão a cada vez,


// e envia o serial se ele for pressionado
void loop()
{
if (digitalRead(buttonPin) == HIGH)
serialWrite('H');
else
serialWrite('L');

delay(1000);
}

3. Operadores de comparação

Os operadores de comparação da linguagem de programação C/C++.

x == y (x é igual a y)
x != y (x é não igual a y)
x < y (x é menor que y)
x > y (x é maior que y)
x <= y (x é menor ou igual a y)
x >= y (x é maior ou igual a y)

4. Operadores booleanos

Os operadores booleanos da linguagem C/C++.

4.1. && ("E" lógico)

Verdadeiro apenas se os dois operandos forem verdadeiros, ou seja a primeira condição "e"
a segunda forem verdadeiras, e.g.
if (digitalRead(2) == 1 && digitalRead(3) == 1) { // ler dois interruptores
// ...
}

é verdadeiro apenas se os dois interruptores estiverem fechados.

4.2. || ("OU" lógico)

Verdadeiro se algum dos operandos for verdadeiro, ou seja se a primeira "ou" a segunda
condição for verdadeira e.g.

if (x > 0 || y > 0) {
// ...
}
é verdadeiro apenas se x ou y forem maiores que 0.
4.3. ! (negação)

Verdadeiro apenas se o operando for falso e.g.

if (!x) {
// ...
}

É verdadeiro apenas se x for falso (i.e. se x for igual a 0).

Cuidado
Certifique-se de não confundir o operador booleano "E" representado por "&&" e o
operador lógico de bits "E" representado apenas por "&". Do mesmo modo não confunda o
booleano "OU" representado por "||" e o operador lógico de bits "|".
O operador lógico de bits "NÃO" representado por um "~" não se parece com o operador
booleano "!", mas mesmo assim tenha certeza de estar usando o que você deseja.

Exemplo

if (a >= 10 && a <= 20){} // verdadeiro se a estiver entre 10 e 20

5. Operadores de bits

Os operadores de bits realizam cálculos ao nível de bits das variáveis. Eles ajudam a
resolver uma grande quantidade de problemas de programação.

5.1. Operador de bits AND (&)

O operador de bits AND (e) em C++ é um simples & usado entre duas outras expressões
inteiras. Ele realiza uma operação entre cada bit de cada uma destas expressões de acordo
com a seguinte regra: se os dois bits de entrada forem 1 o resultado da operação também é
1, caso contrário é 0. Outro modo de expressar esta regra é:

0 0 1 1 operando1
0 1 0 1 operando2
----------
0 0 0 1 (operando1 & operando2) - resultado de retorno

Em Arduino, o tipo int (inteiro) é um valor de 16 bits, portanto usando & entre duas
expressões int faz com que ocorram 16 operações AND simultâneas. Em um fragmento de
código:

int a = 92; // em binario: 0000000001011100


int b = 101; // em binario: 0000000001100101
int c = a & b; // resultado: 0000000001000100, ou 68 em decimal.
Cada um dos 16 bits em a AND b, é processado usando este operador e todos os 16 bits
resultantes são armazenados em c resultado o valor 0000000001000100, que é 68 na
notação decimal.
Um dos usos mais comuns do operador de bits AND é selecionar alguns bits de um valor
inteiro, freqüentemente chamado de máscara.

5.2. Operador de bits OR ( | )

O operador de bits OR (ou) em C++ é o símbolo de barra vertical, |. Como o operador & ele
realiza cálculos com cada bit de duas expressões seguindo a seguinte regra: o resultado da
operação é 1, se um dos bits de entrada for 1, caso contrário é 0. Em outras palavras:

0 0 1 1 operando1
0 1 0 1 operando2
----------
0 1 1 1 (operando1 | operando2) - resultado de retorno

Em um fragmento de código:

int a = 92; // in binario: 0000000001011100


int b = 101; // in binario: 0000000001100101
int c = a | b; // resultado: 0000000001111101, ou 125 em decimal.

Exemplo

Um uso comum para os operadores de bits AND e OR é o que os programadores chamam


Ler-Modificar-Escrever em uma porta. Em microcontroladores, uma porta é um registrador
de 8 bits que representa os estados de entrada ou saída dos pinos digitais.

Escrevendo em um controle de porta, todos os pinos são modificados de uma vez.


PORTD é uma constante pré-construída (Registrador) que se refere aos estados de saída dos
pinos digitais 0,1,2,3,4,5,6,7. Se há um 1 em algum dos bits, então este pino está em HIGH.
(os pinos ainda precisam ser definidos como pinos de saída pelo comando pinMode()).
Deste modo se escrevemos PORTD = B10001100; o que fazemos é colocar os pinos 2,3 e 7
em HIGH. Um efeito colateral é que mudamos o estado dos pinos 0 e 1 que são usados pelo
Arduino na comunicação serial, ou seja, interferimos nesta comunicação.

Nosso algoritmo para este programa deve ser:

Ler o PORTD e limpar somente os bits que queremos controlar (com o operador AND).
Combinar o valor modificado de PORTD com o novo valor dos pinos que queremos
controlar (com o operador OR).

int i; // variável do contador


int j;

void setup(){
DDRD = DDRD | B11111100; // marca a direção dos bits para os pinos 2 a 7 deixando
os //pinos 0 e o 1 intocados (xx | 00 == xx)
// o mesmo que pinMode(pin, OUTPUT) para os pinos 2 a 7
Serial.begin(9600);
}

void loop(){
for (i=0; i<64; i++){
PORTD = PORTD & B00000011; // limpa os bits de 2 - 7, deixa os pinos 0 e 1 intocados //
(xx & 11 == xx)
j = (i << 2); // desvia os bits da variavel 2 bits para a esquerda para evitar os pino 0 e 1
PORTD = PORTD | j; // combina a informação da porta com a nova informação para os
//pinos dos LEDs
Serial.println(PORTD, BIN); // debug para verificar a máscara
delay(100);
}
}

5.3. Operador de bits XOR ( ^ )

Há um operador um pouco raro em C++ chamado EXCLUSIVE OR (ou exclusivo)


também conhecido por XOR. Este operador é escrito com o símbolo do acento circunflexo
^. O resultado desta operação é 1 se os dois bits de entrada forem diferentes, caso contrário
retorna 0:

0 0 1 1 operando1
0 1 0 1 operando2
----------
0 1 1 0 (operando1 ^ operando2) - resultado de retorno

Um simples código de exemplo:

int x = 12; // binario: 1100


int y = 10; // binario: 1010
int z = x ^ y; // binario: 0110, or decimal 6

O operador XOR é freqüentemente utilizado para inverter alguns dos bits de uma expressão
inteira. Na máscara deste operador se há um 1 o bit correspondente é invertido, se há um
zero o bit é mantido como está. Abaixo há um programa para piscar o pino digital 5.

// Piscar_Pino_5
// demonstração para o Exclusive OR

void setup(){
DDRD = DDRD | B00100000; // marca o pino digital 5 como saida.
Serial.begin(9600);
}
void loop(){
PORTD = PORTD ^ B00100000; // inverte o bit 5 (digital pino 5), mantem os demais
intocados.
delay(100);
}

6. Operadores compostos

6.1. ++ (incremento) / -- (decremento)

Descrição
Incrementar ou decrementar uma variável (adicionar ou subtrair 1)

Sintaxe
x++; // incrementa x em 1 e retorna o antigo valor de x
++x; // incrementa x em 1 e retorna o novo vaor de x

x-- ; // decrementa x em 1 e retorna o antigo valor de x


--x ; // decrementa x em 1 e retorna o novo valor de x

Parâmetros
x: uma variável do tipo int ou long (possivelmente não assinalada)

Retornos
O original ou recentemente incrementado / decrementado valor da variável.

Exemplos
x = 2;
y = ++x; // x agora contém 3, y contém 3
y = x--; // x contém 2 de novo, y ainda contém 3

6.2. += , -= , *= , /=

Descrição
Realiza uma operação matemática em uma variável com outra constante ou variável. O
operador += (e os outros) são apenas abreviações práticas da sintaxe expandida listada
abaixo:

Sintaxe
x += y; // equivalente à expressão x = x + y;
x -= y; // equivalente à expressão x = x - y;
x *= y; // equivalente à expressão x = x * y;
x /= y; // equivalente à expressão x = x / y;

Parâmetros
x: qualquer tipo de variável
y: qualquer tipo de variável ou constante

Exemplos
x = 2;
x += 4; // x agora contém 6
x -= 3; // x agora contém 3
x *= 10; // x agora contém 30
x /= 2; // x agora contém 15

7. Variáveis

Variáveis são expressões que você pode usar em programas para armazenar valores como a
leitura de um sensor em um pino analógico.

8. Tipos de dados

Variáveis podem ser de vários tipos:

8.1. booleanos

Variáveis booleanas podem ter apenas dois valores: verdadeiro (true) e falso (false).

Exemplo

int LEDpin = 5; // LED no pino 5


int switchPin = 13; // interruptor no, outro lado conectado ao terra.

boolean running = false;

void setup()
{
pinMode(LEDpin, OUTPUT);
pinMode(switchPin, INPUT);
digitalWrite(switchPin, HIGH); // "levanta" o resistor
}

void loop()
{
if (digitalRead(switchPin) == LOW)
{ // interruptor é pressionado - resistor se mantém "levantado"
delay(100); // espera para filtrar ruído da chave
running = !running; // inverte o valor da variável running
digitalWrite(LEDpin, running) // indica via LED
}
}
8.2. char

Descrição
Um tipo de dado que ocupa 1 byte de memória e armazena o valor de um caractere.
Caracteres literais são escritos entre ' ' (em inglês estes caracteres se chamam single quotes,
não consigo imaginar como possa ser em português) como este: 'A' (para cdeias de
caracteres - strings - use aspas: "ABC").
Entretanto caracteres são armazenados como números. Você pode ver o código específico
na tabela ASCII. Isto significa que é possível realizar operações artiméticas com caracteres,
nos quais o valor ASCII do caractere é utilizado (e.g. 'A' + 1 vale 66, desde que o valor
ASCII do A máiusculo é 65). O tipo de dado char é também do tipo assinalado, isso quer
dizer que é possível codificar números de -128 a 127. Para um tipo de dado não assinalado
de 1 byte (8 bits) use o tipo de dado byte.

Exemplo
char myChar = 'A';
char myChar = 65; // ambos são equivalentes

8.3. byte

Descrição
Um byte armazena um número de 8 bits não assinalado, de 0 a 255.

Exemplo
byte b = B10010; // "B" é o formatador binário (B10010 = 18 decimal)

8.4. int

Descrição
Inteiro é o principal tipo de dado para armazenamento numérico capaz de números de 2
bytes. Isto abrange a faixa de -32.768 a 32.767 (valor mínimo de -2^15 e valor máximo de
(2^15) -1).
Ints armazenam números negativos com uma técnica chamada Complemento de dois. O bit
mais alto, as vezes chamado de bit de "sinal", sinaliza se o número é positivo ou negatico.
O Arduino cuida da manipulação de números nagativos para você, assim as operações
aritméticas funcionam de modo transparente e esperado. Entretanto pode ocorrer uma
complicação inesperada na manipulação do operador para deslocar bits à direita (>>).

Exemplo
int ledPin = 13;

Sintaxe
int var = val;

var - o nome da variável int


val - o valor designado para a variável
Dica de programação
Quando uma variável excede seu valor máximo de que é capaz ela "decai" ao valor mínimo
de que é capaz. Note que isso ocorre nas duas direções.
int x
x = -32,768;
x = x - 1; // x agora contém 32,767 - decaindo na direção negativa

x = 32,767;
x = x + 1; // x agora contém -32,768 - decaido

8.5. unsigned int ( int não assinalado)

Descrição
ints não assinalados (inteiros sem sinal) são o mesmo que ints no modo como armazenam
valores de 2 bytes. Entretanto, ao invés de armazenar números negativos, armazenam
somente valores positivos abrangendo a faixa de 0 a 65.535 ((2^16)-1).
A diferença entre ints e ints não assinalados está no modo como o bit mais alto é
interpretado. No Arduino o tipo int (que é assinalado), se o bit mais elevado é 1, o número é
interpretado como negativo.

Exemplo
unsigned int ledPin = 13;

Sintaxe
unsigned int var = val;

var - nome da variável do tipo int não assinalado


val - o valor designado para a variável

Dica de programação
Quando variáveis excedam sua capacidade máxima elas "decaem" para o valor de sua
capacidade mínima. Note que isso ocorre nas duas direções.

Exemplo
unsigned int x;
x = 0;
x = x - 1; // x agora contém 65535 - decaindo na direção negativa
x = x + 1; // x agora contém 0 - decaindo

8.6. long

Descrição

Variáveis do tipo long têm um tamanho ampliado para armazenamento de números, e são
capazes de armazenar 32 bits (4 bytes), de -2.147.483,648 a 2.147.483.647.
Exemplo
long speedOfLight = 186000L; // veja Constantes inteiras para a explicação do 'L'

Sintaxe
long var = val;
var - o nome da variável de tipo long
val - o valor designado para a variável

8.7. unsigned long ( long não assinalado)

Descrição

long não assinalados (longos sem sinal) são variáveis de tamanho ampliado para
armazenamento numérico. Diferente do long padrão, os não assinalados não armazenam
números negativos, abrangendo a faixa de 0 a 4.294.967.295 (2^32 - 1).

Exemplo
unsigned long time;

void setup()
{
Serial.begin(9600);
}

void loop()
{
Serial.print("Time: ");
time = millis();
//imprime o tempo desde que o programa começou a rodar
Serial.println(time);
// espera um segundo de modo que o programa não envie quantidades absurdas de dados
delay(1000);
}

Sintaxe
unsigned long var = val;
var - o nome de sua variável tipo long
val - o valor designado para a variável

8.8. float

Descrição

Tipo de dado para números de ponto flutuante, um número que tem um ponto decimal.
Números de ponto flutuante são freqüentemente usados para aproximar valores análogos e
contínuos porque têm mais resolução que os inteiros. Números de ponto flutuante
abrangem a faixa de 3,4028235E+38 a -3,4028235E+38. Eles são armazenados em 32 bits
(4 bytes) de informação.
Números de ponto flutuante não são exatos e podem gerar resultados estranhos quando
comparados. Por exemplo, 6.0 / 3.0 pode não ser igual a 2.0. Você deve, em vez disso,
verificar que o valor absoluto da diferença entre os números é menor que um valor pré-
determinado.
A matemática de ponto flutuante também é muito mais lenta que a dos inteiros. Na
realização de cálculos, deve ser evitada se, por exemplo, um loop tem que rodar a
velocidade máxima para uma função em que o tempo é crítico. Programadores
freqüentemente se esforçam para converter cálculos com pontos flutuantes em matemática
de inteiros para aumentar a velocidade.

Sintaxe
float var = val;
var - o nome da sua variável de ponto flutuante
val - o valor designado para a variável

Exemplo
int x;
int y;
float z;

x = 1;
y = x / 2; // y agora contém 0, inteiros não suportam frações
z = (float)x / 2.0; // z agora contém .5 (você deve usar 2.0, não 2)

Dica de programação
Serial.println() trunca os floats (despreza as frações) em inteiros quando enviando
comunicação serial. Multiplique por potências de 10 para preservar a resolução.

8.9. double

Descrição
Número de ponto flutuante de precisão dupla. Ocupa 4 bytes.
A implementação do double no Arduino é atualmente exatamente a mesma do float, sem
ganho de precisão.

Dica
Usuários que utilizam códigos de outras fontes que incluem variáveis do tipo double devem
examinar o código para verificar se a precisão implicada é diferente daquela realmente
alcançada pelo Arduino
8.10. Arrays

Um array é uma coleção de variáveis que são acessadas com um índice numérico. Arrays na
liguagem de programação C, na qual o Arduino é baseado, podem ser complicados, mas o
uso de arrays unidimensionais é relativamente simplificada.

Criando (Declarando) um Array


Todos os métodos abaixo são modos válidos para criar (declarar) um array.
int myInts[6];
int myPins[] = {2, 4, 8, 3, 6};
int mySensVals[6] = {2, 4, -8, 3, 2};
char message[6] = "hello";

Você pode declarar um array sem inicializar como em myInts.


Em myPins declaramos um array sem escolher explicitamente um tamanho. O compilador
conta os elementos e cria o array do tamanho apropriado.
Finalmente, você pode inicializar e especificar o tamanho do array como em mySensVals.
Note que quando declarar um array do tipo char, um elemento a mais é necessário para
armazenar o caractere null de finalização.

Acessando um Array
Arrays são indexados a partir do zero, ou seja, fazendo referência à inicialização de arrays
acima, o primeiro elemento do array está no índice 0, assim:
mySensVals[0] == 2, mySensVals[1] == 4,
e assim por diante. Isso também significa que em um array de 10 elementos o índice do
último elemento é 9, assim:
int myArray[10]={9,3,2,4,3,2,7,8,9,11};
// myArray[9] contém 11
// myArray[10] é inválido e contém informação aleatória (outro endereço de memória)
Por esta razão você deve acessar arrays cuidadosamente. Acessar um array após o seu final
(usando um índice maior do que o declarado) é ler uma faixa de memória que está sendo
utilizada para outros propósitos. Ler destes locais provavelmente não vai gerar nada além
de dados inválidos. Escrever em locais de memória aleatórios decididamente não é uma boa
idéia, e provavelmente conduzirá a maus resultados como mal funcionamento ou
travamento do programa. Isto também pode ser um bug difícil de rastrear.
Diferente de algumas versões do BASIC, o compilador C não checa para ver se um acesso
a um array está dentro das margens legais do tamanho com que o array foi declarado.

Designar um valor para um array:


mySensVals[0] = 10;
Recuperar um valor de um array:
x = mySensVals[4];
Arrays e FOR
Arrays são freqüentemente manipulados dentro da sentença for, nas quais o contador é
usado com índice para cada elemento. Por exemplo, para imprimir os elementos de um
array através da porta serial você poderia fazer alguma coisa assim:
int i;
for (i = 0; i < 5; i = i + 1) {
Serial.println(myPins[i]);
}

8.11. String

Descrição
Strings são representadas como arrays do tipo de dado char e terminadas por null (código
ASCII 0).

Exemplos
Abaixo, declarações válidas de strings.
char Str1[15];
char Str2[8] = {'a', 'r', 'd', 'u', 'i', 'n', 'o'};
char Str3[8] = {'a', 'r', 'd', 'u', 'i', 'n', 'o', '\0'};
char Str4[ ] = "arduino";
char Str5[8] = "arduino";
char Str6[15] = "arduino";

Possibilidades de declaração de strings

Declarar um array de chars sem inicializar como em Str1;


Declarar um array de chars (com um char a mais) e o compilador vai adicionar o caractere
null necessário como em Str2;
Adicionar explicitamente o caractere null como em Str3;
Inicializar com uma string constante entre aspas; o compilador determina o tamanho a
armazenar a string e o caractere null final como em Str4;
Inicializar o array com uma string constante e o tamanho explícitos como em Str5;
Inicializar o array deixando espaço extra para uma string maior como em Str6;

Terminação em Null
Geralmente strings são terminadas com o caractere null (código ASCII 0). Isto permite às
funções (como Serial.print()) saber onde está o final da string. De outro modo elas
continuariam lendo os bytes subsequentes da memória que de fato não pertencem à string.
Isto significa que sua string deve ter espaço para um caractere a mais do que o texto que ela
contém. É por isso que Str2 e Str5 precisam ter 8 caracteres, embora "arduino" tenha
apenas 7 - a última posição é automaticamente preenchida com o caracatere null. Str4 terá o
tamanho determinado automaticamente como 8 caracteres, um extra para o null. Na Str3
nós incluímos explicitamente o caractere null (escrito como '\0').
Note que é possível ter uma string sem o caractere final null (e.g. se você tivesse
especificado o tamanho da Str2 com sete ao invés de oito). Isto vai danificar a maioria das
funções que usam strings, portanto você não deve fazer isso intencionalmente. Entretanto se
você notar algo se comportando de maneira estranha (operações em caracteres que não
pertencem à string) este poderia ser o problema.
Aspas ou apóstrofos?
Strings são sempre definidas com aspas ("Abc") e caracteres sempre definidos com
apóstrofos('A').

Envolvendo strings longas


Você pode envolver strings longas desse modo:
char myString[] = "This is the first line"
" this is the second line"
" etcetera";

Arrays de strings
Freqüentemente é conveniente, quando se está trabalhando com grandes quantidades de
texto, como em um projeto com um display de LCD, configurar um array de strings.
Devido ao fato de as strings serem elas mesmas arrays, este é de fato um exemplo de um
array bi-dimencional.
No código abaixo os asteriscos após o tipo de dado char "char*" indica que se trata de um
array de "ponteiros". Todos os nomes de array são de fato ponteiros, e assim são requeridos
para se configurar um array de arrays. Ponteiros são uma das partes mais esotéricas da
linguagem C que os principiantes têm que entender, mas é necessário entender os ponteiros
em detalhe para fazer um uso efetivo deles neste caso.

Exemplo
char* myStrings[]={"This is string 1", "This is string 2", "This is string 3",
"This is string 4", "This is string 5","This is string 6"};

void setup(){
Serial.begin(9600);
}

void loop(){
for (int i = 0; i < 6; i++){
Serial.println(myStrings[i]);
delay(500);
}
}

8.12. void

A palavra-chave void é usada apenas em declarações de funções. Ela indica que a função
não deve enviar nenhuma informação de retorno à função que a chamou.
Exemplo:
// ações são realizadas nas funções "setup" e "loop"
// mas nenhuma informação é enviada ao programa mais amplo

void setup()
{
// ...
}

void loop()
{
// ...
}

9. Constantes

Constantes são variáveis pré-definidas na linguagem Arduino. Elas são usadas para tornar
os programas mais facilmente legíveis. Nós classificamos as constantes em grupos.

Definindo níveis lógicos, verdadeiro e falso (constantes booleanas)


Há duas constantes usadas para representar verdade ou falsidade na linguagem Arduino:
true (verdadeiro), e false (falso).

false
false é a mais simples das duas e é definida como 0 (zero).

true
true é frequentemente definida como 1, o que é correto, mas true tem uma definição mais
ampla. Qualquer inteiro que não é zero é TRUE, em um modo booleano. Assim, -1, 2 e
-200 são todos definidos como true.
Note que true e false são digitadas com minúsculas diferente de HIGH, LOW, INPUT, e
OUTPUT.

Definindo níveis de pinos, HIGH e LOW


Quando estamos lendo ou escrevendo em um pino digital há apenas dois valores que um
pino pode ter: HIGH (alto) e LOW (baixo).

HIGH
O significado de HIGH (em referência a um pino) pode variar um pouco dependendo se
este pino é uma entrada (INPUT) ou saída (OUTPUT). Quando um pino é configurado
como INPUT com pinMode, e lido com um digitalRead, o microcontrolador considera
como HIGH se a voltagem for de 3 volts ou mais.
Um pino também pode ser configurado como um INPUT com o pinMode, e posteriormente
receber um HIGH com um digitalWrite, isto vai "levantar" o resistor interno de 20KΩ que
vai manter a leitura do pino como HIGH a não ser que ela seja alterada para low por um
circuíto externo.
Quando um pino é configurado como OUTPUT com o pinMode, e marcado como HIGH
com o digitalWrite, ele está a 5 volts. Neste estado ele pode enviar corrente como por
exemplo acender um LED que está conectado com um resistor em série ao terra, ou a outro
pino configurado como OUTPUT e marcado como LOW.

LOW
O significado de LOW também pode variar dependendo do pino ser marcado como INPUT
ou OUTPUT. Quando um pino é configurado como um INPUT com o pinMode, e lido com
o digitalRead, o microcontrolador considera como LOW se a voltagem for de 2 volts ou
menos.
Quando um pino é configurado como OUTPUT com pinMode, e marcado como LOW com
o digitalWrite, ele está a 0 volts. Neste estado ele pode "drenar" corrente como por exemplo
para acender um LED que está conectado com um resistor em série ao +5 volts, ou a outro
pino configurado como OUTPUT e marcado como HIGH.

Definindo pinos digitais, INPUT e OUTPUT

Pinos digitais podem ser tanto de INPUT como de OUTPUT. Mudar um pino de INPUT
para OUTPUT com pinMode() muda drasticamente o seu comportamento elétrico.
Pinos configurados como Inputs.
Os pinos do Arduino (Atmega) configurados como INPUT com pinMode() estão em um
estado de alta impedância. Um modo de explicar é que os pinos configurados como INPUT
fazem demandas extremamente pequenas ao circuíto do qual estão tomando amostras, algo
como um resistor de 100 Megaohms em série com o pino. Sendo assim é útil para ler um
sensor mas não para energizar um LED.

Pinos configurados como outputs

Pinos configurados como OUTPUT com pinMode() estão em um estado de baixa


impedância. Isto significa que eles podem fornecer grandes quantidades de corrente para
outros circuítos. Os pinos do Atmega podem fornecer corrente positiva ou drenar corrente
negativa até 40 mA (milliamperes) de/para outros dispositivos ou circuitos. Isto faz com
que eles sejam úteis para energizar um LED mas disfuncionais para a leitura de sensores.
Pinos configurados como outputs também podem ser danificados ou destruídos por curto-
circuitos com o terra ou com outros pontos de 5 volts. A quantidade de corrente fornecida
por um pino do Atmega também não é suficiente para ativar muitos relês e motores e, neste
caso, algum circuíto de interface será necessário.

9.1. Constantes inteiras

Constantes inteiras são números usados diretamente no código. Por padrão estes números
são tratatados como int, mas você pode alterar este comportamento com os modificadores
U e L (veja abaixo).
Normalmente constantes inteiras são tratadas na base 10 (decimal), mas formatadores
especiais podem ser usados para entrar números em outras bases.

Base Exemplo Formatador Comentário

10 (decimal) 123 nenhum

2 (binário) B1111011 'B' inicial valores de 8 bits (0 a 255)

8 (octal) 0173 '0' inicial caracteres válidos: 0-7

16 (hexadecimal) 0x7B '0x' inicial caracteres válidos: 0-9 A-F, a-f

Decimal são na base 10. Esta é a matemática do senso comum com a qual você está
acostumado. Constantes sem outros prefixos são assumidos como decimais.

Exemplo:
101 // o mesmo que 101 decimal ((1 * 10^2) + (0 * 10^1) + 1)

Binários são na base 2. Apenas os caracteres 0 e 1 são válidos.

Exemplo:
B101 // o mesmo que 5 decimal ((1 * 2^2) + (0 * 2^1) + 1)
O formatador binário trabalha apenas com bytes (8 bits) entre 0 (B0) e 255 (B11111111).
Se for conveniente entrar um número de 16 bits na forma binária você pode fazer isso
seguindo o algoritmo abaixo:
myInt = B1100110010101010; // entrada inválida
myInt = (B11001100 * 256) + B10101010; // B11001100 é o primeiro byte e B10101010
o segundo.

Octais são na base oito. Apenas caracteres entre 0 e 7 são válidos. Valores octais são
indicados pelo prefixo "0".

Exemplo:
0101 // o mesmo que 65 decimal ((1 * 8^2) + (0 * 8^1) + 1)

Cuidado
É possível gerar um erro difícil de encontrar (não intencional) incluindo um zero à frente de
uma constante o que fará com que o compilador interprete o valor como octal.
Hexadecimais (ou hex) são na base 16. Caracteres válidos são de 0 a 9 e as letras de A a F;
A vale 10, B vale 11 até F que vale 15. Valores hexadecimais são indicados pelo prefixo
"0x". Note A-F pode ser escrito tanto com maiúsculas quanto com minúsculas (a-f).

Exemplo:
0x101 // o mesmo que 257 decimal ((1 * 16^2) + (0 * 16^1) + 1)
Formatadores U e L
Por padrão uma constante inteira é tratada como um int com as limitações pertinentes nos
valores. Para especificar uma constante inteira com outro tipo de dado proceda assim:
um 'u' ou 'U' para forçar a constante como do tipo não assinalado (unsigned). Exemplo: 33u
um 'l' ou 'L' para forçar a constante como do tipo longo (long). Exemplo: 100000L
um 'ul' ou 'UL' para forçar a constante como do tipo longo não assinalado (unsigned long).
Exemplo: 32767ul

10. Conversão de dados

São funções utilizadas para fazer a conversão de tipos de dados.

10.1. char()

Descrição
Converte um valor para o tipo de dado char.

Sintaxe
char(x)

Parâmetros
x: um valor de qualquer tipo

Retorno
char

10.2. byte()

Descrição
Converte um valor para o tipo de dado byte.

Sintaxe
byte(x).

Parâmetros
x: um valor de qualquer tipo.

Retorno
Byte.

10.3. int()

Descrição
Converte um valor para o tipo de dado int.
Sintaxe
int(x).

Parâmetros
x: um valor de qualquer tipo.

Retorno
int

11. Estruturas de controle

11.1. if (condicional) e ==, !=, <, > (operadores de comparação)

if, que é usado juntamente com um operador de comparação, verifica quando uma condição
é satisfeita, como por exemplo um input acima de um determinado valor. O formato para
uma verificação if é:

if (algumaVariavel > 50)


{
// faça alguma coisa
}

O programa checa se algumaVariavel (colocar acentos em nomes de variáveis não é uma


boa idéia) é maior que 50. Se for, o programa realiza uma ação específica. Colocado de
outra maneira, se a sentença que está dentro dos parêntesis é verdadeira o código que está
dentro das chaves roda; caso contrário o programa salta este bloco de código.
As chaves podem ser omitidas após uma sentença if se só houver uma única linha de código
(definida pelo ponto e vírgula) que será executado de modo condicional:

if (x > 120) digitalWrite(LEDpin, HIGH);

if (x > 120)
digitalWrite(LEDpin, HIGH);

if (x > 120) {digitalWrite(LEDpin, HIGH);} // todos são corretos

A sentença que está sendo verificada necessita o uso de pelo menos um dos operadores:

11.2. Operadores de comparação:

x == y (x é igual a y)
x != y (x é não igual a y)
x < y (x é menor que y)
x > y (x é maior que y)
x <= y (x é menor ou igual a y)
x >= y (x é maior ou igual a y)
Cuidado:
Tenha precaução com o uso acidental de apenas um sinal de igual (e.g. if (x = 10) ). O sinal
de igual simples é um operador de atribuição e coloca o valor 10 na variável x. Ao contrário
o sinal de igual duplo (e.g. if (x == 10) ), que é um operador de comparação, verifica se x é
igual a 10 ou não. A última sentença só é verdadeira se x for igual a 10, mas a anterior
sempre será verdadeira.
Isto ocorre por que a linguagem C (na qual o Arduino é baseado) atribui um valor à
sentença (x=10) do seguinte modo: 10 é colocado na variável x (lembre o sinal de igual
simples é um operador de atribuição), então x agora contém 10. Então o condicional 'if'
atribui um valor a 10, que será sempre verdadeiro (TRUE), desde que números diferentes
de zero são sempre equiparados à verdadeiro. Consequentemente, if (x = 10) será sempre
verdadeiro, que não é o que pretendemos quando usamos um 'if'. Adicionalmente o valor 10
será guardado na variável x que também não é o que pretendemos.
if também pode ser usado como parte de uma estrutura de controle ramificada através da
construção if..else.

11.3. if / else

if/else permite um controle maior sobre o fluxo de código do que a sentença if básica,
tornando possível que múltiplos testes sejam agrupados. Por exemplo, uma entrada
analógica poderia ser verificada e uma ação específica seria tomada se o valor de input
fosse menor que 500 e outra ação seria tomada se a entrada fosse 500 ou mais. O código
seria assim:

if (pinFiveInput < 500)


{
// ação A
}
else
{
// ação B
}

else pode preceder outro teste if , e assim múltiplos testes, mutuamente exclusivos, podem
ser realizados ao mesmo tempo.
Cada teste precede o próximo até que um teste com valor verdadeiro é encontrado. Quando
um teste com valor verdadeiro é encontrado o seu bloco de código associado é executado e
então o programa salta para a sequência após todo o bloco if/else. Se a nenhum teste é
atribuido o valor verdadeiro o bloco que estiver no else sozinho é executado, se houver
algum.
Note que um bloco else if pode ser usado com ou sem um bloco else final. Um número
ilimitado destes ramos else if é permitido.

if (pinFiveInput < 500)


{
// faça a coisa A
}
else if (pinFiveInput >= 1000)
{
// faça a coisa B
}
else
{
// faça a coisa C
}

Outro modo de fazer testes de ramificações mutuamente exclusivas é através da sentença


switch case.

11.4. sentença switch / case

Do mesmo modo que as sentenças if, as switch / case controlam o fluxo dos programas.
Switch/case permite ao programador construir uma lista de "casos" dentro de um bloco
delimitado por chaves. O programa checa cada caso com a variável de teste e executa o
código se encontrar um valor idêntico.
Switch / case é um pouco mais flexível que uma estrutura if/else de modo que o
programador pode determinar se a estrutura switch deve continuar checando por valores
idênticos na lista dos "casos" após encontrar um valor idêntico. Se a sentença break não é
encontrada após a execução do bloco de código selecionado por um dos "casos", então o
programa vai continuar a checar por mais valores idênticos entre os "casos" restantes. Se
uma sentença break é encontrada o código sai da estrutura do mesmo modo que em uma
construção if/else if.

Parâmetros

var - a variável para a qual você busca valores idênticos


default - se nenhuma outra condição for satisfeita o código que está no default é executado
break - sem o break a sentença switch vai continuar checando as outras sentenças case para
qualquer outro possível valor idêntico. Se algum for encontrado será executado do mesmo
modo, o que pode não ser o que você deseja. Break indica ao switch para parar de procurar
por outros valores idênticos e sai da sentença switch.

Exemplo

switch (var) {
case 1:
//faça alguma coisa quando var == 1
break;
// break is optional
case 2:
//faça alguma coisa quando == 2
break;
default:
// se nenhum valor for idêntico, faça o default
// default é opcional
}

11.5. while

Descrição

while fará com que o bloco de código entre chaves se repita continua e indefinidamente até
que a expressão entre parentesis() se torne falsa. Algo tem que provocar uma mudança no
valor da variável que está sendo verificada ou o código vai sempre ficar dando voltas
dentro do while. Isto poderia ser o incremento de uma variável ou uma condição externa
como o teste de um sensor.

Syntax

while(expressão){
// código
}

Parâmetros
expressão - uma sentença booleana em C que possa ser verificada como verdadeira ou
falsa.

Exemplo
var = 0;
while(var < 200){
// algum código que se repete 200 vezes
var++;
}

11.6. do - while

O do funciona da mesma maneira que o loop while, com a exceção de que a condição é
testada no final do bloco de código. Enquanto no while, se a condição for falsa, o bloco de
código não será executado, no do ele sempre será executado pelo menos uma vez.

Exemplo

do
{
// bloco de código
} while (condição);
Exemplo
do
{
delay(50); // espera para que os sensores se estabilizem
x = readSensors(); // verifica o sensor

} while (x < 100);

11.7. break

break é usado para sair de um bloco do, for, ou while, se sobrepondo à condição normal de
verificação. Também é usado para sair de uma sentença switch.

Examplo

for (x = 0; x < 255; x ++)


{
digitalWrite(PWMpin, x);
sens = analogRead(sensorPin);
if (sens > threshold){ // checar a detecção por um sensor
x = 0;
break;
}
delay(50);
}

11.8. continue

continue é usado para saltar porções de código em blocos do, for, ou while. Ele força com
que o código avance até o teste da condição saltando todos os demais.

Exemplo

for (x = 0; x < 255; x ++)


{
if (x > 40 && x < 120){ // criar saltos de execução
continue;
}

digitalWrite(PWMpin, x);
delay(50);
}

11.9. return

Finaliza uma função e retorna um valor, se necessário.


Sintaxe:

return;
return valor; // ambas formas são válidas.

Parâmetros
valor: alguma variável ou constante

Exemplos:
Uma função para comparar o valor de um sensor com um limite.

int checkSensor(){
if (analogRead (0) > 400) {
return 1;
else{
return 0;
}
}

A palavra-chave return é útil para testar uma seção de código sem ter que transformar em
"comentário" um grande e possivelmente defeituoso bloco de código.

void loop(){

// aqui, uma brilhante idéia de programação

return;

// restante do bloco de código não funcional


// este código nunca será executado
}

11.10. goto

Transfere o fluxo do programa para um outro ponto etiquetado.

Sintaxe
label:
goto etiqueta; // envia o fluxo do programa para etiqueta

Dica
O uso do goto é desencorajado em programação C e inclusive alguns autores afirmam que o
goto nunca é realmente necessário, mas usado com cautela pode simplificar alguns
programas. A razão pela qual muitos programadores desaprovam seu uso é que com o uso
indiscriminado é fácil de se criar um programa com um fluxo indefinido e muito difícil de
ser depurado.
No entanto, há casos em que o goto pode ser útil e simplificar o código. Uma destas
situações é provocar uma saída de um grupo de loops aglutinados ou de blocos lógicos if
com uma determinada condição.

Exemplo

for(byte r = 0; r < 255; r++){


for(byte g = 255; g > -1; g--){
for(byte b = 0; b < 255; b++){
if (analogRead(0) > 250){ goto bailout;}
// more statements ...
}
}
}
bailout:

12. Funções

Este item apresenta algumas funções que fazem parte da linguagem Arduino.

12.1. Entrada e saída digital

12.1.1. pinMode()

Descrição
Configura o pino especificado para que se comporte ou como uma entrada (input) ou uma
saída (output).

Sintaxe
pinMode(pin, mode)

Parâmetros
pin: o número do pin o qual você deseja predeterminar.
mode: pode ser INPUT ou OUTPUT.

Retorno
Nenhum.

Exemplo

int ledPin = 13; // LED conectado ao pino digital 13

void setup()
{
pinMode(ledPin, OUTPUT); // predetermina o pino digital como uma saída
}
void loop()
{
digitalWrite(ledPin, HIGH); // acende o LED
delay(1000); // espera um segundo
digitalWrite(ledPin, LOW); // apaga o LED
delay(1000); // espera um segundo
}

Nota
Os pinos de entrada analógica podem ser usados como pinos digitais e devem ser
referenciados com os números de 14 (entrada analógica 0) a 19 (entrada analógica 5).

12.1.2. digitalWrite()

Descrição
Escreve um valor HIGH ou um LOW em um pino digital. Se o pino foi configurado como
uma saída (output) com o pinMode(), sua voltagem será determinada ao valor
correspondente: 5V (ou 3.3V nas placas de 3.3V) para HIGH, 0V (terra) para LOW.
Se o pino está configurado como uma entrada (input) escrever um HIGH levantará o
resistor interno de 20KΩ. Escrever um LOW rebaixará o resistor.

Sintaxe
digitalWrite(pin, valor)

Parâmetros
pin: o número do pin
valor: HIGH ou LOW

Retorno
Nenhum

Exemplo

int ledPin = 13; // LED conectado ao pino digital 13

void setup()
{
pinMode(ledPin, OUTPUT); // determia o pino digital como uma saída
}

void loop()
{
digitalWrite(ledPin, HIGH); // acende o LED
delay(1000); // espera um segundo
digitalWrite(ledPin, LOW); // apaga um led
delay(1000); // espera um segundo
}
Nota
Os pinos de entrada analógica podem ser usados como pinos digitais e devem ser
referenciados com os números de 14 (entrada analógica 0) a 19 (entrada analógica 5).

12.1.3. digitalRead()

Descrição
Lê o valor de um pino digital especificado, HIGH ou LOW.

Sintaxe
digitalRead(pin)

Parâmetros
pin: o número do pin digital que você quer ler (int)

Retorno
HIGH ou LOW

Exemplo
Transfere para o pino 13 o valor lido no pino 7 que é uma entrada.

int ledPin = 13; // LED conectado ao pino digital 13


int inPin = 7; // botão conectado ao pino digital 7
int val = 0; // variável para armazenar o valor lido

void setup()
{
pinMode(ledPin, OUTPUT); // pré-determina o pino digital 13 como uma saída
pinMode(inPin, INPUT); // pré-determina o pino dgital 7 como uma entrada
}

void loop()
{
val = digitalRead(inPin); // lê o pino de entrada
digitalWrite(ledPin, val); // acende ou apaga o LED de acordo com o pino de entrada
}

Nota
Se o pino não estiver conectado a nada digitalRead() pode retornar tanto HIGH como LOW
(e isso pode variar aleatoriamente).
Os pinos de entrada analógica podem ser usados como pinos digitais e devem ser
referenciados com os números de 14 (entrada analógica 0) a 19 (entrada analógica 5).
12.2. Entrada e saída analógica

12.2.1. analogRead()

Descrição
Lê o valor de um pino analógico especificado. A placa Arduino contém um conversor
analógico-digital de 10 bits com 6 canais (8 canais no Mini e no Nano). Com isto ele pode
mapear voltagens de entrada entre 0 e 5 volts para valores inteiros entre 0 e 1023. Isto
permite uma resolução entre leituras de 5 volts / 1024 unidades ou 0,0049 volts (4.9 mV)
por unidade.
São necessários aproximadamente 100 μs (0.0001 s) para ler uma entrada analógica,
portanto a velocidade máxima de leitura é de aproximadamente 10.000 vezes por segundo.

Sintaxe
analogRead(pin)

Parâmetros
pin: o número do pino analógico que se deseja ler (0 a 5 na maioria das placas, 0 ta 7 no
Mini e no Nano)

Retorno
int (0 a 1023)

Nota
Se o pino analógico não estiver conectado a nada o valor de retorno do analogRead() vai
variar de acordo com uma grande quantidade de fatores (e.g. os valores de outras entradas
analógicas, a distância de sua mão à placa, etc.). Na prática é um valor aleatório.

Exemplo

int analogPin = 3; // perna do meio de um potenciómetro conectada ao pino analógico 3


// pernas externas conectadas ao terra e ao +5V
int val = 0; // variável para armazenar o valor lido
void setup()
{
Serial.begin(9600); // inicial a comunicação serial
}

void loop()
{
val = analogRead(analogPin); // lê o pino de entrada
Serial.println(val); // informa o valor lido
}
12.2.2. analogWrite()

Descrição
Escreve um valor analógico (onda PWM) em um pino. Pode ser usado para acender um
LED variando o brilho ou girar um motor a velocidade variável. Depois de realizar um
analogWrite(), o pino vai gerar uma onda quadrada estável com o ciclo de rendimento
especificado até que o próximo analogWrite() seja realizado (ou que seja realizado um
digitalRead() ou digitalWrite() no mesmo pino). A freqüência do sinal PWM é de
aproximadamente 490Hz.
Nas novas placas Arduino (incluindo o Mini e o BT) com o chip ATmega168 esta função é
eficiente nos pinos 3,5,6,9,10 e 11. Placas Arduino mais antigas com um ATmega8
suportam o analogWrite() apenas nos pinos 9,10 e 11.

Sintaxe
analogWrite(pin, valor)

Parâmetros
pin: o pino no qual se deseja escrever
valor: o rendimento do ciclo: entre 0 (sempre desligado) e 255 (sempre ligado).

Retorno
Nenhum

Notas e problemas conhecidos


Não é necessário realizar um pinMode() para pré-determinar o comportamento do pino
como saída antes de realizar um analogWrite().
As saídas PWM geradas pelos pinos 5 e 6 terão rendimento de ciclo acima do esperado.
Isto se deve às interações com as funções millis() e delay(), que compartilham o mesmo
temporizador interno usado para gerar as saídas PWM.

Exemplo
Torna o brilho de um LED proporcional ao valor lido em um potenciômetro.

int ledPin = 9; // LED conectado ao pino digital 9


int analogPin = 3; // potentiómetro conectado ao pino analógico 3
int val = 0; // variável para armazenar o valor lido

void setup()
{
pinMode(ledPin, OUTPUT); // pré-determina o pino como saída
}
void loop()
{
val = analogRead(analogPin); // lê o pino de entrada
analogWrite(ledPin, val / 4); // os valores do analogRead variam de 0 a 1023, os valores
//do analogWrite variam de 0 a 255.
}

12.3. Funções de tempo

12.3.1. millis()

Descrição
Retorna o número de milisegundos desde que a placa Arduino começou a rodar o programa.
Este número extrapolará (voltará ao zero) depois de aproximadamente 50 dias.

Parâmetros
Nenhum

Retorno
O número de milisegundos desde que o programa começou a rodar como um tipo longo não
assinalado.

Exemplo
unsigned long time;

void setup(){
Serial.begin(9600);
}
void loop(){
Serial.print("Time: ");
time = millis();
//imprime o tempo desde que o programa começou
Serial.println(time);
// espera um segundo para não ficar enviando quantidades absurdas de dados
delay(1000);
}

Dica:
Verifique se o retorno para o millis é um unsigned. Erros podem ocorrer se um programador
tentar realizar cálculos com outros tipos de dados, como inteiros.

12.3.2. micros()

Descrição
Retorna o número de microsegundos desde que a placa Arduino começou a rodar o
programa. Este número extrapolará (voltará ao zero) depois de aproximadamente 70
minutos. Nas placas Arduino de 16 MHz (e.g. Duemilanove e Nano), esta função tem uma
resolução de 4 microsegundos (o valor de retorno será sempre um múltiplo de 4) Nas placas
Arduino de 8MHz (e.g. LilyPad), esta função tem uma resolução de 8 microsegundos.

Parâmetros
Nenhum

Retorno
O número de microsegundos desde que o programa começou a rodar como um tipo
unsigned long.

Exemplo

unsigned long time;


void setup(){ Serial.begin(9600);}

void loop(){
Serial.print("Time: ");
time = micros(); //imprime o tempo desde que o programa começou a rodar
Serial.println(time);
//espera um segundo para não ficar enviando quantidades absurdas de dados
delay(1000);
}

12.3.3. delay(ms)

Descrição
Suspende a execução do programa pelo tempo (em milisegundos) especificado como
parâmetro.

Parâmetros
ms (unsigned long): o número de milisegundos em que o programa ficará com a execução
em suspenso.

Retorno
Nenhum

Exemplo
int ledPin = 13; // LED conectado ao pino digital 13

void setup()
{
pinMode(ledPin, OUTPUT); // marca o pino digital como saída
}

void loop()
{
digitalWrite(ledPin, HIGH); // acende o LED
delay(1000); // espera por um segundo
digitalWrite(ledPin, LOW); // apaga o LED
delay(1000); // espera por um segundo
}

Cuidado
Embora seja fácil criar um LED piscando com a função delay(), e muitos programas usam
intervalos curtos para tarefas como a de filtrar ruídos, o uso do delay() em um programa
tem aspectos negativos importantes. Nenhuma leitura de sensores, cálculo matemático, ou
manipulação de pinos pode seguir durante a execução desta função, portanto muitas outras
funções ficam em espera. Para controles de tempo alternativos veja a função millis() e e seu
programa de exemplo. Programadores com mais conhecimento normalmente evitam o uso
de delay() para cronometrar eventos mais logos do que 10 milisegundos, a não ser que o
programa seja muito simples.
Algumas coisas de fato continuam acontecendo enquanto a função delay() está controlando
o chip ATmega porque as interrupções não são desabilitadas. A comunicação que aparece
no pino RX continua sendo gravada. os pinos e as leituras de PWM (analogWrite) são
mantidos, e as interrupções continuam funcionando.

12.3.4. delayMicroseconds(μs)

Descrição
Suspende a execução do programa pelo tempo (em microsegundos) especificado como
parâmetro.
Atualmente o maior valor que produzirá uma suspenção precisa é 16383. Isto pode mudar
em distribuições futuras do Arduino. Para suspenções maiores que milhares de
microsegundo você deve utilizar a função delay().

Parâmetros
μs: o número de microsegundos da suspenção.

Retorno
Nenhum

Exemplo
Configura o pino 8 para trabalhar como uma saída. Envia uma cadeia de pulsos com um
período de 100 microsegundos.

int outPin = 8; // digital pino 8

void setup()
{
pinMode(outPin, OUTPUT); // marca o pino digital como saída
}

void loop()
{
digitalWrite(outPin, HIGH); // ativa o pino
delayMicroseconds(50); // suspenção de 50 microsegundos
digitalWrite(outPin, LOW); // desativa o pino
delayMicroseconds(50); // suspenção de 50 microsegundos
}

Cuidados e problemas conhecidos


Esta função funciona com bastante precisão na faixa dos 3 microsegundos e acima. Não
podemos nos assegurar que funcione com precisão para tempos de suspenção menores.
Para assegurar suspenções mais precisas esta função desabilita as interrupções durante sua
operação. Isto significa que algumas coisas (como o recebimento de informações seriais, ou
que a atualização do valor de retorno da função mills() ) não funcionarão. Desse modo,
você deve usar esta função apenas para suspenções curtas, e usar delay() para as mais
longas. delayMicroseconds(0) gerará uma suspenção muito maior do que a esperada (~1020
μs) bem como se o parâmetro for um número negativo.

12.4. Funções matemáticas

12.4.1. min(x, y)

Descrição
Calcula o mínimo entre dois números.

Parâmetros
x: o primeiro número, de qualquer tipo de dado
y: o segundo número, de qualquer tipo de dado

Retorno
O menor dos dois números.

Exemplos

sensVal = min(sensVal, 100); // assinala à variável sensVal o mínimo entre seu prório valor
e 100
// assegurando que seu valor nunca seja menor que 100

Nota
Talvez, de modo não-intuitivo, max() é frequentemente utilizado para restringir o valor
mais baixo de uma variável, enquanto min() é utilizado para restringir o valor mais alto.

Cuidado:
Devido ao modo como a função min() foi implementada você deve evitar utilizar outras
funções dentro dos parênteses, isto pode levar a resultados incorretos
min(a++, 100); // evite isso

a++;
min(a, 100); // usse isso, mantenha outros cálculos fora da função

12.4.2. max(x, y)

Descrição
Calcula o máximo entre dois números.

Parâmetros
x: o primeiro número, de qualquer tipo de dado
y: o segundo número, de qualquer tipo de dado

Retorno
O maior dos dois números

Exemplo

sensVal = max(senVal, 20); // atribui à variável sensVal o máximo entre seu próprio valor e
20 // assegurando que seu valor seja pelo menos 20

Nota
Talvez, de modo não-intuitivo, max() é frequentemente utilizado para restringir o valor
mais baixo de uma variável, enquanto min() é utilizado para restringir o valor mais alto.

Cuidado
Devido ao modo como a função max() foi implementada você deve evitar utilizar outras
funções dentro dos parênteses, isto pode levar a resultados incorretos
max(a--, 0); // evite isso

a--; // use isso, mantenha outros cálculos fora da função


max(a, 0);

12.4.3. abs(x)

Descrição
Calcula o valor absoluto de um número.

Parâmetros
x: o número

Retorno
x: se x for maior ou igual a 0
-x: se x for menor que 0.
Cuidado
Devido ao modo como a função abs() foi implementada você deve evitar utilizar outras
funções dentro dos parênteses, isto pode levar a resultados incorretos.

abs(a++); // evite isso

a++; // use isso, mantenha outros cálculos fora da função


abs(a);

12.4.4. constrain(x, a, b)

Descrição
Restringe um número dentro de uma faixa.

Parâmetros
x: o número a restringir, todos os tipos de dados
a: o extremo inferior da faixa, todos os tipos de dados
b: o extremo superior da faixa, todos os tipos de dados

Retorno
x: se x estiver entre a e b
a: se x for menor que a
b: se x for mairo que b

Exemplo
sensVal = constrain(sensVal, 10, 150);
// limita o valor da variável sensVal a valores entre 10 e 150

12.4.5. map(value, fromLow, fromHigh, toLow, toHigh)

Descrição
Re-mapeia um número de uma faixa de valores para outra. Isto é, um valor de fromLow é
mapeado para toLow, um valor fromHigh para toHigh, e valores intermediários da primeira
faixa para a segunda faixa, mantendo-se a proporção entre eles.
Não restringe valores dentro da faixa, porque valores que extrapolem podem ser úteis e
intencionais. A função constrain() pode ser utilizada tanto antes como depois desta função
se limites para as faixas forem necessários.
Verifique que os limites inferiores de uma faixa podem ser maiores ou menores que os
limites superiores. Desse modo a função map() pode ser utilizada para colocar em ordem
reversa uma faixa de valores, como por exemplo:
y = map(x, 1, 50, 50, 1);
A função também pode utilizar números negativos como neste exemplo:
y = map(x, 1, 50, 50, -100);

A função map() utiliza números inteiros e não gera frações. Quando o resultado for
fracionário ele será truncado e não arredondado.
Parâmetros
value: o número a ser mapeado
fromLow: limite inferior da faixa atual de value
fromHigh: limite superior da faixa atual de value
toLow: limite inferior da faixa para a qual se quer mapear
toHigh: limite superior da faixa para a qual se quer mapear

Retorno
O valor mapeado.

Exemplo
/* Mapear uma entrada analógica de 10 bits para uma saída analógica de 8 bits (0 a 255) */

void setup() {}

void loop()
{
int val = analogRead(0);
val = map(val, 0, 1023, 0, 255);
analogWrite(9, val);
}

Apêndice
Para aqueles com inclinação matemática aqui está a função completa:
long map(long x, long in_min, long in_max, long out_min, long out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

12.4.6. pow(base, expoente)

Descrição
Calcula o valor de um número elevado a uma potência. Pow() pode ser utilizado com uma
potência fracionária. É útil para gerar mapeamentos exponenciais de valores ou curvas.

Parâmetros
base: o número(float)
expoente: a potência à qual a base é elevada (float)

Retorno
O resultado da exponeciação (double)

12.4.7. sq(x)

Descrição
Calcula o quadrado de um número. O número multiplicado por ele mesmo.
Parâmetros
x: o número, qualquer tipo de dado

Retorno
o quadrado do número.

12.4.8. sqrt(x)

Descrição

Calcula a raíz quadrada de um número.

Parâmetros
x: o número, qualquer tipo de dado

Retorno
double, a raíz quadrada do número.

12.5. Funções trigonométricas

12.5.1. sin(rad)

Descrição
Calcula o seno de um ângulo (em redianos). O resultado será entre -1 e 1.

Parâmetros
rad: o ângulo em radianos (float).

Retorno
o seno do ângulo (double).

Nota
Serial.print() e Serial.println() atualmente não suportam floats.

12.5.2. cos(rad)

Descrição
Calcula o cosseno de um ângulo (em redianos). O resultado será entre -1 e 1.

Parâmetros
rad: o ângulo em radianos (float).

Retorno
O cosseno do ângulo (double).
12.5.3. tan(rad)

Descrição
Calcula a tangente de um ângulo (em redianos).

Parâmetros
rad: o ângulo em radianos (float).

Retorno
a tangente do ângulo (double).

Nota
Serial.print() e Serial.println() atualmente não suportam floats.

12.6. Comunicação serial

Usado para comunicação entre a placa Arduino e um computador ou outros dispositivos.


Esta comunicação ocorre através dos conectores serial ou USB da placa Arduino e nos
pinos digitais 0 (RX) e 1 (TX). Assim, se você utilizar estas funções não poderá utilizar os
pinos 0 e 1 para entrada e saída digital.

12.6.1. Serial.begin(int velocidade)

Descrição
Ajusta o taxa de transferência em bits por segundo (baud) para transmissão de dados pelo
padrão serial. Para comunicação com um computador use uma destas taxas: 300, 1200,
2400, 4800, 9600, 14400, 19200, 28800, 57600, 115200. Você pode, entretanto, especificar
outras velocidades por exemplo para comunicação através dos pinos 0 e 1 com um
componente que requer uma taxa específica.

Parametros
int velocidade, em bits por segundo (baud)

Retorno
Nenhum

Exemplo:

void setup() {
Serial.begin(9600); // abre a porta serial e ajusta a taxa de transferência de dados
para //9600 bps
}

void loop() {}
Exemplo para o Arduino Mega:
// Arduino Mega usando as quatro portas seriais simultaneamente
// (Serial, Serial1, Serial2, Serial3),
// com diferentes taxas de transferência:

void setup(){
Serial.begin(9600);
Serial1.begin(38400);
Serial2.begin(19200);
Serial3.begin(4800);

Serial.println("Hello Computer");
Serial1.println("Hello Serial 1");
Serial2.println("Hello Serial 2");
Serial3.println("Hello Serial 3");
}

void loop() {}

12.6.2. int Serial.available()

Descrição
Obtem o número de bytes (caracteres) disponíveis para leitura através da porta serial.

Parâmetros
Nenhum

Retorno
O número de bytes disponíveis para leitura no buffer serial. O buffer serial pode armazenar
até 128 bytes.

Exemplo
int incomingByte = 0;// para dados seriais que estão entrando

void setup() {
Serial.begin(9600); // abre a porta serial e ajusta a taxa de transferência para 9600
bps
}

void loop() {

// envia dados apenas quando dados forem também recebidos:


if (Serial.available() > 0) {
// lê o byte que está entrando:
incomingByte = Serial.read();

// diga o que você recebeu:


Serial.print("Eu recebi : ");
Serial.println(incomingByte, DEC);
}
}

Exemplo para o Arduino Mega:


void setup() {
Serial.begin(9600);
Serial1.begin(9600);

void loop() {
// lê na porta 0 e envia para a porta 1:
if (Serial.available()) {
int inByte = Serial.read();
Serial1.print(inByte, BYTE);

}
// lê na porta 1 e envia para a porta 0:
if (Serial1.available()) {
int inByte = Serial1.read();
Serial.print(inByte, BYTE);
}
}

12.6.3. int Serial.read()

Descrição
Lê dados que estejam entrando pela porta serial.

Parâmetros
Nenhum

Retorno
o primeiro byte disponível na entrada da porta serial (ou -1 se não hover dados disponíveis)
int

Exemplo
int incomingByte = 0;// para entrada serial

void setup() {
Serial.begin(9600); // abre a porta serial e ajusta a velocidade para 9600 bps
}

void loop() {
// envia dados apenas quando recebe dados:
if (Serial.available() > 0) {
// lê o primeiro byte disponível:
incomingByte = Serial.read();

// imprime na tela o byte recebido:


Serial.print("Eu recebi: ");
Serial.println(incomingByte, DEC);
}
}

12.6.4. Serial.flush()

Descrição
Esvazia o buffer de entrada da porta serial. Isto é, qualquer chamada à Serial.read() ou
Serial.available() somente retornarão dados recebidos após a última chamada à
Serial.flush().

Parâmetros
nenhum

Retorno
nenhum

12.6.5. Serial.print(data)

Descrição
Envia dados pela porta serial.

Parâmetro
data: todos os tipos inteiros incluindo caracteres

Sintaxe
Este comando pode assumir diversas formas:

Serial.print(b) sem nenhum formato especificado, imprime b como um número decimal


em uma string ASCII.

Exemplo:
int b = 79;
Serial.print(b);
imprime a string ASCII "79".
Serial.print(b, DEC) imprime b como um número decimal em uma string ASCII.

Exemplo:
int b = 79;
Serial.print(b, DEC);
imprime a string ASCII "79".

Serial.print(b, HEX) imprime b como um número hexadecimal em uma string ASCII.

Exemplo:
int b = 79;
Serial.print(b, HEX);
imprime a string string "4F".

Serial.print(b, OCT) imprime b como um número octal em uma string ASCII.

Exemplo:
int b = 79;
Serial.print(b, OCT);
imprime a string "117".

Serial.print(b, BIN) imprime b como um número binário em uma string ASCII.

Exemplo:
int b = 79;
Serial.print(b, BIN);
imprime a string "1001111".

Serial.print(b, BYTE) imprime b como um byte único.

Exemplo
int b = 79;
Serial.print(b, BYTE);
imprime a string "O" que é o caractér ASCII representado pelo valor 79.

Serial.print(str) se str for uma string ou um array de char imprime uma string ASCII.

Exemplo:
Serial.print("Hello World!");
imprime a string "Hello World!".

Parâmetros
b: o byte a imprimir, ou
str: a string a imprimir

Retorno
Nenhum
Exemplo:
/*
Usa um bloco FOR para dados e imprime um número em vários formatos.
*/
int x = 0; // variável

void setup() {
Serial.begin(9600); // abre a porta serial e ajusta a velocidade para 9600 bps
}

void loop() {
// imprime etiquetas
Serial.print("SEM FORMATO"); // imprime uma etiqueta
Serial.print("\t"); // imprime um tab

Serial.print("DEC");
Serial.print("\t");

Serial.print("HEX");
Serial.print("\t");

Serial.print("OCT");
Serial.print("\t");

Serial.print("BIN");
Serial.print("\t");

Serial.println("BYTE");

for(x=0; x< 64; x++){ // apenas parte da tabela ASCII

// imprime em vários formatos


Serial.print(x); // imprime um ASCII decimal - o mesmo que "DEC"
Serial.print("\t"); // imprime um tab

Serial.print(x, DEC); // imprime um ASCII decimal


Serial.print("\t"); // imprime um tab

Serial.print(x, HEX); // imprime um ASCII hexadecimal


Serial.print("\t"); // imprime um tab

Serial.print(x, OCT); // imprime um ASCII octal


Serial.print("\t"); // imprime um tab

Serial.print(x, BIN); // imprime um ASCII binario


Serial.print("\t"); // imprime um tab
Serial.println(x, BYTE); // imprime como um byte único e adciona um "cariage return"

// com o "println"
delay(200); // espera 200 millisegundos
}
Serial.println(""); // imprime outro carriage return
}

Dicas de programação e problemas conhecidos


Serial.print() não funciona com floats, portanto você precisa fazer uma conversão para um
tipo inteiro, perdendo a informação dos valores fracionários. Em algumas situações é útil
multiplicar um float por uma potência de 10 para preservar (ao menos em parte) a
informação fracionária.
Seja cuidadoso ao fazer cálculos dentro dos parêntesis e.g.
Serial.print(x-2, DEC);
Os tipos de dados unsigned char, e byte irão gerar resultados incorretos e atuar como se
fossem do tipo de dado assinalado.
A função Serial.print envia os dados para um buffer. Ele esperará que um caractere seja
enviado antes de seguir para o próximo. Entretanto a função envia o retorno antes de enviar
o último caractere.

12.6.6. println()

Descrição
Envia dados pela porta serial, como a função print(), acrescentado um caractere retorno de
carro (ASCII 13, ou '\ r ') e um caractere nova linha (ASCII 10, ou '\ n '). Este comando tem
as mesmas formas como Serial.print ().

13. Biblioteca (Library) LiquidCrystal

Esta biblioteca permite o Arduino controlar um Display de Cristal Líquido (LCDs) baseado no
controlador Hitachi HD44780 (ou compatível), que é encontrado na maioria dos LCDs atuais.
A biblioteca funciona no modo de 4 ou 8 bits (ou seja, usando 4 ou 8 linhas de dados, além de
RS, Enable (EN) e, opcionalmente, as linhas de controle rw).
Os LCDs têm uma interface paralela, o que significa que o microcontrolador tem que
manipular os vários pinos da interface de uma só vez para controlar a exibição. A interface
consiste dos seguintes pinos:

 Pinos de dados: D7-D6-D5-D4-D3-D2-D1-D0 (8bits) - os pinos de dados são


usados para enviar as palavras de configurações e os dados (caracteres).
 Pinos de controle: EN (6), RS (4), R/W (5) - o pino EN informa ao display de LCD
quando o dado está pronto para ser lido. O pino RS é usado para diferenciar se a
palavra que foi enviada ao LCD é de configuração ou caractere.
 Pinos de alimentação: Vcc (2) e GND (1).
 Pino de controle de contraste: VO (3) - este pino permite alterar o contraste do
display.
 Pinos de iluminação do fundo - backlight: A (16), K (15) - nem todos os displays
possuem iluminação de fundo.
PINAGEM DE UM LCD 16 x 2 (caracteres x linhas)
Capítulo 3

Aplicações com o Arduino

Exemplo1 : Piscar um LED ligado a uma saída digital

Na maioria das linguagens de programação, a primeira linha de programa que você escreve
diz “Hello World” na tela do computador. Como a placa Arduino não tem uma tela,
substituiremos esta função fazendo piscar um Led ligado a uma saída digital.
Algumas placas já tem um Led acoplado ao pino 13 da mesma. Na maioria das outras
placas (como Mini ou BT) existe um resistor de 1 KB no pino 13, permitindo que você
conecte o Led diretamente a saída digital. Os Led´s tem polaridade, o que significa que ele
só irá acender se você conectar os terminais corretamente. O terminal mais longo
geralmente é o anodo (positivo) e deverá ser conectada ao pino 13. O terminal mais curto
(Catodo) se conecta ao GND, o encapsulamento do Led´s normalmente tem a superfície
plana deste lado. Se o Led não acender, tente inverter os terminais (você não irá danificar o
Led se encaixar os terminais ao contrário por um curto período de tempo).

Circuito
Código

int ledPin = 13; // LED conectado ao pino 13 e denominado de ledPin;

void setup()
{
pinMode(ledPin, OUTPUT); // Configura o pino 13 como saída;
}

void loop()
{
digitalWrite(ledPin, HIGH); // Coloca em nível alto o pino 13;
delay(1000); // Atrasa um Segundo;
digitalWrite(ledPin, LOW); // Coloca em nível baixo o pino 13;
delay(1000); // Atrasa um segundo.
}

Exercício1:

Modifique o Hardware, colocando o LED em série com uma resistência de 200 Ω no pino
12 do Arduino. Altere o software, mude o tempo para 500ms. Compile e rode novamente o
programa.

Exemplo 2: Piscar um LED sem delay


Às vezes você precisa fazer piscar um Led (ou alguma outra função sensitiva de tempo) ao
mesmo tempo em que outro evento ocorre (como observar o teclar de um botão por
exemplo). Isso significa que você não pode usar a função delay, ou você pararia qualquer
outro programa enquanto o Led pisca. Aqui segue um código que mostra como piscar um
Led sem delay. O código mantém a informação da última vez que o Led ligou ou desligou.
Assim, para cada loop ele checa se passou um intervalo de tempo suficiente; se passou
tempo suficiente ele desliga o Led caso estivesse aceso, e vice-versa.

Código

int ledPin = 13; // LED conectado ao pino digital 13;


int value = LOW; // Estado anterior do LED;
long previousMillis = 0; // Armazena a última vez que o LED foi atualizado;
long interval = 1000; // Intervalo no qual o LED piscará;

void setup()
{
pinMode(ledPin, OUTPUT); // configura o pino digital como saída
}
void loop()
{
if (millis() - previousMillis > interval) {
previousMillis = millis();
if (value == LOW)
value = HIGH;
else
value = LOW;

digitalWrite(ledPin, value);
}
}

Exemplo3: Botão e LED

O botão é um componente que conecta dois pontos do circuito quando está pressionado.
Neste exemplo quando o botão está pressionado o Led se acende.
Conectamos 3 fios à placa Arduino. O primeiro conecta uma das saídas do botão através do
resistor pull-up (aqui 10 KOhms) até a fonte de 5 volts. O segundo cabo conecta a
correspondente saída do botão ao terra. O terceiro conecta ao pino 2 digital, que faz a
leitura do estado do botão.
Quando o botão está aberto (não pressionado) não há conexão entre as duas saídas do
botão, então o pino está conectado aos 5 volts (através do resistor pull-up) e podemos ler
um valor HIGH. Quando o botão está fechado (pressionado) faz a conexão entre as saídas
do botão e fazendo a conexão terra, e com isso podemos ler um valor LOW. Você também
poderá fazer a instalação no sentido oposto com um resistor pull-down mantendo o input
LOW e mudando para HIGH com o botão pressionado. Se fizer assim, o comportamento do
projeto será invertido, com o Led normalmente aceso e apagando quando o botão for
pressionado.
Se você desconectar o pino digital e/s de todo o resto, o Led poderá piscar com erro. Isso
acontece porque a entrada está flutuante, isso é, ele vai mais ou menos aleatoriamente
informar HIGH ou LOW. Por isso é necessário o resistor pull-up ou pull-down neste
circuito.
Circuito

Código
int ledPin = 13; // Determina o pino digital para o LED;
int inPin = 2; // Determina o pino digital para a chave pushbutton
int val = 0; // Variável para armazenar o estado da chave pushbutton;

void setup() {
pinMode(ledPin, OUTPUT); // declara LED como saída;
pinMode(inPin, INPUT); // declara o botão pushbutton como entrada;
}

void loop(){
val = digitalRead(inPin); // Lê o botão de entrada;
if (val == HIGH) { // Verifica se a entrada é alta (HIGH), botão liberado;
digitalWrite(ledPin, LOW); // Desliga o LED;
} else {
digitalWrite(ledPin, HIGH); // Liga o LED;
}
}
Exemplo 4: Filtrar o ruído (Retirar a trepidação da chave)

Este exemplo mostra o uso de um botão como interruptor: cada vez que você pressiona o
botão, o LED (ou outro componente) liga (se estiver desligado) ou desliga (se estiver
ligado). Ele também filtra o sinal da entrada (tira a trepidação da chave), sem a qual
pressionando uma vez o botão, apareceria no código múltiplos acessos. Use a função
millis() para obter a informação do momento em que o botão foi pressionado.

Circuito
Um botão entre o pino 7 e o terra e um LED no pino 13.

Code
int inPin = 7; // o numero do pino de entrada
int outPin = 13; // o numero do pino de saida

int state = HIGH; // o estado corrente do pino de saída


int reading; // a leitura corrente do pino de entrada
int previous = LOW; // a leitura previa do pino de entrada

// as seguintes variaveis sao do tipo long por que o tempo é medido em milisegundos e
// rapidamente se tornarão um numero grande demais para uma variavel do tipo int

long time = 0; // o último tempo em que o pino de entrada teve o valor alterado
long debounce = 200; // o tempo de filtragem, aumentar se a saída piscar

void setup()
{
pinMode(inPin, INPUT);
pinMode(outPin, OUTPUT);
}

void loop()
{
reading = digitalRead(inPin);

// se apenas pressionarmos o botao (i.e. modificarmos a entrada de LOW para HIGH),


// e se esperamos tempo suficiente desde a última pressionada para ignorar qualquer
ruído...

if (reading == HIGH && previous == LOW && millis() - time > debounce) {
// ... inverte a saída
if (state == HIGH)
state = LOW;
else
state = HIGH;

// ... e se lembra quando o botão foi pressionado pela última vez


time = millis();
}

digitalWrite(outPin, state);

previous = reading;
}

Exemplo 5: LEDs sequenciais

Este exemplo usa 6 LEDs conectados entre os pinos 2 e 7 da placa usando resistores de 200
Ohm. O código faz os LEDs piscarem em sequência um a um, usando uma construção
for(;;).

Circuíto

Código

int pinArray[] = {2, 3, 4, 5, 6, 7};


int count = 0;
int timer = 100;

void setup(){
// fazendo todas as declarações de uma vez
for (count=0;count<6;count++) {
pinMode(pinArray[count], OUTPUT);
}
}

void loop() {
for (count=0;count<6;count++) {
digitalWrite(pinArray[count], HIGH);
delay(timer);
digitalWrite(pinArray[count], LOW);
delay(timer);
}
for (count=5;count>=0;count--) {
digitalWrite(pinArray[count], HIGH);
delay(timer);
digitalWrite(pinArray[count], LOW);
delay(timer);
}
}

Exemplo 6: Entrada Analógica controlando o período de um LED.

O arduino Duemilanove possui 6 pinos que são configurados como entrada analógica
(Analog In). A conversão é realizada em 10 bits, portanto os valores convertidos nestas
entradas, variam de 0 a 1023 em decimal.
O potenciômetro é um componente eletrônico que fornece resistência variável, da qual
podemos fazer a leitura através da placa Arduino como um valor analógico. Neste exemplo
este valor controla o período em que pisca um LED.
Conectamos o potenciômetro conforme circuito abaixo, no qual a tensão ajustada pelo
divisor de tensão é conectada ao pino 2 da entrada analógica do arduino. O LED do pino 13
é utilizado neste exemplo.
Girando a haste do potenciômetro, vamos mudar a resistência elétrica do mesmo e em
conseqüência a tensão elétrica do divisor de tensão. Este valor de tensão é aplicado ao pino
2 da entrada analógica do Arduino. Quando a haste é girada até o final, teremos 5 volts
aplicado na entrada 2, assim teremos uma leitura equivalente a 1023. Para variações entre 0
e 5V, o valor convertido variará de 0 a 1023.

Circuito
Código

int potPin = 2; // Entrada analogica para o divisor de tensão;


int ledPin = 13; // Saída digital para o LED;
int val = 0; // Variável para armazenar o valor convertido na entrada analógica;

void setup() {
pinMode(ledPin, OUTPUT); // declara o pino 13 (ledPin) como saída
}

void loop() {
val = analogRead(potPin); // Lê a entrada analogical;
digitalWrite(ledPin, HIGH); // Liga o LED;
delay(val); // Atrasa um tempo equivalente a leitura da entrada analógica;
digitalWrite(ledPin, LOW); // Desliga o LED;
delay(val); // Atrasa um tempo equivalente a leitura da entrada analógica
}
Exemplo 7: Controle da intensidade luminosa de um LED utilizando PWM. (saída
analógica)
Demonstra o uso de uma saída analógica (PWM) para controlar a intensidade luminosa de
um LED. A saída PWM 9 está conectada a um LED em série com resistor de 270Ω.

Circuito

Código

int value = 0; // variavel para armazenar o valor atualizado


int ledpin = 9; // LED conectado ao pino digital 9

void setup()
{
// nao ha necessidade de setup
}

void loop()
{
for(value = 0 ; value <= 255; value+=5) // Intensidade luminosa do min. para o Max.
{
analogWrite(ledpin, value); // ajusta o valor do PWM
delay(30); // espera 30 mS para que o efeito seja visível
}
for(value = 255; value >=0; value-=5) // Intensidade luminosa do Max. para o min.
{
analogWrite(ledpin, value);
delay(30);
}
}

Exemplo 8: Regulando
Faz repetidas leituras a partir de uma entrada analógica, calculando a média e informando o
computador. Demonstra o uso de arrays (vetores).

Circuito
Potenciômetro no pino de entrada analógica 0.

Código
// Define the number of samples to keep track of. The higher the number,
// the more the readings will be smoothed, but the slower the output will
// respond to the input. Using a #define rather than a normal variable lets
// use this value to determine the size of the readings array.

#define NUMREADINGS 10
int readings[NUMREADINGS]; // the readings from the analog input
int index = 0; // the index of the current reading
int total = 0; // the running total
int average = 0; // the average

int inputPin = 0;

void setup()
{
Serial.begin(9600); // initialize serial communication with computer
for (int i = 0; i < NUMREADINGS; i++)
readings[i] = 0; // initialize all the readings to 0
}

void loop()
{
total -= readings[index]; // subtract the last reading
readings[index] = analogRead(inputPin); // read from the sensor
total += readings[index]; // add the reading to the total
index = (index + 1); // advance to the next index

if (index >= NUMREADINGS) // if we're at the end of the array...


index = 0; // ...wrap around to the beginning

average = total / NUMREADINGS; // calculate the average


Serial.println(average); // send it to the computer (as ASCII digits)
}
Exemplo 9 : Dimmer controlado pelo processing

Demonstra o envio de dados desde o computador até a placa Arduino, neste caso para
controlar o brilho de um LED. Os dados são enviados em bytes individuais, cada um deles
varia entre 0 e 255. O Arduino lê esta informação e a usa para estabelecer o brilho do LED.
Você também pode enviar dados para o Arduino através de qualquer software que possa
acessar o computador através da porta serial

Circuito
Um LED conectado ao pino 9. Use resistor apropriado se necessário. Para os LED´s mais
comuns você pode trabalhar sem resistor já que a saída da corrente da E/S digital é
limitada.

Código

#define ledPin 9 // the pin that the LED is attached to

void setup()
{
// initialize the serial communication:
Serial.begin(9600);
// initialize the ledPin as an output:
pinMode(ledPin, OUTPUT);
}

void loop() {
byte brightness;

// check if data has been sent from the computer:


if (Serial.available()) {
// read the most recent byte (which will be from 0 to 255):
brightness = Serial.read();
// set the brightness of the LED:
analogWrite(ledPin, brightness);
}
}

Código Processing

Use o projeto abaixo em Processing. Ele enviará dados através da porta serial até o Arduino
para controlar a luminosidade do LED.

import processing.serial.*;
Serial port;

void setup() {
size(256, 150);

println("Available serial ports:");


println(Serial.list());

//port = new Serial(this, Serial.list()[0], 9600);

port = new Serial(this, "COM1", 9600);


}

void draw() {
for (int i = 0; i < 256; i++) {
stroke(i);
line(i, 0, i, 150);
}

port.write(mouseX);
}
Exemplo 10: Comunicação Arduino- Processing

Este exemplo mostra como enviar um byte de dados do Arduino para um computador
pessoal e mostrá-los em um gráfico através do software processing

Hardware Requerido:
Placa do Arduino;
Sensor analógico.

Software Requerido:
Processing.

Circuito
Conecte o potenciômetro como sensor analógico na entrada analógica 0.

Código para o arduino


void setup() {
Serial.begin(9600);
}

void loop() {
Serial.println(analogRead(A0));
delay(10);
}

Código para o Processing

import processing.serial.*;

Serial.myPort;
int xPos = 1;

void setup () {
size(400, 300);
myPort = new Serial(this, ‘COM 4’, 9600);
myPort.bufferUntil('\n');
background(0);
}
void draw () {
}

void serialEvent (Serial myPort) {


String inString = myPort.readStringUntil('\n');
if (inString != null) {
inString = trim(inString);
float inByte = float(inString);
inByte = map(inByte, 0, 1023, 0, height);
stroke(127,34,255);
line(xPos, height, xPos, height - inByte);
if (xPos >= width) {
xPos = 0;
background(0);
}
else {
xPos++;
}
}
}

Exemplo 11: Controlando um LED através do processing


Este exemplo utiliza o Arduino para receber dados do computador. O Arduino irá acender
um LED quando ele receber o caracter 'H ', e desligar o LED quando ele receber o caracter
"L" do software Processing.

Hardware Requerido
Arduino

Software Requerido
Processing

Circuito

Código no Arduino
const int ledPin = 13;
int incomingByte;

void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
}

void loop() {
if (Serial.available() > 0) {
incomingByte = Serial.read();
if (incomingByte == 'H') {
digitalWrite(ledPin, HIGH);
}
if (incomingByte == 'L') {
digitalWrite(ledPin, LOW);
}
}
}

Código no Processing

import processing.serial.*;

float boxX;
float boxY;
int boxSize = 20;
boolean mouseOverBox = false;

Serial port;

void setup() {
size(200, 200);
boxX = width/2.0;
boxY = height/2.0;
rectMode(RADIUS);
println(Serial.list());
port = new Serial(this, ‘COM4’, 9600);

void draw()
{
background(0);
if (mouseX > boxX-boxSize && mouseX < boxX+boxSize &&
mouseY > boxY-boxSize && mouseY < boxY+boxSize) {
mouseOverBox = true;
stroke(255);
fill(153);
port.write('H');
}
else {
stroke(153);
fill(153);
port.write('L');
mouseOverBox = false;
}
rect(boxX, boxY, boxSize, boxSize);
}

Capítulo 5
EXEMPLOS DESENVOLVIDOS EM SALA DE AULA

EXEMPLO 1 - PISCA LED - HARDWARE

EXEMPLO1 – PISCA LED - SOFTWARE


EXEMPLO 2 – SEQUENCIAL DE LEDS - HARDWARE
EXEMPLO 2 - SEQUENCIAL DE LEDS - SOFTWARE
EXEMPLO 2 - SEQUENCIAL DE LEDS – SOFTWARE 2
EXEMPLO 3 - BOTÃO E LED - HARDWARE
EXEMPLO 3 – BOTÃO E LED - SOFTWARE
EXEMPLO 4 – BOTÃO E LED 2 - HARDWARE
EXEMPLO 4 – BOTÃO E LED 2 - SOFTWARE
/* Este programa ilustra o uso de botões para controlar uma
determinada ação */
int BT1 = 8;
int BT2 = 9;
int LED10 = 10;
int LED11 = 11;
int LED12 = 12;
int Leitura_BT1 = 0;
int Leitura_BT2 = 0;
int controle = 0;

void setup(){
pinMode(BT1, INPUT);
pinMode(BT2, INPUT);
pinMode(LED10, OUTPUT);
pinMode(LED11, OUTPUT);
pinMode(LED12, OUTPUT);
}

void loop(){
Leitura_BT1 = digitalRead(BT1);
Leitura_BT2 = digitalRead(BT2);

if(Leitura_BT1 == HIGH){
controle = 1;
}
else{
if(controle == HIGH && Leitura_BT2 == HIGH ){
controle = 0;
}
}

switch(controle){
case 0: {
digitalWrite(LED10, LOW);
digitalWrite(LED11, LOW);
digitalWrite(LED12, LOW);
break;
}
case 1: {
digitalWrite(LED10, HIGH);
digitalWrite(LED11, HIGH);
digitalWrite(LED12, HIGH);
break;
}

}
}

EXEMPLO 5 – MODULAÇÃO PWM - HARDWARE


EXEMPLO 5 – MODULAÇÃO PWM - SOFTWARE