Hello Guest it is December 12, 2024, 08:48:32 PM

Author Topic: Macro code problems  (Read 9451 times)

0 Members and 1 Guest are viewing this topic.

Macro code problems
« on: February 20, 2008, 06:56:33 PM »
Hi,
Wonder if anyone can help, please. I'm developing macros for Mach3. I've found several problems:

1. ELSEIF isn't recognised in the VB editor as a keyword (i.e. it appears as black, not blue text). I'm having to use ELSE IF, which then needs another nested END IF.

2. I frequently get multiple instances of the VB editor window open. As many as eight windows just pop open. I think it happens when I execute a macro with an error in it. Does that sound right?

3. I often get Syntax error messages (because my syntax may well be wrong), but the cursor doesn't go to the line in error. It can be very difficult to pin down the error if I've done a lot of editing. For instance, I thought I had to declare external functions as they appear in the documentation, such as SUB Code (text as string). That line would cause a syntax error with no pointer to the line.

4 If I declare my functions before the main code of the macro, the editor is happy, but my macro never executes.
For instance, if the file M1000.m1s consisted of nothing but:
Function Max(a,b) as double
  if a>b then Max=a else Max=b
End Function
Code "G1 Z" & Max(Param1(), Param2())

...the Code "G1.." line would never execute, whereas if I put all function declarations after the main code there is no problem. Is this a feature? Is it documented?

5. This isn't a problem, but a query: Sometimes I could implement some logic either in Gcode in the part file or in VB in a macro. Gcode logic is very primitive, though. For instance, you can code a 'For i=a to b' loop or 'if a>b then c' entirely in Gcode. Are there any guidelines / rules of thumb as to where to put one's logic? Portability of the Gcode isn't important to me. I'm very inclined to put all my logic in macros or to create wizards. Readability is far far better, for one thing, but I lose the ability to single step, I think. Or can I put breakpoints in macros that are invoked during execution of a part file?

Any thoughts very welcome
Chris Lusby Taylor

Offline poppabear

*
  • *
  •  2,235 2,235
  • Briceville, TN, USA
Re: Macro code problems
« Reply #1 on: February 20, 2008, 11:20:13 PM »
In a nut shell, your syntax is not correct.

You problems are vauge, post up the code (Unless it is secreat), then we can look at it, and repost it with corrections and comments for you.

G-code:  You can do Parameters and math equations, for logic you can call macros (M-Codes) from the G code lines, and you can put your data to logically manipulate in the macros and then continue processing the g code.

Vauge synatax errors are usally you left a End If, or a End Sub Off of the submain program in that case the cursor is vauge.

Multilple windows open if you continue to try and rerun code that is in error.

You just need to use Else only, if you need another branch then use Else If but in eigther case you have to use End If when done.

Or: Select Case for more complex choice/decisions.

scott
« Last Edit: February 20, 2008, 11:22:52 PM by poppabear »
fun times
Re: Macro code problems
« Reply #2 on: February 21, 2008, 11:20:21 AM »
Hi,
Thanks for the reply. I'm sorry if the problem appears vague. I tried to concoct the minimum code fragment that would illustrate my point. The code I posted wasn't copied from Mach3. It was typed in manually, so may well be wrong, though I can't see why.

But below I have the actual macro file that exhibits the problem I mentioned. If I merely move the declarations of the functions Max and Min to the end of the file it runs correctly. As it is, I get no error message when I press the green > button in the VB editor, but when my part file invokes it, no G code is output, so something is wrong.

My query about Elseif is exhibited by this file, too. It seems to execute correctly, but the word Elseif is black, not blue, in the editor.
The difference between Elseif and Else if is that elseif doesan't need its own end if.
I haven't surrounded my code with Sub Main...End Sub: Main as I can see no need to unless I want to exit prematurely.

None of the macros delivered with Mach3 uses Subs or Functions, so I can't see how others have done it.

My file M1000.m1s follows.
Thanks
Chris Lusby Taylor

'Macro for drawing a line clipped to x, y limits
'******   Revision 0.1 Feb 20 2008    *****
'Globals:
'#11=x min
'#14=x max
'#21=y min
'#24=y max
'#30 z safe
'#31 z engrave depth
'#15= border width
'
'Call with Pmmmm Qyyy Sccc where
'S=1 draw in X negative direction (am)
'S=2 draw in X positive direction (pm)
'S=3 position head at safe z on inner clip, X negative
'S=4 position head at safe z on inner clip, X positive

Option Explicit
Dim M,C,S,x1,x2,y1,y2 As Double

Function Max(ByVal a As Double, ByVal b As Double) As Double
 If a>b Then Max=a Else Max=b
End Function

Function Min(ByVal a As Double, ByVal b As Double) As Double
 If a>b Then Min=b Else Min=a
End Function

M = Param1()
C = Param2()
S = Param3()
Select Case S
  Case 1,3
     If M=0 Then
        y1=C
        y2=C
        x2=GetVar(11)
        x1=x2+GetVar(15)
     Else
     If M>0 Then
        y1=Max(GetVar(21)+GetVar(15),(GetVar(11)+GetVar(15))*M+C)
        x1=(y1-C)/M
        y2=Max(GetVar(21),GetVar(11)*M+C)
        x2=(y2-C)/M
     Else
        y1=Min(GetVar(24)-GetVar(15),(GetVar(11)+GetVar(15))*M+C)
        x1=(y1-C)/M
        y2=Min(GetVar(24),GetVar(11)*M+C)
        x2=(y2-C)/M
     End If
     End If
  Case 2,4
     If M=0 Then
        y1=C
        y2=C
        x2=GetVar(14)
        x1=x2-GetVar(15)
     ElseIf M<0 Then
        y1=Max(GetVar(21)+GetVar(15),(GetVar(14)-GetVar(15))*M+C)
        x1=(y1-C)/M
        y2=Max(GetVar(21),GetVar(14)*M+C)
        x2=(y2-C)/M
     Else
        y1=Min(GetVar(24)-GetVar(15),(GetVar(14)-GetVar(15))*M+C)
        x1=(y1-C)/M
        y2=Min(GetVar(24),GetVar(14)*M+C)
        x2=(y2-C)/M
     End If
End Select

Call Code("G0 X" & x1 & " Y" &y1)
If S<3 Then
   Call Code ("G1 Z" & GetVar(31))
   Call Code ("G1 X" & x2 &" Y" &y2)
   Call Code ("G1 Z" & GetVar(30))
End If



Offline stirling

*
  • *
  •  2,188 2,188
  • UK
    • www.razordance.co.uk
Re: Macro code problems
« Reply #3 on: February 26, 2008, 10:31:01 AM »
Hi Chris

1. elseif works as it should in VBA but no one seems to have told the CypressVB syntax editor "pretty printer" and so it stays black. FWIW I'd resist mixing 'elseif' with 'else if' if you value readability.

2. Can happen and more annoyingly the windows will stay "at the back" and will probably be called 'hidden' or something.

3. part 1: The Cypress debugger is nearly as sophisticated as its syntax editor.
   part 2: You should not declare Mach functions. like "code" for example.

4. Hmmmmm - I'm pretty sure this didn't used to be the case but I just checked and it does it on mine also. This would appear to be a feature and is of course quite wrong.

5. I know this is possible in a limited way in turbocnc for example but not (thankfully) in Mach - I've never understood why a "language" that has no means of input could possibly have any use for decision constructs. (OK there's G31 - but lets not go there)

Cheers

Ian

Re: Macro code problems
« Reply #4 on: February 26, 2008, 04:46:38 PM »
Quote
I haven't surrounded my code with Sub Main...End Sub: Main as I can see no need to unless I want to exit prematurely.

I have seen very strange things happen in VB when you dont make a sub. Some functions fail to execute outside a sub. I now make all button scripts to be a sub, with the last line a call to sub main. It has solved several strange problems.

I cannot explain why, I just know it works.
Re: Macro code problems
« Reply #5 on: February 28, 2008, 09:14:09 PM »
Thank you Stirling and Ron for your thoughts and analysis of my problems.
It seems I'm running into the quirks of Cypress VB, rather than merely my own incompetence.

I think I can make a good case for wanting decision logic in a non-interactive language. It's a question of when a decision can be made. Some at compile time, some not until execution time. Also, code can be a lot more compact if, for instance, a subroutine can execute differently depending on some run-time conditions it tests.
One example - I loop for various values of an angle. If the angle is 90 degrees I'd better know that before I try to take its tangent.
 I am engraving sundials. I've not yet tried writing a wizard, but am getting close. At the moment I'm putting my code structure and decision making in macros which, as I've discovered, have to use a Teach File to output Gcode that will get executed in a reliable order.
Back to my previous queries: I think I have the answers now. Thank you. I couldn't see any error in my file that declared functions before the main, and it seems there was none. But Ron's suggestion of wrapping the main code as a sub (which I've seen others use), then invoking it after the End Sub seems to work, so perhaps functions and subs behave differently.

Every day throws up new questions. For instance, today I found that an M30 immediately after a macro call may sometimes be ignored. To test a new macro I put two lines at the start of an existing .tap file. They were:
M2000 P1
M30
...
.. and I was surprised when the Toolpath display showed that the M30 had been ignored. By the way, is there any way to pass P, Q and S values into a macro under test in the VB Editor window?

I also found that G68 doesn't seem to work as advertised. It rotates the axes, but it also moves the origin to the given point. For instance G68 A10 B10 R45 rotates the axes 45 degrees anticlockwise about the point (10,10) and makes the point (10,10) the new origin. That's not what the Mach3 Guide says. Or is it just badly written? To me, rotating the coordinate system about a certain point leaves that point with the same coordinates it originally had, not (0,0). However, the way Mach3 behaves is useful and may be the industry standard way for G68 to behave. Perhaps it's just the manual that's misleading.

However, whereas G68 A10 B10 R45 followed by a G0 X0 Y0 moves to the point (10,10), if the R angle is zero the G68 behaves like G69, and G0 X0 Y0 moves to the previous (0,0) not (10,10). So, if the angle R is a parameter which might on occasion be zero, you'd better avoid ever setting the A and B values to non-zero. Much better to use G52 first, I think:
G52 X10 Y10
G68 A0 B0 R[expression]
will always work even if R=0.
But is any of this documented anywhere?
Best wishes
Chris