void Config_RetrieveSettings()
{
    int i=EEPROM_OFFSET;
    char stored_ver[4];
    char ver[4]=EEPROM_VERSION;
    EEPROM_READ_VAR(i,stored_ver); //read stored version
    //  SERIAL_ECHOLN("Version: [" << ver << "] Stored version: [" << stored_ver << "]");
    if (strncmp(ver,stored_ver,3) == 0)
    {
        // version number match
        EEPROM_READ_VAR(i,axis_steps_per_unit);
        EEPROM_READ_VAR(i,max_feedrate);
        EEPROM_READ_VAR(i,max_acceleration_units_per_sq_second);

        // steps per sq second need to be updated to agree with the units per sq second (as they are what is used in the planner)
		reset_acceleration_rates();

        EEPROM_READ_VAR(i,acceleration);
        EEPROM_READ_VAR(i,retract_acceleration);
        EEPROM_READ_VAR(i,minimumfeedrate);
        EEPROM_READ_VAR(i,mintravelfeedrate);
        EEPROM_READ_VAR(i,minsegmenttime);
        EEPROM_READ_VAR(i,max_xy_jerk);
        EEPROM_READ_VAR(i,max_z_jerk);
        EEPROM_READ_VAR(i,max_e_jerk);
        EEPROM_READ_VAR(i,add_homeing);
        #ifndef ULTIPANEL
        int plaPreheatHotendTemp, plaPreheatHPBTemp, plaPreheatFanSpeed;
        int absPreheatHotendTemp, absPreheatHPBTemp, absPreheatFanSpeed;
        #endif
        EEPROM_READ_VAR(i,plaPreheatHotendTemp);
        EEPROM_READ_VAR(i,plaPreheatHPBTemp);
        EEPROM_READ_VAR(i,plaPreheatFanSpeed);
        EEPROM_READ_VAR(i,absPreheatHotendTemp);
        EEPROM_READ_VAR(i,absPreheatHPBTemp);
        EEPROM_READ_VAR(i,absPreheatFanSpeed);
        EEPROM_READ_VAR(i,zprobe_zoffset);
        #ifndef PIDTEMP
        float Kp,Ki,Kd;
        #endif
        // do not need to scale PID values as the values in EEPROM are already scaled
        EEPROM_READ_VAR(i,Kp);
        EEPROM_READ_VAR(i,Ki);
        EEPROM_READ_VAR(i,Kd);
        int lcd_contrast;
        EEPROM_READ_VAR(i,lcd_contrast);

		// Call updatePID (similar to when we have processed M301)
		updatePID();
        SERIAL_ECHO_START;
        SERIAL_ECHOLNPGM("Stored settings retrieved");
    }
    else
    {
        Config_ResetDefault();
    }
    #ifdef EEPROM_CHITCHAT
      Config_PrintSettings();
    #endif
}
示例#2
0
void Config_RetrieveSettings()
{
    int i=EEPROM_OFFSET;
    char stored_ver[4];
    char ver[4]=EEPROM_VERSION;
    EEPROM_READ_VAR(i,stored_ver); //read stored version
    //  SERIAL_ECHOLN("Version: [" << ver << "] Stored version: [" << stored_ver << "]");
    if (strncmp(ver,stored_ver,3) == 0)
    {
        // version number match
        EEPROM_READ_VAR(i,axis_steps_per_unit);  
        EEPROM_READ_VAR(i,max_feedrate);  
        EEPROM_READ_VAR(i,max_acceleration_units_per_sq_second);
        EEPROM_READ_VAR(i,acceleration);
        EEPROM_READ_VAR(i,retract_acceleration);
        EEPROM_READ_VAR(i,minimumfeedrate);
        EEPROM_READ_VAR(i,mintravelfeedrate);
        EEPROM_READ_VAR(i,minsegmenttime);
        EEPROM_READ_VAR(i,max_xy_jerk);
        EEPROM_READ_VAR(i,max_z_jerk);
        EEPROM_READ_VAR(i,max_e_jerk);
        EEPROM_READ_VAR(i,add_homeing);
        #ifndef ULTIPANEL
        int plaPreheatHotendTemp, plaPreheatHPBTemp, plaPreheatFanSpeed;
        int absPreheatHotendTemp, absPreheatHPBTemp, absPreheatFanSpeed;
        #endif
        EEPROM_READ_VAR(i,plaPreheatHotendTemp);
        EEPROM_READ_VAR(i,plaPreheatHPBTemp);
        EEPROM_READ_VAR(i,plaPreheatFanSpeed);
        EEPROM_READ_VAR(i,absPreheatHotendTemp);
        EEPROM_READ_VAR(i,absPreheatHPBTemp);
        EEPROM_READ_VAR(i,absPreheatFanSpeed);
        #ifndef PIDTEMP
        float Kp,Ki,Kd;
        #endif
        EEPROM_READ_VAR(i,Kp);
        EEPROM_READ_VAR(i,Ki);
        EEPROM_READ_VAR(i,Kd);

        SERIAL_ECHO_START;
        SERIAL_ECHOLNPGM("Stored settings retreived:");
    }
    else
    {
        Config_ResetDefault();
        SERIAL_ECHO_START;
        SERIAL_ECHOLN("Using Default settings:");
    }
    Config_PrintSettings();
}
void Config_RetrieveSettings()
{
    int i=EEPROM_OFFSET;
    char stored_ver[4];
    char ver[4]=EEPROM_VERSION;
    EEPROM_READ_VAR(i,stored_ver); //read stored version
    //  SERIAL_ECHOLN("Version: [" << ver << "] Stored version: [" << stored_ver << "]");
    if (strncmp(ver,stored_ver,3) == 0)
    {
        // version number match
        //EEPROM_READ_VAR(i,axis_steps_per_unit);  
        //EEPROM_READ_VAR(i,max_acceleration_units_per_sq_second);
        
        // steps per sq second need to be updated to agree with the units per sq second (as they are what is used in the planner)
		//reset_acceleration_rates();
        
        //EEPROM_READ_VAR(i,acceleration);
        //EEPROM_READ_VAR(i,minsegmenttime);
        //#ifndef PIDTEMP
        //float Kp,Ki,Kd;
        //#endif
        // do not need to scale PID values as the values in EEPROM are already scaled		
        //EEPROM_READ_VAR(i,Kp);
        //EEPROM_READ_VAR(i,Ki);
        //EEPROM_READ_VAR(i,Kd);

		// Call updatePID (similar to when we have processed M301)
		//updatePID();
        //SERIAL_ECHO_START;
        //SERIAL_ECHOLNPGM("Stored settings retrieved");
    }
    else
    {
        Config_ResetDefault();
    }
    #ifdef EEPROM_CHITCHAT
      Config_PrintSettings();
    #endif
}
void Config_RetrieveSettings() {

  int i = EEPROM_OFFSET;
  char stored_ver[4];
  char ver[4] = EEPROM_VERSION;
  EEPROM_READ_VAR(i, stored_ver); //read stored version
  //  SERIAL_ECHOLN("Version: [" << ver << "] Stored version: [" << stored_ver << "]");

  if (strncmp(ver, stored_ver, 3) != 0) {
    Config_ResetDefault();
  }
  else {
    float dummy = 0;

    // version number match
    EEPROM_READ_VAR(i, axis_steps_per_unit);
    EEPROM_READ_VAR(i, max_feedrate);
    EEPROM_READ_VAR(i, max_acceleration_units_per_sq_second);

    // steps per sq second need to be updated to agree with the units per sq second (as they are what is used in the planner)
    reset_acceleration_rates();

    EEPROM_READ_VAR(i, acceleration);
    EEPROM_READ_VAR(i, retract_acceleration);
    EEPROM_READ_VAR(i, travel_acceleration);
    EEPROM_READ_VAR(i, minimumfeedrate);
    EEPROM_READ_VAR(i, mintravelfeedrate);
    EEPROM_READ_VAR(i, minsegmenttime);
    EEPROM_READ_VAR(i, max_xy_jerk);
    EEPROM_READ_VAR(i, max_z_jerk);
    EEPROM_READ_VAR(i, max_e_jerk);
    EEPROM_READ_VAR(i, home_offset);

    uint8_t dummy_uint8 = 0, mesh_num_x = 0, mesh_num_y = 0;
    EEPROM_READ_VAR(i, dummy_uint8);
    EEPROM_READ_VAR(i, mesh_num_x);
    EEPROM_READ_VAR(i, mesh_num_y);
    #if ENABLED(MESH_BED_LEVELING)
      mbl.active = dummy_uint8;
      if (mesh_num_x == MESH_NUM_X_POINTS && mesh_num_y == MESH_NUM_Y_POINTS) {
        EEPROM_READ_VAR(i, mbl.z_values);
      } else {
        mbl.reset();
        for (int q = 0; q < mesh_num_x * mesh_num_y; q++) EEPROM_READ_VAR(i, dummy);
      }
    #else
      for (int q = 0; q < mesh_num_x * mesh_num_y; q++) EEPROM_READ_VAR(i, dummy);
    #endif // MESH_BED_LEVELING

    #if DISABLED(AUTO_BED_LEVELING_FEATURE)
      float zprobe_zoffset = 0;
    #endif
    EEPROM_READ_VAR(i, zprobe_zoffset);

    #if ENABLED(DELTA)
      EEPROM_READ_VAR(i, endstop_adj);                // 3 floats
      EEPROM_READ_VAR(i, delta_radius);               // 1 float
      EEPROM_READ_VAR(i, delta_diagonal_rod);         // 1 float
      EEPROM_READ_VAR(i, delta_segments_per_second);  // 1 float
    #elif ENABLED(Z_DUAL_ENDSTOPS)
      EEPROM_READ_VAR(i, z_endstop_adj);
      dummy = 0.0f;
      for (int q=5; q--;) EEPROM_READ_VAR(i, dummy);
    #else
      dummy = 0.0f;
      for (int q=6; q--;) EEPROM_READ_VAR(i, dummy);
    #endif

    #if DISABLED(ULTIPANEL)
      int plaPreheatHotendTemp, plaPreheatHPBTemp, plaPreheatFanSpeed,
          absPreheatHotendTemp, absPreheatHPBTemp, absPreheatFanSpeed;
    #endif

    EEPROM_READ_VAR(i, plaPreheatHotendTemp);
    EEPROM_READ_VAR(i, plaPreheatHPBTemp);
    EEPROM_READ_VAR(i, plaPreheatFanSpeed);
    EEPROM_READ_VAR(i, absPreheatHotendTemp);
    EEPROM_READ_VAR(i, absPreheatHPBTemp);
    EEPROM_READ_VAR(i, absPreheatFanSpeed);

    #if ENABLED(PIDTEMP)
      for (int e = 0; e < 4; e++) { // 4 = max extruders currently supported by Marlin
        EEPROM_READ_VAR(i, dummy); // Kp
        if (e < EXTRUDERS && dummy != DUMMY_PID_VALUE) {
          // do not need to scale PID values as the values in EEPROM are already scaled
          PID_PARAM(Kp, e) = dummy;
          EEPROM_READ_VAR(i, PID_PARAM(Ki, e));
          EEPROM_READ_VAR(i, PID_PARAM(Kd, e));
          #if ENABLED(PID_ADD_EXTRUSION_RATE)
            EEPROM_READ_VAR(i, PID_PARAM(Kc, e));
          #else
            EEPROM_READ_VAR(i, dummy);
          #endif
        }
        else {
          for (int q=3; q--;) EEPROM_READ_VAR(i, dummy); // Ki, Kd, Kc
        }
      }
    #else // !PIDTEMP
      // 4 x 4 = 16 slots for PID parameters
      for (int q=16; q--;) EEPROM_READ_VAR(i, dummy);  // 4x Kp, Ki, Kd, Kc
    #endif // !PIDTEMP

    #if DISABLED(PID_ADD_EXTRUSION_RATE)
      int lpq_len;
    #endif
    EEPROM_READ_VAR(i, lpq_len);

    #if DISABLED(PIDTEMPBED)
      float bedKp, bedKi, bedKd;
    #endif

    EEPROM_READ_VAR(i, dummy); // bedKp
    if (dummy != DUMMY_PID_VALUE) {
      bedKp = dummy; UNUSED(bedKp);
      EEPROM_READ_VAR(i, bedKi);
      EEPROM_READ_VAR(i, bedKd);
    }
    else {
      for (int q=2; q--;) EEPROM_READ_VAR(i, dummy); // bedKi, bedKd
    }

    #if DISABLED(HAS_LCD_CONTRAST)
      int lcd_contrast;
    #endif
    EEPROM_READ_VAR(i, lcd_contrast);

    #if ENABLED(SCARA)
      EEPROM_READ_VAR(i, axis_scaling);  // 3 floats
    #else
      EEPROM_READ_VAR(i, dummy);
    #endif

    #if ENABLED(FWRETRACT)
      EEPROM_READ_VAR(i, autoretract_enabled);
      EEPROM_READ_VAR(i, retract_length);
      #if EXTRUDERS > 1
        EEPROM_READ_VAR(i, retract_length_swap);
      #else
        EEPROM_READ_VAR(i, dummy);
      #endif
      EEPROM_READ_VAR(i, retract_feedrate);
      EEPROM_READ_VAR(i, retract_zlift);
      EEPROM_READ_VAR(i, retract_recover_length);
      #if EXTRUDERS > 1
        EEPROM_READ_VAR(i, retract_recover_length_swap);
      #else
        EEPROM_READ_VAR(i, dummy);
      #endif
      EEPROM_READ_VAR(i, retract_recover_feedrate);
    #endif // FWRETRACT

    EEPROM_READ_VAR(i, volumetric_enabled);

    for (int q = 0; q < 4; q++) {
      EEPROM_READ_VAR(i, dummy);
      if (q < EXTRUDERS) filament_size[q] = dummy;
    }

    calculate_volumetric_multipliers();
    // Call updatePID (similar to when we have processed M301)
    updatePID();

    // Report settings retrieved and length
    SERIAL_ECHO_START;
    SERIAL_ECHO(ver);
    SERIAL_ECHOPAIR(" stored settings retrieved (", (unsigned long)i);
    SERIAL_ECHOLNPGM(" bytes)");
  }

  #if ENABLED(EEPROM_CHITCHAT)
    Config_PrintSettings();
  #endif
}
示例#5
0
void Config_StoreSettings()  {
  float dummy = 0.0f;
  char ver[4] = "000";
  int i = EEPROM_OFFSET;
  EEPROM_WRITE_VAR(i, ver); // invalidate data first
  EEPROM_WRITE_VAR(i, axis_steps_per_unit);
  EEPROM_WRITE_VAR(i, max_feedrate);
  EEPROM_WRITE_VAR(i, max_acceleration_units_per_sq_second);
  EEPROM_WRITE_VAR(i, acceleration);
  EEPROM_WRITE_VAR(i, retract_acceleration);
  EEPROM_WRITE_VAR(i, minimumfeedrate);
  EEPROM_WRITE_VAR(i, mintravelfeedrate);
  EEPROM_WRITE_VAR(i, minsegmenttime);
  EEPROM_WRITE_VAR(i, max_xy_jerk);
  EEPROM_WRITE_VAR(i, max_z_jerk);
  EEPROM_WRITE_VAR(i, max_e_jerk);
  EEPROM_WRITE_VAR(i, add_homing);

  #ifdef DELTA
    EEPROM_WRITE_VAR(i, endstop_adj);               // 3 floats
    EEPROM_WRITE_VAR(i, delta_radius);              // 1 float
    EEPROM_WRITE_VAR(i, delta_diagonal_rod);        // 1 float
    EEPROM_WRITE_VAR(i, delta_segments_per_second); // 1 float
  #else
    dummy = 0.0f;
    for (int q=6; q--;) EEPROM_WRITE_VAR(i, dummy);
  #endif

  #ifndef ULTIPANEL
    int plaPreheatHotendTemp = PLA_PREHEAT_HOTEND_TEMP, plaPreheatHPBTemp = PLA_PREHEAT_HPB_TEMP, plaPreheatFanSpeed = PLA_PREHEAT_FAN_SPEED,
        absPreheatHotendTemp = ABS_PREHEAT_HOTEND_TEMP, absPreheatHPBTemp = ABS_PREHEAT_HPB_TEMP, absPreheatFanSpeed = ABS_PREHEAT_FAN_SPEED;
  #endif // !ULTIPANEL

  EEPROM_WRITE_VAR(i, plaPreheatHotendTemp);
  EEPROM_WRITE_VAR(i, plaPreheatHPBTemp);
  EEPROM_WRITE_VAR(i, plaPreheatFanSpeed);
  EEPROM_WRITE_VAR(i, absPreheatHotendTemp);
  EEPROM_WRITE_VAR(i, absPreheatHPBTemp);
  EEPROM_WRITE_VAR(i, absPreheatFanSpeed);
  EEPROM_WRITE_VAR(i, zprobe_zoffset);

  for (int e = 0; e < 4; e++) {

    #ifdef PIDTEMP
      if (e < EXTRUDERS) {
        EEPROM_WRITE_VAR(i, PID_PARAM(Kp, e));
        EEPROM_WRITE_VAR(i, PID_PARAM(Ki, e));
        EEPROM_WRITE_VAR(i, PID_PARAM(Kd, e));
        #ifdef PID_ADD_EXTRUSION_RATE
          EEPROM_WRITE_VAR(i, PID_PARAM(Kc, e));
        #else
          dummy = 1.0f; // 1.0 = default kc
          EEPROM_WRITE_VAR(i, dummy);
        #endif
      }
      else {
    #else // !PIDTEMP
      {
    #endif // !PIDTEMP

        dummy = DUMMY_PID_VALUE;
        EEPROM_WRITE_VAR(i, dummy);
        dummy = 0.0f;
        for (int q = 3; q--;) EEPROM_WRITE_VAR(i, dummy);
      }

  } // Extruders Loop

  #ifndef DOGLCD
    int lcd_contrast = 32;
  #endif
  EEPROM_WRITE_VAR(i, lcd_contrast);

  #ifdef SCARA
    EEPROM_WRITE_VAR(i, axis_scaling); // 3 floats
  #else
    dummy = 1.0f;
    EEPROM_WRITE_VAR(i, dummy);
  #endif

  #ifdef FWRETRACT
    EEPROM_WRITE_VAR(i, autoretract_enabled);
    EEPROM_WRITE_VAR(i, retract_length);
    #if EXTRUDERS > 1
      EEPROM_WRITE_VAR(i, retract_length_swap);
    #else
      dummy = 0.0f;
      EEPROM_WRITE_VAR(i, dummy);
    #endif
    EEPROM_WRITE_VAR(i, retract_feedrate);
    EEPROM_WRITE_VAR(i, retract_zlift);
    EEPROM_WRITE_VAR(i, retract_recover_length);
    #if EXTRUDERS > 1
      EEPROM_WRITE_VAR(i, retract_recover_length_swap);
    #else
      dummy = 0.0f;
      EEPROM_WRITE_VAR(i, dummy);
    #endif
    EEPROM_WRITE_VAR(i, retract_recover_feedrate);
  #endif // FWRETRACT

  EEPROM_WRITE_VAR(i, volumetric_enabled);

  // Save filament sizes
  for (int q = 0; q < 4; q++) {
    if (q < EXTRUDERS) dummy = filament_size[q];
    EEPROM_WRITE_VAR(i, dummy);
  }

  int storageSize = i;

  char ver2[4] = EEPROM_VERSION;
  int j = EEPROM_OFFSET;
  EEPROM_WRITE_VAR(j, ver2); // validate data

  // Report storage size
  SERIAL_ECHO_START;
  SERIAL_ECHOPAIR("Settings Stored (", (unsigned long)i);
  SERIAL_ECHOLNPGM(" bytes)");
}

void Config_RetrieveSettings() {

  int i = EEPROM_OFFSET;
  char stored_ver[4];
  char ver[4] = EEPROM_VERSION;
  EEPROM_READ_VAR(i, stored_ver); //read stored version
  //  SERIAL_ECHOLN("Version: [" << ver << "] Stored version: [" << stored_ver << "]");

  if (strncmp(ver, stored_ver, 3) != 0) {
    Config_ResetDefault();
  }
  else {
    float dummy = 0;

    // version number match
    EEPROM_READ_VAR(i, axis_steps_per_unit);
    EEPROM_READ_VAR(i, max_feedrate);
    EEPROM_READ_VAR(i, max_acceleration_units_per_sq_second);

        // steps per sq second need to be updated to agree with the units per sq second (as they are what is used in the planner)
    reset_acceleration_rates();

    EEPROM_READ_VAR(i, acceleration);
    EEPROM_READ_VAR(i, retract_acceleration);
    EEPROM_READ_VAR(i, minimumfeedrate);
    EEPROM_READ_VAR(i, mintravelfeedrate);
    EEPROM_READ_VAR(i, minsegmenttime);
    EEPROM_READ_VAR(i, max_xy_jerk);
    EEPROM_READ_VAR(i, max_z_jerk);
    EEPROM_READ_VAR(i, max_e_jerk);
    EEPROM_READ_VAR(i, add_homing);

    #ifdef DELTA
      EEPROM_READ_VAR(i, endstop_adj);                // 3 floats
      EEPROM_READ_VAR(i, delta_radius);               // 1 float
      EEPROM_READ_VAR(i, delta_diagonal_rod);         // 1 float
      EEPROM_READ_VAR(i, delta_segments_per_second);  // 1 float
    #else
      for (int q=6; q--;) EEPROM_READ_VAR(i, dummy);
    #endif

    #ifndef ULTIPANEL
      int plaPreheatHotendTemp, plaPreheatHPBTemp, plaPreheatFanSpeed,
          absPreheatHotendTemp, absPreheatHPBTemp, absPreheatFanSpeed;
    #endif

    EEPROM_READ_VAR(i, plaPreheatHotendTemp);
    EEPROM_READ_VAR(i, plaPreheatHPBTemp);
    EEPROM_READ_VAR(i, plaPreheatFanSpeed);
    EEPROM_READ_VAR(i, absPreheatHotendTemp);
    EEPROM_READ_VAR(i, absPreheatHPBTemp);
    EEPROM_READ_VAR(i, absPreheatFanSpeed);
    EEPROM_READ_VAR(i, zprobe_zoffset);

    #ifdef PIDTEMP
      for (int e = 0; e < 4; e++) { // 4 = max extruders currently supported by Marlin
        EEPROM_READ_VAR(i, dummy);
        if (e < EXTRUDERS && dummy != DUMMY_PID_VALUE) {
          // do not need to scale PID values as the values in EEPROM are already scaled
          PID_PARAM(Kp, e) = dummy;
          EEPROM_READ_VAR(i, PID_PARAM(Ki, e));
          EEPROM_READ_VAR(i, PID_PARAM(Kd, e));
          #ifdef PID_ADD_EXTRUSION_RATE
            EEPROM_READ_VAR(i, PID_PARAM(Kc, e));
          #else
            EEPROM_READ_VAR(i, dummy);
          #endif
        }
        else {
          for (int q=3; q--;) EEPROM_READ_VAR(i, dummy); // Ki, Kd, Kc
        }
      }
    #else // !PIDTEMP
      // 4 x 4 = 16 slots for PID parameters
      for (int q=16; q--;) EEPROM_READ_VAR(i, dummy);  // 4x Kp, Ki, Kd, Kc
    #endif // !PIDTEMP

    #ifndef DOGLCD
      int lcd_contrast;
    #endif
    EEPROM_READ_VAR(i, lcd_contrast);

    #ifdef SCARA
      EEPROM_READ_VAR(i, axis_scaling);  // 3 floats
    #else
      EEPROM_READ_VAR(i, dummy);
    #endif

    #ifdef FWRETRACT
      EEPROM_READ_VAR(i, autoretract_enabled);
      EEPROM_READ_VAR(i, retract_length);
      #if EXTRUDERS > 1
        EEPROM_READ_VAR(i, retract_length_swap);
      #else
        EEPROM_READ_VAR(i, dummy);
      #endif
      EEPROM_READ_VAR(i, retract_feedrate);
      EEPROM_READ_VAR(i, retract_zlift);
      EEPROM_READ_VAR(i, retract_recover_length);
      #if EXTRUDERS > 1
        EEPROM_READ_VAR(i, retract_recover_length_swap);
      #else
        EEPROM_READ_VAR(i, dummy);
      #endif
      EEPROM_READ_VAR(i, retract_recover_feedrate);
    #endif // FWRETRACT

    EEPROM_READ_VAR(i, volumetric_enabled);

    for (int q = 0; q < 4; q++) {
      EEPROM_READ_VAR(i, dummy);
      if (q < EXTRUDERS) filament_size[q] = dummy;
    }

    calculate_volumetric_multipliers();
    // Call updatePID (similar to when we have processed M301)
    updatePID();

    // Report settings retrieved and length
    SERIAL_ECHO_START;
    SERIAL_ECHO(ver);
    SERIAL_ECHOPAIR(" stored settings retrieved (", (unsigned long)i);
    SERIAL_ECHOLNPGM(" bytes)");
  }

  #ifdef EEPROM_CHITCHAT
    Config_PrintSettings();
  #endif
}
void Config_RetrieveSettings()
{
    int i=EEPROM_OFFSET;
    char stored_ver[4];
    char ver[4]=EEPROM_VERSION;
    EEPROM_READ_VAR(i,stored_ver); //read stored version
    //  SERIAL_ECHOLN("Version: [" << ver << "] Stored version: [" << stored_ver << "]");
    if (strncmp(ver,stored_ver,3) == 0)
    {
        // version number match
        EEPROM_READ_VAR(i,axis_steps_per_unit);
        EEPROM_READ_VAR(i,max_feedrate);
        EEPROM_READ_VAR(i,max_acceleration_units_per_sq_second);

        // steps per sq second need to be updated to agree with the units per sq second (as they are what is used in the planner)
        reset_acceleration_rates();

        EEPROM_READ_VAR(i,acceleration);
        EEPROM_READ_VAR(i,retract_acceleration);
        EEPROM_READ_VAR(i,minimumfeedrate);
        EEPROM_READ_VAR(i,mintravelfeedrate);
        EEPROM_READ_VAR(i,minsegmenttime);
        EEPROM_READ_VAR(i,max_xy_jerk);
        EEPROM_READ_VAR(i,max_z_jerk);
        EEPROM_READ_VAR(i,max_e_jerk);
        EEPROM_READ_VAR(i,add_homeing);
#ifndef ULTIPANEL
        int plaPreheatHotendTemp, plaPreheatHPBTemp, plaPreheatFanSpeed;
        int absPreheatHotendTemp, absPreheatHPBTemp, absPreheatFanSpeed;
#endif
        EEPROM_READ_VAR(i,plaPreheatHotendTemp);
        EEPROM_READ_VAR(i,plaPreheatHPBTemp);
        EEPROM_READ_VAR(i,plaPreheatFanSpeed);
        EEPROM_READ_VAR(i,absPreheatHotendTemp);
        EEPROM_READ_VAR(i,absPreheatHPBTemp);
        EEPROM_READ_VAR(i,absPreheatFanSpeed);
#ifndef PIDTEMP
        float Kp,Ki,Kd;
#endif
        // do not need to scale PID values as the values in EEPROM are already scaled
        EEPROM_READ_VAR(i,Kp);
        EEPROM_READ_VAR(i,Ki);
        EEPROM_READ_VAR(i,Kd);
        EEPROM_READ_VAR(i,motor_current_setting);
#ifdef ENABLE_ULTILCD2
        EEPROM_READ_VAR(i,led_brightness_level);
        EEPROM_READ_VAR(i,led_mode);
#else
        uint8_t dummyByte;
        EEPROM_READ_VAR(i,dummyByte);
        EEPROM_READ_VAR(i,dummyByte);
#endif
        EEPROM_READ_VAR(i,retract_length);
        EEPROM_READ_VAR(i,retract_feedrate);

        // Call updatePID (similar to when we have processed M301)
        updatePID();
        SERIAL_ECHO_START;
        SERIAL_ECHOLNPGM("Stored settings retrieved");
    }
    else
    {
        Config_ResetDefault();
    }
    if (strncmp_P(ver, PSTR("V010"), 3) == 0)
    {
        i = EEPROM_OFFSET + 84;
        EEPROM_READ_VAR(i,add_homeing);
    }
    Config_PrintSettings();

    //ignore EEPROM extruder steps/mm and current
    float temp1[]=DEFAULT_AXIS_STEPS_PER_UNIT;
    axis_steps_per_unit[3]=temp1[3]; //overide EEPROM steps
    float temp2[]=DEFAULT_PWM_MOTOR_CURRENT;
    motor_current_setting[2] = temp2[2]; // overide EEPROM current
}
/**
 * M501 - Retrieve Configuration
 */
void Config_RetrieveSettings() {
  int i = EEPROM_OFFSET;
  char stored_ver[6];
  uint16_t stored_checksum;
  EEPROM_READ_VAR(i, stored_ver);
  EEPROM_READ_VAR(i, stored_checksum);

  if (DEBUGGING(INFO)) {
    ECHO_SMV(INFO, "Version: [", version);
    ECHO_MV("] Stored version: [", stored_ver);
    ECHO_EM("]");
  }

  if (strncmp(version, stored_ver, 5) != 0) {
    Config_ResetDefault();
  }
  else {
    float dummy = 0;

    eeprom_checksum = 0; // clear before reading first "real data"

    // version number match
    EEPROM_READ_VAR(i, planner.axis_steps_per_mm);
    EEPROM_READ_VAR(i, planner.max_feedrate);
    EEPROM_READ_VAR(i, planner.max_acceleration_mm_per_s2);

    EEPROM_READ_VAR(i, planner.acceleration);
    EEPROM_READ_VAR(i, planner.retract_acceleration);
    EEPROM_READ_VAR(i, planner.travel_acceleration);
    EEPROM_READ_VAR(i, planner.min_feedrate);
    EEPROM_READ_VAR(i, planner.min_travel_feedrate);
    EEPROM_READ_VAR(i, planner.min_segment_time);
    EEPROM_READ_VAR(i, planner.max_xy_jerk);
    EEPROM_READ_VAR(i, planner.max_z_jerk);
    EEPROM_READ_VAR(i, planner.max_e_jerk);
    EEPROM_READ_VAR(i, home_offset);
    EEPROM_READ_VAR(i, hotend_offset);

    #if ENABLED(MESH_BED_LEVELING)
      uint8_t mesh_num_x = 0, mesh_num_y = 0;
      EEPROM_READ_VAR(i, mbl.status);
      EEPROM_READ_VAR(i, mbl.z_offset);
      EEPROM_READ_VAR(i, mesh_num_x);
      EEPROM_READ_VAR(i, mesh_num_y);
      EEPROM_READ_VAR(i, mbl.z_values);
    #endif

    #if HEATER_USES_AD595
      EEPROM_READ_VAR(i, ad595_offset);
      EEPROM_READ_VAR(i, ad595_gain);
      for (int8_t h = 0; h < HOTENDS; h++)
        if (ad595_gain[h] == 0) ad595_gain[h] == TEMP_SENSOR_AD595_GAIN;
    #endif

    #if MECH(DELTA)
      EEPROM_READ_VAR(i, endstop_adj);
      EEPROM_READ_VAR(i, delta_radius);
      EEPROM_READ_VAR(i, delta_diagonal_rod);
      EEPROM_READ_VAR(i, sw_endstop_max);
      EEPROM_READ_VAR(i, tower_adj);
      EEPROM_READ_VAR(i, diagrod_adj);
    #endif //DELTA

    #if HASNT(BED_PROBE)
      float zprobe_zoffset = 0;
    #endif
    EEPROM_READ_VAR(i, zprobe_zoffset);

    #if DISABLED(ULTIPANEL)
      int plaPreheatHotendTemp, plaPreheatHPBTemp, plaPreheatFanSpeed,
          absPreheatHotendTemp, absPreheatHPBTemp, absPreheatFanSpeed,
          gumPreheatHotendTemp, gumPreheatHPBTemp, gumPreheatFanSpeed;
    #endif

    EEPROM_READ_VAR(i, plaPreheatHotendTemp);
    EEPROM_READ_VAR(i, plaPreheatHPBTemp);
    EEPROM_READ_VAR(i, plaPreheatFanSpeed);
    EEPROM_READ_VAR(i, absPreheatHotendTemp);
    EEPROM_READ_VAR(i, absPreheatHPBTemp);
    EEPROM_READ_VAR(i, absPreheatFanSpeed);
    EEPROM_READ_VAR(i, gumPreheatHotendTemp);
    EEPROM_READ_VAR(i, gumPreheatHPBTemp);
    EEPROM_READ_VAR(i, gumPreheatFanSpeed);

    #if ENABLED(PIDTEMP)
      for (int8_t h = 0; h < HOTENDS; h++) {
        EEPROM_READ_VAR(i, PID_PARAM(Kp, h));
        EEPROM_READ_VAR(i, PID_PARAM(Ki, h));
        EEPROM_READ_VAR(i, PID_PARAM(Kd, h));
        EEPROM_READ_VAR(i, PID_PARAM(Kc, h));
      }
    #endif // PIDTEMP

    #if DISABLED(PID_ADD_EXTRUSION_RATE)
      int lpq_len;
    #endif
    EEPROM_READ_VAR(i, lpq_len);

    #if ENABLED(PIDTEMPBED)
      EEPROM_READ_VAR(i, bedKp);
      EEPROM_READ_VAR(i, bedKi);
      EEPROM_READ_VAR(i, bedKd);
    #endif

    #if ENABLED(PIDTEMPCHAMBER)
      EEPROM_READ_VAR(i, chamberKp);
      EEPROM_READ_VAR(i, chamberKi);
      EEPROM_READ_VAR(i, chamberKd);
    #endif

    #if ENABLED(PIDTEMPCOOLER)
      EEPROM_READ_VAR(i, coolerKp);
      EEPROM_READ_VAR(i, coolerKi);
      EEPROM_READ_VAR(i, coolerKd);
    #endif

    #if HASNT(LCD_CONTRAST)
      int lcd_contrast;
    #endif
    EEPROM_READ_VAR(i, lcd_contrast);

    #if MECH(SCARA)
      EEPROM_READ_VAR(i, axis_scaling);  // 3 floats
    #endif

    #if ENABLED(FWRETRACT)
      EEPROM_READ_VAR(i, autoretract_enabled);
      EEPROM_READ_VAR(i, retract_length);
      #if EXTRUDERS > 1
        EEPROM_READ_VAR(i, retract_length_swap);
      #else
        EEPROM_READ_VAR(i, dummy);
      #endif
      EEPROM_READ_VAR(i, retract_feedrate);
      EEPROM_READ_VAR(i, retract_zlift);
      EEPROM_READ_VAR(i, retract_recover_length);
      #if EXTRUDERS > 1
        EEPROM_READ_VAR(i, retract_recover_length_swap);
      #else
        EEPROM_READ_VAR(i, dummy);
      #endif
      EEPROM_READ_VAR(i, retract_recover_feedrate);
    #endif // FWRETRACT

    EEPROM_READ_VAR(i, volumetric_enabled);

    for (int8_t e = 0; e < EXTRUDERS; e++)
      EEPROM_READ_VAR(i, filament_size[e]);

    #if ENABLED(IDLE_OOZING_PREVENT)
      EEPROM_READ_VAR(i, IDLE_OOZING_enabled);
    #endif

    #if MB(ALLIGATOR)
      EEPROM_READ_VAR(i, motor_current);
    #endif

    if (eeprom_checksum == stored_checksum) {
      Config_Postprocess();
      ECHO_SV(DB, version);
      ECHO_MV(" stored settings retrieved (", i);
      ECHO_EM(" bytes)");
    }
    else {
      ECHO_LM(ER, "EEPROM checksum mismatch");
      Config_ResetDefault();
    }
  }

  #if ENABLED(EEPROM_CHITCHAT)
    Config_PrintSettings();
  #endif
}
示例#8
0
/**
 * M501 - Retrieve Configuration
 */
void Config_RetrieveSettings() {
  EEPROM_START();
  char stored_ver[4];
  EEPROM_READ(stored_ver); // read stored version
  uint16_t stored_checksum;
  EEPROM_READ(stored_checksum);
  //  SERIAL_ECHOLN("Version: [" << ver << "] Stored version: [" << stored_ver << "]");
  if (strncmp(version,stored_ver,3) == 0) {
    eeprom_checksum = 0; // clear before reading first "real data"

    // version number match
    EEPROM_READ(axis_steps_per_unit);
    EEPROM_READ(max_feedrate);
    EEPROM_READ(max_acceleration_units_per_sq_second);
    EEPROM_READ(acceleration);
    EEPROM_READ(retract_acceleration);
    EEPROM_READ(minimumfeedrate);
    EEPROM_READ(mintravelfeedrate);
    EEPROM_READ(minsegmenttime);
    EEPROM_READ(max_xy_jerk);
    EEPROM_READ(max_z_jerk);
    EEPROM_READ(max_e_jerk);
    EEPROM_READ(add_homeing);
#ifndef ULTIPANEL
#ifdef PRINT_PLA
    int plaPreheatHotendTemp, plaPreheatHPBTemp, plaPreheatFanSpeed;
#endif
#ifdef PRINT_ABS
    int absPreheatHotendTemp, absPreheatHPBTemp, absPreheatFanSpeed;
#endif
#endif
#ifdef PRINT_PLA
    EEPROM_READ(plaPreheatHotendTemp);
    EEPROM_READ(plaPreheatHPBTemp);
    EEPROM_READ(plaPreheatFanSpeed);
#endif
    /*#ifdef PRINT_ABS
      EEPROM_READ(absPreheatHotendTemp);
      EEPROM_READ(absPreheatHPBTemp);
      EEPROM_READ(absPreheatFanSpeed);
      #endif*/
#ifndef PIDTEMP
    float Kp,Ki,Kd;
#endif
    // do not need to scale PID values as the values in EEPROM are already scaled
    EEPROM_READ(Kp);
    EEPROM_READ(Ki);
    EEPROM_READ(Kd);
#ifndef DOGLCD
    int lcd_contrast;
#endif
    EEPROM_READ(lcd_contrast);
#if !HAS_BED_PROBE
    float zprobe_zoffset;
#endif
    EEPROM_READ(zprobe_zoffset);

    if (eeprom_checksum == stored_checksum) {
      Config_Postprocess();
      SERIAL_ECHO_START;
      SERIAL_ECHO(version);
      SERIAL_ECHOPAIR(" stored settings retrieved (", (unsigned long)eeprom_index);
      SERIAL_ECHOLNPGM(" bytes)");
    } else {
      SERIAL_ERROR_START;
      SERIAL_ERRORLNPGM("EEPROM checksum mismatch");
      Config_ResetDefault();
    }
  } else {
    Config_ResetDefault();
  }
#ifdef EEPROM_CHITCHAT
  Config_PrintSettings();
#endif
}
示例#9
0
/*----------------------------------------
*
* Start the massive Gcode processing loop
*-----------------------------------------
*/
void process_commands()
{
  int result;
  int motorChannel, motorPower;
  unsigned long codenum;
  char *starpos = NULL;
  
  if(code_seen('G'))
  {
    switch((int)code_value())
    {
    case 0: // G0 -> G1
    case 1: // G1
      break;
	  
    case 2:
	  break;
	  
    case 3:
	  break;
	  
    case 4: // G4 dwell
      //LCD_MESSAGEPGM(MSG_DWELL);
      codenum = 0;
      if(code_seen('P')) codenum = code_value(); // milliseconds to wait
      if(code_seen('S')) codenum = code_value() * 1000; // seconds to wait

      //codenum += millis();  // keep track of when we started waiting
      previous_millis_cmd = 0;//millis();
      while(++previous_millis_cmd  < codenum ){
        manage_inactivity();
		_delay_ms(1);
      }
      break;
	  
	case 5: // G5 - Absolute command motor C<Channel> P<motor power -1000 to 1000>
	     if(!Stopped) {
		     if(code_seen('C')) {
				motorChannel = code_value(); // motor channel 1,2
				if(code_seen('P')) {
					motorPower = code_value(); // motor power -1000,1000
					fault = 0; // clear fault flag
					motorControl->commandMotorPower(motorChannel, motorPower);
				} // code P
			 } // code C
	     } // stopped
	     break;
		 
    case 28:
      previous_millis_cmd = 0;
      break;
	  
    case 90: // G90
      break;
	  
    case 91: // G91
      break;
	  
    case 92: // G92
      break;
	  
	case 99: // G99 start watchdog timer. G99 T<time_in_millis> values are 15,30,60,120,250,500,1000,4000,8000 default 4000
		if( code_seen('T') ) {
			int time_val = code_value();
			watchdog_timer = new WatchdogTimer();
			watchdog_timer->watchdog_init(time_val);
		}
		break;
		
	case 100: // G100 reset watchog timer before time interval is expired, otherwise a reset occurs
		if( watchdog_timer != NULL )
			watchdog_timer->watchdog_reset();
		break;
		
    } // switch
  } // if code
  /*-------------------------------------
  * M Code processing
  *--------------------------------------
  */
  else if(code_seen('M'))
  {
    switch( (int)code_value() )
    {
	case 0: // M0 Set real time output off
		realtime_output = 0;
		break;
		
	case 1: // M1 Set real time output on
		realtime_output = 1;
		break;
		
	case 2: // M2 [C<channel> E<encoder pin>] set smart controller (default) with optional encoder pin per channel
		motor_status = 0;
		motorControl = &roboteqDevice;
		if(code_seen('C')) {
			channel = code_value();
			if(code_seen('E')) {
				pin_number = code_value();
				motorControl->createEncoder(channel, pin_number);
			}
		}
		break;
		
	//Set PWM motor driver, map pin to channel, this will check to prevent free running motors during inactivity
	//For a PWM motor control subsequent G5 commands are affected here. 	
	case 3: // M3 P<pin> C<channel> D<direction pin> E<default dir> W<encoder pin> [T<timer mode 0-3>] [R<resolution 8,9,10 bits>] [X<prescale 0-7>]
	  motor_status = 1;
	  pin_number = -1;
	  encode_pin = 0;
	  motorControl = (AbstractMotorControl*)&hBridgeDriver;
	  ((HBridgeDriver*)motorControl)->setMotors((PWM**)&ppwms);
	  ((HBridgeDriver*)motorControl)->setDirectionPins((Digital**)&pdigitals);
	  if(code_seen('P'))
          pin_number = code_value();
	  else
		 break;
      if(code_seen('C')) {
        channel = code_value();
		if( code_seen('D'))
			dir_pin = code_value();
		else 
			break;
		if( code_seen('E'))
			dir_default = code_value();
		else
			break;
		if( code_seen('W')) 
			encode_pin = code_value(); 
		((HBridgeDriver*)motorControl)->createPWM(channel, pin_number, dir_pin, dir_default, timer_pre, timer_res);
		if(encode_pin)
			motorControl->createEncoder(channel, encode_pin);
      } // code C
	  break;
	
	case 4:
		// BLDC motor
		// BLDC: lo1,lo2,lo3,hi1,hi2,hi3,hall1,hall2,hall3,enable
		// hall sensors hall1:bit0,hall2:bit1,hall2:bit2 of commu array offset
		// BLDC3PhaseSensor* tmotor1 = new BLDC3PhaseSensor(29,31,33,8,9,10,64,65,66);
		// tmotor2 = new BLDC3PhaseSensor(35,37,39,11,12,13,67,68,69,30);
		// tmotor1->motor_init();
		// tmotor2->Motor_init();
		break;
		
	case 11: // M11 C<channel> D<duration> Set maximum motor cycle duration for given channel.
		if( code_seen('C') ) {
			channel = code_value();
			if( code_seen('D') )
				motorControl->setDuration(channel, code_value());
		}
	break;
	
	case 12: // M12 C<channel> P<offset> set amount to add to G5 for min motor power
		if( code_seen('C') ) {
			channel = code_value();
			if( code_seen('P'))
				motorControl->setMinMotorPower(channel, code_value());
		}
		break;
			 	
    case 17:
      break;
	  
	case 18: //M18
	  break;
	  
	case 31: //M31 take time since the start of the SD print or an M109 command
      stoptime=0;//millis();
      char time[30];
      t =(stoptime-starttime)/1000;
      int sec,min;
      min=t/60;
      sec=t%60;
      sprintf_P(time, PSTR("%i min, %i sec"), min, sec);
      SERIAL_PGMLN(timeCntrlHdr);
	  SERIAL_PGM("1 ");
      SERIAL_PORT.println(time);
	  SERIAL_PORT.flush();
      //lcd_setstatus(time);
      //autotempShutdown();
      break;
	  
	case 33: // M33 P<ultrasonic pin> D<min. distance in cm> [E<direction 1- forward facing, 0 - reverse facing sensor>] 
	// link Motor controller to ultrasonic sensor, the sensor must exist via M301
	  motor_status = 1;
	  pin_number = 0;
	  if(code_seen('P')) {
        pin_number = code_value();
		if( code_seen('D'))
			dist = code_value();
		else 
			break;
		dir_face = 1; // default forward
		if( code_seen('E'))
			dir_face = code_value(); // optional
		motorControl->linkDistanceSensor((Ultrasonic**)psonics, pin_number, dist, dir_face);
	  } // code_seen = 'P'
	  break;
	  
	  case 35: //M35 - Clear all digital pins
		for(int i = 0; i < 10; i++) {
			 if(pdigitals[i]) {
				unassignPin(pdigitals[i]->pin);
				delete pdigitals[i];
				pdigitals[i] = 0;
			 }
		}
	  break;
		  
	  case 36: //M36 - Clear all analog pins
		  	 for(int i = 0; i < 10; i++) {
			  	  if(panalogs[i]) {
					unassignPin(panalogs[i]->pin);
				  	delete panalogs[i];
					panalogs[i] = 0;
			  	  }
		  	 }
	  break;
	  
	  case 37: //M36 - Clear all PWM pins
	  for(int i = 0; i < 10; i++) {
		  if(ppwms[i]) {
			  unassignPin(ppwms[i]->pin);
			  delete ppwms[i];
			  ppwms[i] = 0;
		  }
	  }
	  break;
	  
	  case 38: //M38 - Remove PWM pin P<pin>
	  	  pin_number = -1;
	  	  if (code_seen('P')) {
		  	  pin_number = code_value();
		  	  if(unassignPin(pin_number) ) {
			  	  for(int i = 0; i < 10; i++) {
				  	  if(ppwms[i] && ppwms[i]->pin == pin_number) {
					  	  delete ppwms[i];
						  ppwms[i] = 0;
				  	  } // pwms == pin_number
			  	  } // i iterate pwm array
		  	  } // unassign pin
	  	  } // code P
	  break;
	  
	  case 39: //M39 - Remove Persistent Analog pin P<pin>
	  	  pin_number = -1;
	  	  if (code_seen('P')) {
		  	  pin_number = code_value();
		  	  if(unassignPin(pin_number) ) {
			  	  for(int i = 0; i < 10; i++) {
				  	  if(panalogs[i] && panalogs[i]->pin == pin_number) {
					  	delete panalogs[i];
						panalogs[i] = 0;
					    break;
				  	  }
			  	  }
		  	  }
	  	  }
	  break;
			
	  case 40: //M40 - Remove persistent digital pin P<pin>
	       pin_number = -1;
	       if (code_seen('P')) {
		       pin_number = code_value();
		       if(unassignPin(pin_number) ) {
			       for(int i = 0; i < 10; i++) {
				       if(pdigitals[i] && pdigitals[i] == pin_number) {
					       delete pdigitals[i];
						   pdigitals[i] = 0;
					       break;
				       }
			       }
			   }
		   }
	  break;
		
	  case 41: //M41 - Create persistent digital pin, Write digital pin HIGH P<pin> (this gives you a 5v source on pin)
	     pin_number = -1;
	     if (code_seen('P')) {
		     pin_number = code_value();
		     if( assignPin(pin_number) ) {
			     dpin = new Digital(pin_number);
				 dpin->setPin(pin_number);
			     dpin->pinMode(OUTPUT);
			     dpin->digitalWrite(HIGH);
			     for(int i = 0; i < 10; i++) {
				     if(!pdigitals[i]) {
					     pdigitals[i] = dpin;
					     break;
				     }
			     }
			 } else {
			     for(int i = 0; i < 10; i++) {
				     if(pdigitals[i] && pdigitals[i]->pin == pin_number) {
						 pdigitals[i]->setPin(pin_number);
						 pdigitals[i]->pinMode(OUTPUT);
					     pdigitals[i]->digitalWrite(HIGH);
					     break;
				     }
			     }
		     }
	     }
	break;
	     
    case 42: //M42 - Create persistent digital pin, Write digital pin LOW P<pin> (This gives you a grounded pin)
	  pin_number = -1;
	  if (code_seen('P')) {
        pin_number = code_value();
		if( assignPin(pin_number) ) {
			dpin = new Digital(pin_number);
			dpin->pinMode(OUTPUT);
			dpin->digitalWrite(LOW);
			for(int i = 0; i < 10; i++) {
				if(!pdigitals[i]) {
					pdigitals[i] = dpin;
					break;
				}
			}
		} else {
			for(int i = 0; i < 10; i++) {
				if(pdigitals[i] && pdigitals[i]->pin == pin_number) {
					pdigitals[i]->setPin(pin_number);
					pdigitals[i]->pinMode(OUTPUT);
					pdigitals[i]->digitalWrite(LOW);
					break;
				}
			}
		}
	  }
     break;
	 
	case 43: // M43 Read from digital pin P<pin>
        pin_number = -1;
        if (code_seen('P'))
          pin_number = code_value();
   		if( assignPin(pin_number) ) {
			dpin = new Digital(pin_number);
			dpin->pinMode(INPUT);
			int res = dpin->digitalRead();
			delete &dpin;
			unassignPin(pin_number); // reset it since this is a one-shot
			SERIAL_PGMLN(digitalPinHdr);
			SERIAL_PGM("1 ");
			SERIAL_PORT.println(pin_number);
			SERIAL_PGM("2 ");
			SERIAL_PORT.println(res);
			SERIAL_PORT.println();
			SERIAL_PORT.flush();
		}
		break;
	
	case 44: // M44 -Read digital pin with pullup P<pin>
        pin_number = -1;
        if (code_seen('P'))
          pin_number = code_value();
    	if( assignPin(pin_number) ) {
			dpin = new Digital(pin_number);
			dpin->pinMode(INPUT_PULLUP);
			int res = dpin->digitalRead();
			delete &dpin;
			unassignPin(pin_number); // reset it since this is a one-shot
			SERIAL_PGMLN(digitalPinHdr);
			SERIAL_PGM("1 ");
			SERIAL_PORT.println(pin_number);
			SERIAL_PGM("2 ");
			SERIAL_PORT.println(res);
			SERIAL_PORT.flush();
		}
		break;
		
	 // PWM value between 0 and 255, default timer mode is 2; clear on match, default resolution is 8 bits, default prescale is 1
	 // Prescale: 1,2,4,6,7,8,9 = none, 8, 64, 256, 1024, external falling, external rising
	 // Use M445 to disable pin permanently or use timer more 0 to stop pulse without removing pin assignment
     case 45: // M45 - set up PWM P<pin> S<power val 0-255> [T<timer mode 0-3>] [R<resolution 8,9,10 bits>] [X<prescale 0-7>]
	  pin_number = -1;
	  if(code_seen('P') )
          pin_number = code_value();
	  else
		 break;
      if (code_seen('S')) {
        int pin_status = code_value();
		int timer_mode = 2;
		int timer_res = 8;
		int timer_pre = 1;
		
		if( pin_status < 0 || pin_status > 255)
			pin_status = 0;
		// this is a semi-permanent pin assignment so dont add if its already assigned
		if( assignPin(pin_number) ) {
			// timer mode 0-3: 0 stop, 1 toggle on compare match, 2 clear on match, 3 set on match (see HardwareTimer)
			if( code_seen('T') ) {
				timer_mode = code_value();
				if( timer_mode < 0 || timer_mode > 3 )
					timer_mode = 0;
			}
			// timer bit resolution 8,9, or 10 bits
			if( code_seen('R')) {
				timer_res = code_value();
				if( timer_res < 8 || timer_res > 10 )
					timer_res = 8;
			}
			// X - prescale 0-7 for power of 2
			if( code_seen('X') ) {
				timer_pre = code_value();
				if( timer_pre < 0 || timer_pre > 7 )
					timer_pre = 0;
			}
			for(int i = 0; i < 10; i++) {
				if(ppwms[i] == NULL) {
					ppin = new PWM(pin_number);
					ppin->init(pin_number);
					ppin->setPWMPrescale(timer_pre);
					ppin->setPWMResolution(timer_res);
					ppin->pwmWrite(pin_status,timer_mode); // default is 2, clear on match. to turn off, use 0
					ppwms[i] = ppin;
					break;
				}
			}
		 } else { // reassign pin with new mode and value
			 for(int i = 0; i < 10; i++) {
				 if(ppwms[i] && ppwms[i]->pin == pin_number) {
					 // timer mode 0-3: 0 stop, 1 toggle on compare match, 2 clear on match, 3 set on match (see HardwareTimer)
					 if( code_seen('T') ) {
						 timer_mode = code_value();
						 if( timer_mode < 0 || timer_mode > 3 )
							timer_mode = 2; // mess up the code get clear on match default
					 }
					 //ppwms[i]->init();
					 ppwms[i]->pwmWrite(pin_status, timer_mode);
					 break;
				 }
			 }
		 }
      }
	  break;
	  
	  case 46: // M46 -Read analog pin P<pin>
        pin_number = -1;
        if (code_seen('P'))
          pin_number = code_value();
		if( assignPin(pin_number) ) {
			apin = new Analog(pin_number);
			int res = apin->analogRead();
			res = apin->analogRead(); // de-jitter
			delete &apin;
			unassignPin(pin_number);
			SERIAL_PGMLN(analogPinHdr);
			SERIAL_PGM("1 ");
			SERIAL_PORT.println(pin_number);
			SERIAL_PGM("2 ");
			SERIAL_PORT.println(res);
			SERIAL_PORT.flush();
		}
     break;
	 
     case 80: // M80 - Turn on Power Supply
	  #if defined(PS_ON_PIN) && PS_ON_PIN > -1
        SET_OUTPUT(PS_ON_PIN); //GND
        WRITE(PS_ON_PIN, PS_ON_AWAKE);
        // If you have a switch on suicide pin, this is useful
        #if defined(SUICIDE_PIN) && SUICIDE_PIN > -1
            SET_OUTPUT(SUICIDE_PIN);
            WRITE(SUICIDE_PIN, HIGH);
        #endif
      #endif
	  break;

     case 81: // M81 - Turn off Power
      if( motorControl->isConnected())
		motorControl->commandEmergencyStop();
      #if defined(SUICIDE_PIN) && SUICIDE_PIN > -1
        suicide();
      #elif defined(PS_ON_PIN) && PS_ON_PIN > -1
        SET_OUTPUT(PS_ON_PIN);
        WRITE(PS_ON_PIN, PS_ON_ASLEEP);
      #endif
	    _delay_ms(1000); // Wait 1 sec before switch off
	  break;

    case 82:
      break;
	  
    case 83:
      break;
	  
    case 84: // M84
      break;
	  
    case 85: // M85
      break;
	  
    case 92: // M92
      break;
	  
	case 104: // M104
      break;
	  
    case 105 : // M105
      SERIAL_PORT.println();
      break; 
	   
    case 106: //M106
        break;
		
    case 107: //M107
        break;
	
    case 109: // M109 
      break;
	  
    case 115: // M115
      SERIAL_PGMLN(MSG_M115_REPORT);
      break;
	  
    case 117: 
      break;
	  
    case 114: // M114
      break;
	  
    case 120: // M120
      break;
	  
    case 121: // M121
      break;
	  
    case 119: // M119
      break; 
	  
	case 140: // M140 
      break;
	  
    case 150: // M150 - set an RGB value
        byte red;
        byte grn;
        byte blu;
        if(code_seen('R')) red = code_value();
        if(code_seen('U')) grn = code_value();
        if(code_seen('B')) blu = code_value();
        //SendColors(red,grn,blu);
      break;
	  
	case 190: // M190
      break;
	  
    case 200:
      break;
	  
    case 201: // M201
      //reset_acceleration_rates();
      break;
	  
    case 202: // M202
      break;
	  
    case 203:
      break;
	  
    case 204: // M204 acceleration T
      if(code_seen('T')) ;//max_acceleration = code_value();
      break;
	  
    case 205: //M205 advanced settings:  maximum travel speed T=travel
      if(code_seen('T')) ;//maxtravelspeed = code_value();
	  break;
	
    case 206: 
      break;
	  
    case 207:
	  break;
	  
    case 208:
      break;
	  
    case 209: 
	  break;
	  
    case 218:
	  break;
	  
    case 220: 
      if(code_seen('S'))
      {
        
      }
    break;
	
    case 221: 
      if(code_seen('S'))
      {
        
      }
    break;

	case 226: // M226 P<pin number> S<pin state>- Wait until the specified pin reaches the state required, default is opposite current state
      if(code_seen('P')) {
        int pin_number = code_value(); // pin number
        int pin_state = -1; // required pin state - default is inverted
        if(code_seen('S')) 
			pin_state = code_value(); // required pin state
		if( assignPin(pin_number) ) {
			Digital pn = new Digital(pin_number);
            pn.pinMode(INPUT);
            int target;
            switch(pin_state){
				case 1:
					target = HIGH;
					break;
				case 0:
					target = LOW;
					break;
				default:
					target = !pn.digitalRead(); // opposite of current state
					break;
            } // switch
            while(pn.digitalRead() != target) {
              manage_inactivity();
            } // while
			delete &pn;
			unassignPin(pin_number);
          } // if pin_number
      } // code seen p
    break;

	case 227: // M227 P<pin number> S<pin state>- INPUT_PULLUP Wait until the specified pin reaches the state required, default is opposite current state
	if(code_seen('P')) {
		int pin_number = code_value(); // pin number
		int pin_state = -1; // required pin state - default is inverted
		if(code_seen('S'))
		pin_state = code_value(); // required pin state
		if( assignPin(pin_number) ) {
			Digital pn = new Digital(pin_number);
			pn.pinMode(INPUT_PULLUP);
			int target;
			switch(pin_state){
				case 1:
				target = HIGH;
				break;
				case 0:
				target = LOW;
				break;
				default:
				target = !pn.digitalRead(); // opposite of current state
				break;
			} // switch
			while(pn.digitalRead() != target) {
				manage_inactivity();
			} // while
			delete &pn;
			unassignPin(pin_number);
		} // if pin_number
	} // code seen p
	break;
		
	case 240: // M240  Triggers a camera by emulating a Canon RC-1 : http://www.doc-diy.net/photo/rc-1_hacked/
	/*
      #if defined(PHOTOGRAPH_PIN) && PHOTOGRAPH_PIN > -1
        const uint8_t NUM_PULSES=16;
        const float PULSE_LENGTH=0.01524;
        for(int i=0; i < NUM_PULSES; i++) {
          WRITE(PHOTOGRAPH_PIN, HIGH);
          _delay_ms(PULSE_LENGTH);
          WRITE(PHOTOGRAPH_PIN, LOW);
          _delay_ms(PULSE_LENGTH);
        }
        delay(7.33);
        for(int i=0; i < NUM_PULSES; i++) {
          WRITE(PHOTOGRAPH_PIN, HIGH);
          _delay_ms(PULSE_LENGTH);
          WRITE(PHOTOGRAPH_PIN, LOW);
          _delay_ms(PULSE_LENGTH);
        }
      #endif
	  */
    break;
	
	case 250: 
      break;
	
    case 280: 
      break;

    case 300: // M300 - emit ultrasonic pulse on given pin and return duration P<pin number>
      uspin = code_seen('P') ? code_value() : 0;
      if (uspin > 0) {
		Ultrasonic* upin = new Ultrasonic(uspin);
		pin_number = upin->getPin();
		SERIAL_PGMLN(sonicCntrlHdr);
		SERIAL_PGM("1 "); // pin
		SERIAL_PORT.println(pin_number);
		SERIAL_PGM("2 "); // sequence
		SERIAL_PORT.println(upin->getRange()); // range
		delete upin;
      }
    break;
		
    case 301: // M301 - toggle ultrasonic during inactivity P<pin>
		// wont assign pin 0 as its sensitive
		uspin = code_seen('P') ? code_value() : 0;
		// this is a permanent pin assignment so dont add if its already assigned
		if( assignPin(uspin) ) {
			for(int i = 0; i < 10; i++) {
				if(!psonics[i]) {
					psonics[i] = new Ultrasonic(uspin);
					break;
				}
			}
		}
		break;
	
	case 302: // M302 - disable ultrasonic during inactivity P<pin>
		uspin = code_seen('P') ? code_value() : 0;
		unassignPin(uspin);
		for(int i = 0; i < 10; i++) {
				if(psonics[i] && psonics[i] == uspin) {
					delete psonics[i];
					psonics[i] = 0;
					break;
				}
		}
      break;
	
	case 303: // M303 - toggle analog read during inactivity P<pin> with exclusion range 0-1024 via L<min> H<max> if present
		// wont assign pin 0 as its sensitive
		// if optional L and H values exclude readings in that range
		uspin = code_seen('P') ? code_value() : 0;
		// this is a permanent pin assignment so dont add if its already assigned
		if( assignPin(uspin) ) {
			for(int i = 0; i < 10; i++) {
				if(!panalogs[i]) {
					analogRanges[0][i] = code_seen('L') ? code_value() : 0;
					analogRanges[1][i] = code_seen('H') ? code_value() : 0;
					panalogs[i] = new Analog(uspin);
					panalogs[i]->pinMode(INPUT);
					break;
				}
			}
		} else { // reassign values for assigned pin
			for(int i = 0; i < 10; i++) {
				if(panalogs[i] && panalogs[i]->pin == uspin) {
					analogRanges[0][i] = code_seen('L') ? code_value() : 0;
					analogRanges[1][i] = code_seen('H') ? code_value() : 0;
					break;
				}
			}
		}
      break;
	  
	case 304:// M304 - toggle analog read INPUT_PULLUP during inactivity P<pin> with exclusion range 0-1024 via L<min> H<max> if present
		// if optional L and H values exclude readings in that range
		uspin = code_seen('P') ? code_value() : 0;
		// this is a permanent pin assignment so dont add if its already assigned
		if( assignPin(uspin) ) {
			for(int i = 0; i < 10; i++) {
				if(!panalogs[i]) {
					analogRanges[0][i] = code_seen('L') ? code_value() : 0;
					analogRanges[1][i] = code_seen('H') ? code_value() : 0;
					panalogs[i] = new Analog(uspin);
					panalogs[i]->pinMode(INPUT_PULLUP);
					break;
				}
			}
		} else { // reassign values for assigned pin
			for(int i = 0; i < 10; i++) {
				if(panalogs[i] && panalogs[i]->pin == uspin) {
					analogRanges[0][i] = code_seen('L') ? code_value() : 0;
					analogRanges[1][i] = code_seen('H') ? code_value() : 0;
					break;
				}
			}
		}
      break;
	
	case 305: // M305 - toggle digital read during inactivity M305 P<pin> T<target> 0 or 1 for target value, default 0
		// wont assign pin 0 as its sensitive
		// Looks for target value for pin during inactive, if so publish with <digitalpin> header and 1 - pin, 2 - value
		uspin = code_seen('P') ? code_value() : 0;
		digitarg = code_seen('T') ? code_value() : 0;
		// this is a permanent pin assignment so dont add if its already assigned
		if( assignPin(uspin) ) {
			for(int i = 0; i < 10; i++) {
				if(!pdigitals[i]) {
					pdigitals[i] = new Digital(uspin);
					pdigitals[i]->pinMode(INPUT);
					digitalTarget[i] = digitarg;
					break;
				}
			}
		} else {
			for(int i = 0; i < 10; i++) {
				if(pdigitals[i] && pdigitals[i]->pin == uspin) {
					digitalTarget[i] = digitarg;
					break;
				}
			}
		}
      break;
	
	case 306:// M306 - INPUT_PULLUP toggle digital read during inactivity M306 P<pin> T<target> 0 or 1 for target value, default 0
		// Looks for target value for pin during inactive, if so publish with <digitalpin> header and 1 - pin 2 - value
		uspin = code_seen('P') ? code_value() : 0;
		digitarg = code_seen('T') ? code_value() : 0;
		// this is a permanent pin assignment so dont add if its already assigned
		if( assignPin(uspin) ) {
			for(int i = 0; i < 10; i++) {
				if(!pdigitals[i]) {
					pdigitals[i] = new Digital(uspin);
					pdigitals[i]->pinMode(INPUT_PULLUP);
					digitalTarget[i] = digitarg;
					break;
				}
			}
		} else {
			for(int i = 0; i < 10; i++) {
				if(pdigitals[i] && pdigitals[i]->pin == uspin) {
					digitalTarget[i] = digitarg;
					break;
				}
			}
		}
		break;
	
    case 349: // M349
	/*
        if(code_seen('P')) bedKp = code_value();
        if(code_seen('I')) bedKi = scalePID_i(code_value());
        if(code_seen('D')) bedKd = scalePID_d(code_value());

        updatePID();
        SERIAL_PROTOCOL(MSG_OK);
        SERIAL_PROTOCOL(" p:");
        SERIAL_PROTOCOL(bedKp);
        SERIAL_PROTOCOL(" i:");
        SERIAL_PROTOCOL(unscalePID_i(bedKi));
        SERIAL_PROTOCOL(" d:");
        SERIAL_PROTOCOL(unscalePID_d(bedKd));
        SERIAL_PROTOCOLLN("");
		*/
      break;
	  
   case 350:
    break;
	
   case 351: 
      break;
	  
    case 400:
      
    break;
	
    case 401:
        
    break;
	
    case 402:
        
    break;
	
	case 444: // M444 - set battery warning threshold V<volts*10>!!!!!!!!!!!!!!!!!! REMEMBER ITS TIMES 10 !!!!!!!!!!!!!!!!!!
	    if(code_seen('V')) {
			BatteryThreshold = code_value(); // times 10!!!
		}
		break;
		
	case 445: // M445 - Turn off pulsed write pin - disable PWM P<pin>
      pin_number = -1;
      if (code_seen('P'))
          pin_number = code_value();
	  unassignPin(pin_number);
	  for(int i = 0; i < 10; i++) {
			if(ppwms[i] && ppwms[i] == pin_number) {
				ppwms[i]->pwmWrite(0,0); // default is 2, clear on match. to turn off, use 0 
				delete ppwms[i];
				ppwms[i] = 0;
				break;
			}
	  }
	  break;
	  
    case 500: // M500 Store settings in EEPROM
        Config_StoreSettings();
    break;
	
    case 501: // M501 Read settings from EEPROM
        Config_RetrieveSettings();
    break;
	
    case 502: // M502 Revert to default settings
        Config_ResetDefault();
    break;
	
    case 503: // M503 print settings currently in memory
        Config_PrintSettings();
    break;
	
    case 540:
        //if(code_seen('S')) abort_on_endstop_hit = code_value() > 0;
    break;
	
    case 600: 
    break;
	
    case 605: 
    break;
	
	case 666:
    break;
	  
	case 700: // return stats
	  // Check startup - does nothing if bootloader sets MCUSR to 0
	  mcu = MCUSR;
	  if(mcu & 1) SERIAL_PGMLN(MSG_POWERUP);
	  if(mcu & 2) SERIAL_PGMLN(MSG_EXTERNAL_RESET);
	  if(mcu & 4) SERIAL_PGMLN(MSG_BROWNOUT_RESET);
	  if(mcu & 8) SERIAL_PGMLN(MSG_WATCHDOG_RESET);
	  if(mcu & 32) SERIAL_PGMLN(MSG_SOFTWARE_RESET);
	  MCUSR=0;
	  SERIAL_PGM(VERSION_STRING);
	  #ifdef STRING_VERSION_CONFIG_H
	  #ifdef STRING_CONFIG_H_AUTHOR
	  SERIAL_PGM(MSG_CONFIGURATION_VER);
	  SERIAL_PGM(STRING_VERSION_CONFIG_H);
	  SERIAL_PGM(MSG_AUTHOR);
	  SERIAL_PGMLN(STRING_CONFIG_H_AUTHOR);
	  SERIAL_PGM("Compiled: ");
	  SERIAL_PGM(__DATE__);
	  #endif
	  #endif
	  SERIAL_PGM(MSG_FREE_MEMORY);
	  SERIAL_PORT.println(freeMemory());
	  SERIAL_PORT.flush();
	  break; 
	  
	case 701: // Report digital pins in use
		SERIAL_PGMLN("Digital Pins:");
		for(int i = 0; i < 10; i++) {
			if( pdigitals[i] ) {
				SERIAL_PORT.print(pdigitals[i]->pin);
				switch(pdigitals[i]->mode) {
					case INPUT:
						SERIAL_PGMLN(" INPUT");
						break;
					case INPUT_PULLUP:
						SERIAL_PGMLN(" INPUT_PULLUP");
						break;
					case OUTPUT:
						SERIAL_PGMLN(" OUTPUT");
						break;
				}
			}
		}
		SERIAL_PORT.println();
		SERIAL_PORT.flush();
		break;
		
	case 702: // Report analog pins in use
		SERIAL_PGMLN("Analog Pins:");
		for(int i = 0; i < 10; i++) {
			if( panalogs[i]  ) {
				SERIAL_PORT.print(panalogs[i]->pin);
				switch(panalogs[i]->mode) {
					case INPUT:
					SERIAL_PGMLN(" INPUT");
					break;
					case INPUT_PULLUP:
					SERIAL_PGMLN(" INPUT_PULLUP");
					break;
					case OUTPUT:
					SERIAL_PGMLN(" OUTPUT");
					break;
				}
			}
		}
		SERIAL_PORT.println();
		SERIAL_PORT.flush();
		break;
		
	case 703: // Report ultrasonic pins in use
		SERIAL_PGMLN("Ultrasonic Pins:");
		for(int i = 0; i < 10; i++) {
			if( psonics[i] ) {
				SERIAL_PGM("Pin:");
				SERIAL_PORT.println(psonics[i]->getPin());
			}
		}
		SERIAL_PORT.flush();
		break;
		
	case 704: // Report PWM pins in use
		SERIAL_PGMLN("PWM Pins:");
		for(int i = 0; i < 10; i++) {
			if( ppwms[i] ) {
				SERIAL_PGM("Pin:");
				SERIAL_PORT.print(ppwms[i]->pin);
				SERIAL_PGM(" Timer channel:");
				SERIAL_PORT.print(ppwms[i]->channel);
				switch(ppwms[i]->mode) {
					case INPUT:
						SERIAL_PGM(" INPUT");
						break;
					case INPUT_PULLUP:
						SERIAL_PGM(" INPUT_PULLUP");
						break;
					case OUTPUT:
						SERIAL_PGM(" OUTPUT");
						break;
				}
				SERIAL_PORT.println();
			}
			SERIAL_PORT.flush();
		}
		break;
		
	case 705:
			// see if it has propulsion attributes declared with M3 as interrupt serviced
			switch(motor_status) {
				case 0:
					SERIAL_PGMLN("Multi Channel Motor Controller:");
					break;
				case 1:
					SERIAL_PGMLN("H-Bridge Brushed DC Motor Driver(s):");
					break;
				case 2:
					SERIAL_PGMLN("Brushless DC Motor Driver(s):");
					break;
			}
			for(int i = 0 ; i < motorControl->getChannels(); i++) { //per channel
					SERIAL_PGM("Motor channel:");
					SERIAL_PORT.print(i+1);
					SERIAL_PGM(" Min Power:");
					SERIAL_PORT.print(motorControl->getMinMotorPower(i+1));
					SERIAL_PGM(" Speed:");
					SERIAL_PORT.print(motorControl->getMotorSpeed(i+1));
					SERIAL_PGM(" Curr. Dir:");
					SERIAL_PORT.print(motorControl->getCurrentDirection(i+1));
					SERIAL_PGM(" Default. Dir:");
					SERIAL_PORT.println(motorControl->getDefaultDirection(i+1));
					SERIAL_PGM(" Encoder Pin:");
					if(motorControl->getWheelEncoder(i+1)) {
						SERIAL_PORT.print(motorControl->getWheelEncoder(i+1)->pin);
						SERIAL_PGM(" Count:");
						SERIAL_PORT.print(motorControl->getEncoderCount(i+1));
						SERIAL_PGM(" Duration:");
						SERIAL_PORT.println(motorControl->getMaxMotorDuration(i+1));
					} else {
						SERIAL_PGMLN("None.");
					}
			}
			SERIAL_PGM("Ultrasonic pins:");
			if( motorControl->totalUltrasonics() ) {
				SERIAL_PORT.println(motorControl->totalUltrasonics());
				for(int j = 0; j < motorControl->totalUltrasonics(); j++) {
					SERIAL_PGM("Pin:");
					SERIAL_PORT.print(psonics[motorControl->getUltrasonicIndex(i+1)]->getPin());
					SERIAL_PGM(" Facing:");
					SERIAL_PORT.print(motorControl->getUltrasonicFacing(i+1));
					SERIAL_PGM(" Shutdown cm:");
					SERIAL_PORT.println(motorControl->getMinMotorDist(i+1));
				}
			} else {
						SERIAL_PGMLN("None.");
			}
			SERIAL_PORT.flush();
			break;
			
	case 706: // Report all pins in use
		for(int i = 0; i < 100; i++) {
			if( pinAssignment(i) == PIN_ASSIGNED ) {
				SERIAL_PORT.print(i);
				SERIAL_PORT.print(',');
			}
		}
		SERIAL_PORT.println();
		SERIAL_PORT.flush();
		break;
		
	case 797:
		break;
		
	case 798: // Report controller status
		//SERIAL_PGMLN(motorCntrlHdr);
		if( motorControl->isConnected() ) {
			for(int i = 0; i < motorControl->getChannels() ; i++ ) {
				SERIAL_PGM("Motor Channel:");
				SERIAL_PORT.println(i+1);
				char* buf = motorControl->getDriverInfo(i+1);
				while(*buf) {
					SERIAL_PORT.print(*buf);
					buf++;
				}
			}
		}
		SERIAL_PORT.println();
		SERIAL_PORT.flush();
		break;	
		
	case 799: // Reset Motor controller
		motorControl->commandEmergencyStop();
		break;		
		
	case 800: 
		break;
		
	case 801: // IMU
		prh = new PitchRollHeading();
		orient = prh->getPitchRollHeading();
		SERIAL_PGMLN(posCntrlHdr);
		SERIAL_PGM("1 ");
		SERIAL_PORT.println(orient.pitch);
		SERIAL_PGM("2 ");
		SERIAL_PORT.println(orient.roll);
		SERIAL_PGM("3 ");
		SERIAL_PORT.println(orient.heading);
		break;	
			
	case 802: // Acquire analog pin data M802 Pnn Sxxx Mxxx P=Pin number, S=number readings, M=microseconds per reading. X - pullup.
		// Publish <dataset> 1 - pin, 2 - reading
		if( code_seen('P')) {
			apin = new Analog((uint8_t)code_value());
			if( code_seen('X') )
				apin->pinMode(INPUT_PULLUP);
			else
				apin->pinMode(INPUT);
		}
		nread = 0;
		if( code_seen('S') ) {
			nread = code_value();
		}
		micros = 0;
		if( code_seen('M')) {
			micros = (uint32_t)code_value();
		}
		values = new int(nread);
		for(int i = 0; i < nread; i++) {
			*(values+i) = apin->analogRead();
			for(int j = 0; j < micros; j++) _delay_us(1);
		}
		SERIAL_PGMLN(datasetHdr);
		SERIAL_PORT.println();
		for(int i = 0; i < nread; i++) {
			SERIAL_PORT.print(i+1); // sequence
			SERIAL_PORT.print(' ');
			// 0 element is pin number
			if( i == 0 )
				SERIAL_PORT.println(apin->pin);
			else
				SERIAL_PORT.println(*(values+i)); // value
		}
		delete values;
		SERIAL_PORT.println();
		SERIAL_PORT.flush();
		break;	
		
	case 803:
		break;	
		
	case 907: 
		break; 
		 
	case 908: // M908 Control digital trimpot directly.
		uint8_t current;
		if(code_seen('P')) channel=code_value();
		if(code_seen('S')) current=code_value();
		digitalPotWrite(channel, current);
		break;
		
    case 999: // M999: Reset
		Stopped = false;
		//lcd_reset_alert_level();
		gcode_LastN = Stopped_gcode_LastN;
		//FlushSerialRequestResend();
		if( watchdog_timer != NULL )
			delete watchdog_timer;
		watchdog_timer = new WatchdogTimer();
		watchdog_timer->watchdog_init(15); // 15 ms
	
  } // switch m code

  } else { // if M code
    SERIAL_PGMLN(MSG_UNKNOWN_COMMAND);
    //SERIAL_PORT.println(cmdbuffer[bufindr]);
  }

}
void Config_RetrieveSettings()
{
    int i=EEPROM_OFFSET;
    char stored_ver[4];
    char ver[4]=EEPROM_VERSION;
    EEPROM_READ_VAR(i,stored_ver); //read stored version
    //  SERIAL_ECHOLN("Version: [" << ver << "] Stored version: [" << stored_ver << "]");
    if (strncmp(ver,stored_ver,3) == 0)
    {
        // version number match
        EEPROM_READ_VAR(i,axis_steps_per_unit);
        EEPROM_READ_VAR(i,max_feedrate);  
        EEPROM_READ_VAR(i,max_acceleration_units_per_sq_second);
        
        // steps per sq second need to be updated to agree with the units per sq second (as they are what is used in the planner)
		reset_acceleration_rates();
        
        EEPROM_READ_VAR(i,acceleration);
        EEPROM_READ_VAR(i,retract_acceleration);
        EEPROM_READ_VAR(i,minimumfeedrate);
        EEPROM_READ_VAR(i,mintravelfeedrate);
        EEPROM_READ_VAR(i,minsegmenttime);
        EEPROM_READ_VAR(i,max_xy_jerk);
        EEPROM_READ_VAR(i,max_z_jerk);
        EEPROM_READ_VAR(i,max_e_jerk);
        EEPROM_READ_VAR(i,add_homing);
        #ifdef DELTA
		EEPROM_READ_VAR(i,endstop_adj);
		EEPROM_READ_VAR(i,delta_radius);
		EEPROM_READ_VAR(i,delta_diagonal_rod);
		EEPROM_READ_VAR(i,delta_segments_per_second);
        #endif
        #ifndef ULTIPANEL
        int plaPreheatHotendTemp, plaPreheatHPBTemp, plaPreheatFanSpeed;
        int absPreheatHotendTemp, absPreheatHPBTemp, absPreheatFanSpeed;

        #endif
        EEPROM_READ_VAR(i,plaPreheatHotendTemp);
        EEPROM_READ_VAR(i,plaPreheatHPBTemp);
        EEPROM_READ_VAR(i,plaPreheatFanSpeed);
        EEPROM_READ_VAR(i,absPreheatHotendTemp);
        EEPROM_READ_VAR(i,absPreheatHPBTemp);
        EEPROM_READ_VAR(i,absPreheatFanSpeed);
        

        
        EEPROM_READ_VAR(i,zprobe_zoffset);
        #ifndef PIDTEMP
        float Kp,Ki,Kd;
        #endif
        // do not need to scale PID values as the values in EEPROM are already scaled		
        EEPROM_READ_VAR(i,Kp);
        EEPROM_READ_VAR(i,Ki);
        EEPROM_READ_VAR(i,Kd);
        #ifndef DOGLCD
        int lcd_contrast;
        #endif
        EEPROM_READ_VAR(i,lcd_contrast);
		#ifdef SCARA
		EEPROM_READ_VAR(i,axis_scaling);
		#endif

		#ifdef FWRETRACT
		EEPROM_READ_VAR(i,autoretract_enabled);
		EEPROM_READ_VAR(i,retract_length);
		#if EXTRUDERS > 1
		EEPROM_READ_VAR(i,retract_length_swap);
		#endif
		EEPROM_READ_VAR(i,retract_feedrate);
		EEPROM_READ_VAR(i,retract_zlift);
		EEPROM_READ_VAR(i,retract_recover_length);
		#if EXTRUDERS > 1
		EEPROM_READ_VAR(i,retract_recover_length_swap);
		#endif
		EEPROM_READ_VAR(i,retract_recover_feedrate);
		#endif

		EEPROM_READ_VAR(i, volumetric_enabled);
		EEPROM_READ_VAR(i, filament_size[0]);
#if EXTRUDERS > 1
		EEPROM_READ_VAR(i, filament_size[1]);
#if EXTRUDERS > 2
		EEPROM_READ_VAR(i, filament_size[2]);
#endif
#endif
		calculate_volumetric_multipliers();
		// Call updatePID (similar to when we have processed M301)
		updatePID();
        SERIAL_ECHO_START;
        SERIAL_ECHOLNPGM("Stored settings retrieved");
    }
    else
    {
        Config_ResetDefault();
    }
    #ifdef EEPROM_CHITCHAT
      Config_PrintSettings();
    #endif
}
/**
 * Retrieve Configuration Settings - M501
 */
void Config_RetrieveSettings() {

  int i = EEPROM_OFFSET;
  char stored_ver[7];
  char ver[7] = EEPROM_VERSION;
  EEPROM_READ_VAR(i, stored_ver); // read stored version
  //ECHO_EM("Version: [" << ver << "] Stored version: [" << stored_ver << "]");

  if (strncmp(ver, stored_ver, 6) != 0) {
    Config_ResetDefault();
  }
  else {
    float dummy = 0;

    // version number match
    EEPROM_READ_VAR(i, axis_steps_per_unit);
    EEPROM_READ_VAR(i, max_feedrate);
    EEPROM_READ_VAR(i, max_acceleration_units_per_sq_second);

    // steps per sq second need to be updated to agree with the units per sq second (as they are what is used in the planner)
    reset_acceleration_rates();

    EEPROM_READ_VAR(i, acceleration);
    EEPROM_READ_VAR(i, retract_acceleration);
    EEPROM_READ_VAR(i, travel_acceleration);
    EEPROM_READ_VAR(i, minimumfeedrate);
    EEPROM_READ_VAR(i, mintravelfeedrate);
    EEPROM_READ_VAR(i, minsegmenttime);
    EEPROM_READ_VAR(i, max_xy_jerk);
    EEPROM_READ_VAR(i, max_z_jerk);
    EEPROM_READ_VAR(i, max_e_jerk);
    EEPROM_READ_VAR(i, home_offset);
    EEPROM_READ_VAR(i, hotend_offset);

    #if !MECH(DELTA)
      EEPROM_READ_VAR(i, zprobe_zoffset);
    #endif

    #if HEATER_USES_AD595
      EEPROM_READ_VAR(i, ad595_offset);
      EEPROM_READ_VAR(i, ad595_gain);
      for (int8_t h = 0; h < HOTENDS; h++)
        if (ad595_gain[h] == 0) ad595_gain[h] == TEMP_SENSOR_AD595_GAIN;
    #endif

    #if MECH(DELTA)
      EEPROM_READ_VAR(i, endstop_adj);
      EEPROM_READ_VAR(i, delta_radius);
      EEPROM_READ_VAR(i, delta_diagonal_rod);
      EEPROM_READ_VAR(i, sw_endstop_max);
      EEPROM_READ_VAR(i, tower_adj);
      EEPROM_READ_VAR(i, diagrod_adj);
      EEPROM_READ_VAR(i, z_probe_offset);
      // Update delta constants for updated delta_radius & tower_adj values
      set_delta_constants();
    #endif //DELTA

    #if DISABLED(ULTIPANEL)
      int plaPreheatHotendTemp, plaPreheatHPBTemp, plaPreheatFanSpeed,
          absPreheatHotendTemp, absPreheatHPBTemp, absPreheatFanSpeed,
          gumPreheatHotendTemp, gumPreheatHPBTemp, gumPreheatFanSpeed;
    #endif

    EEPROM_READ_VAR(i, plaPreheatHotendTemp);
    EEPROM_READ_VAR(i, plaPreheatHPBTemp);
    EEPROM_READ_VAR(i, plaPreheatFanSpeed);
    EEPROM_READ_VAR(i, absPreheatHotendTemp);
    EEPROM_READ_VAR(i, absPreheatHPBTemp);
    EEPROM_READ_VAR(i, absPreheatFanSpeed);
    EEPROM_READ_VAR(i, gumPreheatHotendTemp);
    EEPROM_READ_VAR(i, gumPreheatHPBTemp);
    EEPROM_READ_VAR(i, gumPreheatFanSpeed);

    #if ENABLED(PIDTEMP)
      for (int8_t h = 0; h < HOTENDS; h++) {
        EEPROM_READ_VAR(i, PID_PARAM(Kp, h));
        EEPROM_READ_VAR(i, PID_PARAM(Ki, h));
        EEPROM_READ_VAR(i, PID_PARAM(Kd, h));
        EEPROM_READ_VAR(i, PID_PARAM(Kc, h));
      }
    #endif // PIDTEMP

    #if DISABLED(PID_ADD_EXTRUSION_RATE)
      int lpq_len;
    #endif
    EEPROM_READ_VAR(i, lpq_len);

    #if ENABLED(PIDTEMPBED)
      EEPROM_READ_VAR(i, bedKp);
      EEPROM_READ_VAR(i, bedKi);
      EEPROM_READ_VAR(i, bedKd);
    #endif

    #if HASNT(LCD_CONTRAST)
      int lcd_contrast;
    #endif

    EEPROM_READ_VAR(i, lcd_contrast);

    #if MECH(SCARA)
      EEPROM_READ_VAR(i, axis_scaling);  // 3 floats
    #endif

    #if ENABLED(FWRETRACT)
      EEPROM_READ_VAR(i, autoretract_enabled);
      EEPROM_READ_VAR(i, retract_length);
      #if EXTRUDERS > 1
        EEPROM_READ_VAR(i, retract_length_swap);
      #else
        EEPROM_READ_VAR(i, dummy);
      #endif
      EEPROM_READ_VAR(i, retract_feedrate);
      EEPROM_READ_VAR(i, retract_zlift);
      EEPROM_READ_VAR(i, retract_recover_length);
      #if EXTRUDERS > 1
        EEPROM_READ_VAR(i, retract_recover_length_swap);
      #else
        EEPROM_READ_VAR(i, dummy);
      #endif
      EEPROM_READ_VAR(i, retract_recover_feedrate);
    #endif // FWRETRACT

    EEPROM_READ_VAR(i, volumetric_enabled);

    for (int8_t e = 0; e < EXTRUDERS; e++)
      EEPROM_READ_VAR(i, filament_size[e]);

    calculate_volumetric_multipliers();

    #if ENABLED(IDLE_OOZING_PREVENT)
      EEPROM_READ_VAR(i, IDLE_OOZING_enabled);
    #endif

    #if MB(ALLIGATOR)
      EEPROM_READ_VAR(i, motor_current);
    #endif

    // Call updatePID (similar to when we have processed M301)
    updatePID();

    // Report settings retrieved and length
    ECHO_SV(DB, ver);
    ECHO_MV(" stored settings retrieved (", (unsigned long)i);
    ECHO_EM(" bytes)");
  }

  #if ENABLED(EEPROM_CHITCHAT)
    Config_PrintSettings();
  #endif
}
示例#12
0
void Config_RetrieveSettings()
{
    int i=EEPROM_OFFSET_READ;
    char stored_ver[4];
    char ver[4]=EEPROM_VERSION;
    unsigned long zero_pad=0;

    EEPROM_READ_VAR(i,fab_serial_code);
    EEPROM_READ_VAR(i,fab_control_serial_code);
    EEPROM_READ_VAR(i,fab_board_version);
    EEPROM_READ_VAR(i,fab_batch_number);
    EEPROM_READ_VAR(i,fab_control_batch_number);
    EEPROM_READ_VAR(i,led_board_version);
    EEPROM_READ_VAR(i,flex_board_version);
    EEPROM_READ_VAR(i,plateconn_board_version);
    EEPROM_READ_VAR(i,hotplate_board_version);
    EEPROM_READ_VAR(i,general_assembly_version);
    EEPROM_READ_VAR(i,zero_pad);

    EEPROM_READ_VAR(i,stored_ver); //read stored version
    //  SERIAL_ECHOLN("Version: [" << ver << "] Stored version: [" << stored_ver << "]");
    if (strncmp(ver,stored_ver,3) == 0)
    {
        // version number match
        EEPROM_READ_VAR(i,axis_steps_per_unit);
        EEPROM_READ_VAR(i,max_feedrate);
        EEPROM_READ_VAR(i,max_acceleration_units_per_sq_second);

        // steps per sq second need to be updated to agree with the units per sq second (as they are what is used in the planner)
		reset_acceleration_rates();

        EEPROM_READ_VAR(i,acceleration);
        EEPROM_READ_VAR(i,retract_acceleration);
        EEPROM_READ_VAR(i,minimumfeedrate);
        EEPROM_READ_VAR(i,mintravelfeedrate);
        EEPROM_READ_VAR(i,minsegmenttime);
        EEPROM_READ_VAR(i,max_xy_jerk);
        EEPROM_READ_VAR(i,max_z_jerk);
        EEPROM_READ_VAR(i,max_e_jerk);
        EEPROM_READ_VAR(i,add_homeing);
        #ifdef DELTA
		EEPROM_READ_VAR(i,endstop_adj);
		EEPROM_READ_VAR(i,delta_radius);
		EEPROM_READ_VAR(i,delta_diagonal_rod);
		EEPROM_READ_VAR(i,delta_segments_per_second);
        #endif
        #ifndef ULTIPANEL
        int plaPreheatHotendTemp, plaPreheatHPBTemp, plaPreheatFanSpeed;
        int absPreheatHotendTemp, absPreheatHPBTemp, absPreheatFanSpeed;
        #endif
        EEPROM_READ_VAR(i,plaPreheatHotendTemp);
        EEPROM_READ_VAR(i,plaPreheatHPBTemp);
        EEPROM_READ_VAR(i,plaPreheatFanSpeed);
        EEPROM_READ_VAR(i,absPreheatHotendTemp);
        EEPROM_READ_VAR(i,absPreheatHPBTemp);
        EEPROM_READ_VAR(i,absPreheatFanSpeed);
        EEPROM_READ_VAR(i,zprobe_zoffset);
        #ifndef PIDTEMP
        float Kp,Ki,Kd;
        #endif
        // do not need to scale PID values as the values in EEPROM are already scaled
        EEPROM_READ_VAR(i,Kp);
        EEPROM_READ_VAR(i,Ki);
        EEPROM_READ_VAR(i,Kd);
        #ifndef DOGLCD
        int lcd_contrast;
        #endif
        EEPROM_READ_VAR(i,lcd_contrast);
        EEPROM_READ_VAR(i,servo_retracted_angle);
        EEPROM_READ_VAR(i,servo_extended_angle);
        servo_endstop_angles[4] = servo_extended_angle;
        servo_endstop_angles[5] = servo_retracted_angle;

        EEPROM_READ_VAR(i,installed_head_id);

		// Call updatePID (similar to when we have processed M301)
		updatePID();
        SERIAL_ECHO_START;
        SERIAL_ECHOLNPGM("Stored settings retrieved");
    }
    else
    {
        Config_ResetDefault();
    }
    #ifdef EEPROM_CHITCHAT
      Config_PrintSettings();
    #endif
}