Partilhar: WhatsApp
aulify · Sebenta
UC · Unidade de Competência · UC02164

Sebenta · Configurar sensores (UC02164)

Do microcontrolador ao efeito interativo, com sensores de luz, temperatura, proximidade, movimento, som e toque
25h · 2.25 pontos crédito Curso: T. Animação 2D e 3D, T. Produção de Conteúdos I ↗ Referencial oficial SNQ
Índice

Introdução

Um conteúdo interativo que só responde ao rato e ao teclado está limitado ao ecrã. Quando esse conteúdo passa a responder à luz da sala, à presença de uma pessoa ou a um toque num objeto, entra num território novo: a computação física, onde o software conversa diretamente com o mundo real.

Esta sebenta ensina a configurar sensores: ligar fisicamente cada sensor a um microcontrolador, ler o seu valor, calibrá-lo às condições reais do espaço, e usar esse valor para acionar um efeito, seja um LED, um motor, seja um conteúdo interativo ou uma animação 3D num computador. É a competência que permite construir instalações que reagem ao público, cenografias digitais e exposições participativas.

O percurso segue a lógica de qualquer profissional de instalações interativas: primeiro entende-se o ciclo sensor → processamento → atuador e a placa que o executa (Arduino, ESP32); depois estuda-se cada família de sensor (luz, temperatura, proximidade, movimento, som, toque), sempre com a mesma metodologia de ligação, leitura e calibração; e por fim liga-se tudo isto a aplicações reais de conteúdos interativos e modelação 3D.

Objetivos de aprendizagem (referencial): configurar microcontroladores e sensores com o kit de instalações eletrónicas e o IDE de desenvolvimento; ler sinais digitais e analógicos; calibrar sensores às condições reais; e integrar os valores lidos em aplicações de conteúdos interativos e modelação 3D.

1. Computação física: o ciclo sensor, processamento, atuador

A computação física (physical computing) liga o mundo digital ao mundo real através de dois tipos de componentes:

Todo o sistema segue o mesmo ciclo, repetido continuamente enquanto a placa está ligada:

[Fenómeno físico]  [Sensor]  [Microcontrolador]  [Decisão]  [Atuador ou aplicação]  [Efeito]

Por exemplo: a luz da sala baixa (fenómeno) → um LDR mede a variação (sensor) → o Arduino lê o valor e compara com um limiar (decisão) → acende um LED ou envia um sinal a uma aplicação (atuador) → a instalação reage (efeito).

Este ciclo repete-se dezenas a centenas de vezes por segundo. É a estrutura mental por trás de todos os exemplos desta sebenta: mudam os sensores e os efeitos, mas o ciclo é sempre o mesmo.

2. Microcontroladores: Arduino e ESP32

O microcontrolador é o "cérebro" do sistema: um pequeno computador dedicado, num só chip, que corre um único programa em ciclo contínuo desde que é ligado, sem sistema operativo.

Arduino

O Arduino é a placa de referência para prototipagem de computação física, de código aberto:

ESP32

O ESP32 é um microcontrolador com Wi-Fi e Bluetooth integrados, programado com o mesmo IDE e a mesma linguagem do Arduino, apenas mudando a placa selecionada.

Arduino Uno ESP32
Ligação sem fios não Wi-Fi + Bluetooth
Velocidade de processamento 16 MHz até 240 MHz
Uso típico protótipo local, um ponto de sensor vários pontos de sensor a comunicar em rede

Numa instalação com sensores espalhados por várias salas, o ESP32 permite que cada ponto envie os seus valores para um painel ou aplicação central, sem cabos entre salas.

3. O IDE Arduino: instalar, configurar e escrever o primeiro sketch

O IDE Arduino (Integrated Development Environment) é o programa onde se escreve, verifica e envia o código para a placa. Um programa Arduino chama-se sketch.

Exemplo resolvido · instalação e primeiro sketch

  1. Descarregar o IDE em arduino.cc e instalar (Windows, macOS ou Linux).
  2. Ligar a placa por cabo USB (tem de ser um cabo de dados, não só de carga).
  3. Em Ferramentas → Placa, escolher o modelo (ex.: Arduino Uno).
  4. Em Ferramentas → Porta, escolher a porta série onde a placa aparece.
  5. Escrever o sketch mais simples possível, o "pisca-pisca":
void setup() {
  pinMode(13, OUTPUT);   // corre uma vez: configura o pino 13 como saída
}

void loop() {
  digitalWrite(13, HIGH); // liga o LED
  delay(500);              // espera meio segundo
  digitalWrite(13, LOW);  // desliga o LED
  delay(500);
}
  1. Clicar em Verificar (compila o código) e depois Carregar (envia para a placa).

Um sketch tem sempre duas funções: setup(), que corre uma única vez ao ligar ou reiniciar, e loop(), que corre em ciclo contínuo, para sempre, enquanto a placa está ligada. É literalmente o ciclo sensor-processamento-atuador do Capítulo 1, escrito em código.

4. Sinais digitais e sinais analógicos

Distinguir sinal digital de sinal analógico é a base de qualquer leitura de sensor correta.

Sinais digitais

Só têm dois estados: LOW (0 V) ou HIGH (5 V). Lê-se com digitalRead(pino), depois de configurar o pino como entrada com pinMode(pino, INPUT).

int estado = digitalRead(2);
if (estado == HIGH) {
  Serial.println("Presença detetada");
}

Exemplos de sensores digitais: botão, interruptor, PIR (deteta movimento sim/não), a maioria dos sensores de toque.

Sinais analógicos

Variam de forma contínua entre um mínimo e um máximo. Lê-se com analogRead(pino), apenas nos pinos A0 a A5, que devolve um valor entre 0 e 1023 (1023 corresponde a 5 V).

int leitura = analogRead(A0);
float tensao = leitura * (5.0 / 1023.0);

Exemplos: LDR (luz), termístor, potenciómetro, muitos módulos de som. O valor 0-1023 vem de uma conversão analógico-digital (ADC) de 10 bits: 2¹⁰ = 1024 níveis possíveis, de 0 a 1023.

Sinal digital Sinal analógico
Valores possíveis 2 (HIGH/LOW) 1024 (0 a 1023)
Função de leitura digitalRead() analogRead()
Pinos qualquer pino digital apenas A0-A5
Exemplo botão, PIR LDR, termístor

5. Sensores de luz e temperatura

O LDR (fotorresistência)

O LDR é uma resistência cuja resistência elétrica diminui com mais luz. Liga-se num divisor de tensão com uma resistência fixa (ex.: 10 kΩ), para transformar a variação de resistência numa variação de tensão que o analogRead consegue medir.

int luz = analogRead(A0);
if (luz < 300) {
  Serial.println("Ambiente escuro: ativar efeito");
}

Exemplo resolvido · calibrar um limiar de luz

Um limiar copiado de um tutorial raramente funciona no espaço real. A calibração faz-se sempre assim:

  1. Ligar o LDR e imprimir a leitura no Serial Monitor durante cerca de 30 segundos, em condições normais da sala.
  2. Anotar o valor típico com as luzes acesas (ex.: ~700) e com as luzes apagadas (ex.: ~150).
  3. Definir o limiar a meio caminho entre os dois extremos: int LIMIAR = 400;
  4. Testar em condições reais e ajustar se o efeito disparar por engano ou não disparar quando devia.

O sensor DHT11/DHT22

O DHT11 (ou o mais preciso DHT22) mede temperatura e humidade num único componente de três pinos (alimentação, sinal, terra). Ao contrário do LDR, comunica por um protocolo digital próprio, exigindo uma biblioteca instalada no IDE.

#include <DHT.h>
DHT dht(2, DHT11);

void setup() { dht.begin(); }
void loop() {
  float temp = dht.readTemperature();
  float hum = dht.readHumidity();
  if (isnan(temp)) {
    Serial.println("Erro de leitura");
  } else {
    Serial.println(temp);
  }
}

isnan() ("is not a number") verifica se a leitura falhou, um passo essencial: sensores reais falham por fios soltos ou interferência, e um projeto que confia cegamente no valor lido falha em público.

6. Sensores de proximidade e movimento

O sensor de ultrassons HC-SR04

O HC-SR04 mede distância pelo eco de ultrassons, com dois pinos de sinal: Trig (dispara o impulso) e Echo (recebe o eco). O princípio: o Trig envia um impulso sonoro, este bate num obstáculo e volta, e o Echo fica HIGH durante o tempo de ida e volta.

Distância = (tempo do eco × velocidade do som) / 2

Com a velocidade do som a 340 m/s (0,034 cm/µs), o código fica:

digitalWrite(TRIG, LOW);
delayMicroseconds(2);
digitalWrite(TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG, LOW);

long duracao = pulseIn(ECHO, HIGH);
float distancia = duracao * 0.034 / 2;

Divide-se por 2 porque o tempo medido é ida e volta, não só a ida. A gama típica de funcionamento é de 2 cm a 400 cm.

O sensor PIR (deteção de presença)

O PIR (Passive Infrared) deteta movimento de calor corporal numa área e devolve um sinal digital: HIGH quando há movimento, com um tempo de retenção ajustável.

int movimento = digitalRead(PIR_PIN);

O PIR responde a corpos quentes em movimento, não a objetos parados nem a variações de luz. Deve evitar-se colocá-lo perto de fontes de calor (radiadores, luz solar direta), que geram falsos positivos.

Acelerómetro e giroscópio

O acelerómetro mede aceleração (incluindo a gravidade) em três eixos; o giroscópio mede rotação. O módulo mais comum, o MPU6050, combina os dois e comunica por protocolo I2C, exigindo calibração inicial da posição de repouso.

7. Sensores de som e toque

Módulos de som

Um módulo de som (com microfone de eletreto) existe em duas variantes: digital (HIGH quando o som ultrapassa um limiar ajustável no módulo) ou analógico (valor contínuo 0-1023 proporcional ao volume).

int nivel = analogRead(SOM_PIN);
if (nivel > 600) {
  Serial.println("Som alto: ativar efeito de luz");
}

Este módulo só mede intensidade de som, não reconhece voz nem palavras. Um valor instável (ruído de fundo) beneficia de uma média de várias leituras para reduzir falsos positivos.

Sensores de toque e capacitivos

Um sensor capacitivo deteta o contacto ou a proximidade da pele, que altera um pequeno campo elétrico. Módulos dedicados (ex.: TTP223) devolvem um sinal digital simples, sem partes móveis, e por isso resistem melhor ao uso repetido do público numa exposição.

Exemplo resolvido · debounce (anti-ressalto)

Uma transição de estado (toque, botão) gera muitas vezes ruído elétrico que a placa lê como vários toques em vez de um. O debounce filtra isso:

int ultimoEstado = LOW;
unsigned long ultimaMudanca = 0;

int atual = digitalRead(TOQUE_PIN);
if (atual != ultimoEstado && millis() - ultimaMudanca > 50) {
  ultimaMudanca = millis();
  ultimoEstado = atual;
  if (atual == HIGH) Serial.println("Toque válido");
}

millis() devolve o tempo, em milissegundos, desde que a placa ligou, e permite medir intervalos sem bloquear o resto do programa, ao contrário de delay(). Num sistema com vários sensores, usar delay() para debounce impede a leitura dos outros sensores entretanto.

8. Atuadores: dar resposta ao sensor

O atuador produz o efeito observável em resposta ao que o sensor leu.

PWM: simular saída analógica

O Arduino não tem saída verdadeiramente analógica nos pinos comuns, mas simula-a por PWM (Pulse Width Modulation): liga e desliga o pino muito depressa, e a proporção de tempo em HIGH determina o brilho ou a velocidade percebidos.

int luz = analogRead(A0);
int brilho = map(luz, 0, 1023, 0, 255);
analogWrite(9, brilho);

A função map() converte um valor de uma escala (0-1023, do sensor) para outra (0-255, do atuador PWM): é a ponte direta entre a leitura de um sensor e o efeito de um atuador, e fecha por completo o ciclo do Capítulo 1.

9. Ligações físicas: protoboard e datasheets

A protoboard e o kit de instalações eletrónicas

A protoboard permite ligar componentes sem soldar. As linhas verticais (laterais) servem normalmente para alimentação, partilhada por toda a placa; as colunas horizontais (centro) ligam-se em grupos de 5, para os componentes. O kit de instalações eletrónicas da UC junta protoboard, fios de ligação (jumpers), resistências, LEDs e os sensores estudados nos capítulos anteriores.

Ler um datasheet

O datasheet é a ficha técnica de um componente. Antes de ligar qualquer sensor novo, procura-se:

  1. Tensão de alimentação (3,3 V ou 5 V): ligar à tensão errada danifica o componente.
  2. Pinout: qual pino é VCC (alimentação), GND (terra) e sinal.
  3. Gama de funcionamento: ex.: o HC-SR04 só é fiável entre 2 e 400 cm.
  4. Corrente máxima: decide se é preciso um driver (motores) ou não (LEDs pequenos).

Um esquema de ligações copiado de um tutorial sem confirmar no datasheet do componente concreto é a causa mais comum de "o sensor não funciona".

10. Comunicação série e depuração

O Serial Monitor do IDE mostra em tempo real o que a placa envia pela porta USB, e é a principal ferramenta de depuração:

void setup() {
  Serial.begin(9600);
}
void loop() {
  int valor = analogRead(A0);
  Serial.print("Sensor: ");
  Serial.println(valor);
  delay(200);
}

Serial.begin(9600) inicia a comunicação a 9600 bauds, valor que tem de coincidir dos dois lados. O Plotter Série (Ferramentas → Plotter Série) desenha o valor ao longo do tempo, útil para ver ruído e tendências de um sensor analógico.

Metodologia de depuração de sensores

Quando um sensor não dá o resultado esperado, a sequência correta é sempre:

  1. Confirmar a ligação física contra o datasheet.
  2. Imprimir o valor bruto no Serial Monitor, sem lógica nenhuma à volta.
  3. Comparar com o valor esperado.
  4. Isolar o sensor, testando-o sozinho se houver dúvida.
  5. Só depois adicionar a lógica (limiares, condições, atuadores).

Depurar de fora para dentro, do fio até ao efeito, é sempre mais rápido do que alterar o código todo de uma vez.

11. Integrar sensores em aplicações interativas

O valor lido por um sensor não fica preso ao microcontrolador: pode ser enviado pela porta série (ou por Wi-Fi, com o ESP32) para software de conteúdos interativos e modelação 3D:

Exemplo resolvido · protocolo simples de comunicação

Para que a aplicação leia os dados sem erros, define-se um formato fixo antes de programar os dois lados:

Serial.print("LUZ:");
Serial.println(analogRead(A0));
Saída no Serial Monitor:
LUZ:812
LUZ:809
LUZ:340

A aplicação recebe cada linha, separa pelo carácter :, e usa só o número. Com vários sensores no mesmo sistema, um rótulo por sensor (LUZ:, DIST:, SOM:) evita confundir os valores do lado da aplicação. Esta ponte, sensor → microcontrolador → aplicação, é o objetivo final da UC: o sensor deixa de ser um exercício isolado e passa a controlar conteúdo interativo real.

12. Boas práticas, segurança e calibração

Rigor na montagem e na calibração é o que separa um protótipo que funciona uma vez de uma instalação que aguenta uma exposição inteira, com público real.

Erros comuns

Glossário

Síntese

Toda a computação física segue o mesmo ciclo: sensor → processamento → atuador, executado por um microcontrolador (Arduino ou ESP32) programado no IDE Arduino. Cada sensor estudado (luz, temperatura e humidade, proximidade, movimento, som, toque) lê-se de forma digital (digitalRead(), dois estados) ou analógica (analogRead(), 0 a 1023), liga-se numa protoboard conforme o datasheet, e exige calibração no espaço real antes de confiar no seu valor. O Serial Monitor é a ferramenta de depuração central, e a metodologia de resolução de problemas (ligação → valor bruto → comparação → isolamento → lógica) aplica-se a qualquer sensor que "não funcione". Por fim, o valor de um sensor integra-se em aplicações interativas (Processing, TouchDesigner, Unity) através de um protocolo de comunicação simples e consistente, transformando um exercício de eletrónica num efeito interativo real.

Exercícios resolvidos

1. Um LDR foi lido com digitalRead() e o valor nunca varia como esperado. Porquê, e como corrigir?

Resolução: o LDR é um sensor analógico, com valores contínuos entre 0 e 1023, não apenas dois estados. digitalRead() só distingue HIGH de LOW e por isso não capta a variação real de luz. A correção é usar analogRead(pino) num pino A0-A5.

2. Um HC-SR04 mede o tempo de eco em 600 µs. Qual é a distância ao obstáculo, em centímetros?

Resolução: distância = (tempo × velocidade do som) / 2 = (600 × 0,034) / 2 = 20,4 / 2 = 10,2 cm. Divide-se por 2 porque o tempo medido é de ida e volta.

3. Um sensor de toque capacitivo regista vários toques quando o utilizador só tocou uma vez. Que técnica resolve isto, e porque não deve usar-se delay()?

Resolução: a técnica é o debounce, comparando o tempo desde a última mudança de estado com millis() e só aceitando uma nova leitura passado um intervalo mínimo (ex.: 50 ms). Não se usa delay() porque bloqueia todo o programa, impedindo a leitura de outros sensores no mesmo ciclo.

4. Um grupo quer que um LED fique mais ou menos brilhante conforme a luz ambiente, com o LDR ligado em A0 e o LED no pino 9. Escreve a lógica.

Resolução: cpp int luz = analogRead(A0); int brilho = map(luz, 0, 1023, 0, 255); analogWrite(9, brilho); map() converte a leitura do sensor (0-1023) para a gama de PWM do atuador (0-255); analogWrite() só funciona num pino marcado com ~.

5. Antes de instalar um novo módulo de sensor pela primeira vez, que quatro informações se procuram no datasheet e porquê cada uma importa?

Resolução: tensão de alimentação (ligar à tensão errada danifica o componente); pinout (saber qual pino é VCC, GND e sinal, para não trocar); gama de funcionamento (saber os limites fiáveis de leitura); corrente máxima (decidir se é preciso um driver, como nos motores).

6. Um sensor de som dá leituras muito instáveis, com picos e quedas constantes mesmo em silêncio. Que duas técnicas ajudam a estabilizar a leitura?

Resolução: fazer uma média de várias leituras consecutivas, em vez de decidir com base numa só; e validar a leitura (verificar se está dentro de uma gama esperada) antes de a usar para acionar qualquer efeito.

7. Uma instalação usa um Arduino Uno para ler um PIR e um TouchDesigner para mostrar uma animação quando há movimento. Descreve, em três passos, como ligar estes dois sistemas.

Resolução: 1) o Arduino lê o PIR com digitalRead() e envia o resultado pela porta série num formato fixo (ex.: Serial.println("MOV:1") quando há movimento); 2) o TouchDesigner usa o operador Serial DAT para receber essa linha em tempo real; 3) dentro do TouchDesigner, essa leitura aciona a animação, mantendo o mesmo ciclo sensor → processamento → atuador, agora com o atuador do lado do software.