Aula 01 - Plataforma Arduino, Arquitetura do Hardware e Primeiros Códigos
1. O Ecossistema Arduino e a Computação Física
A plataforma Arduino surgiu em 2005 no Interaction Design Institute Ivrea (Itália) como um projeto de hardware e software livres (Open-Source Hardware/Software) concebido para democratizar o acesso à computação física e ao controle embarcado.
Embora amplamente reconhecida como uma ferramenta de prototipagem rápida, a arquitetura do Arduino Uno R3 baseia-se em um microcontrolador industrial padrão — o Atmel AVR ATmega328P — e obedece aos mais rigorosos conceitos da engenharia eletrônica: barramentos de alimentação com proteção contra sobrecorrente, conversores de nível lógico, temporização a cristal piezoelétrico e gravação em memória não-volátil sem necessidade de hardware de gravação proprietário dedicado.
2. Engenharia de Hardware da Placa Arduino Uno R3
2.1 Subsistema de Alimentação e Proteção Elétrica
A placa Uno R3 possui três alternativas para suprimento de energia:
- Alimentação via Cabo USB (): Fornecida diretamente pela porta USB do computador hospedeiro. O circuito inclui um termistor PTC rearmável (PolySwitch) que limita a corrente em , protegendo as portas USB do computador contra curtos-circuitos acidentais na protoboard;
- Jack P4 de Alimentação Externa (): Conector fêmea de centro positivo () que aceita fontes de corrente contínua não-reguladas de (limites extremos: ). Um diodo Schottky em série protege contra inversão acidental de polaridade;
- Regulador Linear LDO (Low Dropout): O circuito integrado NCP1117ST50 reduz a tensão de entrada para regulados para alimentar o microcontrolador. Uma segunda linha linear fornece (até ) para alimentar sensores modernos de baixa tensão;
- Circuito de Comutação Automática de Fonte: Um comparador operacional (LM358) monitora a tensão : se (isto é, ), um MOSFET canal P corta a alimentação da porta USB, priorizando a fonte externa e evitando correntes reversas danosas ao computador.
2.2 O Conversor USB-Serial e o Auto-Reset
Em placas Arduino genuínas e clones de primeira linha, a interface USB não é um conversor dedicado estático (como o antigo FT232RL ou o econômico CH340G), mas sim um segundo microcontrolador RISC completo — o ATmega16U2 — programado com firmware USB CDC (Communications Device Class):
- O ATmega16U2 traduz pacotes virtuais USB em pulsos seriais UART nos pinos D0 (RX) e D1 (TX);
- O Sinal DTR de Auto-Reset: Na linha DTR (Data Terminal Ready), há um capacitor cerâmico em série de conectado ao pino
RESETdo ATmega328P. Quando a IDE do Arduino abre a porta serial para efetuar o upload do código, a descida de DTR gera um pulso negativo que reseta o ATmega328P no instante exato, iniciando o Bootloader sem necessidade de intervenção física humana no botão de reset.
3. O Microcontrolador ATmega328P e o Papel do Bootloader
O coração operacional da placa é o microcontrolador Atmel ATmega328P em encapsulamento DIP de 28 pinos:
- Arquitetura Harvard RISC avançada com 131 instruções de máquina;
- Frequência de operação fixada em por um cristal oscilador de quartzo externo acoplado a dois capacitores cerâmicos de carga de ;
- Ciclo de Máquina: Diferentemente do PIC que divide o clock por 4, a arquitetura AVR executa a maioria das instruções em um único ciclo de clock puro ():
3.1 Mecanismo de Auto-Programação (Self-Programming)
Tradicionalmente, microcontroladores exigiam programadores externos (como USBasp, PICkit ou JTAG) que aplicavam protocolos seriais síncronos nos pinos SPI com o chip em reset.
O Bootloader Optiboot (instalado de fábrica no topo da Flash, endereços a ):
- É executado imediatamente após qualquer evento de Reset;
- Pisca rapidamente o LED do pino D13 e escuta a porta serial a por cerca de ;
- Se receber o caractere de sincronismo do protocolo STK500 vindo da IDE, entra em modo de gravação: recebe os blocos binários compilados via UART e utiliza a instrução de hardware
SPM(Store Program Memory) para reescrever as páginas da Flash; - Se nenhum dado for recebido no timeout, o Optiboot salta para o endereço e executa imediatamente o código do usuário residente na memória.
4. Estrutura Canônica do Código e Compilação em C++
Diferentemente de programas C clássicos para desktop que possuem uma função main() linear que retorna zero ao término da execução, o framework Arduino converte o sketch (.ino) internamente em um código fonte padrão que roda em um laço perpétuo (bare-metal superloop):
// Arquivo interno da biblioteca Arduino Core (main.cpp):
#include <Arduino.h>
int main(void) {
init(); // Inicializa temporizadores internos Timer0 para millis() e ADC
initVariant();
setup(); // Executa a função de inicialização do usuário (1 única vez)
for (;;) {
loop(); // Executa iterativamente em loop infinito
if (serialEventRun) serialEventRun();
}
return 0;
}4.1 A Função setup()
Executada exatamente uma vez quando a placa é ligada ou resetada. Destina-se à configuração estática de hardware:
- Definição da direção de pinos GPIO (
pinMode); - Inicialização de barramentos de comunicação (
Serial.begin,Wire.begin,SPI.begin); - Configuração de timers, interrupções externas e calibração de sensores.
4.2 A Função loop()
Executada ciclicamente em repetição infinita enquanto a placa estiver energizada. Contém a lógica de controle principal:
- Leitura de sensores analógicos e digitais;
- Processamento algorítmico e máquinas de estados;
- Atualização das saídas de controle (relés, PWM de motores, displays).
5. Abstração de Alto Nível vs. Acesso Direto a Registradores
A biblioteca padrão do Arduino fornece funções de alto nível que priorizam a portabilidade e facilidade de aprendizado, mas que introduzem sobrecarga de processamento (overhead) devido a pesquisas em tabelas e verificações de segurança:
5.1 O Registrador PINx como Alternador de Hardware (Hardware Toggle)
Uma característica singular da arquitetura Atmel AVR é que escrever o bit lógico no registrador de leitura PINx faz com que o hardware inverta instantaneamente (toggle) o estado do pino correspondente no registrador de saída PORTx em um único ciclo de máquina ():
6. Diagrama Arquitetural Consolidado
O diagrama técnico vetorial a seguir ilustra a topologia física da placa Arduino Uno R3, destacando os subsistemas de regulação de alimentação, o conversor serial ATmega16U2, a pinagem do microcontrolador ATmega328P e a comparação com os registradores nativos DDRB/PORTB:
7. Exercícios Resolvidos e Aplicações em Concursos
Exercício 1 (Petrobras - Engenharia Eletrônica / CESGRANRIO)
Enunciado: Deseja-se conectar um LED vermelho de sinalização industrial ao pino digital D13 de uma placa Arduino Uno R3 operando com . Os parâmetros ópticos do LED fornecidos pelo catálogo são: queda de tensão direta sob corrente nominal direta .
- Calcule o valor exato do resistor limitador de corrente a ser colocado em série com o LED.
- Selecione o valor comercial normalizado na série E24 imediatamente superior para operar de forma conservadora e calcule a corrente real de trabalho resultante.
- Determine a dissipação de potência nominal no resistor limitador e no pino de saída do microcontrolador.
Resolução Passo a Passo:
-
Cálculo do Resistor Limitador Teórico: Aplicando a Lei de Ohm na malha fechada do pino de saída:
-
Seleção Comercial e Corrente Real: Na série comercial normalizada E24 (), os valores próximos são . Adotando o valor comercial padrão superior de : Como (limite seguro do pino GPIO do ATmega328P), o circuito opera com excelente brilho e durabilidade térmica infinita.
-
Dissipação de Potência:
- No resistor limitador de : Um resistor convencional de filme de carbono de () opera com ampla folga.
- Potência fornecida pelo pino D13 do microcontrolador:
Exercício 2 (Marinha do Brasil - Corpo de Engenheiros)
Enunciado: Um engenheiro de controle necessita gerar uma onda quadrada com frequência de exatamente em um pino digital de uma placa Arduino Uno R3 operando com clock de .
- Demonstre formalmente por que é matematicamente impossível gerar essa frequência utilizando a função padrão
digitalWrite(pin, val). - Escreva o trecho de código em linguagem C/C++ utilizando manipulação direta de registradores nativos do ATmega328P para sintetizar a onda de com duty cycle simétrico de .
Resolução Técnica Analítica:
-
Limitação da Função
digitalWrite:- Para sintetizar uma onda quadrada de , o período total deve ser:
- Cada semiperíodo (tempo em nível alto e tempo em nível baixo) deve durar rigorosamente:
- Em um clock de (), correspondem a:
- A função
digitalWrite()consome internamente cerca de de clock () para decodificar tabelas de portas e desabilitar PWMs. Duas chamadas consecutivas consom mais de (), limitando a frequência máxima de chaveamento em cerca de . Logo, atingir viadigitalWrite()é fisicamente impossível!
-
Código Otimizado em Registradores Nativos: Para consumir exatamente 8 ciclos por semiperíodo:
- 1 ciclo para inverter o pino via registrador
PINB; - 7 ciclos de atraso gerados por instruções de máquina
NOP(No Operation - 1 ciclo cada) ou loops calibrados:
- 1 ciclo para inverter o pino via registrador
void setup() {
DDRB |= (1 << 5); // Configura pino D13 (PB5) como saída digital (1 ciclo)
}
void loop() {
while (1) {
PINB = (1 << 5); // Inverte o estado de D13 (1 ciclo de máquina)
__asm__ __volatile__ (
"nop\n\t" // 1 ciclo
"nop\n\t" // 1 ciclo
"nop\n\t" // 1 ciclo
"nop\n\t" // 1 ciclo
"nop\n\t" // 1 ciclo
); // Salto incondicional do loop consome 2 ciclos (Total = 1 + 5 + 2 = 8 ciclos!)
}
}Com em nível alto e em nível baixo: A onda de é gerada com precisão de cristal de quartzo!