EM LIGHT

Auteur avatarBenjamin Fouilhac | Dernière modification 12/12/2025 par BenjaminF

Item-POCL Light EM IMG 20251015 153044.jpg
La fabrication de l'objet s'inscrit dans une volonté de dévoiler le fonctionnement afin de faciliter la compréhension et la maintenabilité de l'appareil. En effet, tous les composants sont visibles, toutes les soudures et câbles également.
Difficulté
Technique
Durée
2 jour(s)
Disciplines scientifiques
Informatique, Electricité, Mathématique, Sciences sociales
<languages />
Licence : Attribution (CC-BY)

Introduction

Light'EM est un POCL (Petit Objet Connecté Ludique) réalisé lors du Hackaton de l'association "Les Petits Débrouillards" du 13 au 15 octobre 2025. Il récupère les données des capteurs d'ondes électromagnétiques (EM) de Bordeaux et retranscrit ces données invisibles en une couleur indiquant un léger degré de pollution (vert) jusqu'à un degré plus fort (rouge). L'idée est de mettre en lumière la pollution électromagnétique dans la ville de Bordeaux.

Étape 1 - Découpe laser

Structure :  

A l’aide de la découpeuse laser, réaliser les différentes pièces pour l’assemblage. (voir fichier ci-dessous).

Dimensions cercles : Cercles intérieurs 9cm de diamètre ; cercle extérieur 10cm de diamètre.

Dimensions carrés : 9 cm de coté.

Dimensions rectangle : 9cm de longueurs et 7cm de largeurs



Étape 2 - Découpe cercle

Découper également à l’aide compas-cutter 6 cercles de claques transparents de diamètre différents :

Un de 2cm, 4cm, 6cm, 8cm, 10cm, 12cm.



Étape 3 - Début assemblage

Notre produit est constitué de 4 étages qui sont respectivement : un 1er étage formé de 2 rectangles avec un trou carré au milieu où l’on retrouve la carte mère du produit ; un 2e étage toujours formé de 2 rectangles avec un trou circulaire ou l’on retrouve des LED pour indiquer l’exposition ; un 3e étage où l’on retrouve un papier calque transparent.

L’assemblage de ces étages se fait grâce à des bâtons de 10cm de hauteur et de 0.8cm de diamètres à placer dans les trous fais au préalable grâce à la découpeuse laser.



Étape 4 - Composants électroniques

Pour le fonctionnement technique, le POCL est composé de plusieurs éléments électroniques :

  • un microcontrôleur ESP32, coeur de l'objet, qui contient et exécute le code
  • un cercle de LEDs, branché au microcontrôleur, affichant une couleur unie en fonction des données récupérées des capteurs d'ondes électromagnétiques.
  • deux boutons : un pour changer de capteur (modifiant ainsi les données récupérées et potentiellement la couleur), un autre pour revenir au capteur par défaut (le capteur préféré de l'utilisateur, changeable dans le code).

Les différents composants sont installés sur les étages de notre objet de la façon suivante :

  • le socle contient la carte ESP32. Il a été taillé aux dimensions du microcontrôleur de façon à ce qu'il soit fixe.
  • le premier étage comprend le cercle de 24 LEDs, connecté à l'ESP32
  • le second étage contient le cercle de calque pour uniformer la lumière des LEDs en une couleur unie
  • le dernier étage possède les boutons qui permettent de changer de capteur d'ondes EM.

Pour les branchements entre les composants et la carte :

  • Nous commençons par connecter les boutons poussoirs : chaque bouton dispose d’un câble rouge pour l’entrée et d’un câble noir pour la mise à la terre.
  • Les deux câbles noirs sont reliés à la masse (GND) de la carte ESP32, tandis que les câbles rouges sont connectés respectivement aux broches D4 et D18. Si vous les branchez ailleurs, il faudra faire attention au code et adapter pour que la connexion soit possible
  • Nous installons ensuite un cercle de LED, relié au microcontrôleur via un câble blanc branché sur la broche RX2.
  • Enfin, nous utilisons un câble USB-A à USB-C comme alimentation ; connecteur USB-C étant celui de la carte.


Étape 5 - Programmation

La carte ESP32 a été flashée avec Micropython grâce à cet outil pour ensuite pouvoir programmer en python.

L'ensemble du code est consultable sur ce repo Github et toutes les données des capteurs sont récupérées depuis cette API.

Pour faire fonctionner le POCL, il lui faut un accès à internet. Pour ça, vous devez créer un point d'accès avec les caractéristiques suivantes : "POCO X7 Pro Benjamin" / "benjamin1234".

Cela vous permet de simuler le point d'accès afin qu'il puisse récupérer les données des capteurs. Une autre façon serait d'aller modifier dans le code embarqué les informations de connexion selon votre point d'accès.

Pour ça, la plateforme DBlocaData permet de pouvoir accéder aux fichiers installés sur l'ESP32.

  • Connectez le POCL avec le câble USB sur l'ordinateur
  • Cliquez sur l'icône de connexion en haut à droite pour lier l'ESP32
  • Une fois la carte liée, cliquez sur l'onglet "Fichiers"
  • Sur cette page, cliquez sur le bouton à droite de "Fichiers sur le microcontrôleur" dans la partie gauche de l'écran
  • Vous verrez alors le fichier boot.py, qui est exécuté à chaque démarrage du POCL. Vous pourrez alors modifier le code microPython qui est dessus.
  • Pensez à cliquer sur le bouton "Save" pour enregistrer les changements dans le code et que ce soit appliqué sur le microcontrôleur

 Code source du POCL, disponible sur le Github

import network
import urequests
from machine import Pin
import neopixel
import time
import builtins

len = builtins.len


def connectToWifi():  # Fonction qui permet de connecter l'ESP 32  à un Wifi
    led_demarrage.off()
    try:
        wifiCon = network.WLAN(network.STA_IF)
        wifiCon.active(True)
        wifiCon.scan()
        wifiCon.connect("POCO X7 Pro Benjamin", "benjamin1234")
        led_demarrage.on()
    except OSError as e:
        print("Erreur de connexion")
        for i in range(5):
            led_demarrage.on()
            time.sleep(1)
            led_demarrage.off()
        connectToWifi()


def getDataMesure(datasetId, langue, gid):  # Permet de récupérer la mesure en fonction du dataset et du gid. Retourne aussi en fonction de la langue
    url = "https://datahub.bordeaux-metropole.fr/api/explore/v2.1/catalog/datasets/" + datasetId + "/records?where=gid%3D" + str(gid) + "&offset=0&lang=" + langue + "&timezone=Europe%2FParis&include_links=false&include_app_metas=false"
    try:
        return urequests.get(url).json()["results"][0][
            "mesure"]  # On rcupre la valeur de la cl mesure en fonction de la hirarchie du JSON
    except OSError as e:
        print("Erreur lors de la requte.")
        getDataMesure(datasetId, langue, gid)


def eteindreLEDS():  # Permet d'teindre les LEDs
    for i in range(24):
        n[i] = (0, 0, 0)  # Met toutes les couleurs  noir (0, 0, 0)
        n.write()


def updateLEDS(mesure):  # Fonction qui permet de mettre  jour l'affichage des LEDs en fonction de la mesure
    for i in range(24):
        n[i] = colors[
            int(mesure * 3)]  # Permet de scale la mesure de 0  4 -> 0  12 = donne l'index de la couleur  mettre
        n.write()


def incrHandler(pin):  # Fonction qui trigger quand le bouton d'incrementation est appuye
    global currgid, gidBordeaux, last_incr_time

    current_time = time.ticks_ms()
    if time.ticks_diff(current_time, last_incr_time) < 2000:
        return
    last_incr_time = current_time

    print(f"currgid avant: {currgid}")

    current_idx = gidBordeaux.index(currgid)
    print(f"index trouv: {current_idx}")

    next_idx = (current_idx + 1) % len(gidBordeaux)
    print(f"prochain index: {next_idx}")

    currgid = gidBordeaux[next_idx]
    print(f"nouveau currgid: {currgid}")
    main()


def resetHandler(pin):  # Fonction qui permet de revenir au capteur de dpart
    global currgid, gidBordeaux, last_reset_time

    current_time = time.ticks_ms()
    if time.ticks_diff(current_time, last_reset_time) < 2000:
        return
    last_reset_time = current_time

    currgid = gidBordeaux[0]
    print("reset gid : " + str(currgid))
    main()


def main():
    mesure = getDataMesure("rt_ondeelectro_p", "fr", currgid)
    eteindreLEDS()
    updateLEDS(mesure)
    print(mesure)
    print(int(mesure * 3))
    print(colors[int(mesure * 3)])


# Led de test

led_demarrage = Pin(2, Pin.OUT)
led_demarrage.on()

# Initialisation des boutons incr et reset ainsi que des triggers
boutonIncr = Pin(18, Pin.IN, Pin.PULL_UP)
boutonReset = Pin(4, Pin.IN, Pin.PULL_UP)
boutonIncr.irq(trigger=Pin.IRQ_FALLING, handler=incrHandler)
boutonReset.irq(trigger=Pin.IRQ_FALLING, handler=resetHandler)

# Variables pour enlever le rebond
last_incr_time = 0
last_reset_time = 0

# Tableaux des codes RGB des 12 couleurs
colors = [(0, 255, 0), (42, 255, 12), (85, 255, 35), (128, 255, 98), (170, 255, 140), (255, 255, 225), (255, 204, 174),
          (255, 153, 123), (255, 102, 72), (255, 51, 21), (255, 0, 0)]

# Initialisation du cercle de LEDs
ledcircle = Pin(16, Pin.OUT)
n = neopixel.NeoPixel(ledcircle, 24)

gidBordeaux = [9, 3, 20, 19, 22]  # Diffrents capteurs de Bordeaux (1, 2, 3, 4, 5)
currgid = gidBordeaux[4]  # Capteur par dfaut (Bordeaux 1)

time.sleep(1.5)  # Tempo de dmarrage
connectToWifi()
time.sleep(5)  # Petite tempo entre

while True:
    main()
    time.sleep(900) 


Dernière modification 12/12/2025 par user:BenjaminF.

Commentaires

Draft