Python Scripting Example: Studio Clock

@DougE Great design, great example, the result is both functional and aesthetically pleasing. :thumbsup: I was planning a clock using WS2812 LEDs, didn’t quite get round to it yet.

@Anders_Wallin Intel Ediison is small and fully supported by Arduino, but it is not cheap. Also small but a lot cheaper are the ESP8266 modules. They have limited IO, so you would need to drive the LEDs via SPI and some external logic chips…

They have limited IO, so you would need to drive the LEDs via SPI and some external logic chips…

I haven’t tested it yet, but I’m planning to use a 16-Channel Constant-Current LED Driver like the TLC 59281 from Texas Instruments. Thats the reason I made it an Common Anode.

that his script is a gold mine

Thanks. Got some more code snippets from my test project to build digits with single LEDs for you. It was the easiest way for building digits. Haven’t decided how to wire the rest (I’m waiting till I know how I will do the rest. The samples are already ordered.).

#uses the common 7-Segment numbering with 0=a, 1=b, ...

#scaling factor for Segments spacing
f=0.33 
#relative position offset of Horizontal and Vertical Segments to center
OffDig = [[0,  -2*f], [f,-f], [f, f], [0,2*f], [-f,f], [-f,-f], [0, 0]]

def buildHSeg(mod,  offX,  offY):
    print "buildHSeg",  mod[0][6]
    for i in range(len(mod)):
        mod[i][1].SetOrientation([-900,  900][i%2])
        mod[i][1].SetPosition(pcbnew.wxPointMM((-1.5+i)*Scale/8+offX,  0+offY))
        
def buildVSeg(mod,  offX,  offY):
    print "buildVSeg", mod[0][6]
    for i in range(len(mod)):
        mod[i][1].SetOrientation([0,  1800][i%2])
        mod[i][1].SetPosition(pcbnew.wxPointMM(0+offX,  (-1.5+i)*Scale/8+offY))
         
def build7Seg(mods, offsetX,  offsetY):
    print "build7Seg"
    for i in range(len(mods)/4):
        if i in [0, 6, 3]:
            buildHSeg(mods[i*4:i*4+4],  OffDig[i][0]*Scale + offsetX, OffDig[i][1]*Scale + offsetY)
        else:
            buildVSeg(mods[i*4:i*4+4],  OffDig[i][0]*Scale + offsetX, OffDig[i][1]*Scale + offsetY)

build7Seg(MatrixDigitLeds, 0, 0) 
for i in range(len(MatrixDigitLeds)):
    if i%4 != 3:
        addTrack(MatrixDigitLeds[i][2].GetPosition(), MatrixDigitLeds[i+1][4].GetPosition(), MatrixDigitLeds[i+1][5],  0)

It will get you something like this. The series-circuits shouldn’t be a problem when you use a Constant Current Driver.

3 Likes

Very nice to see real world examples of using skidl and pcbnew scripting. Just what I needed. Thank you very much for sharing it’s so much easier to work from examples.

Hi,
Great idea, I like it a lot. I tried to do this in KiCAD 4.0.6(I’m on a nightly build), but I didn’t have any luck with it.
However you can create circular array, which can be utilized to do the same layout. :slight_smile:

Cheers,
Tibor

I working on a much cleaner Script at the Moment. It won’t be as fast as my original one, but is better to read and fixes some bugs (concerning the order of the Elements).

It will also include the routing for four 7-Segment Displays and two 16 pin connectors.
My goal is to script the whole clock without any control circuits on the board. This way I can build the controls external and don’t have to decide jet, what micro-controller and LED-Drivers I will use.

Maybe that one will work and if its not, it will be a lot easer to debug.

As promised a cleaner script with a full routed StudioClock. Here are the source files.
KiCadStudioClock.zip (37.8 KB)

Some Experiences
-most of the scripting it is quite easy as the patterns are simple
-the exceptions from the patterns create the big problems
-keeping track of components you created is not easy, so don’t do it
-storing the Modules and Nets in a Sorted Dictionary, this way I can filter out what I need
-when you change the radius, you might need to adjust some variables in the functions
-hitting the Polygon lines requires some maths
-my motivation felt very deep
-some List are not sorted and the function uses there existing patterns
-the functions GetPosition and GetLayer are your best friend
-define your reference system properly (can be different from the native) it saves a lot of time

5 Likes

That is a beautiful board!

Are you sure this has anything to do with this script? You might want to ask for help on a windows specialized forum instead of one for an open source project.

@DougE from your example, can I assume that it is possible to create a complete PCB from start to finish in python?

That’s right. The script already does that for the PCB part. At this level of automation, using parameters, it would even be absolutely counterproductive to do something by hand.
Also the Netlist can be generated automatically as @devbisme showed in a previous post post.

The placement of footprints is easy, but the routing is a lot of effort because you have to script each track individually, even if in loops, and collision free. However, I can imagine scripting the well scriptable first and leaving the rest of the routing to an Autorouter.

Hello
I tried to download the KicadStudioClock.zip, example but it says access denied. Is it just me? If not, would it be possible to repost the link? Thanks.

@DougE hasn’t posted since 2019. Kicad is at least 2 versions newer since that script was used.

Thanks for the update. I guess I’m out of luck. I thought I might be able to adapt it if I could download the zip, but maybe the scripting language has changed too much.

Well, I’ve tagged him so if his account is set to receive updates all might not be lost. You could also try PM. That will almost certainly send an alert if he has it set and hasn’t changed emails.

EDIT: This seems to be the github repo:

It links back to this thread.

I also found an old copy among my own bitcollection.

2017-08-06_KiCadStudioClock.zip (37.8 KB)

This file also seems to be related:
schematic.py (1017 Bytes)

The scripting language used is python, and that has not changed much, but KiCad’s file formats have changed. The schematic format has been completely redesigned for KiCad V6, while (I think) the changes in the PCB format are much smaller, but I don’t know details.

And the origins of SKiDL:

Thanks for doing that. I have some reading to do now.

Thank’s for the zip file. I hadn’t distinguished between the scripting language and the Kicad file format. That’s good to know.

@hermit I do still watch this thread (or better the mail told me i still watch) and still have the source files.
@paulvdh thanks for re-posting the zip

Since this issue seems to come up regularly, it seems appropriate to update my 5 year old script (which is still in Python 2) and publish it on GitHub or similar. It would be great If anyone (maybe @jerseyp2) has the time and spirit to do this (I could then update my original post with the link).

2 Likes

@DougE Since I’m using FreeCad and the KicadStepUp plugin, and trying to incorporate some kind of enclosure for the PCB, I thought I’d try to see if I can create a script to take my Kicad LED model positions imported into FreeCad, position them, and then use KicadStepUp to push the positions back to Kicad. It doesn’t get me the traces, but it might be possible to implement, and I’m new to Python, so it’s a challenge.

I’ve used the Lattice2 workbench to set placements for 300 LEDs on a circle, and now I’m slowly trying to figure out how to programmatically attach the LED STEP files to those placements. I’m trying to keep it parametric, so I’m driving it from a spreadsheet. Small steps. I hope someone has the time to update your script. It’s an impressive project, and I’m going to study it more when I have a chance. Thanks for posting an updated comment.

There are a lot of useful plugins for kicad v6 with open source, just go to plugin manager and browse. They all have github/gitlab links.
Not to say that having this script ported to v6 and python3 wouldn’t be useful, just pointing out other sources for someone who needs good working examples.