Create a gist now

Instantly share code, notes, and snippets.

anonymous /r-array-gen.py Secret
Created Oct 19, 2016

Embed
What would you like to do?
Simple script to generate resistor-arrays of various kinds. See http://forum.fritzing.org/t/resistor-array/2079 for reference. Version 2.0.
#!/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">&#177;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