Exemple #1
0
// Block until all buffered steps are executed.
void plan_synchronize()
{
  while (plan_get_current_block() || sys.cycle_start) { 
    execute_runtime();   // Check and execute run-time commands
    if (sys.abort) { return; } // Check for system abort
  }    
}
Exemple #2
0
// Block until all buffered steps are executed or in a cycle state. Works with feed hold
// during a synchronize call, if it should happen. Also, waits for clean cycle end.
void Grbl::Protocol::buffer_synchronize()
{
  // If system is queued, ensure cycle resumes if the auto start flag is present.
  auto_cycle_start();
  // Check and set auto start to resume cycle after synchronize and caller completes.
  if (parent->m_system.sys.state == STATE_CYCLE) { parent->m_system.sys.auto_start = true; }
  while (parent->m_plan.get_current_block() || (parent->m_system.sys.state == STATE_CYCLE)) { 
    execute_runtime();   // Check and execute run-time commands
    if (parent->m_system.sys.abort) { return; } // Check for system abort
  }    
}
Exemple #3
0
// Directs and executes one line of formatted input from protocol_process. While mostly
// incoming streaming g-code blocks, this also directs and executes Grbl internal commands,
// such as settings, initiating the homing cycle, and toggling switch states.
void Grbl::Protocol::execute_line(char *line)
{      
  execute_runtime(); // Runtime command check point.
  if (parent->m_system.sys.abort) { return; } // Bail to calling function upon system abort  

  if (line[0] == 0) {
    // Empty or comment line. Send status message for syncing purposes.
    parent->m_report.status_message(STATUS_OK);

  } else if (line[0] == '$') {
    // Grbl '$' system command
    parent->m_report.status_message(parent->m_system.execute_line(line));
    
  } else if (parent->m_system.sys.state == STATE_ALARM) {
    // Everything else is gcode. Block if in alarm mode.
    parent->m_report.status_message(STATUS_ALARM_LOCK);

  } else {
    // Parse and execute g-code block!
    parent->m_report.status_message(parent->m_gc.execute_line(line));
  }
}
Exemple #4
0
/* 
  GRBL PRIMARY LOOP:
*/
void Grbl::Protocol::main_loop()
{
  // ------------------------------------------------------------
  // Complete initialization procedures upon a power-up or reset.
  // ------------------------------------------------------------
  
  // Print welcome message   
  parent->m_report.init_message();

  // Check for and report alarm state after a reset, error, or an initial power up.
  if (parent->m_system.sys.state == STATE_ALARM) {
    parent->m_report.feedback_message(MESSAGE_ALARM_LOCK); 
  } else {
    // All systems go!
    parent->m_system.sys.state = STATE_IDLE; // Set system to ready. Clear all state flags.
    parent->m_system.execute_startup(line); // Execute startup script.
  }
    
  // ---------------------------------------------------------------------------------  
  // Primary loop! Upon a system abort, this exits back to main() to reset the system. 
  // ---------------------------------------------------------------------------------  
  
  uint8_t iscomment = false;
  uint8_t char_counter = 0;
  uint8_t c;
  for (;;) {

    // Process one line of incoming serial data, as the data becomes available. Performs an
    // initial filtering by removing spaces and comments and capitalizing all letters.
    
    // NOTE: While comment, spaces, and block delete(if supported) handling should technically 
    // be done in the g-code parser, doing it here helps compress the incoming data into Grbl's
    // line buffer, which is limited in size. The g-code standard actually states a line can't
    // exceed 256 characters, but the Arduino Uno does not have the memory space for this.
    // With a better processor, it would be very easy to pull this initial parsing out as a 
    // seperate task to be shared by the g-code parser and Grbl's system commands.
    
    while((c = parent->m_serial->getc()) != SERIAL_NO_DATA) {
      if ((c == '\n') || (c == '\r')) { // End of line reached
        line[char_counter] = 0; // Set string termination character.
        execute_line(line); // Line is complete. Execute it!
        iscomment = false;
        char_counter = 0;
      } else {
        if (iscomment) {
          // Throw away all comment characters
          if (c == ')') {
            // End of comment. Resume line.
            iscomment = false;
          }
        } else {
          if (c <= ' ') { 
            // Throw away whitepace and control characters  
          } else if (c == '/') { 
            // Block delete NOT SUPPORTED. Ignore character.
            // NOTE: If supported, would simply need to check the system if block delete is enabled.
          } else if (c == '(') {
            // Enable comments flag and ignore all characters until ')' or EOL.
            // NOTE: This doesn't follow the NIST definition exactly, but is good enough for now.
            // In the future, we could simply remove the items within the comments, but retain the
            // comment control characters, so that the g-code parser can error-check it.
            iscomment = true;
          // } else if (c == ';') {
            // Comment character to EOL NOT SUPPORTED. LinuxCNC definition. Not NIST.
            
          // TODO: Install '%' feature 
          // } else if (c == '%') {
            // Program start-end percent sign NOT SUPPORTED.
            // NOTE: This maybe installed to tell Grbl when a program is running vs manual input,
            // where, during a program, the system auto-cycle start will continue to execute 
            // everything until the next '%' sign. This will help fix resuming issues with certain
            // functions that empty the planner buffer to execute its task on-time.

          } else if (char_counter >= (LINE_BUFFER_SIZE-1)) {
            // Detect line buffer overflow. Report error and reset line buffer.
            parent->m_report.status_message(STATUS_OVERFLOW);
            iscomment = false;
            char_counter = 0;
          } else if (c >= 'a' && c <= 'z') { // Upcase lowercase
            line[char_counter++] = c-'a'+'A';
          } else {
            line[char_counter++] = c;
          }
        }
      }
    }
    
    // If there are no more characters in the serial read buffer to be processed and executed,
    // this indicates that g-code streaming has either filled the planner buffer or has 
    // completed. In either case, auto-cycle start, if enabled, any queued moves.
    auto_cycle_start();

    execute_runtime();  // Runtime command check point.
    if (parent->m_system.sys.abort) { return; } // Bail to main() program loop to reset system.
              
  }
  
  return; /* Never reached */
}