La semaine de l'électronique
Les ESP 32
Drivers à installer pour utiliser les esp32 sous windows (seulement)
- Télécharger et dézipper le fichier driver
- Lancer le fichier CP210X......X64.exe qui se trouve dans le répertoire
- Suivre les instructions
- Installer Thonny et les plug-in "ESPTOOL" et "ESP32"
- Redémarrer Thonny
Installations pour la carte esp32 avec Thonny
- Installer les plug-in ESPTOOL et ESP32 dans Thonny puis redémarrer Thonny
- Vérifier que les deux plug-in (ESPTOOL et ESP32) sont bien installés
- Installer l'interpréteur Firmware ESP32-micropython sur la carte esp32 (via Thonny)
- Sélectionner l'interpréteur (executé -> interpréteur) ESP32 ainsi que le port sur lequel est connecté le carte esp32
Premier jour : Code pour contrôler les leds et déjà un peu plus ...
Préparation des fichiers :
- Sauvegarder sur la carte esp32, un fichier nommé
saved_mode.txtqui contenient le caractère0 - Sauvegarder sur la carte esp32, un fichier vide nommé
boot.py - Sauvegarder sur la carte esp32, un fichier nommé
main.pyqui contient le code suivant :
Importation des librairies :
On écrit dans le fichier
main.py :
##############################################################################################################
#
#
#
#
##############################################################################################################
## Importation des librairies ##
##############################################################################################################
#
#
##############################################################################################################
import machine
import neopixel
import _thread
import random
import time
import socket
import select
import gc
Définitions nécéssaires :
On ajoute à la fin du code dans
main.py :
##############################################################################################################
#
#
#
#
##############################################################################################################
## Définitions et initialisations des leds, du bouton et du mode de lumiere souhaite ##
## Pour utiliser ces variables dans une fonction, il faut utiliser la commande 'global NomVariable' ##
## au debut de la fonction ##
##############################################################################################################
#
#
##############################################################################################################
#...On installe le ruban LED sur la pin 5 et on informe qu'il contient 26 leds
nb_leds_ruban = 26
ruban_led = neopixel.NeoPixel(machine.Pin(5), nb_leds_ruban)
#...On installe le bouton sur la pin 19 (et l'autre fil sur le signal 3v3)
# bouton.value() vaut 1 si bouton appuyé, 0 sinon.
bouton= machine.Pin(19, machine.Pin.IN, machine.Pin.PULL_DOWN)
#...On initialise le mode de lumière souhaité en se basant sur ce que qui a été sauvegardé
# dans le fichier saved_mode.txt ou à 0 en cas de problème
selected_mode = 0
with open('saved_mode.txt', 'r') as file:
try:
selected_mode = file.read()
selected_mode = int(selected_mode)
except:
selected_mode = 0
Définition de deux fonctions pour allumer les 3 premières leds en bleu, blanc, rouge et les éteindre
On ajoute à la fin du code dans
main.py :
##############################################################################################################
#
#
#
#
##############################################################################################################
## Définiton des fonctions pour gerer les lumières
##############################################################################################################
#
#
##############################################################################################################
#...Allume les 3 premières leds en bleu, blanc, rouge
def Led_bleue_blanc_rouge():
#...On dit que l'on va utiliser la variable global ruban_led
global ruban_led
#...On définit les leds
# ruban_led est une liste de leds. Le premier élément de la liste ruban_led[0] est la premiére led et ainsi de suite.
ruban_led[0]=(0,0,255) #... première led en bleue
ruban_led[1]=(255,255,255) #... deuxième led en blanc
ruban_led[2]=(255,0,0) #... troisième led en rouge
ruban_led.write() #...On affiche les leds comme on les a définies
return
##############################################################################################################
#...Eteind les 3 premières leds ("allume en noir")
def Clear_leds_123():
global ruban_led
ruban_led[0]=(0,0,0) #... première led eteinte
ruban_led[1]=(0,0,0) #... deuxième led eteinte
ruban_led[2]=(0,0,0) #... troisième led eteinte
ruban_led.write() #...On affiche les leds comme on les a définies
return
Lien vers un site qui vous donnera le code RGB pour les couleurs
Utilisation de ces fonctions dans le thread principal
On veut écrire une suite d'instructions qui va :- Ecrire dans la console "Début du programme"
- Allumer les 3 premières leds en bleu, blanc, rouge pendant 3 secondes
- Eteindre les 3 premières leds
On ajoute à la fin du code dans
main.py :
##############################################################################################################
#
#
#
#
##############################################################################################################
## DEBUT DU PROGRAMME ##
##############################################################################################################
#
#
##############################################################################################################
print('------------------------------------------------------------------------')
print('')
print(' - Début du programme - ')
print('')
print('------------------------------------------------------------------------')
##############################################################################################################
## Thread principal ##
##############################################################################################################
Led_bleue_blanc_rouge()
time.sleep(3)
Clear_leds_123()
Définition d'une fonction qui éteint les TOUTES les leds
#
#
##############################################################################################################
## Définiton des fonctions pour gerer les lumières
##############################################################################################################
#
#
...
##############################################################################################################
def ClearLeds():
global ruban_led
for i in range(ruban_led.__len__()):
ruban_led[i]=(0,0,0)
ruban_led.write()
return
...
Deuxième jour : Fonctions pour faire les différents modes d'allumage et boucle infinie pour gérer le bouton
Fonction pour les différents modes d'allumage des leds
Fonction avec argument pour allumer TOUTES les lumières de la même couleur
On écrit dans le fichier
main.py dans la partie ## Définiton des fonctions pour gerer les lumières :
##############################################################################################################
def TurnOnLeds(couleur):
global ruban_led
global selected_mode
print(f'Start TurnOnLeds with {couleur} ...')
num = selected_mode
for i in range(ruban_led.__len__()):
ruban_led[i]=couleur
ruban_led.write()
while True:
time.sleep(0.05)
if selected_mode != num:
ClearLeds()
print('... end TurnOnLeds')
return
Cette fonction utilise un argument appellé couleur qui permet de choisir la couleur souhaitée lorsque l'on appelle la fonction. Cette fonction utilise une boucle infinie qui ne fait rien qu'attendre que la variable
selected_mode change de valeur (avec le bouton voir plus tard). Lorsque la variable
selected_mode change, la fonction éteint toutes les leds en appellant la fonction ClearsLeds() puis s'arrête avec la commande return IMPORTANT : Cette structure devra être utilisée pour toutes les fonctions qui définissent des modes lumineux.
Utilisation de cette fonction pour allumer toutes les leds en rose
On écrit dans le fichier
main.py dans la partie ## Thread principal :
##############################################################################################################
TurnOnLeds((191, 0, 255))
Attention : les doubles parenthèses dans TurnOnLeds((191, 0, 255)) sont importantes car la couleur est définie avec les parenthèses (191, 0, 255) . On peut également utiliser :
##############################################################################################################
rose = (191, 0, 255)
TurnOnLeds(rose)
Attention : Cette fonction ne s'arrète jamais car la variable selected_mode ne change jamais pour l'instant.
A vous de créer les fonctions qui allument les leds comme vous le souhaitez ...
En se basant sur le modèle de la fonction
TurnOnLeds(couleur) . Vous écrivez ces fonctions dans le fichier
main.py dans la partie ## Définiton des fonctions pour gerer les lumières . Vous pouvez imaginer le mode que vous voulez, voici quelques idées pour vous inspirer :
- Des leds qui s'allument 10 min
- Des leds qui s'allument 10 min avec une intensité de lumière décroissante
- Des leds qui clignotes
- Des leds qui changent de couleur
- Un point de lumière qui se promène avec les autres lumières éteintes ou d'une autre couleur
- ...
## Thread principal (tu ne pourras tester qu'un mode à la fois).
Utilisation de Thread séparés pour allumer les leds
Définition d'une fonction qui lance un mode lumineux dans un Thread séparé en fonction d'un nombre
On écrit dans le fichier
main.py à la fin de la partie ## Définiton des fonctions pour gerer les lumières :
##############################################################################################################
def StartMode(mode):
global selected_mode
selected_mode = mode
with open('saved_mode.txt', 'w') as file:
file.write(f'{selected_mode}')
print(' ------> selected_mode =', selected_mode)
time.sleep(0.5)
if selected_mode == 1: _thread.start_new_thread( TurnOnLeds, ((25,25,25),)) #...Allume en blanc
elif selected_mode == 2: _thread.start_new_thread( TurnOnLeds, ((255,255,255),)) #...Allume en blanc
elif selected_mode == 3: _thread.start_new_thread( TurnOnLeds, ((255,0,0),)) #...Allume en rouge
elif selected_mode == 4: _thread.start_new_thread( TurnOnLeds, ((0,255,0),)) #...Allume en vert
elif selected_mode == 5: _thread.start_new_thread( TurnOnLeds, ((0,0,255),)) #...Allume en bleu
elif selected_mode == 6: _thread.start_new_thread( TurnOnLeds, ((0,0,25),)) #...Allume en bleu faible
Attention : Il est important de respecter les (( ),)) dans la fonction start_new_thread() . Cette fonction lance, dans un Thread séparé, la fonction
TurnOnLeds(couleur) qui allume les leds de couleurs différentes en fonction du numéro de mode
(variable selected_mode ).
Enchainement de deux modes différents
On écrit dans le fichier
main.py à la fin de la partie ## Thread principal .
##############################################################################################################
StartMode(1)
time.sleep(4)
StartMode(3)
Boucle infinie qui gère le bouton
On écrit dans le fichier
main.py à la fin de la partie ## Thread principal .
##############################################################################################################
## Boucle principale qui écoute le bouton ##
##############################################################################################################
StartMode(selected_mode)
while True:
time.sleep(0.1)
#...Button
if bouton.value() == 1:
mode = (selected_mode+1)%13
StartMode(mode)
Troisième jour : Quelques fonctions pour faire des modes
Voici quelques exemples de fonction qui permettent de faire des modes pour votre lampe
Vous pouvez les utiliser avec ou sans modifications mais dans tous les cas vous devez ajouter un mode dans la fonction StartMode(selected_mode) .
##############################################################################################################
#...Mode qui allume des leds avec des couleurs aléatoires
def DimRand(max = 20):
global ruban_led
global selected_mode
print('Start DimRand ...')
n = ruban_led.__len__()
num = selected_mode
while True:
for j in range(max):
if selected_mode != num:
ClearLeds()
print('... end DimRand')
return
for i in range(n):
couleur = [0,0,0]
couleur[random.randint(0,2)] = j+1
ruban_led[i]=couleur
time.sleep(0.05)
ruban_led.write()
for j in range(max):
if selected_mode != num:
ClearLeds()
print('... end DimRand')
return
for i in range(n):
couleur = [0,0,0]
couleur[random.randint(0,2)] = max-j+1
ruban_led[n-i-1]=couleur
time.sleep(0.05)
ruban_led.write()
##############################################################################################################
#...Mode qui fait clignoter les leds d'une couleur donnée
def Clignote(couleur=(50,50,50)):
global ruban_led
global selected_mode
print(f'Start Clignote with {couleur} ...')
num = selected_mode
while True:
for i in range(ruban_led.__len__()):
if selected_mode != num:
ClearLeds()
print('... end Clignote')
return
ruban_led[i]=couleur
ruban_led.write()
time.sleep(0.02)
for j in range(ruban_led.__len__()):
if selected_mode != num:
ClearLeds()
print('... end Clignote')
return
ruban_led[j]=(0,0,0)
ruban_led.write()
time.sleep(0.02)
##############################################################################################################
#...Mode qui augmente puis diminue l'intensité des leds en boucle
def Fade_in_out():
global ruban_led
global selected_mode
print('Start Fade_in_out ...')
num = selected_mode
while True:
for i in range(0, 4 * 256, 8):
if selected_mode != num:
ClearLeds()
print('... end Fade_in_out')
return
for j in range(ruban_led.__len__()):
if (i // 256) % 2 == 0:
val = i & 0xff
else:
val = 255 - (i & 0xff)
ruban_led[j] = (val, val//2, 0)
time.sleep(0.01)
ruban_led.write()
##############################################################################################################
#...Mode qui allume toutes les leds et qui fait circuler une led éteinte en boucle
def Cycle():
global ruban_led
global selected_mode
print('Start Cycle ...')
n = ruban_led.__len__()
num = selected_mode
while True:
for i in range(4 * n):
if selected_mode != num:
ClearLeds()
print('... end Cycle')
return
for j in range(n):
ruban_led[j] = (0, 0, 0)
ruban_led[i % n] = (255, 255, 255)
ruban_led.write()
time.sleep_ms(20)
##############################################################################################################
#...Mode qui avancer et rebondir une seule led
def Bounce():
global ruban_led
global selected_mode
print('Start Bounce ...')
n = ruban_led.__len__()
num = selected_mode
while True:
for i in range(4 * n):
if selected_mode != num:
ClearLeds()
print('... end Bounce')
return
for j in range(n):
ruban_led[j] = (0, 128, 128)
if (i // n) % 2 == 0:
ruban_led[i % n] = (0, 0, 0)
else:
ruban_led[n - 1 - (i % n)] = (0, 0, 0)
ruban_led.write()
time.sleep_ms(20)
##############################################################################################################
#...Mode qui allume les leds en dégradé de couleur
import math
def arc_en_ciel():
# Pour utiliser cette fonction il faut ajouter "import math" au début du code
global ruban_led
global selected_mode
num = selected_mode
print('Start arc_en_ciel ...')
for i in range(ruban_led.__len__()):
r = int((1 + math.sin(i / 5)) * 127)
g = int((1 + math.sin(i / 3)) * 127)
b = int((1 + math.sin(i / 7)) * 127)
ruban_led[i] = (r, g, b)
ruban_led.write()
while True:
time.sleep(0.05)
if selected_mode != num:
ClearLeds()
print('... end TurnOnLeds')
return
##############################################################################################################
#...Mode qui fait clignoter les leds en mode disco
def disco_light():
global ruban_led
global selected_mode
num = selected_mode
print('Start disco_light ...')
while True:
for i in range(ruban_led.__len__()):
ruban_led[i] = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
ruban_led.write()
time.sleep_ms(100)
for i in range(ruban_led.__len__()):
ruban_led[i] = (0, 0, 0)
ruban_led.write()
time.sleep_ms(100)
if selected_mode != num:
ClearLeds()
print('... end TurnOnLeds')
return
##############################################################################################################
#...Mode qui fait des jeux de lumière avec des motifs aléatoires
def light_show():
global ruban_led
global selected_mode
num = selected_mode
print('Start light_show ...')
while True:
ruban_led.fill((random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))
ruban_led.write()
time.sleep_ms(random.randint(100, 500))
ruban_led.fill((random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))
ruban_led.write()
time.sleep_ms(random.randint(100, 500))
ruban_led.fill((random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))
ruban_led.write()
time.sleep_ms(random.randint(100, 500))
ruban_led.fill((random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))
ruban_led.write()
time.sleep_ms(random.randint(100, 500))
ruban_led.fill((random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))
ruban_led.write()
time.sleep_ms(random.randint(100, 500))
if selected_mode != num:
ClearLeds()
print('... end TurnOnLeds')
return
##############################################################################################################
#...Mode qui affiche un minuteur en minute avec des leds bleues
def show_timer(mytimer = 600):
global ruban_led
global selected_mode
num = selected_mode
print('Start show_timer ...')
num = selected_mode
#############################################
# définit la couleur des LEDs
def set_color(color):
global ruban_led
for i in range(ruban_led.__len__()):
ruban_led[i] = color
ruban_led.write()
#############################################
# convertit le temps en minutes et secondes
def get_time(mytimer):
minutes = mytimer // 60
seconds = mytimer % 60
return minutes, seconds
#############################################
while mytimer > 0:
minutes, seconds = get_time(mytimer)
# allume les LEDs de minute
set_color((0, 0, 255))
for i in range(minutes):
ruban_led[i] = (255, 255, 255)
ruban_led.write()
time.sleep(0.5)
# éteint les LEDs de minute et allume la LED de seconde
set_color((0, 0, 0))
ruban_led[ruban_led.__len__() - 1] = (255, 0, 0)
ruban_led.write()
time.sleep(0.5)
mytimer -= 1
if selected_mode != num:
ClearLeds()
print('... end TurnOnLeds')
return
##############################################################################################################
#...Mode qui fait se poursuivre ou se croiser deux leds vertes qui deviennent rouge lorsqu'elles se croisent
def poursuite():
global ruban_led
global selected_mode
num = selected_mode
print('Start poursuite ...')
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
OFF = (0, 0, 0)
# initialise les positions et les vitesses des particules
pos1 = random.randint(0, ruban_led.__len__()-1)
pos2 = random.randint(0, ruban_led.__len__()-1)
while pos1 == pos2:
pos2 = random.randint(0, ruban_led.__len__()-1)
dir1 = random.choice([-1, 1])
dir2 = random.choice([-1, 1])
speed1 = random.randint(1, 3)
speed2 = random.randint(1, 3)
last_collision = time.time()
# boucle principale du simulateur
while True:
# allume les LEDs des particules
for i in range(ruban_led.__len__()):
if i == pos1 or i == pos2:
ruban_led[i] = GREEN
else:
ruban_led[i] = OFF
ruban_led.write()
# vérifie si les particules sont entrées en collision
if pos1 == pos2:
last_collision = time.time()
ruban_led[pos1] = RED
ruban_led[pos2] = RED
ruban_led.write()
time.sleep(1)
# redémarre le simulateur après l'accident
pos1 = random.randint(0, ruban_led.__len__()-1)
pos2 = random.randint(0, ruban_led.__len__()-1)
while pos1 == pos2:
pos2 = random.randint(0, ruban_led.__len__()-1)
dir1 = random.choice([-1, 1])
dir2 = random.choice([-1, 1])
speed1 = random.randint(1, 3)
speed2 = random.randint(1, 3)
else:
# déplace les particules dans leur direction respective
pos1 += dir1*speed1
pos2 += dir2*speed2
# inverse la direction des particules lorsqu'elles atteignent les extrémités du ruban
if pos1 >= ruban_led.__len__():
pos1 = 0
elif pos1 < 0:
pos1 = ruban_led.__len__() - 1
if pos2 >= ruban_led.__len__():
pos2 = 0
elif pos2 < 0:
pos2 = ruban_led.__len__() - 1
time.sleep(0.05) # ajoute une petite pause pour ralentir le mouvement des particules et éviter les collisions manquées
if time.time() - last_collision > 10 :
for i in range(ruban_led.__len__()) :
ruban_led[i] = GREEN
time.sleep(0.08)
ruban_led.write()
pos1 = random.randint(0, ruban_led.__len__()-1)
pos2 = random.randint(0, ruban_led.__len__()-1)
while pos1 == pos2:
pos2 = random.randint(0, ruban_led.__len__()-1)
dir1 = random.choice([-1, 1])
dir2 = random.choice([-1, 1])
speed1 = random.randint(1, 3)
speed2 = random.randint(1, 3)
last_collision = time.time()
if selected_mode != num:
ClearLeds()
print('... end TurnOnLeds')
return
##############################################################################################################
#...Mode Arc en ciel de Dila (chatGPT)
##############################################################################################################
# Function to convert HSV to RGB
def hsv_to_rgb(h, s, v):
if s == 0.0:
return (v, v, v)
i = int(h * 6.0)
f = (h * 6.0) - i
p = v * (1.0 - s)
q = v * (1.0 - f * s)
t = v * (1.0 - (1.0 - f) * s)
i = i % 6
if i == 0:
return (v, t, p)
if i == 1:
return (q, v, p)
if i == 2:
return (p, v, t)
if i == 3:
return (p, q, v)
if i == 4:
return (t, p, v)
if i == 5:
return (v, p, q)
##############################################################################################################
def rainbow_cycle():
global ruban_led
global selected_mode
num = selected_mode
while selected_mode == num:
for i in range(nb_leds_ruban):
# Calculate the hue based on LED index and time
hue = (i / nb_leds_ruban) + (time.ticks_ms() / 1000.0) * 0.1
rgb = hsv_to_rgb(hue % 1.0, 1.0, 1.0) # Saturation = 1, Value = 1 (full brightness)
ruban_led[i] = (int(rgb[0] * 255), int(rgb[1] * 255), int(rgb[2] * 255))
ruban_led.write()
time.sleep(0.01)
ClearLeds()
print('... end rainbow_cycle')
return
La fonction StartMode(mode) qui permet d'utiliser tous ces modes :
###########################################################################################
def StartMode(mode):
global selected_mode
selected_mode = mode
with open('saved_mode.txt', 'w') as file:
file.write(f'{selected_mode}')
print(' ------> selected_mode =', selected_mode)
time.sleep(0.5)
if selected_mode == 1: _thread.start_new_thread( DimRand, ())
elif selected_mode == 2: _thread.start_new_thread( Clignote, ((20,20,0),))
elif selected_mode == 3: _thread.start_new_thread( Clignote, ((0,0,20),))
elif selected_mode == 4: _thread.start_new_thread( Fade_in_out, ())
elif selected_mode == 5: _thread.start_new_thread( Cycle, ())
elif selected_mode == 6: _thread.start_new_thread( Bounce, ())
elif selected_mode == 7: _thread.start_new_thread( arc_en_ciel, ())
elif selected_mode == 8: _thread.start_new_thread( disco_light, ())
elif selected_mode == 9: _thread.start_new_thread( light_show, ())
elif selected_mode == 10: _thread.start_new_thread( show_timer, ())
elif selected_mode == 11: _thread.start_new_thread( poursuite, ())
Troisième jour : Ajout d'un serveur WEB pour controler la lampe à distance
Généralité
Dans cette section nous n'allons pas vous expliquer comment on programme un serveur WEB sur un EPS32 avec micropython, l'idèe est de vous donner les étapes et les fonctions qui vous permettrons d'ajouter un serveur WEB pour controler votre lampe à distance.
Comment cela va fonctionner en pratique :
- Votre EPS32 va créer un reseau WIFI sur lequel vous pourrez vous connecter.
- Vous pourrez acceder au serveur WEB du ESP32 en allant sur l'adresse http://192.168.4.1/
- A cette adresse une page WEB vous permettra de changer de mode de la lampe.
Marche à suivre pour l'installation
Préparation du EPS32 pour qu'il gère le serveur WEB
- Installer le fichier boot.py sur le ESP32
- Modifier le nom du reseau WIFI
ssid = 'NomReseau'pour qu'il soit personnalisé avec votre prénom (ne pas utilise d'accents) - Utiliser par exemple
ssid = 'Lampe_julien' - Vous pouvez également modifier le mot de passe WIFI
password = 'lampeled'mais ce n'est pas obligatoire - Installer le fichier web_server.py sur le ESP32
Modification du ficher main.py pour utiliser le serveur WEB
Dans la partie
## Importation des librairies Ajouter la ligne :
##############################################################################################################
#
#
#
#
##############################################################################################################
## Importation des librairies ##
##############################################################################################################
#
#
##############################################################################################################
...
...
import web_server
Dans la partie
## DEBUT DU PROGRAMME Définir une liste qui contient les noms des différents modes puis définir et démarrer le serveur WEB :
##############################################################################################################
## DEBUT DU PROGRAMME ##
##############################################################################################################
#
#
##############################################################################################################
...
...
liste_noms_modes = ['Clignote bleu',
'Flash blanc',
'Arc en ciel',
'mode4',
'mode5',
'mode6',
'mode7',
'mode8',
'mode9',
'mode0',
...
...
...]
serveur = web_server.serveur_web(StartMode,liste_noms_modes)
serveur.start()
Attention : Il faut avoir le même nombre de noms que de modes
Utilisation du serveur web
Pour acceder au serveur WEB :
- Connecter votre téléphone ou un ordinateur au réseau WIFI du ESP32 en utilisant le nom et le mot de passe que vous avez défini
- Accéder à la page WEB :
http://192.168.4.1/avec un navigateur internet - Cliquer sur les modes qui vous interessent