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

Sebenta · Internet of Things (UC00643)

ESP32, MQTT, dashboards e dispositivos conectados
25h · 2.25 pontos crédito Curso: T. Desenv. Software, T. Sist. Comp. Redes ↗ Referencial oficial SNQ
Índice

Introdução

Internet of Things (IoT) é o universo de dispositivos físicos conectados à internet: lâmpadas, frigoríficos, contadores de electricidade, sensores agrícolas, trackers GPS, máquinas industriais, anéis fitness, carros. Em 2026 há mais de 30 mil milhões de devices IoT no mundo — e cresce.

Esta UC é o passo natural depois de Arduino básico (UC02842). Vamos pegar nos artefactos tangíveis e conectá-los à internet, enviar dados para dashboards, controlá-los remotamente, integrar com smart home. Foco em ESP32 (microcontrolador com WiFi e Bluetooth integrados), MQTT (protocolo IoT standard) e plataformas cloud acessíveis.

Em 25 horas vais conseguir construir uma estação ambiental que envia dados para a internet, com dashboard visual e controlo remoto.

1. IoT em contexto

O que é

Internet of Things: objectos físicos com sensores, software e conectividade que trocam dados pela rede. Não é um produto único — é um paradigma.

Características: - Sensoreamento: temperatura, humidade, presença, movimento, luz, qualidade do ar, etc. - Actuação: ligar/desligar luzes, abrir válvulas, alertar utilizadores. - Conectividade: WiFi, Bluetooth, Zigbee, Z-Wave, LoRa, 4G/5G. - Processamento: edge (no device) e cloud. - Dashboards / apps: humanos vêem e controlam.

Onde está

Casa: - Smart speakers (Alexa, Google, HomePod). - Lâmpadas (Philips Hue, IKEA Tradfri). - Termostatos (Nest, Ecobee). - Cameras (Ring, Arlo). - Robot vacuums (Roomba). - Plugs/relés (TP-Link, Shelly).

Indústria (IIoT — Industrial IoT): - Manutenção preditiva (vibração de motores). - Tracking de stock e equipamento. - Monitorização ambiental em fábricas. - Smart agriculture: humidade solo, temperatura estufas.

Cidades (Smart cities): - Parking sensors. - Iluminação adaptativa. - Recolha de lixo (sensores em contentores). - Qualidade do ar.

Saúde: - Wearables (Apple Watch, Fitbit). - Medical alert pendants. - Remote patient monitoring.

Stack típico

[Sensor]──┐
[Sensor]──┼──[MCU+conectividade]──[Rede]──[Cloud broker]──[Storage/BD]
[Actuator]                                                      
                                                          [Dashboard/App]
                                                          [ML/Analytics]
                                                          [Alertas]

Esta UC

Foco no que dá para construir em casa/escola com componentes baratos: - ESP32 como MCU + WiFi. - MQTT como protocolo de mensagens. - Adafruit IO ou ThingSpeak como cloud. - Home Assistant opcionalmente para self-host completo.

2. ESP32 / ESP8266 — hardware

ESP8266 vs ESP32

ESP8266 (Espressif, 2014): - WiFi. - 1 core, 80MHz, 80KB RAM, ~1MB flash. - 17 GPIO. - €3-5. - Boards: NodeMCU, Wemos D1 mini.

ESP32 (Espressif, 2016): - WiFi + Bluetooth (BLE). - 2 cores Xtensa LX6, até 240MHz, 520KB RAM, 4MB+ flash. - 30+ GPIO, 18 ADC, 2 DAC, touch sensors, hall sensor. - €5-15. - Boards: ESP32 DevKit V1, Lolin32, TTGO T-Display.

Esta UC usa ESP32 (mais capaz, ainda barato, futuro-proof). Recomendo ESP32 DevKit V1 / NodeMCU-32S (US$5-10).

Variantes ESP32 modernas

Setup no Arduino IDE

  1. File → Preferences:
  2. Additional Boards Manager URL: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
  3. Tools → Board → Boards Manager:
  4. Procura "esp32" by Espressif → Install (~200MB).
  5. Liga ESP32 USB.
  6. Tools → Board → ESP32 → ESP32 Dev Module (genérico).
  7. Tools → Port → seleccionar.

Drivers USB: alguns boards usam CP2102 (Silicon Labs) ou CH340 (WCH). Se PC não detectar, instala driver apropriado.

PlatformIO alternativa

Para projectos sérios. platformio.ini:

[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
lib_deps =
    knolleary/PubSubClient
    adafruit/DHT sensor library

Pinos especiais

Cuidado: nem todos os GPIO são iguais. - Boot pins (0, 2, 12, 15): cuidado durante reset. - Input-only (34, 35, 36, 39): só lêem, não escrevem. - GPIO 6-11: ligados à flash interna — não usar. - ADC2 (4, 12, 13...): não funciona com WiFi ligado.

Para sensores analógicos: usar ADC1 (32, 33, 34, 35, 36, 39).

3. Hello WiFi

Connect a rede

#include <WiFi.h>

const char* SSID = "TP-Link_AB12";
const char* PASS = "minha-pass";

void setup() {
  Serial.begin(115200);

  WiFi.begin(SSID, PASS);
  Serial.print("A conectar");

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println();
  Serial.print("IP: ");
  Serial.println(WiFi.localIP());
  Serial.print("RSSI: ");
  Serial.println(WiFi.RSSI());   // força sinal dBm
}

void loop() {}

Baud rate típico ESP32: 115200.

Status checks

WiFi.status() == WL_CONNECTED   // bom
WiFi.RSSI()                      // -50 forte, -80 fraco
WiFi.localIP()                   // ex: 192.168.1.123
WiFi.macAddress()                // ex: AA:BB:CC:DD:EE:FF
WiFi.SSID()                      // rede actual

WiFi.h functions úteis

WiFi.disconnect();      // desconectar
WiFi.reconnect();       // re-tentar
WiFi.setHostname("estacao-aulify");

// Static IP em vez de DHCP
IPAddress local(192, 168, 1, 200);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
WiFi.config(local, gateway, subnet);

4. HTTP

HTTP GET (consumir API)

#include <WiFi.h>
#include <HTTPClient.h>

void loop() {
  if (WiFi.status() != WL_CONNECTED) return;

  HTTPClient http;
  http.begin("http://wttr.in/Lisbon?format=%t");

  int code = http.GET();
  if (code == 200) {
    String body = http.getString();
    Serial.println(body);
  } else {
    Serial.print("Erro: ");
    Serial.println(code);
  }

  http.end();
  delay(60000);   // cada 60s
}

HTTPS (TLS)

#include <WiFiClientSecure.h>
#include <HTTPClient.h>

WiFiClientSecure client;

void setup() {
  // ...
  client.setInsecure();   // skip cert validation (dev only)
  // ou: client.setCACert(rootCACertificate);
}

void loop() {
  HTTPClient http;
  http.begin(client, "https://api.example.com/data");
  int code = http.GET();
  // ...
}

HTTP POST

HTTPClient http;
http.begin("http://meu-server.pt/api/sensor");
http.addHeader("Content-Type", "application/json");

float temp = 21.5;
float humid = 60.0;

String body = "{\"temp\":";
body += temp;
body += ",\"humid\":";
body += humid;
body += "}";

int code = http.POST(body);
Serial.println(code);
http.end();

Quando usar HTTP vs MQTT

5. MQTT

O que é

MQTT (Message Queuing Telemetry Transport): protocolo pub/sub criado por IBM nos anos 90 para sensores. Hoje é o standard de facto em IoT.

Modelo:

Publisher ─publish─→ Broker ─subscribe→ Subscriber
                       ↑
                       │
                  routing por topic

Topics são strings hierárquicas: casa/sala/temperatura. Subscribers ouvem topics (ou wildcards: casa/+/temperatura, casa/#).

Broker

Pode ser: - Self-hosted: Mosquitto (open source), HiveMQ. - Cloud SaaS: HiveMQ Cloud, AWS IoT Core, Azure IoT Hub. - Free public: broker.hivemq.com:1883 (para testes — não usar em produção).

ESP32 + MQTT (PubSubClient)

Library popular: PubSubClient by Nick O'Leary.

#include <WiFi.h>
#include <PubSubClient.h>

const char* SSID = "wifi";
const char* PASS = "pass";
const char* BROKER = "broker.hivemq.com";
const int   PORT = 1883;

WiFiClient espClient;
PubSubClient mqtt(espClient);

void setupWiFi() {
  WiFi.begin(SSID, PASS);
  while (WiFi.status() != WL_CONNECTED) delay(500);
}

void reconnectMQTT() {
  while (!mqtt.connected()) {
    String id = "aulify-" + String(random(0xffff), HEX);
    if (mqtt.connect(id.c_str())) {
      mqtt.subscribe("aulify/cmd");
    } else {
      delay(5000);
    }
  }
}

void onMessage(char* topic, byte* payload, unsigned int len) {
  String msg;
  for (int i = 0; i < len; i++) msg += (char)payload[i];
  Serial.print(topic);
  Serial.print(" → ");
  Serial.println(msg);
}

void setup() {
  Serial.begin(115200);
  setupWiFi();
  mqtt.setServer(BROKER, PORT);
  mqtt.setCallback(onMessage);
}

unsigned long ultimaPub = 0;

void loop() {
  if (!mqtt.connected()) reconnectMQTT();
  mqtt.loop();

  if (millis() - ultimaPub > 5000) {
    ultimaPub = millis();
    float t = 20.0 + (random(100) / 10.0);   // dummy
    char buf[10];
    dtostrf(t, 4, 2, buf);
    mqtt.publish("aulify/sala/temp", buf);
  }
}

Topic design

Princípios: - Hierárquico (<empresa>/<sala>/<sensor>). - Específico (não tudo num topic). - Camel ou snake — sê consistente. - Wildcards: + (1 nível), # (vários).

Exemplos: - aulify/sala1/temp - aulify/sala1/humid - aulify/sala2/temp - aulify/+/temp → todas as salas, temp. - aulify/# → tudo.

QoS levels

Para sensores enviando todos os 5s: QoS 0 chega. Para comandos críticos (abrir porta): QoS 1 ou 2.

Retained messages

Servidor "guarda" última mensagem do topic. Novos subscribers recebem-na imediatamente.

mqtt.publish("aulify/estado", "online", true);  // retained=true

6. Dashboards cloud

ThingSpeak

MathWorks. Open source on-premise possível. Free: 8 canais, 3M msgs/ano, update mínimo 15s.

Workflow: 1. thingspeak.com → sign up. 2. Channels → New Channel → "Sala de aula" → fields: temp, humid, luz. 3. API Keys tab → copy Write API Key. 4. ESP32 envia via HTTP GET:

String url = "http://api.thingspeak.com/update?api_key=YOUR_KEY";
url += "&field1=" + String(temp);
url += "&field2=" + String(humid);
http.begin(url);
http.GET();
  1. Dashboard auto-actualiza com gráficos.
  2. Matlab Analytics integrado para análise.

Adafruit IO

Adafruit. Free: 10 feeds, 30 data points/min, 30 dias storage.

io.adafruit.com → sign up → Feeds → New Feed.

Trabalha com MQTT ou REST:

#include <Adafruit_MQTT.h>
#include <Adafruit_MQTT_Client.h>

#define AIO_SERVER "io.adafruit.com"
#define AIO_PORT 1883
#define AIO_USER "teu-username"
#define AIO_KEY  "aio_xxx..."

WiFiClient client;
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_PORT, AIO_USER, AIO_KEY);

Adafruit_MQTT_Publish tempFeed(&mqtt, AIO_USER "/feeds/temperatura");

void loop() {
  if (!mqtt.connected()) mqtt.connect();

  float t = 21.5;
  tempFeed.publish(t);
  delay(10000);
}

Dashboards no site: drag-drop blocks (line chart, gauge, slider, toggle).

Blynk

Foca em app mobile + dashboards. Free tier limitado (4 widgets por device).

Vantagem: UI mobile pré-construída. Tu controlas LEDs/relés do telemóvel.

Self-hosted: Grafana + InfluxDB

Stack profissional open source: - InfluxDB: time-series DB. - Grafana: dashboards customizáveis. - Mosquitto: broker MQTT. - Telegraf: agente que junta tudo.

Mais setup mas zero limites e zero dependência de cloud.

7. Home Assistant

Plataforma open source de smart home, self-hosted (Raspberry Pi, Docker, NUC).

Casos de uso: - Centralizar controlo (Hue + Sonos + Ring + DIY ESP32 num só dashboard). - Automações ("ao pôr do sol, liga luzes da sala se alguém estiver em casa"). - Voice (Alexa/Google integrações).

Setup rápido com Docker

docker run -d --name homeassistant --restart unless-stopped \
  -v ~/ha-config:/config \
  --network=host \
  ghcr.io/home-assistant/home-assistant:stable

Abrir http://localhost:8123 → onboarding.

Integração MQTT

Settings → Devices & Services → Add Integration → MQTT → conectar a broker.

ESP32 publica em home/sala/temp. HA descobre como sensor.

YAML config

# configuration.yaml
mqtt:
  sensor:
    - name: "Temperatura sala"
      state_topic: "home/sala/temp"
      unit_of_measurement: "°C"

  switch:
    - name: "Luz exterior"
      command_topic: "home/exterior/luz/cmd"
      state_topic: "home/exterior/luz/state"
      payload_on: "ON"
      payload_off: "OFF"

ESP32 ouve home/exterior/luz/cmd e liga relé.

Automations

# automations.yaml
- alias: "Aviso temp alta"
  trigger:
    platform: numeric_state
    entity_id: sensor.temperatura_sala
    above: 28
  action:
    service: notify.mobile_app
    data:
      message: "Está calor: {{ states.sensor.temperatura_sala.state }}°C"

8. Deep sleep — bateria dura meses

ESP32 consumo: - Active: 80-240mA. - WiFi connected idle: ~70mA. - Light sleep: ~5mA. - Deep sleep: ~10µA (microamperes!).

Estratégia para sensores em bateria: 1. Acordar. 2. Conectar WiFi. 3. Ler sensor. 4. Enviar via MQTT/HTTP. 5. Dormir 5-15 min. 6. Repetir.

#include "esp_sleep.h"

#define uS_PER_SEC 1000000ULL

void deepSleepMin(int minutos) {
  Serial.println("A dormir...");
  Serial.flush();
  esp_sleep_enable_timer_wakeup(minutos * 60 * uS_PER_SEC);
  esp_deep_sleep_start();
  // nunca volta
}

void setup() {
  Serial.begin(115200);

  // WiFi + sensor + MQTT
  connectWiFi();
  float t = readSensor();
  publishMQTT(t);

  deepSleepMin(15);
}

void loop() {}   // não chega aqui

Bateria 2500mAh em deep sleep contínuo: ~10 anos teóricos (na prática ~1 ano com wake-ups).

RTC memory

Variáveis em RTC_DATA_ATTR sobrevivem deep sleep:

RTC_DATA_ATTR int bootCount = 0;

void setup() {
  bootCount++;
  Serial.println(bootCount);
  deepSleepMin(1);
}

9. OTA — actualizar firmware via WiFi

Após primeiro upload USB, podes actualizar via rede:

#include <ArduinoOTA.h>

void setupOTA() {
  ArduinoOTA.setHostname("estacao-aulify");
  ArduinoOTA.setPassword("ota-pass");

  ArduinoOTA.onStart([]() {
    Serial.println("OTA iniciado");
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("OTA completo");
  });

  ArduinoOTA.begin();
}

void setup() {
  connectWiFi();
  setupOTA();
}

void loop() {
  ArduinoOTA.handle();   // tem que ser chamado regularmente

  // restante código
}

Arduino IDE → Tools → Port → vai aparecer estacao-aulify at 192.168.x.x (Network).

OTA é obrigatório em devices que vais instalar fora do alcance fácil.

10. Segurança

Riscos comuns

Em 2016, botnet Mirai infectou milhões de devices IoT com defaults — usou-os para DDoS massivos.

Mitigações

#include <WiFiClientSecure.h>

WiFiClientSecure client;
client.setCACert(rootCA);
PubSubClient mqtt(client);
mqtt.setServer("io.adafruit.com", 8883);   // porta TLS

GDPR e privacy

Devices IoT podem recolher PII (presença, hábitos, voice). Cuidado: - Documentar que dados são recolhidos. - Consent explícito. - Anonimização quando possível. - Direito ao apagamento.

11. Protocolos alternativos

Bluetooth Low Energy (BLE)

ESP32 suporta BLE nativo. Para devices pessoais (wearables, beacons), perto da pessoa.

#include <BLEDevice.h>
#include <BLEServer.h>

BLEServer* server = BLEDevice::createServer();
BLEService* svc = server->createService("...");
BLECharacteristic* ch = svc->createCharacteristic(...);
svc->start();
server->getAdvertising()->start();

Phones podem detectar via apps tipo nRF Connect.

LoRa / LoRaWAN

Para longas distâncias (km) e muito baixo consumo — agricultura, smart cities.

Não usa WiFi: rádio sub-GHz. Bandwidth muito baixo (uns bytes por minuto).

Hardware: módulos SX1276/SX1278, RFM95.

Zigbee / Z-Wave / Matter

Mesh networks para smart home. Standards seguidos pela maioria dos devices comerciais. Matter (2022+) é o novo unificador.

ESP32-C6 e ESP32-H2 suportam 802.15.4 (base Zigbee/Thread/Matter).

NB-IoT / LTE-M (4G IoT)

Conectividade celular específica para IoT — baixo consumo, ideal para trackers GPS em qualquer sítio. Custos de SIM por device.

12. Boas práticas em produção

Robustez

#include <esp_task_wdt.h>

void setup() {
  esp_task_wdt_init(10, true);   // 10s timeout
  esp_task_wdt_add(NULL);
}

void loop() {
  esp_task_wdt_reset();   // "estou vivo"
  // resto
}

Logging

Serial.println() durante dev. Em produção: - MQTT logs para um topic. - HTTP push para serviço de logs. - Local SD card (SPI module).

Configuração

Não hardcode WiFi pass / API keys no código (vão para Git!).

Soluções: - WiFiManager library: web portal para configurar primeiro arranque. - Preferences (NVS): guardar em flash. - ESPAsyncWebServer: AP mode com config form.

#include <WiFiManager.h>

WiFiManager wm;

void setup() {
  if (!wm.autoConnect("AulifyIoT")) {
    ESP.restart();
  }
  // chega aqui = conectado
}

Primeiro arranque cria hotspot "AulifyIoT"; conectas-te com telemóvel, escolhes WiFi, e ESP guarda credenciais.

13. Próximos passos

Glossário

Recursos

IoT é uma das áreas mais excitantes para makers e engenheiros. Combina hardware, software, redes, cloud, e tem aplicações em qualquer indústria. Aprender ESP32 + MQTT abre portas para smart home, agricultura, monitorização ambiental, retail, healthcare e indústria. Começa pequeno (uma estação meteorológica), itera, e em pouco tempo tens projectos genuinamente úteis.