#!/usr/bin/env python # depends on kicad-skip (https://github.com/psychogenic/kicad-skip) # tested with led:SK6805-EC15 (https://partdb.alfter.us/en/part/168/info#attachments) # should be adaptable to similar addressable LED footprints # start with three symbols: the LED to use, and GND and +5V power symbols from skip import Symbol, Schematic array_width=48 array_height=12 basename=f"rgb-led-matrix-{array_width}x{array_height}" base_prefix="D" base_width=6 # this connects DOUT to DIN directly within each row base_height=8 gndlabel="GND" pwrlabel="+5V" gridOrigin = (18, 14) unitspace = 2.54 def units_to_mm(u:int): return u*unitspace def to_grid(xunits:int, yunits:int): global unitspace, gridOrigin return ( (gridOrigin[0]*unitspace)+(xunits*unitspace), (gridOrigin[1]*unitspace)+(yunits*unitspace)) def add_parts(basedOn:Symbol, width:int, height:int, start_ref_count:int=1): dcount=start_ref_count table=[] for y in range(height): row_leds=[] for x in range(width): new_part=basedOn.clone() coords=to_grid(x*base_width, y*base_height) new_part.move(coords[0], coords[1]) new_part.setAllReferences(f"{base_prefix}{dcount}") row_leds.append(new_part) dcount+=1 table.append(row_leds) return table def make_grid(sch:Schematic, basedOn:Symbol, width:int, height:int, start_ref_count:int=1): for i in sch.symbol: if i.Value.value==gndlabel: gnd=i if i.Value.value==pwrlabel: pwr=i grid=add_parts(basedOn, width, height, start_ref_count) y=0 for row in grid: x=0 for led in row: if x==0: wire=sch.wire.new() # add a GND symbol and connect to it wire.start_at(led.pin.VSS) wire.delta_y=0 wire.delta_x=-units_to_mm(base_width) sym=gnd.clone() sym.move(wire.end) if x==array_width-1: wire=sch.wire.new() # add a +5V symbol and connect to it wire.start_at(led.pin.VDD) wire.delta_y=0 wire.delta_x=units_to_mm(base_width) sym=pwr.clone() sym.move(wire.end) if x==0 and y>0: lwire=sch.wire.new() # inter-row connect on left lwire.start_at(led.pin.DIN) lwire.delta_y=-units_to_mm(base_height/2) lwire.delta_x=0 wire=sch.wire.new() wire.start_at(lwire.end) wire.delta_y=0 wire.delta_x=units_to_mm(array_width*base_width) if x==array_width-1 and y