#!/usr/bin/env python3 """Dessine schemas/schema_electrique.svg : schéma de la maquette 3 x 3, avec les symboles normalisés (résistances rectangulaires) et des fils colorés. Usage : python3 outils/schema_electrique.py schemas/schema_electrique.svg""" import sys ROUGE, VERT, BLEU = "#d62828", "#2a9d3a", "#2f6fc4" TEINTE = {ROUGE: "#fbd5d5", VERT: "#d3f0d8", BLEU: "#d6e3f7"} LIGNE, BASE, MASSE, TEXTE = "#3a3a3a", "#c98a00", "#222222", "#333333" LX = [170, 370, 570] # x de la diode rouge de chaque colonne LY = [330, 480, 630] # y des anodes de chaque ligne DX = 48 # écart entre les diodes R, G, B d'une LED COULEURS = [("R", ROUGE, "220 Ω"), ("G", VERT, "150 Ω"), ("B", BLEU, "150 Ω")] XT = 790 # centre des transistors XD = {0: 900, 1: 930, 2: 960} # descentes D11, D12, D13 X_GND = 1000 Y_PIN = 170 # bas du bloc Arduino out = [] A = out.append def ligne(x1, y1, x2, y2, c, w=2.2): A(f'') def chemin(d, c, w=2.2): A(f'') def point(x, y, c): A(f'') def texte(x, y, s, taille=13, ancre="middle", c=TEXTE, gras=False, rot=None, italique=False): tr = f' transform="rotate({rot} {x} {y})"' if rot else "" A(f'{s}') def resistance_v(x, y1, y2, c, valeur): """Résistance verticale entre y1 et y2 (rectangle de 50 px au milieu).""" m = (y1 + y2) / 2 ligne(x, y1, x, m - 25, c) ligne(x, m + 25, x, y2, c) A(f'') texte(x + 19, m, valeur, 12, c=c, rot=-90) def resistance_h(x1, x2, y, c, valeur): m = (x1 + x2) / 2 ligne(x1, y, m - 25, y, c) ligne(m + 25, y, x2, y, c) A(f'') texte(m, y - 13, valeur, 12, c=c) def diode(x, ya, c): """Diode verticale : anode en haut (ya), cathode en bas (ya + 32).""" ligne(x, ya, x, ya + 8, c) A(f'') ligne(x - 9, ya + 22, x + 9, ya + 22, c, 2.4) ligne(x, ya + 22, x, ya + 32, LIGNE) for dy in (0, 7): # lumière émise x1, y1, x2, y2 = x + 9, ya + 15 + dy, x + 18, ya + 6 + dy ligne(x1, y1, x2, y2, c, 1.4) A(f'') def masse(x, y): ligne(x - 11, y, x + 11, y, MASSE, 2.4) ligne(x - 7, y + 5, x + 7, y + 5, MASSE, 2.4) ligne(x - 3, y + 10, x + 3, y + 10, MASSE, 2.4) def transistor(r, yt): """NPN dessiné en miroir : base à droite, collecteur en haut à gauche, émetteur en bas à gauche (vers la masse).""" xb = XT + 8 A(f'') ligne(xb, yt - 13, xb, yt + 13, TEXTE, 3) ligne(xb, yt - 6, XT - 12, yt - 20, LIGNE) # collecteur ligne(xb, yt + 6, XT - 12, yt + 20, MASSE) # émetteur A(f'') ligne(xb, yt, XT + 40, yt, BASE) # base texte(XT - 44, yt - 2, f"T{r}", 14, gras=True) texte(XT - 44, yt + 14, "BC337", 11, c="#666") texte(XT + 22, yt + 18, "B", 10, c="#888") texte(XT - 22, yt - 26, "C", 10, c="#888") texte(XT - 26, yt + 28, "E", 10, c="#888") W, H = 1080, 970 A(f'') A('Schéma électrique de la maquette 3 x 3') A(f'') texte(40, 38, "Maquette 3 × 3 : schéma électrique", 22, "start", "#111", True) texte(40, 60, "9 LED RGB à cathode commune, allumées ligne par ligne (multiplexage)", 14, "start", "#666") # ---------------------------------------------------------------- Arduino A(f'') texte(565, 112, "Arduino Uno", 20, gras=True, c="#00666d") texte(565, 132, "alimenté par le câble USB", 12, c="#4d8f94") broches = {} for c in range(3): for k, (_, coul, _) in enumerate(COULEURS): broches[f"D{2 + 3 * c + k}"] = (LX[c] + DX * k - 22, coul) for r in range(3): broches[f"D{11 + r}"] = (XD[r], BASE) broches["GND"] = (X_GND, MASSE) for nom, (x, coul) in broches.items(): ligne(x, Y_PIN, x, Y_PIN + 20, coul) texte(x, Y_PIN - 10, nom, 12, gras=True, c=coul if coul != BASE else "#9a6a00") masse(X_GND, Y_PIN + 20) # ---------------------------------------------------------------- colonnes (anodes) for c in range(3): for k, (_, coul, val) in enumerate(COULEURS): xb = LX[c] + DX * k - 22 resistance_v(xb, Y_PIN + 20, 265, coul, val) y_fin = LY[2] - 12 ligne(xb, 265, xb, y_fin, coul) for r in range(3): xd, ys = LX[c] + DX * k, LY[r] - 12 chemin(f"M{xb} {ys} H{xd} V{LY[r]}", coul) if r < 2: point(xb, ys, coul) texte(LX[c] + DX, LY[2] + 100, f"colonne {c}", 14, c="#555", gras=True) # ---------------------------------------------------------------- LED for r in range(3): for c in range(3): x0 = LX[c] A(f'') texte(x0 + DX + 2, LY[r] - 22, f"L{r}C{c}", 11, c="#888", gras=True) for r in range(3): for c in range(3): for k, (_, coul, _) in enumerate(COULEURS): diode(LX[c] + DX * k, LY[r], coul) # ---------------------------------------------------------------- lignes (cathodes) bus_x = sorted(LX[c] + DX * k - 22 for c in range(3) for k in range(3)) for r in range(3): y = LY[r] + 60 for c in range(3): for k in range(3): xd = LX[c] + DX * k ligne(xd, LY[r] + 32, xd, y, LIGNE) if not (c == 0 and k == 0): point(xd, y, LIGNE) # ligne horizontale avec des « ponts » là où elle croise une colonne d = f"M{LX[0]} {y}" if r < 2: for xb in bus_x: if LX[0] < xb < XT - 12: d += f" H{xb - 6} a6 6 0 0 1 12 0" d += f" H{XT - 12} V{y + 40 - 20}" chemin(d, LIGNE) texte(XT - 56, y - 8, f"ligne {r}", 13, "end", c="#555", gras=True) yt = y + 40 transistor(r, yt) ligne(XT - 12, yt + 20, XT - 12, yt + 36, MASSE) masse(XT - 12, yt + 36) resistance_h(XT + 40, XD[r], yt, BASE, "1 kΩ") ligne(XD[r], yt, XD[r], Y_PIN + 20, BASE) # ---------------------------------------------------------------- légende ly = 840 A(f'') texte(60, ly, "Légende", 15, "start", "#111", True) items = [ (lambda x, y: (ligne(x, y, x + 30, y, ROUGE), ligne(x + 34, y, x + 64, y, VERT), ligne(x + 68, y, x + 98, y, BLEU)), "colonnes : anodes R, G, B (D2 à D10)"), (lambda x, y: ligne(x, y, x + 98, y, LIGNE), "lignes : cathodes communes"), (lambda x, y: ligne(x, y, x + 98, y, BASE), "commande des lignes (D11 à D13)"), (lambda x, y: masse(x + 49, y - 6), "masse (GND) : symboles tous reliés"), (lambda x, y: point(x + 49, y, LIGNE), "point = fils connectés"), (lambda x, y: chemin(f"M{x} {y} H{x + 43} a6 6 0 0 1 12 0 H{x + 98}", LIGNE), "pont = croisement sans contact"), ] for i, (dessin, legende) in enumerate(items): col, lig = i % 3, i // 3 x, y = (60, 400, 700)[col], ly + 30 + lig * 32 dessin(x, y) texte(x + 110, y + 4, legende, 12, "start") texte(60, ly + 98, "Un pixel s'allume quand sa ligne est active (D11, D12 ou D13 à HIGH : le " "transistor relie les cathodes à la masse) et que sa couleur l'est aussi (D2 à D10).", 12, "start", "#555", italique=True) A("") with open(sys.argv[1], "w") as f: f.write("\n".join(out))