'M830 a G83 canned drilling macro'''''''''''''''''''''''''''''''''' (c) Mick Grant 16122009-0930'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''M830.M1s' Peck drilling macro with retraction between pecks to ZMax value in R parameter' Works for Lathe or Mill depending upon what axis G code is in .nc file (G17 or G18)''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''Dim berror As BooleanDim linestring As StringSub Main()Message ("") 'clear the message line'declare variablesDim diametermode, abs_mode, params_found, metric_mode, inch_mode, Lathe, Mill As BooleanDim filesys, filetxt, lastline, oldline As StringDim currentfile As StringDim XPos, YPos, ZMax, Peck, Pause, Dwell, Feed, XInc, YInc, Holes, retval, LineNo, CurrentLine, P As DoubleDim ZMin As VariantDim NumPecks, w As VariantDim ParamArray(12) As StringDim Params(12) As DoubleDim s1, s2, v As StringConst ForReading = 1, ForWriting = 2, ForAppending = 8Dim x, y, z, u, t As Integer' params passed in commented out M830 line eg ;M830 X0 Y0 Z-10 R10 Q2.5 W0.5 P0 D0 F10 I20 J0 L4' all params are required, macro will decide which to use depending upon axis mode and L value' Must ensure that G4 delay times are set in config to same as you use i.e. milliseconds or seconds' If you enter P3000 and it is not set to milliseconds, you will have a long wait!!!ParamArray(0) = "X"	ParamArray(1) = "Y"ParamArray(2) = "Z"ParamArray(3) = "R"ParamArray(4) = "Q"ParamArray(5) = "W"	' user selected distance to return short of last peckParamArray(6) = "P"	' Pause is the delay at the top of retraction ( to dislodge chips from drill etc )ParamArray(7) = "D"	' Dwell is delay at bottom of holeParamArray(8) = "F"ParamArray(9) = "I"	' X incrementParamArray(10) = "J"	' Y incrementParamArray(11) = "L"	' Holesendreached = falseberror = falseP = Param1()		' the line number of ;M830 parameters''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''currentfile = FileName() 'undocumented way to get the currently loaded nc fileSet filesys = CreateObject("Scripting.FileSystemObject")Set filetxt = filesys.OpenTextFile(currentfile, ForReading, True)	Do While(filetxt.AtEndOfStream <> true )		linestring = filetxt.ReadLine()		StripComments        ' strip comments to prevent a reference to G17 or G18 in them being mistaken for code		If Len(linestring) Then			If InStr(1, linestring,"G17") > 0  Then 				Mill = true			End If			If InStr(1, linestring,"G18") > 0  Then ' not safe to assume if not G17 must be G18				Lathe = true			End If		End If	Loopfiletxt.Close      ' can't find a rewind function as in C, so close the file object and open another for next parseIf Lathe = true And Mill = true Or Lathe = false And Mill = false Then	Message ("Axis mode not properly set - G17 or G18")	berror = true	GoTo FinishEnd IfSet filesys = CreateObject("Scripting.FileSystemObject")Set filetxt = filesys.OpenTextFile(currentfile, ForReading, True)'''''''''''''''''''''' Parse the M830 line '''''''''''''''''''''''''''''''''''''''''''''''''''''''params_found = false	Do While( filetxt.AtEndOfStream <> true )		linestring = filetxt.ReadLine()		If InStr(1, linestring,"N" &P) = 1 And InStr(1, linestring,";M830") > 0 Then		params_found = true			' eg ;M830 X0 Y0 Z-10 R10 Q2.5 W0.5 P0 D0 F10 I20 J0 L4		UCase(linestring)		' convert to uppercase for ease of parsing		v = linestring + " "    ' add trailing space so searching works   		u = 0		While(u < 12)			x = InStr(1, v, ParamArray(u))			If x Then    				y = InStr(x, v, " ")     				s1 = Mid( v, x+1, y - (x+1))    				RTrim(s1)    				Params(u) = Val(s1)			Else				berror = true				Message(ParamArray(u) & " value not set")				GoTo Finish			End If			u = u + 1		Wend		End If		If params_found = true Then			Exit Do		End If	Loop 	'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''If params_found = false Then	berror = true	message ("Error - M830 parameters  not found in GCode")	GoTo FinishEnd If''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''	Transfer parameters to variables''''''''''''         XPos YPos ZMin ZMax Peck Waver Pause Dwell Feed XInc YInc Holes =  X0 Y0 Z-10 R10 Q2.5 W0.5 P0 D0 F10 I20 J0 L4Xpos = Params(0)YPos = Params(1)ZMin = Params(2)ZMax = Params(3)Peck = Params(4)Waver  = Params(5)Pause = Params(6)Dwell = Params(7)Feed = Params(8)XInc = Params(9)YInc = Params(10)Holes = Params(11)''''''''''  Sanity checks'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''diametermode = IsDiameter()  ' Returns a non-zero value if Mach3 is in Diameter mode otherwise zero for radius mode. abs_mode = GetOEMLed(48)  ' is the Abs LED lit?metric_mode = GetOEMLed(802)   ' is it in metric modeinch_mode = GetOEMLed(801)    ' sanity check must be one or the otherIf Lathe = true Then'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' We change to G90 anyway, but this just gives the user a clue that they should be in absolute mode' with all co-ordinates being fixed locations not offsets' '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''	If abs_mode = false Or diametermode = false Then 		Message "Incremental and Radius modes not supported"    		berror = true			GoTo Finish	End IfEnd IfIf (metric_mode = false And inch_mode = false) Or (metric_mode = true And inch_mode = true) Then	Message "Dimension units not set (G20/G21)"	berror = true		GoTo FinishEnd If' Check Sanity of parameters etc here''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''If Holes = 0 Then	' Must be one hole, we need pos number for while() loop to work	Holes = 1End IfIf ZMin >= 0 Or ZMax <= 0 Then	Message ("Error Z => 0 or R <= 0")	berror = true	GoTo FinishEnd If
 ' use variant to convert negative signed number to posIf InStr(1, ZMin,"-") = 1 Then		y = Mid(ZMin,2, Len(ZMin - 1))	End IfIf y < Peck Then	Message ("Peck distance greater than drill depth")	berror = true	GoTo FinishEnd If''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''NumPecks = (y / Peck) ' depth divided by Peck depth''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Debug - this is how to write a log to get a code dump'Set filesys = CreateObject("Scripting.FileSystemObject")'Set filetxt = filesys.OpenTextFile("C:\machlog.txt", ForWriting, True)' swap each code s1 for filetxt.WriteLine(s1)'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Peck drilling loop runs inside another loop controlled by L parameter (number of holes)' Allows holes to be drilled repeatedly at incremental X and Y positions' from last hole, but only in one plane.' If several rows of holes are required for instance, make a call to M380 for each row ' of L holes'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''x = 0z = 0t = 0w = 0s1 = "" 	code "G90"	s1 = "G0 X" &XPos	If Mill = true Then		s1 = s1 + " Y" &YPos	End If	s1 = s1 + " Z" &ZMax	code s1		' go to start position XPos (YPos) R				While(IsMoving())		sleep 10    ' save repeated polling whilst move taking place	Wend		While(t < Holes)		Do While ( x < NumPecks ) 	   		z = z + Peck    			'''''''''''''''''''' drill to peck depth    			If z > y Then    				z = y       ' if NumPecks is not whole number, prevent over drilling on last loop    			End If    						s1 = "G1 Z-" &z 			s1 = s1 + " F" &Feed 			If Dwell > 0 Then				s1 = s1 + " G4 P" &Dwell			End If					code s1			While(IsMoving())				sleep 10    			Wend			''''''''''''''''''''''' retract to ZMax			s1 = "G0 Z" &ZMax 			If Pause > 0 Then				s2 = "G4 P" &Pause			End If			code s1			While(IsMoving())				sleep 10    			Wend			If Len(s2) Then		'' the G4 Pxx was being ignored by Mach after G0 retract but not after G1 drill				code s2		'' no idea why, presume G0 cancels any dwell				s2 = ""			End If						'''''''''''''''''''''''  check if done and break out if so				If z >= y Then				GoTo Repeat  			End If			''' If not, then rapid in to a fraction short of last peck by W amount					w = z - Waver			 ' use variant to convert negative signed number to pos
			 ' avoiding Z--0.5 situation			If InStr(1, w,"-") = 1 Then					w = Mid(w,2, Len(w - 1))				End If									s1 = "G0 Z-" &w 				code s1			While(IsMoving())				sleep 10    			Wend					x = x + 1		LoopRepeat:				t = t + 1		If t < Holes Then		' Holes is at least 2, move to next one			code "G91"		' incremental movement			s1 = "G0 X" &XInc			If Mill = true Then				s1 = s1 + " Y" &YInc			End If			code s1		' go to next incremental position XInc (YInc) R			While(IsMoving())				sleep 10    			Wend			code "G90"		' back to absolute again			x = 0			z = 0		End If	Wend''' Debug 'filetxt.Close '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''Finish:Erase ParamArrayfiletxt.CloseIf berror Then		' ensure we do not try to continue drilling if error condition	code "M5"       	code "G80"		code "M9"	code "M30"End IfEnd Sub Main         ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''Subroutines''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Strip the comment lines because Mach does not count them and cannot get current line correctly otherwise' also danger that if reference is made to macro or G code in comments could confuse parsingSub StripComments()Dim x, y As Integer	Trim(linestring) ' remove leading and trailing whitespace	x = InStr(1, linestring, ";") ' get rid of comments which caused probs	If x  And InStr(1, linestring,";M831") = 0 Then 		' dont want to remove parameters line			If x = 1  Then  ' whole line is commented out, so nothing to do			linestring = ""			Exit Sub		Else			linestring = Left(linestring, x -1)		End If	End If		x = InStr(1, linestring, "(" ) ' get rid of parenthesis too	If x Then 		If x = 1  Then  ' whole line is commented out, so nothing to do			linestring = ""			Exit Sub		Else			linestring = Left(linestring, x -1)		End If	End IfEnd Sub                     ' Strip the line numbers, spaces and tab chars to leave the GcodeSub StripNums()Dim x, y As IntegerTrim(linestring) ' remove leading and trailing whitespacex = InStr(1, linestring, " ")y = InStr(1, linestring, Chr(9))  'only way I can find of doing what would just be "\t" in C++If (x < y Or y = 0) And x > 0 Then	linestring = Right(linestring, Len(linestring) - x)Else	If y > 0 Then		linestring = Right(linestring, Len(linestring) - y)	Else		If InStr(1, linestring, "N") > 0 Then			Print "Malformed GCode" &Chr(13) & "No space or tab after line number" & Left(linestring, 3)		Else			Print "Malformed GCode" &Chr(13) & "No valid line number detected"		End If		berror = true		Exit Sub	End IfEnd IfLTrim(linestring)linestring = linestring & " "	' trailing space to enable other search routines to workEnd Sub                        
