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

Kit Avançado Arduino Uno AE050 — Curso Completo com Projetos Práticos

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 EngenhariaEspecificação TécnicaObservações de Operação
Microcontrolador PrincipalATmega328P (8-bit AVR RISC)DIP-28 ou SMD, 16 MIPS a 16 MHz
Tensão Lógica de Operação5,0 VDC (TTL)Nível HIGH ~5 V, LOW ~0 V
Entrada Recomendada (VIN / Jack P4)7,0 V a 12,0 VDCRegulador linear LDO onboard
Entrada Limite (VIN)6,0 V a 20,0 VDCAcima de 12 V aquece o LDO
GPIOs Digitais14 pinos (D0 a D13)6 com PWM por hardware (3, 5, 6, 9, 10, 11 — marcados com ~)
Entradas Analógicas6 canais (A0 a A5)ADC 10 bits (0 a 1023 passos)
Corrente por Pino20 mA típico, 40 mA absolutoSoma total recomendada abaixo de 200 mA
Saída 3,3 V50 mA máximoPara módulos de 3,3 V como ADXL335 e RC522
Flash / SRAM / EEPROM32 KB / 2 KB / 1 KB0,5 KB da Flash ocupados pelo bootloader Optiboot
Clock16 MHzRessonador cerâmico externo
Interface USB-SerialCH340G / CP2102 / ATmega16U2 (conforme revisão)Conversão UART-USB, exige driver no Windows
Comunicação Serial HardwareD0 (RX) e D1 (TX) via USBEvitar 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 é:

VIN=ADC×5,01023V_{IN} = \frac{ADC \times 5{,}0}{1023}

onde ADCADC é a contagem de 0 a 1023 e VINV_{IN} é 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):

D=tONT×100%D = \frac{t_{ON}}{T} \times 100\% VMED=D×5,0 VV_{MED} = D \times 5{,}0\,\text{V}

onde tONt_{ON} é o tempo em HIGH dentro do período TT (~2 ms no PWM de ~490/976 Hz do Uno) e VMEDV_{MED} é 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 DD.

A Lei de Ohm governa todos os dimensionamentos de LED e divisor:

V=R×IV = R \times I R=VFONTE−VLEDILEDR = \frac{V_{FONTE} - V_{LED}}{I_{LED}}

Para LED vermelho (VLED≈2,0 VV_{LED} \approx 2{,}0\,\text{V}) a 15 mA em 5 V, R≈200 ΩR \approx 200\,\Omega — por isso o kit usa 220 Ω\Omega como padrão.

Mapa de Pinos e Protocolos Usados no Curso

SubsistemaPinos Típicos no AE050Protocolo / Técnica
LED onboard BlinkD13GPIO saída digital + delay()
LEDs, botões, buzzer ativo, tilt, relé (lógica)D2–D13GPIO digital, INPUT_PULLUP para botões
RGB, buzzer passivo (melodias), motor DC, servoD3, D5, D6, D9, D10, D11 (~)PWM por hardware + tone() + biblioteca Servo
Fotocélula, termistor, joystick XY, água, som AO, ADXL335 XYZA0–A5ADC 10 bits + divisor resistivo
74HC595 (LEDs e 7-seg)D4 (dados), D5 (latch), D6 (clock) e variante D8/D11/D12Serial-para-paralelo via shiftOut()
LCD 16x2 modo 4 bitsD7 (RS), D8 (E), D9–D12 (D4–D7)Biblioteca LiquidCrystal
Ultrassom HC-SR04Trig/Echo digitaisPulso de 10 µs + pulseIn()
Teclado 4x48 digitais (4 linhas + 4 colunas)Varredura matricial (Keypad)
DHT111 digitalProtocolo proprietário 1-wire temporizado
IR receptor1 digital com interrupçãoDecodificação NEC (IRremote)
MAX7219 matriz 8x8DIN/CS/CLKSPI por software (LedControl)
DS3231 RTCA4 (SDA), A5 (SCL)I2C + RTClib
RC522 RFIDD9 (RST), D10 (SS), D11 (MOSI), D12 (MISO), D13 (SCK)SPI hardware + MFRC522
Servo SG901 PWM + 5 V + GNDPulsos de 1–2 ms a 50 Hz
Motor DC via PN22221 PWM + transistor + diodo 1N4007Chaveamento low-side
Passo 28BYJ-48 + ULN2003IN1–IN4Sequência de 4 fases
Encoder rotativoCLK/DT/SWLeitura 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
Conteúdo do kit AE050 parte 2
Conteúdo do kit AE050 parte 3 Conteúdo do kit AE050 parte 4

📦 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.

Tela inicial da IDE Arduino da Lição 0 Gerenciador de dispositivos para driver USB

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, Servo e Wire continuam nos mesmos menus. O que não muda: placa tem que ser Arduino Uno e a porta tem que ser a da Uno, nunca Arduino Leonardo ou 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).

Gerenciador de bibliotecas da IDE Instalação de biblioteca ZIP

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 GerenciadorVersão usada no cursoDownload ZIP (espelho oficial)Lições
Servo.h (embutida na IDE)já vem instalada — nada a instalarnúcleo AVR da IDE—15
LiquidCrystal (embutida na IDE)já vem instalada — nada a instalarnúcleo AVR da IDE—16, 17
Stepper.h (embutida na IDE)já vem instalada — nada a instalarnúcleo AVR da IDE—31, 32, 33
Wire.h / SPI.h (embutidas na IDE)já vêm instaladas — nada a instalarnúcleo AVR da IDE—27, 29
pitches.h (aba do sketch, não é Manager)não buscar — criar aba no sketchtabela oficial Arduinopitches.h oficial (tutorial)10
KeypadKeypad por Mark Stanley, Alexander Brevig3.1.1Chris—A/Keypad19
DHT sensor library + Adafruit Unified Sensor (dependência obrigatória)DHT sensor library por Adafruit e Adafruit Unified Sensor por Adafruit1.4.7 + última do Unified Sensoradafruit/DHT-sensor-library + adafruit/Adafruit_Sensor20
IRremoteIRremote 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
LedControlLedControl por Eberhard Fahle1.0.6wayoda/LedControl23
RTClibRTClib por Adafruit2.x atualadafruit/RTClib27
MFRC522MFRC522 por GithubCommunity1.4.12miguelbalboa/rfid29

⚠️ Atenção: a IRremote 3.x/4.x mudou a API (IrReceiver, sem decode_results/results.value) e QUEBRA os códigos das Lições 22 e 32. No Gerenciador, abra o menu de versões da IRremote e fixe a 2.8.1 antes de Instalar. A DHT só compila com a dependência Adafruit Unified Sensor instalada 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)

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.

Exemplo Blink na IDE Placa Uno com LED L indicado
ItemQtdObservação
Placa Uno R31LED L = D13 onboard, sem fiação externa
Cabo USB de dados1Porta + 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:

T=tON+tOFFT = t_{ON} + t_{OFF} f=1Tf = \frac{1}{T}

Com 1000+1000 ms, T=2 sT = 2\,\text{s} e f=0,5 Hzf = 0{,}5\,\text{Hz}. Com 500+500 ms, f=1 Hzf = 1\,\text{Hz}. 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.

Protoboard MB-102 e LED 5 mm Código de cores de resistores

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.

ItemQtdDetalhe
Uno R31Fonte 5 V + GND via USB
LED vermelho 5 mm1Anodo longo, catodo com chanfro
Resistor 220 Ω1Vermelho-vermelho-marrom-dourado
Resistor 1 kΩ1Marrom-preto-vermelho-dourado
Resistor 10 kΩ1Marrom-preto-laranja-dourado
Jumpers M-M25 V → resistor → anodo; catodo → GND
LigaçãoOrigemDestino
Alimentação5V da UnoTrilho + / resistor
ResistorTrilho 5 VAnodo do LED (perna longa)
CatodoPerna curta do LEDGND da Uno

Dimensionamento pela Lei de Ohm com VFONTE=5 VV_{FONTE} = 5\,\text{V} e VLED≈2 VV_{LED} \approx 2\,\text{V}:

I=5−2RI = \frac{5 - 2}{R}

Com R=220 ΩR = 220\,\Omega, I≈13,6 mAI \approx 13{,}6\,\text{mA} (brilhante e seguro). Com 1 kΩ1\,\text{k}\Omega, I≈3 mAI \approx 3\,\text{mA}. Com 10 kΩ10\,\text{k}\Omega, I≈0,3 mAI \approx 0{,}3\,\text{mA} (fraco). Potência no resistor:

P=R×I2P = R \times I^{2}

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.

LED RGB e pinagem Esquemático RGB com 3 resistores

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.

ItemQtd
Uno R3 + protoboard1 cada
LED RGB catodo comum1
Resistores 220 Ω3
Jumpers M-M4
CorPino Uno (PWM)Resistor
VermelhoD9 (~)220 Ω em série
VerdeD10 (~)220 Ω em série
AzulD11 (~)220 Ω em série
Comum (mais longo)GNDdireto
// 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:

VMED=valor255×5,0 VV_{MED} = \frac{valor}{255} \times 5{,}0\,\text{V}

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).

ItemQtd
Uno + protoboard1 cada
LED vermelho + 220 Ω1 cada
Push-buttons 4 pinos2
Jumpers M-M6
LigaçãoDetalhe
LED anodo via 220 ΩD13 (ou D8) como saída
LED catodoGND
Botão A (liga)Pino D2 → GND quando pressionado
Botão B (desliga)Pino D3 → GND quando pressionado
Posição na protoboardPernas 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).

CI 74HC595 na protoboard Oito LEDs com resistores

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).

ItemQtd
Uno + protoboard1 cada
LEDs 5 mm8
Resistores 220 Ω8
CI 74HC5951
Jumpers M-M14
Uno74HC595Função
D4Pino 14 (DS)Dado serial
D5Pino 12 (ST_CP)Latch (copia para saída)
D6Pino 11 (SH_CP)Clock (desloca 1 bit por pulso)
5 VPinos 16 (Vcc) e 10 (MR)Alimentação + reset desligado
GNDPinos 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”.

ItemQtd
Base Lições 6–7 (Uno + 595 + 8 LEDs)1 conjunto
Fotocélula LDR1
Resistor fixo 1 kΩ1
Ligação analógicaDetalhe
LDR entre 5 V e A0Ramo superior do divisor
Resistor 1 kΩ entre A0 e GNDRamo inferior do divisor
Ponto médio (A0)Tensão proporcional à luz

A tensão no ponto médio é:

VA0=5,0×1 kΩRLDR+1 kΩV_{A0} = 5{,}0 \times \frac{1\,\text{k}\Omega}{R_{LDR} + 1\,\text{k}\Omega}

No escuro (RLDR≈50 kΩR_{LDR} \approx 50\,\text{k}\Omega), VA0≈0,1 VV_{A0} \approx 0{,}1\,\text{V} (ADC ~20). No claro (RLDR≈0,5 kΩR_{LDR} \approx 0{,}5\,\text{k}\Omega), VA0≈3,3 VV_{A0} \approx 3{,}3\,\text{V} (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).

ItemQtd
Uno R31
Buzzer ativo 5 V1
Jumpers F-M2
LigaçãoDetalhe
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).

ItemQtd
Uno R31
Buzzer passivo1 (placa verde visível)
Jumpers F-M2 (vermelho D8, preto GND)

A frequência define a nota; o período é:

T=1fT = \frac{1}{f}

Para Lá 880 Hz, T≈1,14 msT \approx 1{,}14\,\text{ms}. 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 (ou Ctrl+Shift+N), nomeie como pitches.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 sketch deve listar o .ino e o pitches.h lado a lado; Verificar compila sem No 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.

ItemQtd
Uno R31
Ball switch1
Jumpers F-M2
LigaçãoDetalhe
Terminal 1D2 com INPUT_PULLUP
Terminal 2GND
// 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.

Módulo relé e transistor PN2222 Motor DC 6V da Lição 12
ItemQtdFunção
Uno + protoboard1 cadaLógica
Relé 5 V1Contatos COM/NA/NF
Transistor PN22221Chave da bobina
Diodo 1N40071Flyback (faixa no +)
Resistor 220 Ω1Base do transistor
Motor DC 6 V1Carga no contato do relé
Fonte protoboard + adaptador 9 V1 cadaForça (GND comum com Uno)
Jumpers M-M8Conforme esquemático da doc
Ligação lógicaDetalhe
D8 via 220 ΩBase do PN2222
Emissor PN2222GND comum
Coletor PN2222Bobina do relé + anodo do 1N4007
Outro lado da bobina + catodo 1N4007 (faixa)5 V
Contato COMFonte 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ígitodp a b c d e f g (catodo comum)
00 1 1 1 1 1 1 0
10 0 1 1 0 0 0 0
20 1 1 0 1 1 0 1
30 1 1 1 1 0 0 1
40 0 1 1 0 0 1 1
50 1 0 1 1 0 1 1
60 1 0 1 1 1 1 1
70 1 1 1 0 0 0 0
80 1 1 1 1 1 1 1
90 1 1 1 1 0 1 1
595 QSegmento 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.

Display 4 dígitos na protoboard Esquemático multiplexado 4 dígitos
ItemQtd
Uno + protoboard1 cada
Display 4 dígitos1
74HC5951
Resistores 220 Ω4 (um por dígito/seleção)
Jumpers M-M20 (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:

fquadro=14×5 ms=50 Hzf_{quadro} = \frac{1}{4 \times 5\,\text{ms}} = 50\,\text{Hz}

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.

ItemQtd
Uno R31
Servo SG90 + cruzetas/parafusos1
Jumpers F-M2–3 (sinal + alimentação)
FioDestino
MarromGND
Vermelho5 V
LaranjaD9 (~, PWM)
θ≈tpulso−1 ms1 ms×180°,1 ms≤tpulso≤2 ms\theta \approx \frac{t_{pulso} - 1\,\text{ms}}{1\,\text{ms}} \times 180°,\quad 1\,\text{ms} \le t_{pulso} \le 2\,\text{ms}

📦 Bibliotecas desta lição: Servo — embutida na IDE, nada a baixar.

  • Instalação: nenhuma. Confira em Sketch > Incluir Biblioteca que Servo está listada e em Arquivo > Exemplos > Servo > Sweep que o exemplo abre e compila.
  • Se Servo.h der No such file, reinstale o núcleo AVR em Ferramentas > 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 LCDNomeFunçãoUno (exemplo do curso)
1VSSTerraGND
2VDDLógica5 V
3VOContrasteCursor do pot (extremos em 5 V/GND)
4RSRegistrador (dado/comando)D7
5R/WLeitura/escritaGND (só escrita)
6EHabilita (borda)D8
11–14D4–D7Dados 4 bitsD9–D12
15–16A/KBacklight5 V/GND (via resistor onboard)
ItemQtd
Uno + protoboard1 cada
LCD16021
Potenciômetro 10 kΩ1
Jumpers F-M16

📦 Bibliotecas desta lição: LiquidCrystal — embutida na IDE, nada a baixar.

  • Instalação: nenhuma. Confira em Arquivo > Exemplos > LiquidCrystal > HelloWorld que 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.

ItemQtd
Base Lição 16 completa1
Sensor TMP36 (ou NTC do kit)1
Resistor 10 kΩ (apoio do divisor)1
Jumpers extrasconforme 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:

V=ADC×5,01024V = \frac{ADC \times 5{,}0}{1024} TC=(V−0,5)×100T_{C} = (V - 0{,}5) \times 100 TF=TC×95+32T_{F} = T_{C} \times \frac{9}{5} + 32

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.

ItemQtd
Uno R31
HC-SR041
Jumpers F-M4
HC-SR04UnoNota
Vcc5 VLógica 5 V
GNDGNDComum
TrigD8 (saída)Pulso de 10 µs
EchoD9 (entrada)Largura = ida-volta

Física do tempo de voo com vsom≈340 m/sv_{som} \approx 340\,\text{m/s}:

d=t×v2d = \frac{t \times v}{2}

Atalhos da doc com tt em microssegundos:

dcm=tμs58d_{cm} = \frac{t_{\mu s}}{58} din=tμs148d_{in} = \frac{t_{\mu s}}{148}

📦 Bibliotecas desta lição: nenhuma — o código abaixo usa pulseIn() nativo, sem biblioteca externa. Se a sua IDE oferecer NewPing/Ultrasonic no 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.

Teclado matricial 4x4 Ligação do teclado à Uno
ItemQtd
Uno R31
Teclado membrana 4x41 (8 vias)
Jumpers M-M8
TecladoUno (exemplo)
R1–R4 (linhas)D9, D8, D7, D6
C1–C4 (colunas)D5, D4, D3, D2

📦 Bibliotecas desta lição: Keypad por Mark Stanley, Alexander Brevig (versão 3.1.1).

  • Via Gerenciador (recomendado): Sketch > Incluir Biblioteca > Gerenciar Bibliotecas… → buscar Keypad → selecionar 3.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 > HelloKeypad deve abrir e compilar sem No 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.

ItemQtd
Uno R31
Módulo DHT11 (3 pinos: VCC/DATA/GND)1
Jumpers F-M3
DHT11Uno
VCC5 V
DATAD2 (com pull-up; módulo já traz)
GNDGND

📦 Bibliotecas desta lição: DHT sensor library por Adafruit (versão 1.4.7) + dependência obrigatória Adafruit Unified Sensor.

  • Via Gerenciador (recomendado): Sketch > Incluir Biblioteca > Gerenciar Bibliotecas… → buscar DHT sensor library → Instalar (aceitar instalar as dependências quando a IDE oferecer Adafruit Unified Sensor) → buscar Adafruit Unified Sensor e confirmar instalada → reiniciar a IDE.
  • Via ZIP: adafruit/DHT-sensor-library + adafruit/Adafruit_Sensor (Code > Download ZIP em cada) → Adicionar Biblioteca .ZIP… uma por vez → reiniciar a IDE.
  • Conferência: Arquivo > Exemplos > DHT sensor library > DHTtester deve 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.

ItemQtd
Uno R31
Joystick XY+Key1
Jumpers F-M5
JoystickUno
Vcc5 V
GNDGND
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:

X0≈Y0≈512X_{0} \approx Y_{0} \approx 512

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.

ItemQtd
Uno R31
Receptor IR (3 pinos)1
Controle IR1 (bateria inclusa no kit)
Jumpers F-M3
IRUno
VCC (ou +)5 V
GND (−)GND
OUT (S)D11 (pino de interrupção da lib)

📦 Bibliotecas desta lição: IRremote por shirriff, z3t0, ArminJo — fixar a versão 2.8.1 (linha 2.x).

  • Via Gerenciador (recomendado): Sketch > Incluir Biblioteca > Gerenciar Bibliotecas… → buscar IRremote → no menu de versões escolher 2.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 > IRrecvDemo deve abrir e compilar.
  • ⚠️ Atenção: NÃO instale a IRremote 3.x/4.x aqui — ela remove IRrecv/decode_results/results.value usados no código abaixo e a compilação falha. Se já instalou a nova, volte ao Gerenciador, selecione 2.8.1 e Instalar.

// 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.

ItemQtd
Uno R31
Matriz MAX7219 8x81
Jumpers F-M5 (VCC/GND/DIN/CS/CLK)
MAX7219Uno
VCC5 V
GNDGND
DIND12
CSD11
CLKD10

📦 Bibliotecas desta lição: LedControl por Eberhard Fahle (versão 1.0.6).

  • Via Gerenciador (recomendado): Sketch > Incluir Biblioteca > Gerenciar Bibliotecas… → buscar LedControl → Instalar → reiniciar a IDE.
  • Via ZIP: baixar em wayoda/LedControl (Code > Download ZIP) → Adicionar Biblioteca .ZIP… → reiniciar a IDE.
  • Conferência: Arquivo > Exemplos > LedControl > LCDemoMatrix deve abrir e compilar sem No 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.

ItemQtd
Uno R31
ADXL3351
Jumpers F-M6–7 (VCC 3V3/GND/X/Y/Z + ST opcional)
ADXL335UnoAlerta
VCC3,3 V (nunca 5 V)Limite 3,6 V
GNDGNDComum
X / Y / ZA0 / A1 / A20–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):

V=ADC×5,01023V = \frac{ADC \times 5{,}0}{1023} a=V−V0S,V0≈1,65 V,  S≈0,3 V/ga = \frac{V - V_{0}}{S},\quad V_{0} \approx 1{,}65\,\text{V},\; S \approx 0{,}3\,\text{V/g}
// 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 gz≈+1 gg_{z} \approx +1\,\text{g} (gravidade) e gx,gy≈0g_{x},g_{y} \approx 0. 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 3V3 da 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.

Sensor PIR HC-SR501 Ajustes de sensibilidade e tempo do PIR
ItemQtd
Uno R31
HC-SR5011
Jumpers F-M3
LED + 220 Ω (opcional p/ teste)1 cada
PIRUno
VCC5 V
OUTD2
GNDGND
// 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.

ItemQtd
Uno R31
Sensor de nível (placa pectinada + módulo)1
Jumpers F-M3–4
SensorUnoUso
VCC (+)5 VAlimenta amplificador
GND (−)GNDComum
AO (analógica)A0Nível 0–1023
DO (digital, se houver)D2Alarme 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):

nıˊvel∝1Rtrilhas(h)nível \propto \frac{1}{R_{trilhas}(h)}

onde hh é 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.

ItemQtd
Uno R31
DS3231 com bateria1
Jumpers F-M4
DS3231Uno (I2C hardware)
VCC5 V (ou 3,3 V conforme módulo)
GNDGND
SDAA4
SCLA5

📦 Bibliotecas desta lição: RTClib por Adafruit + Wire (embutida, I2C em A4/A5).

  • Via Gerenciador (recomendado): Sketch > Incluir Biblioteca > Gerenciar Bibliotecas… → buscar RTClib → Instalar (a Wire já 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 > ds3231 deve abrir e compilar sem No 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.

ItemQtd
Uno R31
Sensor de som (AO/DO/GND/VCC)1
Jumpers F-M4 (VCC/GND/AO/DO)
SensorUno
VCC5 V
GNDGND
AOA0
DOD2
// 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.

Leitor RFID RC522 com cartão e tag Fiação SPI do RC522
ItemQtd
Uno R31
RC522 + cartão + tag1 kit
Jumpers F-M7
RC522UnoBarramento
VCC3,3 V (nunca 5 V)Força RF
GNDGNDComum
RSTD9Reset
SDA (SS)D10Seleção SPI
MOSID11SPI hardware
MISOD12SPI hardware
SCKD13SPI hardware

📦 Bibliotecas desta lição: MFRC522 por GithubCommunity (versão 1.4.12) + SPI (embutida, D11–D13).

  • Via Gerenciador (recomendado): Sketch > Incluir Biblioteca > Gerenciar Bibliotecas… → buscar MFRC522 → Instalar (a SPI já 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 > DumpInfo deve abrir e compilar sem No 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 3V3 antes 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é.

ItemQtd
Uno + protoboard1 cada
Motor DC 6 V1
PN2222 + 1N4007 + 220 Ω1 cada
Fonte externa (protoboard/9 V)1 (GND comum)
Jumpers M-M3 + força
LigaçãoDetalhe
D9 (~) via 220 ΩBase do PN2222
EmissorGND comum
ColetorMotor (−) + anodo 1N4007
Motor (+) + catodo 1N4007 (faixa)5–6 V externos
GND externoGND da Uno (obrigatório)

A corrente de base necessária para saturar:

IB≈IChFE,minI_{B} \approx \frac{I_{C}}{h_{FE,min}}

Com IC≈300 mAI_{C} \approx 300\,\text{mA} de partida e hFE≈100h_{FE} \approx 100, IB≈3 mAI_{B} \approx 3\,\text{mA}; os 220 Ω entregam ~20 mA, saturando com folga. Velocidade por duty:

ω≈D×ωmax\omega \approx D \times \omega_{max}
// 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.

Motor 28BYJ-48 com driver ULN2003 Sequência de fases do passo
ItemQtd
Uno R31
28BYJ-48 5 V + placa ULN20031 conjunto
Jumpers F-M4–5 (IN1–IN4 + VCC/GND) + USB para lógica
ULN2003UnoFase
IN1D8Bobina A
IN2D9Bobina B
IN3D10Bobina C
IN4D11Bobina D
VCC / GND da placa5 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):

PassoIN1IN2IN3IN4
11100
20110
30011
41001

Ângulo por passo no eixo de saída com 2048 passos/volta:

θpasso=360°2048≈0,176°/passo\theta_{passo} = \frac{360°}{2048} \approx 0{,}176°/\text{passo}

📦 Bibliotecas desta lição: Stepper — embutida na IDE, nada a baixar.

  • Instalação: nenhuma. Confira em Arquivo > Exemplos > Stepper > stepper_oneRevolution que 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.

ItemQtd
Base Lição 31 (Uno + 28BYJ + ULN2003)1
Receptor IR + controle1 cada
Fonte protoboard + adaptador 9 V/1 A1 cada
JumpersForça + sinal IR
Receptor IRUno
VCC5 V
GNDGND comum com fonte externa
OUTD2 (interrupção da IRremote)
ULN2003Uno/Fonte
IN1–IN4D8–D11 (lógica)
VCC placa5 V da fonte de protoboard (não do USB em carga)
GND placaGND comum (Uno + fonte)

📦 Bibliotecas desta lição: Stepper (embutida, já conferida na Lição 31) + IRremote 2.8.1 (mesma da Lição 22).

  • Instalação: nenhuma ação nova se as Lições 22 e 31 já compilam. Se IRremote.h der No such file, repetir o quadro da Lição 22 fixando a versão 2.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.

ItemQtd
Uno R31
28BYJ-48 + ULN20031 conjunto
Encoder rotativo (CLK/DT/SW/VCC/GND)1
Jumpers F-M9 (4 motor + 5 encoder)
EncoderUnoLeitura
VCC (+)5 VPull-ups do módulo
GNDGNDComum
CLKD2Canal A (interrupção externa)
DTD3Canal B (direção)
SWD4 (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.

PassoVerificação Pré-EnergizaçãoCritério de Aprovação
1Cabo USB é de dados e está na mesma porta de semprePorta da Uno aparece em Ferramentas > Porta e some ao desplugar
2Placa Arduino Uno selecionada, nada em D0/D1Upload do Blink funciona e LED L pisca
3Bibliotecas da lição instaladas e IDE reiniciadaExemplo da lib compila sem No such file
4Trilhos de força conferidos (5 V, 3V3, GND) com multímetro ou LED de teste5 V onde é 5 V, 3,3 V onde é 3,3 V (ADXL335, RC522), GND contínuo
5Polaridades (LED, buzzer, diodo, transistor, relé, motor) contra a tabela da liçãoFaixa do diodo ao +, base via resistor, anodo longo ao +
6Fontes externas ligadas por último, com GND comumMotor/relé/passo com força própria, lógica sem queda
7Trimpots 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.

SintomaCausa Raiz Mais ProvávelAção Corretiva (nesta ordem)
avrdude: stk500_recv() / porta cinzaCabo só-carga, driver CH340 ausente, placa/porta erradasTrocar 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 acontecePorta de outro dispositivo / exemplo erradoReselecionar COM /dev/ttyUSB; regravar Blink da Lição 2 e observar LED L
No such file or directory / does not name a typeBiblioteca não instalada ou pasta duplaReinstalar pela Lição 1 (Manager/ZIP/manual); pasta deve ser libraries/Nome/Nome.h; reiniciar IDE
LED não acende / invertidoPolaridade ou resistor abertoPerna longa ao + via 220 Ω; testar LED em 5 V+GND direto com resistor; trocar fileira da protoboard
RGB com cor faltandoPino sem ~ ou resistor ausenteUsar D9/D10/D11 com 220 Ω por cor; comum (mais longo) ao GND (catodo comum)
Botão liga sozinho / invertidoSem INPUT_PULLUP ou pernas no mesmo ladoUsar INPUT_PULLUP (LOW=pressionado); pernas em lados opostos do canal
595 com LEDs tremendo/fora de ordemLatch invertido ou LSB/MSB trocadoLOW→shiftOut→HIGH; testar LSBFIRST vs MSBFIRST; OE ao GND, MR+Vcc em 5 V
Monitor Serial com hieróglifosBaud divergenteIDE e monitor em 9600; Serial.begin(9600)
Barra LDR invertida / travadaDivisor trocado ou A0 erradoLDR ao 5 V, 1 kΩ ao GND, meio em A0; reading/57; testar cobrindo/soprando luz
Buzzer ativo mudoCápsula trocada (passivo no lugar)Ativo = fita preta (CC apita); passivo = placa verde (precisa tone())
Escala desafinada / mudaSem pitches.h ou analogWrite no lugar de toneInstalar lib de tons; usar tone(pino,freq,dur) pino D8
Tilt nunca mudaOrientação travada ou jumper soltoGirar 90° além de ~20°; D2 com pull-up até GND via chave; delay(200) anti-repique
Relé chia sem comutar / Uno resetaFonte fraca, GND não comum, sem flybackFonte externa 9 V com GND comum; 1N4007 faixa ao +; 220 Ω na base; só motor 6 V nos contatos
7-seg embaralhado / invertidoMapa Q→segmento ou anodo/catodo trocadoConferir Q0–Q7→A–G–DP pino a pino; catodo (3/8) ao GND, anodo a 5 V + tabela complementar
4 dígitos com fantasma / fracoSem blanking ou corrente baixaDesligar dígito entre varreduras; delay(5); 50 Hz mínimo; resistores por dígito
Servo tremendo / estalandoFonte 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 / apagadoContraste ou begin / backlightGirar pot VO; lcd.begin(16,2); A/K em 5 V/GND; lcd(7,8,9,10,11,12)
Temp travada em 0/1023Sensor sem força ou pino erradoTMP36 VCC/GND + OUT em A0; (V-0.5)*100; reescrever linha inteira contra fantasma
HC-SR04 zero / pulandoSem eco ou ciclo <60 msAlvo plano a 20 cm; delay(100); Trig 10 µs + pulseIn com timeout; cm=t/58
Teclado repete / troca teclaMembrana frouxa ou mapa trocadoReencaixar 8 vias; conferir R1–R4/C1–C4 vs makeKeymap; testar no Serial antes do LCD
DHT11 NaNIntervalo <2 s ou DATA erradodelay(2000); DATA em D2 com pull-up; VCC 5 V
Joystick fora do centroVcc fraco ou fim de cursoCentro ~512±50; Vcc 5 V; X=A0 Y=A1 SW=D2 pull-up
IR sem HEXPino sem suporte, sol ou bateriaOUT em D11/D2 conforme lib; <5 m sem sol; trocar bateria; anotar hex do seu lote
Matriz apagada / flickershutdown ou brilho/fonteshutdown(0,false); setIntensity(0,8); DIN/CS/CLK = D12/D11/D10; USB forte
ADXL335 saturado / quenteAlimentado em 5 VDesligar e pôr em 3V3 (limite 3,6 V); X=A0 Y=A1 Z=A2; parado Z≈+1 g
PIR dispara sozinho / mortoSem calibração ou mira ruim60 s parado após ligar; sens/tempo no meio; mirar passagem, não janela/sol
Nível sempre 0 / derivaSonda seca/oxidada ou AO/DO trocadoImergir 1–3 cm; AO em A0; secar após teste; calibrar vazio/cheio
DS3231 não encontrado / hora voltaSDA/SCL trocados ou adjust repetidoSDA=A4 SCL=A5; ajustar uma vez e comentar adjust depois
Som saturado / DO presoGanho/limiar no extremoTrimpot até LED de bordo piscar só na palma; AO em A0 + Plotter
RFID não lê / esquentaVCC 5 V ou SPI frouxoVCC em 3V3; SDA=D10 RST=D9 MOSI=D11 MISO=D12 SCK=D13; tag a 0–3 cm paralela
Motor DC parado com chiado / resetSem torque de partida ou sem diodo/GND comumPartir de ~30 % PWM; 1N4007 faixa ao +; GND externo = GND Uno; fonte externa
Passo vibra sem girarSequência/fio errado ou rpm altaOrdem 8,10,9,11; 10 rpm; 4 jumpers firmes; fonte externa sob carga
Passo+IR morto (IR vivo)Força sem GND comumFonte 9 V ligada + GND comum; OUT IR em D2; remapear hex do seu controle
Encoder invertido / duploConvenção do lote ou repiqueTrocar ++/-- 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.