/* * TipTop - Moniteur de température * Board : Adafruit Feather ESP32-S2 * Capteur: BME280 (I2C) * LED : NeoPixel intégré (broche 33) * Seuil : 57 °C → vert si < 57 | rouge si ≥ 57 * Telegram: message envoyé quand la température repasse sous 57 °C */ #include #include #include #include #include // ───────────────────────────────────────────── // CONFIGURATION → remplissez ces valeurs // ───────────────────────────────────────────── const char* WIFI_SSID = "iPhone"; const char* WIFI_PASSWORD = "tortue2000"; const String BOT_TOKEN = "8699409267:AAEIkSJwbAoe6kpGztx5k-FugjZc4S_q148"; // ex: 123456789:ABCdef... const String CHAT_ID = "8797119126"; // ex: 987654321 const float SEUIL_TEMP = 57.0; // seuil en °C // ───────────────────────────────────────────── // NeoPixel intégré du Feather ESP32-S2 #define NEOPIXEL_PIN 33 #define NEOPIXEL_COUNT 1 Adafruit_NeoPixel pixel(NEOPIXEL_COUNT, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800); // BME280 Adafruit_BME280 bme; // État précédent pour détecter le passage sous le seuil bool etaitChaud = false; // ───────────────────────────────────────────── void setup() { Serial.begin(115200); delay(500); Serial.println("\n== TipTop démarrage =="); // NeoPixel pixel.begin(); pixel.setBrightness(80); // 0-255, ajustez selon vos yeux pixel.show(); // BME280 (adresse I2C par défaut : 0x76 ou 0x77) if (!bme.begin(0x76)) { if (!bme.begin(0x77)) { Serial.println("BME280 non trouvé ! Vérifiez le câblage."); setCouleur(0, 0, 50); // bleu clignotant = erreur capteur while (true) { pixel.clear(); pixel.show(); delay(300); setCouleur(0, 0, 50); delay(300); } } } Serial.println("BME280 détecté."); // WiFi Serial.print("Connexion WiFi"); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("\nWiFi connecté — IP : " + WiFi.localIP().toString()); } // ───────────────────────────────────────────── void loop() { float temperature = bme.readTemperature(); Serial.print("Température : "); Serial.print(temperature, 1); Serial.println(" °C"); if (temperature >= SEUIL_TEMP) { // ── Trop chaud → LED rouge ── setCouleur(255, 0, 0); etaitChaud = true; } else { // ── En dessous du seuil → LED verte ── setCouleur(0, 255, 0); // Envoi Telegram uniquement lors du passage chaud → froid if (etaitChaud) { Serial.println("Passage sous le seuil → envoi Telegram…"); envoyerTelegram("🍵 Votre boisson est prête. Signé TipTop."); etaitChaud = false; } } delay(2000); // lecture toutes les 2 secondes } // ───────────────────────────────────────────── // Allume le NeoPixel avec la couleur RGB // ───────────────────────────────────────────── void setCouleur(uint8_t r, uint8_t g, uint8_t b) { pixel.setPixelColor(0, pixel.Color(r, g, b)); pixel.show(); } // ───────────────────────────────────────────── // Envoie un message via l'API Telegram Bot // ───────────────────────────────────────────── void envoyerTelegram(String message) { if (WiFi.status() != WL_CONNECTED) { Serial.println("WiFi déconnecté, message non envoyé."); return; } HTTPClient http; String url = "https://api.telegram.org/bot" + BOT_TOKEN + "/sendMessage?chat_id=" + CHAT_ID + "&text=" + urlencode(message); http.begin(url); int code = http.GET(); if (code == 200) { Serial.println("Message Telegram envoyé ✓"); } else { Serial.println("Erreur Telegram : HTTP " + String(code)); } http.end(); } // ───────────────────────────────────────────── // Encode une chaîne pour URL (espaces, accents…) // ───────────────────────────────────────────── String urlencode(String str) { String encoded = ""; char c; for (int i = 0; i < str.length(); i++) { c = str.charAt(i); if (isAlphaNumeric(c) || c == '-' || c == '_' || c == '.' || c == '~') { encoded += c; } else { encoded += '%'; if ((uint8_t)c < 16) encoded += '0'; encoded += String((uint8_t)c, HEX); } } return encoded; }