Buffered commands

I wrote my own Gcode interpreter and still have an outstanding question and issue.   The implementation of buffered and unbuffered commands. The Receive ISR receives all buffered and unbuffered commands and places them into the circular buffer, however unbuffered commands are not acknowledged until they are completed, while buffered commands are acknowledged before they are buffered.  The G code document however simply says that the unbuffered command is saved and implemented after the circular buffer is emptied, which means that until the nonbuffered command finally gets to be the next command to implement and finish.  So why can't they share a common circular buffer if the results appear to be the same? Must there be separate storage for  a single unbuffered command because all of the circular buffer space is reserved only for buffered commands? That seems to be simpler.

Comments

  • Don't think so complicated. Of course the incoming bytes are all in one circular buffer - normally the one arduino serial offers anyway. You send the "ok" once the space in that buffer is emptied and you have verified line number/checksum. What you do afterwards is completely up to you. In general all commands get executed directly. The only exception are moves that get added in move buffer so you can build a move buffer for fluent execution. Some commands may also take longer to finish (heat extruder and wait). In that case you should implement the busy protocol that sends a "busy: heating" or whatever text you like when a command takes more then 2 seconds. This allow sthe host to detect that a command is not timed out but just taking longer.
  • Thanks that helps, since that is what I implemented.  I just finished checking it.  However I do my check sum in the parser rather than in the RxInterrupt routine before running the command. The RxInterrupt routine is where I detect Move commands like G0, G1, G28 and then acknowledge it. Since I didn't use Arduino or Atmel chip none of those built in functions are available to me.
  • Sounds like you have out of order execution for gcode commands. In any case you should match the "ok" to the incoming order. That is what hosts expect. Our host/server know next command in queue has for example 17 byte and next "ok" frees 17 byte so 17 more bytes get send. Also the line numbers in "ok" response should increase matching the send line number. That allows to detect missed "ok" from communication errors. Moves should only be buffered when it is their turn or you need a good and complex logic to detect M400/G4/M106 between them.
  • I dont know what you mean by out of order Gcommands?  I Parse the commands in the order they came in and the ok signals are also in the same order going out.
     
    When you get a check sum error should the input buffer pointers be reset to zero so that you dont do the following commands stacked in the RxBuffer, to prevent out of order implementation? This I need to fix. So whenever the rs is sent nothing preloaded follows, until the same command is resent.
  • Yes, after rs you expect the line you have send. Since modes different then ping pong have already "wrong" lines in rs buffer you flush them and ignore them. There might even a new one on it's way with wrong line number until the correct one comes.
  • The example given in the RepRap Wiki for the Check Sum implied to me that the check sum was not done at the front end of the uart_Rx ISR but after it was buffered.  So I did that whole function in the Parser, which of course means that there can be several command lines that are in the buffer before being implemented.  So if there is an error I flush these out.  I started geting rs errors for lines that all work when manually entered in a Terminal Program.  Not sure what is causing that. However I have a question about the fact that when the Host connects,  before there is a start, it sends a bunch of commands.  These I buffer in the RxBuffer and Parse and implement once start is activated.  Then I get a bunch rs (resend outputs).  Is my description OK?  Should I accept uart inputs before start?
    int cs = 0;
    for(i = 0; cmd[i] != '*' && cmd[i] != NULL; i++)
       cs = cs ^ cmd[i];
    cs &= 0xff;  // Defensive programming...


  • use
    uint8_t cs = 0
    and you can spare defensive programming and code gets faster:-)

    You should activate serial quite early and then just before that start accepting inputs. Host first waits for start, but when it does not come within 1-2s it sends the commands anyway as some boards do not reset on connect and this no start will appear.

    Just have a look at repetier-firmware gcode.cpp to see how we handle communication there.
Sign In or Register to comment.