RepRapMicron Conductive Probe Experiments
Contents
Overview
This section contains notes on ad hoc research that explores the possibility of using a conductive probe to detect the position on the Z axis of the μRepRap build bed. This could be used during operation as a printer, but also aids investigating the characteristics and repeatability of the Block Stage mechanism. It is anticipated that some form of conductive area on a smooth glass slide would interact with a probe tip, a technique often used in GRBL CNC controllers referred to as the "Z Touch" feature. Fortunately, the current RepRapMicron iteration uses one of those.
A New Zealand 10c coin was used for testing as this was conductive and had relatively fine detail on it that would provide some height test data.
The slide holder design used (source files here) keeps the glass slide in place, and allows the contact probe ground wire to press on the object being probed. This has the added benefit of holding the sample in place too. It is hoped to eventually coat some or all of the slide with tin oxide and probe the surface height variations in both the RepRapMicron's mechanism and the slide's tin oxide surface.
CNCjs was used as the control program. This has a Probe function that will lower the probe until a contact is completed between the probe and a conductive surface, and a serial console that logs the result of the probe data. A python script was used to generate a grid of desired probe points as gcode, and this was sent to the RepRapMicron with CNCjs as if it were a standard gcode cutting file.
After the data was copied it was broken up into columns by using a LibreOffice spreadsheet and further reformatted to make it compatible with the Open Source graphing program gnuplot. Gnuplot was used to create a 3D map of the probe height data that could be rotated in 3D as well as be used for documentation purposes.
Implementation
A qualitative approach was taken to determine the level of accuracy and potential hardware requirements of more quantitative analysis. A robust but not particularly fine probe tip was selected. The substrate used was a worn New Zealand 10c coin - copper-plated steel approximately 20mm dia.
A single jumper pin was driven firmly into the wire slot in the probe tip holder until it was firmly in contact with the probe wire. A similar pin was soldered to the substrate grounding point: an anchored single strand copper wire with a single coil in it to provide some spring to the connection.These pins were then connected to the "Z Touch" pins on the GRBL RAMPS board with DuPont jumper leads. These pins correspond to the T2 thermistor connection and connect to the A5 pin on the ATmega CPU.
A Python script (see Addendum) was then written to create a grid of locations to probe. At each point the gcode commands:
G1 Z0.15 F100 ; Move to safe Z height G1 Xn.nnm Ym.mmm F100 ; Move to point G38.2 Z-2 F100 ; Probe point
were issued.
The gcode was then loaded into CNCjs as if it were a standard cutting file. The probe was positioned over a letter on the coin, the workspace X & Y were set to zero, and the height adjusted so that the probe was about 0.1mm above the coin. For the first time, this was able to be done with the CNCjs Probe function and it was immediately obvious that the process will cut out a lot of manual fiddling.
The CNCjs serial console was cleared, and the gcode executed. Each point took approximately 6 seconds to probe. An initial run of 5x5 points was tested and the resolution increased to eventually use a 30x30 grid with 0.05mm spacing. The probe results were then copied from the CNCjs serial monitor window.
Graphing the Results
The raw data was imported into a LibreOffice spreadsheet with cut & paste. By setting the column separators to comma and colon it was possible to break the probe result data into 5 columns. The columns without XYZ data were deleted. These columns were copy/pasted into a text file and then run through a bash script that separated the X scan lines with a blank line. This step is required by gnuplot when doing 3D surface maps. Obviously, this process could be better automated. Eventually a data series like this was produced and saved as a text .dat file:-4.775 -2.225 -1.25 -4.775 -2.175 -1.24 -4.775 -2.125 -1.24 ... -4.775 -0.825 -1.17 -4.775 -0.775 -1.17 -4.725 -2.225 -1.23 -4.725 -2.175 -1.22 ... -4.725 -0.825 -1.17 -4.725 -0.775 -1.17 -4.675 -2.225 -1.22 -4.675 -2.175 -1.21
This gnuplot script was then used to create a surface 3D graph:
set title "RepRapMicron Coin 'A' Scan 30x30 with 0.05mm Spacing" # set output 'dgrid3d.png' splot "30x30_pm1.dat" with pm3d pause -1The gnuplot graph can be rotated and examined in real time. Being able to examine the data from different angles was surprisingly enlightening. Eventually the letters "IRB" in a font 0.7mm high were mapped. A different slope was encountered on both X & Y axis, so the slope is very dependent on the probe position and a progressive mapping will be needed to correct for this.
Initial Data Analysis
A few things became immediately apparent once probe height data started becoming available:
Firstly, repeatedly probing the same point gave a height result +/- 3μm even using the relatively crude (but robust) probe tip. Typical data arrived in this format:
[PRB:0.000,0.000,-0.615:1] [PRB:0.000,0.000,-0.618:1] [PRB:0.000,0.000,-0.617:1]
Secondly, there appears to be a distinct slant on the 3D graph of very approximately 1:10 i.e. for every 10 units of movement on the X axis, the Z axis raises or lowers by 1 unit. A similar though lesser degree of slope applies to the Y axis and appears to be cumulative on the Z axis. This appears to be a feature of the flexure joints in the Block Stage but at first glance looks like it can be compensated for in software later.
Thirdly, I have the X axis direction reversed. Oopsie. Fix that later.
It would be interesting to process the data to remove this slope, and that might also provide insight into what kind of correction factors will need to be incorporated in the software.
For better data however, a more consistent surface and finer probe would be desirable. These are quite possible to achieve with equipment developed for the project so far, but during the initial stages it is best to use equipment that is (a) harder to damage, and (b) easier to replace.
Addendum
A few pieces of program script that were useful in this experiment and may be of general interest:
Test Grid Gcode
This is the python code that was used to generate the test grid:
# probe_grid_gcode.py - Generate gcode to us Z probe to probe out a specified grid
def probe_grid_gcode(grid_size, line_spacing, safe_z_height, feed_rate):
gcode = []
# Set initial position and safe Z height
gcode.append("G21 ; Set units to millimeters")
gcode.append("G90 ; Absolute positioning")
# Calculate starting point (center of the grid)
start_x = -((grid_size - 1) * line_spacing) / 2
start_y = -((grid_size - 1) * line_spacing) / 2
# Move along lines along X axis
for row in range(grid_size):
x_row = start_x + row * line_spacing
# Probe points along Y axis
for col in range(grid_size):
y = start_y + col * line_spacing
x = x_row
gcode.append("G1 Z{} F{} ; Move to safe Z height".format(safe_z_height, feed_rate))
gcode.append("G1 X{} Y{} F{} ; Move to point".format(x, y, feed_rate))
y = start_y + (grid_size - 1) * line_spacing
gcode.append("G38.2 Z-2 F{} ; Probe point".format(feed_rate))
gcode.append("G0 Z{}".format(safe_z_height))
gcode.append("M2 ; End of program")
return gcode
# Example usage
grid_size = 30 # ?x? grid
line_spacing = 0.05 # Distance between grid lines in mm
safe_z_height = 0.15 # Safe Z height in mm
feed_rate = 100 # Feed rate in mm/min
generated_gcode = probe_grid_gcode(grid_size, line_spacing, safe_z_height, feed_rate)
for line in generated_gcode:
print(line)
Inserting Line Breaks
This bash script was used to insert line breaks between successive scans of the X axis. It simply determines if the first parameter changes from the previous line, and if it does adds a blank line:
#!/bin/bash
# Check if a file argument is provided
if [ -z "$1" ]; then
echo "Usage: $0 filename"
exit 1
fi
# Initialize previous first parameter variable
previous_first=""
# Read file line by line
while read -r line; do
# Extract the first parameter (first column)
first_param=$(echo "$line" | awk '{print $1}')
# Check if the first parameter is different from the previous one
if [ "$first_param" != "$previous_first" ] && [ -n "$previous_first" ]; then
# Echo a blank line if it changes
echo
fi
# Echo the current line
echo "$line"
# Update previous first parameter
previous_first="$first_param"
done < "$1"