Kit Avançado de Arduino Uno AE050 - 34 Projetos - Curso Completo

Introdução
Este curso apresenta uma formação técnica completa em computação física, sistemas embarcados e instrumentação eletrônica utilizando a plataforma Arduino Uno R3 (microcontrolador ATmega328P) e o conjunto de componentes KUONGSHUN AE050 — The Most Complete Starter Kit for UNO. Ao longo de 34 lições numeradas de 0 a 33, na ordem exata da documentação oficial do fabricante, são explorados desde os fundamentos de eletricidade e lógica digital até subsistemas de automação com multiplexação, sensoriamento ambiental, comunicação serial, barramentos I2C (Inter-Integrated Circuit) e SPI (Serial Peripheral Interface), modulação por largura de pulso (PWM — Pulse Width Modulation), detecção ultrassônica, identificação por radiofrequência (RFID — Radio-Frequency Identification) e acionamento de potência com transistores, relés e drivers Darlington.
O conteúdo foi concebido como material educacional progressivo para quem está começando em eletrônica e deseja chegar ao domínio prático de sensores, atuadores, displays e motores. Cada lição é auto-contida nesta página única e segue o mesmo ritual de engenharia: fundamento físico do componente, tabela de materiais, diagrama esquemático com montagem em matriz de contatos (breadboard), tabela de conexões pino a pino, código-fonte em C++ para Arduino comentado linha a linha em português, procedimento de gravação e teste com resultado esperado, além de diagnósticos de falha.
O que você vai aprender:
- Compreender a arquitetura do ATmega328P, pinos digitais, entradas analógicas com conversor ADC de 10 bits, temporizadores e comunicação UART
- Montar circuitos em protoboard com LEDs, resistores, botões, potenciômetros e divisores de tensão, aplicando a Lei de Ohm
- Expandir saídas digitais com registrador de deslocamento 74HC595 e displays de 7 segmentos, LCD 16x2 e matriz MAX7219
- Medir luz, temperatura, umidade, distância, som, movimento, nível de água, aceleração, tempo real e proximidade RFID
- Gerar sons com buzzers ativo e passivo, controlar servo SG90, motor DC com transistor, motor de passo 28BYJ-48 com ULN2003, relé e teclado matricial
- Decodificar controle remoto infravermelho, usar Monitor Serial para depuração e integrar joystick, encoder rotativo, PIR e ultrassom em automações
- Diagnosticar falhas de driver USB-serial, porta, biblioteca, alimentação e fiação pelo Guia Diagnóstico
Material utilizado: Kits Arduino Uno na loja RoboBuilders
Visão Geral do Kit e Arquitetura de Hardware
A plataforma Arduino Uno R3 adotada no kit AE050 é construída em torno do microcontrolador de 8 bits ATmega328P (família AVR, 16 MHz com ressonador cerâmico externo, arquitetura Harvard modificada). O kit segue a documentação oficial KUONGSHUN AE050, cuja lista de lições vai da instalação da IDE (Lição 0) ao controle de motor de passo com encoder (Lição 33). Nenhum projeto foi reordenado, fundido ou omitido neste curso.
Especificações Técnicas da Placa Arduino Uno R3
| Parâmetro de Engenharia | Especificação Técnica | Observações de Operação |
|---|---|---|
| Microcontrolador Principal | ATmega328P (8-bit AVR RISC) | DIP-28 ou SMD, 16 MIPS a 16 MHz |
| Tensão Lógica de Operação | 5,0 VDC (TTL) | Nível HIGH ~5 V, LOW ~0 V |
| Entrada Recomendada (VIN / Jack P4) | 7,0 V a 12,0 VDC | Regulador linear LDO onboard |
| Entrada Limite (VIN) | 6,0 V a 20,0 VDC | Acima de 12 V aquece o LDO |
| GPIOs Digitais | 14 pinos (D0 a D13) | 6 com PWM por hardware (3, 5, 6, 9, 10, 11 — marcados com ~) |
| Entradas Analógicas | 6 canais (A0 a A5) | ADC 10 bits (0 a 1023 passos) |
| Corrente por Pino | 20 mA típico, 40 mA absoluto | Soma total recomendada abaixo de 200 mA |
| Saída 3,3 V | 50 mA máximo | Para módulos de 3,3 V como ADXL335 e RC522 |
| Flash / SRAM / EEPROM | 32 KB / 2 KB / 1 KB | 0,5 KB da Flash ocupados pelo bootloader Optiboot |
| Clock | 16 MHz | Ressonador cerâmico externo |
| Interface USB-Serial | CH340G / CP2102 / ATmega16U2 (conforme revisão) | Conversão UART-USB, exige driver no Windows |
| Comunicação Serial Hardware | D0 (RX) e D1 (TX) via USB | Evitar usar D0/D1 com periféricos durante upload |
O conversor analógico-digital de 10 bits é o coração das medições deste curso (fotocélula, termistor, joystick, sensor de água, som, acelerômetro). A relação entre contagem e tensão é:
onde é a contagem de 0 a 1023 e é a tensão no pino analógico. Essa equação reaparece nas Lições 8, 17, 21, 24, 26 e 28 com divisores e condicionamentos diferentes.
O controle de potência por PWM usa o conceito de ciclo de trabalho (duty cycle):
onde é o tempo em HIGH dentro do período (~2 ms no PWM de ~490/976 Hz do Uno) e é a tensão média percebida pela carga (brilho do LED, velocidade do motor, posição do servo, volume do buzzer passivo). O comando analogWrite(pino, valor) com valor de 0 a 255 implementa exatamente esse .
A Lei de Ohm governa todos os dimensionamentos de LED e divisor:
Para LED vermelho () a 15 mA em 5 V, — por isso o kit usa 220 como padrão.
Mapa de Pinos e Protocolos Usados no Curso
| Subsistema | Pinos Típicos no AE050 | Protocolo / Técnica |
|---|---|---|
| LED onboard Blink | D13 | GPIO saída digital + delay() |
| LEDs, botões, buzzer ativo, tilt, relé (lógica) | D2–D13 | GPIO digital, INPUT_PULLUP para botões |
| RGB, buzzer passivo (melodias), motor DC, servo | D3, D5, D6, D9, D10, D11 (~) | PWM por hardware + tone() + biblioteca Servo |
| Fotocélula, termistor, joystick XY, água, som AO, ADXL335 XYZ | A0–A5 | ADC 10 bits + divisor resistivo |
| 74HC595 (LEDs e 7-seg) | D4 (dados), D5 (latch), D6 (clock) e variante D8/D11/D12 | Serial-para-paralelo via shiftOut() |
| LCD 16x2 modo 4 bits | D7 (RS), D8 (E), D9–D12 (D4–D7) | Biblioteca LiquidCrystal |
| Ultrassom HC-SR04 | Trig/Echo digitais | Pulso de 10 µs + pulseIn() |
| Teclado 4x4 | 8 digitais (4 linhas + 4 colunas) | Varredura matricial (Keypad) |
| DHT11 | 1 digital | Protocolo proprietário 1-wire temporizado |
| IR receptor | 1 digital com interrupção | Decodificação NEC (IRremote) |
| MAX7219 matriz 8x8 | DIN/CS/CLK | SPI por software (LedControl) |
| DS3231 RTC | A4 (SDA), A5 (SCL) | I2C + RTClib |
| RC522 RFID | D9 (RST), D10 (SS), D11 (MOSI), D12 (MISO), D13 (SCK) | SPI hardware + MFRC522 |
| Servo SG90 | 1 PWM + 5 V + GND | Pulsos de 1–2 ms a 50 Hz |
| Motor DC via PN2222 | 1 PWM + transistor + diodo 1N4007 | Chaveamento low-side |
| Passo 28BYJ-48 + ULN2003 | IN1–IN4 | Sequência de 4 fases |
| Encoder rotativo | CLK/DT/SW | Leitura de quadratura + chave |
Inventário Completo do Kit AE050 (Packing List — espelho da doc + Lições 2–33)
O kit retratado nas páginas 3 a 8 do PDF e consumido ao longo das Lições 2 a 33 reúne:
- 1x Placa compatível com Arduino Uno R3 (ATmega328P, USB tipo B)
- 1x Cabo USB A-B para programação e alimentação
- 1x Matriz de contatos (breadboard MB-102, 830 pontos) com trilhos de alimentação
- Jumpers macho-macho variados e jumpers fêmea-macho para módulos
- 1x Módulo de fonte para protoboard (trilho 3,3 V / 5 V) e acessórios de alimentação citados na Lição 12/32 (adaptador 9 V, conector Jack P4)
- 1x Display LCD 1602 alfanumérico + 1x potenciômetro de contraste
- 1x Display de 7 segmentos de 1 dígito + 1x display de 4 dígitos
- 1x Matriz de LEDs 8x8 com driver MAX7219
- 1x CI registrador de deslocamento 74HC595
- 1x Servo SG90 180 graus
- 1x Motor DC 6 V + hélice (conforme Lição 12/30) + 1x transistor PN2222 + 1x diodo 1N4007
- 1x Módulo relé 5 V (contatos COM/NA/NF)
- 1x Buzzer ativo 5 V + 1x buzzer passivo piezo
- 1x Sensor DHT11 de temperatura e umidade (módulo)
- 1x Sensor ultrassônico HC-SR04
- 1x Teclado matricial de membrana 4x4
- 1x Joystick analógico de 2 eixos com chave
- 1x Receptor IR + controle remoto
- 1x Módulo acelerômetro ADXL335 (3 eixos, alimentação 3,3 V)
- 1x Sensor PIR HC-SR501
- 1x Sensor de nível de água (trilhas pectinadas)
- 1x Módulo relógio de tempo real DS3231 com bateria de backup
- 1x Sensor de som com microfone de eletreto e comparador LM393 (saídas AO/DO + trimpot)
- 1x Kit RFID RC522 (leitor + cartão + tag) para SPI
- 1x Motor de passo 28BYJ-48 5 V + placa driver ULN2003
- 1x Módulo encoder rotativo (CLK/DT/SW, usado na Lição 33)
- 1x Fotocélula LDR + 1x termistor NTC + 1x sensor de inclinação por esfera (ball switch / tilt SW-520D)
- LEDs 5 mm variados + 1x LED RGB de 4 pinos
- Resistores 220 Ω, 1 kΩ, 10 kΩ (faixas coloridas) + botões tácteis 4 pinos
- Componentes das fotos de abertura do PDF (páginas 3–8) conferem com a lista acima; a ordem de consumo segue as Lições 2–33 sem exceção
📦 Somatória Geral do Kit: mais de 150 peças individuais entre placa, protoboard, jumpers, displays, CIs, sensores, atuadores, motores, LEDs, resistores e botões, distribuídos nas categorias acima para executar as 34 lições sem compras adicionais além de fonte USB e eventual bateria 9 V citada nas lições de potência.
⚠️ Atenção: nunca alimente motores, relés ou a bobina do passo pela porta USB do PC além do teste lógico de milissegundos. Use a fonte de protoboard ou adaptador 9 V com terra comum (GND compartilhado) nas Lições 12, 30, 31 e 32. Cabo USB deve ser de dados, não só de carga, senão a porta não aparece.
Módulo 0 — Preparação do Ambiente (Lições 0 e 1)
Lição 0: Instalação da IDE Arduino, Driver USB-Serial, Placa e Porta
A Lição 0 do PDF instala a IDE a partir do site arduino.cc, descompacta o ZIP no Desktop (Windows), instala o driver USB via Gerenciador de Dispositivos apontando para a pasta drivers do Arduino, e configura Ferramentas > Placa > Arduino Uno e Ferramentas > Porta. No Mac arrasta Arduino.app para Aplicativos; no Linux segue o guia da comunidade por distribuição. O teste final é o upload do exemplo Arquivo > Exemplos > 01.Basics > Blink.
Siga na ordem oficial. O PDF foi escrito na era IDE 1.0.5/1.5 beta, mas o ritual é idêntico nas IDEs 1.8.x e 2.x modernas: baixar do portal oficial, instalar, conectar a Uno via USB de dados, resolver o driver (CH340/CP210x/16U2 conforme a revisão da sua placa), selecionar placa e porta, abrir o Blink e gravar. O LED L ligado ao D13 deve piscar. Se o upload falhar com avrdude: stk500_recv(), volte a este checklist antes de culpar o código: cabo, driver, placa, porta, nada ligado em D0/D1 durante a gravação.
Etapas oficiais detalhadas: primeiro baixe o ZIP do Windows no arduino.cc e extraia com Extrair tudo para o Desktop. A pasta contém o executável da IDE e a subpasta de drivers. Com a Uno conectada, o Windows acusa Dispositivo desconhecido com triângulo amarelo em Outros dispositivos. Clique com botão direito, Atualizar driver, Procurar no computador, aponte para arduino-1.0.x/drivers (nas IDEs modernas o instalador já traz o driver assinado; no Windows 10/11 aceite o driver do fabricante CH340 se a placa usar esse chip). Confirme a instalação quando o aviso de segurança aparecer. Só então abra a IDE. No menu Ferramentas, selecione Placa: Arduino Uno e em Porta a COM recém-criada (ou /dev/ttyUSBn / /dev/tty.usbmodemXXXX no Linux/Mac). A barra inferior da IDE exibe placa e porta ativas. Esse vínculo placa+porta é pré-requisito de todas as 33 lições seguintes.
💡 Dica: anote a COM da sua Uno (ex.: COM4) e mantenha sempre a mesma porta USB do PC. Trocar de porta cria outra COM e o upload falha até você reselecionar.
⚠️ Atenção: o PDF original cita a IDE 1.0.5 por ser de 2014. Você pode usar a IDE 2.x atual sem prejuízo — os exemplos
Blink,LiquidCrystal,ServoeWirecontinuam nos mesmos menus. O que não muda: placa tem que serArduino Unoe a porta tem que ser a da Uno, nuncaArduino Leonardoou porta Bluetooth.
Resultado esperado: IDE abre, placa Arduino Uno e porta selecionadas, exemplo Blink gravado, LED L piscando em 1 Hz. Sem isso, não avance para a Lição 1.
Lição 1: Instalação de Bibliotecas (Library Manager, ZIP e Manual)
A Lição 1 define biblioteca como coleção de .cpp/.h (+ keywords.txt + pasta examples) que estende a IDE para sensores, displays e protocolos, e ensina as três vias oficiais: Gerenciador de Bibliotecas (IDE 1.6.2 em diante, Sketch > Incluir Biblioteca > Gerenciar Bibliotecas, buscar, escolher versão, Instalar), importação de .ZIP (Sketch > Incluir Biblioteca > Adicionar Biblioteca .ZIP, sem descompactar antes) e instalação manual (encerrar a IDE, descompactar para Documentos/Arduino/libraries/NomeDaLib/NomeDaLib.cpp, sem aninhar pasta dupla, reabrir e conferir em Sketch > Incluir Biblioteca e Arquivo > Exemplos após reiniciar).
Resumo operacional da própria Lição 1: instale de uma vez todos os ZIPs que acompanham o kit para não repetir o passo nas lições seguintes; depois basta ligar o hardware do esquemático e gravar o código fornecido. As bibliotecas usadas neste curso são LiquidCrystal (LCD, Lições 16–17), DHT (Lição 20), Keypad (Lição 19), IRremote (Lições 22/32), LedControl ou equivalente para MAX7219 (Lição 23), MFRC522 (Lição 29), RTClib/DS1307RTC (Lição 27), Servo (Lição 15), Stepper (Lições 31–33) e suporte a HC-SR04 (Lição 18, por biblioteca ou pulseIn nativo). Sempre confira a versão instalada no Gerenciador — núcleo ou lib errada é a causa número 1 de erro de compilação (No such file or directory, does not name a type).
Tabela-mestre de bibliotecas do curso
Instale pelo Gerenciador (Sketch > Incluir Biblioteca > Gerenciar Bibliotecas…, buscar pelo nome exato, escolher a versão, Instalar) ou via ZIP (Sketch > Incluir Biblioteca > Adicionar Biblioteca .ZIP…, sem descompactar antes). Cada lição repete o seu quadro de instalação antes do código.
Biblioteca (#include) | Buscar no Gerenciador | Versão usada no curso | Download ZIP (espelho oficial) | Lições |
|---|---|---|---|---|
Servo.h (embutida na IDE) | já vem instalada — nada a instalar | núcleo AVR da IDE | — | 15 |
LiquidCrystal (embutida na IDE) | já vem instalada — nada a instalar | núcleo AVR da IDE | — | 16, 17 |
Stepper.h (embutida na IDE) | já vem instalada — nada a instalar | núcleo AVR da IDE | — | 31, 32, 33 |
Wire.h / SPI.h (embutidas na IDE) | já vêm instaladas — nada a instalar | núcleo AVR da IDE | — | 27, 29 |
pitches.h (aba do sketch, não é Manager) | não buscar — criar aba no sketch | tabela oficial Arduino | pitches.h oficial (tutorial) | 10 |
Keypad | Keypad por Mark Stanley, Alexander Brevig | 3.1.1 | Chris—A/Keypad | 19 |
DHT sensor library + Adafruit Unified Sensor (dependência obrigatória) | DHT sensor library por Adafruit e Adafruit Unified Sensor por Adafruit | 1.4.7 + última do Unified Sensor | adafruit/DHT-sensor-library + adafruit/Adafruit_Sensor | 20 |
IRremote | IRremote por shirriff, z3t0, ArminJo — selecionar versão 2.x no menu de versões (NÃO usar 3.x/4.x com o código deste curso) | 2.8.1 (linha 2.x) | Arduino-IRremote — Releases (baixar o ZIP da 2.8.1) | 22, 32 |
LedControl | LedControl por Eberhard Fahle | 1.0.6 | wayoda/LedControl | 23 |
RTClib | RTClib por Adafruit | 2.x atual | adafruit/RTClib | 27 |
MFRC522 | MFRC522 por GithubCommunity | 1.4.12 | miguelbalboa/rfid | 29 |
⚠️ Atenção: a
IRremote3.x/4.x mudou a API (IrReceiver, semdecode_results/results.value) e QUEBRA os códigos das Lições 22 e 32. No Gerenciador, abra o menu de versões daIRremotee fixe a 2.8.1 antes deInstalar. ADHTsó compila com a dependênciaAdafruit Unified Sensorinstalada junto.
Estrutura correta após instalação manual no Windows:
Documentos\Arduino\libraries\NomeDaLib\NomeDaLib.cpp
Documentos\Arduino\libraries\NomeDaLib\NomeDaLib.h
Documentos\Arduino\libraries\NomeDaLib\examples\...
Estrutura errada que quebra tudo (não faça): .cpp solto direto em libraries, ou pasta dupla libraries\NomeDaLib\NomeDaLib\NomeDaLib.cpp. Reinicie a IDE após instalar para os exemplos aparecerem em Arquivo > Exemplos.
💡 Dica: instale uma lib por vez pelo Gerenciador, feche e reabra a IDE, e compile um exemplo da lib antes de montar o circuito. Isola erro de software de erro de fiação.
Módulo 1 — Fundamentos Digitais e Expansão (Lições 2 a 7)
Lição 2: Blink — Piscar o LED Embarcado (D13)
A Lição 2 reprograma a Uno com o exemplo Arquivo > Exemplos > 01.Basics > Blink. A placa possui fileiras de conectores para shields e um LED soldado chamado L, ligado ao pino digital 13. Muitas Unos já vêm com Blink gravado de fábrica, então o L pode estar piscando ao conectar o USB — o exercício é gravar sua própria cópia (Arquivo > Salvar como > MyBlink, pois exemplos são somente-leitura), configurar placa/porta como na Lição 0 e clicar em Upload (segundo botão da barra). A IDE mostra Compilando sketch, depois Enviando, com os LEDs RX/TX tremeluzindo, e por fim Concluído com uso de ~1084 bytes dos 32256 disponíveis.
| Item | Qtd | Observação |
|---|---|---|
| Placa Uno R3 | 1 | LED L = D13 onboard, sem fiação externa |
| Cabo USB de dados | 1 | Porta + placa corretas |
// MyBlink — Lição 2 AE050: pisca o LED embarcado L (D13)
// Comentado linha a linha em português técnico.
int led = 13; // apelido: LED embarcado está no digital 13 na Uno
void setup() {
pinMode(led, OUTPUT); // configura D13 como saída (fonte de corrente)
}
void loop() {
digitalWrite(led, HIGH); // aplica ~5 V em D13: acende o LED
delay(1000); // espera 1000 ms (1 s) com LED aceso
digitalWrite(led, LOW); // aplica ~0 V em D13: apaga o LED
delay(1000); // espera 1000 ms com LED apagado; loop recomeça
}
Comentários // são de linha e /* ... */ são de bloco — o compilador ignora, servem para documentar. setup() roda uma vez após reset/upload; loop() repete para sempre. Para piscar duas vezes mais rápido troque ambos delay(1000) por delay(500) e grave de novo. Período e frequência obedecem a:
Com 1000+1000 ms, e . Com 500+500 ms, . Se der erro de porta não encontrada, volte à Lição 0 (cabo, driver, placa, porta). Resultado esperado: L piscando no ritmo gravado, sem nenhum fio externo.
Lição 3: LED com Resistores (220 Ω, 1 kΩ, 10 kΩ) e Protoboard MB-102
A Lição 3 ensina brilho com resistores diferentes e apresenta a protoboard MB-102, o LED de 5 mm e o código de cores. Na protoboard, furos da mesma fileira curta são interligados por lâminas metálicas internas; o canal central separa os dois lados (ideal para CIs); os trilhos longos laterais (+/-) distribuem 5 V e GND. Conexões push-fit são ótimas para prototipar, mas menos confiáveis que solda — mau contato aqui explica LED que falha ao encostar no fio.
O LED tem polaridade: perna longa = anodo (+), perna curta com chanfro no corpo = catodo (−). Ligação direta em 5 V sem resistor destrói a junção por sobrecorrente. O resistor pode ir antes ou depois do LED (circuito série, mesma corrente). Com 5 V da Uno via USB, teste 220 Ω (bem brilhante), 1 kΩ (médio) e 10 kΩ (quase apagado). Toque o jumper vermelho como chave para comparar.
| Item | Qtd | Detalhe |
|---|---|---|
| Uno R3 | 1 | Fonte 5 V + GND via USB |
| LED vermelho 5 mm | 1 | Anodo longo, catodo com chanfro |
| Resistor 220 Ω | 1 | Vermelho-vermelho-marrom-dourado |
| Resistor 1 kΩ | 1 | Marrom-preto-vermelho-dourado |
| Resistor 10 kΩ | 1 | Marrom-preto-laranja-dourado |
| Jumpers M-M | 2 | 5 V → resistor → anodo; catodo → GND |
| Ligação | Origem | Destino |
|---|---|---|
| Alimentação | 5V da Uno | Trilho + / resistor |
| Resistor | Trilho 5 V | Anodo do LED (perna longa) |
| Catodo | Perna curta do LED | GND da Uno |
Dimensionamento pela Lei de Ohm com e :
Com , (brilhante e seguro). Com , . Com , (fraco). Potência no resistor:
Bem abaixo de 1/4 W em todos os casos. Resultado esperado: brilho cai nitidamente de 220 Ω para 10 kΩ; invertendo o LED ele apaga (polaridade); resistor de qualquer lado funciona.
⚠️ Atenção: confira se as pernas do resistor não se encostam. Encurte-as para deitar rente à protoboard se preciso.
Lição 4: LED RGB e PWM (Mistura de Cores)
A Lição 4 usa um LED RGB de 4 pinos (3 LEDs internos: vermelho, verde, azul) para percorrer vermelho → verde → azul com laços for. Há duas variantes: anodo comum (pino comum em 5 V) e catodo comum (pino comum em GND). O kit usa catodo comum: o pino mais longo (2º a partir do chanfro) vai ao GND, e cada cor vai a um PWM (~) via 220 Ω. Sem os 3 resistores, a corrente estoura.
O olho tem receptores para vermelho, verde e azul; o cérebro interpreta a soma como cor. Vermelho+verde em mesmo brilho = amarelo; os três iguais = branco; os três apagados = preto. Como variar brilho sem trocar resistor? Com PWM: analogWrite(pino, 0) = sempre apagado, analogWrite(pino, 255) = sempre aceso, valores intermediários geram pulsos de ~1/500 s cuja largura define a potência média — o olho não percebe o chaveamento, só o brilho.
| Item | Qtd |
|---|---|
| Uno R3 + protoboard | 1 cada |
| LED RGB catodo comum | 1 |
| Resistores 220 Ω | 3 |
| Jumpers M-M | 4 |
| Cor | Pino Uno (PWM) | Resistor |
|---|---|---|
| Vermelho | D9 (~) | 220 Ω em série |
| Verde | D10 (~) | 220 Ω em série |
| Azul | D11 (~) | 220 Ω em série |
| Comum (mais longo) | GND | direto |
// Lição 4 AE050: ciclo RGB vermelho->verde->azul via PWM
// Cada cor em um pino com ~ (PWM por hardware).
const int PIN_R = 9; // vermelho via 220 ohms
const int PIN_G = 10; // verde via 220 ohms
const int PIN_B = 11; // azul via 220 ohms
void setup() {
pinMode(PIN_R, OUTPUT); // habilita driver de saída
pinMode(PIN_G, OUTPUT); // idem para verde
pinMode(PIN_B, OUTPUT); // idem para azul
}
void loop() {
// 1) vermelho máximo -> transfere para verde
for (int v = 0; v <= 255; v++) { // varre duty 0..100%
analogWrite(PIN_R, 255 - v); // apaga vermelho aos poucos
analogWrite(PIN_G, v); // acende verde aos poucos
analogWrite(PIN_B, 0); // azul apagado nesta rampa
delay(10); // passo visível (~2,5 s por rampa)
}
// 2) verde -> azul
for (int v = 0; v <= 255; v++) {
analogWrite(PIN_G, 255 - v); // apaga verde
analogWrite(PIN_B, v); // acende azul
analogWrite(PIN_R, 0); // vermelho apagado
delay(10);
}
// 3) azul -> vermelho (fecha o ciclo)
for (int v = 0; v <= 255; v++) {
analogWrite(PIN_B, 255 - v); // apaga azul
analogWrite(PIN_R, v); // acende vermelho
analogWrite(PIN_G, 0); // verde apagado
delay(10);
}
}
A tensão média por cor segue o duty:
Resultado esperado: transição suave vermelho→verde→azul→vermelho em loop. Se uma cor não acende, confira resistor e se o pino é realmente PWM (~).
Lição 5: Entradas Digitais com Push-Buttons (INPUT_PULLUP)
A Lição 5 liga dois botões tácteis de 4 pinos (internamente B–C e A–D interligados; só 2 contatos elétricos) para acender/apagar um LED. O botão de cima acende, o de baixo apaga. O segredo é pinMode(pino, INPUT_PULLUP): resistor interno puxa a entrada para HIGH quando solta; ao pressionar, o botão curto-circuita para GND e a leitura vai a LOW (lógica invertida proposital, dispensa resistor externo).
| Item | Qtd |
|---|---|
| Uno + protoboard | 1 cada |
| LED vermelho + 220 Ω | 1 cada |
| Push-buttons 4 pinos | 2 |
| Jumpers M-M | 6 |
| Ligação | Detalhe |
|---|---|
| LED anodo via 220 Ω | D13 (ou D8) como saída |
| LED catodo | GND |
| Botão A (liga) | Pino D2 → GND quando pressionado |
| Botão B (desliga) | Pino D3 → GND quando pressionado |
| Posição na protoboard | Pernas em lados opostos do canal central, senão curto permanente |
// Lição 5 AE050: dois botões ligam/desligam um LED (pull-up interno)
const int ledPin = 13; // saída do LED (via 220 ohms)
const int buttonApin = 2; // botão superior: liga
const int buttonBpin = 3; // botão inferior: desliga
void setup() {
pinMode(ledPin, OUTPUT); // LED como saída
pinMode(buttonApin, INPUT_PULLUP); // entrada com pull-up: solto=HIGH
pinMode(buttonBpin, INPUT_PULLUP); // idem; pressionado=LOW
}
void loop() {
if (digitalRead(buttonApin) == LOW) { // topo pressionado aterra D2
digitalWrite(ledPin, HIGH); // acende o LED
}
if (digitalRead(buttonBpin) == LOW) { // base pressionada aterra D3
digitalWrite(ledPin, LOW); // apaga o LED
}
}
Sem INPUT_PULLUP a entrada flutua e o LED pisca sozinho por ruído. Resultado esperado: topo acende e mantém, base apaga e mantém. Se o botão parece invertido, é o comportamento correto do pull-up (LOW = pressionado).
Lição 6: Oito LEDs com 74HC595 (Serial-para-Paralelo)
A Lição 6 resolve a falta de pinos: 8 LEDs com resistores usando só 3 pinos da Uno via CI 74HC595 (8 memórias de 1 bit, carrega por Data+Clock e copia para saída via Latch). Troca velocidade (500 mil atualizações/s em vez de 8 milhões diretas) por economia de pinos — imperceptível para o olho. A lição ainda prepara terreno para display de 7 segmentos (Lição 13).
Coloque o 595 com o chanfro em U para cima (pino 1 à esquerda do chanfro). Pinos de controle: DS (14) = dados, SH_CP (11) = clock, ST_CP (12) = latch, OE (13, ativo em LOW) ao GND, MR (10) e Vcc (16) em 5 V, GND (8) ao GND. Saídas Q0–Q7 alimentam os 8 LEDs via 220 Ω (anodos para o CI no exemplo do PDF).
| Item | Qtd |
|---|---|
| Uno + protoboard | 1 cada |
| LEDs 5 mm | 8 |
| Resistores 220 Ω | 8 |
| CI 74HC595 | 1 |
| Jumpers M-M | 14 |
| Uno | 74HC595 | Função |
|---|---|---|
| D4 | Pino 14 (DS) | Dado serial |
| D5 | Pino 12 (ST_CP) | Latch (copia para saída) |
| D6 | Pino 11 (SH_CP) | Clock (desloca 1 bit por pulso) |
| 5 V | Pinos 16 (Vcc) e 10 (MR) | Alimentação + reset desligado |
| GND | Pinos 8 (GND) e 13 (OE) | Terra + saídas habilitadas |
// Lição 6 AE050: cascata de 8 LEDs via 74HC595
int latchPin = 5; // ST_CP pino 12: congela/mostra saídas
int clockPin = 6; // SH_CP pino 11: desloca bits
int dataPin = 4; // DS pino 14: bit da vez (HIGH=1, LOW=0)
byte leds = 0; // 8 bits = estado dos 8 LEDs (1=aceso)
void setup() {
pinMode(latchPin, OUTPUT); // controle como saídas
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
}
void loop() {
leds = 0; // apaga padrão
updateShiftRegister(); // envia e mostra
delay(500); // pausa com tudo apagado
for (int i = 0; i < 8; i++) { // acende 0..7 em sequência
bitSet(leds, i); // liga bit i sem mexer nos outros
updateShiftRegister();// reflete no hardware
delay(500); // intervalo visível
}
}
void updateShiftRegister() {
digitalWrite(latchPin, LOW); // abre latch: saídas congeladas
shiftOut(dataPin, clockPin, LSBFIRST, leds); // envia 8 bits, LSB primeiro
digitalWrite(latchPin, HIGH); // fecha latch: copia para Q0-Q7
}
Para apagar um LED use bitClear(leds, i) + updateShiftRegister(). Resultado esperado: LEDs acendem em cascata até todos acesos, apagam e repetem. Se LEDs tremem durante carga, o latch está invertido; se a ordem sai trocada, troque LSBFIRST por MSBFIRST.
Lição 7: Monitor Serial Controlando os 8 LEDs
A Lição 7 reaproveita o circuito da Lição 6 e adiciona a “corda umbilical” USB: o Monitor Serial (lupa no canto da IDE) envia e recebe texto. O Arduino imprime Enter LED Number 0 to 7 or 'x' to clear; você digita 0–7 para acender o LED correspondente ou x para apagar todos, com confirmação de volta (Turned on LED 3, Cleared).
Taxa (baud rate) tem que coincidir nos dois lados (9600 no exemplo). O while (!Serial) só é vital no Leonardo; na Uno o reset automático ao abrir o monitor já sincroniza, mas manter não prejudica.
// Lição 7 AE050: controle dos 8 LEDs via Monitor Serial (base Lição 6)
int latchPin = 5; // ST_CP
int clockPin = 6; // SH_CP
int dataPin = 4; // DS
byte leds = 0; // estado atual
void setup() {
pinMode(latchPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
updateShiftRegister(); // começa apagado
Serial.begin(9600); // abre UART USB a 9600 bps
while (!Serial) { ; } // espera host (Leonardo; inócuo na Uno)
Serial.println("Enter LED Number 0 to 7 or 'x' to clear"); // prompt
}
void loop() {
if (Serial.available()) { // há byte no buffer? senão nada faz
char ch = Serial.read(); // lê 1 caractere e remove do buffer
if (ch >= '0' && ch <= '7') { // dígito válido? (compara código ASCII)
int led = ch - '0'; // converte caractere '3' no número 3
bitSet(leds, led); // marca o bit
updateShiftRegister(); // mostra
Serial.print("Turned on LED "); // confirma em duas partes
Serial.println(led); // println pula linha no fim
}
if (ch == 'x') { // comando limpar
leds = 0; // zera padrão
updateShiftRegister(); // apaga hardware
Serial.println("Cleared"); // confirma
}
}
}
void updateShiftRegister() {
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, leds);
digitalWrite(latchPin, HIGH);
}
Detalhe ASCII: caracteres têm códigos numéricos; '7' - '0' = 7 porque a subtração usa os códigos. Serial.print não pula linha, Serial.println pula — por isso a confirmação sai como Turned on LED 3 em uma linha. Resultado esperado: digitar x 0 3 5 acende 0, 3 e 5 com ecos corretos; x apaga tudo. Se saem hieróglifos, o baud do monitor está diferente de 9600.
Módulo 2 — Luz, Som e Chaveamento de Potência (Lições 8 a 13)
Lição 8: Fotocélula LDR Controlando a Barra de LEDs
A Lição 8 troca o potenciômetro por uma fotocélula (LDR — Light Dependent Resistor: ~50 kΩ no escuro, ~500 Ω no claro) no mesmo barramento de 8 LEDs com 595 das lições anteriores. LDR + resistor fixo de 1 kΩ formam um divisor que converte luz em tensão para o ADC. Luz forte = resistência baixa = divisor “todo para cima”; sombra = resistência alta = divisor “para o GND”.
| Item | Qtd |
|---|---|
| Base Lições 6–7 (Uno + 595 + 8 LEDs) | 1 conjunto |
| Fotocélula LDR | 1 |
| Resistor fixo 1 kΩ | 1 |
| Ligação analógica | Detalhe |
|---|---|
| LDR entre 5 V e A0 | Ramo superior do divisor |
| Resistor 1 kΩ entre A0 e GND | Ramo inferior do divisor |
| Ponto médio (A0) | Tensão proporcional à luz |
A tensão no ponto médio é:
No escuro (), (ADC ~20). No claro (), (ADC ~680). O código mapeia a leitura para 0–8 LEDs com reading / 57 (metade do divisor do potenciômetro, compensando o resistor fixo; 511 já acende tudo e 9 estoura como “todos + folga”).
// Lição 8 AE050: barra de LEDs segue a luz (LDR em A0 + 595)
int latchPin = 5; // ST_CP
int clockPin = 6; // SH_CP
int dataPin = 4; // DS
const int lightPin = A0; // ponto médio do divisor LDR/1k
byte leds = 0;
void setup() {
pinMode(latchPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
}
void loop() {
int reading = analogRead(lightPin); // 0..1023 conforme a luz
int numLEDSLit = reading / 57; // 0..~9 zonas (metade do pot)
if (numLEDSLit > 8) numLEDSLit = 8; // trava no hardware real
leds = 0; // reconstrói padrão
for (int i = 0; i < numLEDSLit; i++) bitSet(leds, i);
updateShiftRegister(); // mostra
delay(100); // estabiliza sem flicker
}
void updateShiftRegister() {
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, leds);
digitalWrite(latchPin, HIGH);
}
Resultado esperado: cobrir a LDR com o dedo apaga a barra; aproximar de lâmpada acende progressivamente. Se inverteu (escuro acende), trocou LDR e resistor de posição — revise o divisor.
Lição 9: Buzzer Ativo (Som com Corrente Contínua)
A Lição 9 gera som com buzzer ativo: capsula com oscilador interno, basta CC que ele apita. Distinção física do kit: com pinos para cima, o passivo mostra placa verde, o ativo é selado com fita preta. O ativo custa mais pelo oscilador embutido; o passivo precisa de onda quadrada de 2–5 kHz gerada pela Uno (Lição 10).
| Item | Qtd |
|---|---|
| Uno R3 | 1 |
| Buzzer ativo 5 V | 1 |
| Jumpers F-M | 2 |
| Ligação | Detalhe |
|---|---|
| Fio positivo (vermelho) | Pino digital (ex.: D8) ou 5 V para teste contínuo |
| Fio negativo (preto) | GND |
// Lição 9 AE050: bipe com buzzer ativo (oscilador interno)
const int buzzerPin = 8; // saída que alimenta o buzzer
void setup() {
pinMode(buzzerPin, OUTPUT); // habilita corrente
}
void loop() {
digitalWrite(buzzerPin, HIGH); // 5 V: oscilador interno apita
delay(500); // meio segundo ligado
digitalWrite(buzzerPin, LOW); // 0 V: silencia
delay(500); // meio segundo desligado
}
Resultado esperado: bipes de ~0,5 s em loop. Silêncio total indica buzzer passivo trocado (precisa de tone(), ver Lição 10) ou polaridade invertida.
Lição 10: Buzzer Passivo e Escala Musical (Do a Dó Agudo com PWM)
A Lição 10 toca 8 notas de 0,5 s (Dó 523 Hz, Ré 587, Mi 659, Fá 698, Sol 784, Lá 880, Si 988, Dó agudo 1047 Hz) com buzzer passivo — sem oscilador, o ar vibra conforme o PWM. Não use analogWrite() (fixo em ~500 Hz, desafina); use tone(pino, freq, dur) que gera onda quadrada na frequência exata. Exige a tabela pitches.h (ver quadro de instalação abaixo).
| Item | Qtd |
|---|---|
| Uno R3 | 1 |
| Buzzer passivo | 1 (placa verde visível) |
| Jumpers F-M | 2 (vermelho D8, preto GND) |
A frequência define a nota; o período é:
Para Lá 880 Hz, . O tone() alterna HIGH/LOW nesse ritmo pelo tempo pedido.
📦 Bibliotecas desta lição:
pitches.h— não é biblioteca do Gerenciador, é uma aba do sketch com a tabela de notas.
- Download: pitches.h oficial (tutorial de referência).
- Instalação: na IDE, com o sketch da Lição 10 aberto, clique em
Nova aba(ouCtrl+Shift+N), nomeie comopitches.h, cole o conteúdo do link e salve na mesma pasta do sketch. O#include "pitches.h"(entre aspas) só compila se a aba estiver junto ao.ino.- Conferência:
Sketch > Mostrar pasta do sketchdeve listar o.inoe opitches.hlado a lado;Verificarcompila semNo such file or directory.
// Lição 10 AE050: escala com buzzer passivo via tone()
#include "pitches.h" // tabela NOTE_C5...; aba criada pelo quadro acima
const int buzzerPin = 8; // sinal (vermelho); preto no GND
// sequência didática da doc: 8 graus de Dó a Dó agudo
int melody[] = {NOTE_C5, NOTE_D5, NOTE_E5, NOTE_F5, NOTE_G5, NOTE_A5, NOTE_B5, NOTE_C6};
int noteDurations[] = {2, 2, 2, 2, 2, 2, 2, 2}; // 2 = semínima relativa
void setup() {
// nada a configurar além do tone sob demanda
}
void loop() {
for (int i = 0; i < 8; i++) { // percorre a escala
int noteDuration = 500; // 0,5 s por nota (doc oficial)
tone(buzzerPin, melody[i], noteDuration); // gera f da nota
delay(noteDuration + 50); // 50 ms de respiro entre notas
}
delay(1000); // 1 s de silêncio antes de repetir a escala
noTone(buzzerPin); // garante silêncio (segurança)
}
Se usar pitches.h, confira o #include entre aspas ou < > conforme a lib instalada. Resultado esperado: escala ascendente nítida repetindo. Som rouco/baixo indica pino sem tone() ou buzzer ativo no lugar (troque as cápsulas).
⚠️ Atenção: buzzer alto perto do ouvido por muito tempo irrita; teste com a cápsula sobre a mesa, não colada ao ouvido.
Lição 11: Chave de Esfera (Tilt / Ball Switch)
A Lição 11 detecta inclinação com chave de esfera SW-520D: cavidade cilíndrica com massa condutiva (esfera; versões antigas usavam mercúrio, chamadas mercury switches). Com a extremidade de polos para baixo, a esfera curto-circuita os polos (chave fechada); ao inclinar, abre. Não tem precisão de acelerômetro, mas comuta potência sozinha, sem circuito extra — ideal para brinquedos, alarmes e interruptores de queda.
| Item | Qtd |
|---|---|
| Uno R3 | 1 |
| Ball switch | 1 |
| Jumpers F-M | 2 |
| Ligação | Detalhe |
|---|---|
| Terminal 1 | D2 com INPUT_PULLUP |
| Terminal 2 | GND |
// Lição 11 AE050: LED acende ao inclinar (ball switch em D2)
const int tiltPin = 2; // chave entre D2 e GND
const int ledPin = 13; // LED L embarcado como indicador
void setup() {
pinMode(tiltPin, INPUT_PULLUP); // solto=HIGH, fechado=LOW
pinMode(ledPin, OUTPUT); // indicador
Serial.begin(9600); // depuração do estado
}
void loop() {
int estado = digitalRead(tiltPin); // HIGH=aberta, LOW=fechada
digitalWrite(ledPin, estado == LOW ? HIGH : LOW); // inclina->acende
Serial.println(estado == LOW ? "INCLINADO" : "NIVELADO");
delay(200); // debounce simples da esfera quicando
}
A esfera quica e gera repiques de milissegundos — o delay(200) e a decisão por nível (não por borda) evitam tremor. Resultado esperado: inclinar além de ~15–30° acende o L e imprime INCLINADO; voltar apaga. Se nunca muda, a chave está travada na horizontal errada ou com perna solta no jumper fêmea.
Lição 12: Relé Eletromecânico com Transistor, Diodo e Motor 6 V
A Lição 12 comuta carga real com relé (chave operada por eletroímã, com isolamento total entre controle e potência; contatos COM/NA/NF). Como a Uno não entrega corrente de bobina nem de motor, o acionamento usa transistor PN2222 como chave low-side, resistor de base 220 Ω e diodo 1N4007 em antiparalelo com a carga indutiva (absorve o pico reverso ao desligar). O motor 6 V vai em fonte externa (módulo de protoboard + adaptador 9 V citados no PDF), nunca só no USB.
| Item | Qtd | Função |
|---|---|---|
| Uno + protoboard | 1 cada | Lógica |
| Relé 5 V | 1 | Contatos COM/NA/NF |
| Transistor PN2222 | 1 | Chave da bobina |
| Diodo 1N4007 | 1 | Flyback (faixa no +) |
| Resistor 220 Ω | 1 | Base do transistor |
| Motor DC 6 V | 1 | Carga no contato do relé |
| Fonte protoboard + adaptador 9 V | 1 cada | Força (GND comum com Uno) |
| Jumpers M-M | 8 | Conforme esquemático da doc |
| Ligação lógica | Detalhe |
|---|---|
| D8 via 220 Ω | Base do PN2222 |
| Emissor PN2222 | GND comum |
| Coletor PN2222 | Bobina do relé + anodo do 1N4007 |
| Outro lado da bobina + catodo 1N4007 (faixa) | 5 V |
| Contato COM | Fonte do motor; NA ao motor conforme doc |
// Lição 12 AE050: relé liga/desliga motor 6 V a cada 2 s
const int relePin = 8; // base do PN2222 via 220 ohms
void setup() {
pinMode(relePin, OUTPUT); // controle da bobina
}
void loop() {
digitalWrite(relePin, HIGH); // satura transistor: bobina atrai, NA fecha
delay(2000); // motor roda 2 s
digitalWrite(relePin, LOW); // corta base: mola abre, motor para
delay(2000); // pausa 2 s
}
Sem o diodo, o pico indutivo (V = L × di/dt) pode matar o transistor e resetar a Uno. Resultado esperado: “clic” do relé alternando com motor girando/parando. Se o relé chia sem comutar, a fonte externa está fraca ou o GND não é comum.
⛔ Perigo: nesta lição use só o motor 6 V do kit nos contatos. Nunca ligue rede 127/220 V no relé deste kit didático sem supervisão qualificada e invólucro isolado.
Lição 13: 74HC595 com Display de 7 Segmentos (0–9)
A Lição 13 junta Lições 6–7: o 595 agora alimenta um display de 7 segmentos (a–g + DP) que conta 9→0. O PDF traz a tabela para catodo comum (troque 1↔0 se o seu for anodo comum). Cada segmento leva 220 Ω em série. Controle: DS→D11, ST_CP (latch)→D8, SH_CP (clock)→D12; Vcc+MR em 5 V; GND+OE ao GND; pinos 3/8 do display ao GND (catodo comum).
| Dígito | dp a b c d e f g (catodo comum) |
|---|---|
| 0 | 0 1 1 1 1 1 1 0 |
| 1 | 0 0 1 1 0 0 0 0 |
| 2 | 0 1 1 0 1 1 0 1 |
| 3 | 0 1 1 1 1 0 0 1 |
| 4 | 0 0 1 1 0 0 1 1 |
| 5 | 0 1 0 1 1 0 1 1 |
| 6 | 0 1 0 1 1 1 1 1 |
| 7 | 0 1 1 1 0 0 0 0 |
| 8 | 0 1 1 1 1 1 1 1 |
| 9 | 0 1 1 1 1 0 1 1 |
| 595 Q | Segmento do display |
|---|---|
| Q0→A (7), Q1→B (6), Q2→C (4), Q3→D (2), Q4→E (1), Q5→F (9), Q6→G (10), Q7→DP (5) |
// Lição 13 AE050: conta 9->0 em display 7-seg via 595 (catodo comum)
int latchPin = 8; // ST_CP pino 12
int clockPin = 12; // SH_CP pino 11
int dataPin = 11; // DS pino 14
// mapas da tabela oficial (bit7=DP ... bit0=G? ordem LSB/Q0=A):
byte tabela[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; // 0-9
void setup() {
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
void loop() {
for (int d = 9; d >= 0; d--) { // contagem regressiva oficial
digitalWrite(latchPin, LOW); // congela
shiftOut(dataPin, clockPin, MSBFIRST, tabela[d]); // envia padrão
digitalWrite(latchPin, HIGH); // mostra
delay(600); // dígito legível
}
}
Se os segmentos saem embaralhados, confira o mapeamento Q→letra pino a pino; se tudo invertido (aceso/apagado trocados), seu display é anodo comum — alimente pinos 3/8 em 5 V e complemente a tabela. Resultado esperado: 9→0 nítido repetindo.
Módulo 3 — Displays e Medição (Lições 14 a 19)
Lição 14: Display de 7 Segmentos de 4 Dígitos (Multiplexação e Persistência)
A Lição 14 expande a 13 para 4 dígitos com apenas um 595 + 4 pinos de seleção de dígito. O truque é a multiplexação temporal: só um dígito é ligado por vez, mas a varredura é tão rápida que a persistência retiniana funde tudo e parecem simultâneos. Em anodo comum o pino comum vai a 5 V; em catodo comum vai ao GND — o PDF usa catodo comum no exemplo.
| Item | Qtd |
|---|---|
| Uno + protoboard | 1 cada |
| Display 4 dígitos | 1 |
| 74HC595 | 1 |
| Resistores 220 Ω | 4 (um por dígito/seleção) |
| Jumpers M-M | 20 (chicote completo) |
A rotina típica: envia segmentos do dígito N via 595, habilita o catodo/anodo de N por ~5 ms, desabilita, avança para N+1. Frequência de quadro:
Acima de ~40 Hz o tremor some para a maioria das pessoas.
// Lição 14 AE050: contador 0-9999 em display 4 dígitos multiplexado
int latchPin = 8; // ST_CP
int clockPin = 12; // SH_CP
int dataPin = 11; // DS
int digitos[] = {2, 3, 4, 5}; // seleção D1..D4 (catodo comum: LOW habilita)
byte tabela[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void setup() {
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
for (int i = 0; i < 4; i++) { // dígitos como saída
pinMode(digitos[i], OUTPUT);
digitalWrite(digitos[i], HIGH); // começa desabilitado (catodo)
}
}
void loop() {
static int valor = 0; // 0..9999
// exibe o mesmo valor por ~200 quadros (tempo legível)
for (int q = 0; q < 200; q++) mostra4(valor);
valor = (valor + 1) % 10000; // incrementa com volta
}
void mostra4(int v) {
int d[4] = {(v / 1000) % 10, (v / 100) % 10, (v / 10) % 10, v % 10};
for (int i = 0; i < 4; i++) { // varre D1..D4
digitalWrite(latchPin, LOW); // congela segmentos
shiftOut(dataPin, clockPin, MSBFIRST, tabela[d[i]]); // padrão
digitalWrite(latchPin, HIGH); // prepara
digitalWrite(digitos[i], LOW); // habilita este dígito
delay(5); // janela de persistência
digitalWrite(digitos[i], HIGH); // desliga antes do próximo (anti-fantasma)
}
}
Resultado esperado: contador subindo legível sem fantasma. Dígito fraco demais indica delay(5) curto ou resistor alto; fantasma indica falta do desligamento entre dígitos.
Lição 15: Servo Motor SG90 (Pulsos de 1–2 ms)
A Lição 15 posiciona um servo de engrenagens com curso de 180°: marrom = GND, vermelho = VCC (5 V), laranja = sinal. A Uno envia trem de pulsos a ~50 Hz; a largura define o ângulo (1 ms ≈ 0°, 1,5 ms ≈ 90°, 2 ms ≈ 180°). A biblioteca Servo abstrai o trem; sem ela seria preciso delayMicroseconds() manual com jitter.
| Item | Qtd |
|---|---|
| Uno R3 | 1 |
| Servo SG90 + cruzetas/parafusos | 1 |
| Jumpers F-M | 2–3 (sinal + alimentação) |
| Fio | Destino |
|---|---|
| Marrom | GND |
| Vermelho | 5 V |
| Laranja | D9 (~, PWM) |
📦 Bibliotecas desta lição:
Servo— embutida na IDE, nada a baixar.
- Instalação: nenhuma. Confira em
Sketch > Incluir BibliotecaqueServoestá listada e emArquivo > Exemplos > Servo > Sweepque o exemplo abre e compila.- Se
Servo.hderNo such file, reinstale o núcleo AVR emFerramentas > Placa > Gerenciador de Placas… > Arduino AVR Boards(ver Lição 1).
// Lição 15 AE050: varredura 0->180->0 do SG90
#include <Servo.h> // embutida na IDE (ver quadro acima)
Servo meuServo; // objeto que gera o trem de pulsos
const int servoPin = 9; // sinal laranja
void setup() {
meuServo.attach(servoPin); // vincula PWM e inicia 50 Hz
}
void loop() {
for (int ang = 0; ang <= 180; ang += 5) { // ida em passos de 5°
meuServo.write(ang); // converte ângulo em largura de pulso
delay(100); // aguarda mecânica acompanhar
}
for (int ang = 180; ang >= 0; ang -= 5) { // volta
meuServo.write(ang);
delay(100);
}
}
Resultado esperado: varredura suave sem estalos. Tremor/estalo indica fonte fraca (USB com motor + LEDs juntos) ou tentativa de passar de 0/180° forçando a trava mecânica — nunca force o eixo com a mão ligado.
Lição 16: Display LCD 1602 (Texto 2x16 com LiquidCrystal)
A Lição 16 liga o alfanumérico 2 linhas × 16 colunas (backlight branco sobre azul, cada caractere em matriz de pixels) e roda o exemplo da lib com pinos trocados para LiquidCrystal lcd(7, 8, 9, 10, 11, 12). Se seu LCD veio sem barra de pinos, solde-a antes. O potenciômetro no pino 3 (VO) ajusta contraste; sem ele o texto fica invisível mesmo com código certo.
| Pino LCD | Nome | Função | Uno (exemplo do curso) |
|---|---|---|---|
| 1 | VSS | Terra | GND |
| 2 | VDD | Lógica | 5 V |
| 3 | VO | Contraste | Cursor do pot (extremos em 5 V/GND) |
| 4 | RS | Registrador (dado/comando) | D7 |
| 5 | R/W | Leitura/escrita | GND (só escrita) |
| 6 | E | Habilita (borda) | D8 |
| 11–14 | D4–D7 | Dados 4 bits | D9–D12 |
| 15–16 | A/K | Backlight | 5 V/GND (via resistor onboard) |
| Item | Qtd |
|---|---|
| Uno + protoboard | 1 cada |
| LCD1602 | 1 |
| Potenciômetro 10 kΩ | 1 |
| Jumpers F-M | 16 |
📦 Bibliotecas desta lição:
LiquidCrystal— embutida na IDE, nada a baixar.
- Instalação: nenhuma. Confira em
Arquivo > Exemplos > LiquidCrystal > HelloWorldque o exemplo abre e compila antes de gravar o código abaixo.
// Lição 16 AE050: hello world + cronômetro no LCD 16x2
#include <LiquidCrystal.h> // embutida na IDE (ver quadro acima)
// RS E D4 D5 D6 D7 — ordem do construtor:
LiquidCrystal lcd(7, 8, 9, 10, 11, 12); // pinagem da doc AE050
void setup() {
lcd.begin(16, 2); // informa geometria 16 colunas x 2 linhas
lcd.print("hello, world!"); // 1ª linha fixa
}
void loop() {
lcd.setCursor(0, 1); // coluna 0, linha 1 (índices começam em 0)
lcd.print(millis() / 1000); // segundos desde o reset
delay(250); // atualiza 4x por segundo sem flicker
}
lcd.begin(16,2) configura o controlador; setCursor(col,lin) posiciona; millis()/1000 conta segundos. Resultado esperado: hello, world! fixo e contador subindo na 2ª linha após girar o pot até o contraste ideal. Só quadrados pretos = contraste no extremo ou lcd.begin faltando; nada aceso = backlight sem 5 V.
💡 Dica: alinhe o LCD no topo da protoboard com fileiras numeradas para contar pinos sem erro; o fio amarelo longo do cursor do pot ao VO é o mais esquecido.
Lição 17: Termômetro com TMP36/Termistor + LCD
A Lição 17 reaproveita a montagem da 16, move jumpers do pot e adiciona sensor de temperatura + LDR de apoio, exibindo temperatura e luz no LCD. O texto oficial usa TMP36 (saída linear 10 mV/°C com 500 mV em 0 °C); o kit também traz NTC 10 kΩ — o código abaixo segue a doc (TMP36 em A0). Aquecer o sensor com o dedo eleva a leitura na hora.
| Item | Qtd |
|---|---|
| Base Lição 16 completa | 1 |
| Sensor TMP36 (ou NTC do kit) | 1 |
| Resistor 10 kΩ (apoio do divisor) | 1 |
| Jumpers extras | conforme layout p93 |
📦 Bibliotecas desta lição:
LiquidCrystal— embutida na IDE (mesma da Lição 16), nada a baixar. Reaproveite a instalação já conferida na Lição 16.
// Lição 17 AE050: termômetro no LCD (TMP36 em A0, base Lição 16)
#include <LiquidCrystal.h> // embutida na IDE (ver Lição 16)
// BS E D4 D5 D6 D7 — anote sua pinagem para manutenção:
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
const int tempPin = A0; // saída do TMP36
void setup() {
lcd.begin(16, 2); // 16x2
}
void loop() {
int tempReading = analogRead(tempPin); // 0..1023
float tempVolts = tempReading * 5.0 / 1024.0; // converte em volts
float tempC = (tempVolts - 0.5) * 100.0; // TMP36: 10 mV/°C, 500 mV em 0°C
float tempF = tempC * 9.0 / 5.0 + 32.0; // conversão C->F
// Reescreve a linha inteira para apagar dígitos fantasmas (101.50->99.00):
lcd.setCursor(0, 0); // 1ª linha
lcd.print("Temp C "); // rótulo + espaços de limpeza
lcd.setCursor(7, 0); // campo numérico
lcd.print(tempC); // valor
lcd.print(" "); // apaga resto da linha
lcd.setCursor(0, 1); // 2ª linha
lcd.print("Temp F "); // rótulo
lcd.setCursor(7, 1);
lcd.print(tempF);
lcd.print(" ");
delay(500); // 2 leituras/s (estável e legível)
}
Cadeia de conversão:
Resultado esperado: ~25 °C ambiente subindo ao encostar o dedo; linhas sem restos de dígitos. Leitura travada em 0 ou 1023 indica sensor sem 5 V/GND ou pino analógico errado.
Lição 18: Sensor Ultrassônico HC-SR04 (2–400 cm)
A Lição 18 mede distância sem contato com o HC-SR04 (transmissor + receptor + controle, precisão ~3 mm). Ritual: pulso de trigger ≥10 µs, o módulo emite 8 ciclos a 40 kHz, levanta o echo pelo tempo de ida-volta. Use ciclo >60 ms para não confundir eco com novo disparo. Com biblioteca dedicada o código encurta; abaixo a versão com pulseIn() + fórmula oficial.
| Item | Qtd |
|---|---|
| Uno R3 | 1 |
| HC-SR04 | 1 |
| Jumpers F-M | 4 |
| HC-SR04 | Uno | Nota |
|---|---|---|
| Vcc | 5 V | Lógica 5 V |
| GND | GND | Comum |
| Trig | D8 (saída) | Pulso de 10 µs |
| Echo | D9 (entrada) | Largura = ida-volta |
Física do tempo de voo com :
Atalhos da doc com em microssegundos:
📦 Bibliotecas desta lição: nenhuma — o código abaixo usa
pulseIn()nativo, sem biblioteca externa. Se a sua IDE oferecerNewPing/Ultrasonicno Gerenciador, ignore para esta lição.
// Lição 18 AE050: trena ultrassônica no Serial (HC-SR04)
const int trigPin = 8; // saída do pulso
const int echoPin = 9; // entrada da largura
void setup() {
pinMode(trigPin, OUTPUT); // trigger como saída
pinMode(echoPin, INPUT); // echo como entrada
Serial.begin(9600); // exibe cm
}
void loop() {
digitalWrite(trigPin, LOW); // garante nível baixo
delayMicroseconds(2); // estabiliza
digitalWrite(trigPin, HIGH); // inicia trigger
delayMicroseconds(10); // 10 us oficiais
digitalWrite(trigPin, LOW); // encerra; módulo emite 8x40 kHz
long t = pulseIn(echoPin, HIGH, 30000); // largura do echo (timeout 30 ms)
float cm = t / 58.0; // fórmula oficial da doc
Serial.print("Distancia: "); // rótulo
Serial.print(cm); // valor
Serial.println(" cm"); // unidade + quebra
delay(100); // >60 ms entre medidas (anti-eco)
}
Resultado esperado: mão a 20 cm lê ~20 cm estável; parede a 2 m lê ~200 cm. Zero fixo = echo sem retorno (alvo absorvente/fino ou timeout); leitura pulando = fonte ruidosa ou intervalo <60 ms.
Lição 19: Teclado Matricial 4x4 (Membrana)
A Lição 19 lê 16 teclas (0–9, A–D, *, #) com só 8 pinos via codificação matricial (4 linhas × 4 colunas varridas por firmware; um teclado linear precisaria de 17 fios). Aplicações: celulares, fechaduras, fornos, fax. Nesta etapa a tecla aparece no Monitor Serial; a integração com LCD fica como exercício guiado.
| Item | Qtd |
|---|---|
| Uno R3 | 1 |
| Teclado membrana 4x4 | 1 (8 vias) |
| Jumpers M-M | 8 |
| Teclado | Uno (exemplo) |
|---|---|
| R1–R4 (linhas) | D9, D8, D7, D6 |
| C1–C4 (colunas) | D5, D4, D3, D2 |
📦 Bibliotecas desta lição:
Keypadpor Mark Stanley, Alexander Brevig (versão 3.1.1).
- Via Gerenciador (recomendado):
Sketch > Incluir Biblioteca > Gerenciar Bibliotecas…→ buscarKeypad→ selecionar3.1.1→Instalar→ reiniciar a IDE.- Via ZIP: baixar em Chris—A/Keypad (
Code > Download ZIP) →Sketch > Incluir Biblioteca > Adicionar Biblioteca .ZIP…→ reiniciar a IDE.- Conferência:
Arquivo > Exemplos > Keypad > HelloKeypaddeve abrir e compilar semNo such file or directory.
// Lição 19 AE050: ecoa teclas 4x4 no Serial (lib Keypad)
#include <Keypad.h> // instalada pelo quadro acima
const byte LINHAS = 4; // 4 linhas
const byte COLS = 4; // 4 colunas
char teclas[LINHAS][COLS] = { // mapa impresso na membrana
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte pinLinhas[LINHAS] = {9, 8, 7, 6}; // R1..R4
byte pinCols[COLS] = {5, 4, 3, 2}; // C1..C4
Keypad teclado = Keypad(makeKeymap(teclas), pinLinhas, pinCols, LINHAS, COLS);
void setup() {
Serial.begin(9600); // exibe tecla
Serial.println("Pressione uma tecla..."); // prompt
}
void loop() {
char k = teclado.getKey(); // varre matriz; 0 se nada
if (k) { // tecla nova detectada (com debounce interno)
Serial.print("Tecla: "); // rótulo
Serial.println(k); // caractere pressionado
}
}
Resultado esperado: cada pressão imprime uma vez. Repetição fantasma indica membrana mal encaixada ou pinos de linha/coluna trocados no makeKeymap.
Módulo 4 — Ambiente, Movimento e Sem Fio (Lições 20 a 25)
Lição 20: DHT11 — Temperatura e Umidade Digital
A Lição 20 usa o DHT11 (sensor composto calibrado com NTC + elemento resistivo de umidade + microcontrolador interno) para temperatura e umidade com precisão suficiente para climatização didática. A biblioteca dedicada encurta o protocolo 1-wire temporizado (pulsos de ~20–80 µs que delay() quebraria). Respeite o intervalo mínimo de ~2 s entre leituras — o sensor precisa estabilizar o capacitor higroscópico.
| Item | Qtd |
|---|---|
| Uno R3 | 1 |
| Módulo DHT11 (3 pinos: VCC/DATA/GND) | 1 |
| Jumpers F-M | 3 |
| DHT11 | Uno |
|---|---|
| VCC | 5 V |
| DATA | D2 (com pull-up; módulo já traz) |
| GND | GND |
📦 Bibliotecas desta lição:
DHT sensor librarypor Adafruit (versão 1.4.7) + dependência obrigatóriaAdafruit Unified Sensor.
- Via Gerenciador (recomendado):
Sketch > Incluir Biblioteca > Gerenciar Bibliotecas…→ buscarDHT sensor library→Instalar(aceitar instalar as dependências quando a IDE oferecerAdafruit Unified Sensor) → buscarAdafruit Unified Sensore confirmar instalada → reiniciar a IDE.- Via ZIP: adafruit/DHT-sensor-library + adafruit/Adafruit_Sensor (
Code > Download ZIPem cada) →Adicionar Biblioteca .ZIP…uma por vez → reiniciar a IDE.- Conferência:
Arquivo > Exemplos > DHT sensor library > DHTtesterdeve abrir e compilar. Sem o Unified Sensor o erro éAdafruit_Sensor.h: No such file or directory.
// Lição 20 AE050: DHT11 no Serial (2 s entre leituras)
#include <DHT.h> // instalada pelo quadro acima (com Unified Sensor)
#define DHTPIN 2 // DATA
#define DHTTYPE DHT11 // variante do kit (não DHT22)
DHT dht(DHTPIN, DHTTYPE); // objeto do sensor
void setup() {
Serial.begin(9600); // exibe
dht.begin(); // inicia temporização do protocolo
}
void loop() {
delay(2000); // janela mínima oficial do DHT11
float h = dht.readHumidity(); // %UR
float t = dht.readTemperature(); // °C (false=F)
if (isnan(h) || isnan(t)) { // falha de checksum/tempo?
Serial.println("Falha DHT11: confira fiação e 2 s"); // diagnostica
return; // tenta na próxima janela
}
Serial.print("Umidade: "); // rótulos
Serial.print(h);
Serial.print(" % | Temp: ");
Serial.print(t);
Serial.println(" C");
}
Resultado esperado: ~50 %UR / ~25 °C em ambiente, subindo ao soprar. NaN persistente = DATA em pino errado, intervalo <2 s ou módulo 3,3 V sem VCC adequado.
Lição 21: Joystick Analógico (X, Y + Chave Z)
A Lição 21 adiciona controle manual com o módulo joystick (2 potenciômetros + chave táctil do botão): 5 pinos (Vcc, GND, X, Y, Key/SW). O manche é analógico de verdade (0–1023 por eixo, centro ~512), superior aos direcionais de contato seco para robôs e menus.
| Item | Qtd |
|---|---|
| Uno R3 | 1 |
| Joystick XY+Key | 1 |
| Jumpers F-M | 5 |
| Joystick | Uno |
|---|---|
| Vcc | 5 V |
| GND | GND |
| VRx (X) | A0 |
| VRy (Y) | A1 |
| SW (Key) | D2 (INPUT_PULLUP, aperta=GND) |
// Lição 21 AE050: lê X, Y e botão do joystick
const int pinX = A0; // horizontal 0..1023
const int pinY = A1; // vertical 0..1023
const int pinKey = 2; // aperta=LOW
void setup() {
pinMode(pinKey, INPUT_PULLUP); // chave sem resistor externo
Serial.begin(9600); // exibe
}
void loop() {
int x = analogRead(pinX); // posição H
int y = analogRead(pinY); // posição V
int k = digitalRead(pinKey); // botão
Serial.print("X="); // telemetria compacta
Serial.print(x);
Serial.print(" Y=");
Serial.print(y);
Serial.print(" Key=");
Serial.println(k == LOW ? "PRESS" : "SOLTO"); // decodifica pull-up
delay(200); // legível sem flood
}
Centro ideal:
com tolerância de ±50 por mecânica. Resultado esperado: solto ~512/512 SOLTO; cantos 0/1023; apertar imprime PRESS. Deriva grande indica Vcc fraco ou potenciômetro gasto.
Lição 22: Receptor IR e Controle Remoto (NEC, 38 kHz)
A Lição 22 dá controle sem fio com receptor AX-1838HS (fotodiodo + pré-amplificador sintonizado em 38 kHz) e controle de 21 teclas. A lib IRremote decodifica o protocolo NEC (endereço + comando + repetição ao segurar). O sketch lista os hex de cada tecla, sinaliza código reconhecido e repetição.
| Item | Qtd |
|---|---|
| Uno R3 | 1 |
| Receptor IR (3 pinos) | 1 |
| Controle IR | 1 (bateria inclusa no kit) |
| Jumpers F-M | 3 |
| IR | Uno |
|---|---|
| VCC (ou +) | 5 V |
| GND (−) | GND |
| OUT (S) | D11 (pino de interrupção da lib) |
📦 Bibliotecas desta lição:
IRremotepor shirriff, z3t0, ArminJo — fixar a versão 2.8.1 (linha 2.x).
- Via Gerenciador (recomendado):
Sketch > Incluir Biblioteca > Gerenciar Bibliotecas…→ buscarIRremote→ no menu de versões escolher2.8.1→Instalar→ reiniciar a IDE.- Via ZIP: Arduino-IRremote — Releases → baixar o ZIP da
2.8.1→Sketch > Incluir Biblioteca > Adicionar Biblioteca .ZIP…→ reiniciar a IDE.- Conferência:
Arquivo > Exemplos > IRremote > IRrecvDemodeve abrir e compilar.⚠️ Atenção: NÃO instale a
IRremote3.x/4.x aqui — ela removeIRrecv/decode_results/results.valueusados no código abaixo e a compilação falha. Se já instalou a nova, volte ao Gerenciador, selecione2.8.1eInstalar.
// Lição 22 AE050: decodifica NEC e exibe hex (lib IRremote 2.x)
#include <IRremote.h> // versão 2.8.1 instalada pelo quadro acima
const int RECV_PIN = 11; // OUT do receptor
IRrecv irrecv(RECV_PIN); // objeto receptor
decode_results results; // quadro decodificado
void setup() {
Serial.begin(9600); // exibe hex
irrecv.enableIRIn(); // liga timer de captura 38 kHz
Serial.println("Aponte o controle e pressione..."); // prompt
}
void loop() {
if (irrecv.decode(&results)) { // quadro completo?
Serial.print("HEX=0x"); // prefixo
Serial.print(results.value, HEX); // código NEC
Serial.print(" bits=");
Serial.print(results.bits); // normalmente 32
if (results.value == 0xFFFFFFFF) Serial.print(" (REPETE)"); // segurar tecla
Serial.println(); // fecha linha
irrecv.resume(); // rearma para o próximo quadro
}
}
Mire o controle para o receptor a <5 m sem luz solar direta (sol satura o fotodiodo). Resultado esperado: cada tecla um hex estável; segurar gera 0xFFFFFFFF. Nada chegando = OUT em pino sem suporte da versão da lib, bateria do controle fraca ou receptor invertido (VCC/GND trocados aquecem — desligue e confira).
💡 Dica: anote os hex do SEU controle em tabela — eles variam por lote e serão reutilizados na Lição 32 para dirigir o passo.
Lição 23: Matriz 8x8 com MAX7219 (Texto Deslizante com 3 Pinos)
A Lição 23 acende 64 LEDs com 3 pinos via driver MAX7219 (registradores + varredura multiplexada interna + controle de brilho). A lib (LedControl/MaxMatrix) abstrai SPI por software (DIN/CS/CLK). Encadear módulos é só ligar DOUT→DIN do próximo.
| Item | Qtd |
|---|---|
| Uno R3 | 1 |
| Matriz MAX7219 8x8 | 1 |
| Jumpers F-M | 5 (VCC/GND/DIN/CS/CLK) |
| MAX7219 | Uno |
|---|---|
| VCC | 5 V |
| GND | GND |
| DIN | D12 |
| CS | D11 |
| CLK | D10 |
📦 Bibliotecas desta lição:
LedControlpor Eberhard Fahle (versão 1.0.6).
- Via Gerenciador (recomendado):
Sketch > Incluir Biblioteca > Gerenciar Bibliotecas…→ buscarLedControl→Instalar→ reiniciar a IDE.- Via ZIP: baixar em wayoda/LedControl (
Code > Download ZIP) →Adicionar Biblioteca .ZIP…→ reiniciar a IDE.- Conferência:
Arquivo > Exemplos > LedControl > LCDemoMatrixdeve abrir e compilar semNo such file or directory.
// Lição 23 AE050: texto deslizante na 8x8 (LedControl)
#include <LedControl.h> // instalada pelo quadro acima
LedControl lc = LedControl(12, 10, 11, 1); // DIN,CLK,CS, 1 módulo
void setup() {
lc.shutdown(0, false); // sai do modo economia
lc.setIntensity(0, 8); // brilho 0..15 (8 = meio)
lc.clearDisplay(0); // limpa
}
void loop() {
// varre coluna acesa como teste de varredura (base do scroll)
for (int col = 0; col < 8; col++) {
lc.clearDisplay(0); // apaga quadro anterior
for (int row = 0; row < 8; row++) lc.setLed(0, row, col, true); // coluna
delay(150); // velocidade legível
}
// Para texto real, use os exemplos Font/Scroll da lib com a mesma fiação.
}
Brilho via corrente multiplexada — subir setIntensity acima de 12 com USB fraco causa flicker por queda de 5 V. Resultado esperado: coluna varrendo suave; exemplos de scroll exibem letras deslizantes. Matriz apagada = CS/CLK trocados ou shutdown esquecido.
Lição 24: Acelerômetro ADXL335 (3 Eixos, Alimentar em 3,3 V)
A Lição 24 mede aceleração/inclinação com ADXL335 (MEMS capacitivo, 3 saídas analógicas X/Y/Z, faixa ±3 g, alimentação 1,8–3,6 V, 22×23 mm). Aviso oficial em caixa alta: não alimente pela Uno em 5 V — use o pino 3V. 5 V perfura o MEMS e mata o módulo.
| Item | Qtd |
|---|---|
| Uno R3 | 1 |
| ADXL335 | 1 |
| Jumpers F-M | 6–7 (VCC 3V3/GND/X/Y/Z + ST opcional) |
| ADXL335 | Uno | Alerta |
|---|---|---|
| VCC | 3,3 V (nunca 5 V) | Limite 3,6 V |
| GND | GND | Comum |
| X / Y / Z | A0 / A1 / A2 | 0–3,3 V (ADC ~0–675) |
| ST | — | Autoteste, deixar solto |
Conversão com referência 3,3 V externa (ou correção proporcional em 5 V):
// Lição 24 AE050: lê XYZ do ADXL335 alimentado em 3V3
const int pinX = A0; // saídas analógicas
const int pinY = A1;
const int pinZ = A2;
void setup() {
Serial.begin(9600); // exibe g
}
void loop() {
int ax = analogRead(pinX); // contagens 0..1023 (fundo 5 V)
int ay = analogRead(pinY);
int az = analogRead(pinZ);
// Converte para volts e depois g (zero-g ~1,65 V, sens ~0,30 V/g):
float vx = ax * 5.0 / 1023.0; // tensão lida
float vy = ay * 5.0 / 1023.0;
float vz = az * 5.0 / 1023.0;
float gx = (vx - 1.65) / 0.30; // aceleração por eixo
float gy = (vy - 1.65) / 0.30;
float gz = (vz - 1.65) / 0.30;
Serial.print("g: "); // telemetria
Serial.print(gx); Serial.print(" ");
Serial.print(gy); Serial.print(" ");
Serial.println(gz);
delay(250); // 4 Hz legível
}
Parado na mesa espera-se (gravidade) e . Resultado esperado: inclinar troca o vetor; girar 90° transfere 1 g de eixo. Saturado em 1023 = alimentou em 5 V (desligue e confira antes que queime).
⛔ Perigo: 5 V no VCC do ADXL335 danifica o sensor. Confira o jumper no pino
3V3da Uno antes de energizar.
Lição 25: PIR HC-SR501 (Presença com Pi rental e Fresnel)
A Lição 25 acende LED ao detectar gente com PIR (piroelétrico diferencial + lente de Fresnel que fatiava o ambiente em zonas; passar entre zonas gera o pulso). A Uno “escuta” o pino OUT e comanda o LED. Dois trimpots: sensibilidade (alcance 3–7 m) e tempo (duração do HIGH, segundos a minutos); jumper de retrigger define se novo movimento estende o pulso.
| Item | Qtd |
|---|---|
| Uno R3 | 1 |
| HC-SR501 | 1 |
| Jumpers F-M | 3 |
| LED + 220 Ω (opcional p/ teste) | 1 cada |
| PIR | Uno |
|---|---|
| VCC | 5 V |
| OUT | D2 |
| GND | GND |
// Lição 25 AE050: LED segue presença (PIR em D2)
const int pirPin = 2; // OUT do HC-SR501
const int ledPin = 13; // indicador L
void setup() {
pinMode(pirPin, INPUT); // sensor já entrega nível lógico
pinMode(ledPin, OUTPUT);
Serial.begin(9600); // log de eventos
Serial.println("Aguarde 30-60 s (calibracao do PIR)..."); // estabiliza
delay(1000); // a estabilização real é esperar parado
}
void loop() {
int mov = digitalRead(pirPin); // HIGH=movimento na janela de tempo
digitalWrite(ledPin, mov); // espelha no LED
if (mov) Serial.println("Movimento!"); // loga só evento
delay(200); // evita flood
}
Aguarde 30–60 s parado após energizar (o piroelétrico calibra o fundo térmico). Resultado esperado: atravessar a sala acende o L pelo tempo ajustado; parado apaga. Disparo contínuo indica sensibilidade no máximo, corrente de ar quente ou sensor encarando janela/sol.
Módulo 5 — Tempo, Água, Som, RFID e Potência DC (Lições 26 a 30)
Lição 26: Sensor de Nível de Água (Trilhas Pectinadas + Amplificador)
A Lição 26 percebe profundidade com módulo de trilhas pectinadas em PCB + transistor amplificador: imerso, as trilhas apresentam resistência que cai com a área molhada; o transistor converte em sinal elétrico para o ADC. Saída analógica (nível proporcional) e digital (limiar via comparador, quando houver). Leitura é relativa (calibre vazio/cheio no seu copo), não milímetros absolutos sem calibração.
| Item | Qtd |
|---|---|
| Uno R3 | 1 |
| Sensor de nível (placa pectinada + módulo) | 1 |
| Jumpers F-M | 3–4 |
| Sensor | Uno | Uso |
|---|---|---|
| VCC (+) | 5 V | Alimenta amplificador |
| GND (−) | GND | Comum |
| AO (analógica) | A0 | Nível 0–1023 |
| DO (digital, se houver) | D2 | Alarme de limiar |
// Lição 26 AE050: nível de água em A0 com alarme em D2 (opcional)
const int aguaAO = A0; // proporcional à área molhada
const int aguaDO = 2; // limiar (se o módulo tiver)
const int ledPin = 13; // alarme visual
void setup() {
pinMode(aguaDO, INPUT); // comparador já entrega nível
pinMode(ledPin, OUTPUT);
Serial.begin(9600); // exibe 0..1023
}
void loop() {
int nivel = analogRead(aguaAO); // seco~0, imerso sobe
int alarme = digitalRead(aguaDO); // HIGH/LOW conforme trimpot
Serial.print("Nivel ADC="); // telemetria
Serial.print(nivel);
Serial.print(" DO=");
Serial.println(alarme);
digitalWrite(ledPin, alarme == HIGH ? HIGH : LOW); // espelha limiar
delay(300); // água oscila; filtra no tempo
}
Relação aproximada (calibrar nos seus marcos):
onde é a altura molhada. Resultado esperado: seco ~0–50, meio copo ~300–500, fundo ~600+. Oxidação das trilhas com semanas de imersão contínua deriva a leitura — use só durante o teste e seque após (e nunca no mesmo copo de água potável da bancada eletrônica sem higiene).
⚠️ Atenção: sensor de nível é para água limpa fria em recipiente plástico. Não use com líquidos inflamáveis, condutivos agressivos ou rede elétrica por perto.
Lição 27: Relógio de Tempo Real DS3231 (I2C com Bateria de Backup)
A Lição 27 mantém ano/mês/dia/hora/min/seg/dia-da-semana com DS3231 (oscilador TCXO compensado, deriva de segundos por mês) e bateria que segura o tempo desligado, com carregador de trickle. Fiação é só I2C: SDA/SCL + VCC/GND (“três cabos de dados” na tradução da doc contam SDA/SCL + referência). A doc cita DS1302/DS3231 lado a lado — o procedimento abaixo usa o DS3231 do kit com RTClib.
| Item | Qtd |
|---|---|
| Uno R3 | 1 |
| DS3231 com bateria | 1 |
| Jumpers F-M | 4 |
| DS3231 | Uno (I2C hardware) |
|---|---|
| VCC | 5 V (ou 3,3 V conforme módulo) |
| GND | GND |
| SDA | A4 |
| SCL | A5 |
📦 Bibliotecas desta lição:
RTClibpor Adafruit +Wire(embutida, I2C em A4/A5).
- Via Gerenciador (recomendado):
Sketch > Incluir Biblioteca > Gerenciar Bibliotecas…→ buscarRTClib→Instalar(aWirejá vem na IDE, nada a fazer) → reiniciar a IDE.- Via ZIP: baixar em adafruit/RTClib (
Code > Download ZIP) →Adicionar Biblioteca .ZIP…→ reiniciar a IDE.- Conferência:
Arquivo > Exemplos > RTClib > ds3231deve abrir e compilar semNo such file or directory.
// Lição 27 AE050: relógio DS3231 via I2C (RTClib)
#include <Wire.h> // embutida na IDE (I2C em A4/A5 na Uno)
#include <RTClib.h> // instalada pelo quadro acima
RTC_DS3231 rtc; // objeto do relógio
void setup() {
Serial.begin(9600); // exibe data/hora
Wire.begin(); // inicia I2C como mestre
if (!rtc.begin()) { // DS3231 respondeu?
Serial.println("DS3231 nao encontrado: confira SDA=A4 SCL=A5"); // diagnostica
while (1) { ; } // trava para corrigir fiação
}
if (rtc.lostPower()) { // bateria descarregada ou 1º uso?
rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // acerta com hora da compilação
Serial.println("RTC ajustado com hora da compilacao"); // informa
}
}
void loop() {
DateTime agora = rtc.now(); // lê 7 registradores de uma vez
Serial.print(agora.day()); // DD/MM/AAAA HH:MM:SS
Serial.print('/');
Serial.print(agora.month());
Serial.print('/');
Serial.print(agora.year());
Serial.print(' ');
Serial.print(agora.hour());
Serial.print(':');
Serial.print(agora.minute());
Serial.print(':');
Serial.println(agora.second());
delay(1000); // 1 Hz
}
Ajuste uma vez e comente o rtc.adjust() nas próximas gravações, senão toda recompilação atrasa o relógio para a hora antiga do build. Resultado esperado: carimbo subindo a cada segundo e sobrevivendo a reset (bateria). DS3231 não encontrado = SDA/SCL trocados ou VCC errado.
Lição 28: Sensor de Som com LM393 (AO Proporcional + DO com Limiar)
A Lição 28 capta som com microfone de eletreto + amplificador + comparador LM393 com trimpot: AO entrega a envoltória analógica em tempo real; DO vira nível digital quando o pico supera o limiar (sensibilidade no potenciômetro). Ideal para palmas que disparam eventos (com debounce) ou VU-meter no Serial Plotter.
| Item | Qtd |
|---|---|
| Uno R3 | 1 |
| Sensor de som (AO/DO/GND/VCC) | 1 |
| Jumpers F-M | 4 (VCC/GND/AO/DO) |
| Sensor | Uno |
|---|---|
| VCC | 5 V |
| GND | GND |
| AO | A0 |
| DO | D2 |
// Lição 28 AE050: VU analógico + gatilho digital de palma
const int somAO = A0; // envoltória 0..1023
const int somDO = 2; // limiar (trimpot)
const int ledPin = 13; // pisca na palma
void setup() {
pinMode(somDO, INPUT); // comparador entrega nível
pinMode(ledPin, OUTPUT);
Serial.begin(9600); // VU no Plotter
}
void loop() {
int env = analogRead(somAO); // volume instantâneo
int gatilho = digitalRead(somDO); // HIGH/LOW vs limiar
Serial.println(env); // uma coluna: use Serial Plotter (Ferramentas)
if (gatilho == HIGH) { // pico acima do trimpot?
digitalWrite(ledPin, HIGH); // sinaliza
delay(150); // janela anti-repicada da palma
digitalWrite(ledPin, LOW);
}
delay(20); // ~50 amostras/s
}
Calibre o trimpot até o LED de bordo do módulo piscar só na palma (não no ruído da sala). Resultado esperado: Plotter sobe na fala/palma; DO dispara limpo. AO saturado em 1023 = ganho máximo + ambiente ruidoso; DO sempre HIGH = limiar baixo demais.
Lição 29: RFID RC522 a 13,56 MHz (SPI com MIFARE)
A Lição 29 lê cartões/tags sem contato com MFRC522 (transmissor 13,56 MHz, modo ISO14443A/MIFARE) via SPI de hardware. O leitor conversa com Uno, Raspberry Pi ou Beagle por SDA(SS)/SCK/MOSI/MISO/RST. Alimentação lógica é 3,3 V no módulo do kit — 5 V no VCC queima o front-end de RF.
| Item | Qtd |
|---|---|
| Uno R3 | 1 |
| RC522 + cartão + tag | 1 kit |
| Jumpers F-M | 7 |
| RC522 | Uno | Barramento |
|---|---|---|
| VCC | 3,3 V (nunca 5 V) | Força RF |
| GND | GND | Comum |
| RST | D9 | Reset |
| SDA (SS) | D10 | Seleção SPI |
| MOSI | D11 | SPI hardware |
| MISO | D12 | SPI hardware |
| SCK | D13 | SPI hardware |
📦 Bibliotecas desta lição:
MFRC522por GithubCommunity (versão 1.4.12) +SPI(embutida, D11–D13).
- Via Gerenciador (recomendado):
Sketch > Incluir Biblioteca > Gerenciar Bibliotecas…→ buscarMFRC522→Instalar(aSPIjá vem na IDE) → reiniciar a IDE.- Via ZIP: baixar em miguelbalboa/rfid (
Code > Download ZIP) →Adicionar Biblioteca .ZIP…→ reiniciar a IDE.- Conferência:
Arquivo > Exemplos > MFRC522 > DumpInfodeve abrir e compilar semNo such file or directory.
// Lição 29 AE050: imprime UID do cartão/tag (MFRC522)
#include <SPI.h> // embutida na IDE (D11-D13 na Uno)
#include <MFRC522.h> // instalada pelo quadro acima
#define SS_PIN 10 // SDA/SS
#define RST_PIN 9 // reset
MFRC522 rfid(SS_PIN, RST_PIN); // objeto do leitor
void setup() {
Serial.begin(9600); // exibe UID
SPI.begin(); // inicia SPI hardware
rfid.PCD_Init(); // inicializa MFRC522
Serial.println("Aproxime cartao ou tag..."); // prompt
}
void loop() {
if (!rfid.PICC_IsNewCardPresent()) return; // sem campo? volta
if (!rfid.PICC_ReadCardSerial()) return; // falhou CRC? volta
Serial.print("UID:"); // imprime bytes em HEX
for (byte i = 0; i < rfid.uid.size; i++) {
Serial.print(rfid.uid.uidByte[i] < 0x10 ? " 0" : " "); // zero à esquerda
Serial.print(rfid.uid.uidByte[i], HEX); // byte
}
Serial.println(); // fecha linha
rfid.PICC_HaltA(); // encerra sessão (tira do campo)
delay(500); // evita releitura colada
}
Aproxime a 0–3 cm, paralelo à antena. Resultado esperado: UID estável por cartão (ex.: UID: 83 1A 2B 3C). Nada lê = VCC em 5 V (corrija antes de queimar), SPI com jumpers longos/frouxos ou tag fora do campo.
⛔ Perigo: confira
3V3antes de energizar o RC522. Inversão VCC/GND aquece o módulo em segundos.
Lição 30: Motor DC com Transistor PN2222 e Diodo Flyback
A Lição 30 controla o mini DC 6 V com a Uno sem queimar o pino: o digital não entrega corrente de partida, então o PN2222 faz o chaveamento low-side (base via 220 Ω, emissor ao GND, coletor ao motor), o 1N4007 em antiparalelo absorve o pico indutivo, e a velocidade sai por PWM. É a mesma célula de potência da Lição 12, agora com velocidade variável em vez de relé.
| Item | Qtd |
|---|---|
| Uno + protoboard | 1 cada |
| Motor DC 6 V | 1 |
| PN2222 + 1N4007 + 220 Ω | 1 cada |
| Fonte externa (protoboard/9 V) | 1 (GND comum) |
| Jumpers M-M | 3 + força |
| Ligação | Detalhe |
|---|---|
D9 (~) via 220 Ω | Base do PN2222 |
| Emissor | GND comum |
| Coletor | Motor (−) + anodo 1N4007 |
| Motor (+) + catodo 1N4007 (faixa) | 5–6 V externos |
| GND externo | GND da Uno (obrigatório) |
A corrente de base necessária para saturar:
Com de partida e , ; os 220 Ω entregam ~20 mA, saturando com folga. Velocidade por duty:
// Lição 30 AE050: rampa de velocidade do DC via PWM (PN2222)
const int motorPin = 9; // base via 220 ohms (PWM ~)
void setup() {
pinMode(motorPin, OUTPUT); // chave low-side
}
void loop() {
for (int v = 0; v <= 255; v += 5) { // acelera
analogWrite(motorPin, v); // duty 0->100%
delay(50); // rampa suave (~2,5 s)
}
delay(1000); // 1 s no máximo
for (int v = 255; v >= 0; v -= 5) { // desacelera
analogWrite(motorPin, v);
delay(50);
}
delay(1000); // 1 s parado (resfria/observa)
}
Sem o diodo o pico (V = L × di/dt) frita o transistor e reseta a Uno a cada desligada. Resultado esperado: rampa audível subindo/descendo sem resets. Motor parado com chiado = PWM baixo sem torque de partida (parta de ~30 %); reset ao desligar = diodo invertido/ausente ou GND não comum.
Módulo 6 — Movimento de Precisão (Lições 31 a 33)
Lição 31: Motor de Passo 28BYJ-48 com Driver ULN2003 (4 Fases, Redução 1:64)
A Lição 31 aciona o passo unipolar 28BYJ-48 5 V com sua plaquinha ULN2003 (array Darlington com diodos de flyback integrados e LEDs de fase). É o motor didático ideal: barato, com redução interna 1:64 que multiplica torque e resolução, embora limite velocidade e força absoluta. O modo de onda completa do exemplo energiza 2 fases por vez em sequência de 4 passos elétricos; a redução transforma cada passo elétrico em fração minúscula no eixo de saída — 2048 passos por volta no modo do kit.
| Item | Qtd |
|---|---|
| Uno R3 | 1 |
| 28BYJ-48 5 V + placa ULN2003 | 1 conjunto |
| Jumpers F-M | 4–5 (IN1–IN4 + VCC/GND) + USB para lógica |
| ULN2003 | Uno | Fase |
|---|---|---|
| IN1 | D8 | Bobina A |
| IN2 | D9 | Bobina B |
| IN3 | D10 | Bobina C |
| IN4 | D11 | Bobina D |
| VCC / GND da placa | 5 V / GND (USB aguenta o teste curto; carga mecânica pede fonte externa) | Força das bobinas |
Sequência de onda completa (1 = fase energizada):
| Passo | IN1 | IN2 | IN3 | IN4 |
|---|---|---|---|---|
| 1 | 1 | 1 | 0 | 0 |
| 2 | 0 | 1 | 1 | 0 |
| 3 | 0 | 0 | 1 | 1 |
| 4 | 1 | 0 | 0 | 1 |
Ângulo por passo no eixo de saída com 2048 passos/volta:
📦 Bibliotecas desta lição:
Stepper— embutida na IDE, nada a baixar.
- Instalação: nenhuma. Confira em
Arquivo > Exemplos > Stepper > stepper_oneRevolutionque o exemplo abre e compila.
// Lição 31 AE050: 28BYJ-48 gira 1 volta CW e 1 CCW (meio passo simplificado)
#include <Stepper.h> // embutida na IDE (ver quadro acima)
const int PASSOS_POR_VOLTA = 2048; // redução 1:64 do kit
// Ordem dos pinos define a sequência de fases (IN1..IN4):
Stepper passo(PASSOS_POR_VOLTA, 8, 10, 9, 11); // embaralha 9/10 p/ sequência correta
void setup() {
passo.setSpeed(10); // 10 rpm (28BYJ não passa muito disso com torque)
Serial.begin(9600); // log
}
void loop() {
Serial.println("CW 1 volta..."); // horária
passo.step(PASSOS_POR_VOLTA); // +2048 passos
delay(500); // pausa mecânica
Serial.println("CCW 1 volta..."); // anti-horária
passo.step(-PASSOS_POR_VOLTA); // -2048 passos
delay(500);
}
A ordem 8, 10, 9, 11 (e não 8, 9, 10, 11) casa a lib com a trilha da placa ULN2003 do kit — com ordem errada o motor vibra parado. Velocidade acima de ~15 rpm perde passos com carga. Resultado esperado: 1 volta CW, pausa, 1 volta CCW, LEDs da placa piscando em sequência. Vibração sem giro = sequência errada ou 1 fio solto; giro fraco = USB no limite (passe para fonte externa com GND comum).
💡 Dica: marque o eixo com fita crepe em bandeira para contar a volta visualmente. Sem referência visual, 2048 micropassos parecem “não sair do lugar”.
Lição 32: Passo com Controle Remoto IR (Potência Separada + Lógica IR)
A Lição 32 dirige o mesmo 28BYJ-48 à distância com o controle da Lição 22. Arquitetura correta: lógica IR direto na Uno (consome quase nada) + força do motor em fonte de protoboard com 9 V/1 A (o USB do PC não sustenta bobinas + IR + LEDs sem cair). Terra comum obrigatório entre fonte e Uno, senão o ULN2003 flutua. Reutilize os hex anotados na Lição 22 para frente/trás/para/velocidade.
| Item | Qtd |
|---|---|
| Base Lição 31 (Uno + 28BYJ + ULN2003) | 1 |
| Receptor IR + controle | 1 cada |
| Fonte protoboard + adaptador 9 V/1 A | 1 cada |
| Jumpers | Força + sinal IR |
| Receptor IR | Uno |
|---|---|
| VCC | 5 V |
| GND | GND comum com fonte externa |
| OUT | D2 (interrupção da IRremote) |
| ULN2003 | Uno/Fonte |
|---|---|
| IN1–IN4 | D8–D11 (lógica) |
| VCC placa | 5 V da fonte de protoboard (não do USB em carga) |
| GND placa | GND comum (Uno + fonte) |
📦 Bibliotecas desta lição:
Stepper(embutida, já conferida na Lição 31) +IRremote2.8.1 (mesma da Lição 22).
- Instalação: nenhuma ação nova se as Lições 22 e 31 já compilam. Se
IRremote.hderNo such file, repetir o quadro da Lição 22 fixando a versão2.8.1— NÃO usar 3.x/4.x com este código.
// Lição 32 AE050: passo obedece setas do controle IR (fonte externa no motor)
#include <Stepper.h> // embutida (ver Lição 31)
#include <IRremote.h> // 2.8.1 (ver Lição 22; NÃO usar 3.x/4.x)
const int PASSOS_POR_VOLTA = 2048;
Stepper passo(PASSOS_POR_VOLTA, 8, 10, 9, 11); // mesma sequência da L31
const int RECV_PIN = 2; // OUT do IR
IRrecv irrecv(RECV_PIN); // receptor
decode_results results; // quadro NEC
// Troque pelos HEX do SEU controle (anotados na Lição 22):
const unsigned long CMD_FRENTE = 0xFF629D; // exemplo: seta cima
const unsigned long CMD_TRAS = 0xFFA857; // exemplo: seta baixo
const unsigned long CMD_PARA = 0xFF02FD; // exemplo: OK/para
void setup() {
passo.setSpeed(10); // rpm seguro
Serial.begin(9600); // log de comandos
irrecv.enableIRIn(); // inicia captura 38 kHz
Serial.println("IR->Passo pronto: frente/tras/para"); // prompt
}
void loop() {
if (irrecv.decode(&results)) { // chegou quadro?
unsigned long cmd = results.value; // código (ignora 0xFFFFFFFF aqui p/ clareza)
if (cmd == CMD_FRENTE) { // frente
Serial.println("FRENTE 1/4 volta"); // confirma
passo.step(PASSOS_POR_VOLTA / 4); // 512 passos
} else if (cmd == CMD_TRAS) { // trás
Serial.println("TRAS 1/4 volta");
passo.step(-(int)(PASSOS_POR_VOLTA / 4)); // volta parcial
} else if (cmd == CMD_PARA) { // para (só loga; passo já é estático)
Serial.println("PARADO"); // sem bobina extra
} else { // não mapeado
Serial.print("HEX nao mapeado: 0x"); // ajuda a mapear
Serial.println(cmd, HEX); // anote e troque as consts acima
}
irrecv.resume(); // rearma receptor
}
}
Se segurar a tecla, o controle manda 0xFFFFFFFF (repetição) — o exemplo acima ignora de propósito para o iniciante não girar sem parar; como evolução, trate repetição como “continua andando”. Resultado esperado: seta cima avança 1/4 de volta, baixo recua, OK loga parado. Motor morto com IR vivo = fonte externa desligada ou GND não comum; IR morto = OUT em pino sem suporte ou bateria fraca.
⚠️ Atenção: ligue a fonte externa só após conferir IN1–IN4 e GND comum. ULN2003 com VCC sem GND queima a trilha da placa em segundos. Área de teste livre: o eixo com fita pode chicotear fios soltos.
Lição 33: Passo com Encoder Rotativo (Segue o Botão)
A Lição 33 multi-partes fecha o curso: o 28BYJ-48 com ULN2003 obedece um encoder rotativo mecânico (2 sinais em quadratura CLK/DT + chave SW ao apertar). Girar horário avança passos, anti-horário recua, na proporção 1:1 com os detentes do botão — controle de precisão “manual” sem PC. É a base de CNC/jog didático: cada clique do encoder vira N passos do motor.
| Item | Qtd |
|---|---|
| Uno R3 | 1 |
| 28BYJ-48 + ULN2003 | 1 conjunto |
| Encoder rotativo (CLK/DT/SW/VCC/GND) | 1 |
| Jumpers F-M | 9 (4 motor + 5 encoder) |
| Encoder | Uno | Leitura |
|---|---|---|
| VCC (+) | 5 V | Pull-ups do módulo |
| GND | GND | Comum |
| CLK | D2 | Canal A (interrupção externa) |
| DT | D3 | Canal B (direção) |
| SW | D4 (INPUT_PULLUP) | Chave (aperta=GND, zera posição) |
Quadratura: CLK e DT defasados 90°; a ordem de borda diz a direção. Se CLK cai com DT=HIGH é um sentido, com DT=LOW é o outro (convenção do lote — se inverter no seu hardware, troque o sinal no if).
📦 Bibliotecas desta lição:
Stepper— embutida na IDE (mesma da Lição 31), nada a baixar. O encoder é lido com interrupção nativa, sem biblioteca externa.
// Lição 33 AE050: motor segue o encoder (CW avança, CCW recua, SW zera)
#include <Stepper.h> // embutida (ver Lição 31)
const int PASSOS_POR_VOLTA = 2048;
Stepper passo(PASSOS_POR_VOLTA, 8, 10, 9, 11); // sequência L31
const int PIN_CLK = 2; // canal A (INT0)
const int PIN_DT = 3; // canal B
const int PIN_SW = 4; // chave (pull-up)
volatile long posicao = 0; // cliques acumulados (interrupção escreve)
long ultimaPos = 0; // último valor já enviado ao motor
void setup() {
passo.setSpeed(12); // jog responsivo sem perder passo
pinMode(PIN_DT, INPUT); // quadratura
pinMode(PIN_SW, INPUT_PULLUP); // chave sem resistor
attachInterrupt(digitalPinToInterrupt(PIN_CLK), aoGirar, FALLING); // borda de CLK
Serial.begin(9600); // log de posição
Serial.println("Gire o encoder; aperte para zerar"); // prompt
}
void loop() {
if (digitalRead(PIN_SW) == LOW) { // botão apertado?
posicao = 0; // zera referência
ultimaPos = 0; // sincroniza motor
Serial.println("ZERO"); // confirma
delay(300); // debounce da chave
}
if (posicao != ultimaPos) { // há movimento pendente?
long delta = posicao - ultimaPos; // cliques desde o último envio
passo.step(delta * 32); // 32 passos de motor por clique (ajuste fino)
ultimaPos = posicao; // consome
Serial.print("pos="); // telemetria
Serial.println(posicao);
}
}
// Interrupção: roda a cada detente do encoder (rápida, sem delay/Serial aqui):
void aoGirar() {
if (digitalRead(PIN_DT) == HIGH) posicao++; // convenção do lote
else posicao--; // sentido oposto
}
volatile é obrigatório porque a interrupção muda posicao fora do loop. Nunca use delay() ou Serial dentro da ISR — trava a quadratura. Ganho 32 passos/clique equilibra precisão e velocidade; suba para 64 se quiser volta mais rápida, desça para 16 se quiser ajuste fino. Resultado esperado: 1 clique = microavanço imediato no mesmo sentido da mão; apertar zera e o próximo giro parte do zero. Sentido invertido = troque ++/-- na ISR; pulos duplos = encoder sem debounce mecânico (gire devagar) ou jumpers frouxos.
Guia Diagnóstico (Troubleshooting — Todos os 34 Projetos)
Use esta matriz como protocolo de bancada, não como leitura corrida. Comece pelo checklist de pré-energização antes de culpar qualquer componente: ele elimina mais de oitenta por cento das falhas de iniciantes em minutos, sem trocar peça. Só depois desça para a linha da tabela correspondente ao sintoma observado, execute as ações na ordem indicada (da causa mais barata para a mais cara) e reteste após cada passo isolado. Se duas falhas coexistirem (por exemplo, lib errada mais fiação trocada), corrija o software primeiro, pois recompilar é mais rápido que refazer o chicote, e só então mexa no hardware. Registre o que mudou em cada tentativa em um caderno de bancada com hora, sintoma e ação, pois diagnóstico sem registro vira tentativa aleatória e queima tempo e componente.
| Passo | Verificação Pré-Energização | Critério de Aprovação |
|---|---|---|
| 1 | Cabo USB é de dados e está na mesma porta de sempre | Porta da Uno aparece em Ferramentas > Porta e some ao desplugar |
| 2 | Placa Arduino Uno selecionada, nada em D0/D1 | Upload do Blink funciona e LED L pisca |
| 3 | Bibliotecas da lição instaladas e IDE reiniciada | Exemplo da lib compila sem No such file |
| 4 | Trilhos de força conferidos (5 V, 3V3, GND) com multímetro ou LED de teste | 5 V onde é 5 V, 3,3 V onde é 3,3 V (ADXL335, RC522), GND contínuo |
| 5 | Polaridades (LED, buzzer, diodo, transistor, relé, motor) contra a tabela da lição | Faixa do diodo ao +, base via resistor, anodo longo ao + |
| 6 | Fontes externas ligadas por último, com GND comum | Motor/relé/passo com força própria, lógica sem queda |
| 7 | Trimpots no meio do curso antes do primeiro teste (PIR, som, contraste LCD) | Ajuste fino só após o circuito responder |
Com o checklist aprovado, a matriz abaixo cobre os erros reais do kit AE050 observados na documentação oficial e em bancada: driver USB-serial, porta, biblioteca com versão, alimentação subdimensionada, fiação trocada, divisor invertido, pull-up ausente, latch do 595, baud do Serial, limiar de comparador, calibração de PIR e LDR, tabela de display complementar, sequência de fases do passo e quadratura do encoder. Cada linha indica sintoma observável, causa raiz mais provável e ação corretiva ordenada para isolar a camada defeituosa sem desmontar o circuito inteiro.
| Sintoma | Causa Raiz Mais Provável | Ação Corretiva (nesta ordem) |
|---|---|---|
avrdude: stk500_recv() / porta cinza | Cabo só-carga, driver CH340 ausente, placa/porta erradas | Trocar por USB de dados; instalar driver do chip da sua placa; Ferramentas > Placa: Arduino Uno + Porta da Uno; nada em D0/D1 durante upload |
| Upload ok mas nada acontece | Porta de outro dispositivo / exemplo errado | Reselecionar COM /dev/ttyUSB; regravar Blink da Lição 2 e observar LED L |
No such file or directory / does not name a type | Biblioteca não instalada ou pasta dupla | Reinstalar pela Lição 1 (Manager/ZIP/manual); pasta deve ser libraries/Nome/Nome.h; reiniciar IDE |
| LED não acende / invertido | Polaridade ou resistor aberto | Perna longa ao + via 220 Ω; testar LED em 5 V+GND direto com resistor; trocar fileira da protoboard |
| RGB com cor faltando | Pino sem ~ ou resistor ausente | Usar D9/D10/D11 com 220 Ω por cor; comum (mais longo) ao GND (catodo comum) |
| Botão liga sozinho / invertido | Sem INPUT_PULLUP ou pernas no mesmo lado | Usar INPUT_PULLUP (LOW=pressionado); pernas em lados opostos do canal |
| 595 com LEDs tremendo/fora de ordem | Latch invertido ou LSB/MSB trocado | LOW→shiftOut→HIGH; testar LSBFIRST vs MSBFIRST; OE ao GND, MR+Vcc em 5 V |
| Monitor Serial com hieróglifos | Baud divergente | IDE e monitor em 9600; Serial.begin(9600) |
| Barra LDR invertida / travada | Divisor trocado ou A0 errado | LDR ao 5 V, 1 kΩ ao GND, meio em A0; reading/57; testar cobrindo/soprando luz |
| Buzzer ativo mudo | Cápsula trocada (passivo no lugar) | Ativo = fita preta (CC apita); passivo = placa verde (precisa tone()) |
| Escala desafinada / muda | Sem pitches.h ou analogWrite no lugar de tone | Instalar lib de tons; usar tone(pino,freq,dur) pino D8 |
| Tilt nunca muda | Orientação travada ou jumper solto | Girar 90° além de ~20°; D2 com pull-up até GND via chave; delay(200) anti-repique |
| Relé chia sem comutar / Uno reseta | Fonte fraca, GND não comum, sem flyback | Fonte externa 9 V com GND comum; 1N4007 faixa ao +; 220 Ω na base; só motor 6 V nos contatos |
| 7-seg embaralhado / invertido | Mapa Q→segmento ou anodo/catodo trocado | Conferir Q0–Q7→A–G–DP pino a pino; catodo (3/8) ao GND, anodo a 5 V + tabela complementar |
| 4 dígitos com fantasma / fraco | Sem blanking ou corrente baixa | Desligar dígito entre varreduras; delay(5); 50 Hz mínimo; resistores por dígito |
| Servo tremendo / estalando | Fonte fraca ou além de 0/180° | USB dedicado ou fonte; write(0..180) sem forçar eixo com a mão |
| LCD só quadrados / apagado | Contraste ou begin / backlight | Girar pot VO; lcd.begin(16,2); A/K em 5 V/GND; lcd(7,8,9,10,11,12) |
| Temp travada em 0/1023 | Sensor sem força ou pino errado | TMP36 VCC/GND + OUT em A0; (V-0.5)*100; reescrever linha inteira contra fantasma |
| HC-SR04 zero / pulando | Sem eco ou ciclo <60 ms | Alvo plano a 20 cm; delay(100); Trig 10 µs + pulseIn com timeout; cm=t/58 |
| Teclado repete / troca tecla | Membrana frouxa ou mapa trocado | Reencaixar 8 vias; conferir R1–R4/C1–C4 vs makeKeymap; testar no Serial antes do LCD |
DHT11 NaN | Intervalo <2 s ou DATA errado | delay(2000); DATA em D2 com pull-up; VCC 5 V |
| Joystick fora do centro | Vcc fraco ou fim de curso | Centro ~512±50; Vcc 5 V; X=A0 Y=A1 SW=D2 pull-up |
| IR sem HEX | Pino sem suporte, sol ou bateria | OUT em D11/D2 conforme lib; <5 m sem sol; trocar bateria; anotar hex do seu lote |
| Matriz apagada / flicker | shutdown ou brilho/fonte | shutdown(0,false); setIntensity(0,8); DIN/CS/CLK = D12/D11/D10; USB forte |
| ADXL335 saturado / quente | Alimentado em 5 V | Desligar e pôr em 3V3 (limite 3,6 V); X=A0 Y=A1 Z=A2; parado Z≈+1 g |
| PIR dispara sozinho / morto | Sem calibração ou mira ruim | 60 s parado após ligar; sens/tempo no meio; mirar passagem, não janela/sol |
| Nível sempre 0 / deriva | Sonda seca/oxidada ou AO/DO trocado | Imergir 1–3 cm; AO em A0; secar após teste; calibrar vazio/cheio |
DS3231 não encontrado / hora volta | SDA/SCL trocados ou adjust repetido | SDA=A4 SCL=A5; ajustar uma vez e comentar adjust depois |
| Som saturado / DO preso | Ganho/limiar no extremo | Trimpot até LED de bordo piscar só na palma; AO em A0 + Plotter |
| RFID não lê / esquenta | VCC 5 V ou SPI frouxo | VCC em 3V3; SDA=D10 RST=D9 MOSI=D11 MISO=D12 SCK=D13; tag a 0–3 cm paralela |
| Motor DC parado com chiado / reset | Sem torque de partida ou sem diodo/GND comum | Partir de ~30 % PWM; 1N4007 faixa ao +; GND externo = GND Uno; fonte externa |
| Passo vibra sem girar | Sequência/fio errado ou rpm alta | Ordem 8,10,9,11; 10 rpm; 4 jumpers firmes; fonte externa sob carga |
| Passo+IR morto (IR vivo) | Força sem GND comum | Fonte 9 V ligada + GND comum; OUT IR em D2; remapear hex do seu controle |
| Encoder invertido / duplo | Convenção do lote ou repique | Trocar ++/-- na ISR; girar devagar; 32 passos/clique; SW com pull-up e debounce |
💡 Dica: diante de qualquer falha, isole em 3 camadas: 1) software (exemplo mínimo da lib compila?), 2) alimentação (USB de dados? 3V3 vs 5 V? GND comum? fonte externa ligada?), 3) fiação (pino a pino contra a tabela da lição, jumpers firmes, nada em D0/D1 no upload). Noventa por cento dos defeitos deste kit caem em placa/porta, lib/versão ou VCC/GND.
Solução de problemas
Olá! Sou o assistente técnico da RoboBuilders. Descreva seu problema com o Kit Avançado de Arduino Uno AE050 - 34 Projetos - Curso Completo e eu ajudarei a encontrar a solução.
O assistente usa IA e pode errar. Confirme informações críticas no datasheet oficial do fabricante.