UC02842

Artefactos tangíveis — Arduino

Sensores, actuadores, electrónica criativa

Curso profissional · 50h · Hardware + código

Plano

  1. Arduino — landscape
  2. Setup e primeiro sketch
  3. Digital I/O — LEDs e botões
  4. Analog I/O — sensores
  5. PWM, motores, servos
  6. LCD, OLED, displays
  7. Comunicação série, I2C, SPI
  8. Projecto integrado

Bloco 1 · O que é Arduino

Arduino — visão geral

  • Plataforma open-source de microcontroladores.
  • Fundada em 2005 em Ivrea, Itália.
  • Hardware barato (€5-€30 por board) + IDE gratuita.
  • Comunidade enorme, milhares de tutoriais e libraries.

Para makers, estudantes, artistas, engenheiros — quem queira mexer em electrónica + código.

Boards populares

  • Arduino Uno (R3 ou R4): clássico, recomendado para começar.
  • Arduino Nano: pequeno, breadboard-friendly.
  • Arduino Mega: mais pinos, projectos grandes.
  • Arduino Leonardo: USB nativo (pode ser teclado/rato).
  • ESP32 / ESP8266: WiFi + Bluetooth integrados (IoT).
  • Raspberry Pi Pico: alternativa moderna RP2040.

Onde se usa

  • Educação: STEM em escolas.
  • Prototipagem: produtos antes de fabricar.
  • Arte interactiva: instalações museológicas.
  • DIY: domótica, estações meteorológicas.
  • Robótica: amador e académico.
  • Industrial light: PoCs e instrumentação.

Bloco 2 · Setup

IDE + driver

  1. Download Arduino IDE 2.x em arduino.cc.
  2. Liga Uno via USB.
  3. Tools → Board → Arduino Uno.
  4. Tools → Port → selecciona (/dev/ttyUSB0, COM3, etc.).

Alternativa moderna: VSCode + PlatformIO.

// O LED interno (pino 13) pisca cada segundo.

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);
  delay(1000);
  digitalWrite(LED_BUILTIN, LOW);
  delay(1000);
}

Click Upload (seta). LED pisca.

Estrutura de um sketch

// Variáveis globais
int pinoLED = 13;

void setup() {
  // Corre 1 vez no arranque
  pinMode(pinoLED, OUTPUT);
  Serial.begin(9600);    // comunicação série
}

void loop() {
  // Corre repetidamente para sempre
  digitalWrite(pinoLED, HIGH);
  Serial.println("LED ON");
  delay(500);
  digitalWrite(pinoLED, LOW);
  delay(500);
}

Bloco 3 · Digital I/O

LED externo

Pino 8 ──[R 220Ω]──[LED+ → LED-]── GND
const int LED = 8;

void setup() {
  pinMode(LED, OUTPUT);
}

void loop() {
  digitalWrite(LED, HIGH);
  delay(500);
  digitalWrite(LED, LOW);
  delay(500);
}

Sempre resistência (220-330Ω) com LEDs (senão queimam).

Botão como input

5V ──[R 10kΩ pull-up]──┬── Pino 2
                       │
                      [Botão]
                       │
                      GND

Ou usar pull-up interna:

const int BOTAO = 2;
const int LED = 8;

void setup() {
  pinMode(BOTAO, INPUT_PULLUP);
  pinMode(LED, OUTPUT);
}

void loop() {
  int estado = digitalRead(BOTAO);
  // INPUT_PULLUP: HIGH = solto, LOW = premido
  digitalWrite(LED, estado == LOW ? HIGH : LOW);
}

Debounce

Botões mecânicos "ressaltam" — várias leituras a cada toque.

int estadoAnterior = HIGH;
unsigned long ultimoToque = 0;
const unsigned long DEBOUNCE_MS = 50;

void loop() {
  int estado = digitalRead(BOTAO);
  
  if (estado != estadoAnterior 
      && millis() - ultimoToque > DEBOUNCE_MS) {
    ultimoToque = millis();
    if (estado == LOW) {
      // Premiu
      Serial.println("Click!");
    }
    estadoAnterior = estado;
  }
}

Bloco 4 · Analog I/O

Analog input (sensores)

Pinos A0-A5: leem 0-5V → valor 0-1023 (10 bits).

const int POT = A0;

void setup() {
  Serial.begin(9600);
}

void loop() {
  int valor = analogRead(POT);
  float voltagem = valor * (5.0 / 1023.0);
  Serial.print("Raw: ");
  Serial.print(valor);
  Serial.print(" → ");
  Serial.print(voltagem, 2);
  Serial.println("V");
  delay(200);
}

Sensores comuns

  • Potenciómetro: tensão variável manual.
  • LDR (foto-resistência): mede luz.
  • NTC: termistor (temperatura).
  • TMP36: temperatura linear precisa.
  • MQ-x: gases.
  • HC-SR04: distância ultrassónica.
  • DHT11/22: temperatura + humidade.
  • MPU6050: acelerómetro + giroscópio.

Sensor de temperatura TMP36

TMP36: pino + → 5V
       pino sinal → A0
       pino - → GND
void loop() {
  int raw = analogRead(A0);
  float voltagem = raw * (5.0 / 1023.0);
  float tempC = (voltagem - 0.5) * 100.0;
  
  Serial.print("Temp: ");
  Serial.print(tempC, 1);
  Serial.println(" °C");
  delay(1000);
}

DHT22 (mais fiável)

#include <DHT.h>

#define DHT_PIN 2
DHT dht(DHT_PIN, DHT22);

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 de leitura!");
    return;
  }
  
  Serial.print(t, 1);
  Serial.print("°C, ");
  Serial.print(h, 1);
  Serial.println("%");
  delay(2000);
}

Instalar library "DHT sensor library" (Tools → Manage Libraries).

Bloco 5 · PWM, motores, servos

PWM — analogWrite

Pinos com "~" (3, 5, 6, 9, 10, 11) suportam PWM.

analogWrite(pin, valor) — valor 0 (off) a 255 (full).

// LED fade
const int LED = 9;

void setup() {
  pinMode(LED, OUTPUT);
}

void loop() {
  for (int v = 0; v <= 255; v++) {
    analogWrite(LED, v);
    delay(10);
  }
  for (int v = 255; v >= 0; v--) {
    analogWrite(LED, v);
    delay(10);
  }
}

Servo motor

#include <Servo.h>

Servo meuServo;

void setup() {
  meuServo.attach(9);
}

void loop() {
  // Varrer 0° → 180°
  for (int ang = 0; ang <= 180; ang += 5) {
    meuServo.write(ang);
    delay(50);
  }
  // E voltar
  for (int ang = 180; ang >= 0; ang -= 5) {
    meuServo.write(ang);
    delay(50);
  }
}

Servos: 5V, GND, sinal. Library <Servo.h> built-in.

Motor DC com transistor / ponte H

  • LED é fraco — pode ligar directo ao pino.
  • Motor DC puxa muita corrente — usar transistor (BC547, 2N2222) ou ponte H (L293D, L298N).
  • Para bidireccional: ponte H obrigatória.
// L293D — controlar motor
const int IN1 = 7, IN2 = 8, EN = 9;

void setup() {
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(EN, OUTPUT);
}

void andarFrente(int velocidade) {
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  analogWrite(EN, velocidade);   // 0-255
}

Bloco 6 · Displays

LCD 16x2 (HD44780, com I2C)

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);

void setup() {
  lcd.init();
  lcd.backlight();
  lcd.print("Ola mundo!");
  lcd.setCursor(0, 1);
  lcd.print("Linha 2");
}

void loop() {}

Endereço I2C varia (0x27, 0x3F). Sketch i2c_scanner detecta-o.

OLED (SSD1306)

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define WIDTH 128
#define HEIGHT 64
Adafruit_SSD1306 display(WIDTH, HEIGHT, &Wire, -1);

void setup() {
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.print("Olá!");
  display.display();
}

void loop() {}

Bonitos, monocromáticos, baixo consumo. €3-5.

Bloco 7 · Comunicação

Serial — debug

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.print("Valor: ");
  Serial.println(analogRead(A0));
  delay(500);
}

Serial Monitor (Tools → Serial Monitor, 9600 baud) mostra output.

Util para debugging — Serial.println() em vez de print do Python.

I2C — dois fios (SDA, SCL)

Protocolo para vários dispositivos com 2 fios. Cada dispositivo tem endereço único.

Comum em: LCDs, OLEDs, RTCs, sensores BME280/MPU6050.

#include <Wire.h>

void setup() {
  Wire.begin();   // master
  Serial.begin(9600);
}

// I2C scanner para encontrar dispositivos
void loop() {
  for (int a = 1; a < 127; a++) {
    Wire.beginTransmission(a);
    if (Wire.endTransmission() == 0) {
      Serial.print("Found: 0x");
      Serial.println(a, HEX);
    }
  }
  delay(5000);
}

SPI — mais rápido, 4 fios

MISO, MOSI, SCK, SS. Para SD cards, displays grandes, sensores rápidos.

Library <SPI.h> para o bus, library do dispositivo para o protocolo.

Bloco 8 · Boas práticas

Hardware

  • Sempre desligar antes de mexer em fios.
  • Polaridade: LEDs, capacitores electrolíticos, ICs.
  • Resistências de protecção em LEDs (220-330Ω) e bases de transistores.
  • Pull-ups/pull-downs em entradas (evita flutuar).
  • GND comum entre tudo.
  • Tensão certa (5V Uno, 3.3V ESP32 / Nano 33).

Software

  • delay() bloqueia — para multi-tarefas, usar millis().
  • Variáveis globais poucas e bem nomeadas.
  • const quando não muda.
  • Modularizar com funções e tabs (.h/.cpp no projecto).
  • Libraries quando possível (não reinventar).

Multi-tasking com millis()

// Pisca LED + lê sensor sem bloquear

unsigned long ultimoBlink = 0;
unsigned long ultimaLeitura = 0;
bool ledOn = false;

void loop() {
  unsigned long agora = millis();
  
  if (agora - ultimoBlink > 500) {
    ultimoBlink = agora;
    ledOn = !ledOn;
    digitalWrite(LED, ledOn ? HIGH : LOW);
  }
  
  if (agora - ultimaLeitura > 1000) {
    ultimaLeitura = agora;
    Serial.println(analogRead(A0));
  }
}

UC02842 · resumo

  • Arduino = microcontrolador acessível, perfeito para começar.
  • Digital I/O (LEDs, botões) com pull-ups.
  • Analog input (0-1023) lê sensores.
  • PWM (analogWrite) controla intensidade.
  • Servos e motores com libraries.
  • LCD/OLED via I2C.
  • Serial Monitor essencial para debug.
  • millis() > delay() para multi-tarefas.
  • Base para IoT, robótica, projectos físicos.