Looping gcode

So, I’d like to loop through a sequence of patterns without user intervention. It looks like Marlin implements loading a new gcode file with the M23 command (M23 “filename”). Has anyone tried it? I’m thinking of putting a line at the bottom of each gcode file that loads the next one in sequence. When I get to the end of the last file I load the first one over again. To insert a new patterns I just edit the appropriate files to link it into the chain and the next time it gets to that place the new code is loaded as if it’s been there all along.

I’m also interested in finding a fairly automatic way to move from pattern to pattern without crossing a finished pattern in the process. I’m currently finishing in the center then start the next in the center, which works, but when I finish on the outside I have to manually code in a non-destructive home (you need to move along an edge to a corner then do a home or else you run a risk of moving through the pattern with the Y home before the X home starts).

I have not seen that.

If you are going to use full table designs, I label my gcode with where it starts, a home starting gcode will end very near the center. So if I run a home starting gcode (start with a g28) the next one I will use is a center starting, the easiest. No fuss no muss.

At the end of a center starting gcode (no g28) it will leave the ball at an edge, so I will manually add a few lines of code to get it home without crossing the design.

For me I never thought to do continuous I usually just make them in pairs and cut and paste one long gcode. The m23 would be cool if you alternated the file names so you had alternating home and center starts.

Hi guys,

I know this is an old thread - I’ve been away for a while - but I thought I’d mention that my table runs autonomously off of files on an SD card. I don’t have an LCD hooked up, just a separate arduino nano that feeds gcode to the controller - in my case, I’m running GRBL, but this will work with just about any setup. On startup, the nano homes the table, then starts drawing the designs in random order, without repeating. My designs are generally created to end at 0,0. There might be a few old ones that end in the middle, but I don’t worry about them. Even if the table draws a big ugly travel line from the center to another starting point, I know if will be drawn over soon enough.

Anyways, this is an old thread, and maybe no one is interested in this anymore. If you are, let me know, and I’ll provide some more details.

Karl, would you be willing to provide detailed instructions on how you setup the nano and how it connects to the controller board? I think it would be very nice to just turn on the table and it automatically starts making designs.

Hi Troy, not sure how much detail you need, but I’ll provide what I can off the top of my head.

First, I must correct that I am using a Pro Micro instead of a Nano. The reason for this is that the Pro Micro has a hardware UART available for communicating with the control board, which made it easier for me for programming and prototyping. Note that there are still several things I would like to change in the programming of my gcode feeder, but it does work as of now.

Second, my sand table is running GRBL on an Uno with cnc shield. My method for feeding gcode from the pro micro to the controller will work with other setups, such as ramps/mega, as long as it has UART pins (most arduinos do, as far as I know).

The pro micro has an SD card board attached to it. It also has RX and TX connected to the controller board’s TX and RX. It also has a momentary push button and a toggle switch connected between pin 2 and ground - these are used to tell the machine to draw the next pattern. If the toggle switch is off, the machine stops after each file is drawn and waits until the button is pushed. If the toggle switch is turned on, the table will draw each design, one after the other.

The design files are stored in the root directory, and have numeric names (1.g, 2.g, 3.g, etc.). There is one other file, called home.g, which contains the gcode to home the machine. On startup, the gcode feeder runs home.g, then gets a count of how many files are on the card (minus the homing file). It then creates a random array of that many numbers. It checks to see if pin 2 is low (button pushed or toggle switch on), and when it is, it starts drawing the file that matches the first number in the random array. When the file is finished, the code again checks to see if pin 2 is low, and then either waits or immediately starts the next file in the array.

That’s about it. Future plans are to figure out how not to need the files to be named numerically (create a randomized array of the file names, or open files based on an index number, rather than file name). I would also like to be able to interrupt a drawing in progress and just start the next one. I welcome any tips from anyone with ideas on how to do those things.

The current version of the code is available here: https://github.com/karltinsly/gcode-feeder.

Let me know if I can provide any other details for you.


1 Like

I somehow missed this thread. :frowning:

The M23 is what things like octoprint use to print from SD card. IIRC, they are stored with DOS names, so 8 digits max, and a 3 digit extension. The long names are obtained via another call. But I think it would work with file1.gco or something similar. I could be wrong.

Karl, I’ve got some updates to that github code coming for you. I don’t have an SD card reader though, which one do you have? Also, the pro mini and the nano don’t compile, because they don’t have two HW serial ports. The ones that work for me are basically the mega, or the leonardo.

I’ll put more details about the code changes in github, but I’ve got your “next pattern” shortcut button coded and almost arbitrary names (I don’t know what happens if they are long, it might still work).

Very cool, Jeff! I look forward to checking out the new capabilities! Thanks so much for the help.

The pro micro I’m using - actually a sparkfun board, not an arduino - I believe is basically a miniature leonardo.

I’m cool with 8.3 names - I can use a naming convention to make the names a bit more descriptive than 1.g, etc.

The SD card reader is something like this: https://www.amazon.com/gp/product/B01MSNX0TW/ref=oh_aui_search_detailpage?ie=UTF8&psc=1


I got an arduino that I think is like yours, and some sd readers. I poked at it some today.

The first thing I noticed is that my super cool, but never tested code doesn’t run out of the box. It’s allocating too much memory, and it’s silently failing. So I changed the number of max files to 10 (there’s a better place somewhere between 10 and 100, but I’d rather fight it later, with dynamic allocation, so I put it at 10 for now). I made a few other changes, and it seems to be working for me.

I don’t have it connected to the zen yet, but just hooking the rx1 and tx1 together made it go through the files I put on there.

For some reason, I really want it to loop through the folders, but since it’s random, I’m not sure why. Anyway, give that a try and let me know if it doesn’t work for you. I will think about the best way to allocate as many files as possible, and possibly check to determine if we are out of memory. ATM, when you allocate the 100, the SD card’s openNextFile() or similar just silently returns nothing. I tried it with 40 and it seemed to work fine.

Thanks, Jeff. I’ll try and take a look at it soon.

By the way, maxing out the memory was one of the challenges that was causing me problems, too. I was hoping to use the same random hat function I’m currently using, but use the number from the randomized array to open files by index number, rather than file name. This article seems to explain how, but I haven’t had a chance to really dig into it yet. https://arduino.stackexchange.com/questions/39249/optimizing-arduino-file-selection-from-sd-card

Yeah, that example uses a different library, but it has a dirIndex() method to get some kind of index. I will look into that. I just barely got it working, and it’s pretty interesting. Now that I have a 5 pack of SD card readers, I’ll want to learn more and put them everywhere.

I have a few esp8266/esp32’s monitoring things around my house. I bet they could pretty easily log to an SD and I’d have an easier time debugging them. It’s pretty easy to get something working the first day, but getting it to work for months is hard, because you’re not watching them when they fail and it takes a while before you see if your fix worked.

Turns out I mistyped at the very beginning of this thread. The command is M32, not M23. If you search for M32 here you should see the Select and Start entry. If anyone has gotten it to work though, I’d really like to know how. I created eleven gcode files (one each from outside to center and visa versa for the five object type in Sandify, plus an outside to outside wipe) and added a last line to each with the M32 code pointing toward an appropriate new file. If I’d done everything right, it’d have cycled through the files then repeated and repeated and… No such luck though, it always ends up stopping after some time. I haven’t watched all through though so I don’t know if it does just the first file or two files.

And now I’ve watched all the way through. One time and it stops, so either I have the wrong syntax or something is broken. :frowning:

First, shorten the gcode so you can debug faster :wink:

Second, it’s a goofy dos file format. Something like 8 characters and three of the extension. If two files have the same first 8 characters, it does some Tilda + number business. The easiest way is to list them with that gcode command. Or just need it one.gco and two.gco and try that.

You could also try the same m command from the terminal and see if you can get it right.

Ah, I didn’t even think of 8.3 naming. I also wasn’t thinking running it from R-H would allow me to access the card, but of course it should. Time to play more with it. After this batch of coffee is roasted…

And it works! (For a short while, then it fails).

It loads the first file, which loads the second file, which doesn’t load the third file. I’m guessing there are too many file handles open at once, since it doesn’t look like the M32 closes the first file when opening the second, which doesn’t close the second when attempting to open the third. I guess what I really need is for the command to fork the next file, then immediately continue the first (which would close since there are no more commands to parse). I don’t know if Marlin allows forks though…

Seems like such a simple thing, but quickly went over my head. Maybe there is some info to be found on those continuous belt printers. I believe they print a sequential list of files? Not 100% on this though.

That makes sense. What about just putting one gcode file with all the M32s in it, then it wouldn’t loop, but you could make it work for 10,000 years.

You could probably edit Marlin to close the last file on a new file, but that wouldn’t be working as advertised either.

You could also use another Arduino and an SD card reader, like Karl did. Did you see that post? I went through and edited it a bit, but you’d have much more flexibility.

I’m going to go the route of a master file that lists all the gcode files in sequence to see if I can get enough hours out of a session to at least cover the hours of operation down there, then look into adding a flag to the M32 command to exit the previous file after starting the new one. I’ll let you all know how it goes…

And that didn’t work any better, but I next tried the P parameter to make sure the files didn’t try to execute at the same time. Here’s what worked:

G28 X Y

M32 P !StarO.gco#
M32 P !StarI.gco#
M32 P !SquareO.gco#
M32 P !SquareI.gco#
M32 P !LogoO.gco#
M32 P !LogoI.gco#
M32 P !CircleO.gco#
M32 P !CircleI.gco#
M32 P !TriangO.gco#
M32 P !TriangI.gco#
M32 P !WipeOO.gco#

2 hours and 41 minutes to run on my small ZenXY, I’ll tweak to pseudo randomize the file list and expand to run for 10 hours or so. Once we get it out in the field I’ll start toward coding some ad style displays (“Drink Beer Here” seems to be a potential ;)) and perhaps coding in the Route 30 logo.

Logo in bottle caps[attachment file=52807]

1 Like