# Using a PCB trace as a heater / Hilbert Curves

I'm considering making a PCB to use as a heater for a 3d printer bed. This has been common practice for ~10 years (https://www.thingiverse.com/thing:3919).

I was playing around with KiCad and python, and made a PCB trace that could (in theory) be infinitely long.

Steps:

• open KiCad, open the symbol/footpad tool, create a new library, create a new component with two pad and 3-4 copper lines linking them, save
• open the library file in notepad++, and find the copper traces and pads
• replace them with the output of the following code, then save.


#create Hilbert Sequence
hilbert_seq = "a"
scale = 100
num_recurr = 5

for _ in range(num_recurr):
new_seq = ""
for char in hilbert_seq:
if char == "a":
new_seq += "-bF+aFa+Fb-"
elif char == "b":
new_seq += "+aF-bFb-Fa+"
else:
new_seq += char
hilbert_seq = new_seq
#print(hilbert_seq)

#create sequence of points
fwd_step = scale / (2**num_recurr-1)
lines = []
pos_x, pos_y = 0.0, 0.0
angle = 0
for char in hilbert_seq:

if char == "F":
if angle == 0: dx, dy = fwd_step, 0
if angle == 1: dx, dy = 0, fwd_step
if angle == 2: dx, dy = -fwd_step, 0
if angle == 3: dx, dy = 0, -fwd_step
new_x, new_y = pos_x+dx, pos_y+dy
lines.append( ((pos_x, pos_y), (new_x, new_y)) )
#print((angle, pos_x, pos_y, dx, dy, new_x, new_y))
pos_x, pos_y = new_x, new_y

elif char == "+":
angle = (angle+1) % 4
elif char == "-":
angle = (angle-1) % 4

#trace_width, fwd_step - space between traces for square, needs to be re-computed for circle
trace_width = 1 #fwd_step - 0.3
lines = [(l[0],l[1],trace_width) for l in lines]

#optionally, map into a circle with a very equiareal transform
import math
sqr2 = math.sqrt(2)
def to_circle(l):
#https://marc-b-reynolds.github.io/math/2017/01/08/SquareDisc.html
x1,y1,x2,y2,width = l[0][0],l[0][1],l[1][0],l[1][1],l[2]
x1_s,y1_s,x2_s,y2_s = 2*x1/scale-1,2*y1/scale+1, 2*x2/scale-1,2*y2/scale+1
#print((x1_s,y1_s,x2_s,y2_s))
def square_to_disc(x,y):
if x*x>y*y: return (math.copysign(1,x)*math.sqrt(2*x*x-y*y)/sqr2, y/sqr2)
else:  return (x/sqr2, math.copysign(1,y)*math.sqrt(2*y*y-x*x)/sqr2)
x1_plus_s, y1_plus_s = square_to_disc(x1_s, y1_s)
x2_plus_s, y2_plus_s = square_to_disc(x2_s, y2_s)
return ( (x1_plus_s*scale, y1_plus_s*scale), (x2_plus_s*scale, y2_plus_s*scale), width)
lines = [to_circle(l) for l in lines]

#output
def line_to_text(l):
return "(fp_line (start {start_x} {start_y}) (end {end_x} {end_y}) (layer \"F.Cu\") (width {width}) (tstamp 1947ea8e-3ea5-493b-ab1c-4e8c5a675398))".format(start_x=l[0][0], start_y=l[0][1], end_x=l[1][0], end_y=l[1][1], width=l[2])

for l in lines: print(line_to_text(l))



Output:

(Edit: This circuit is very typically connected to a 3D printer circuit, so a thermistor reads a temperature to a microprocessor, and the microprocessor turns the heating on/off, transformed 12V switched with a mosfet for the cheaper RAMPS 1.4 board, electrical mains through a solid state relay for high end systems. The objective is to reach a stated temperature with uniform heating (lookup 'heatbed temperature per filament'). Heat itself goes through several layers, PCB, then Kapton heat transfer tape, then a printing bed made of glass or PEI or some other material. PCB/heatbed geometry is dictated by the 3d printer's geometry. High power output is seen as convenient as it means the printer can startup more quickly.)

My question is:

• what are the constraints (electric field between traces, inter-trace, heat) ?
• does this have any practical application ? It raises the resistance of the trace.
• If you run the code in 'square' mode, the trace is dense (high fill factor). Transforming a square into a circle is non trivial (can't have a transformation that keeps angles and areas) so I didn't implement trace size variation. It also raises the question of whether the traces should be all equal width (even heating, some space lost) or space occupying with larger traces on the diagonals (uneven heating ?). In all cases for a circle, a spiral (that gets infinitely thinner with more turns) might be a better idea.
– Raph
Dec 30, 2021 at 7:01
• fractal patterns are sometimes used as antennas Dec 30, 2021 at 7:04
• some board houses don't like sharp corners, why not just do a two-start spiral like is used on some electric heating rings, you can build a fairly good approximation from quarter-circle arcs of steadily increasing radius. Dec 30, 2021 at 7:08
• Your fat Hilbert will see current crowding at the inside of every hairpin turn, so there will be many hot spots and cold spots. Dec 30, 2021 at 7:11
• The designs look really cool. I am not seeing the benefit compared to simple back-and-forth trace routing, though. Don't necessarily see a drawback either. Hot spots might not be an issue because copper is also a good thermal conductor. It will be hard to sustain a temperature gradient in a copper foil. Dec 30, 2021 at 7:23

I have some experience with PCB heaters using copper traces on polyimide (flex circuit) substrate. My goal has always been to use uniform copper trace width with consistent trace-to-trace spacing so that the heat generation is uniform. I follow a simple back and forth pattern. My heaters have been rectangles (more or less).

The starting point for the design is the power dissipation required. The available voltage is likely already fixed. So once you know how many Watts you need to generate, you can calculate resistance using R = V^2/P.

From there I select a trace width and length that achieves my target resistance at high fill factor of the available area.

Super accuracy should not be expected. Also, copper has a rather large positive temperature coefficient of resistance. Every 10 C raises the resistance by about 4%.

It should be mentioned that commercial heaters are often designed with nichrome foil instead of copper. Nichrome has much higher resistance, so coarser geometry is possible, and compared to copper, nichrome has resistance that is stable with temperature.

Obviously, the copper dimensions need to be reasonable and achievable by the board house. Trace widths and spaces probably need to be something like 0.15mm minimum. In the heaters I have designed, the traces were much wider than that.

Single layer copper on polyimide substrate seems to handle temperatures up to 120 C OK. Not sure how much higher than that you can go because I have not tried it.

• on R = V^2/P, to develop the formula a bit more: if the heater area is L x W, and I divide it into n sections, I have nL lengths of copper with width W/n (at most) and thickness T. So n^2 L/W/T = V^2/P. n (the number of back and forth traces) is approximately equal to sqrt(V^2 T H / P /L). A good starting point for the units is that 1m of 2oz/ft2 copper with width 0.25mm has 1ohm resistance (at 10C). A circle has 0.78 times the area of the square, so the approximate number of traces will be of the same order of magnitude.
– Raph
Dec 30, 2021 at 14:27
• I accepted your answer, along with Jasen's comments: fractals are for RF/antennas, and sharp turns will cause hotspots. Thank you.
– Raph
Dec 30, 2021 at 14:44

what are the constraints (electric field between traces

Yes. For every trace clearance there's a maximum voltage limit.

inter-trace

Obviously. The PCB house provides minimum trace clearance and trace width they can manufacture for a given product.

heat

Obviously as well. You can approximate your curve as if it was a uniform planar heater and use the thermal formulas for the PCB material in the application you use it for (i.e. typically you'd be heating something, and not merely still air).

does this have any practical application ? It raises the resistance of the trace

For a fixed voltage, heating power is inversely proportional to the resistance. Raising the resistance reduces the heat output. So the practical application is to provide a trace of sufficient resistance so that the desired thermal power output won't be exceeded.