-
-
Save anonymous/cb907737750e180b5f881a11237c6d62 to your computer and use it in GitHub Desktop.
Simple script to generate resistor-arrays of various kinds. See http://forum.fritzing.org/t/resistor-array/2079 for reference. Version 2.0.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# coding=utf-8 | |
# This script generates resistor-arrays of various sizes. Documentation on the | |
# usage will follow. See: http://forum.fritzing.org/t/2079 | |
import svgwrite as svg | |
from svgwrite.base import BaseElement | |
from svgwrite.mixins import Presentation, Markers, Transform | |
import os | |
import shutil | |
import zipfile | |
STAR = 1 | |
PARALLEL = 3 | |
BASEPATH = os.getcwd() | |
def gen_fzp(output, resistors, circuittype, resistance, img_icon, img_bredboard, img_schematic, img_pcb): | |
pins = pin_number(resistors, circuittype) | |
fzp = '<?xml version="1.0" encoding="UTF-8"?>\n' \ | |
'<module fritzingVersion="0.9.3b" moduleId="Resistor' | |
fzp += 'Bussed' if circuittype == PARALLEL else 'Isolated' | |
fzp += str(resistors) | |
fzp += 'SIP_ResistorModuleID">\n' \ | |
' <version>4</version>\n' \ | |
' <title>' | |
fzp += 'Bussed' if circuittype == PARALLEL else 'Isolated' | |
fzp += str(resistors) | |
fzp += ' Resistor-' | |
fzp += str(resistors) | |
fzp += ' (SIP-' | |
fzp += str(pins) | |
fzp += ')</title>\n' \ | |
' <label>R</label>\n' \ | |
' <date>Mon Sep 26 2016</date>\n' \ | |
' <author>Stephen Lilley</author>\n' \ | |
' <tags>\n' \ | |
' <tag>resistor</tag>\n' \ | |
' <tag>' | |
fzp += 'parallel' if circuittype == PARALLEL else 'star' | |
fzp += '</tag>\n' \ | |
' <tag>array</tag>\n' \ | |
' <tag>network</tag>\n' \ | |
' <tag>' | |
fzp += 'bussed' if circuittype == PARALLEL else 'isolated' | |
fzp += '</tag>\n' \ | |
' </tags>\n' \ | |
' <properties>\n' \ | |
' <property name="family">Resistor (Networks / Arrays)</property>\n' \ | |
' <property name="package">SIP-' | |
fzp += str(pins) | |
fzp += '</property>\n' \ | |
' <property name="circuit type">Bussed</property>\n' \ | |
' <property name="pins">' | |
fzp += str(pins) | |
fzp += '</property>\n' \ | |
' <property name="resistors">' | |
fzp += str(resistors) | |
fzp += '</property>\n' \ | |
' <property showInLabel="yes" name="Resistance">' | |
fzp += str(resistance) | |
fzp += '</property>\n' \ | |
' <property showInLabel="yes" name="power"></property>\n' \ | |
' <property showInLabel="no" name="tolerance">±5%</property>\n' \ | |
' <property name="part number"></property>\n' \ | |
' <property name="variant">variant 1</property>\n' \ | |
' </properties>\n' \ | |
' <taxonomy>discreteParts.resistor.' | |
fzp += str(resistance) | |
fzp += '</taxonomy>\n' \ | |
' <description>A resistor array is a single package which contains more than one resistor. They are typically used for convenience when several resistors are needed together in the same place in a circuit.</description>\n' \ | |
' <spice><line>RA{instanceTitle} {net connector0} {net connector1} {resistance}</line>\n' \ | |
' </spice>\n' \ | |
' <views>\n' \ | |
' <iconView>\n' \ | |
' <layers image="icon/' + img_icon + '">\n' \ | |
' <layer layerId="icon"/>\n' \ | |
' </layers>\n' \ | |
' </iconView>\n' \ | |
' <breadboardView>\n' \ | |
' <layers image="breadboard/' + img_bredboard + '">\n' \ | |
' <layer layerId="breadboard"/>\n' \ | |
' </layers>\n' \ | |
' </breadboardView>\n' \ | |
' <schematicView>\n' \ | |
' <layers image="schematic/' + img_schematic + '">\n' \ | |
' <layer layerId="schematic"/>\n' \ | |
' </layers>\n' \ | |
' </schematicView>\n' \ | |
' <pcbView>\n' \ | |
' <layers image="pcb/' + img_pcb + '">\n' \ | |
' <layer layerId="copper0"/>\n' \ | |
' <layer layerId="copper1"/>\n' \ | |
' <layer layerId="silkscreen"/>\n' \ | |
' </layers>\n' \ | |
' </pcbView>\n' \ | |
' </views>\n' \ | |
' <connectors>\n' | |
for i in range(pins): | |
fzp += ' <connector id="connector' + str(i) + '" type="male" name="Pin ' + str(i) + '">\n' \ | |
' <description>Pin' + str(i) + '</description>\n' \ | |
' <views>\n' \ | |
' <breadboardView>\n' \ | |
' <p svgId="connector' + str(i) + 'pin" layer="breadboard"/>\n' \ | |
' </breadboardView>\n' \ | |
' <schematicView>\n' \ | |
' <p terminalId="connector' + str(i) + 'terminal" svgId="connector' + str(i) + 'pin" layer="schematic"/>\n' \ | |
' </schematicView>\n' \ | |
' <pcbView>\n' \ | |
' <p svgId="connector' + str(i) + 'pin" layer="copper0"/>\n' \ | |
' <p svgId="connector' + str(i) + 'pin" layer="copper1"/>\n' \ | |
' </pcbView>\n' \ | |
' </views>\n' \ | |
' </connector>\n' | |
fzp += ' </connectors>\n' \ | |
'</module>\n' | |
with open(output, "w") as f: | |
f.write(fzp) | |
# Generates a breadboard-view of the element and saves it to a file. | |
# @param output File to save the view to | |
# @param pins Number of pins to generate | |
# @param label Label to write on top | |
def gen_breadboard(output, resistors, circuittype, resistance): | |
dx = 26494 # Difference between each pin | |
min_width = 73017 # Base width of the viewbox for a three-pin-object | |
width_multiplicator = 0.275642 / min_width | |
# Used to calculate the width of the SVG in inches | |
pins = pin_number(resistors, circuittype) | |
# Calculate the viewbox | |
width = min_width + (pins - 3) * dx | |
temp_name = "temp.svg" | |
draw = svg.Drawing(temp_name, | |
size = (str(width * width_multiplicator) + "in", "0.334972in"), | |
viewBox = "0 0 " + str(width) + " 88734") | |
# Center expandable body | |
expand = (pins - 3) * dx | |
path = [ | |
("M", 48808 + expand, 41602), | |
("l", -123, 17, -24247 - expand, 0, 0, -41521), | |
("c", 7776, -115, 16651, -123, 24370 + expand, -17), | |
("l", 0, 41530, 0, -8), | |
("z") | |
] | |
draw.add(draw.path(d = path, fill = "#EB9922")) | |
path = [ | |
("M", 24439, 97), | |
("c", 7768, -115, 16634, -131, 24370 + expand, -25), | |
("l", 0, 2756), | |
("c", -7735, -106, -16602, -91, -24370 - expand, 25), | |
("l", 0, -2756), | |
("z") | |
] | |
draw.add(draw.path(d = path, fill = "#D3891E")) | |
# Right end | |
path = [ | |
("M", 72013 + expand, 41315), | |
"c0,3109 -1862,5085 -5094,5085l-8186 0c-4643,-7243 11558,0 0,0 -1887,-2937 -5176,-4889 -8924,-4889 -452,0 -894,25 -1329,82l0 -41530c9056,131 16487,418 18440,885 2731,664 4159,2568 5094,5094 2256,6119 0,35263 0,35263l-1 9z" | |
] | |
draw.add(draw.path(d = path, fill = "#EB9922")) | |
path = [ | |
("M", 48488 + expand, 73), | |
"c9121,123 16602,418 18563,894 2731,664 4159,2568 5094,5094 821,2215 985,7710 796,13345 -41,-4650 -115,-8727 -796,-10581 -935,-2526 -2354,-4429 -5094,-5094 -1961,-467 -9441,-762 -18563,-894l0 -2756 0 -7zm23525 41242c0,3109 -1862,5085 -5094,5085 -14371,0 -5340,0 -8186,0 -1887,-2937 -5176,-4889 -8924,-4889 -452,0 -894,25 -1329,82l0 -6545c452,-66 894,-98 1329,-98 3790,0 8440,2666 11016,5930 1124,1477 -6414,-8047 -378,-140 2149,2756 5250,1083 6184,590 2633,-1681 3748,-3683 4151,-5340 1066,-4331 2018,-11271 2158,-22861 197,10753 -935,28184 -935,28184l7 1z" | |
] | |
draw.add(draw.path(d = path, fill = "#D3891E")) | |
path = [ | |
("M", 68921 + expand, 5142), | |
"c-2067,-1542 -8219,-394 -8252,1944 6365,3822 5766,21466 5709,23680 8,4773 2838,5266 3076,5274 2108,41 4700,-26986 -533,-30899l0 1z" | |
] | |
draw.add(draw.path(d = path, fill = "#FEFEFE", fill_opacity="0.549020", enable_background="new")) | |
# Generate the bottom pins | |
params = { "fill": "none", "stroke": "#96989A", "stroke_width": "5297.99", "stroke_linecap": "round" } | |
for i in range(pins): | |
x = 10076 + dx * i | |
# Generate the repeated middle content | |
if (i >= 2): | |
shift = dx * (i - 2) | |
path = [ | |
("M", 49808 + shift, 41520), | |
"c-3748,0 -7046,1944 -8924,4889l-8637 0c-1887,-2937 -5176,-4889 -8924,-4889l0 0 0 -10376 26494 0 0 10376 -8 0z" | |
] | |
draw.add(draw.path(d = path, fill = "#EB9922")) | |
path = [ | |
("M", 49808 + shift, 34958), | |
"l0 6562c-3748,0 -7046,1944 -8924,4889l-8637 0c-1887,-2937 -5176,-4889 -8924,-4889l0 0 0 -6562 0 0c3765,0 8449,2657 11016,5930 1477,1969 2969,1895 4463,0 2559,-3256 7226,-5930 11016,-5930l-9 0z" | |
] | |
draw.add(draw.path(d = path, fill = "#D3891E")) | |
# Place the actual legs | |
draw.add(draw.line((x, 51937), (x, 86085), **params)) | |
draw.add(draw.rect((x - 5906, 46401), (11804, 5299), fill = "#727376")) | |
draw.add(draw.rect((x - 4209, 46401), (1591, 5299), fill = "#E6E7E8")) | |
# Place the connector | |
draw.add(draw.rect((x - 2649, 78136), (5299, 10598), id = "connector" + str(i) + "pin", fill = "none")) | |
# Left end | |
draw.add(draw.path(fill = "#EB9922", d = "M24766 41618c-476,-66 -951,-98 -1443,-98 -3748,0 -7046,1944 -8924,4889l-8440 0c-3289,0 -5094,-4905 -5094,-5094 0,0 -1944,-29143 0,-35255 853,-2682 2608,-4618 5094,-5094 2280,-435 9794,-730 18816,-870l0 41521 -8 -1z")) | |
draw.add(draw.path(fill = "#D3891E", d = "M24766 41618c-467,-66 -951,-98 -1443,-98 -3748,0 -7046,1944 -8924,4889l-8440 0c-3289,0 -5094,-4905 -5094,-5094 0,0 -1017,-15273 -845,-26027 303,9728 812,18924 1214,20367 762,2822 2108,4036 4577,5815 1961,878 4249,1870 6496,-575 2568,-3264 7251,-5930 11016,-5930 467,0 951,41 1443,123l0 6537 -1 -8zm-24640 -22278c-41,-5800 148,-11057 861,-13279 853,-2682 2608,-4618 5094,-5094 2273,-435 9720,-730 18686,-870l0 2756c-8965,140 -16413,435 -18686,870 -2485,476 -4240,2411 -5094,5094 -590,1862 -821,5864 -861,10524l0 -1z")) | |
draw.add(draw.path(fill = "#FEFEFE", fill_opacity="0.549020", enable_background = "new", d="M4817 4511c3249,-1452 10196,-229 10057,2322 -8005,0 -5356,18357 -7653,23591 -1615,3675 -2256,4675 -4749,5577 -1239,-353 -3232,-28996 2346,-31490z")) | |
draw.add(draw.circle((11133, 31398), r = 2649)) | |
# Add the text on top | |
label = gen_label(resistors, circuittype, resistance) | |
draw.add(draw.text(label, x = [ 13782 ], y = [ 31398 ], fill = "#5F6160", font_weight = "normal", font_size = "18395.9", font_family = "Droid Sans")) | |
# Save the file | |
draw.save() | |
add_linebreaks(temp_name, output, True) | |
def gen_label(resistors, circuittype, resistance): | |
res = str(resistance) | |
res_code = res[:2] + str(len(res) - 2) | |
n = pin_number(resistors, circuittype) | |
return "L {:02d} {} {}".format(n, circuittype, res_code) | |
def pin_number(resistors, circuittype): | |
return resistors + 1 if circuittype == STAR else resistors * 2 | |
# Load the file to add linebreaks | |
# @param input File that should be modified | |
# @param output Location to save result to | |
# @param remove_input Remove inputfile after successful output-generation | |
def add_linebreaks(input, output, remove_input = False): | |
with open(output, "wt") as fout: | |
with open(input, "rt") as fin: | |
for line in fin: | |
fout.write(line.replace(">", ">\r\n")) | |
if (remove_input): os.remove(input) | |
# Generates an icon of the element and saves it to a file. | |
# @param output File to save the view to | |
# @param pins Number of pins to generate | |
# @param label Label to write on top | |
# @param resistance Resistance-value of the part | |
def gen_icon(output, resistors, circuittype, resistance): | |
gen_breadboard(output, resistors, circuittype, resistance) | |
def gen_pcb(output, resistors, circuittype, resistance): | |
dx = 2793 # Difference between each pin | |
min_width = 8657 # Base width of the viewbox for a three-pin-object | |
width_multiplicator = 0.309984 / min_width | |
# Used to calculate the width of the SVG in inches | |
pins = pin_number(resistors, circuittype) | |
# Calculate the viewbox | |
width = min_width + (pins - 3) * dx | |
temp_name = "temp.svg" | |
draw = svg.Drawing(temp_name, | |
size = (str(width * width_multiplicator) + "in", "0.11in"), | |
viewBox = "0 0 " + str(width) + " 3072") | |
# Structure | |
g_pcb = svg.container.Group(id = "pcb") | |
draw.add(g_pcb) | |
# Silkscreen | |
g_silk = svg.container.Group(id = "silkscreen") | |
g_silk.add(draw.rect((140, 140), (dx * pins + 2, 2793), fill = "none", stroke = "#FEFEFE", stroke_width = "279.267")) | |
g_silk.add(draw.line((1117, 2932), (140, 1955), fill = "none", stroke = "white", stroke_width = "139.629")) | |
g_pcb.add(g_silk) | |
# Copper 1 | |
g_cop_par = svg.container.Group(id = "copper1") | |
g_pcb.add(g_cop_par) | |
# Copper 0 | |
g_cop = svg.container.Group(id = "copper0") | |
g_cop_par.add(g_cop) | |
# Add Pins | |
for i in range(pins): | |
g_cop.add(draw.circle((dx * i + 1536, 1536), id = "connector{}pin".format(i), fill = "none", stroke = "#FFBF00", stroke_width = "558.514", r = 810)) | |
# Save the file | |
draw.save() | |
add_linebreaks(temp_name, output, True) | |
# Generates the schematics-view and saves it to a file. | |
# @param output File to save the view to | |
# @param pins Number of pins to generate | |
# @param label Label to write on top | |
# @param resistance Resistance-value of the part | |
def gen_schematics(output, resistors, circuittype, resistance): | |
dy = 7370 # Difference between each pin | |
min_height = 29993 # Base height of the viewbox for a three-pin-object | |
height_multiplicator = 0.406945 / min_height | |
# Used to calculate the height of the SVG in inches | |
pins = pin_number(resistors, circuittype) | |
# Calculate the viewbox | |
height = min_height + (pins - 3) * dy | |
temp_name = "temp.svg" | |
draw = svg.Drawing(temp_name, | |
size = ("0.508346in", str(height * height_multiplicator) + "in"), | |
viewBox = "0 0 37467 " + str(height)) | |
# Expandable body | |
expand = (pins - 3) * dy | |
draw.add(draw.rect((7730, 256), (29481, 29481 + expand), fill = "#FEFEFE", stroke = "#373435", stroke_width = "511.857", stroke_linecap = "round")) | |
if (circuittype == STAR): draw.add(draw.line((33525, 7626), (33525, 22366 + expand), fill = "none", stroke = "#606062", stroke_width = "511.857", stroke_linecap = "round")) | |
# External pins | |
for i in range(pins): | |
y = dy * i | |
draw.add(draw.line((358, 7626 + y), (7720, 7626 + y), id = "connector{}pin".format(i), fill = "none", stroke = "#787878", stroke_width = "716.426", stroke_linecap = "round")) | |
draw.add(draw.rect((321, 7589 + y), (74, 74), fill = "none", id = "connector{}terminal".format(i))) | |
draw.add(draw.text(str(i + 1), x = [ 3057.2 ], y = [ 6551.4 + y ], fill = "#606062", font_weight = "normal", font_size = "3582.71", font_family = "Droid Sans")) | |
# Internal pins | |
for i in range(0, pins, 2): | |
y = dy * i | |
draw.add(draw.line((7730, 7625 + y), (33526, 7625 + y), fill = "none", stroke = "#606062", stroke_width = "511.857", stroke_linecap = "round")) | |
if (circuittype == STAR): break | |
draw.add(draw.line((33526, 7625 + y), (33526, 7625 + y + dy), fill = "none", stroke = "#606062", stroke_width = "511.857", stroke_linecap = "round")) | |
# Internal resistors | |
for i in range(1, pins): | |
if (circuittype == PARALLEL and not i % 2): continue | |
y = dy * (i - 1) | |
path = [ | |
("M", 27998, 14996 + y), | |
"l5527 0m-6265 2949l737 -2949m-2579 -2948l1842 5897m-3685 0l1843 -5897m-3685 0l1842 5897m-3685 0l1843 -5897m-3685 0l1842 5897m-3685 0l1843 -5897m-3685 0l1842 5897m-2948 -2949l1106 -2948m-6633 2948l5527 0" | |
] | |
draw.add(draw.path(fill = "none", stroke = "#606062", stroke_width = "511.857", stroke_linecap = "round", d = path)) | |
# Connectordots | |
if (circuittype == STAR): | |
for i in range(1, pins - 1): | |
y = dy * (i - 1) | |
draw.add(draw.circle((33451, 14996 + y), r = 663, fill = "#606062", stroke = "#606062", stroke_width = "221.109")) | |
# Save the file | |
draw.save() | |
add_linebreaks(temp_name, output, True) | |
def gen_part(output, resistors, circuittype, resistance): | |
name = 'resistor-' | |
name += 'bussed' if circuittype == PARALLEL else 'isolated' | |
name += '-' + str(resistors) + '-sip' | |
basedir = "temp/" | |
if (os.path.exists(basedir)): shutil.rmtree(basedir) | |
os.makedirs(basedir) | |
f_icon = "svg.icon." + name + "_icon.svg" | |
f_breadboard = "svg.breadboard." + name + "_breadboard.svg" | |
f_schematic = "svg.schematic." + name + "_schematic.svg" | |
f_pcb = "svg.pcb." + name + "_pcb.svg" | |
f_fzp = "part." + name + ".fzp" | |
gen_icon(f_icon, resistors, circuittype, resistance) | |
gen_breadboard(f_breadboard, resistors, circuittype, resistance) | |
gen_schematics(f_schematic, resistors, circuittype, resistance) | |
gen_pcb(f_pcb, resistors, circuittype, resistance) | |
gen_fzp(f_fzp, resistors, circuittype, resistance, name + "_icon.svg", name + "_breadboard.svg", name + "_schematic.svg", name + "_pcb.svg") | |
f_zip = zipfile.ZipFile(output, 'w') | |
for f in [f_icon, f_breadboard, f_schematic, f_pcb, f_fzp]: | |
f_zip.write(f, f) | |
f_zip.close() | |
shutil.rmtree(basedir) | |
if not os.path.exists("build"): os.makedirs("build") | |
gen_part("build/test.fzpz", 10, PARALLEL, 220) | |
#if not os.path.exists("build"): os.makedirs("build") | |
#gen_fzp("build/test.fzp", 3, PARALLEL, 220, "bla.svg", "bla.svg", "blub.svg", "bla.svg") | |
# for i in range(3, 6): | |
# gen_breadboard("build/parallel_{}.breadboard.svg".format(i), i, PARALLEL, 470) | |
# gen_schematics("build/parallel_{}.schematics.svg".format(i), i, PARALLEL, 470) | |
# gen_pcb("build/parallel_{}.pcb.svg".format(i), i, PARALLEL, 470) | |
# gen_icon("build/parallel_{}.icon.svg".format(i), i, PARALLEL, 470) | |
# for i in range(4, 10): | |
# gen_breadboard("build/star_{}.breadboard.svg".format(i), i, STAR, 10000) | |
# gen_schematics("build/star_{}.schematics.svg".format(i), i, STAR, 10000) | |
# gen_pcb("build/star_{}.pcb.svg".format(i), i, STAR, 10000) | |
# gen_icon("build/star_{}.icon.svg".format(i), i, STAR, 10000) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment