I am using my laser etcher to make precision cuts in printed circuit boards, and need to calibrate my galvo lens accurately. I describe here a fast and easy procedure that gives about ±0.05mm uncertainty. The key features are:
-
a custom burn file for acrylic that accurately etches 1.4mm diameter holes at calibration points,
-
measuring the distances with a digital caliper, sending the numbers via a bluetooth keypad to a
-
python program that automatically updates the parameters in Lightburn, so no typing mistakes.
I tried using the Lightburn calibration routine in an iterative manner to improve the accuracy of the calibration. However, this did not work and I was even unable to remove a visible bulge. I then wrote a simple Python algorithm that updates the calibration by iteration. I found it converges rapidly and gives very low errors. I explain how it works later in the document.
This photo of the digital-caliper measurement shows how the caliper tips self-center into the holes. The bluetooth link button is under my right index finger. To self-center reproducibly, push down on the caliper with the left hand between the tips, and wiggle the wheel back and forth with the right thumb.
Purchase the following 3 parts, for about $100 total:
-
6”x6”x1/8” black acrylic sheets, by Adrattnay; Amazon , $9 for 5 sheets.
-
8” digital calipers with a bluetooth link, by iGaging; Amazon, $76. Don’t buy expensive calipers that need a special interface; any added accuracy won’t matter.
-
Centerline gauge-set that screws onto the calipers to measure hole distances, HHIP 4100-0040; Amazon, $21.
Setup and calibrate the above parts, and ready Python:
-
With the burn file linked below “GalvoBurnCal”, adjust the burn setting to give a cylindrical hole that is deep enough so that the tip of the centerline gauge does not bottom out of the hole. My settings are for a 6W UV laser, the ComMarker Omni X with the 150x150mm lens.
-
Install the centerline gauge on the calipers, making sure that the tips of the two cones are level.
-
Measure the offset of the centerline gauge. This can be done with another set of calipers, but the easiest way is to measure with a pair of holes drilled by a CNC with a known separation. My measurement is longer than the design value, so I use an additive offset of -0.33mm.
-
Setup the bluetooth connection via instructions with the caliper, which installs as a bluetooth keyboard on your computer. Test the bluetooth keypad interface by sending measurements to a text file on your computer: open any text file, and when pushing the bluetooth button on the caliper you should see the measured value with a return are “typed” into the text file.
-
For MAC OS, I had to grant terminal accessibility by going to “Systems setting / Privacy & Security / Accessibility”, and then turned on accessibility.
-
For windows, it connects with “add device” in bluetooth.
-
-
Set the Python file path to “prefs” for updating the LightBurn parameters. In LightBurn, click on “File / Preferences / Open Prefs Folder” to open a folder where “prefs” is located. Right click on the file path at the top, and choose “copy address”. Then paste this address in the Python program “GalvoCalibrate” for the FilePath, as text. My Python program sets this as shown here, where I have added the r and two quotes for formating:
FilePath = r“C:\Users\jmart\AppData\Local\LightBurn”
The initial calibration starts by selecting in Lightburn the “Laser Tools / Device Setting”, and then selecting the “Galvo and Basic Settings” tab. Set all the lens parameters on the bottom left to 1, and then adjust the “Scale” settings so that the burn pattern “GalvoBurnCal” with 120mm spacing fits on your acrylic sheet. For my galvo, it is 80%.
Iterative calibration uses the following procedure:
-
In LightBurn, burn “GalvoBurnCal” as a calibration test pattern into the acrylic sheet with your current LightBurn parameter settings.
-
In Python, open “HoleCal.txt”, a text file to be used for data entry. It is in the same folder as “GalvoCalibrate”. Click on this file, and enter the offset (for example -0.33mm) as the first-line entry. The cursor should be on the 2nd line.
-
Measure the 14 parameters in the sequence H1-H6, V1-V6, and D1-D2, clicking to transmit the bluetooth entry and checking that they are being entered correctly in the “HoleCal.txt” file. Unlike a ruler measurement, this step is easy and takes about 1-2 minutes..
-
Close Lightburn. This allows the “prefs” file to be updated properly in the next step.
-
In Python, run “GalvoCalibrate”. The Python program will analyze the “HoleCal.txt” data to measure the scale, bulge, skew and trapezoid. Enter “y” to read the current “prefs” file to update and save these parameters for the next time you run LightBurn.
2 or 3 iterations are typically needed to converge to ±0.03mm errors, as displayed by the “Galvo Calibrate” program.
Results. The “GalvoCalibration” program displays the parameters from the measurements, and computes the change in the parameters to iterate. It outputs the following, where the first measurements are errors in millimeters, and the second is the change in parameters going to Lightburn.
- The initial calibration as described above. Here, you see scale errors from 60mm, and significant bulge in Y of 1.95mm
Measurements (mm)
Avg. X,Y = 59.7367 61.5150
Bulge X,Y = -0.2075 1.9500
Skew = 0.0250
Trap X,Y = -0.0325 -0.0500
Change in LightBurn parameters (dim’less)
Delta S_X,Y = 0.0035 -0.0202
Delta B_X,Y = 0.0083 -0.0707
Delta Skew = 0.0003
Delta T_X,Y = 0.0008 -0.0012
- After the 3rd iteration, an additional measurement shows a very accurate calibration, to the precision of the caliper measurements.
Measurements (mm)
Avg. X,Y = 60.0300 60.0333
Bulge X,Y = -0.0300 0.0425
Skew = -0.0150
Trap X,Y = 0.0400 -0.0175
- Here are the settings of the LightBurn parameters after the 3rd calibration
The algorithm. The “GalvoCalibration” program computes the following measurements from the 14 inputs H1-H6, V1-V6 and D1-D2, as defined in the Lightburn lens calibration.
Sx = (H1+H2+H3+H4+H5+H6)/6 # average x, for scale
Sy = (V1+V2+V3+V4+V5+V6)/6 # average y
Bx = ((H1-H3)+(H5-H3)+(H2-H4)+(H6-H4))/4 # bulge x
By = ((V1-V2)+(V3-V2)+(V4-V5)+(V6-V5))/4 # bulge y
K = (D1-D2)/4 # skew x and y
Tx = ( (H1-H5)/2 + (H2-H6)/2 )/2 # trapezoid x
Ty = ( (V1-V3)/2 + (V4-V6)/2 )/2 # trapezoid y
It’s a problem that we do not know how LightBurn defines its parameters. To relate the two, I run calibration measurements where I change the LightBurn parameters by +0.1, burn the file, and then determine the difference between it and the unchanged values of my parameter measurements as defined above. For a change in LightBurn of Bulge X by 0.1, I find my Bx changed by 2.5075mm:
Scale X,Y = 1.6367 -0.0767
Bulge X,Y = 2.5075 0.3875
Skew = -0.1450
Trap X,Y = 0.0025 -0.0925
I found that ignoring the cross-coupling terms, for example Scale X or Bulge Y in this example, still gives good results. These cross-corrections are small, and do not matter because we are iterating the calibrations. Here, I do not try to get all the calibrations correct in one step. This is a general principle why feedback works.
A change in the LightBurn Bulge X parameter changes my Bx measurement by 2.5075mm. From this number, I can then compute the needed change in the LightBurn parameter DeltaBx when iterating the calibrations, as shown below. Here the scaling factors are all obtained by doing the above calibrations for each parameter. The scale corrections DelSx and DelSy are a simple expression, but I found that adjusting it by 0.7 gives faster convergence. This is probably due to the non-linear angular dependence of distance, as discussed later.
DelBx = -0.1*(Bx/2.51)
DelBy = -0.1*(By/2.76)
DelKx = +0.1*(K /9.19)
DelKy = +0.1*(K /9.19)
DelTx = -0.1*(Tx/3.93)
DelTy = +0.1*(Ty/4.14)
DelSx = (1-Sx/60)*0.7
DelSy = (1-Sy/60)*0.7
The problem: angle non-linearity. When I burn a test calibration of an array of holes with 10mm spacing, I see non-uniform spacing. This can even be seen by eye in the photograph below. This comes from the geometry of the galvo lens writing to a horizontal surface, since the Lightburn software controls only the angle of the galvo lens.
For this geometry, the angle theta is converted to a horizontal distance d’ by the formula
d’ = f tan(theta)
where f is the focal length of the lens, specified as 231mm for my system. LightBurn is calibrated using the approximation that the angle theta is small and given by theta = d/f, giving d’ = d, where d is the designed distance. Expanding the tangent formula in a Taylor series to the next correction, one finds
d’ = d[ 1 + (⅓)(d/f)^2 ]
This idea can be tested by measuring the distance between the center mark and holes at varying distances. From the above formula, the ratio of the measured d’/d versus d should have a parabolic shape, with a curvature that corresponds to approximately the focal length of the lens. This is plotted below, and the best fit of the focal length 240mm is close to that specified for my lens. The calibration was done at 60mm, where the ratio is 1 as expected. There is a significant change in the spacing near the origin, about 2%.
It would be useful for LightBurn to include this angle correction, as then the lens could be further calibrated to have very low distortion for precision etching.
Software
-
Lightburn calibration file “GalvoBurnCal.lbrn2 GalvoBurnCal.lbrn2 (102.6 KB)
-
Python program “GalvoCalibrate.py” GalvoCalibrate.txt (3.6 KB)
-
Example python data “HoleCal.txt”
-0.33
60.31
60.47
60.34
60.42
60.28
60.34
60.42
60.42
60.42
60.30
60.25
60.37
170.02
170.08



