Sebenta · Arduino e artefactos tangíveis (UC02842)
- Introdução
- 1. Arduino — plataforma e ecossistema
- 2. Setup
- 3. Estrutura de um sketch Arduino
- 4. Pinos digitais — output e input
- 5. Pinos analógicos — sensores
- 6. PWM — analog output
- 7. Motores e movimento
- 8. Displays
- 9. Comunicação
- 10. Multi-tarefas — millis() em vez de delay()
- 11. Boas práticas
- 12. Projectos de inspiração
- 13. Recursos
- 14. Próximos passos
- Glossário
Introdução
Arduino é a plataforma que democratizou a electrónica programada. Lançada em 2005 em Ivrea (Itália) por um grupo de designers e engenheiros, partia de um princípio simples: dar a artistas e estudantes uma forma acessível de combinar código e hardware. Vinte anos depois, é o standard educativo, de prototipagem e de DIY em todo o mundo.
Esta sebenta cobre Arduino na perspectiva de artefactos tangíveis — projectos que vivem no mundo físico: instalações interactivas, automações domésticas, robôs, estações sensoriais. Vais aprender a controlar LEDs, ler sensores, mover motores, fazer comunicar dispositivos, e juntar tudo em projectos completos.
Não precisas de background em electrónica. Cada conceito é apresentado com analogia, código mínimo e exemplos.
1. Arduino — plataforma e ecossistema
O que é
"Arduino" é três coisas ao mesmo tempo:
- Hardware: boards (Uno, Nano, Mega, etc.) com microcontrolador.
- Software: IDE para escrever código (C/C++) e fazer upload.
- Ecossistema: comunidade, libraries, shields, tutoriais.
Open source — qualquer pessoa pode fabricar clones (e há muitos).
Boards principais
| Board | Microcontrolador | Pinos | Memória | Preço |
|---|---|---|---|---|
| Uno R3 | ATmega328P | 14 dig + 6 ana | 32KB Flash | €25 |
| Uno R4 WiFi | RA4M1 | idem | 256KB | €30 |
| Nano | ATmega328P | idem | 32KB | €15 |
| Mega 2560 | ATmega2560 | 54 dig + 16 ana | 256KB | €40 |
| Leonardo | ATmega32U4 | 20 dig + 12 ana | 32KB | €25 |
| ESP32 | ESP32-WROOM | 30+ | 4MB + WiFi | €10 |
| Pico | RP2040 | 26 | 2MB | €5 |
Para esta UC: Uno R3 ou compatible. Mais robusto para iniciantes (alimentação 5V, mais tolerante a erros).
Onde se usa
- Educação STEM em escolas (do básico ao superior).
- Prototipagem industrial — antes de fabricar PCB própria.
- Instalações interactivas (museus, arte digital).
- Domótica DIY (luzes, persianas, alarmes).
- Estações meteorológicas e ambientais.
- Robótica amadora.
- Wearables (e-textiles).
- Saúde (monitores baratos para investigação).
Limites
Não é para: - Aplicações industriais críticas (usa PLCs). - Processamento de imagem ou ML pesado (usa Raspberry Pi / Jetson). - Produção em massa de produtos (usa microcontrolador directo, sem placa Arduino).
Mas como plataforma de aprendizagem e prototipagem — imbatível.
2. Setup
Hardware necessário
Kit básico Arduino (€30-50): - Arduino Uno. - Cabo USB-B. - Breadboard. - Jumper wires (M-M, M-F). - LEDs vários (5mm vermelho, verde, azul). - Resistências (220Ω, 1kΩ, 10kΩ). - Botões de pressão. - Potenciómetros. - Sensor (LDR, TMP36, HC-SR04). - Servo motor SG90.
Software
Arduino IDE 2.x (gratuita): arduino.cc/en/software.
Após instalar:
1. Liga Uno via USB.
2. Tools → Board → Arduino Uno.
3. Tools → Port → escolher (/dev/ttyACM0, /dev/cu.usbserial-..., COM3).
4. File → Examples → Basics → Blink → verificar/upload.
Se LED da board (TX/RX, L) pisca brevemente no upload, está tudo bem.
Alternativa: PlatformIO em VSCode
Para projectos maiores: - Auto-completion melhor. - Library management. - Git-friendly (vs sketches single file).
# VSCode → install extension "PlatformIO IDE"
# Cria projecto → escolher board → editar src/main.cpp
Online IDE
Wokwi (wokwi.com): simulador Arduino online — útil sem hardware.
Hello world: Blink
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
}
LED_BUILTIN é o pino 13 (Uno tem LED ligado a esse pino).
Click Upload (seta). Após uns segundos, LED pisca a 1Hz.
3. Estrutura de um sketch Arduino
// Variáveis globais e constantes
const int LED_PIN = 13;
int counter = 0;
void setup() {
// Corre UMA VEZ no arranque (reset ou power-on)
pinMode(LED_PIN, OUTPUT);
Serial.begin(9600); // comunicação USB
Serial.println("Iniciado!");
}
void loop() {
// Corre INFINITAMENTE em loop após setup()
digitalWrite(LED_PIN, HIGH);
delay(500);
digitalWrite(LED_PIN, LOW);
delay(500);
counter++;
Serial.print("Loops: ");
Serial.println(counter);
}
A linguagem é C++ com algumas conveniências:
- setup() e loop() obrigatórios.
- Tipos: int, byte, boolean, float, String, etc.
- Funções built-in: pinMode(), digitalRead/Write(), analogRead/Write(), delay(), millis().
Sketch em múltiplos ficheiros
Para projectos maiores, abre Sketch → Add File ou cria tabs. Cada tab é um ficheiro .ino, .h ou .cpp na pasta do sketch.
4. Pinos digitais — output e input
Output: piscar LED
Hardware:
Pino 8 ────[Resistor 220Ω]────[ânodo LED ▶ cátodo]──── GND
Importante: sempre resistência em série com LED. Sem ela, LED queima (puxa corrente excessiva).
LED tem polaridade: - Ânodo (+, perna longa). - Cátodo (-, perna curta, lado com flat na lente).
Código:
const int LED = 8;
void setup() {
pinMode(LED, OUTPUT);
}
void loop() {
digitalWrite(LED, HIGH); // 5V
delay(500);
digitalWrite(LED, LOW); // 0V
delay(500);
}
Input: botão
Hardware (com resistência pull-up externa):
5V ──[10kΩ]──┬── Pino 2
│
[Botão]
│
GND
Quando botão solto: pino lê HIGH (5V via pull-up). Quando premido: pino lê LOW (curto-circuito com GND).
Código com pull-up externa:
const int BUTTON = 2;
const int LED = 8;
void setup() {
pinMode(BUTTON, INPUT);
pinMode(LED, OUTPUT);
}
void loop() {
int s = digitalRead(BUTTON);
digitalWrite(LED, s == LOW ? HIGH : LOW);
}
Pull-up interna (mais fácil)
Arduino tem resistências pull-up internas — usá-las e poupar a externa:
void setup() {
pinMode(BUTTON, INPUT_PULLUP); // ← liga pull-up interna
pinMode(LED, OUTPUT);
}
Botão liga directo entre pino e GND. Sem necessidade da resistência 10kΩ.
Debounce — botões "tremem"
Quando carregas num botão mecânico, os contactos ressaltam alguns ms — produzindo várias transições falsas. Para detectar "click" correctamente:
const int BUTTON = 2;
int lastState = HIGH;
unsigned long lastChange = 0;
const unsigned long DEBOUNCE = 50; // ms
void loop() {
int s = digitalRead(BUTTON);
if (s != lastState && millis() - lastChange > DEBOUNCE) {
lastChange = millis();
lastState = s;
if (s == LOW) {
Serial.println("CLICK");
}
}
}
Library Bounce2 automatiza isto.
5. Pinos analógicos — sensores
Analog input (A0-A5)
Pinos com prefixo A lêem tensão entre 0V e 5V com resolução de 10 bits → valor 0-1023.
const int POT = A0;
void setup() {
Serial.begin(9600);
}
void loop() {
int raw = analogRead(POT);
float volts = raw * (5.0 / 1023.0);
Serial.print("Raw: ");
Serial.print(raw);
Serial.print(" | ");
Serial.print(volts, 2);
Serial.println(" V");
delay(200);
}
Sensor TMP36 (temperatura)
Cabeça plana virada para ti: - Pino esquerdo → 5V. - Pino do meio → A0. - Pino direito → GND.
void loop() {
int raw = analogRead(A0);
float volts = raw * (5.0 / 1023.0);
float temp = (volts - 0.5) * 100.0; // TMP36 datasheet
Serial.print(temp, 1);
Serial.println(" °C");
delay(1000);
}
TMP36: 0.5V a 0°C, 10mV/°C. Por isso a fórmula.
LDR (foto-resistência)
Divisor de tensão com LDR + resistor 10kΩ:
5V ── LDR ── A0
│
10kΩ
│
GND
Mais luz = LDR menos resistente = leitura maior.
void loop() {
int luz = analogRead(A0);
if (luz < 300) Serial.println("Escuro");
else if (luz < 700) Serial.println("Médio");
else Serial.println("Brilhante");
delay(300);
}
HC-SR04 (distância ultrassónica)
4 pinos: VCC (5V), Trig, Echo, GND.
const int TRIG = 9, ECHO = 10;
void setup() {
pinMode(TRIG, OUTPUT);
pinMode(ECHO, INPUT);
Serial.begin(9600);
}
float medirDistancia() {
digitalWrite(TRIG, LOW);
delayMicroseconds(2);
digitalWrite(TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG, LOW);
long duracao = pulseIn(ECHO, HIGH);
float cm = duracao * 0.0343 / 2; // velocidade som 343 m/s
return cm;
}
void loop() {
float d = medirDistancia();
Serial.print(d, 1);
Serial.println(" cm");
delay(200);
}
Range típico: 2cm-400cm. Útil para sensores de presença, parking, robots.
DHT22 (temperatura + humidade)
Sensor digital mais fiável que TMP36. Requer library:
Tools → Manage Libraries → "DHT sensor library" by Adafruit.
#include <DHT.h>
#define DHT_PIN 2
#define DHT_TYPE DHT22
DHT dht(DHT_PIN, DHT_TYPE);
void setup() {
Serial.begin(9600);
dht.begin();
}
void loop() {
float h = dht.readHumidity();
float t = dht.readTemperature();
if (isnan(h) || isnan(t)) {
Serial.println("Erro");
return;
}
Serial.print(t, 1); Serial.print("°C, ");
Serial.print(h, 1); Serial.println("%");
delay(2000); // mínimo 1s entre leituras
}
6. PWM — analog output
O que é PWM
Pinos digitais não conseguem "5V parcial". Mas com Pulse Width Modulation (PWM) podes simular tensão variável ligando e desligando muito rápido com duty cycle variável.
- 0% duty = pino sempre off = 0V efectivo.
- 50% duty = on metade do tempo = 2.5V efectivo.
- 100% duty = sempre on = 5V efectivo.
analogWrite(pino, valor): valor 0-255 (mapeia para 0-100% duty).
Só funciona em pinos PWM: 3, 5, 6, 9, 10, 11 no Uno (marcados com ~).
LED fade
const int LED = 9;
void setup() {
pinMode(LED, OUTPUT);
}
void loop() {
// Acender progressivamente
for (int v = 0; v <= 255; v++) {
analogWrite(LED, v);
delay(5);
}
// Apagar progressivamente
for (int v = 255; v >= 0; v--) {
analogWrite(LED, v);
delay(5);
}
}
Controlar LED com potenciómetro
void loop() {
int raw = analogRead(A0); // 0-1023
int brilho = map(raw, 0, 1023, 0, 255);
analogWrite(LED, brilho);
}
map() converte de um range para outro — função muito útil.
7. Motores e movimento
Servo motor (SG90 e similares)
Servos são motores DC + caixa redutora + encoder + controlador. Aceitam posição alvo (0-180°).
SG90 cabos:
Castanho/preto → GND
Vermelho → 5V (ou fonte externa para servos grandes)
Laranja/amarelo → pino digital
#include <Servo.h>
Servo servo;
void setup() {
servo.attach(9);
}
void loop() {
servo.write(0); delay(1000);
servo.write(90); delay(1000);
servo.write(180); delay(1000);
}
Library Servo.h já vem com o IDE.
Controlo com potenciómetro:
void loop() {
int raw = analogRead(A0);
int ang = map(raw, 0, 1023, 0, 180);
servo.write(ang);
delay(20);
}
Motor DC bidireccional (ponte H L293D)
Servo só dá posição; motor DC dá rotação contínua. Para controlar direcção precisas de ponte H (chip L293D ou módulo L298N).
L293D:
IN1, IN2 → pinos digitais Arduino (controlo direcção)
EN1 (PWM) → pino PWM Arduino (controlo velocidade)
OUT1, OUT2 → motor
VCC1 (5V), VCC2 (fonte motor), GND (comum)
const int IN1 = 7, IN2 = 8, EN = 9;
void setup() {
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(EN, OUTPUT);
}
void frente(int v) {
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
analogWrite(EN, v); // 0-255
}
void tras(int v) {
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
analogWrite(EN, v);
}
void parar() {
analogWrite(EN, 0);
}
void loop() {
frente(200); delay(2000);
parar(); delay(500);
tras(200); delay(2000);
parar(); delay(500);
}
Sempre alimentar motor com fonte externa (não USB do Arduino — puxa demasiada corrente).
Stepper motors
Para precisão absoluta (impressoras 3D, CNC). Usar Stepper.h ou AccelStepper.h.
8. Displays
LCD 16x2 (com I2C)
LCDs originais Hitachi têm 16 pinos — confuso. Hoje vendidos com módulo I2C (PCF8574) atrás — usa só 4 fios.
LCD I2C: GND, VCC, SDA (A4 no Uno), SCL (A5)
Instalar library "LiquidCrystal_I2C" (procurar em Library Manager).
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
void setup() {
lcd.init();
lcd.backlight();
lcd.print("Hello World!");
lcd.setCursor(0, 1);
lcd.print("Linha 2");
}
void loop() {
lcd.setCursor(8, 1);
lcd.print(millis() / 1000);
delay(1000);
}
Endereço I2C: normalmente 0x27 ou 0x3F. Se nada aparecer, corre i2c_scanner (sketch popular) para descobrir.
OLED SSD1306 (128x64)
Display monocromático bonito, alto contraste, baixo consumo.
OLED I2C: GND, VCC (3.3V ou 5V), SDA (A4), SCL (A5)
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
Adafruit_SSD1306 display(128, 64, &Wire, -1);
void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Hello!");
display.setTextSize(1);
display.println("Texto pequeno");
display.drawRect(0, 40, 100, 20, SSD1306_WHITE);
display.fillCircle(110, 50, 8, SSD1306_WHITE);
display.display(); // OBRIGATÓRIO para mostrar
}
void loop() {}
Libraries: Adafruit_GFX (gráficos genéricos) + Adafruit_SSD1306 (driver).
Outros displays
- 7-segment: clássico para números (TM1637).
- Matriz LED 8x8 (MAX7219): scroll text, animations.
- TFT 1.8" / 2.4": a cores, mais cars.
- E-ink: muito eficiente em consumo (Waveshare).
9. Comunicação
Serial — debug essencial
Cada Arduino tem UART (Universal Asynchronous Receiver-Transmitter) → comunicação serial via USB.
void setup() {
Serial.begin(9600); // baud rate (deve match com Serial Monitor)
}
void loop() {
Serial.println("Hello");
Serial.print("Valor: ");
Serial.println(analogRead(A0));
delay(1000);
}
Tools → Serial Monitor (Ctrl+Shift+M). Define mesma baud rate.
Receber dados via Serial
void loop() {
if (Serial.available()) {
String linha = Serial.readStringUntil('\n');
linha.trim();
if (linha == "on") {
digitalWrite(LED, HIGH);
} else if (linha == "off") {
digitalWrite(LED, LOW);
} else {
Serial.print("Recebido: ");
Serial.println(linha);
}
}
}
Para enviar comandos do PC: no Serial Monitor, escreve no campo de cima e Enter.
I2C — dois fios para muitos dispositivos
Bus I2C tem dois fios: SDA (data) e SCL (clock). Vários dispositivos partilham — cada um com endereço único (7 bits).
No Uno: A4 = SDA, A5 = SCL.
#include <Wire.h>
void setup() {
Wire.begin();
Serial.begin(9600);
}
// Scanner I2C
void loop() {
for (int addr = 1; addr < 127; addr++) {
Wire.beginTransmission(addr);
byte err = Wire.endTransmission();
if (err == 0) {
Serial.print("Encontrado em 0x");
Serial.println(addr, HEX);
}
}
delay(5000);
}
SPI — mais rápido, 4 fios
Para SD cards, displays grandes, alguns sensores rápidos. Pinos no Uno: 10 (SS), 11 (MOSI), 12 (MISO), 13 (SCK). Library <SPI.h>.
WiFi (precisa de board com WiFi)
Uno R4 WiFi, Nano 33 IoT, ESP32, ESP8266.
// Para ESP32
#include <WiFi.h>
const char* ssid = "Aulify-WiFi";
const char* pass = "secret";
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nConnected!");
Serial.println(WiFi.localIP());
}
Daí abre-se mundo IoT (UC00643).
10. Multi-tarefas — millis() em vez de delay()
delay() bloqueia tudo durante esse tempo. Para fazer várias coisas "ao mesmo tempo", usar millis():
unsigned long lastBlink = 0;
unsigned long lastSensor = 0;
unsigned long lastDisplay = 0;
bool ledOn = false;
void loop() {
unsigned long now = millis();
// Pisca LED a cada 500ms
if (now - lastBlink >= 500) {
lastBlink = now;
ledOn = !ledOn;
digitalWrite(LED, ledOn ? HIGH : LOW);
}
// Lê sensor a cada 1000ms
if (now - lastSensor >= 1000) {
lastSensor = now;
int v = analogRead(A0);
Serial.println(v);
}
// Actualiza display a cada 2000ms
if (now - lastDisplay >= 2000) {
lastDisplay = now;
updateDisplay();
}
}
millis() retorna ms desde o reset. Overflow após ~50 dias, mas a subtracção mantém-se correcta por aritmética unsigned.
11. Boas práticas
Hardware
- Desliga antes de modificar circuitos.
- Resistência sempre com LED (220-330Ω para 5V).
- Polaridade: LEDs, capacitores electrolíticos, diodos, ICs (pino 1 marcado).
- GND comum entre tudo (sem isto, nada funciona consistente).
- Pull-up/pull-down em entradas digitais (senão flutuam).
- Decoupling caps (100nF) perto de IC para suprimir ruído.
- Não passar limites de corrente: max 40mA por pino, 200mA total no chip.
Código
- Constantes com
const(mais legível que#define). - Comentários generosos — sketches "tornam-se hieróglifos" sem.
- Funções para tarefas repetidas.
millis()em vez dedelay()para multi-tasking.- Variables com nome significativo.
pinMode()explícito no setup, mesmo se default (INPUT).
Workflow
- Começar simples (Blink) e adicionar uma coisa de cada vez.
- Testar com Serial.println() em cada passo novo.
- Backup antes de mudanças grandes (git, ou cópia da pasta).
- Libraries confiáveis (Adafruit, popular GitHub repos).
12. Projectos de inspiração
- Estação meteorológica: DHT22 + BMP280 + LCD/OLED + WiFi (envia a Thingspeak).
- Controlo de iluminação: PIR + relés + WiFi + Home Assistant.
- Robô seguidor de linha: 2 motores DC + sensores IR + L293D.
- Smart vaso de plantas: sensor humidade solo + bomba água + LCD.
- Theremin DIY: ultrassom + buzzer (controla nota pela distância da mão).
- Câmara digital simples: ESP32-CAM + OLED + botão.
- Bin organizer: HC-SR04 mede nível, LED notifica quando cheio.
- Wearable LED: NeoPixel ring + bateria + acelerómetro (reage a movimento).
- Game console retro: Pico + LCD + botões (snake, pong).
13. Recursos
Aprendizagem
- Arduino docs (arduino.cc/reference/en): referência completa de funções.
- Arduino Project Hub (projecthub.arduino.cc): projectos da comunidade.
- Adafruit Learning System (learn.adafruit.com): tutoriais excelentes.
- Random Nerd Tutorials (randomnerdtutorials.com): ESP32, ESP8266.
- Paul McWhorter no YouTube: série de aulas Arduino.
- Andreas Spiess ("the guy with the Swiss accent"): IoT prático.
Compra
- Bot'n Roll (Portugal): kits educativos.
- Mauser Electrónica: componentes individuais PT.
- AliExpress / Banggood: barato, 2-4 semanas envio.
- Mouser / Digi-Key: profissional, EUA/EU.
- Pimoroni (UK): kits criativos.
Simulador
- Wokwi (wokwi.com): browser-based, gratuito.
- Tinkercad Circuits (tinkercad.com): mais simples, óptimo para escolas.
14. Próximos passos
- ESP32 / ESP8266: WiFi + Bluetooth → IoT.
- CircuitPython ou MicroPython: Python em microcontroladores.
- Raspberry Pi: Linux completo, mais poderoso.
- PCB design: KiCad, EasyEDA para circuitos custom.
- Robótica avançada: ROS (Robot Operating System).
- Sinais e DSP: FFT, filtros, áudio.
- RTOS: FreeRTOS em ESP32 para tarefas concorrentes verdadeiras.
Glossário
- MCU: Microcontrolador.
- Pin: pino de I/O.
- Sketch: ficheiro de código Arduino.
- Bootloader: pequeno programa que permite upload via USB.
- HIGH/LOW: estados digitais (5V/0V em Uno).
- PWM: Pulse Width Modulation (saída analog simulada).
- ADC: Analog-to-Digital Converter (analogRead).
- DAC: Digital-to-Analog (não tem em Uno, tem em Nano 33).
- Pull-up / Pull-down: resistência que define estado padrão.
- Debounce: filtrar transições falsas de botões.
- Library: package de código reutilizável.
- Shield: placa que encaixa em cima do Arduino.
- Datasheet: PDF com specs de um componente.
Arduino é o melhor sítio para começar electrónica programada. A combinação de hardware barato + software acessível + comunidade enorme torna a curva de aprendizagem suave mas profunda. Em 50 horas vais conseguir construir projectos genuinamente úteis. Em 500 horas dominas as bases para qualquer carreira em embedded, IoT ou robótica.