C'est l'hiver ! Hiver.gif

ENIB 2026 : Enibel

De Les Fabriques du Ponant
Révision datée du 20 janvier 2026 à 11:35 par Mama (discussion | contributions) (Code Arduino)
Aller à : navigation, rechercher

Introduction

Dans le cadre de notre intersemestre, nous participons au hackathon « Hack the POCL », organisé par Les Petits Débrouillards et Les Fabriques du Ponant.

L’objectif de ce hackathon est de rendre des données tangibles en inventant un POCL : un Petit Objet Connecté Ludique.

Notre projet doit également être documenté, c’est pourquoi ce wiki a été créé, afin de retracer la genèse et l’évolution de notre travail.

Nous avons choisi de concevoir un décibelmètre capable d’allumer différentes LED en fonction du niveau sonore capté par un micro.

Ce dispositif peut avoir plusieurs usages, le plus évident étant une utilisation en salle de classe.

Une fois le système installé, une limite de décibels sera définie dans le code que nous fournirons, afin de déclencher l’allumage des LED selon le niveau de bruit. 3 niveaux :

  • Vert : le niveau sonore est faible
  • Jaune : le niveau sonore est assez élevé
  • Rouge : le niveau sonore est très élevé

Équipe

Voici notre équipe :

Enib.jpg

À gauche : Léïa et Maël

À droite : Arthur et Alexis

Ainsi que Mael, non présent lors de la photo

Nous sommes tous les cinq des étudiant·e·s de 3e année de l'ENIB

Logo-enib.png

Outils et matériel

Pour réaliser ce projet, nous avons besoin :

  • Un ESP32S (ou node MCU_32S)
  • Un ESP32S 38P
  • Un panneau LED 16x16
  • Des câbles Dupont
  • Un micro INMP441

Fichiers à joindre

Code Arduino

  1  //Librairie
  2 #include <Adafruit_NeoPixel.h>
  3 #include <driver/i2s.h>
  4 
  5 //Configuration
  6 ///Leds
  7 #define W2812_PIN 27 //Broche du Din du panneau led 
  8 #define WS2812_PIXELS_NUM 256 // Nombres de leds
  9 ///Micro
 10 #define I2S_WS 25 //GPIO 25
 11 #define I2S_SD 32 //GPIO 32
 12 #define I2S_SCK 33 //GPIO 33
 13 
 14 //Matrice
 15 Adafruit_NeoPixel ledStrip(WS2812_PIXELS_NUM, W2812_PIN, NEO_GRB + NEO_KHZ800); 
 16 // Crée l'instance ledStrip avec 256 LED/pixels sur la sortie GPIO27->PIN27 du microcontrôleur. La communication se fera en GRB (Green, Red, Blue) à 800kHZ
 17 
 18 //Variable systèmes
 19 ///Luminosité
 20 const int luminosite = 10;
 21 ///Couleurs codées en (red, green, blue)
 22 uint32_t white = ledStrip.Color(255, 255, 255); // Blanc
 23 uint32_t green = ledStrip.Color(0, 255, 0); // Vert
 24 uint32_t red = ledStrip.Color(255, 0, 0); // Rouge
 25 uint32_t yellow = ledStrip.Color(255, 255, 0); // Jaune
 26 uint32_t marine_blue = ledStrip.Color(46, 62, 115); // Bleu marine
 27 ///Seuils son
 28 const int seuil_orange = 70; //dB -> Jaune
 29 const int seuil_rouge = 90; //dB -> Rouge
 30 const int GAIN_CALIBRATION = 20;
 31 ///Variable micro
 32 unsigned long lastAudioRead = 0;
 33 float dB_cached = 0;
 34 ///Dessins
 35 // On utilise uint16_t car il y a 16 bits (pixels) par ligne
 36 const uint16_t faceHappy[16] = {
 37   0b1111111111111111,
 38   0b1111100000011111,
 39   0b1111011111101111,
 40   0b1110111111110111,
 41   0b1101111111111011,
 42   0b1011100111001101, // Yeux
 43   0b1011100111001101, // Yeux
 44   0b1011111111111101,
 45   0b1011111111111101,
 46   0b1011011111101101, // Début sourire
 47   0b1011101111011101,
 48   0b1101110000111011,
 49   0b1110111111110111,
 50   0b1111011111101111,
 51   0b1111100000011111,
 52   0b1111111111111111
 53 };
 54 const uint16_t faceNeutral[16] = {
 55   0b1111111111111111,
 56   0b1111100000011111,
 57   0b1111011111101111,
 58   0b1110111111110111,
 59   0b1101111111111011,
 60   0b1011100111001101, // Yeux
 61   0b1011100111001101, // Yeux
 62   0b1011111111111101,
 63   0b1011111111111101,
 64   0b1011111111111101,
 65   0b1011000000001101, // Bouche droite
 66   0b1101111111111011,
 67   0b1110111111110111,
 68   0b1111011111101111,
 69   0b1111100000011111,
 70   0b1111111111111111
 71 };
 72 const uint16_t faceSad[16] = {
 73   0b1111111111111111,
 74   0b1111100000011111,
 75   0b1111011111101111,
 76   0b1110111111110111,
 77   0b1101111111111011,
 78   0b1011100111001101, // Yeux
 79   0b1011100111001101, // Yeux
 80   0b1011111111111101,
 81   0b1011111111111101,
 82   0b1011110000111101, // Bouche triste
 83   0b1011101111011101,
 84   0b1101011111101011,
 85   0b1110111111110111,
 86   0b1111011111101111,
 87   0b1111100000011111,
 88   0b1111111111111111
 89 };
 90 
 91 int i;
 92 
 93 void setup() {
 94   // put your setup code here, to run once:
 95   Serial.begin(115200);
 96   ledStrip.begin();
 97   ledStrip.setBrightness(luminosite);
 98   setupI2S();
 99   Serial.println("BOOT OK");
100 }
101 
102 void loop() {
103 
104   // --- Lecture audio toutes les 100 ms ---
105   if (millis() - lastAudioRead > 100) {
106     dB_cached = readDecibels();
107     lastAudioRead = millis();
108     Serial.println(dB_cached);
109   }
110 
111   // --- Affichage ---
112   if (dB_cached >= seuil_rouge) {
113     afficherDessin(faceSad, red);
114   }
115   else if (dB_cached >= seuil_orange) {
116     afficherDessin(faceNeutral, yellow);
117   }
118   else {
119     afficherDessin(faceHappy, green);
120   }
121 
122   delay(10);   // laisse respirer FreeRTOS
123   yield();     // nourrit le watchdog
124   Serial.println("RUNNING");
125   delay(1000);
126 }
127 
128 //Fonction d'affichage en 16x16
129 void afficherDessin(const uint16_t dessin[], uint32_t couleur){
130   ledStrip.clear();
131   for (int y = 0; y<16; y++){
132     for (int x = 0; x<16; x++){
133       //On verif le bit x dans la ligne y ( en partant de la gauche)
134       if ((dessin[y]>>(15-x)) & 0x01){
135         int index;
136         // Logique serpentin pour largueur 16
137         if (y%2 ==0){
138           index = (y * 16) + x;
139         }else{
140           index = (y*16) + (15 - x);
141         }
142         ledStrip.setPixelColor(index, couleur);
143       }
144     }
145   }
146   ledStrip.show();
147 }
148 
149 //Fonction MICRO (I2S)
150 void setupI2S() {
151   const i2s_config_t i2s_config = {
152     .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
153     .sample_rate = 44100,
154     .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
155     .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
156     .communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),
157     .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
158     .dma_buf_count = 8,
159     .dma_buf_len = 64
160   };
161   i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
162   const i2s_pin_config_t pins = {.bck_io_num = I2S_SCK, .ws_io_num = I2S_WS, .data_out_num = -1, .data_in_num = I2S_SD};
163   i2s_set_pin(I2S_NUM_0, &pins);
164   i2s_zero_dma_buffer(I2S_NUM_0);
165   delay(10);
166 }
167 
168 float readDecibels() {
169   static int32_t samples[128];
170   size_t bytesRead = 0;
171 
172   esp_err_t result = i2s_read(
173     I2S_NUM_0,
174     samples,
175     sizeof(samples),
176     &bytesRead,
177     20 / portTICK_PERIOD_MS
178   );
179 
180   if (result != ESP_OK || bytesRead < 16) {
181     return dB_cached;  // garde l’ancienne valeur
182   }
183 
184   long long sum = 0;
185   int count = bytesRead / 4;
186 
187   for (int i = 0; i < count; i++) {
188     int32_t val = samples[i] >> 14;
189     sum += (int64_t)val * val;
190   }
191 
192   float rms = sqrt((float)sum / count);
193   if (rms <= 0) return dB_cached;
194 
195   return 20.0 * log10(rms) + GAIN_CALIBRATION;
196 }

Schéma de branchement

ENIBEL Schema.jpg

Étapes de fabrication

Ce projet est assez simple et nécessite peu d'étapes :

Étape 1

Tout d'abord, vérifiez le matériel : que les pins soient en bon état, qu'il n'y ait pas de câble sectionné, pas de LED cassé…

Pour l'Arduino, il faut connecter l'ESP32S à votre ordinateur et également avoir l'application Arduino et leurs pilotes (Adafruit DMA neopixel library par Adafruit). Pour plus de détails, référez vous vers ce lien : https://www.wikidebrouillard.org/wiki/Utiliser_l%27ESP32_avec_le_logiciel_Arduino

Étape 2

Ouvrez l'application Arduino et copiez le code fourni.

Faites le branchement également fourni.

Étape 3

Vous pouvez modifiez dans le code les différents paramètres mis en valeur par défaut pour changer les niveaux de décibels où les LEDs s'activent.

Vous pouvez également changer pour adapter à un panneau LED plus petit ou plus grand.

De même pour l'affichage ainsi que les couleurs qui s'activeront.

Notre histoire

Après avoir réfléchis a plusieurs idées, nous sommes partis sur un décibelmètre capable d’allumer différentes LED en fonction du niveau sonore capté par un micro.

Pour cela, nous étions parti sur des LEDs polarisées mais après une demande au magasin des petits débrouillards, nous avons eu un panneau LED ce qui nous arrange pour le résultat final. Nous voulons faire un smiley pour le cas d'une salle de classe.

Un problème que nous avons rencontré est le branchement du panneau LED qui ne marchait sur aucun des appareils de l'équipe et le téléversement du code sur l'ESP32S avec l'erreur


Problème

rstx0x8 (TG1WDT_SYS_RESET)

Solution

Sources et documentation complémentaire

  • Rédаctiоn et illustratiоn :

Pоur tоus vоs trаvauх, qu'ils sоient écrits оu visuels, l'utilisatiоn de l'intеlligеnce artificiеllе générativе, que сe sоit pоur le teхte оu les images, n'еst pas conseillé.

  • Prоgrammаtiоn :

En сe qui cоncernе la prоgrаmmatiоn, il est еssentiеl de ne pаs faire dе l'IA vоtrе prеmier rеcоurs. Cоncеntrеz-vоus d'abоrd sur vоtre prоpre lоgiquе, votre experience еt lеs ressоurcеs disponibles.

  • Transpаrence et dосumеntatiоn :

Si vоus utilisеz l'IA pоur déblоquer оu améliоrеr une pаrtiе de vоtre cоdе, il est cruciаl de l'indiquеr сlairеmеnt dans vоtre dосumentatiоn tеchniquе.

  • Traçabilité :

Chаque ехtrait de cоde généré avес l'аidе de l'IA dоit êtrе accоmpagné de la sоurce, ainsi que du prоmpt eхact qui a été utilisé pоur sа créatiоn, afin d'аssurеr une évaluatiоn clаire dе vоtre prоcessus.

Élément de présentation

ENIBEL.jpg

Ne pas modifier sous cette ligne