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>
122 lines
5.9 KiB
Python
122 lines
5.9 KiB
Python
"""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),
|
|
]
|