"""Ofensteuerung (Wemos D1 mini) - einzige Quelle für Schaltplan + Platine. Pins: Symbol-Pinnummer == Footprint-Padnummer. pcb: (x, y, rot) in mm, Platine 100 x 100, Ursprung oben links. 230-V-Bereich oben links (Rahmen auf dem Bestückungsdruck), Kleinspannung rechts und unten. """ PROJECT = 'ofensteuerung' W, H = 100.0, 100.0 FP_R = 'Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P7.62mm_Horizontal' FP_C = 'Capacitor_THT:C_Disc_D5.0mm_W2.5mm_P5.00mm' FP_CP10 = 'Capacitor_THT:CP_Radial_D10.0mm_P5.00mm' FP_CP8 = 'Capacitor_THT:CP_Radial_D8.0mm_P3.50mm' FP_CP5 = 'Capacitor_THT:CP_Radial_D5.0mm_P2.00mm' FP_Q = 'Package_TO_SOT_THT:TO-92_Inline_Wide' FP_LED = 'LED_THT:LED_D3.0mm' FP_D41 = 'Diode_THT:D_DO-41_SOD81_P10.16mm_Horizontal' FP_T3 = 'Connector_Phoenix_MSTB:PhoenixContact_MSTBA_2,5_3-G-5,08_1x03_P5.08mm_Horizontal' FP_T2 = 'Connector_Phoenix_MSTB:PhoenixContact_MSTBA_2,5_2-G-5,08_1x02_P5.08mm_Horizontal' FP_H2 = 'Connector_PinHeader_2.54mm:PinHeader_1x02_P2.54mm_Vertical' TERM = 'Steckklemme 5,08 mm (Phoenix MSTBA/MSTB oder 2EDGR/2EDGK kompatibel)' TERM230 = 'Steckklemme 5,08 mm, 250 V / 12 A (Phoenix MSTBA 2,5/x-G-5,08 + MSTB 2,5/x-ST-5,08)' MAINS = ('L_IN', 'L_F', 'L_SW', 'L_PUMP', 'N', 'PE') PARTS = [] def P(ref, sym, val, fp, pins, pcb, **kw): d = dict(ref=ref, sym=sym, val=val, fp=fp, pins=pins, pcb=pcb); d.update(kw); PARTS.append(d) def R(ref, val, a, b, pcb, **kw): P(ref, 'Device:R', val, FP_R, {'1': a, '2': b}, pcb, **kw) def C(ref, val, a, b, pcb, fp=FP_C, sym='Device:C', **kw): P(ref, sym, val, fp, {'1': a, '2': b}, pcb, **kw) # ================= 230 V ================= P('J2', 'Connector:Screw_Terminal_01x03', 'NETZ 230V (PE/N/L)', FP_T3, {'1': 'L_IN', '2': 'N', '3': 'PE'}, (21.16, 10.5, 180), mpn=TERM230, desc='Netzzuleitung, vor der Platine abgesichert (LS 10 A)') P('J4', 'Connector:Screw_Terminal_01x03', 'THERMOSTAT (L/Ls/N)', FP_T3, {'1': 'N', '2': 'L_SW', '3': 'L_F'}, (39.52, 10.5, 180), mpn=TERM230, desc='Thermostat-Schließer zwischen L und Ls (parallel zum Relaiskontakt, schaltet die Pumpe auch ohne ESP); N für Thermostate mit Versorgung/Kontrolllampe') P('J3', 'Connector:Screw_Terminal_01x03', 'PUMPE 230V (L/N/PE)', FP_T3, {'1': 'PE', '2': 'N', '3': 'L_PUMP'}, (57.88, 10.5, 180), mpn=TERM230) P('F1', 'Device:Fuse', 'T 2A', 'Fuse:Fuseholder_Clip-5x20mm_Littelfuse_111_Inline_P20.00x5.00mm_D1.05mm_Horizontal', {'1': 'L_IN', '2': 'L_F'}, (9.36, 25.0, 0), desc='Feinsicherung 5x20 träge, Pumpe + Thermostatkreis', mpn='2x Sicherungsclip 5x20 (oder Halter aus B-12-2)') P('K1', 'Relay:SANYOU_SRD_Form_C', 'SRD-05VDC-SL-C', 'Relay_THT:Relay_SPDT_SANYOU_SRD_Series_Form_C', {'1': 'L_F', '2': 'RELAY_C', '3': 'L_SW', '4': None, '5': '+5V'}, (29.36, 48.0, 90), desc='Songle SRD-05VDC-SL-C 10 A/250 V, Schließer (NO) schaltet Pumpe', ncname={'4': ''}) P('T1', PROJECT + ':ZMCT103C', 'ZMCT103C', PROJECT + ':ZMCT103C_Drahtbruecke', {'1': 'CT_A', '2': 'VMID', '3': 'L_SW', '4': 'L_PUMP'}, (50.0, 38.0, 90), desc='Stromwandler 5A/5mA (1000:1). Pumpen-L als isolierte Drahtbrücke (H07V-K 1,5 mm²) durchs Loch: Pad L_SW -> Loch -> Pad L_PUMP') # ================= Versorgung 5 V ================= P('J1', 'Connector:Screw_Terminal_01x02', 'VIN 5V/3A (+/-)', FP_T2, {'1': '+5V', '2': 'GND'}, (84.44, 89.5, 0), mpn=TERM, desc='5-V-Netzteil >= 3 A (Servo MG996R zieht bis 2,5 A)') C('C1', '1000u/10V', '+5V', 'GND', (90.0, 79.0, 0), fp=FP_CP10, sym='Device:C_Polarized', desc='Puffer für Servo-Anlaufstrom') C('C2', '100n', '+5V', 'GND', (85.5, 40.5, 0)) R('R4', '2k2', '+5V', 'LED5_A', (77.0, 47.0, 0)) P('D3', 'Device:LED', 'LED grün', FP_LED, {'1': 'GND', '2': 'LED5_A'}, (91.5, 47.0, 180)) # ================= Wemos ================= P('A1', PROJECT + ':WEMOS_D1_mini', 'WEMOS D1 mini', PROJECT + ':WEMOS_D1_mini_Socket', { '1': None, '2': 'A0', '3': 'RELAY_G', '4': 'SCK', '5': 'MISO', '6': 'PWM_G', '7': 'TC_CS', '8': '+3V3', '9': 'TX', '10': 'FB', '11': 'SCL', '12': 'SDA', '13': 'SERVO_G', '14': 'OW', '15': 'GND', '16': '+5V'}, (70.0, 16.0, 0), desc='auf 2x 1x8 Buchsenleiste 2,54 mm', ncname={'1': 'RST'}) C('C3', '10u', '+3V3', 'GND', (77.0, 40.5, 0), fp=FP_CP5, sym='Device:C_Polarized') C('C4', '100n', '+3V3', 'GND', (69.0, 40.5, 0)) # ================= Relaistreiber ================= R('R1', '1k', 'RELAY_G', 'RELAY_B', (15.0, 61.0, 0)) R('R2', '10k', 'RELAY_B', 'GND', (15.0, 64.5, 0), desc='hält das Relais beim Booten aus') P('Q1', 'Transistor_BJT:Q_NPN_CBE', 'BC546B', FP_Q, {'1': 'RELAY_C', '2': 'RELAY_B', '3': 'GND'}, (26.5, 63.0, 0)) P('D1', 'Device:D', '1N4007', FP_D41, {'1': '+5V', '2': 'RELAY_C'}, (23.0, 57.0, 0), desc='Freilaufdiode Relaisspule') R('R3', '1k', '+5V', 'LEDK_A', (34.0, 66.0, 0)) P('D2', 'Device:LED', 'LED rot', FP_LED, {'1': 'RELAY_C', '2': 'LEDK_A'}, (37.0, 61.5, 0), desc='leuchtet, wenn das Relais anzieht') # ================= Strommessung (ZMCT103C -> ADS1115 A0-A1 differenziell) ================= R('R5', '100', 'CT_A', 'VMID', (44.0, 58.5, 0), desc='Bürde: 1 A Pumpenstrom = 100 mV eff.') R('R6', '10k', '+3V3', 'VMID', (44.0, 62.0, 0)) R('R7', '10k', 'VMID', 'GND', (44.0, 65.5, 0)) C('C5', '10u', 'VMID', 'GND', (56.0, 60.0, 0), fp=FP_CP5, sym='Device:C_Polarized') C('C6', '100n', 'VMID', 'GND', (55.0, 65.5, 0)) P('A2', PROJECT + ':ADS1115_Modul', 'ADS1115 Modul', PROJECT + ':ADS1115_Module_1x10', { '1': '+3V3', '2': 'GND', '3': 'SCL', '4': 'SDA', '5': 'GND', '6': None, '7': 'CT_A', '8': 'VMID', '9': 'ADS_A2', '10': 'ADS_A3'}, (16.0, 81.5, 0), desc='I2C 0x48 (ADDR=GND), auf 1x10 Buchsenleiste', ncname={'6': 'ALRT'}) # ================= Abgastemperatur (MAX6675-Modul, Typ K) ================= P('A3', PROJECT + ':MAX6675_Modul', 'MAX6675 Modul', PROJECT + ':MAX6675_Module_1x5', {'1': 'GND', '2': '+3V3', '3': 'SCK', '4': 'TC_CS', '5': 'MISO'}, (76.5, 58.5, 0), desc='Thermoelement Typ K direkt an die Schraubklemme des Moduls (Plattenrand). Pinfolge GND VCC SCK CS SO vor dem Einlöten prüfen') R('R9', '10k', 'TC_CS', 'GND', (72.5, 59.0, 90), desc='GPIO15 muss beim Booten low sein') C('C8', '100n', '+3V3', 'GND', (68.5, 64.0, 90)) # ================= 1-Wire DS18B20 (3 Klemmen, ein Bus) ================= for i, xyr in enumerate(((11.0, 89.5, 0), (29.36, 89.5, 0), (10.5, 58.0, 270))): P(f'J{5+i}', 'Connector:Screw_Terminal_01x03', 'DS18B20 (GND/DQ/3V3)', FP_T3, {'1': 'GND', '2': 'OW', '3': '+3V3'}, xyr, mpn=TERM, desc='DS18B20: schwarz GND, gelb DQ, rot VDD') R('R8', '4k7', '+3V3', 'OW', (3.5, 76.0, 0)) C('C7', '100n', '+3V3', 'GND', (3.5, 80.0, 0)) # ================= Luftklappe: Servo MG996R ================= P('J8', 'Connector:Screw_Terminal_01x03', 'KLAPPE SERVO (GND/5V/SIG)', FP_T3, {'1': 'GND', '2': '+5V', '3': 'SERVO'}, (47.72, 89.5, 0), mpn=TERM, desc='MG996R: braun GND, rot +5V, orange Signal') R('R10', '330', 'SERVO_G', 'SERVO', (47.0, 83.0, 0), desc='Schutzwiderstand Signal (3,3-V-Pegel reicht für MG996R)') C('C9', '470u/10V', '+5V', 'GND', (51.0, 76.5, 0), fp=FP_CP8, sym='Device:C_Polarized', desc='Puffer direkt an der Servoklemme') C('C10', '100n', '+5V', 'GND', (44.0, 76.5, 90)) # ================= PWM-Pumpe (optional, wie Umwälzpumpe) ================= P('J9', 'Connector:Screw_Terminal_01x03', 'PWM-PUMPE (GND/FB/PWM)', FP_T3, {'1': 'GND', '2': 'FB_IN', '3': 'PWM_OUT'}, (66.08, 89.5, 0), mpn=TERM, desc='Signalkabel PWM-Hocheffizienzpumpe (Profil H/S), wie Umwälzpumpe') R('R11', '1k', 'PWM_G', 'PWM_B', (73.0, 84.0, 90)) R('R12', '10k', 'PWM_B', 'GND', (76.5, 84.0, 90)) P('Q2', 'Transistor_BJT:Q_NPN_CBE', 'BC546B', FP_Q, {'1': 'PWM_OUT', '2': 'PWM_B', '3': 'GND'}, (80.0, 82.0, 0)) R('R13', '470', 'PWM_PU', 'PWM_OUT', (69.5, 84.0, 90)) P('JP1', 'Jumper:Jumper_2_Open', 'Pull-up 5V', FP_H2, {'1': '+5V', '2': 'PWM_PU'}, (66.0, 78.5, 0), desc='gesteckt: Ausgang 0/5 V (VTS/AMG), offen: Open-Collector -> ESP aus = Pumpe nach Bedienfeld') R('R14', '220', 'FB_IN', 'FB', (62.5, 84.0, 90)) R('R15', '4k7', '+3V3', 'FB', (59.0, 84.0, 90)) # ================= Erweiterung ================= P('J10', 'Connector_Generic:Conn_01x09', 'ERWEITERUNG', 'Connector_PinHeader_2.54mm:PinHeader_1x09_P2.54mm_Vertical', { '1': '+5V', '2': '+3V3', '3': 'GND', '4': 'SDA', '5': 'SCL', '6': 'A0', '7': 'TX', '8': 'ADS_A2', '9': 'ADS_A3'}, (97.5, 32.0, 0), desc='I2C, ESP A0, TX (GPIO1), ADS1115 A2/A3 für spätere Sensoren') for i, (x, y) in enumerate([(3.5, 3.5), (96.5, 3.5), (3.5, 96.5), (97.1, 97.1)]): P(f'H{i+1}', 'Mechanical:MountingHole', 'M3', 'MountingHole:MountingHole_3.2mm_M3', {}, (x, y, 0)) # PWR_FLAGs (nur Schaltplan) for i, net in enumerate(('+5V', 'GND')): P(f'#FLG0{i+1}', 'power:PWR_FLAG', 'PWR_FLAG', '', {'1': net}, None, board=False) NOCONNECT = {('A1', '1'), ('A2', '6'), ('K1', '4')} # ---------- 230-V-Bereich ---------- # Polygon des Netzspannungsbereichs (keine GND-Fläche; beim Routen der Kleinspannung gesperrt) MAINS_AREA = [(0.6, 0.6), (66.3, 0.6), (66.3, 53.5), (0.6, 53.5)] # Kleinspannungs-Stummel, die aus dem 230-V-Bereich herausführen (vorverlegt): (net, [(x,y),...]) LV_STUBS = [] # in gen_pcb aus den Padpositionen berechnet # ---------- Bestückungsdruck ---------- TERMLBL = { 'J1': ('5V 3A', ['+', '-']), 'J2': ('NETZ 230V', ['L', 'N', 'PE']), 'J3': ('PUMPE', ['PE', 'N', 'L']), 'J4': ('THERMOSTAT', ['N', 'Ls', 'L']), 'J5': ('DS18B20', ['GND', 'DQ', '3V3']), 'J6': ('DS18B20', ['GND', 'DQ', '3V3']), 'J7': ('DS18B20', ['GND', 'DQ', '3V3']), 'J8': ('KLAPPE', ['GND', '5V', 'SIG']), 'J9': ('PWM-PUMPE', ['GND', 'FB', 'PWM']), } SILK = [] for p in PARTS: if p['ref'] in TERMLBL: name, pins = TERMLBL[p['ref']] x0, y0, rot = p['pcb'] if rot == 270: # linke Kante, Pins nach unten ys = [y0 + 5.08 * i for i in range(len(pins))] for y, t in zip(ys, pins): SILK.append((t, x0 + 3.6, y, 0.8)) SILK.append((name, x0 - 5.5, sum(ys) / len(ys), 1.1, 'F.SilkS', 90, True)) continue if rot == 90: # rechte Kante, Pin 1 unten, Pins nach oben ys = [y0 - 5.08 * i for i in range(len(pins))] for y, t in zip(ys, pins): SILK.append((t, x0 - 6.0, y, 0.9)) SILK.append((name, x0 - 1.0, ys[-1] - 4.8, 1.1, 'F.SilkS', 0, True)) continue sgn = 1 if rot == 0 else -1 xs = [x0 + sgn * 5.08 * i for i in range(len(pins))] ly = y0 + (4.05 if rot == 180 else -3.0) gy = y0 + (-6.0 if rot == 180 else -5.0) for x, t in zip(xs, pins): SILK.append((t, x, ly, 0.9)) if rot == 180: SILK.append((name, sum(xs) / len(xs), ly + 2.0, 1.1, 'F.SilkS', 0, True)) else: SILK.append((name, sum(xs) / len(xs), gy, 1.1, 'F.SilkS', 0, True)) for i, t in enumerate(['5V', '3V3', 'GND', 'SDA', 'SCL', 'A0', 'TX', 'AD2', 'AD3']): SILK.append((t, 94.4, 32.0 + 2.54 * i, 0.8, 'F.SilkS', 0)) SILK += [ ('OFENSTEUERUNG v1.0', 50, 97.0, 1.2, 'B.SilkS', 0, True), ('!! 230 V !!', 9.0, 44.0, 1.5, 'F.SilkS', 0, True), ('Draht L durchs Loch', 49.5, 27.5, 0.8), ('T2A', 19.2, 28.6, 0.9), ('PU', 66.0, 77.4, 0.8), ('Typ K', 98.6, 63.5, 0.9, 'F.SilkS', 90), ]