Non-plated through-hole pads on back copper only

It is surprising that there is no such pad built-in in Kicad as this is the most basic use case, non-plated through-hole pads on back copper only like on a good ol’ single layer PCB. I need those for some footprints I create so that the parts can be de-soldered easily and replaced.

I have read the similar posts here but all solutions look dodgy at best or somewhat complicated. I don’t want to re-drill plated holes to remove plating. Even a google search doesn’t yield much results. I can’t believe I am the only one with such a simple need. Am I missing something?

I am using Kicad 7.0.2. Any help appreciated.
Joris

Good because such pads like to break away when soldered many times?

In most cases using sockets will be more common if parts need to be easily replaced.

I understand that you want to have whole PCB with PTH holes and only some footprints with NPTH holes. It is really not a most basic use case.

If you want whole PCB with single layer pads with NPTH holes then you have no problem. If you order single sided PCB with no plating hole process than all holes will be not plated. It is probably more basic use case. But last time I used single sided PCB was around 1990.
I suppose price for single layer PCB is the same as for two layer until you don’t order several m² of them.

If NONE of the board needs plated through holes then this becomes a step for the manufacturer.

Thanks for your reply. Good to know one has this option with the fab house. However in my case I need only some components to have non-plated hole pads.

Try to build that on proto board…

I won’t replace components so often that pads will lift, but say I need replacing one or try some new capacitor brand, I just throw the board and build a new one?

Just way too many through hole components in the libraries in a world that is moving away from them to justify anything other than making the ones you want for personal use probably. I’m not sure if this does what you want in that regard.

1 Like

Actually, what you want (if not wanting plating on the walls) is shown in image below…

You can have or not-have a Mask…
(I CNC Mill my boards so, this is all I ever need…)

1 Like

Thanks for your reply. How were you able to route tracks to a mechanical NPTH that has no net? I was only able to start a track from a component with regular pad to the periphery of the NPTH but that is messy…

As you may have observed, there were no nets in my example.

Ability for Connection to PAD/etc is determined in part by DRC settings, Interactive-Route settings and learning by clicking and seeing what works/doesn’t-work. That’s where your homework play’s a role…

Just to show that Nets can be used and/or not-used, below…

I doubt that. Most of us like getting a free via.

Make your own pads. Or snip the leads before using a solder sucker.

Cost savings for single sided NPTH are only for punched rather than drilled, paper based PCBs - the brown ones you see in older Sony gear. For most hobbyist or business uses, double sided PTH is a much better choice for simple boards

And still in use to this day.
Has anyone looked at the PCBs controlling your “pop-up” toaster; or the SMPS in your PC or Microwave oven, or even the power supplies in flat screen TVs and monitors?

Hollow rivets are still also used on many of these boards for large, heavy components in an effort to minimize dry joints caused by temperature fluctuations over time.

I found the solution on in this excellent thread here on kicad.info on the layout forum.

Basically the idea is to have the pad to be connected as an SMD pad on the back copper so it has a net and pin number etc…, then placing an NPTH mechanical pad over it. I have made the NPTH pad a slim 1mm ring and the hole is as required by the part.



For the net-connected SMD pad I decided to use a slightly larger than standard pad and have set the local solder mask clearance to -0.3mm so that the solder resist overlaps the copper while still maintaining sufficient soldering area. This is to try and mitigate the risk of pad lifting in the eventuality of part replacement.

Of course DRC complaints a lot about clearances and also pad type mismatch (SMD pads for THT footprint) but that’s manageable. Also tracks can’t be routed to the pad center because of the mechanical hole but that can be dealt with as described in the original thread by drawing the track next to the pad and then moving it in contact with the copper.

I’m only half in the thread but seems to work so far with the provided example and a modified capacitor footprint of mine. Note that I didn’t make the effort of nice track placement in this simple example. Still a bit cumbersome but the number of such single layer components will be small. Kudos to paulvdh for this work and thanks to all who replied.

If it helps, I ended up writing a plugin to switch selected pads from PTH to NPTH-over-SMD and back. I was using kicad 6 and unfortunately it appears to be broken on 7 - I will at some point revisit it, but I don’t know if this thread will still be open by then.

import pcbnew

layers = {pcbnew.BOARD_GetStandardLayerName(n):n for n in range(pcbnew.PCB_LAYER_ID_COUNT)}


class HomePad(pcbnew.ActionPlugin):
    def __init__(self, flip, *args, **kwargs):
        self.flip = flip
        super().__init__(*args, **kwargs)


    def defaults(self):
        self.name = "Homemade pads - connected on {}".format('front' if self.flip else 'back')
        self.category = "Footprint mod"
        self.description = "Converts PTH into one-sided NPTHs"

    def Run(self):
        flip = self.flip
        for fp in pcbnew.GetBoard().GetFootprints():
            for p in fp.Pads():
                if (p.IsSelected() or fp.IsSelected()) and p.GetAttribute() == pcbnew.PAD_ATTRIB_PTH:
                    npth = p.Duplicate()
                    fp.Add(npth)
                    npth.SetNumber(p.GetNumber() + '_Hole')
                    npth.SetAttribute(pcbnew.PAD_ATTRIB_NPTH)
                    npth.SetSize(npth.GetDrillSize())
                    npth.SetDrillSize(npth.GetDrillSize())
                    lset = npth.UnplatedHoleMask()
                    lset.removeLayer(layers['F.Cu'])
                    lset.removeLayer(layers['B.Cu'])
                    npth.SetLayerSet(lset)
                    p.SetAttribute(pcbnew.PAD_ATTRIB_SMD)
                    bset = p.SMDMask()
                    fset = p.ApertureMask()
                    backside = p.Duplicate()
                    fp.Add(backside)
                    backside.SetNumber('{}_{}'.format(p.GetNumber(), 'back' if flip else 'front'))
                    add = ['B.Cu', 'B.Paste', 'B.Mask']
                    remove = ['F.Cu', 'F.Paste', 'F.Mask']
                    if (p.IsFlipped() or flip) and not (p.IsFlipped() and flip):
                        (add, remove) = (remove, add)
                    for l in add:
                        bset.addLayer(layers[l])
                        fset.removeLayer(layers[l])
                    for l in remove:
                        bset.removeLayer(layers[l])
                        if not l.endswith('.Cu'):
                            fset.addLayer(layers[l])
                    p.SetLayerSet(bset)
                    backside.SetLayerSet(fset)
                    backside.SetNet(None)


class UndoHomePad(pcbnew.ActionPlugin):
    def defaults(self):
        self.name = "Undo homemade pads"
        self.category = "Footprint mod"
        self.description = "Converts one-sided NPTHs back to 'normal' PTH"

    def Run(self):
        for fp in pcbnew.GetBoard().GetFootprints():
            pads = {}
            for p in fp.Pads():
                pads.setdefault((p.GetX(), p.GetY()), []).append(p)
            for ps in pads.values():
                npth = [p for p in ps if p.GetAttribute() == pcbnew.PAD_ATTRIB_NPTH]
                smd = [p for p in ps if p.GetAttribute() == pcbnew.PAD_ATTRIB_SMD]
                cn_smd = [p for p in smd if not p.IsAperturePad()]
                if len(npth) == 1 and len(cn_smd) == 1:
                    npth = npth[0]
                    cn_smd = cn_smd[0]
                    if fp.IsSelected() or npth.IsSelected() or any(p.IsSelected() for p in smd):
                        cn_smd.SetAttribute(pcbnew.PAD_ATTRIB_PTH)
                        cn_smd.SetDrillSize(npth.GetDrillSize())
                        cn_smd.SetLayerSet(cn_smd.PTHMask())
                        fp.Remove(npth)
                        for p in smd:
                            if p.IsAperturePad():
                                fp.Remove(p)

HomePad(True).register()
HomePad(False).register()
UndoHomePad().register()

1 Like