BUT Mesures Physiques · IUT Aix-Marseille · 2026-2027

Exemple : envoyer des mesures depuis un ModuleAir

Le programme le plus simple : connexion à eduroam, envoi de mesures fixes toutes les 60 secondes, affichage de la réponse du serveur. Il fonctionne aussi sur un NebuleAir (retirez co2).

Code de l'exemple du guide IUT-AMU-09 « Envoyer les mesures de votre capteur au serveur AirCarto », v1.8 du 2026-10-23. Les explications sont dans le PDF.

Mise en route

  1. Téléchargez le projet (bouton vert), décompressez-le. Dans VS Code, onglet PlatformIO, Open Project, choisissez le dossier décompressé.
    Ou créez un projet PlatformIO (carte Espressif ESP32 Dev Module, framework Arduino) et remplacez ses fichiers par ceux ci-dessous, avec le bouton Copier.
  2. Dans src/main.cpp, remplacez les valeurs d'exemple : identifiant et mot de passe ENT, clé du groupe.
  3. Téléversez (Upload), puis ouvrez le moniteur série (Monitor, 115200 bauds).

Ne republiez jamais le fichier une fois rempli : il contient votre mot de passe ENT et la clé du groupe (pas de dépôt Git public, de photo, de compte-rendu). Avant de rendre ou de prêter la carte, effacez-la : pio run -t erase.

Le projet

Télécharger le projet IUT-AMU-09-exemple-v1.8.zip
platformio.ini
[env:moduleair]
platform = espressif32 @ 7.1.3
board = esp32dev
framework = arduino
monitor_speed = 115200
src/main.cpp
// Exemple minimal : Wi-Fi eduroam + envoi de fausses mesures fixes toutes les 60 s.
#include <Arduino.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include "esp_wpa2.h"

const char* WIFI_SSID    = "eduroam";
const char* EAP_IDENTITY = "prenom.nom@etu.univ-amu.fr";  // identifiant ENT complet
const char* EAP_PASSWORD = "MOT_DE_PASSE_ENT";
const char* GROUP_KEY    = "VOTRE_CLE";
const char* URL          = "http://api.aircarto.fr/iut-amu/push";

void connectWiFi() {
  Serial.print("Connexion a ");
  Serial.print(WIFI_SSID);
  // eduroam = WPA2 Entreprise (PEAP / MSCHAPv2) : identifiant + mot de passe ENT
  esp_wifi_sta_wpa2_ent_set_identity((uint8_t*)EAP_IDENTITY, strlen(EAP_IDENTITY));
  esp_wifi_sta_wpa2_ent_set_username((uint8_t*)EAP_IDENTITY, strlen(EAP_IDENTITY));
  esp_wifi_sta_wpa2_ent_set_password((uint8_t*)EAP_PASSWORD, strlen(EAP_PASSWORD));
  esp_wifi_sta_wpa2_ent_enable();
  WiFi.begin(WIFI_SSID);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.print(" OK, IP : ");
  Serial.println(WiFi.localIP());
}

void sendMeasure() {
  // Fausses mesures fixes : à remplacer par les lectures des capteurs.
  String json = "{";
  json += "\"device_id\": \"" + WiFi.macAddress() + "\", ";
  json += "\"pm1\": 1.8, \"pm25\": 2.9, \"pm10\": 4.4, ";
  json += "\"co2\": 812, ";
  json += "\"npm_status\": 0";  // état du NextPM (guide IUT-AMU-04) : 0 = OK, 255 = ne répond pas
  json += "}";
  Serial.print("Envoi : ");
  Serial.println(json);

  HTTPClient http;
  http.begin(URL);
  http.addHeader("Content-Type", "application/json");
  http.addHeader("X-Group-Key", GROUP_KEY);
  int code = http.POST(json);

  if (code > 0) {
    // Code HTTP reçu : afficher aussi le corps, il explique les erreurs.
    Serial.print("Reponse HTTP ");
    Serial.println(code);
    Serial.println(http.getString());
  } else {
    // Pas de réponse du tout : Wi-Fi, URL ou serveur injoignable.
    Serial.print("Echec de l'envoi : ");
    Serial.println(http.errorToString(code));
  }
  http.end();
}

void setup() {
  Serial.begin(115200);
  delay(1000);
  WiFi.mode(WIFI_STA);  // avant WiFi.macAddress(), sinon la MAC lue vaut 0
  connectWiFi();
}

void loop() {
  if (WiFi.status() != WL_CONNECTED) {
    connectWiFi();      // le Wi-Fi est tombé : on se reconnecte
  }
  sendMeasure();
  delay(60000);         // 60 s ; delay() bloque la carte pendant ce temps
}