Sebenta · Internet of Things (UC00643)
- Introdução
- 1. IoT em contexto
- 2. ESP32 / ESP8266 — hardware
- 3. Hello WiFi
- 4. HTTP
- 5. MQTT
- 6. Dashboards cloud
- 7. Home Assistant
- 8. Deep sleep — bateria dura meses
- 9. OTA — actualizar firmware via WiFi
- 10. Segurança
- 11. Protocolos alternativos
- 12. Boas práticas em produção
- 13. Próximos passos
- Glossário
- Recursos
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
- ESP32-S2: WiFi only, single-core, USB nativo.
- ESP32-S3: WiFi + BLE 5, AI accelerator (vector ops).
- ESP32-C3: RISC-V single-core (chip mais barato).
- ESP32-C6: WiFi 6 + Bluetooth + 802.15.4 (Zigbee/Thread).
Setup no Arduino IDE
- File → Preferences:
- Additional Boards Manager URL:
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json - Tools → Board → Boards Manager:
- Procura "esp32" by Espressif → Install (~200MB).
- Liga ESP32 USB.
- Tools → Board → ESP32 → ESP32 Dev Module (genérico).
- 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
- HTTP: APIs REST clássicas. Apropriado para uploads únicos/raros. Mais overhead.
- MQTT: muitas mensagens pequenas, baixo consumo. Preferido em IoT pesado.
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
- QoS 0: fire and forget (pode perder mensagens).
- QoS 1: at least once (pode duplicar).
- QoS 2: exactly once (overhead alto).
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();
- Dashboard auto-actualiza com gráficos.
- 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
- Default credentials (
admin/admin). - MQTT sem TLS — leituras visíveis na rede.
- Firmware velho com vulnerabilidades conhecidas.
- Chaves partilhadas entre devices.
- Sem auth em REST APIs.
Em 2016, botnet Mirai infectou milhões de devices IoT com defaults — usou-os para DDoS massivos.
Mitigações
- MQTTS (TLS) em vez de MQTT plain.
- Credenciais únicas por device.
- Tokens (Adafruit IO usa API keys; AWS usa certificados X.509).
- Rede separada (VLAN IoT).
- OTA updates para patches.
#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
- Reconnect automático WiFi e MQTT.
- Watchdog timer (reinicia se travar).
- Fail-safe defaults (em caso de problema, comportamento sensato).
- Validation de inputs.
#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
- Edge computing: ML no ESP32 (TensorFlow Lite Micro).
- Sensor fusion: combinar múltiplos sensores.
- Mesh networking (ESP-MESH, painlessMesh).
- MicroPython / CircuitPython em ESP32.
- AWS IoT Core / Azure IoT Hub para produtos profissionais.
- Matter standard universal.
- Industrial Modbus / OPC UA para integração fabril.
Glossário
- IoT: Internet of Things.
- IIoT: Industrial IoT.
- MCU: Microcontroller Unit.
- MQTT: Message Queue Telemetry Transport.
- Broker: servidor MQTT.
- Topic: identifier hierárquico de mensagens MQTT.
- QoS: Quality of Service (0, 1, 2).
- Retained: mensagem guardada pelo broker.
- OTA: Over-The-Air firmware update.
- Deep sleep: modo de consumo ultra-baixo.
- Watchdog: reinicia MCU se travar.
- TLS: Transport Layer Security (encriptação).
- MAC address: identifier único de hardware de rede.
- RSSI: força do sinal WiFi em dBm.
Recursos
- Random Nerd Tutorials (randomnerdtutorials.com): excelente IoT/ESP32.
- ESP32 docs (docs.espressif.com).
- HiveMQ MQTT essentials — série gratuita.
- Home Assistant docs.
- Andreas Spiess YouTube (engenheiro suíço, IoT prático).
- Tasmota — firmware open source para muitos devices.
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.