Hello Guest it is November 29, 2023, 11:10:59 AM

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - ChrisLT

Pages: 1 2 »
Chris I have a macroB macro from a fanuc that does about what you say. If you are interrested it has the numbers already gcoded and is laid out similar to your code. If you could convert it into a working MACH Mcode macro it would be very cool to have.

I also have a macro with all the letters coded out, maybe you could do an engrave Mcode as well.

Let me know if you are interested. It would make a very good addition to the MACH TOOL BOX we need to start. I have several cool probing macro/program I can add??

(;-) TP

Sorry chaps, I've been away on other business.
My interest is in engraving sundials. That does include doing some text and I want to create good quality fonts (not screen outline fonts), so, yes, I might be interested, though I'm not 100% sure I understand what you're proposing.
Perhaps you could send me the Fanuc code to clusbytaylor@enterprise.net

General Mach Discussion / Re: Macro or wizard for incrementing number?
« on: March 18, 2008, 09:35:14 PM »
If you needed to, you can easily change the font size and direction of engraving at run-time. Generate the font, digit by digit as I described, all at some nominal size. Say, you made the character height 1 unit.
Then, to print at 5 units height, add G51 X5 Y5 just before each M98, and G50 just after.
This way, you can use one font and engrave at any size. Or even a mix of sizes.
Make sure the font files don't themselves contain any G51 commands. But there's no reason why they should.
Good luck

General Mach Discussion / Re: Macro or wizard for incrementing number?
« on: March 13, 2008, 10:10:22 PM »
Good. That clears up my concern about DROs being persistent.
By the way, I've realised that my G0 commands to position each digit don't work. You should use G68 or G52 instead, I think. This is because the digit subroutines engrave at wherever (0,0) is. G0 doesn't affect this, but G68 and G52 do. I use G68 (rotate and move the coordinate origin) a lot to engrave digits, but you have to be aware that it must have a non-zero angle or it won't move the origin. 0.1 degrees works fine, 0 does not.
By the way, as I've recorded elsewhere, G68 Xx Yy Rr doesn't rotate the coordinate system about (x,y). It moves the origin to (x,y), then rotates the coordinate system about that point. Quite different. But very useful.

General Mach Discussion / Re: Macro or wizard for incrementing number?
« on: March 13, 2008, 05:26:48 PM »
Interestingly, a friend who has a pantographic engraving machine told me that they are still used in industry for engraving serial numbers because that's one non-repetitive operation that CNC isn't good at.
Rubbish, if you ask me. You could easily write a macro to engrave a serial number.
Here's an outline of what I suggest based on what I do to engrave hour numbers on sundials

Preparatory work:
Create ten subroutine files, each of which engraves a digit from 0 to 9 at the current XY position, then ends in an M99. This is easily done with, for instance, the Write wizard. Just run it ten times, once per digit, edit the output to add the M99, save to the subroutines folder. Call the files something like mydigit0.tap to mydigit9.tap
If the digits are bigger or smaller than you need for some items, you can always wrap the invokation inside a G51/G50 pair.

Decide on an unused DRO number to be used for serial numbers. You could add it to your screens so that you can see and set it, if you wished.
Initialise it. (I don't know how to make its value persist from session to session, but I expect it can be done. Even if DROs can't be made persistent, tool and work offsets can so you could treat the current serial number as a tool or fixture offset. Perhaps someone else can help with this issue.)

Write a macro along the lines of:

Dim serial as integer, i as integer, digit as integer
serial=GetUserDRO(nnn) +1
Call SetUserDRO(nnn, serial)
OpenTeachFile("EngraveSerial.tap") 'Create a batch file with the M98 commands in.
Call Code("(Engrave serial number " & serial & ")" )
For i=1 to 4 'or however many digits long your serial numbers are
  digit=serial MOD 10
  serial = serial/10
  Call Code ("G0 X" & <some function of i> ) 'Position each digit.
  Call Code ("M98 (mydigit" & digit & ".tap) L1")
Next i
Call Code ("M30")
Call CloseTeachFile()
Call LoadTeachFile()

..That's it. At the end of your main part file, put in code to position the tool at the serial field, zero the X and Y axes, then invoke the macro.
It will create EngraveSerial.tap, then load it. So the GCode display will look something like:
(Engrave serial number 1234)
G0 X21
M98 (mydigit4.tap) L1
G0 X14
M98 (mydigit3.tap) L1
G0 X7
M98 (mydigit2.tap) L1
G0 X0
M98 (mydigit1.tap) L1

Note that, as written, this engraves the digits in order from least significant to most significant. It depends on the X and Y values having been set to 0 before the macro was invoked. You could do this with G52 or G68 (with a non-zero angle). This seems inelegant. Maybe there's a better way.

Hope this helps

VB and the development of wizards / Re: Reentrant code
« on: March 10, 2008, 10:52:05 PM »
Well, it's good to know that Cypress admit they don't 'fully' support recursion. I will attempt to do their job for them by describing two different ways you can work around the problem.
NOTE: I haven't tested the following code fragments. The syntax may well be wrong. I am composing this email late at night on a different machine from the one I run Mach3 on, which I keep deliberately clean.

1. Use dummy parameters
For all local variables you want to be able to use in a recursively-called sub or function, declare the variable as a parameter.
This is a bit messy in that you have to pass in some, unused, value for the parameter every time you call it, but this can be avoided by having two routines: a top-level one you call only from outside itself, and a recursively-callable one.
For instance, going back to my original problem, I want:

sub divide(byval a as double, byval b as double)
   Dim c as double
   if abs(b-a)>0.1 then
    call divide (a,c)
    call divide (c,b)
    Code "G1 X" & b
  end if
end sub
call divide(10,20)

..This doesn't work in Cypress VB because the second recursive call won't have the correct value for c. But this should:

sub divide(byval a as double, byval b as double, byval c as double)
   if abs(b-a)>0.1 then
    call divide (a,c,0) 'The value of the third parameter is arbitrary. Might as well make it 0
    call divide (c,b,0)
    Code "G1 X" & b
  end if
end sub
call divide(10,20,0) 'Again, the value(s) of the parameters that are really local variables is arbitrary so I use 0

But, if you need a lot of locals this gets cumbersome, as calls have to have lots of trailing ,0,0,0,..., so you could hide it:

sub divide(byval a as double, byval b as double)
   call divideRecurse(a,b,0)
end sub

sub divideRecurse(byval a as double, byval b as double, byval c as double)
   if abs(b-a)>0.1 then
    call divideRecurse (a,c,0) 'The value of the third parameter is arbitrary. Might as well make it 0
    call divideRecurse (c,b,0)
    Code "G1 X" & b
  end if
end sub
call divide(10,20) 'top-level calls don't need any extra parameters

2. Use an array of parameters:

Dim c(10) as double 'assuming 11 is the deepest recursion needed, declare an array for each local variable
sub divide(byval a as double, byval b as double, byval level as integer)
   if abs(b-a)>0.1 then
    c(level)=(a+b)/2  'You must use only this level's copy of the local parameters
    call divide (a,c, level+1)  'The third parameter tells the interpreter which set of locals to use
    call divide (c,b, level+1)
    Code "G1 X" & b
  end if
end sub
call divide(10,20,0) 'You only need one extra parameter. It must be set to 0 or 1 in top-level calls

Possibly, these techniques will already be known and obvious to anyone who uses recursion, but as nobody had previously raised this whole subject, this may not be as many people as I thought.

Recursion can be a very elegant way to encode the logic of certain operations involving trees or, as in my example, the need to divide a big task into smaller ones until the task is so small it can be performed simply without unacceptable error. The actual code I was using this for, by the way, machines Bezier curves by dividing them into tiny fragments, each of which can be approximated by a straight G1 move. This is an ideal subject for recursion.

Any queries, just ask me.

VB and the development of wizards / Re: Reentrant code
« on: March 03, 2008, 02:37:08 PM »
I wasn't meaning to blame Cypress, but it's important to know that functions and subroutines that have local variables are not reentrant. That's a major piece of functionality that you would assume. Luckily, in this instance, debugging quickly showed me the problem, but you could well imagine scenarios where this would create a very obscure bug.

One possible workaround for now would seem to be to declare more parameters than you need. Just use the spares as local variables.

So, I would like to encourage Brian to work on making the code truly reentrant. And, making a single VB context across all the buttons and other objects in a screen, or screenset, would seem hugely beneficial, too. Perhaps the screenset could own a common file whose objects could be accessed from any button or other control.

I posted another email recently on the VB-Mach3 interaction (on how the execution order of multiple Code "M98 (my.tap)" is reversed) and I imagine the issues are related.


LazyCam (Beta) / Re: Arc import prob in Lazy cam
« on: March 03, 2008, 01:56:52 PM »
I've experimented in Corel Draw 12, outputting in all its many file formats and importing into LazyCAM. I find that ellipses are rendered as octagons in some cases. This seems to be because they are output as four Bezier curves, and LazyCAM treats each of these as three straight lines. Outputting from Corel as a WMF gives the most accurate rendition - better than its own native formats. The oldest DXF formats (AutoCad 2.5, from memory) work well, but the newest are hopeless. If you see jagged lines where you expected curves, I think it's because LazyCAM isn't interpreting Beziers correctly.

Is GCode the only graphical language that doesn't support Bezier curves? It seems to me it could make for much better import of DXF and other files. The Bezier probably wasn't invented when GCode started out, but these days it is the way almost all fonts and graphics packages work.
Imagine if you could code:
Gnn X x3 Y y3 Ax By Cxx Dyy (Move along a Bezier curve to x3,y3 with control points x,y and xx,yy)
This would replace anything up to hundreds of lines of G1s.

I have written a 2D Bezier macro for Mach3, but native support would be much more elegant, so that LazyCAM could post it directly. We have all sorts of canned cycles, so why not Beziers? They are extremely easy to scale, rotate, stretch or skew and fast to draw. Much better than circular arcs which are so very restricted.

From the perspective of a CAM programme, I can see that there are some complexities, such as offsetting by tool radius. For Mach3 there might be issues of calculating acceleration and deceleration, but it could convert the curve to a sequence of G1s internally for this purpose.
Other parametric cubic splines exist with, in some cases, valuable properties, but none are as universally found in graphic files as Beziers.

As a newcomer to this business I don't know if this has ever been suggested before and, perhaps, very good reasons exist why it couldn't be done or wouldn't be worthwhile. If so, I'd love to know.

Chris Lusby Taylor

VB and the development of wizards / Reentrant code
« on: March 03, 2008, 05:52:06 AM »
VB functions and subroutines should allocate local variables on the stack so that they can be called reentrantly. Cypress doesn't seem to be doing this. My current code is rather long to post here, but essentially I'm trying to do something like this:

sub divide(byval a as double, byval b as double)
   Dim c as double
   if abs(b-a)>0.1 then
    divide (a,c)
    divide (c,b)
    Code "G1 X" & b
  end if
end sub

What happens is that, after the first recursive call to divide(a,c), c gets set to 0 so the second call is divide(0,d), not divide(c,d). Indeed, the values of all local variables get reset to 0 after the first recursive call. I could recalculate them but that really shouldn't be necessary.
Have I missed something you need to do in VB to make routines recursive? Or is this a bug?
Thanks for any input
Chris Lusby Taylor

VB and the development of wizards / Re: Code Execution order is reversed
« on: February 28, 2008, 09:22:42 PM »
Hi Ian,
Thanks for this explanation. It confirms what I imagined must be happening. Actually, getting my macros to populate a Teach File is no great hardship and seems to cure the problem. I'm not convinced isMoving() would do it, but it might be worth a try.

VB and the development of wizards / Re: Macro code problems
« 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
.. 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

Pages: 1 2 »