Tweaking a Post Processor - TinyG

Tweaking a Post Processor - TinyG

dregalia2014
Enthusiast Enthusiast
1,444 Views
12 Replies
Message 1 of 13

Tweaking a Post Processor - TinyG

dregalia2014
Enthusiast
Enthusiast

Hey guys,

 

I need to tweak the post processor for TinyG for something I'm working on. 

 

Basically, What I need to do is change the M3 S10000 line to write in After the 'plunge' is completed.

(2D POCKET8)
M5
M9
T1
M3 S10000   //From here    <--------------
G54
M9
G0 X2.0183 Y10.3813
Z0.4
Z0.2
G1 Z0.1 F33.3
Z-0.019  //To after this line Here      <----------------
G3 X2.0173 Y10.3811 Z-0.02 I-0.0003 J-0.0009
Y10.3803 I0.0003 J-0.0004 F100.
X2.0179 Y10.3811 I0.0003 J0.0004

And then on right before a 'Retract function, or before a positive Z Action, send M5

That way this:

X2.0118 Y10.3788
X2.0124 Y10.3781
G3 X2.0133 Y10.3778 Z-0.029 I0.0008 J0.0007
G0 Z0.4
X2.1502 Y10.3431
Z0.2
G1 Z0.1 F33.3
Z-0.019
G3 X2.1506 Y10.344 Z-0.02 I-0.0005 J0.0008
X2.1488 Y10.3449 I-0.0011 J0. F100.
Y10.3431 I0.0007 J-0.0009

Would actually look like this:

X2.0118 Y10.3788
X2.0124 Y10.3781
G3 X2.0133 Y10.3778 Z-0.029 I0.0008 J0.0007
M5   <----------------Added
G0 Z0.4
X2.1502 Y10.3431
Z0.2
G1 Z0.1 F33.3
Z-0.019
M3 10000   <----------------Added
G3 X2.1506 Y10.344 Z-0.02 I-0.0005 J0.0008
X2.1488 Y10.3449 I-0.0011 J0. F100.
Y10.3431 I0.0007 J-0.0009

Now looking at the code, I could probably get rid of the code block:

function onSpindleSpeed(spindleSpeed) {
  if (properties.useActiveSpindle) {
    writeBlock(sOutput.format(spindleSpeed));
  } else {
    writeComment(sOutput.format(spindleSpeed));
    onCommand(COMMAND_STOP);
  }
}

or just get rid of the 'write block/comment' piece of it, and leave it in there.. but make it ineffective

I think I can just add a writeblock 'M3 S10000' in here just before the retract command

    if (properties.useG53) {
      // retract to safe plane
      retracted = true;
      // put M3 S10000 here
      writeBlock(gFormat.format(53), "Z" + xyzFormat.format(0)); // retract
      zOutput.reset();

However, I can't find anything where it has the plunge command in the code... I ran the dump file for it, and I found this line of code:

383: onMovement(MOVEMENT_PLUNGE /*plunge*/)

Which tells me I should see something to be able to code against it, right?

 

Would appreciate any assistance or help I can get, hints are very welcome.

 

Thanks!

0 Likes
Accepted solutions (1)
1,445 Views
12 Replies
Replies (12)
Message 2 of 13

dregalia2014
Enthusiast
Enthusiast

Sorry, there are some changes that need to be made to the code that I showed here..

 

Anything that has an 'M3 10000' Should actually be 'M3 S10000' to pull the spindle speed.. which would appear as:

writeBlock(mFormat.format(3) + " " + sOutput.format(spindleRPM));

in the actual code..

 

Again, thanks for any other help.. Rules wise.. when dropping or cutting throw the above block of code

when retracting or 'not cutting' throw 'M5'

 

I'm sure there is an if / else statement to be used somewhere.. but i'm not sure where.. if it's the 'on section' or someplace else.. I watched the videos, and that helped some.. but i'm still missing something.

 

~D

0 Likes
Message 3 of 13

George-Roberts
Collaborator
Collaborator

Hello

 

Hopefully I can help a little! I'll start off with the S prior to the spindle speed... The letter should be pulled through from the formatting at the top of the post, the variable 'sOutput' should contain a prefix option which you can modify to suit your needs, it should look something like this:

 

 

var sOutput = createVariable({prefix:"S", force:true}, rpmFormat);

 

 

Moving the splindle speed to after the plunge is a little more tricky... currently the spindle speed is handled in onSection which is called at the start of each new operation. If you want the spindle speed to be called after plunge, you will need the spindle speed settings in onMovement. Inside here you will need to make a collected state boolean which stores whether the spindle is active and check to see if you are MOVEMENT_CUTTING, if so, apply the spindle speed. Here is an example (you may need to correct parameter names as i'm working from memory)...:

 

at the top of the post in the collected state area add a new variable called something like spindleActivated and give it an initial state:

 

var spindleActivated = false;

Next, create an onMovement section if you dont already have one and add some logic. Something like this should work:

 

 

function onMovement(movement) {

  switch (movement) {
    case MOVEMENT_CUTTING:
      if(!spindleActivated){
writeBlock(mFormat.format(3) + " " + sOutput.format(spindleRPM));
spindleActivated = true;
} break;
default:
if(spindleActivated){
writeBlock(mFormat.format(5));
spindleActivated = false;
}
break;
} }

 

 

If i get time later, i will create a sample post for you (I haven't tested any of the above, just explained how I would approach it).

 

Hope this helps!

0 Likes
Message 4 of 13

dregalia2014
Enthusiast
Enthusiast

George,

 

Thanks so much for the reply.  Is there a 'IsCutting' flag or something in there? 

 

I know on some of the cutting, there is a 'stay down' command that allows it to travel without retracting.  I don't know the dynamics of the program enough that says 'Spindle is only on when cutting' or if it leaves it on all the time when down.. same as coolant. 

 

But, if there was a way to test if it is cutting, I can put an 'if else' statement in there that does a write block to throw an M3 or an M5 command in there, or I can do an 'if statement' and check for 2 different conditions, onMovement and !isJogging, etc... 

 

I think I see what you're saying tho, this will give me the weekend to play with the code and try to get it to spit out what I need it to do.  I am looking forward to see what you have, but I get the gist for sure.  I just wish there was a comprehensive list of everything that I can test for.  I think I can do it from the dump file, but I don't know how the 2 are intermingled.. or how to pick it apart to code against it.

 

386: onMovement(MOVEMENT_CUTTING /*cutting*/)
386: onCircular(false, 2.0176151606041617, 10.38072135504775, -0.02000000063828596, 2.0173047283503016, 10.380308046115665, -0.02000000063828596, 100)
  sweep: 106.260131deg
  radius: 0.000517
387: onCircular(false, 2.0176151606041617, 10.38072135504775, -0.02000000063828596, 2.0173047283503016, 10.381135865459292, -0.02000000063828596, 100)
  sweep: 253.739869deg
  radius: 0.000518
388: onMovement(MOVEMENT_LINK_TRANSITION /*transition*/)

I found the code I was talking about in the dump file.. pardon the fragmented thought process...

Is there a way to code in the onMovement block that Evaluates each line command and says if Movement_cutting then M3 S10000 Else M5 (using the correct formatting codes of course).

 

 

Thanks!

 

~D

0 Likes
Message 5 of 13

George-Roberts
Collaborator
Collaborator
Accepted solution

If you wanted something like isCutting, just set a collected state variable which is set onMovement(). I believe every MOVEMENT_CUTTING is when it is cutting, but i'll have to test.

 

Do you understand how to read the dump file? I'll try to explain what you have shown in your snippet.

 

You will notice that a lot of functions you'll see inside the post have several names inside the brackets, like this:

function onCircular(clockwise, cx, cy, cz, x, y, z, feed) 

The names in brackets are variable names which require data when the function is triggered. So every time you call the onCircular function you must specify each value in the exact same order.

 

In your dump file snippet you can see it shows for on circular

 onCircular(false, 2.0176151606041617, 10.38072135504775, -0.02000000063828596, 2.0173047283503016, 10.380308046115665, -0.02000000063828596, 100)

This has exactly the same number of arguments as the function in the post. So in this case, if we wanted to pull through the 10.3807 number, we would use cy (as it is the third position in both arguments) in the onCircular function.

 

In your snippet you will also see that movement_cutting is specified before the circular moves. Using the same logic as before, we can see exactly what is passed through into the onMovement function (as onMovement is listed before the brackets in the dump file... also, ignore anything between /*  */, that is just a comment so is not passed).

 

So let's say you wanted to keep the spindle on during a transition which is shown here, you could use our same logic as before and come up with something like this:

function onMovement(movement) {

  switch (movement) {
    case MOVEMENT_CUTTING:
      if(!spindleActivated){
        writeBlock(mFormat.format(3) + " " + sOutput.format(spindleRPM));
        spindleActivated = true;
       }
    break;
    case MOVEMENT_LINK_TRANSITION:
    break;
    default:
     if(spindleActivated){
       writeBlock(mFormat.format(5));
       spindleActivated = false;
     }
    break;
   }
	

Here it will just completely ignore our commands on the transition move.

 

If you could upload your post, I'll put a sample together (I like coming up with logic for things that are not natively supported!)

 

Cheers,

George

Message 6 of 13

dregalia2014
Enthusiast
Enthusiast

George,

 

You're just like me then.. lol.  I've been trying to introduce non-native features to things my entire life.. some may have called it 'hacking' back in the day..

 

The Post processor is the regular TinyG.cps thats included with everything.. I just got home, so, I'm going to see what kind of trouble I can get into with it over the next hour or so.. .and then post the modified TinyG with some results.

 

~D

0 Likes
Message 7 of 13

dregalia2014
Enthusiast
Enthusiast

Actually, your code was pretty close to being spot on.. just had to fix a few of the variables..

 

Attached is the tinyg_new.cps that i'm working on.

 

Here's the only problem I can see... 

G54
M9
G0 X2.0183 Y10.3813
Z0.4
Z0.2
G1 Z0.1 F33.3
Z-0.019     <---------- After this line .. Right?
G3 X2.0173 Y10.3811 Z-0.02 I-0.0003 J-0.0009
M3 S10000     <------------This line should be 1 line before 
Y10.3803 I0.0003 J-0.0004 F100.
X2.0179 Y10.3811 I0.0003 J0.0004

Here is the M5:

X2.0148 Y10.3758
G3 X2.0194 Y10.3805 I0.0023 J0.0024
X2.0183 Y10.3813 I-0.0023 J-0.0024
M5
G1 Z-0.029 F33.3  <----- Off on Retract.. so that's right.  
G3 X2.0173 Y10.3811 Z-0.03 I-0.0003 J-0.0009  <--  Moves to new position ???
M3 S10000 <--------  Spindle on
Y10.3803 I0.0003 J-0.0004 F100.
X2.0179 Y10.3811 I0.0003 J0.0004
X2.0173 I-0.0003 J-0.0004

So, honestly, not sure what the G3 line is doing there...if that's just a position line, or if that's the ramp in/lead in/etc..  But does that look right to you?

0 Likes
Message 8 of 13

Laurens-3DTechDraw
Mentor
Mentor

That G3 probably is a lead-in indeed. Because MOVEMENT_CUTTING doesn't include lead-in/lead-out.

Laurens Wijnschenk
3DTechDraw

AutoDesk CAM user & Post editor.
René for Legend.


Message 9 of 13

dregalia2014
Enthusiast
Enthusiast

Thanks Laurens,

 

Appreciate your input.  I can't wait to write this up now that it's fairly working, but essentially what this does, is uses a laser (controlled by M3 spindle on, M5 spindle off and spindle speed as laser strength) as a tool bit.  First run with a 5.5w laser rigged to the spindle controller of my controller software (GRBL).  It brings raster laser options to some of the users.. but it also opens it up for full support inside of Fusion 360. 

 

16195018_10211000369541692_4507625057465111988_n.jpg

 

 

0 Likes
Message 10 of 13

svante.jr.welin
Observer
Observer

Hi,

 

Being completely worthless at programming I have been unable to get the M3 and M5 commands to end up in the correct spot...

Saw your post including "tinyg_new.cps" here but seems like you made some adjustments to it later and it worked well?

 

Would you by any chance be willing to share the final version? It would be much appreciated!

 

Regards,

 

Svante

0 Likes
Message 11 of 13

dregalia2014
Enthusiast
Enthusiast

Svante,

 

My solution works specifically with a solution I built.  If you tell me what you have for a system, and what you're trying to do, I can help you get this all working for your system.  I'm more than happy to share my solution, but I worry that it won't work for your setup. 

Message 12 of 13

svante.jr.welin
Observer
Observer

 Dan,

 

Thank's for replying! In short I constructed a quite simple gantry setup I use for engraving and drawing on large formats. It's controlled by a Synthetos TinyG controlling the x- and y-axes stepper motors. The z-axis is a digital on and off device I control from the TinyG via the M3 and M5 codes (spindle on and off). 

 

I found the Fusion360 path generation and CAM functions to be very capable and would like to use it to produce G-code for the TinyG. Once the code is generated I transfer it manually to the TinyG via the Chilipeppr web app which works quite well (but I have noticed has quite poor G-code generation from for example SVG or DXF-files).

 

Now, much like I think (?) you tried to accomplish, I want to generate G-code in Fusion360 and have the spindle to turn on (M3) when the toolhead is at the starting point of each path to be engraved and turn off (M5) when it reaches the end (and toolhead is lifted). This should then be repeated for each path in the program.

 

Example:

 

G0 X325.279 Y-125.92
Z15.
Z0.
M3
G1 F2500.
X325.271 Y-126.098
X325.224 Y-126.273
X325.138 Y-126.446
X325.012 Y-126.618

...

X328.725 Y-115.082
X328.411 Y-115.376
X328.029 Y-115.672
X327.581 Y-115.972
M5
Z4.
G0 Z5.

 

... and so on to the next

 

It seems only to work when the G1 instructions are not interrupted by a M3 block (it must be placed before "G1") but I have not managed to tweak the post processor configuration enough to accomplish this...

 

Any help is more than welcome!

 

Regards,


Svante

0 Likes
Message 13 of 13

svante.jr.welin
Observer
Observer

Hi again,

 

Turns out I actually succeeded by slightly adapting the tinyg.cps post configuration and using a laser tool in Fusion 360 Smiley Happy 

Needs some more testing but looks very promising! Here's what I did:

 

1. Added capabilities:

 

capabilities = CAPABILITY_MILLING | CAPABILITY_JET;

 

2. Added two entries in the onCommand() function:

 

function onCommand(command) {
switch (command) {
...
case COMMAND_POWER_ON:
  writeBlock(mFormat.format(3));
  return; // write M3 (on)
case COMMAND_POWER_OFF:
  writeBlock(mFormat.format(5));
  return; // write M5 (off)
}

 

Thanks a lot to you Dan for offering help anyway - I might come back...!

 

 

// Svante

0 Likes