In this part I focused on creating of the simple script which allows to execute g-code created by Autoleveller application to collect information about thickness of the PCB in different measurement points and use it to generate corrected g-code. The connection with the devices is as at following diagram:
The script is written in bash and setups serial connection with CNC machine and Z axis probe. One of connectors of Z axis probe is connected to PCB plate and second to the spindle. Below there is diagram of script flow:
At the beginning of script are few basic checks of required arguments and connections (I need add more in final solution). The flow is following:
- setup the custom descriptors for read/write for each device: CNC and Z-probe,
- read one line of source g-code,
- if it is not a z axis leveling command then this line is redirected to CNC machine (In my machine is required to send additional "M105" command to establish and keep connection due the firmware is mainly for 3D printer),
- otherwise is started Z-axis probing procedure which has following steps:
- read the status of Z-axis probe circuit,
- if it is open then switch to relative positioning and perform one step down by 0.01 mm in Z axis,
- if we hit the PCB plate the read the values of positions and switch back to absolute positioning,
- positions are stored in file and next line of g-code is performed.
Here is the source code:
#!/bin/bash
if [ $# -ne 2 ]; then
echo "Usage: zProbe.sh input.gcode probes.txt"
exit 1
fi
PROBETTY=`ls -l /dev/serial/by-id/ | grep "Digispark_Serial" | grep -o "tty.*"`
if [ -z "${PROBETTY}" ]; then
echo "There is no Z axis probe attached."
exit 1;
fi
exec 4</dev/${PROBETTY} 5>/dev/${PROBETTY}
stty -F /dev/${PROBETTY} 115200 raw -echo
PRINTTTY=`ls -l /dev/serial/by-id/ | grep "1a86_USB2.0-Serial" | grep -o "tty.*"`
if [ -z "${PRINTTTY}" ]; then
echo "There is no printer attached."
exit 1;
fi
exec 6</dev/${PRINTTTY} 7>/dev/${PRINTTTY}
stty -F /dev/${PRINTTTY} 115200 raw -echo
sendCommand() {
local COMMAND="$1"
local TIMEOUT="$2"
if [ -z ${TIMEOUT} ]; then
TIMEOUT=0.4
fi
echo "${COMMAND}" >&7
while read -n 100 -t ${TIMEOUT} VALUE <&6; do
echo ${VALUE}
done
echo "M400" >&7
while read -n 100 VALUE <&6; do
echo ${VALUE} | grep -q "ok"
if [ $? -eq 0 ]; then
break;
fi
done
}
probe_zlevel() {
echo "P" >&5
read -n 10 -t 5 VALUE <&4
if [ "${VALUE}" == "O" ]; then
sendCommand "G0 Z-0.01" "0.005" > /dev/null
return 1;
elif [ "${VALUE}" == "C" ]; then
return 0;
else
echo "ERROR"
return -1;
fi
}
sendCommand "M105" > /dev/null
while read line; do
echo ${line} | grep -q "G31 Z-1 F100"
if [ $? -eq 0 ]; then
STATUS=1
sendCommand "M105" > /dev/null
sendCommand "G91" > /dev/null
while [ ${STATUS} -ne 0 ]; do
probe_zlevel
STATUS=`echo $?`
if [ ${STATUS} -eq 0 ]; then
POSITION=`sendCommand "M114"`
echo "${POSITION}" | grep -o "X:.* Y:.* Z:.* " >> $2
sendCommand "G90" > /dev/null
break
elif [ ${STATUS} -eq -1 ]; then
echo "ERROR"
sendCommand "G28" > /dev/null
exit 1
fi
done
else
sendCommand "${line}" > /dev/null
fi
done < $1
I have performed before few tests without leveling and there were difference in cutting of copper layer. I have created a simple schematic which uses 12 mils width paths.
I have used FlatCAM to configure milling with V shape 30 degrees 0.1 mm spindle. The finale g-code is configured to cut with 0.1mm thin.
Then I used the Autoleveller to generate g-code for collect the information about the PCB plate.
Here is output from Autoleveller with collected probes from my PCB plate.
With this information I was able to generate corrected g-code and perform milling. From my initial observations it looks like that I need to spend now more time on finding proper settings e.g. cut depth to get best results. Additionally it will be nice to rewrite this script to other language code e.g. C/C++ with adding more strict checks during performing. Below sample results and video (was speed up 4 times) from probing and milling.










Top Comments