svenhb / GRBL-Plotter

A GCode sender (not only for lasers or plotters) for up to two GRBL controller. SVG, DXF, HPGL import. 6 axis DRO.
https://grbl-plotter.de/
GNU General Public License v3.0
699 stars 176 forks source link

Start condition between tiling steps #159

Closed amoineau closed 3 years ago

amoineau commented 4 years ago

Context

I'm working on a laser cutting machine but the purpose is to cut shapes of fabric longer than the machine. We use a conveyor with an arduino board to move the sheet between cuts. The addition of the "tile" feature is really fortunate for us.

I added a second serial communication to GRBL-plotter in order to communicate with the arduino board. However, right now I have to manually hold the process at the right time, send a command to move the conveyor and resume the process.

Requested feature

I wanted to know if there was a way for me to put the process in hold between tiles while waiting for the conveyor.

The procedure would be : (Plotter) Do tile n > (Plotter) Send "top" & wait > (Arduino) Read "top" and moves conveyor > (Arduino) Send "top" > (Plotter) Do tile n+1 > loop...

Ideally the GRBL would be homing while waiting for the conveyor.

Thank you for your help !

svenhb commented 4 years ago

In principle it is already implemented but never tested: The variables #OFFX and #OFFY contains the offset (index * size) of the actual tile, #INDX and #INDY contains the index of the tile. "(^2" will control the 2nd arduino, the line must be closed with ")" to be handled as comment for the 1st arduino. image

amoineau commented 4 years ago

I'm sorry, I don't understand... How will this stop the tiling process from going to the next tile ? But if I understand correctly I can use this text box to send a serial message toward a second device after each tile, for instance (^2 DOSOMETHING) ? If so, how do you choose the target (COM port) ?

svenhb commented 4 years ago

How will this stop the tiling process from going to the next tile ?

Intended processs (never tested):

  1. Send positioning commands to 2nd arduino, wait for idle of 2nd arduino (command from text box)
  2. Send tile commands to 1st arduino, until tile is finished
  3. Repeat with step 1

image

amoineau commented 4 years ago

Just letting you know that we decided last week to let the tiling feature aside for now to focus on a single page and the tool change. If it's ok with you, i'll let this issue open untill I can go back and spend time trying to solve my problem.

amoineau commented 4 years ago

Hi, everything else is mostly working, so we are back to the tiling process. I'd like to test the process before going too deep into the software.
Therefore, ahead of synchronizing the conveyor and the grbl, I'd like to be able to make a simple pause between tiles to manually handle the transition. I tried the following setup :

image

but the gcode isn't inserted. I tried with M0 too. By the way, is there a command that pauses until another command is sent ?

svenhb commented 4 years ago

It's a bug, you may could remove an "improovement" in "graphicRelated.cs" line 472 to 479 by replacing the code by prevoius version - hope that work:

/* group objects by color/width/layer/tile-nr */
            if (graphicInformation.GroupEnable)
            {   //if (!graphicInformation.OptionClipCode)
                                GroupAllGraphics(graphicInformation);
                return Graphic2GCode.CreateGCode(groupedGraphic, headerInfo, graphicInformation);
            }
amoineau commented 4 years ago

ok i'll try !

amoineau commented 4 years ago

The closest I got in my code is this, line 1584 :

image

svenhb commented 4 years ago

This is too far down. It is at the end of "public static string CreateGCode()" in "graphicRelated.cs"

svenhb commented 4 years ago

Please undo the changings at the end of "public static string CreateGCode()" in "graphicRelated.cs".
Instead insert arround line 784 "countProperty((int)GroupOptions.ByTile, tileID);"
Before:

tileID = string.Format("{0}_X{1}_Y{2}", tileNr, indexX, indexY);
tileCommands.Add(tileID, getTileCommand(indexX, indexY, tileSizeX, tileSizeY));

After:

tileID = string.Format("{0}_X{1}_Y{2}", tileNr, indexX, indexY);
countProperty((int)GroupOptions.ByTile, tileID);
tileCommands.Add(tileID, getTileCommand(indexX, indexY, tileSizeX, tileSizeY));
amoineau commented 3 years ago

It's a bug, you may could remove an "improovement" in "graphicRelated.cs" line 472 to 479 by replacing the code by prevoius version - hope that work:

/* group objects by color/width/layer/tile-nr */
          if (graphicInformation.GroupEnable)
          {   //if (!graphicInformation.OptionClipCode)
                                GroupAllGraphics(graphicInformation);
              return Graphic2GCode.CreateGCode(groupedGraphic, headerInfo, graphicInformation);
          }

Ok I think i found it, but it was line 430 :

image

But actually I don't change anything here, is that it ?

amoineau commented 3 years ago

Instead I change this ? :

image

(I have a 40~ lines offset with you it seems)

To this :

image

amoineau commented 3 years ago

Yep, I have the gcode but I lose the tool changes and the "get feedrate and spindle from tool table". Although it still recognizes each shape depending on their original layer, which is great, I was afraid it would loose this information. But it doesn't act according to it.

image

Here I have a cross going across several tiles using both tools. We can see the pause between tiles and the fact that one of the line is on the laser layer and the other on the ink layer but I don't have the tool change operation or the correct feedrate/spindle that I usually have when working on a "single tile" (no tile).

To compare, here it is when simply unchecking "Apply clipping or Tiling" :

image

amoineau commented 3 years ago

Not that it matters but just to let you know, they are two typos on the tiling setup page. In a tooltip "draen" instead of "drawn" and one of the option is "Clipp" instead of "Clip".

svenhb commented 3 years ago

Up to now it is either tiles or toolchange - check graphic2Gcode.cs arround line 135: Just remove the "else" and it might work

                if (graphicInfo.GroupOption == GroupOptions.ByTile)
                {
                    if (logEnable) Logger.Trace("-CreateGCode  try to insert Tile command {0}", groupObject.key);
                    if (Graphic.tileCommands.ContainsKey(groupObject.key))
                    { finalGcodeString.AppendLine(Graphic.tileCommands[groupObject.key]); }
                }
                else
                {
                    if (logEnable) Logger.Trace("CreateGCode-Group  toolNr:{0}  name:{1}", groupObject.toolNr, groupObject.toolName);

                    ToolChange(groupObject.toolNr, groupObject.toolName);   // add tool change commands (if enabled) and set XYFeed etc.
                }
amoineau commented 3 years ago

if I simply remove the else, won't I lose the toolchange when not tiling ?

svenhb commented 3 years ago

No, but to be sure you could also remove the brackets around the second block

                if (graphicInfo.GroupOption == GroupOptions.ByTile)
                {
                    if (logEnable) Logger.Trace("-CreateGCode  try to insert Tile command {0}", groupObject.key);
                    if (Graphic.tileCommands.ContainsKey(groupObject.key))
                    { finalGcodeString.AppendLine(Graphic.tileCommands[groupObject.key]); }
                }
                if (logEnable) Logger.Trace("CreateGCode-Group  toolNr:{0}  name:{1}", groupObject.toolNr, groupObject.toolName);

                ToolChange(groupObject.toolNr, groupObject.toolName);   // add tool change commands (if enabled) and set XYFeed etc.
amoineau commented 3 years ago

yeah I understood that once I woke up for good... I came back to rectify. Obviously you meant that... (I don't know why but in my head "remove the else" meant put the statements inside the if.)

amoineau commented 3 years ago

The graphic is tiled, I have the "between tiles command" and the tool change commands. But the tool changes don't occur when they are supposed to, instead they occur between tiles.

I'm having a hard time running tests because I suddenly have a bug where the process stop and just nothing happens. Grbl goes from running to idle in the middle of a G1. But I don't think it's related because I tried undoing every recent changes and I still have the problem.

svenhb commented 3 years ago

When should the tool change occur? At the moment each group (color or tile-nr.) gets a tool change. When do you need it?

Grbl goes from running to idle in the middle of a G1

Did you check the COM-window for errors? Are you below 30kHz step-pulse (if using Arduino Uno / Nano)?

amoineau commented 3 years ago

Damn your good, I just spent an hour figuring it out and just when I find out you give me the answer ^^' I found out because while trying with a "clean" version of GRBL-plotter (the latest) it gave me a detailed error report about that, while the version i'm using (the previous) was just stopping everything without telling me anything. Somehow I messed up the GRBL settings yesterday.

To get back to the topic, I want the tool change to occur as it did on single page, grouping the form by layer for each tile and doing: First tile -> Tool change -> First group -> Second tool change -> Second group -> Next tile.

svenhb commented 3 years ago

Ok, just put the tool change in front of the if-part? Hard to match your needs, it goes for all groups: [group -> tool change -> figures]

                if (logEnable) Logger.Trace("CreateGCode-Group  toolNr:{0}  name:{1}", groupObject.toolNr, groupObject.toolName);
                ToolChange(groupObject.toolNr, groupObject.toolName);   // add tool change commands (if enabled) and set XYFeed                 

                if (graphicInfo.GroupOption == GroupOptions.ByTile)
                {
                    if (logEnable) Logger.Trace("-CreateGCode  try to insert Tile command {0}", groupObject.key);
                    if (Graphic.tileCommands.ContainsKey(groupObject.key))
                    { finalGcodeString.AppendLine(Graphic.tileCommands[groupObject.key]); }
                }
etc.
amoineau commented 3 years ago

I get the same result sorry... And It does seem to always default to "tool 1".

svenhb commented 3 years ago

At the beginning. they idea was: use groups to collect data for same tool (grouped by color, layer, pen-width). Then I implemented the tile-option and use groups to seperate the tiles - with out the idea of using tool-change. Probably, if tool change is enabled, it looks for matching tile-names as tool-name to find the correct tool... I don't know what you need...

amoineau commented 3 years ago

I understand what I'm asking is annoying... but I'll try to summarize the best I can to see if we can find a solution.

Context

The purpose of the machine is to be able to cut and mark pieces of sails and paragliders from a roll of fabric. These pieces are quite long so we use a conveyor and a supplier to feed the fabric inside the machine. Hence the tiling.

Current situtation

Thanks to your help we are currently able to cut and mark pieces that fit in the working area, so without using the conveyor. Everything works really well. The process entails:

Last step

The final feature we need in order to manufacture the pieces we want is to be able to do exactly that, but with tiling. So :

The conveyor and supplier work on their side (basically they are just waiting for a serial command "move xxxx" and return something when they are done with how much they moved to check or adjust).

Idea

Maybe an easier approach would be, when tiling, to save each Tile as a File and then processing the files in a row, automatically ? That way we are sure that the process would be exactly the same as a single page and it would maybe be easier to insert the conveyor manipulation between each page ? ....especially since it miiiight be necessary to apply an offset to each page to optimize the covering, depending on the conveyor precision, overshoot, etc... (but that's really a long shot/ideal world kind of feature)

svenhb commented 3 years ago

I see. From my view, I would insert another group-element, called tile, to get an output like [tile (tile specific commands) - group1 (tool change) - figures - group2 (tool change) - figures]
You may add "M0" at the end off a tile-command, to force a pause, to check the alignment of the piece.

Interesting project - would like to see pictures :-)

amoineau commented 3 years ago

I think I understand. Currently tools and tiles are handled at the same level which is the "group". What you are saying is, to avoid interference between the two, tiles should be handled at another (higher) level, like a "super group". Is that it ?

Indeed the project itself is quite interesting but I joined 3 months ago and it was in poor shape after 3 years of tedious development of the machine. I'm supposed to have it working within weeks so it has been kind of nightmarish :/ But if you are interested I would gladly show you what it looks like.

svenhb commented 3 years ago

Yes you are right, I think a "super group" is the solution, I will try to implement.

Yes I'm interested, would like to know more about.

amoineau commented 3 years ago

You have no idea how grateful I am for your work ! If I want to share pictures, where should I post them ?

svenhb commented 3 years ago

If you don't want to do it here, you could mail me: svenhb@web.de

svenhb commented 3 years ago

Please check new version: https://github.com/svenhb/GRBL-Plotter/releases

amoineau commented 3 years ago

Thanks ! I'll do that. And I'll take pictures next time the machine is working. (my phone died last week, I'm getting a new one today)

amoineau commented 3 years ago

According to my first tests it works just as expected ! Nice work and thank you again. Though, (and I'm going to be annoying) would it be possible to have the option to add the Gcode after the tile and not before (or have a parameter for each) ? I don't want the conveyor to run before the first tile but I need it after the last one... :s

svenhb commented 3 years ago

What's about "Skip code for 1st tile" ?

amoineau commented 3 years ago

Works too, if it's simpler for you.

svenhb commented 3 years ago

Function is implemented: https://github.com/svenhb/GRBL-Plotter/releases

amoineau commented 3 years ago

Happy new year ! Sorry I was on holiday since the 24th. I'll try this function, thx.

amoineau commented 3 years ago

I haven't been able to try it yet because of physical problems with the machine. And I didn't forget that I'm supposed to send you pictures/videos of it, as soon as I can get everything to work !

amoineau commented 3 years ago

Okay, I wasn't able to make a complete demonstration but I got close enough and the command insertion and first tile skipping worked as intended. Nice work !

svenhb commented 3 years ago

Sounds good. I am curious how it will go on. 👍

amoineau commented 3 years ago

The last part of the process is to synchronize the tiling and the conveyor, I'm starting to work on that while my colleague finish repairing the machine. I promise after that I should be done bothering you, but I have a few questions about the second serial controller.

Currently, I use an external serial monitor (Termite) to communicate with the conveyor. So I added a pause between each tile and I manually command the conveyor. Obviously I need to have a built-in controller for the conveyor (in order to open and control everything from GRBL-Plotter) and I need to be able to communicate with it from within the G-Code.

Fortunately, you thought of everything and you already have a second serial monitor and the possibility to communicate with it between tiles with the (^2 XXX) rule. But it seems that this controller is meant to communicate with a GRBL firmware and doesn't match well with another firmware (sends and expects things).

Do you think it's possible for me to simplify the second controller, without breaking the first, in order for it to work more like a generic serial monitor ? (Without loosing the "(^2)" feature) Or would it be simpler to make my own serial controller and implement a parallel (^3?) feature ?

svenhb commented 3 years ago

At the moment the 2nd serial is identical to the 1st - its using same form and algorithm. Implementing a 3rd serial would be more save - with using a new form, without all the grbl stuff, I think. Perhaps it's also easy to disable grbl specific handshake for the 2nd serial - I have to think about... Do you need handshake for the other firmware?

amoineau commented 3 years ago

Not particularly, right now the second firmware is a bare-bone command interpreter with some actions behind. For instance if I want to move the conveyor a meter forward (considering it has been calibrated), I just connect through serial and send "$CP1000" and it tells me when it's done.

amoineau commented 3 years ago

If I develop my own serial controller the two hard-points would be :

svenhb commented 3 years ago

1) I would prefer (^3)
2) Good question. At the moment I do it for the 2nd like this: if (_serial_form2.grblStateNow == grblState.idle) You may define a public bool variable to publish the state of your controller.

I will implement a _serial_form3 with basic functionallity, without any grbl content...

svenhb commented 3 years ago

3rd serial com is implemented (and roughly tested): https://github.com/svenhb/GRBL-Plotter/releases Use (^3 xxx) to send a command, serial COM will then switch to 'busy' until given keyword or given timeout, to block grbl streaming. image

amoineau commented 3 years ago

Wow that's amazing ! Thx, i'll try it as soon as I can !

amoineau commented 3 years ago

It works great ! It's exactly what I needed. We still have an eletrical problem to solve and then we should be able to make a complete cycle and print a full wing. I'll take a video :)

amoineau commented 3 years ago

Hello, we were able to make a complete test yesterday (i'll send you a video and some pictures today). Globally it works as expected but they are still many parts that are under-performing. However none of them are related to GRBL Plotter, so I should not be bothering you as much from now on. At least after today because I still have two requests for you ^^':

svenhb commented 3 years ago

Hello, this sounds good.

The changes you made following this issue don't seem to be saved in the exported setup (3rd controller, skip first tile, ...)

I forgot to export/import the "skip first tile" but up to now I didn't export any settings for serial coms. Not sure is this is a good idea...

Is it possible that interference/short circuit are "asking" the grbl board to throw a reset ?

Yes this could be the reason. What kind of controller you are using? GRBL-Plotter assumes a reset when the welcome message "['$' for help]" appears - like after a reset. You may switch on this checkbox inside the COM-CNC window and watch the sent and received data - espacialy if the reset occurs: image

Sometimes it's not a reset but some kind of probing process that get started in the middle of my streaming.

Perhaps use better shieldes USB cable? I read a lot of similar issues at LaserGRBL and often the cable was the reason. If not I would re-compile the grbl-firmware with the option "echo", which causes the arduino to send back the received data. But I don't know what then happens inside GRBL-Plotter...