Portal IDEA
ARDUINO
BÁSICO
Módulo 2 – Programação Básica e Entradas Digitais
Aula
1 – Fundamentos da Programação no Arduino
Depois
de conhecer a placa Arduino e aprender a montar os primeiros circuitos, chega o
momento de compreender como transformar uma ideia em um conjunto de instruções
que o microcontrolador seja capaz de executar. Programar significa justamente
isso: criar uma sequência lógica de comandos que orienta o funcionamento do
sistema. No caso do Arduino, a programação é baseada na linguagem C/C++,
adaptada para facilitar o desenvolvimento de projetos eletrônicos e de
automação.
Um
programa de Arduino é chamado de Sketch e possui uma estrutura simples,
composta principalmente pelas funções setup() e loop(). A função setup()
é executada apenas uma vez quando a placa é ligada ou reiniciada. Nela são
feitas as configurações iniciais, como definir quais pinos funcionarão como
entrada ou saída e iniciar recursos como a comunicação serial. Já a função loop()
é executada continuamente enquanto a placa estiver energizada, repetindo todas
as instruções contidas em seu bloco. Essa organização facilita a leitura do
código e ajuda o programador a separar as configurações iniciais das ações que
devem ocorrer continuamente.
Para
que o Arduino possa armazenar e manipular informações, utilizamos as variáveis.
Uma variável pode ser comparada a uma caixa identificada por um nome, onde é
possível guardar um valor que poderá ser utilizado ou alterado durante a
execução do programa. Esse valor pode representar, por exemplo, a temperatura
medida por um sensor, a intensidade da luz ambiente ou o estado de um botão. O
uso correto das variáveis torna os programas mais organizados, flexíveis e
fáceis de modificar.
Cada
variável possui um tipo de dado, que determina qual tipo de informação poderá
ser armazenada. Entre os tipos mais utilizados estão int, destinado aos
números inteiros; float, utilizado para números com casas decimais; char,
empregado para armazenar um único caractere; String, utilizada para
textos; e bool, que trabalha apenas com dois valores possíveis:
verdadeiro (true) ou falso (false). Escolher corretamente o tipo
de dado contribui para um melhor aproveitamento da memória do microcontrolador
e melhora o desempenho do programa.
Além das variáveis, existem as constantes. Diferentemente das variáveis, uma constante possui um valor fixo, que não pode ser alterado durante a execução do programa.
Elas são muito utilizadas para armazenar configurações permanentes,
como o número do pino em que um LED está conectado. Essa prática torna o código
mais organizado e reduz a possibilidade de alterações acidentais em informações
importantes.
Outro
elemento fundamental da programação são os operadores. Os operadores
aritméticos permitem realizar cálculos, como soma, subtração, multiplicação e
divisão. Já os operadores relacionais são utilizados para comparar valores,
verificando, por exemplo, se dois números são iguais ou se um valor é maior que
outro. Os operadores lógicos combinam diferentes condições para que decisões
mais complexas possam ser tomadas durante a execução do programa. Esses
recursos são indispensáveis para desenvolver aplicações capazes de responder às
informações recebidas pelos sensores.
Durante
a escrita dos programas, também é importante utilizar comentários. Eles são
linhas de texto destinadas exclusivamente ao programador e não são executadas
pelo Arduino. Os comentários servem para explicar a finalidade de determinadas
instruções, facilitando futuras alterações e tornando o código mais
compreensível para outras pessoas que venham a trabalhar no mesmo projeto. Em
programas simples essa prática pode parecer dispensável, mas, à medida que os
projetos crescem, ela se torna um importante recurso de organização.
Uma
das boas práticas na programação consiste em utilizar nomes claros e objetivos
para variáveis e funções. Em vez de utilizar identificadores genéricos, como
"x" ou "a", é preferível escolher nomes que indiquem
claramente sua finalidade, como temperatura, botaoLigado ou velocidadeMotor.
Essa organização facilita tanto o desenvolvimento quanto a manutenção do
código, reduzindo erros e tornando a leitura muito mais intuitiva.
Outro
aspecto importante é realizar pequenos testes durante o desenvolvimento. Em vez
de escrever um programa muito extenso antes de verificar seu funcionamento,
recomenda-se implementar e testar cada etapa separadamente. Essa estratégia
facilita a identificação de erros, reduz o tempo gasto com depuração e
proporciona maior segurança durante a criação de novos projetos.
Ao concluir esta aula, o estudante compreenderá os principais fundamentos da programação aplicada ao Arduino, reconhecerá a função das variáveis, constantes, tipos de dados e operadores, entenderá a estrutura básica de um programa e estará preparado para desenvolver códigos cada vez mais organizados, eficientes e fáceis de manter.
Referências
bibliográficas
BANZI,
Massimo. Primeiros Passos com Arduino. São Paulo: Novatec.
MCROBERTS,
Michael. Arduino Básico. São Paulo: Novatec.
MONK,
Simon. Programação com Arduino: Começando com Sketches. Porto Alegre:
Bookman.
BLOG
DA ROBÓTICA. Fundamentos de Programação para Arduino.
OBSAT
– Ministério da Ciência, Tecnologia e Inovação. Funções e Variáveis.
Instituto
Federal Catarinense. Programação Aplicada a Microcontroladores.
Nerd
Toolkit. Introdução a Variáveis e Constantes no Arduino.
Aula
2 – Estruturas de Decisão e Repetição
À
medida que os projetos com Arduino se tornam mais elaborados, surge a
necessidade de fazer com que a placa tome decisões e execute determinadas ações
repetidamente. Imagine, por exemplo, um sistema de irrigação que só deve ligar
quando o solo estiver seco ou um semáforo que alterna automaticamente entre as
luzes verde, amarela e vermelha. Para resolver situações como essas, a
programação utiliza estruturas de decisão e estruturas de repetição, recursos
que tornam os programas mais inteligentes, organizados e eficientes. Esses
conceitos fazem parte da base da lógica de programação e são amplamente
utilizados em projetos de automação e robótica.
As
estruturas de decisão permitem que o Arduino escolha entre diferentes ações de
acordo com uma condição. A mais utilizada é a instrução if, que executa
um bloco de comandos somente quando determinada condição é verdadeira. Por
exemplo, um sensor de luminosidade pode informar ao Arduino que o ambiente está
escuro; nesse caso, o programa poderá acender automaticamente uma lâmpada. Caso
a condição não seja atendida, o programa simplesmente continuará sua execução
normalmente.
Quando
é necessário definir uma ação alternativa, utiliza-se a estrutura if...else.
Ela permite estabelecer dois caminhos possíveis: um para quando a condição for
verdadeira e outro para quando for falsa. Um exemplo simples é o controle de um
ventilador. Se a temperatura ultrapassar um valor definido, o ventilador será
ligado; caso contrário, permanecerá desligado. Essa estrutura torna o código
mais claro e evita o uso de várias verificações independentes.
Em situações que envolvem diversas possibilidades, pode ser mais adequado utilizar o comando switch...case. Diferentemente do if, que avalia expressões lógicas, o switch compara o valor de uma variável com diferentes opções previamente definidas. Esse recurso é bastante útil quando um mesmo programa precisa executar rotinas distintas
conforme o modo de operação
selecionado pelo usuário ou conforme comandos recebidos por um teclado,
controle remoto ou comunicação serial.
Além
de tomar decisões, muitos programas precisam repetir determinadas ações
continuamente. Para isso existem as estruturas de repetição, também conhecidas
como laços ou loops. Elas evitam a repetição desnecessária de comandos,
tornando os programas menores, mais organizados e fáceis de manter. Em vez de
escrever várias vezes a mesma instrução para acender um LED, por exemplo, basta
utilizar um laço de repetição para que essa tarefa seja executada
automaticamente quantas vezes forem necessárias.
O
laço for é indicado quando já se conhece antecipadamente o número de
repetições que será realizado. Ele utiliza uma variável de controle,
responsável por acompanhar cada repetição até que uma condição de parada seja
alcançada. Essa estrutura é bastante utilizada para criar sequências de LEDs,
realizar contagens ou percorrer conjuntos de dados armazenados em memória. Sua
sintaxe compacta facilita a leitura do código e reduz a possibilidade de erros.
Já
o laço while é utilizado quando não se sabe exatamente quantas vezes uma
ação deverá ser repetida. Nesse caso, o bloco de comandos continuará sendo
executado enquanto determinada condição permanecer verdadeira. Um exemplo é a
leitura contínua de um sensor até que um valor específico seja alcançado. Como
o while depende diretamente da condição estabelecida, é importante
garantir que essa condição possa ser modificada durante a execução do programa,
evitando laços infinitos que impedem o funcionamento adequado do sistema.
Outro
comando muito utilizado é a função delay(), responsável por interromper
temporariamente a execução do programa durante um intervalo de tempo definido
em milissegundos. Embora seja extremamente simples de utilizar, o delay()
bloqueia completamente a execução das demais instruções enquanto a pausa
estiver ativa. Em projetos pequenos isso normalmente não representa um
problema, mas em aplicações mais complexas pode impedir a leitura de sensores
ou atrasar respostas importantes do sistema.
Para contornar essa limitação, a programação do Arduino oferece a função millis(), que retorna o tempo decorrido desde que a placa foi ligada. Diferentemente do delay(), ela permite controlar o tempo sem interromper a execução do restante do programa. Dessa forma, o Arduino pode realizar várias tarefas simultaneamente, como monitorar sensores, atualizar um display e
controlar o tempo sem interromper a execução do restante do
programa. Dessa forma, o Arduino pode realizar várias tarefas simultaneamente,
como monitorar sensores, atualizar um display e controlar motores ao mesmo
tempo. O uso de millis() é considerado uma boa prática em projetos que
exigem maior desempenho e capacidade de resposta.
Como
atividade prática desta aula, pode-se desenvolver um pequeno semáforo
utilizando três LEDs. O programa deverá utilizar estruturas de repetição para
manter o funcionamento contínuo do sistema e estruturas de decisão para
controlar situações específicas, como um modo de manutenção acionado por um
botão. Essa atividade permite observar, na prática, como diferentes estruturas
de programação trabalham em conjunto para resolver um problema real.
Ao
concluir esta aula, o estudante compreenderá quando utilizar as estruturas if,
else, switch, for e while, reconhecerá as
diferenças entre delay() e millis() e será capaz de desenvolver
programas mais organizados, eficientes e preparados para aplicações de
automação e robótica.
Referências
bibliográficas
BANZI,
Massimo. Primeiros Passos com Arduino. São Paulo: Novatec.
MCROBERTS,
Michael. Arduino Básico. São Paulo: Novatec.
MONK,
Simon. Programação com Arduino: Começando com Sketches. Porto Alegre:
Bookman.
OLIVEIRA,
Marcelo Eduardo de. Introdução à Robótica Educacional com Arduino – Hands
On!. Prefeitura de Santo André.
Instituto
Federal Catarinense. Programação Aplicada a Microcontroladores.
TreinaWeb.
Estruturas condicionais e de repetição.
Blog
da Robótica. Fundamentos de Programação para Arduino.
Aula
3 – Entradas Digitais
Uma
das características mais importantes do Arduino é sua capacidade de interagir
com o ambiente ao seu redor. Para isso, a placa recebe informações de sensores,
botões e interruptores por meio das chamadas entradas digitais. Esses
dispositivos permitem que o Arduino identifique eventos simples, como um botão
pressionado, uma chave acionada ou um sensor que detectou movimento. A partir
dessas informações, o programa pode tomar decisões e controlar diferentes
componentes eletrônicos, tornando os projetos interativos e inteligentes.
As entradas digitais trabalham com apenas dois estados possíveis: HIGH (nível lógico alto) e LOW (nível lógico baixo). De forma simplificada, esses estados representam as respostas "ligado" ou "desligado", "verdadeiro" ou "falso". Essa simplicidade torna a leitura das entradas digitais bastante eficiente e
adequada
para dispositivos que possuem apenas duas condições de funcionamento, como
botões, chaves fim de curso, sensores magnéticos e sensores de presença
digitais.
Antes
de utilizar um pino como entrada, é necessário configurá-lo corretamente
utilizando a função pinMode(). Quando um pino é definido como INPUT,
ele passa a receber sinais provenientes dos componentes conectados. Outra
possibilidade é utilizar o modo INPUT_PULLUP, que ativa internamente um
resistor de pull-up, eliminando, em muitos casos, a necessidade de
instalar um resistor externo. Essa configuração simplifica bastante a montagem
dos circuitos e é amplamente utilizada em projetos com botões.
Depois
que o pino foi configurado, o Arduino realiza a leitura utilizando a função digitalRead().
Essa função verifica o estado lógico presente na entrada e retorna apenas um
dos dois valores possíveis: HIGH ou LOW. Com base nesse
resultado, o programa pode executar diferentes ações, como acender um LED,
emitir um som em um buzzer, movimentar um servo motor ou iniciar outra rotina
previamente programada.
Um
dos componentes mais utilizados para demonstrar o funcionamento das entradas
digitais é o botão de pressão (push button). Quando pressionado, ele
altera o estado elétrico do circuito, permitindo que o Arduino identifique a
ação do usuário. Esse princípio está presente em inúmeros equipamentos
eletrônicos do dia a dia, como elevadores, controles remotos, teclados, eletrodomésticos
e sistemas de automação residencial.
Durante
a utilização de entradas digitais, um problema bastante comum é o chamado estado
flutuante (floating). Isso acontece quando um pino permanece sem uma
referência elétrica definida. Nessas condições, o Arduino pode interpretar
sinais aleatórios, fazendo com que o programa registre comandos inexistentes.
Para evitar esse comportamento, utilizam-se resistores de pull-up ou pull-down,
responsáveis por manter o pino em um estado lógico estável quando nenhum botão
estiver sendo pressionado.
O
modo INPUT_PULLUP tornou-se bastante popular justamente porque utiliza
um resistor interno existente no próprio microcontrolador. Nessa configuração,
o pino permanece normalmente em nível lógico HIGH e passa para LOW
quando o botão é pressionado e conectado ao GND. Embora essa lógica seja
inversa em relação à utilizada com resistores pull-down, ela reduz a
quantidade de componentes necessários e simplifica a montagem dos projetos.
Outro fenômeno importante é o chamado debounce. Os
contatos mecânicos de um
botão não fecham de forma perfeitamente instantânea; ao serem pressionados,
podem oscilar rapidamente entre ligado e desligado durante alguns
milissegundos. Como o Arduino executa milhares de instruções por segundo, ele
pode interpretar essas oscilações como vários acionamentos consecutivos. Para
evitar esse problema, utiliza-se o debounce, que pode ser implementado
por meio de componentes eletrônicos ou por programação, filtrando essas
pequenas oscilações antes de considerar o botão realmente pressionado.
Uma
boa prática consiste em testar cada entrada digital individualmente antes de
integrar vários componentes em um mesmo projeto. O uso do Monitor Serial
facilita esse processo, permitindo visualizar em tempo real as mudanças entre
os estados HIGH e LOW. Dessa forma, eventuais problemas de
ligação, configuração ou programação podem ser identificados rapidamente,
reduzindo o tempo gasto na depuração do sistema.
Como
atividade prática desta aula, o aluno poderá montar um circuito simples em que
um botão controla o acionamento de um LED. Inicialmente, o LED permanecerá
apagado e será aceso apenas enquanto o botão estiver pressionado. Em seguida, o
projeto poderá ser ampliado para que cada acionamento alterne o estado do LED
entre ligado e desligado, permitindo explorar tanto a leitura das entradas
digitais quanto as estruturas condicionais estudadas anteriormente.
Ao concluir esta aula, o estudante compreenderá o funcionamento das entradas digitais, saberá configurar corretamente os pinos utilizando INPUT e INPUT_PULLUP, utilizará a função digitalRead() para ler o estado de botões e sensores, compreenderá a importância dos resistores de pull-up e do debounce e estará preparado para desenvolver sistemas capazes de interagir com o ambiente por meio de dispositivos de entrada.
Referências
bibliográficas
BANZI,
Massimo. Primeiros Passos com Arduino. São Paulo: Novatec.
MCROBERTS,
Michael. Arduino Básico. São Paulo: Novatec.
MONK,
Simon. Programação com Arduino: Começando com Sketches. Porto Alegre:
Bookman.
Projeto
Robótica Educacional. Arduino – Entradas e Saídas Digitais.
Arduino
Get Started. Referência da função digitalRead() em português.
Universidade
Federal do Rio Grande do Sul. Introdução ao Arduino.
Universidade
Federal de Santa Catarina. Programação Básica em Arduino.
Estudo
de Caso – Módulo 2
O
sistema de controle da estufa escolar
Uma escola técnica decidiu desenvolver um pequeno projeto de automação
técnica decidiu desenvolver um pequeno projeto de automação para uma
estufa utilizada nas aulas de Ciências. A proposta era simples: instalar um
botão que permitisse ligar e desligar manualmente um sistema de ventilação
representado por um LED. O projeto serviria como base para futuras aplicações
envolvendo sensores de temperatura e umidade.
A
equipe responsável, formada por alunos iniciantes, iniciou a programação
utilizando as estruturas de decisão aprendidas em sala de aula. O programa
verificava constantemente se o botão havia sido pressionado e, quando isso
acontecia, alterava o estado do LED. A montagem parecia correta e o código
compilava sem apresentar erros.
Durante
os primeiros testes, porém, surgiu um comportamento inesperado. Ao pressionar o
botão apenas uma vez, o LED ligava e desligava diversas vezes em sequência. Em
outros momentos, o LED mudava de estado sem que ninguém tocasse no botão. Além
disso, quando decidiram acrescentar uma sequência de piscadas para indicar que
o sistema estava ativo, perceberam que o botão demorava a responder enquanto o
programa executava longos períodos de espera com a função delay(). Esses
problemas são comuns em projetos com entradas digitais e normalmente estão
relacionados ao efeito de bounce (debounce), ao uso de entradas
flutuantes e ao bloqueio causado por atrasos prolongados.
Depois
de analisar cuidadosamente o projeto, os alunos identificaram três causas
principais. A primeira era a ausência de um resistor de pull-up ou pull-down,
deixando a entrada digital em estado flutuante e sujeita a interferências
elétricas. A segunda estava relacionada ao fenômeno conhecido como debounce:
ao ser pressionado, o botão produzia pequenas oscilações mecânicas que o
Arduino interpretava como vários acionamentos consecutivos. Por fim, o uso
excessivo da função delay() fazia com que o programa interrompesse
temporariamente todas as demais tarefas, reduzindo a capacidade de resposta do
sistema.
Para solucionar o primeiro problema, os estudantes configuraram o pino do botão utilizando o modo INPUT_PULLUP, aproveitando o resistor interno do próprio Arduino e eliminando o estado flutuante da entrada. Em seguida, implementaram uma rotina de debounce, permitindo que o programa considerasse apenas pressionamentos realmente estáveis do botão. Por fim, substituíram parte dos atrasos baseados em delay() por uma lógica utilizando a função millis(), permitindo que o Arduino continuasse monitorando o botão enquanto outras
tarefas eram executadas. Essas mudanças
tornaram o sistema muito mais confiável e responsivo.
Após
as correções, o botão passou a responder corretamente, acionando o LED apenas
uma vez a cada pressionamento. A equipe percebeu que pequenos detalhes de
programação e configuração podem fazer grande diferença no desempenho de um
projeto. Mais importante do que simplesmente fazer um circuito funcionar é
compreender por que ele funciona e como evitar comportamentos inesperados.
Erros
comuns observados
Como
evitar esses problemas
Lições
aprendidas
O desenvolvimento desse projeto mostrou que a programação de sistemas embarcados depende tanto da lógica do código quanto da correta configuração do hardware. Estruturas de decisão bem planejadas, laços de repetição utilizados de forma adequada e uma leitura confiável das entradas digitais são fundamentais para construir sistemas seguros e estáveis. Ao adotar boas práticas desde os primeiros projetos, o estudante desenvolve uma base sólida para trabalhar futuramente com sensores, atuadores e aplicações mais complexas de automação e robótica.
Quer acesso gratuito a mais materiais como este?
Acesse materiais, apostilas e vídeos em mais de 3000 cursos, tudo isso gratuitamente!
Matricule-se AgoraQuer acesso gratuito a mais materiais como este?
Acesse materiais, apostilas e vídeos em mais de 3000 cursos, tudo isso gratuitamente!
Matricule-se Agora