#include // 📚 BibliothĂšque U8g2 pour gĂ©rer l’écran OLED SSD1306 via I2C logiciel const int mq4Pin = 2; // đŸ§Ș MQ-4 branchĂ© sur GPIO2 (entrĂ©e analogique) // đŸ–„ïž DĂ©claration de l’écran OLED SSD1306 (128x64 pixels) // Utilisation d’I2C logiciel : SCL = GPIO6, SDA = GPIO5 U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, 6, 5, U8X8_PIN_NONE); unsigned long lastSwitch = 0; // ⏱ Dernier changement d’écran const unsigned long switchInterval = 5000; // ⏱ Intervalle entre Ă©crans (5s) int modeAffichage = 0; // 0 = valeur+texte, 1 = barre, 2 = icĂŽne ASCII bool startupDone = false; // ⚡ Pour afficher l’écran d’accueil une seule fois void setup() { Serial.begin(115200); delay(1000); u8g2.begin(); u8g2.setContrast(255); // LuminositĂ© maximale // === Écran d’accueil === const int xOffset = 28; // Position X du cadre const int yOffset = 24; // Position Y du cadre const int largeur = 72; // Largeur du cadre const int hauteur = 40; // Hauteur du cadre u8g2.clearBuffer(); u8g2.drawFrame(xOffset, yOffset, largeur, hauteur); // Dessin du cadre u8g2.setFont(u8g2_font_6x12_tr); // Police compacte pour 3 lignes // Texte Ă  afficher const char* l1 = "Gaz"; const char* l2 = "Detector"; const char* l3 = "v1.0"; // 📐 Calcul typographique pour centrer verticalement les 3 lignes int ascent = u8g2.getAscent(); int descent = u8g2.getDescent(); // nĂ©gatif int fontH = ascent - descent; int lineSpacing = 2; // espace entre lignes int blockH = 3 * fontH + 2 * lineSpacing; // hauteur totale du bloc texte // Baseline de chaque ligne int baseY1 = yOffset + (hauteur - blockH) / 2 + ascent; int baseY2 = baseY1 + fontH + lineSpacing; int baseY3 = baseY2 + fontH + lineSpacing; // Centrage horizontal par ligne int w1 = u8g2.getStrWidth(l1); int w2 = u8g2.getStrWidth(l2); int w3 = u8g2.getStrWidth(l3); int x1 = xOffset + (largeur - w1) / 2; int x2 = xOffset + (largeur - w2) / 2; int x3 = xOffset + (largeur - w3) / 2; // ✍ Dessin des 3 lignes u8g2.drawStr(x1, baseY1, l1); u8g2.drawStr(x2, baseY2, l2); u8g2.drawStr(x3, baseY3, l3); u8g2.sendBuffer(); delay(3000); // Affichage pendant 3 secondes startupDone = true; // ⚡ Ensuite on passe au cycle normal } // đŸ”Č Fonction pour dessiner une barre horizontale (Ă©cran 2) void drawBatteryBar(int valeur) { const int xOffset = 28; const int yOffset = 24; int largeur = 72; int hauteur = 40; u8g2.drawFrame(xOffset, yOffset, largeur, hauteur); int barWidth = map(valeur, 0, 4095, 0, largeur - 4); int barHeight = 10; int barX = xOffset + 2; int barY = yOffset + (hauteur - barHeight) / 2; u8g2.drawBox(barX, barY, barWidth, barHeight); } void loop() { if (!startupDone) return; // ⏞ Ne rien faire tant que l’écran d’accueil n’est pas passĂ© // đŸ“„ Lecture du capteur MQ-4 int valeur = analogRead(mq4Pin); // DĂ©termination du niveau const char* etat; int niveau; if (valeur < 500) { etat = "Tres faible"; niveau = 1; } else if (valeur < 2000) { etat = "Faible"; niveau = 2; } else if (valeur < 5000) { etat = "Moyen"; niveau = 3; } else if (valeur < 8000) { etat = "Eleve"; niveau = 4; } else { etat = "Critique"; niveau = 5; } // ⏱ Alternance d’écran toutes les 5 secondes if (millis() - lastSwitch > switchInterval) { modeAffichage = (modeAffichage + 1) % 3; lastSwitch = millis(); } u8g2.clearBuffer(); if (modeAffichage == 0) { // === Écran 1 : valeur MQ4 + niveau === const int xOffset = 28; const int yOffset = 24; int largeur = 72; int hauteur = 40; u8g2.drawFrame(xOffset, yOffset, largeur, hauteur); u8g2.setFont(u8g2_font_7x14_tr); // Ligne 1 : valeur brute char ligne1[20]; snprintf(ligne1, sizeof(ligne1), "MQ4:%d", valeur); int w1 = u8g2.getStrWidth(ligne1); int x1 = xOffset + (largeur - w1) / 2; int y1 = yOffset + 16; // Ligne 2 : texte du niveau int w2 = u8g2.getStrWidth(etat); int x2 = xOffset + (largeur - w2) / 2; int y2 = yOffset + 32; u8g2.drawStr(x1, y1, ligne1); u8g2.drawStr(x2, y2, etat); } else if (modeAffichage == 1) { // === Écran 2 : barre horizontale === drawBatteryBar(valeur); } else { // === Écran 3 : icĂŽne ASCII centrĂ©e === const int xOffset = 28; const int yOffset = 24; int largeur = 72; int hauteur = 40; u8g2.drawFrame(xOffset, yOffset, largeur, hauteur); u8g2.setFont(u8g2_font_10x20_tr); // Choix du symbole ASCII selon le niveau const char* symbole; switch (niveau) { case 1: symbole = "OK"; break; case 2: symbole = ":)"; break; case 3: symbole = ":|"; break; case 4: symbole = "!!"; break; case 5: symbole = "!!!"; break; } // Centrage horizontal int w = u8g2.getStrWidth(symbole); int x = xOffset + (largeur - w) / 2; // Centrage vertical avec ascent/descent int ascent = u8g2.getAscent(); int descent = u8g2.getDescent(); int fontH = ascent - descent; int y = yOffset + (hauteur - fontH) / 2 + ascent; u8g2.drawStr(x, y, symbole); } u8g2.sendBuffer(); delay(1000); // Pause entre deux mesures }