Illustre les modules 0 à 2 (9 figures)

Bibliothèque commune schemas/outils.py (boîtes, flèches, chronogrammes, séquences). M0 : chaîne de développement, séquence BOOT/RESET. M1 : architecture, comparatif Uno/ESP32-S3, diviseur de tension. M2 : pull-up, rebonds, chenillard, protocole WS2812.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Artemia
2026-10-18 15:11:18 +02:00
co-authored by Claude Opus 5.5
parent d933e348c0
commit 30d0e356a6
25 changed files with 16693 additions and 0 deletions
+4
View File
@@ -68,10 +68,14 @@ Une fois le paquet installé :
Si l'upload échoue avec un message « Failed to connect », maintenez le bouton BOOT appuyé, appuyez brièvement sur RESET, relâchez BOOT, puis relancez le téléversement. Ce geste force la carte en mode bootloader.
:::
![Forcer le mode téléchargement : séquence des boutons BOOT et RESET](../schemas/svg/m00-boot-reset.svg){#fig-m00-boot-reset width=90%}
## 5. Premier programme : Blink
Nous allons vérifier que toute la chaîne (code → compilation → upload → exécution) fonctionne, en faisant clignoter la LED intégrée.
![La chaîne de développement : du croquis à l'exécution sur la carte, puis retour par le moniteur série](../schemas/svg/m00-chaine-developpement.svg){#fig-m00-chaine-developpement}
```cpp
// Sur la plupart des DevKitC ESP32-S3, la LED simple (non RGB) est sur la broche 2.
// Vérifiez la sérigraphie de votre carte : elle peut varier.
+6
View File
@@ -17,6 +17,8 @@ L'ESP32-S3 va plus loin qu'un microcontrôleur classique (type ATmega328 de l'Ar
## 2. Architecture interne de l'ESP32-S3
![Architecture simplifiée de l'ESP32-S3 et de son module](../schemas/svg/m01-architecture.svg){#fig-m01-architecture}
### 2.1 Cœurs de calcul
- Double cœur Xtensa LX7 cadencé jusqu'à 240 MHz.
@@ -49,10 +51,14 @@ L'ESP32-S3 dispose d'un contrôleur USB OTG natif, permettant la programmation e
| Broches ADC | 10 bits, 5 entrées | 12 bits, jusqu'à 20 entrées |
| PWM | Limité (Timer matériel) | LEDC — jusqu'à 8 canaux configurables |
![Arduino Uno et ESP32-S3 : ordres de grandeur (échelle logarithmique)](../schemas/svg/m01-uno-vs-s3.svg){#fig-m01-uno-vs-s3}
::: {.callout-warning title="Point de vigilance : tension 3,3 V"}
Toutes les broches GPIO de l'ESP32-S3 fonctionnent en logique 3,3 V et ne tolèrent pas 5 V en entrée. Un signal 5 V (capteur, module tiers) doit être abaissé via un diviseur de tension ou un convertisseur de niveau logique avant d'être connecté à une broche.
:::
![Abaisser un signal 5 V à 3,3 V avec un diviseur de tension](../schemas/svg/m01-diviseur-tension.svg){#fig-m01-diviseur-tension width=65%}
## 4. Lire le brochage (pinout) de la carte
Avant de câbler quoi que ce soit, il est indispensable de repérer sur votre carte :
+8
View File
@@ -35,6 +35,8 @@ Une entrée numérique non connectée (« flottante ») peut lire un état aléa
- `INPUT_PULLUP` : la broche est tirée à 3,3 V par défaut (état HIGH) ; le bouton doit relier la broche à GND pour donner un état LOW à l'appui.
- `INPUT_PULLDOWN` : disponible sur l'ESP32-S3 (contrairement à l'AVR classique) — la broche est tirée à 0 V par défaut.
![Bouton sur une entrée en `INPUT_PULLUP` : la résistance de tirage interne fixe l'état au repos](../schemas/svg/m02-pull-up.svg){#fig-m02-pull-up width=70%}
```cpp
#define BUTTON_PIN 5
@@ -56,10 +58,14 @@ void loop() {
Un bouton mécanique génère plusieurs transitions HIGH/LOW parasites en quelques millisecondes lors de l'appui. Un simple `delay(50)` après lecture suffit pour un usage pédagogique ; pour un projet robuste, on mesure le temps écoulé avec `millis()` plutôt que d'utiliser `delay()` (voir Module 6 sur les interruptions et timers).
:::
![Rebonds d'un bouton mécanique : l'anti-rebond ne retient qu'un seul appui](../schemas/svg/m02-rebonds.svg){#fig-m02-rebonds}
## 3. Exercice guidé : chenillard de LED
Câblez 4 LED (avec résistances de 220 Ω) sur 4 GPIO libres, puis reproduisez un effet de chenillard :
![Câblage du chenillard : une résistance de 220 Ω par LED, masse commune](../schemas/svg/m02-chenillard.svg){#fig-m02-chenillard width=75%}
```cpp
const int leds[] = {4, 5, 6, 7};
const int nbLeds = 4;
@@ -87,6 +93,8 @@ Contrairement à une LED classique qui ne prend que deux états (allumé/éteint
Le protocole WS2812 impose un timing très précis (de l'ordre de la centaine de nanosecondes) pour distinguer un bit 0 d'un bit 1. Le générer « à la main » avec digitalWrite serait peu fiable ; on utilise donc une bibliothèque dédiée qui exploite les ressources matérielles du microcontrôleur pour respecter ce timing.
![Protocole WS2812 : trame de 24 bits et codage temporel de chaque bit](../schemas/svg/m02-ws2812.svg){#fig-m02-ws2812}
### 4.2 Installation de la bibliothèque
- Dans l'IDE : Croquis \> Inclure une bibliothèque \> Gérer les bibliothèques.
+53
View File
@@ -0,0 +1,53 @@
"""Module 0 — Prérequis & installation."""
from outils import boite, chronogramme, fleche, toile
from style import BLEU, ENCRE, GRIS, ORANGE, VERT, Figure
def chaine_developpement():
fig, ax = toile(16, 5.6)
# Zones ordinateur / carte
boite(ax, 5.0, 3.0, 9.4, 4.6, couleur=GRIS, fond="#f9fafb")
boite(ax, 13.2, 3.0, 4.6, 4.6, couleur=BLEU, fond="#f5f8fe")
ax.text(0.6, 4.8, "Ordinateur — Arduino IDE", fontsize=9, color=GRIS, fontweight="bold")
ax.text(11.2, 4.8, "Carte ESP32-S3", fontsize=9, color=BLEU, fontweight="bold")
code = boite(ax, 2.0, 3.3, 2.6, 1.4, "Croquis\n(.ino)", couleur=BLEU)
comp = boite(ax, 5.6, 3.3, 2.6, 1.4, "Compilation\n✓ Vérifier", couleur=BLEU)
moni = boite(ax, 4.2, 1.4, 5.4, 0.9, "Moniteur série — 115200 bauds", couleur=VERT, taille=8.5)
flash = boite(ax, 13.2, 3.3, 3.2, 1.4, "Mémoire Flash\n(programme)", couleur=ORANGE)
cpu = boite(ax, 13.2, 1.4, 3.2, 0.9, "Exécution", couleur=ORANGE)
fleche(ax, code["d"], comp["g"])
fleche(ax, comp["d"], flash["g"], "Téléverser →\n(câble USB)", taille=8)
fleche(ax, flash["b"], cpu["h"])
fleche(ax, cpu["g"], moni["d"], "Serial.println()", couleur=VERT, taille=8)
ax.text(8.0, 0.1, "Le même câble USB sert au téléversement et au moniteur série (USB CDC).",
ha="center", fontsize=7.5, color=GRIS, style="italic")
return fig
def boot_reset():
voies = [
("BOOT", [(0, 1), (1, 0), (4, 1)]),
("RESET", [(0, 1), (2, 0), (2.6, 1)]),
]
fig, ax, y = chronogramme(voies, 6, largeur_cm=15, hauteur_voie_cm=1.6,
couleurs={"RESET": ORANGE})
ax.set_xticks([])
ax.spines["bottom"].set_visible(False)
for i in range(2):
ax.text(6.05, y(i) + 1, "relâché", fontsize=7, color=GRIS, va="center")
ax.text(6.05, y(i), "appuyé", fontsize=7, color=GRIS, va="center")
etapes = [(1, "① maintenir BOOT"), (2.3, "② appui bref\nsur RESET"), (4, "③ relâcher BOOT")]
for t, txt in etapes:
ax.axvline(t, color=GRIS, lw=0.8, ls=":")
ax.text(t, 3.05, txt, ha="center", va="bottom", fontsize=8, color=ENCRE)
ax.text(5.0, -0.75, "→ la carte démarre en mode téléchargement", ha="center", fontsize=8.5,
color=VERT, fontweight="bold")
ax.set_ylim(-1.1, 4.1)
fig.tight_layout()
return fig
FIGURES = [
Figure("m00-chaine-developpement", chaine_developpement),
Figure("m00-boot-reset", boot_reset),
]
+85
View File
@@ -0,0 +1,85 @@
"""Module 1 — Découverte du microcontrôleur ESP32-S3."""
import matplotlib.pyplot as plt
import schemdraw
import schemdraw.elements as elm
from outils import boite, fleche, toile
from style import BLEU, CM, ENCRE, GRIS, ORANGE, VERT, Figure
schemdraw.use("matplotlib")
def architecture():
fig, ax = toile(16, 8.2)
boite(ax, 6.6, 4.2, 12.6, 7.6, couleur=BLEU, fond="#f5f8fe")
ax.text(0.6, 7.6, "ESP32-S3 (puce)", fontsize=10, color=BLEU, fontweight="bold")
# Cœurs et mémoire
boite(ax, 2.6, 6.2, 3.8, 1.0, "Cœur 0\nXtensa LX7", couleur=BLEU, taille=8.5)
boite(ax, 2.6, 5.0, 3.8, 1.0, "Cœur 1\nXtensa LX7", couleur=BLEU, taille=8.5)
ax.text(2.6, 4.2, "240 MHz max · FreeRTOS", ha="center", fontsize=7.5, color=GRIS)
sram = boite(ax, 6.6, 5.6, 3.0, 2.2, "SRAM interne\n≈ 512 Ko\n(données +\ninstructions)", couleur=VERT, taille=8.5)
# Radio
boite(ax, 10.6, 6.2, 3.6, 1.0, "Wi-Fi 802.11 b/g/n\n2,4 GHz", couleur=ORANGE, taille=8)
boite(ax, 10.6, 5.0, 3.6, 1.0, "Bluetooth 5 LE\n(pas de Classic)", couleur=ORANGE, taille=8)
# Périphériques
periph = ["GPIO", "ADC 12 bits", "LEDC (PWM)", "UART", "I2C", "SPI", "Timers", "USB OTG"]
for i, p in enumerate(periph):
x = 1.35 + (i % 4) * 2.85
yy = 2.55 if i < 4 else 1.35
boite(ax, x, yy, 2.55, 0.9, p, couleur=GRIS, taille=8.5)
ax.text(0.6, 3.25, "Périphériques intégrés", fontsize=8, color=GRIS, fontweight="bold")
# Bus interne
ax.plot([0.7, 12.5], [3.8, 3.8], color=BLEU, lw=2.2, alpha=0.5)
# Externe
flash = boite(ax, 14.75, 5.6, 2.45, 2.2, "Flash\nexterne\n8–16 Mo\n(programme,\nfichiers)", couleur=VERT, taille=7.5)
psram = boite(ax, 14.7, 2.9, 2.3, 1.2, "PSRAM\n(option)", couleur=VERT, taille=8, alpha=0.8)
ax.text(14.7, 7.15, "sur le module", ha="center", fontsize=7.5, color=GRIS, style="italic")
fleche(ax, (12.9, 5.6), flash["g"], double=True)
fleche(ax, (12.9, 2.9), psram["g"], double=True)
return fig
def uno_vs_s3():
fig, ax = plt.subplots(figsize=(16 * CM, 6.2 * CM))
criteres = ["Fréquence (MHz)", "RAM (Ko)", "Flash (Ko)"]
uno = [16, 2, 32]
s3 = [240, 512, 8192]
y = range(len(criteres))
ax.barh([i + 0.2 for i in y], uno, height=0.38, color=GRIS, label="Arduino Uno (ATmega328)")
ax.barh([i - 0.2 for i in y], s3, height=0.38, color=BLEU, label="ESP32-S3")
ax.set_xscale("log")
ax.set_xlim(1, 300000)
ax.set_yticks(list(y), criteres)
ax.invert_yaxis()
for i, (u, s) in enumerate(zip(uno, s3)):
ax.text(u * 1.15, i + 0.2, f"{u:g}", va="center", fontsize=8, color=ENCRE)
lib = f"{s:g}" if s < 8000 else "8192 (8 Mo)"
ax.text(s * 1.15, i - 0.2, f"{lib} × {s // u}", va="center", fontsize=8, color=BLEU,
fontweight="bold")
ax.set_xlabel("échelle logarithmique : chaque graduation = × 10")
ax.grid(axis="y", visible=False)
ax.legend(loc="lower center", bbox_to_anchor=(0.5, 1.0), ncol=2, fontsize=8, frameon=False)
fig.tight_layout()
return fig
def diviseur_tension():
d = schemdraw.Drawing(show=False)
d.config(fontsize=11, unit=2.6, color=ENCRE)
d += elm.Dot(open=True).label("Signal 5 V\n(module tiers)", loc="left")
d += elm.Resistor().right().label("R1 = 10 kΩ").color(ORANGE)
d += (noeud := elm.Dot())
d += elm.Line().right().length(2.2)
d += elm.Dot(open=True).label("GPIO\n(3,3 V max)", loc="right").color(BLEU)
d += elm.Resistor().down().at(noeud.center).label("R2 = 20 kΩ", loc="bottom").color(ORANGE)
d += elm.Ground()
d += elm.Label().at((noeud.center[0] + 1.2, noeud.center[1] - 2.2)).label(
r"$V_{GPIO} = 5\,V \times \frac{R2}{R1 + R2} \approx 3{,}3\,V$", fontsize=11, color=VERT)
return d.draw(show=False)
FIGURES = [
Figure("m01-architecture", architecture),
Figure("m01-uno-vs-s3", uno_vs_s3),
Figure("m01-diviseur-tension", diviseur_tension),
]
+121
View File
@@ -0,0 +1,121 @@
"""Module 2 — Entrées/sorties numériques & LED RGB NeoPixel."""
import matplotlib.pyplot as plt
import numpy as np
import schemdraw
import schemdraw.elements as elm
from outils import chronogramme
from style import BLEU, CM, ENCRE, GRIS, ORANGE, ROUGE, VERT, Figure
schemdraw.use("matplotlib")
def pull_up():
d = schemdraw.Drawing(show=False)
d.config(fontsize=10.5, unit=2.4, color=ENCRE)
d += (vdd := elm.Vdd().label("3V3"))
d += (r := elm.Resistor().down().label("pull-up interne\n≈ 45 kΩ", loc="bottom").color(BLEU))
d += (n := elm.Dot())
d += (lecture := elm.Line().left().length(2.6).label("vers digitalRead()", loc="top", fontsize=9).color(BLEU))
d += elm.Line().right().at(n.center).length(2.8)
d += (gpio := elm.Dot(open=True).label("GPIO5", loc="top"))
d += elm.Line().right().length(1.2)
d += elm.Button().down().label("bouton", loc="bottom").color(ORANGE)
d += elm.Ground()
d += elm.EncircleBox([vdd, r, n, lecture, gpio], padx=0.3, pady=0.5).linestyle("--").color(GRIS)
d += elm.Label().at((n.center[0] + 1.6, vdd.end[1] + 0.2)).label("à l'intérieur\nde l'ESP32-S3", color=GRIS, fontsize=9)
d += elm.Label().at((gpio.center[0] + 3.6, n.center[1] - 2.0)).label(
"relâché → HIGH (3,3 V)\nappuyé → LOW (0 V)", fontsize=10, color=VERT)
return d.draw(show=False)
def rebonds():
t = [0]
niv = [1]
# Appui avec rebonds autour de 40 ms, relâchement avec rebonds autour de 140 ms
for a, b in ((40, 0), (41.2, 1), (42, 0), (43.5, 1), (44.1, 0), (140, 1), (140.8, 0), (141.9, 1), (142.5, 0), (143.2, 1)):
t.append(a)
niv.append(b)
voies = [("broche (brut)", list(zip(t, niv))),
("état retenu", [(0, 1), (54, 0), (153, 1)])]
fig, ax, y = chronogramme(voies, 200, largeur_cm=16, hauteur_voie_cm=1.7,
graduations=range(0, 201, 25), unite="temps (ms)",
couleurs={"état retenu": VERT})
for x0, x1, txt in ((40, 44.1, "rebonds\n(quelques ms)"), (140, 143.2, "rebonds")):
ax.axvspan(x0 - 1, x1 + 1, color=ORANGE, alpha=0.18)
ax.text((x0 + x1) / 2, y(0) + 1.25, txt, ha="center", fontsize=7.5, color=ORANGE)
ax.annotate("", xy=(54, y(1) + 0.5), xytext=(44.1, y(1) + 0.5),
arrowprops=dict(arrowstyle="<->", color=ENCRE, lw=0.9))
ax.text(49, y(1) + 0.62, "attente", ha="center", fontsize=7, color=ENCRE)
ax.text(97, y(1) + 0.3, "un seul appui détecté", ha="center", fontsize=8, color=VERT, fontweight="bold")
ax.set_ylim(-0.5, 3.9)
fig.tight_layout()
return fig
def chenillard():
d = schemdraw.Drawing(show=False)
d.config(fontsize=10.5, unit=2.2, color=ENCRE)
pins = [elm.IcPin(name=f"GPIO{g}", side="right", anchorname=f"P{g}") for g in (7, 6, 5, 4)]
ic = elm.Ic(pins=pins, size=(3.2, 5.4), pinfontsize=10).label("ESP32-S3", loc="center", fontsize=12).color(BLEU)
d += ic
couleurs = {4: ROUGE, 5: VERT, 6: BLEU, 7: ORANGE}
fins = []
for g in (4, 5, 6, 7):
d += elm.Line().right().at(getattr(ic, f"P{g}")).length(0.6)
d += elm.Resistor().right().label("220 Ω", fontsize=9)
d += elm.LED().right().color(couleurs[g])
d += elm.Line().right().length(0.6)
fins.append(d.here)
d += elm.Line().at(fins[0]).to(fins[-1])
d += elm.Line().down().at(fins[-1]).length(0.6)
d += elm.Ground()
d += elm.Label().at((fins[0][0] + 0.4, (fins[0][1] + fins[-1][1]) / 2)).label("GND\ncommun", loc="right", fontsize=9, color=GRIS)
return d.draw(show=False)
def ws2812():
fig = plt.figure(figsize=(16 * CM, 8.6 * CM))
# (a) trame 24 bits
ax1 = fig.add_axes([0.04, 0.62, 0.92, 0.3])
ax1.axis("off")
ax1.set_xlim(0, 24)
ax1.set_ylim(0, 1.6)
for k, (nom, c) in enumerate((("G", VERT), ("R", ROUGE), ("B", BLEU))):
for b in range(8):
x = k * 8 + b
ax1.add_patch(plt.Rectangle((x, 0.3), 1, 0.8, facecolor=c, alpha=0.18 + 0.06 * (7 - b) / 7,
edgecolor=c, lw=1))
ax1.text(x + 0.5, 0.7, f"{nom}{7 - b}", ha="center", va="center", fontsize=6.5, color=ENCRE)
ax1.text(k * 8 + 4, 1.25, {"G": "Vert (8 bits)", "R": "Rouge (8 bits)", "B": "Bleu (8 bits)"}[nom],
ha="center", fontsize=8.5, color=c, fontweight="bold")
ax1.text(0, 0.02, "(a) Une couleur = 24 bits, envoyés dans l'ordre G-R-B (d'où NEO_GRB), bit de poids fort en premier",
fontsize=8, color=GRIS)
# (b) codage d'un bit
ax2 = fig.add_axes([0.08, 0.12, 0.88, 0.36])
for x0, th, tl, nom in ((0, 0.4, 0.85, "bit 0"), (1.8, 0.8, 0.45, "bit 1")):
xs = [x0, x0, x0 + th, x0 + th, x0 + th + tl]
ys = [0, 1, 1, 0, 0]
ax2.plot(xs, ys, color=BLEU, lw=1.8)
ax2.fill_between([x0, x0 + th], 0, 1, color=BLEU, alpha=0.12)
ax2.text(x0 + (th + tl) / 2, 1.32, nom, ha="center", fontsize=9, fontweight="bold", color=ENCRE)
ax2.annotate("", xy=(x0, 1.1), xytext=(x0 + th, 1.1), arrowprops=dict(arrowstyle="<->", lw=0.8))
ax2.text(x0 + th / 2, 1.14, f"{th} µs".replace(".", ","), ha="center", va="bottom", fontsize=7.5)
ax2.annotate("", xy=(x0 + th, -0.12), xytext=(x0 + th + tl, -0.12), arrowprops=dict(arrowstyle="<->", lw=0.8))
ax2.text(x0 + th + tl / 2, -0.2, f"{tl} µs".replace(".", ","), ha="center", va="top", fontsize=7.5)
ax2.text(3.4, 0.55, "période d'un bit : 1,25 µs (800 kHz)\nla différence se joue à ~400 ns près :\n"
"impossible avec digitalWrite(),\nla bibliothèque utilise le matériel (RMT)",
fontsize=8, color=ENCRE, va="center")
ax2.set_xlim(-0.1, 6.2)
ax2.set_ylim(-0.5, 1.6)
ax2.axis("off")
fig.text(0.04, 0.03, "(b) Codage d'un bit : seule la durée de l'état haut change", fontsize=8, color=GRIS)
return fig
FIGURES = [
Figure("m02-pull-up", pull_up),
Figure("m02-rebonds", rebonds),
Figure("m02-chenillard", chenillard),
Figure("m02-ws2812", ws2812),
]
+129
View File
@@ -0,0 +1,129 @@
"""Briques graphiques communes : toile de dessin, boîtes, flèches, chronogrammes, séquences."""
import matplotlib.pyplot as plt
from matplotlib.patches import FancyBboxPatch
from style import BLEU, CM, ENCRE, GRIS, GRIS_CLAIR
CLAIR = { # fonds pâles associés aux couleurs de la charte
BLEU: "#e8f0fe", "#e07a1f": "#fdf0e3", "#2e8b57": "#e6f4ea",
"#c0392b": "#fce8e6", GRIS: "#f3f4f6",
}
def toile(largeur_cm, hauteur_cm, xmax=None, ymax=None):
"""Figure sans axes, en coordonnées « cm » (1 unité = 1 cm à l'échelle d'origine)."""
fig, ax = plt.subplots(figsize=(largeur_cm * CM, hauteur_cm * CM))
ax.set_xlim(0, xmax or largeur_cm)
ax.set_ylim(0, ymax or hauteur_cm)
ax.set_aspect("equal")
ax.axis("off")
return fig, ax
def boite(ax, x, y, l, h, texte="", couleur=BLEU, taille=9, gras=False, fond=None, style="round", alpha=1):
"""Boîte arrondie centrée sur (x, y). Renvoie un dict des points d'ancrage."""
fond = fond if fond is not None else CLAIR.get(couleur, "white")
ax.add_patch(FancyBboxPatch((x - l / 2, y - h / 2), l, h,
boxstyle=f"{style},pad=0,rounding_size=0.15" if style == "round" else style,
facecolor=fond, edgecolor=couleur, linewidth=1.4, alpha=alpha))
if texte:
ax.text(x, y, texte, ha="center", va="center", fontsize=taille, color=ENCRE,
fontweight="bold" if gras else "normal", linespacing=1.3)
return {"c": (x, y), "g": (x - l / 2, y), "d": (x + l / 2, y),
"h": (x, y + h / 2), "b": (x, y - h / 2)}
def fleche(ax, depart, arrivee, texte="", couleur=ENCRE, taille=8, double=False, pointille=False,
cote="haut", decalage=0.18, courbe=0):
"""Flèche entre deux points, avec étiquette optionnelle au milieu."""
ax.annotate("", xy=arrivee, xytext=depart,
arrowprops=dict(arrowstyle="<|-|>" if double else "-|>", color=couleur, lw=1.3,
linestyle="--" if pointille else "-", shrinkA=0, shrinkB=0,
mutation_scale=11, connectionstyle=f"arc3,rad={courbe}"))
if texte:
mx, my = (depart[0] + arrivee[0]) / 2, (depart[1] + arrivee[1]) / 2
vertical = abs(arrivee[0] - depart[0]) < abs(arrivee[1] - depart[1])
if vertical:
ax.text(mx + decalage, my, texte, ha="left", va="center", fontsize=taille, color=couleur)
else:
dy = decalage if cote == "haut" else -decalage
ax.text(mx, my + dy, texte, ha="center", va="bottom" if cote == "haut" else "top",
fontsize=taille, color=couleur)
def chronogramme(voies, duree, largeur_cm=16, hauteur_voie_cm=1.5, graduations=None, unite="",
couleurs=None):
"""Chronogramme logique.
voies : liste de (nom, [(t, niveau), ...]) — niveau 0/1, maintenu jusqu'au point suivant.
Renvoie (fig, ax, y_voie) où y_voie(i) donne l'ordonnée de base de la voie i.
"""
n = len(voies)
fig, ax = plt.subplots(figsize=(largeur_cm * CM, (n * hauteur_voie_cm + 1.2) * CM))
ax.set_xlim(-duree * 0.02, duree * 1.01)
ax.set_ylim(-0.6, n * 1.6)
ax.spines[["left", "top", "right"]].set_visible(False)
ax.set_yticks([])
ax.grid(axis="y", visible=False)
if graduations is not None:
ax.set_xticks(graduations)
if unite:
ax.set_xlabel(unite)
y_voie = lambda i: (n - 1 - i) * 1.6
for i, (nom, points) in enumerate(voies):
base = y_voie(i)
xs, ys = [], []
for k, (t, niv) in enumerate(points):
fin = points[k + 1][0] if k + 1 < len(points) else duree
xs += [t, fin]
ys += [base + niv, base + niv]
c = (couleurs or {}).get(nom, BLEU)
ax.plot(xs, ys, color=c, lw=1.8, solid_joinstyle="miter")
ax.fill_between(xs, base, ys, color=c, alpha=0.08)
ax.text(-duree * 0.025, base + 0.5, nom, ha="right", va="center", fontsize=9,
color=ENCRE, fontweight="bold")
return fig, ax, y_voie
def sequence(acteurs, messages, largeur_cm=16, pas_cm=0.85, couleurs=None, notes=()):
"""Diagramme de séquence.
acteurs : liste de noms. messages : liste de (source, cible, texte[, pointillé]).
notes : liste de (index_message, acteur, texte) affichées à droite de la ligne de vie.
"""
n = len(messages)
hauteur = n * pas_cm + 2.2
fig, ax = toile(largeur_cm, hauteur)
xs = {a: largeur_cm * (i + 0.5) / len(acteurs) for i, a in enumerate(acteurs)}
haut = hauteur - 0.6
for a, x in xs.items():
c = (couleurs or {}).get(a, BLEU)
boite(ax, x, haut, min(3.6, largeur_cm / len(acteurs) - 0.4), 0.8, a, couleur=c, taille=8.5, gras=True)
ax.plot([x, x], [0.3, haut - 0.4], color=GRIS, lw=1, ls=(0, (3, 3)))
for k, msg in enumerate(messages):
src, dst, texte = msg[:3]
pointille = len(msg) > 3 and msg[3]
y = haut - 1.2 - k * pas_cm
if src == dst:
ax.annotate("", xy=(xs[src] + 0.05, y - 0.3), xytext=(xs[src] + 0.05, y),
arrowprops=dict(arrowstyle="-|>", color=ENCRE, lw=1.1,
connectionstyle="arc,angleA=0,angleB=0,armA=18,armB=18,rad=4",
mutation_scale=9))
ax.text(xs[src] + 0.75, y - 0.15, texte, fontsize=7.8, va="center", color=ENCRE)
continue
fleche(ax, (xs[src], y), (xs[dst], y), texte, pointille=pointille, taille=7.8, decalage=0.08)
for k, acteur, texte in notes:
y = haut - 1.2 - k * pas_cm
ax.text(xs[acteur] + 0.2, y, texte, fontsize=7.5, color=GRIS, style="italic", va="center")
return fig, ax
def legende_couleurs(ax, elements, x, y, taille=7.5):
"""Petite légende manuelle : elements = [(couleur, texte), ...]."""
for i, (c, t) in enumerate(elements):
ax.add_patch(plt.Rectangle((x, y - i * 0.45 - 0.12), 0.35, 0.25, color=c))
ax.text(x + 0.5, y - i * 0.45, t, fontsize=taille, va="center", color=ENCRE)
__all__ = ["toile", "boite", "fleche", "chronogramme", "sequence", "legende_couleurs",
"CLAIR", "GRIS_CLAIR"]
Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 37 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 62 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 71 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 28 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 53 KiB

+940
View File
@@ -0,0 +1,940 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="484.918799pt" height="325.741571pt" viewBox="0 0 484.918799 325.741571" xmlns="http://www.w3.org/2000/svg" version="1.1">
<metadata>
<rdf:RDF xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<cc:Work>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:format>image/svg+xml</dc:format>
<dc:creator>
<cc:Agent>
<dc:title>Matplotlib v3.11.2, https://matplotlib.org/</dc:title>
</cc:Agent>
</dc:creator>
</cc:Work>
</rdf:RDF>
</metadata>
<defs>
<style type="text/css">*{stroke-linejoin: round; stroke-linecap: butt}</style>
</defs>
<g id="figure_1">
<g id="patch_1">
<path d="M 0 325.741571
L 484.918799 325.741571
L 484.918799 0
L 0 0
z
" style="fill: #ffffff"/>
</g>
<g id="axes_1">
<g id="patch_2">
<path d="M 353.84179 46.025854
L 369.194479 56.992061
L 353.84179 67.958267
L 353.84179 46.025854
z
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #c0392b; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="patch_3">
<path d="M 353.84179 110.360933
L 369.194479 121.327139
L 353.84179 132.293346
L 353.84179 110.360933
z
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #2e8b57; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="patch_4">
<path d="M 353.84179 174.696011
L 369.194479 185.662218
L 353.84179 196.628425
L 353.84179 174.696011
z
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #1f5fa8; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="patch_5">
<path d="M 353.84179 239.03109
L 369.194479 249.997297
L 353.84179 260.963503
L 353.84179 239.03109
z
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #e07a1f; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="line2d_1">
<path d="M 28.145455 271.92971
L 168.512899 271.92971
L 168.512899 35.059648
L 28.145455 35.059648
L 28.145455 271.92971
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #1f5fa8; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="line2d_2">
<path d="M 168.512899 249.997297
L 190.445312 249.997297
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #1f5fa8; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="line2d_3">
<path d="M 168.512899 185.662218
L 190.445312 185.662218
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #1f5fa8; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="line2d_4">
<path d="M 168.512899 121.327139
L 190.445312 121.327139
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #1f5fa8; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="line2d_5">
<path d="M 168.512899 56.992061
L 190.445312 56.992061
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #1f5fa8; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="line2d_6">
<path d="M 190.445312 56.992061
L 203.60476 56.992061
L 216.764208 56.992061
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #1f2937; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="line2d_7">
<path d="M 216.764208 56.992061
L 243.083103 56.992061
L 246.738505 46.025854
L 254.04931 67.958267
L 261.360114 46.025854
L 268.670919 67.958267
L 275.981723 46.025854
L 283.292527 67.958267
L 286.94793 56.992061
L 313.266825 56.992061
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #1f2937; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="line2d_8">
<path d="M 313.266825 56.992061
L 353.84179 56.992061
M 369.194479 46.025854
L 369.194479 67.958267
M 369.194479 56.992061
L 409.769443 56.992061
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #c0392b; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="line2d_9">
<path d="M 364.807996 40.542751
L 371.421593 28.968956
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #c0392b; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="patch_6">
<path d="M 368.374766 27.227913
L 375.774203 21.35189
L 374.46842 30.71
z
" clip-path="url(#p7e999a346a)" style="fill: #c0392b"/>
</g>
<g id="line2d_10">
<path d="M 354.93841 40.542751
L 361.552007 28.968956
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #c0392b; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="patch_7">
<path d="M 358.50518 27.227913
L 365.904617 21.35189
L 364.598834 30.71
z
" clip-path="url(#p7e999a346a)" style="fill: #c0392b"/>
</g>
<g id="line2d_11">
<path d="M 409.769443 56.992061
L 422.928891 56.992061
L 436.088339 56.992061
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #1f2937; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="line2d_12">
<path d="M 190.445312 121.327139
L 203.60476 121.327139
L 216.764208 121.327139
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #1f2937; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="line2d_13">
<path d="M 216.764208 121.327139
L 243.083103 121.327139
L 246.738505 110.360933
L 254.04931 132.293346
L 261.360114 110.360933
L 268.670919 132.293346
L 275.981723 110.360933
L 283.292527 132.293346
L 286.94793 121.327139
L 313.266825 121.327139
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #1f2937; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="line2d_14">
<path d="M 313.266825 121.327139
L 353.84179 121.327139
M 369.194479 110.360933
L 369.194479 132.293346
M 369.194479 121.327139
L 409.769443 121.327139
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #2e8b57; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="line2d_15">
<path d="M 364.807996 104.87783
L 371.421593 93.304035
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #2e8b57; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="patch_8">
<path d="M 368.374766 91.562991
L 375.774203 85.686968
L 374.46842 95.045079
z
" clip-path="url(#p7e999a346a)" style="fill: #2e8b57"/>
</g>
<g id="line2d_16">
<path d="M 354.93841 104.87783
L 361.552007 93.304035
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #2e8b57; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="patch_9">
<path d="M 358.50518 91.562991
L 365.904617 85.686968
L 364.598834 95.045079
z
" clip-path="url(#p7e999a346a)" style="fill: #2e8b57"/>
</g>
<g id="line2d_17">
<path d="M 409.769443 121.327139
L 422.928891 121.327139
L 436.088339 121.327139
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #1f2937; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="line2d_18">
<path d="M 190.445312 185.662218
L 203.60476 185.662218
L 216.764208 185.662218
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #1f2937; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="line2d_19">
<path d="M 216.764208 185.662218
L 243.083103 185.662218
L 246.738505 174.696011
L 254.04931 196.628425
L 261.360114 174.696011
L 268.670919 196.628425
L 275.981723 174.696011
L 283.292527 196.628425
L 286.94793 185.662218
L 313.266825 185.662218
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #1f2937; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="line2d_20">
<path d="M 313.266825 185.662218
L 353.84179 185.662218
M 369.194479 174.696011
L 369.194479 196.628425
M 369.194479 185.662218
L 409.769443 185.662218
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #1f5fa8; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="line2d_21">
<path d="M 364.807996 169.212908
L 371.421593 157.639114
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #1f5fa8; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="patch_10">
<path d="M 368.374766 155.89807
L 375.774203 150.022047
L 374.46842 159.380157
z
" clip-path="url(#p7e999a346a)" style="fill: #1f5fa8"/>
</g>
<g id="line2d_22">
<path d="M 354.93841 169.212908
L 361.552007 157.639114
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #1f5fa8; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="patch_11">
<path d="M 358.50518 155.89807
L 365.904617 150.022047
L 364.598834 159.380157
z
" clip-path="url(#p7e999a346a)" style="fill: #1f5fa8"/>
</g>
<g id="line2d_23">
<path d="M 409.769443 185.662218
L 422.928891 185.662218
L 436.088339 185.662218
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #1f2937; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="line2d_24">
<path d="M 190.445312 249.997297
L 203.60476 249.997297
L 216.764208 249.997297
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #1f2937; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="line2d_25">
<path d="M 216.764208 249.997297
L 243.083103 249.997297
L 246.738505 239.03109
L 254.04931 260.963503
L 261.360114 239.03109
L 268.670919 260.963503
L 275.981723 239.03109
L 283.292527 260.963503
L 286.94793 249.997297
L 313.266825 249.997297
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #1f2937; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="line2d_26">
<path d="M 313.266825 249.997297
L 353.84179 249.997297
M 369.194479 239.03109
L 369.194479 260.963503
M 369.194479 249.997297
L 409.769443 249.997297
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #e07a1f; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="line2d_27">
<path d="M 364.807996 233.547987
L 371.421593 221.974192
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #e07a1f; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="patch_12">
<path d="M 368.374766 220.233148
L 375.774203 214.357125
L 374.46842 223.715236
z
" clip-path="url(#p7e999a346a)" style="fill: #e07a1f"/>
</g>
<g id="line2d_28">
<path d="M 354.93841 233.547987
L 361.552007 221.974192
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #e07a1f; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="patch_13">
<path d="M 358.50518 220.233148
L 365.904617 214.357125
L 364.598834 223.715236
z
" clip-path="url(#p7e999a346a)" style="fill: #e07a1f"/>
</g>
<g id="line2d_29">
<path d="M 409.769443 249.997297
L 422.928891 249.997297
L 436.088339 249.997297
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #1f2937; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="line2d_30">
<path d="M 436.088339 56.992061
L 436.088339 153.494679
L 436.088339 249.997297
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #1f2937; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="line2d_31">
<path d="M 436.088339 249.997297
L 436.088339 263.156744
L 436.088339 276.316192
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #1f2937; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="line2d_32">
<path d="M 436.088339 276.316192
L 436.088339 293.862123
L 425.122132 293.862123
L 447.054545 293.862123
M 428.411994 299.125902
L 443.764683 299.125902
M 433.895098 304.389681
L 438.28158 304.389681
" clip-path="url(#p7e999a346a)" style="fill: none; stroke: #1f2937; stroke-width: 2; stroke-linecap: round"/>
</g>
<g id="text_1">
<!-- GPIO7 -->
<g style="fill: #1f5fa8" transform="translate(118.585675 255.093078) scale(0.14 -0.14)">
<defs>
<path id="DejaVuSans-2a" d="M 3809 666
L 3809 1919
L 2778 1919
L 2778 2438
L 4434 2438
L 4434 434
Q 4069 175 3628 42
Q 3188 -91 2688 -91
Q 1594 -91 976 548
Q 359 1188 359 2328
Q 359 3472 976 4111
Q 1594 4750 2688 4750
Q 3144 4750 3555 4637
Q 3966 4525 4313 4306
L 4313 3634
Q 3963 3931 3569 4081
Q 3175 4231 2741 4231
Q 1884 4231 1454 3753
Q 1025 3275 1025 2328
Q 1025 1384 1454 906
Q 1884 428 2741 428
Q 3075 428 3337 486
Q 3600 544 3809 666
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-33" d="M 1259 4147
L 1259 2394
L 2053 2394
Q 2494 2394 2734 2622
Q 2975 2850 2975 3272
Q 2975 3691 2734 3919
Q 2494 4147 2053 4147
L 1259 4147
z
M 628 4666
L 2053 4666
Q 2838 4666 3239 4311
Q 3641 3956 3641 3272
Q 3641 2581 3239 2228
Q 2838 1875 2053 1875
L 1259 1875
L 1259 0
L 628 0
L 628 4666
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-2c" d="M 628 4666
L 1259 4666
L 1259 0
L 628 0
L 628 4666
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-32" d="M 2522 4238
Q 1834 4238 1429 3725
Q 1025 3213 1025 2328
Q 1025 1447 1429 934
Q 1834 422 2522 422
Q 3209 422 3611 934
Q 4013 1447 4013 2328
Q 4013 3213 3611 3725
Q 3209 4238 2522 4238
z
M 2522 4750
Q 3503 4750 4090 4092
Q 4678 3434 4678 2328
Q 4678 1225 4090 567
Q 3503 -91 2522 -91
Q 1538 -91 948 565
Q 359 1222 359 2328
Q 359 3434 948 4092
Q 1538 4750 2522 4750
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-1a" d="M 525 4666
L 3525 4666
L 3525 4397
L 1831 0
L 1172 0
L 2766 4134
L 525 4134
L 525 4666
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#DejaVuSans-2a"/>
<use xlink:href="#DejaVuSans-33" transform="translate(77.484375 0)"/>
<use xlink:href="#DejaVuSans-2c" transform="translate(137.78125 0)"/>
<use xlink:href="#DejaVuSans-32" transform="translate(167.28125 0)"/>
<use xlink:href="#DejaVuSans-1a" transform="translate(246 0)"/>
</g>
</g>
<g id="text_2">
<!-- GPIO6 -->
<g style="fill: #1f5fa8" transform="translate(118.585675 190.757999) scale(0.14 -0.14)">
<defs>
<path id="DejaVuSans-19" d="M 2113 2584
Q 1688 2584 1439 2293
Q 1191 2003 1191 1497
Q 1191 994 1439 701
Q 1688 409 2113 409
Q 2538 409 2786 701
Q 3034 994 3034 1497
Q 3034 2003 2786 2293
Q 2538 2584 2113 2584
z
M 3366 4563
L 3366 3988
Q 3128 4100 2886 4159
Q 2644 4219 2406 4219
Q 1781 4219 1451 3797
Q 1122 3375 1075 2522
Q 1259 2794 1537 2939
Q 1816 3084 2150 3084
Q 2853 3084 3261 2657
Q 3669 2231 3669 1497
Q 3669 778 3244 343
Q 2819 -91 2113 -91
Q 1303 -91 875 529
Q 447 1150 447 2328
Q 447 3434 972 4092
Q 1497 4750 2381 4750
Q 2619 4750 2861 4703
Q 3103 4656 3366 4563
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#DejaVuSans-2a"/>
<use xlink:href="#DejaVuSans-33" transform="translate(77.484375 0)"/>
<use xlink:href="#DejaVuSans-2c" transform="translate(137.78125 0)"/>
<use xlink:href="#DejaVuSans-32" transform="translate(167.28125 0)"/>
<use xlink:href="#DejaVuSans-19" transform="translate(246 0)"/>
</g>
</g>
<g id="text_3">
<!-- GPIO5 -->
<g style="fill: #1f5fa8" transform="translate(118.585675 126.422921) scale(0.14 -0.14)">
<defs>
<path id="DejaVuSans-18" d="M 691 4666
L 3169 4666
L 3169 4134
L 1269 4134
L 1269 2991
Q 1406 3038 1543 3061
Q 1681 3084 1819 3084
Q 2600 3084 3056 2656
Q 3513 2228 3513 1497
Q 3513 744 3044 326
Q 2575 -91 1722 -91
Q 1428 -91 1123 -41
Q 819 9 494 109
L 494 744
Q 775 591 1075 516
Q 1375 441 1709 441
Q 2250 441 2565 725
Q 2881 1009 2881 1497
Q 2881 1984 2565 2268
Q 2250 2553 1709 2553
Q 1456 2553 1204 2497
Q 953 2441 691 2322
L 691 4666
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#DejaVuSans-2a"/>
<use xlink:href="#DejaVuSans-33" transform="translate(77.484375 0)"/>
<use xlink:href="#DejaVuSans-2c" transform="translate(137.78125 0)"/>
<use xlink:href="#DejaVuSans-32" transform="translate(167.28125 0)"/>
<use xlink:href="#DejaVuSans-18" transform="translate(246 0)"/>
</g>
</g>
<g id="text_4">
<!-- GPIO4 -->
<g style="fill: #1f5fa8" transform="translate(118.585675 62.087842) scale(0.14 -0.14)">
<defs>
<path id="DejaVuSans-17" d="M 2419 4116
L 825 1625
L 2419 1625
L 2419 4116
z
M 2253 4666
L 3047 4666
L 3047 1625
L 3713 1625
L 3713 1100
L 3047 1100
L 3047 0
L 2419 0
L 2419 1100
L 313 1100
L 313 1709
L 2253 4666
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#DejaVuSans-2a"/>
<use xlink:href="#DejaVuSans-33" transform="translate(77.484375 0)"/>
<use xlink:href="#DejaVuSans-2c" transform="translate(137.78125 0)"/>
<use xlink:href="#DejaVuSans-32" transform="translate(167.28125 0)"/>
<use xlink:href="#DejaVuSans-17" transform="translate(246 0)"/>
</g>
</g>
<g id="text_5">
<!-- ESP32-S3 -->
<g style="fill: #1f5fa8" transform="translate(74.071284 153.476009) scale(0.12 -0.12)">
<defs>
<path id="DejaVuSans-28" d="M 628 4666
L 3578 4666
L 3578 4134
L 1259 4134
L 1259 2753
L 3481 2753
L 3481 2222
L 1259 2222
L 1259 531
L 3634 531
L 3634 0
L 628 0
L 628 4666
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-36" d="M 3425 4513
L 3425 3897
Q 3066 4069 2747 4153
Q 2428 4238 2131 4238
Q 1616 4238 1336 4038
Q 1056 3838 1056 3469
Q 1056 3159 1242 3001
Q 1428 2844 1947 2747
L 2328 2669
Q 3034 2534 3370 2195
Q 3706 1856 3706 1288
Q 3706 609 3251 259
Q 2797 -91 1919 -91
Q 1588 -91 1214 -16
Q 841 59 441 206
L 441 856
Q 825 641 1194 531
Q 1563 422 1919 422
Q 2459 422 2753 634
Q 3047 847 3047 1241
Q 3047 1584 2836 1778
Q 2625 1972 2144 2069
L 1759 2144
Q 1053 2284 737 2584
Q 422 2884 422 3419
Q 422 4038 858 4394
Q 1294 4750 2059 4750
Q 2388 4750 2728 4690
Q 3069 4631 3425 4513
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-16" d="M 2597 2516
Q 3050 2419 3304 2112
Q 3559 1806 3559 1356
Q 3559 666 3084 287
Q 2609 -91 1734 -91
Q 1441 -91 1130 -33
Q 819 25 488 141
L 488 750
Q 750 597 1062 519
Q 1375 441 1716 441
Q 2309 441 2620 675
Q 2931 909 2931 1356
Q 2931 1769 2642 2001
Q 2353 2234 1838 2234
L 1294 2234
L 1294 2753
L 1863 2753
Q 2328 2753 2575 2939
Q 2822 3125 2822 3475
Q 2822 3834 2567 4026
Q 2313 4219 1838 4219
Q 1578 4219 1281 4162
Q 984 4106 628 3988
L 628 4550
Q 988 4650 1302 4700
Q 1616 4750 1894 4750
Q 2613 4750 3031 4423
Q 3450 4097 3450 3541
Q 3450 3153 3228 2886
Q 3006 2619 2597 2516
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-15" d="M 1228 531
L 3431 531
L 3431 0
L 469 0
L 469 531
Q 828 903 1448 1529
Q 2069 2156 2228 2338
Q 2531 2678 2651 2914
Q 2772 3150 2772 3378
Q 2772 3750 2511 3984
Q 2250 4219 1831 4219
Q 1534 4219 1204 4116
Q 875 4013 500 3803
L 500 4441
Q 881 4594 1212 4672
Q 1544 4750 1819 4750
Q 2544 4750 2975 4387
Q 3406 4025 3406 3419
Q 3406 3131 3298 2873
Q 3191 2616 2906 2266
Q 2828 2175 2409 1742
Q 1991 1309 1228 531
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-10" d="M 313 2009
L 1997 2009
L 1997 1497
L 313 1497
L 313 2009
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#DejaVuSans-28"/>
<use xlink:href="#DejaVuSans-36" transform="translate(63.1875 0)"/>
<use xlink:href="#DejaVuSans-33" transform="translate(126.671875 0)"/>
<use xlink:href="#DejaVuSans-16" transform="translate(186.96875 0)"/>
<use xlink:href="#DejaVuSans-15" transform="translate(250.59375 0)"/>
<use xlink:href="#DejaVuSans-10" transform="translate(314.21875 0)"/>
<use xlink:href="#DejaVuSans-36" transform="translate(350.296875 0)"/>
<use xlink:href="#DejaVuSans-16" transform="translate(413.78125 0)"/>
</g>
</g>
<g id="text_6">
<!-- 220 Ω -->
<g style="fill: #1f2937" transform="translate(251.557001 40.415231) scale(0.09 -0.09)">
<defs>
<path id="DejaVuSans-13" d="M 2034 4250
Q 1547 4250 1301 3770
Q 1056 3291 1056 2328
Q 1056 1369 1301 889
Q 1547 409 2034 409
Q 2525 409 2770 889
Q 3016 1369 3016 2328
Q 3016 3291 2770 3770
Q 2525 4250 2034 4250
z
M 2034 4750
Q 2819 4750 3233 4129
Q 3647 3509 3647 2328
Q 3647 1150 3233 529
Q 2819 -91 2034 -91
Q 1250 -91 836 529
Q 422 1150 422 2328
Q 422 3509 836 4129
Q 1250 4750 2034 4750
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-3" transform="scale(0.015625)"/>
<path id="DejaVuSans-33d" d="M 4647 556
L 4647 0
L 2772 0
L 2772 556
Q 3325 859 3634 1378
Q 3944 1897 3944 2528
Q 3944 3278 3531 3731
Q 3119 4184 2444 4184
Q 1769 4184 1355 3729
Q 941 3275 941 2528
Q 941 1897 1250 1378
Q 1563 859 2119 556
L 2119 0
L 244 0
L 244 556
L 1241 556
Q 747 991 519 1456
Q 294 1922 294 2497
Q 294 3491 894 4106
Q 1491 4722 2444 4722
Q 3391 4722 3994 4106
Q 4594 3494 4594 2528
Q 4594 1922 4372 1459
Q 4150 997 3647 556
L 4647 556
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#DejaVuSans-15"/>
<use xlink:href="#DejaVuSans-15" transform="translate(63.625 0)"/>
<use xlink:href="#DejaVuSans-13" transform="translate(127.25 0)"/>
<use xlink:href="#DejaVuSans-3" transform="translate(190.875 0)"/>
<use xlink:href="#DejaVuSans-33d" transform="translate(222.65625 0)"/>
</g>
</g>
<g id="text_7">
<!-- 220 Ω -->
<g style="fill: #1f2937" transform="translate(251.557001 104.75031) scale(0.09 -0.09)">
<use xlink:href="#DejaVuSans-15"/>
<use xlink:href="#DejaVuSans-15" transform="translate(63.625 0)"/>
<use xlink:href="#DejaVuSans-13" transform="translate(127.25 0)"/>
<use xlink:href="#DejaVuSans-3" transform="translate(190.875 0)"/>
<use xlink:href="#DejaVuSans-33d" transform="translate(222.65625 0)"/>
</g>
</g>
<g id="text_8">
<!-- 220 Ω -->
<g style="fill: #1f2937" transform="translate(251.557001 169.085388) scale(0.09 -0.09)">
<use xlink:href="#DejaVuSans-15"/>
<use xlink:href="#DejaVuSans-15" transform="translate(63.625 0)"/>
<use xlink:href="#DejaVuSans-13" transform="translate(127.25 0)"/>
<use xlink:href="#DejaVuSans-3" transform="translate(190.875 0)"/>
<use xlink:href="#DejaVuSans-33d" transform="translate(222.65625 0)"/>
</g>
</g>
<g id="text_9">
<!-- 220 Ω -->
<g style="fill: #1f2937" transform="translate(251.557001 233.420467) scale(0.09 -0.09)">
<use xlink:href="#DejaVuSans-15"/>
<use xlink:href="#DejaVuSans-15" transform="translate(63.625 0)"/>
<use xlink:href="#DejaVuSans-13" transform="translate(127.25 0)"/>
<use xlink:href="#DejaVuSans-3" transform="translate(190.875 0)"/>
<use xlink:href="#DejaVuSans-33d" transform="translate(222.65625 0)"/>
</g>
</g>
<g id="text_10">
<!-- GND -->
<g style="fill: #6b7280" transform="translate(447.702393 147.657021) scale(0.09 -0.09)">
<defs>
<path id="DejaVuSans-31" d="M 628 4666
L 1478 4666
L 3547 763
L 3547 4666
L 4159 4666
L 4159 0
L 3309 0
L 1241 3903
L 1241 0
L 628 0
L 628 4666
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-27" d="M 1259 4147
L 1259 519
L 2022 519
Q 2988 519 3436 956
Q 3884 1394 3884 2338
Q 3884 3275 3436 3711
Q 2988 4147 2022 4147
L 1259 4147
z
M 628 4666
L 1925 4666
Q 3281 4666 3915 4102
Q 4550 3538 4550 2338
Q 4550 1131 3912 565
Q 3275 0 1925 0
L 628 0
L 628 4666
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#DejaVuSans-2a"/>
<use xlink:href="#DejaVuSans-31" transform="translate(77.484375 0)"/>
<use xlink:href="#DejaVuSans-27" transform="translate(152.296875 0)"/>
</g>
<!-- commun -->
<g style="fill: #6b7280" transform="translate(438.322705 155.837177) scale(0.09 -0.09)">
<defs>
<path id="DejaVuSans-46" d="M 3122 3366
L 3122 2828
Q 2878 2963 2633 3030
Q 2388 3097 2138 3097
Q 1578 3097 1268 2742
Q 959 2388 959 1747
Q 959 1106 1268 751
Q 1578 397 2138 397
Q 2388 397 2633 464
Q 2878 531 3122 666
L 3122 134
Q 2881 22 2623 -34
Q 2366 -91 2075 -91
Q 1284 -91 818 406
Q 353 903 353 1747
Q 353 2603 823 3093
Q 1294 3584 2113 3584
Q 2378 3584 2631 3529
Q 2884 3475 3122 3366
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-52" d="M 1959 3097
Q 1497 3097 1228 2736
Q 959 2375 959 1747
Q 959 1119 1226 758
Q 1494 397 1959 397
Q 2419 397 2687 759
Q 2956 1122 2956 1747
Q 2956 2369 2687 2733
Q 2419 3097 1959 3097
z
M 1959 3584
Q 2709 3584 3137 3096
Q 3566 2609 3566 1747
Q 3566 888 3137 398
Q 2709 -91 1959 -91
Q 1206 -91 779 398
Q 353 888 353 1747
Q 353 2609 779 3096
Q 1206 3584 1959 3584
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-50" d="M 3328 2828
Q 3544 3216 3844 3400
Q 4144 3584 4550 3584
Q 5097 3584 5394 3201
Q 5691 2819 5691 2113
L 5691 0
L 5113 0
L 5113 2094
Q 5113 2597 4934 2840
Q 4756 3084 4391 3084
Q 3944 3084 3684 2787
Q 3425 2491 3425 1978
L 3425 0
L 2847 0
L 2847 2094
Q 2847 2600 2669 2842
Q 2491 3084 2119 3084
Q 1678 3084 1418 2786
Q 1159 2488 1159 1978
L 1159 0
L 581 0
L 581 3500
L 1159 3500
L 1159 2956
Q 1356 3278 1631 3431
Q 1906 3584 2284 3584
Q 2666 3584 2933 3390
Q 3200 3197 3328 2828
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-58" d="M 544 1381
L 544 3500
L 1119 3500
L 1119 1403
Q 1119 906 1312 657
Q 1506 409 1894 409
Q 2359 409 2629 706
Q 2900 1003 2900 1516
L 2900 3500
L 3475 3500
L 3475 0
L 2900 0
L 2900 538
Q 2691 219 2414 64
Q 2138 -91 1772 -91
Q 1169 -91 856 284
Q 544 659 544 1381
z
M 1991 3584
L 1991 3584
z
" transform="scale(0.015625)"/>
<path id="DejaVuSans-51" d="M 3513 2113
L 3513 0
L 2938 0
L 2938 2094
Q 2938 2591 2744 2837
Q 2550 3084 2163 3084
Q 1697 3084 1428 2787
Q 1159 2491 1159 1978
L 1159 0
L 581 0
L 581 3500
L 1159 3500
L 1159 2956
Q 1366 3272 1645 3428
Q 1925 3584 2291 3584
Q 2894 3584 3203 3211
Q 3513 2838 3513 2113
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#DejaVuSans-46"/>
<use xlink:href="#DejaVuSans-52" transform="translate(54.984375 0)"/>
<use xlink:href="#DejaVuSans-50" transform="translate(116.171875 0)"/>
<use xlink:href="#DejaVuSans-50" transform="translate(213.578125 0)"/>
<use xlink:href="#DejaVuSans-58" transform="translate(310.984375 0)"/>
<use xlink:href="#DejaVuSans-51" transform="translate(374.359375 0)"/>
</g>
</g>
</g>
</g>
<defs>
<clipPath id="p7e999a346a">
<rect x="7.2" y="7.2" width="460.8" height="311.341571"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 26 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 44 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 36 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 77 KiB