Multi-layer PCB inductive antenna

I am trying to create a multi-layer PCB inductive antenna - currently 2 layers, maybe more in the future. I created a spiral pattern in a BMP file using the specs from ( and imported it into KiCad using the Bitmap2Component Tool. [More detail, the 2nd layer is mirrored from the first so that the inside of one layer can be connected to the inside of the next layer and have the current flowing in the same direction in both layers. That detail isn’t really important to my issue, but if I don’t include it someone is bound to ask :slight_smile: ] From there, I added pads to both ends of the spiral trace using PCB Footprint Editor. To get it on the correct layer, I manually edited one of the files to move the trace and pads to the bottom copper layer and edited the other similarly to put it on Inner Layer 2. So far, so good.

I used the new footprint in my schematic, exported the netlist, started PCB editor, set it to a 4 layer board, imported the net list which gave a warning about having pads on an invalid layer (inner layer 2). Both inductive antenna patterns showed up on the proper layer along with the rest of the parts. I saved and quit. Again, so far, so good.

When I attempt to re-open the PCB design, kicad crashes. I removed the offending pads from inner layer 2 and tried again. It still crashes. I have a few questions:

  1. Should I report this as a bug since it’s a crash?
  2. Has anyone created an antenna on an inner layer?
  3. Does anyone know a better way to do this?


Are you able to upload the footprint you got there and have trouble with?

What KiCAD version and OS you’re running?

I have a python script that runs outside of KiCAD that can create spirals with segments of copper tracks, so shouldn’t give DRC any hard time.
If you want to give it a whirl:

The output needs to be collected in a text file and then manually copied into the kicad_pcb file with an text editor at the correct place.

Here is some more info on it when I was creating the script:

Thanks for the response!

I’m running 4.02 stable on Windows 10 Pro.

I can’t upload the real file since I’m a new user. However, I simplified the polygon massively so that I can just paste in the text file (below) and it still causes a crash. You need to make your PCB at least 4 layers before reading the netlist. Otherwise, the device (which now is only a short arc) doesn’t show up.

(module PCB_inner2 (layer In2.Cu) (tedit 577A770C)
(fp_text reference L* (at 0 0) (layer F.SilkS) hide
(effects (font (thickness 0.3)))
(fp_text value PCB_IND (at 0.75 0) (layer F.SilkS) hide
(effects (font (thickness 0.3)))
(fp_poly (pts (xy 0.163483 -7.55548) (xy 0.332189 -7.548857) (xy 0.513822 -7.538286) (xy 0.52899 -7.537271)) (layer In2.Cu) (width 0.1))
(pad 1 smd circle (at 0.7 -7.5) (size 0.4 0.4) (layers In2.Cu))
(pad 2 smd circle (at 0 -7.6) (size 0.4 0.4) (layers In2.Cu))

The footprint loads in the editor when I set the layer for F.Cu…

Can you give me the spiral values that you get out of that TI web app?

  • inner radius
  • outer radius
  • start angle
  • track thickness
  • track spacing
  • rotations
  • …?

The footprint will load just fine. Like you said, to see it in footprint editor you need to change the layer with a text editor.

However, if you use this footprint on the In2.Cu layer (say, set it as an inductor footprint) in a PCB, save the layout, then try to re-open the layout, KiCad crashes. As I said, I can’t upload my footprint (because I’m new and the system won’t allow it) so I removed the bulk of a 475k file so that I could just paste the text in and the file not go on for pages and pages. That’s why there’s only an arc. The full version goes from 0.6" to 0.2" and does 22 loops (5 mil trace width, 4 mil trace gap). However, the very short, simple version crashes KiCad just as well as the big one!

Here’s the PCB file (again directly pasted in since I can’t upload). All it contains is the inductor connected to 2 pins of a 6 pin connector. Try loading it in the PCB Layout tool. Note that you will need to change the directory of the library module from Airbios_Libraries to something that makes sense on your setup. On my system, I get a crash if I use the PCB_inner2 file from my prior post (that is, no layers changed from my last post).

(kicad_pcb (version 4) (host pcbnew 4.0.2-stable)

(links 2)
(no_connects 2)
(area 0 0 0 0)
(thickness 1.6)
(drawings 0)
(tracks 0)
(zones 0)
(modules 2)
(nets 7)

(page A4)
(0 F.Cu signal)
(1 In1.Cu signal)
(2 In2.Cu signal)
(31 B.Cu signal)
(33 F.Adhes user)
(35 F.Paste user)
(37 F.SilkS user)
(39 F.Mask user)
(40 Dwgs.User user)
(41 Cmts.User user)
(42 Eco1.User user)
(43 Eco2.User user)
(44 Edge.Cuts user)
(45 Margin user)
(47 F.CrtYd user)
(49 F.Fab user)

(last_trace_width 0.25)
(trace_clearance 0.2)
(zone_clearance 0.508)
(zone_45_only no)
(trace_min 0.2)
(segment_width 0.2)
(edge_width 0.1)
(via_size 0.6)
(via_drill 0.4)
(via_min_size 0.4)
(via_min_drill 0.3)
(uvia_size 0.3)
(uvia_drill 0.1)
(uvias_allowed no)
(uvia_min_size 0.2)
(uvia_min_drill 0.1)
(pcb_text_width 0.3)
(pcb_text_size 1.5 1.5)
(mod_edge_width 0.15)
(mod_text_size 1 1)
(mod_text_width 0.15)
(pad_size 1.5 1.5)
(pad_drill 0.6)
(pad_to_mask_clearance 0)
(aux_axis_origin 0 0)
(visible_elements FFFFFF7F)
(layerselection 0x00030_80000001)
(usegerberextensions false)
(excludeedgelayer true)
(linewidth 0.100000)
(plotframeref false)
(viasonmask false)
(mode 1)
(useauxorigin false)
(hpglpennumber 1)
(hpglpenspeed 20)
(hpglpendiameter 15)
(hpglpenoverlay 2)
(psnegative false)
(psa4output false)
(plotreference true)
(plotvalue true)
(plotinvisibletext false)
(padsonsilk false)
(subtractmaskfromsilk false)
(outputformat 1)
(mirror false)
(drillshape 1)
(scaleselection 1)
(outputdirectory “”))

(net 0 “”)
(net 1 “Net-(L1-Pad1)”)
(net 2 “Net-(L1-Pad2)”)
(net 3 “Net-(P1-Pad2)”)
(net 4 “Net-(P1-Pad3)”)
(net 5 “Net-(P1-Pad4)”)
(net 6 “Net-(P1-Pad5)”)

(net_class Default “This is the default net class.”
(clearance 0.2)
(trace_width 0.25)
(via_dia 0.6)
(via_drill 0.4)
(uvia_dia 0.3)
(uvia_drill 0.1)
(add_net “Net-(L1-Pad1)”)
(add_net “Net-(L1-Pad2)”)
(add_net “Net-(P1-Pad2)”)
(add_net “Net-(P1-Pad3)”)
(add_net “Net-(P1-Pad4)”)
(add_net “Net-(P1-Pad5)”)

(module Airbios_Libraries:PCB_inner2 (layer In2.Cu) (tedit 577A770C) (tstamp 577A78A0)
(at 148.5011 105.0036)
(path /5771908F)
(fp_text reference L1 (at 0 0) (layer F.SilkS) hide
(effects (font (thickness 0.3)))
(fp_text value INDUCTOR (at 0.75 0) (layer F.SilkS) hide
(effects (font (thickness 0.3)))
(fp_poly (pts (xy 0.163483 -7.55548) (xy 0.332189 -7.548857) (xy 0.513822 -7.538286) (xy 0.52899 -7.537271)) (layer In2.Cu) (width 0.1))
(pad 1 smd circle (at 0.7 -7.5) (size 0.4 0.4) (layers In2.Cu)
(net 1 “Net-(L1-Pad1)”))
(pad 2 smd circle (at 0 -7.6) (size 0.4 0.4) (layers In2.Cu)
(net 2 “Net-(L1-Pad2)”))

(module Pin_Headers:Pin_Header_Straight_1x06 (layer F.Cu) (tedit 0) (tstamp 577A78B5)
(at 148.5011 105.0036)
(descr “Through hole pin header”)
(tags “pin header”)
(path /57719018)
(fp_text reference P1 (at 0 -5.1) (layer F.SilkS)
(effects (font (size 1 1) (thickness 0.15)))
(fp_text value CONN_01X06 (at 0 -3.1) (layer F.Fab)
(effects (font (size 1 1) (thickness 0.15)))
(fp_line (start -1.75 -1.75) (end -1.75 14.45) (layer F.CrtYd) (width 0.05))
(fp_line (start 1.75 -1.75) (end 1.75 14.45) (layer F.CrtYd) (width 0.05))
(fp_line (start -1.75 -1.75) (end 1.75 -1.75) (layer F.CrtYd) (width 0.05))
(fp_line (start -1.75 14.45) (end 1.75 14.45) (layer F.CrtYd) (width 0.05))
(fp_line (start 1.27 1.27) (end 1.27 13.97) (layer F.SilkS) (width 0.15))
(fp_line (start 1.27 13.97) (end -1.27 13.97) (layer F.SilkS) (width 0.15))
(fp_line (start -1.27 13.97) (end -1.27 1.27) (layer F.SilkS) (width 0.15))
(fp_line (start 1.55 -1.55) (end 1.55 0) (layer F.SilkS) (width 0.15))
(fp_line (start 1.27 1.27) (end -1.27 1.27) (layer F.SilkS) (width 0.15))
(fp_line (start -1.55 0) (end -1.55 -1.55) (layer F.SilkS) (width 0.15))
(fp_line (start -1.55 -1.55) (end 1.55 -1.55) (layer F.SilkS) (width 0.15))
(pad 1 thru_hole rect (at 0 0) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS)
(net 1 “Net-(L1-Pad1)”))
(pad 2 thru_hole oval (at 0 2.54) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS)
(net 3 “Net-(P1-Pad2)”))
(pad 3 thru_hole oval (at 0 5.08) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS)
(net 4 “Net-(P1-Pad3)”))
(pad 4 thru_hole oval (at 0 7.62) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS)
(net 5 “Net-(P1-Pad4)”))
(pad 5 thru_hole oval (at 0 10.16) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS)
(net 6 “Net-(P1-Pad5)”))
(pad 6 thru_hole oval (at 0 12.7) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS)
(net 2 “Net-(L1-Pad2)”))
(model Pin_Headers.3dshapes/Pin_Header_Straight_1x06.wrl
(at (xyz 0 -0.25 0))
(scale (xyz 1 1 1))
(rotate (xyz 0 0 90))


Those are the settings in the python script from above to get your spiral as copper tracks:

I’ll take your file in the evening (gotta run now) and put it in there, unless you get it done yourself by then.

1 Like

Is this the principle you’re trying to follow?

I don’t think PCBnew is OK with having a SMD pad on an inner copper layer defined by a footprint. There is no such option for the pad.
You said you manually edited the footprint file to move it to one of the inner layers, correct?
PCBnew expects tracks and maybe vias being on inner layers, but not footprints per se.

So, if you want to be able to load your file again, convert the In2.Cu layer settings back to F.Cu or B.Cu.

Now, onto how to do this so PCBnew hasn’t got a hissy fit I’d suggest getting tracks into the inner layers and then connecting them up to your 6 pin footprint with DRC disabled. After that’s done you enable DRC again and the tracks should stay with their respective nets and we can add the inner via.
Does that sound like a plan?
How important is it to you that you can select&drop the inductive antenna as a footprint (be aware that this might collide with KiCAD philosophy)?

#Anyone who is involved with KiCAD development who could share his opinion on the current philosophy about things like that?

The thing you need to remember is that vias won’t come correctly without DRC enabled and the tracks being associated with the correct nets.
So in this case I did:

  • open the file with just the 6 pin header in it in a text editor
  • copying the content of this spiral.txt (299.8 KB) into it
  • open the file in pcbnew and disabling DRC
  • connecting the outer spiral ends to the 6 pin connector
  • enabled DRC again
  • reloading/restarting pcbnew (making sure the spiral tracks have gone through a sanity check by pcbnew and are accepted now)
  • putting in the burried via (after deleting the inner short tracks which are now horizontal) to get more space for the via

PCB_inductive_antenna.kicad_pcb (296.9 KB)

This is the code that puts out 2 spirals on the 2 inner layers, how they appear in the spiral.txt file up there: (6.2 KB)


It took me half a dozen reads, but I mostly get what you are doing and it’s cool and it accomplishes the purpose a different way than creating a custom footprint. It’s more elegant than my original approach. BTW, the graphics in your prior post are wonderful.

One set of questions remain. How do I run your script? Are you running from the Python console inside Pcbnew or a standalone python environment?


I’m answering my own question for anyone who views this thread and is not familiar with Python. This script can be run outside PcbNew. I ran it on Linux and redirected the output to a text file:

python > outputFile.txt

It worked like a champ!

1 Like

H together,
it is nice to learn how to make a spiral, but I’m getting interested in the oval coil shape
who can help me to know what I should modify and how to get it