Internet des Objets (IoT)
Cours Complet selon Référentiel BTS
Systèmes Embarqués Connectés · MQTT, Node-RED, Android
1. Structure d'un Système IoT
🎯 Objectifs du chapitre
- Définir l'Internet des Objets et ses caractéristiques
- Comprendre l'architecture en couches d'un système IoT
- Identifier les domaines d'application
- Connaître les flux de données typiques
Caractéristiques d'un objet connecté
- Identifiable : Possède une identité unique (adresse IP, MAC, UUID)
- Connecté : Communique via un réseau (WiFi, Bluetooth, LoRa…)
- Intelligent : Embarque une capacité de traitement (microcontrôleur)
- Interactif : Perçoit (capteurs) et agit (actionneurs) sur l'environnement
- Autonome : Fonctionne de manière indépendante, souvent sur batterie
75 Mds
Objets connectés prévus en 2025
1100 Mds $
Marché mondial IoT
40%
IoT industriel (IIoT)
25%
Smart Home
┌─────────────────────────────────────────────────────────────────────────┐ │ ARCHITECTURE IoT EN 4 COUCHES │ ├─────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ COUCHE APPLICATION │ │ │ │ - Applications mobiles Android/iOS │ │ │ │ - Dashboards web (Node-RED, Grafana) │ │ │ │ - APIs REST, notifications, alertes │ │ │ └─────────────────────────────────────────────────────────────────┘ │ │ ▲ │ │ │ HTTP, WebSocket │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ COUCHE TRAITEMENT (Cloud/Serveur) │ │ │ │ - Broker MQTT (Mosquitto) │ │ │ │ - Bases de données (InfluxDB, MySQL) │ │ │ │ - Traitement Node-RED, règles, analytics │ │ │ └─────────────────────────────────────────────────────────────────┘ │ │ ▲ │ │ │ MQTT, HTTP │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ COUCHE RÉSEAU (Communication) │ │ │ │ - WiFi (ESP32, ESP8266) │ │ │ │ - Bluetooth / BLE (communication courte portée) │ │ │ │ - LoRa / LoRaWAN (longue portée, basse consommation) │ │ │ └─────────────────────────────────────────────────────────────────┘ │ │ ▲ │ │ │ GPIO, I2C, SPI, UART │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ COUCHE PERCEPTION (Dispositifs) │ │ │ │ - Capteurs : température, humidité, mouvement, lumière… │ │ │ │ - Actionneurs : relais, LEDs, moteurs, vannes… │ │ │ │ - Contrôleurs : ESP32, Arduino, STM32, Raspberry Pi │ │ │ └─────────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────┘
Contrôleur
Microcontrôleur (ESP32, Arduino, STM32) qui exécute le programme
Capteurs
Convertissent grandeurs physiques en signaux électriques
Actionneurs
Agissent sur l'environnement (relais, moteurs, LEDs)
Module Radio
WiFi, Bluetooth, LoRa pour la communication
Alimentation
Batterie, USB, secteur selon l'application
Mémoire
Flash, EEPROM pour stocker données et config
Flux de données typique
/* Flux de données dans un système IoT */ 1. ACQUISITION Capteur DHT22 → Mesure température 25.5°C → Signal numérique 2. TRAITEMENT LOCAL (ESP32) Lecture capteur → Formatage JSON → {"temp": 25.5, "hum": 60} 3. TRANSMISSION (WiFi + MQTT) ESP32 → Publish topic "maison/salon/capteur" → Broker Mosquitto 4. TRAITEMENT SERVEUR (Node-RED) Subscribe topic → Règles → Si temp > 30 → Alerte 5. STOCKAGE Node-RED → InfluxDB → Historique des mesures 6. VISUALISATION (Dashboard) Node-RED Dashboard → Graphiques temps réel → Navigateur/Mobile 7. ACTION (retour vers ESP32) Utilisateur clique "Ventilateur ON" → MQTT → ESP32 → Relais ON
| Domaine | Applications | Exemples |
|---|---|---|
| Smart Home | Domotique, sécurité, confort | Thermostat Nest, éclairage Philips Hue |
| Industrie 4.0 | Maintenance prédictive, suivi production | Capteurs vibration, OEE temps réel |
| Agriculture | Irrigation, monitoring cultures | Capteurs sol, stations météo |
| Santé | Wearables, télémédecine | Montres connectées, oxymètres |
| Smart City | Éclairage, parking, déchets | Lampadaires intelligents, capteurs niveau |
| Transport | Flottes, véhicules connectés | GPS trackers, OBD-II |
2. Contrôleurs IoT
🎯 Objectifs du chapitre
- Connaître les principaux contrôleurs IoT
- Maîtriser l'ESP32 et ses caractéristiques
- Configurer l'environnement Arduino IDE
- Programmer l'ESP32 pour l'IoT
| Contrôleur | CPU | WiFi | Bluetooth | GPIO | Prix |
|---|---|---|---|---|---|
| ESP32 | Dual-Core 240MHz | ✓ | ✓ BLE | 34 | ~5€ |
| ESP8266 | Single 80MHz | ✓ | ✗ | 17 | ~3€ |
| Arduino Uno | ATmega328 16MHz | Shield | Shield | 14 | ~20€ |
| Raspberry Pi Pico W | Dual-Core 133MHz | ✓ | ✓ | 26 | ~8€ |
| STM32 + Module | ARM Cortex-M 168MHz | Module | Module | 80+ | ~15€ |
Dual-Core
Xtensa LX6 240 MHz
WiFi
802.11 b/g/n 2.4GHz
Bluetooth
Classic + BLE 4.2
520 Ko SRAM
+ 4-16 Mo Flash
34 GPIO
ADC, DAC, PWM, I2C, SPI
Deep Sleep
10 µA consommation
Brochage ESP32 DevKit
ESP32 DevKit V1 (30 pins)
┌────────────────────────────────┐
│ ANTENNA │
EN ────┤ 1 GND ├──── GND
VP ─────┤ 2 (ADC, input only) 23 ├──── GPIO23 (SPI MOSI)
VN ─────┤ 3 (ADC, input only) 22 ├──── GPIO22 (I2C SCL)
D34 ──────┤ 4 (input only) TX ├──── TX0
D35 ──────┤ 5 (input only) RX ├──── RX0
D32 ──────┤ 6 (ADC, Touch) 21 ├──── GPIO21 (I2C SDA)
D33 ──────┤ 7 (ADC, Touch) GND ├──── GND
D25 ──────┤ 8 (DAC1) 19 ├──── GPIO19 (SPI MISO)
D26 ──────┤ 9 (DAC2) 18 ├──── GPIO18 (SPI SCK)
D27 ──────┤ 10 (Touch) 5 ├──── GPIO5 (SPI CS)
D14 ──────┤ 11 (Touch) 17 ├──── GPIO17 (UART2 TX)
D12 ──────┤ 12 (Touch) 16 ├──── GPIO16 (UART2 RX)
D13 ──────┤ 13 (Touch) 4 ├──── GPIO4
GND ─────┤ 14 0 ├──── GPIO0 (Boot)
VIN ─────┤ 15 (5V input) 2 ├──── GPIO2 (LED intégrée)
│ ┌─────────┐ 15 ├──── GPIO15
│ │ USB │ 3V3 ├──── 3.3V (sortie)
└─────────┴─────────┴────────┘/* Installation ESP32 dans Arduino IDE */ 1. Ouvrir Arduino IDE 2. Fichier → Preferences 3. Dans "URL de gestionnaire de cartes supplémentaires", ajouter : https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json 4. Outils → Type de carte → Gestionnaire de cartes 5. Rechercher "esp32" 6. Installer "ESP32 by Espressif Systems" 7. Sélectionner : Outils → Type de carte → ESP32 Dev Module 8. Sélectionner le port COM (ex : COM3, /dev/ttyUSB0) 9. Upload Speed : 115200
Premier programme : Blink LED
/* Clignotement LED intégrée ESP32 */ #define LED_PIN 2 // LED intégrée sur GPIO2 void setup() { Serial.begin(115200); pinMode(LED_PIN, OUTPUT); Serial.println("ESP32 démarre!"); } void loop() { digitalWrite(LED_PIN, HIGH); Serial.println("LED ON"); delay(1000); digitalWrite(LED_PIN, LOW); Serial.println("LED OFF"); delay(1000); }
/* Lecture capteur DHT22 (température + humidité) */ #include "DHT.h" #define DHTPIN 4 // GPIO4 #define DHTTYPE DHT22 DHT dht(DHTPIN, DHTTYPE); void setup() { Serial.begin(115200); dht.begin(); Serial.println("Capteur DHT22 initialisé"); } void loop() { float humidity = dht.readHumidity(); float temperature = dht.readTemperature(); if (isnan(humidity) || isnan(temperature)) { Serial.println("Erreur lecture capteur!"); return; } Serial.printf("Température: %.1f°C\n", temperature); Serial.printf("Humidité: %.1f%%\n", humidity); delay(2000); // DHT22 nécessite 2s entre lectures }
3. Communication WiFi
🎯 Objectifs du chapitre
- Comprendre les modes WiFi (Station, AP)
- Connecter l'ESP32 à un réseau WiFi
- Créer un point d'accès WiFi
- Gérer la reconnexion automatique
| Mode | Description | Usage |
|---|---|---|
| WIFI_STA | Station : se connecte à un routeur | Accès Internet, cloud, MQTT |
| WIFI_AP | Access Point : crée son réseau | Configuration, réseau local isolé |
| WIFI_AP_STA | Les deux simultanément | Répéteur, config + cloud |
MODE STATION (STA) MODE ACCESS POINT (AP)
┌─────────────┐ ┌─────────────┐
│ ROUTER │ Internet │ ESP32 │
│ WiFi │◀────────── │ AP Mode │
│ 192.168.1.1 │ │ 192.168.4.1 │
└──────┬──────┘ └──────┬──────┘
│ │
┌─────┴─────┐ ┌─────┴─────┐
│ │ │ │
┌────┴───┐ ┌────┴───┐ ┌────┴───┐ ┌────┴───┐
│ ESP32 │ │ PC │ │ Phone │ │ Laptop │
│ STA │ │ │ │ │ │ │
│.1.100 │ │ .1.50 │ │ .4.2 │ │ .4.3 │
└────────┘ └────────┘ └────────┘ └────────┘/* Connexion WiFi en mode Station */ #include <WiFi.h> const char* ssid = "NomDuReseau"; const char* password = "MotDePasse"; void setup() { Serial.begin(115200); // Démarrer la connexion WiFi WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); Serial.print("Connexion à "); Serial.print(ssid); // Attendre la connexion while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("\nWiFi connecté!"); Serial.print("Adresse IP : "); Serial.println(WiFi.localIP()); Serial.print("Force signal (RSSI) : "); Serial.print(WiFi.RSSI()); Serial.println(" dBm"); } void loop() { // Vérifier la connexion if (WiFi.status() != WL_CONNECTED) { Serial.println("WiFi perdu ! Reconnexion..."); WiFi.reconnect(); } delay(10000); }
/* Créer un point d'accès WiFi */ #include <WiFi.h> const char* ap_ssid = "ESP32_IoT"; const char* ap_password = "12345678"; // Min 8 caractères void setup() { Serial.begin(115200); // Configurer l'Access Point WiFi.mode(WIFI_AP); WiFi.softAP(ap_ssid, ap_password); Serial.println("Point d'accès créé !"); Serial.print("SSID : "); Serial.println(ap_ssid); Serial.print("IP : "); Serial.println(WiFi.softAPIP()); // 192.168.4.1 } void loop() { Serial.printf("Clients connectés : %d\n", WiFi.softAPgetStationNum()); delay(5000); }
4. Communication Bluetooth
🎯 Objectifs du chapitre
- Différencier Bluetooth Classic et BLE
- Créer une communication série Bluetooth
- Comprendre l'architecture GATT du BLE
- Communiquer avec une application Android
| Caractéristique | Bluetooth Classic | Bluetooth Low Energy |
|---|---|---|
| Débit | 1-3 Mbps | 125 kbps - 2 Mbps |
| Consommation | ~30 mA | < 15 mA (pics courts) |
| Portée | ~100 m | ~100 m (BLE 5 : 400 m) |
| Latence | ~100 ms | ~6 ms |
| Appairage | Obligatoire | Optionnel |
| Usage | Audio, fichiers | Capteurs IoT, beacons |
Le mode Bluetooth Serial émule une liaison série RS232 via Bluetooth, permettant une communication simple avec un smartphone.
/* Bluetooth Serial avec ESP32 */ #include "BluetoothSerial.h" BluetoothSerial SerialBT; void setup() { Serial.begin(115200); pinMode(2, OUTPUT); // LED // Démarrer Bluetooth avec nom visible SerialBT.begin("ESP32_BT"); Serial.println("Bluetooth démarré. Appairez votre téléphone !"); } void loop() { // Réception depuis smartphone if (SerialBT.available()) { char c = SerialBT.read(); Serial.write(c); // Afficher sur Serial // Commandes simples if (c == '1') { digitalWrite(2, HIGH); SerialBT.println("LED ON"); } else if (c == '0') { digitalWrite(2, LOW); SerialBT.println("LED OFF"); } } // Envoi depuis Serial vers smartphone if (Serial.available()) { SerialBT.write(Serial.read()); } }
Le BLE utilise une architecture GATT (Generic Attribute Profile) avec des Services et Caractéristiques :
ARCHITECTURE GATT BLE
┌─────────────────────────────────────────┐
│ PROFIL │
│ (ex : Sensor Profile) │
└────────────────────┬────────────────────┘
│
┌─────────────┴─────────────┐
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ SERVICE 1 │ │ SERVICE 2 │
│ UUID: 0x180D │ │ UUID: 0x180F │
│ (Temperature) │ │ (Battery) │
└────────┬────────┘ └────────┬────────┘
│ │
┌────────┴────────┐ ┌────────┴────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ CHARACT. │ │ CHARACT. │ │ CHARACT. │
│ Temp │ │ Humidity │ │ Level │
│ Read │ │ Notify │ │ Read │
└──────────┘ └──────────┘ └──────────┘/* Serveur BLE avec ESP32 */ #include <BLEDevice.h> #include <BLEServer.h> #include <BLEUtils.h> #include <BLE2902.h> #define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" #define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8" BLECharacteristic* pCharacteristic; bool deviceConnected = false; class MyCallbacks: public BLEServerCallbacks { void onConnect(BLEServer* pServer) { deviceConnected = true; } void onDisconnect(BLEServer* pServer) { deviceConnected = false; } }; void setup() { BLEDevice::init("ESP32_BLE"); BLEServer* pServer = BLEDevice::createServer(); pServer->setCallbacks(new MyCallbacks()); BLEService* pService = pServer->createService(SERVICE_UUID); pCharacteristic = pService->createCharacteristic( CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY ); pCharacteristic->addDescriptor(new BLE2902()); pService->start(); pServer->getAdvertising()->start(); } void loop() { if (deviceConnected) { float temp = 25.5; // Lecture capteur char buf[8]; sprintf(buf, "%.1f", temp); pCharacteristic->setValue(buf); pCharacteristic->notify(); } delay(2000); }
5. Communication LoRa
🎯 Objectifs du chapitre
- Comprendre la technologie LoRa et LPWAN
- Connaître les paramètres de modulation
- Configurer un module LoRa avec ESP32
- Comparer LoRa avec WiFi et Bluetooth
15+ km
Portée en zone rurale
10 ans
Autonomie sur pile
50 kbps
Débit maximum
| Technologie | Portée | Débit | Consommation | Usage |
|---|---|---|---|---|
| WiFi | ~100 m | Jusqu'à Gbps | Élevée | Internet, streaming |
| Bluetooth | ~100 m | 1-3 Mbps | Moyenne | Périphériques, audio |
| BLE | ~100 m | 2 Mbps | Très faible | Capteurs, wearables |
| LoRa | 15+ km | 50 kbps | Très faible | Agriculture, smart city |
| Zigbee | ~100 m | 250 kbps | Faible | Domotique, mesh |
/* Émetteur LoRa avec ESP32 + SX1276 */ #include <SPI.h> #include <LoRa.h> // Pins pour module LoRa #define SS 18 #define RST 14 #define DIO0 26 #define BAND 868E6 // Fréquence Europe (868 MHz) void setup() { Serial.begin(115200); LoRa.setPins(SS, RST, DIO0); if (!LoRa.begin(BAND)) { Serial.println("Erreur initialisation LoRa !"); while(1); } // Configuration LoRa.setSpreadingFactor(9); // SF7-SF12 LoRa.setSignalBandwidth(125E3); // 125 kHz LoRa.setTxPower(14); // 14 dBm Serial.println("LoRa initialisé !"); } void loop() { // Envoi d'un paquet LoRa.beginPacket(); LoRa.print("Hello LoRa #"); LoRa.print(millis()); LoRa.endPacket(); Serial.println("Paquet envoyé"); delay(5000); }
6. Protocole MQTT
🎯 Objectifs du chapitre
- Comprendre l'architecture publish/subscribe
- Maîtriser les concepts MQTT (topics, QoS, retain)
- Programmer un client MQTT sur ESP32
- Publier et s'abonner à des topics
ARCHITECTURE MQTT
┌─────────────────┐
│ BROKER │
│ (Mosquitto) │
│ Port: 1883 │
└────────┬────────┘
│
┌──────────────────┼──────────────────┐
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ PUBLISHER│ │SUBSCRIBER│ │ PUB+SUB │
│ ESP32 │ │ Phone │ │ Node-RED │
│ (Capteur)│ │ App │ │ │
└──────────┘ └──────────┘ └──────────┘
Publish: sensors/temp ──────▶ Broker ──────▶ Subscribers
"25.5" (route) (reçoivent)Les topics sont des chemins hiérarchiques utilisés pour organiser les messages :
/* Structure des topics MQTT */ // Hiérarchie avec "/" maison/salon/temperature maison/salon/humidite maison/cuisine/lumiere usine/machine1/vibration /* Wildcards pour abonnements */ + : Remplace UN niveau maison/+/temperature → salon, cuisine, chambre... # : Remplace TOUS les niveaux (fin uniquement) maison/# → tout ce qui commence par maison/
Qualité de Service (QoS)
| QoS | Garantie | Usage |
|---|---|---|
| 0 | At most once (peut être perdu) | Données fréquentes (température) |
| 1 | At least once (doublons possibles) | Données importantes |
| 2 | Exactly once | Commandes critiques |
/* Client MQTT complet avec ESP32 */ #include <WiFi.h> #include <PubSubClient.h> // Configuration const char* ssid = "VotreWiFi"; const char* password = "MotDePasse"; const char* mqtt_server = "192.168.1.100"; // IP du broker const int mqtt_port = 1883; WiFiClient espClient; PubSubClient client(espClient); // Callback réception messages void callback(char* topic, byte* payload, unsigned int length) { Serial.printf("Message reçu [%s] : ", topic); String message; for (int i = 0; i < length; i++) { message += (char)payload[i]; } Serial.println(message); // Traiter les commandes if (String(topic) == "esp32/led") { if (message == "ON") digitalWrite(2, HIGH); if (message == "OFF") digitalWrite(2, LOW); } } void reconnect() { while (!client.connected()) { Serial.print("Connexion MQTT..."); if (client.connect("ESP32Client")) { Serial.println("connecté !"); client.subscribe("esp32/led"); // S'abonner } else { Serial.println(" échec, retry..."); delay(5000); } } } void setup() { Serial.begin(115200); pinMode(2, OUTPUT); // Connexion WiFi WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) delay(500); Serial.println("WiFi OK"); // Configuration MQTT client.setServer(mqtt_server, mqtt_port); client.setCallback(callback); } void loop() { if (!client.connected()) reconnect(); client.loop(); // Publier toutes les 10 secondes static unsigned long lastMsg = 0; if (millis() - lastMsg > 10000) { lastMsg = millis(); float temp = 25.5; // Lecture capteur char msg[10]; sprintf(msg, "%.1f", temp); client.publish("esp32/temperature", msg); Serial.printf("Publié : %s\n", msg); } }
7. Installation Broker Mosquitto
🎯 Objectifs du chapitre
- Installer Mosquitto sur différentes plateformes
- Configurer le broker MQTT
- Tester avec mosquitto_pub et mosquitto_sub
- Sécuriser le broker (authentification)
# Installation sur Raspberry Pi / Ubuntu / Debian sudo apt update sudo apt install mosquitto mosquitto-clients -y # Démarrer et activer au démarrage sudo systemctl start mosquitto sudo systemctl enable mosquitto # Vérifier le statut sudo systemctl status mosquitto # Installation sur Windows # 1. Télécharger depuis : https://mosquitto.org/download/ # 2. Exécuter l'installeur .exe # 3. Le service démarre automatiquement
# Fichier : /etc/mosquitto/mosquitto.conf # Écouter sur toutes les interfaces listener 1883 # Autoriser les connexions anonymes (dev uniquement) allow_anonymous true # --- Configuration avec authentification --- # allow_anonymous false # password_file /etc/mosquitto/passwd # Créer un utilisateur : sudo mosquitto_passwd -c /etc/mosquitto/passwd monuser # Entrer le mot de passe quand demandé # Redémarrer après modification sudo systemctl restart mosquitto
# Terminal 1 : S'abonner à un topic mosquitto_sub -h localhost -t "test/topic" # Terminal 2 : Publier un message mosquitto_pub -h localhost -t "test/topic" -m "Hello MQTT!" # S'abonner à TOUS les topics (debug) mosquitto_sub -h localhost -t "#" -v # Avec authentification mosquitto_pub -h localhost -u monuser -P motdepasse -t "test" -m "Secure!" # Connexion à un broker distant mosquitto_sub -h broker.hivemq.com -t "test/#"
broker.hivemq.com— Port 1883test.mosquitto.org— Port 1883broker.emqx.io— Port 1883