Welcome! Log In Create A New Profile

Advanced

Marlin queue and sending GCODE to it...help please

Posted by warpster 
Marlin queue and sending GCODE to it...help please
November 03, 2022 05:13PM
OK, fist let me say I am a C++ idiot, I've done a lot of Basic and some Arduino C stuff but I'm not good at C....so please forgive how stupid I sound. I have been trying to get a project going that involves using a 2560 and RAMPS 1.4 and an old Full Graphics Display. I am modifying the Marlin code to essentially remove most menus and add one of my own to control a filament rewinder. The rewinder has micro switches for endstops X_Min(left side of spool), and X_Max(right side of spool). I have endstops enabled at all times and I modified endstops.cpp to capture when X_Max triggers. The X_Min and X_Max detect the size of the spool to wind onto (needed to guide the filament back and forth as it winds the filament). So I have figured out enough to get a menu up and from that menu I can home the X_Min and then I move X to the right till it hits the X_Max endstop and that sets my upper limit.

That part is all working but where I am running into my issues is when I try to send the actual GCODE. The GCODES are similar to this, I set absolute mode for the X stepper(driving the filament guide) and relative mode for the extruder stepper(driving the spool winding)

G90
M83
G1 X58 E330 F1000; spool the next layer to the Left and wind 33 times (example on a 60mm wide spool)
G1 X1 E330
G1 X58 E330
G1 X1 E330
G1 X58 E330
G1 X1 E330
G1 X58 E330
G1 X1 E330
G1 X58 E330
G1 X1 E330
G1 X58 E330
G1 X1 E330
G1 X58 E330
G1 X1 E330
G1 X58 E330
G1 X1 E330
G1 X58 E330
G1 X1 E330
G1 X58 E330
G1 X1 E330
G1 X58 E330
G1 X1 E330
etc....
So X goes back and forth to guide the wrapping of the filament and E drives the spool itself. A movement of 10 on the extruder is one wrap.

Originally I tried using the custom user menus but I need to modify the G1 X and E values for each line before sending it so the static nature of the GCODE in custom_User_Menus and the need for a little more control made that not workable. So then I found mention of the queue and inject, inject_P, enqueue_one_now etc. so I started down that path. My big problem is I have no idea how this all works and I can't find good docs or much help on the internet. So I went about trying to get it to work, days later and I keep running into issues. I tried sending one line at a time using the queue methods but depending I might get two commands to work but no more or none of the commands would get to the printer or Marlin would reset itself etc. I've tried concatenating all of the commands together and sending them as one string with \n separators and I got it to run but after the first two lines of G1 it would always quit like there were only two lines there.

I guess I'm asking if there is anyone that could guide me on what path I need to follow to accomplish this? The string of commands could be up to 50 lines or so. If I sent the GCODE from Pronterface etc it never has issues so I assume it is a problem in how I am using the queue, since I really have no clue.

I want to thank you in advance for any guidance anyone may be able to give me. Help! Thanks!
Re: Marlin queue and sending GCODE to it...help please
November 03, 2022 11:59PM
OK, so I thought I would add my code for suggestions, always easier when you have a target.
This is a trimmed and simplified version of what I'm doing but it shows the issue....and I need to send about 30 times this amount.

static void Rewind_Spool() {
  ui.defer_status_screen();
  char gcode_buffer [50];
  //uint16_t Filament_Length = ((Hit_Pos/2) * 10);
  //uint16_t loop_cnt = 0;
  extern const char G1_WIND[];  // PGMSTR(G1_WIND, "G1 X%d F800");

delay(1000);
  sprintf_P(gcode_buffer, G1_WIND, Hit_Pos);
  queue.enqueue_one_now(gcode_buffer);
  SERIAL_ECHOLN(gcode_buffer);
  sprintf_P(gcode_buffer, G1_WIND,1);
  queue.enqueue_one_now(gcode_buffer);
  SERIAL_ECHOLN(gcode_buffer); 
  sprintf_P(gcode_buffer, G1_WIND, Hit_Pos);
  queue.enqueue_one_now(gcode_buffer);
  SERIAL_ECHOLN(gcode_buffer);
  sprintf_P(gcode_buffer, G1_WIND,1);
  queue.enqueue_one_now(gcode_buffer);
  SERIAL_ECHOLN(gcode_buffer);   
  // sprintf_P(gcode_buffer, G1_WIND, Hit_Pos);
  // queue.enqueue_one_now(gcode_buffer);
  // SERIAL_ECHOLN(gcode_buffer);
}


This snippet works but if I uncomment the last 3 lines it does nothing and Pronterface looses control of the printer after this is ran (with the lines uncommented). I assume I'm over running the buffer but I don't know what/how to check if it is OK to send another command. Hopefully someone can set me straight. Thanks
Re: Marlin queue and sending GCODE to it...help please
November 04, 2022 01:07AM
I asked an expert

Their reply

"Interesting. It's always a tricky one. You can't call it from within a G-code handler since it needs the queue to keep getting processed and emptied. If the buffer is filled (by say more than 4 commands) then it will just spin forever.

It may be better for them use queue.inject() instead. "
Re: Marlin queue and sending GCODE to it...help please
November 04, 2022 01:44AM
Quote
warpster
This snippet works but if I uncomment the last 3 lines it does nothing and Pronterface looses control of the printer after this is ran (with the lines uncommented). I assume I'm over running the buffer but I don't know what/how to check if it is OK to send another command. Hopefully someone can set me straight. Thanks

As mentioned, you can avoid filling up the command queue by using queue.inject(cmd) with all the G1 commands together in the single cmd string, separated by "\n". These commands will be queued up once Marlin returns back to the main loop(), where it will also process the next command at the head of the command queue. Marlin allows G-code commands to block the queue by design, so that a long command like `G29` can take as long as needed. And Marlin does handshaking with the host to keep it waiting when the queue gets filled up.

If you just need to do direct motion instead of using the G-code queue, you can use the do_blocking_move_to functions from motion.cpp. These are best used from within a G-code handler, so if you need to do a complex series of moves it can work best to just implement a custom G-code and do the custom motions from within that handler, either with direct moves or by calling gcode.process_subcommands_now.

Edited 2 time(s). Last edit at 11/04/2022 01:47AM by Thinkyhead.


|
| Lead Developer of Marlin Firmware
| Help support my work at Patreon and Elsewhere.
|
Re: Marlin queue and sending GCODE to it...help please
November 04, 2022 03:01AM
Thanks for the replies guys, I feel honored winking smiley
Can queue.inject handle 500 characters? It will be around 35 G1 commands, I'll give that a try today (I guess) and get back to ya.
Re: Marlin queue and sending GCODE to it...help please
November 06, 2022 08:41PM
Well I did get it working but not the way I started....from what I ran into you cannot do more than 1 inject in an ACTION_ITEM, at least I could not find a way, and if I tried to make a large string of GCODEs it would not run the whole thing from an ACTION_ITEM....so I ended up setting up a GCODES_ITEM that runs a string of "M810\nM811\nM810\nM811....." (total 35 of each) and then in an Action_Item I calculate the X and E distances and send an inject that sets M810 to G1 Xxx Exxx and M811 to G1 Xxx Exxx where the xx is the X position desired and xxx is the Extruder distance.. This worked great.

One quick question for you, where is the best place to add a function to test one of the digital input pins? I'm not sure where the main loop is yet...or if that's the best place. It needs to be somewhere that would get ran regularly and at all times. Thanks for your help.
Sorry, only registered users may post in this forum.

Click here to login