Welcome! Log In Create A New Profile

Advanced

Sprinter narrow pulse width

Posted by macegr 
Sprinter narrow pulse width
January 06, 2012 11:00PM
My machine has been out of commission for a few months, after a major rework attempt. Finally got some wiring repaired and have been testing all the newer firmware.

Had very high hopes for Sprinter, but it somehow didn't run well at all. No smooth acceleration like I saw in videos...just rough, noisy, stuttering motion. Decided to tear it all down and look at the pulsetrain coming out of Sprinter. Discovered that the output pulses were extremely short...only two microseconds. The STEP_DELAY_MICROS didn't do what I thought to extend the pulse, just time between pulses.

The machine is a RepStrap I guess, made from a Sony CAST-Pro assembly robot. I have been using the original drivers, which apparently don't like such a short pulse. I looked at this part of the Sprinter source:
      while(((unsigned long)timediff) >= interval && axis_steps_remaining[primary_axis] > 0) {
        steps_done++;
        steps_remaining--;
        axis_steps_remaining[primary_axis]--; timediff -= interval;
        do_step(primary_axis);
        axis_previous_micros[primary_axis] += interval;
        for(int i=0; i < NUM_AXIS; i++) if(i != primary_axis && axis_steps_remaining > 0) {
          axis_error = axis_error - delta;
          if(axis_error < 0) {
            do_step(i); axis_steps_remaining--;
            axis_error = axis_error + delta[primary_axis];
          }
        }
        #ifdef STEP_DELAY_RATIO
        if(timediff >= interval) delayMicroseconds(long_step_delay_ratio * interval / 10000);
        #endif
        #ifdef STEP_DELAY_MICROS
        if(timediff >= interval) delayMicroseconds(STEP_DELAY_MICROS);
        #endif
      }
    }
  }
  #ifdef DEBUG_MOVE_TIME
    log_ulong("_MOVE_TIME - This move took", micros()-startmove);
  #endif
  
  if(DISABLE_X) disable_x();
  if(DISABLE_Y) disable_y();
  if(DISABLE_Z) disable_z();
  if(DISABLE_E) disable_e();
  
  // Update current position partly based on direction, we probably can combine this with the direction code above...
  for(int i=0; i < NUM_AXIS; i++) {
    if (destination > current_position) current_position = current_position + steps_taken /  axis_steps_per_unit;
    else current_position = current_position - steps_taken / axis_steps_per_unit;
  }
}

void do_step(int axis) {
  switch(axis){
  case 0:
    WRITE(X_STEP_PIN, HIGH);
    break;
  case 1:
    WRITE(Y_STEP_PIN, HIGH);
    break;
  case 2:
    WRITE(Z_STEP_PIN, HIGH);
    break;
  case 3:
    WRITE(E_STEP_PIN, HIGH);
    break;
  }
  steps_taken[axis]+=1;
  WRITE(X_STEP_PIN, LOW);
  WRITE(Y_STEP_PIN, LOW);
  WRITE(Z_STEP_PIN, LOW);
  WRITE(E_STEP_PIN, LOW);
}

I decided that instead of turning each pin on and then immediately off, I would turn each one on if needed and then turn them all off. Some pulses would be wider, but they'd all be at minimum some width more than 2us.

      while(((unsigned long)timediff) >= interval && axis_steps_remaining[primary_axis] > 0) {
        steps_done++;
        steps_remaining--;
        axis_steps_remaining[primary_axis]--; timediff -= interval;
        do_step(primary_axis);
        axis_previous_micros[primary_axis] += interval;
        for(int i=0; i < NUM_AXIS; i++) if(i != primary_axis && axis_steps_remaining > 0) {
          axis_error = axis_error - delta;
          if(axis_error < 0) {
            do_step(i); axis_steps_remaining--;
            axis_error = axis_error + delta[primary_axis];
          }
        }

        #ifdef STEP_DELAY_RATIO
        if(timediff >= interval) delayMicroseconds(long_step_delay_ratio * interval / 10000);
        #endif
        #ifdef STEP_DELAY_MICROS
        if(timediff >= interval) delayMicroseconds(STEP_DELAY_MICROS);
        #endif
      
        kill_steps();

      }
    }
  }
  #ifdef DEBUG_MOVE_TIME
    log_ulong("_MOVE_TIME - This move took", micros()-startmove);
  #endif
  
  if(DISABLE_X) disable_x();
  if(DISABLE_Y) disable_y();
  if(DISABLE_Z) disable_z();
  if(DISABLE_E) disable_e();
  
  // Update current position partly based on direction, we probably can combine this with the direction code above...
  for(int i=0; i < NUM_AXIS; i++) {
    if (destination > current_position) current_position = current_position + steps_taken /  axis_steps_per_unit;
    else current_position = current_position - steps_taken / axis_steps_per_unit;
  }
}

void do_step(int axis) {
  switch(axis){
  case 0:
    WRITE(X_STEP_PIN, HIGH);
    break;
  case 1:
    WRITE(Y_STEP_PIN, HIGH);
    break;
  case 2:
    WRITE(Z_STEP_PIN, HIGH);
    break;
  case 3:
    WRITE(E_STEP_PIN, HIGH);
    break;
  }
  steps_taken[axis]+=1;

}

void kill_steps() {
 
  WRITE(X_STEP_PIN, LOW);
  WRITE(Y_STEP_PIN, LOW);
  WRITE(Z_STEP_PIN, LOW);
  WRITE(E_STEP_PIN, LOW);
  
}

This is up to a 37uS pulse block now, maybe a bit long but OK for the speeds we use now. Sprinter and Pronterface are now running butter-smooth. Just need to tweak my filament settings again.
Re: Sprinter narrow pulse width
January 07, 2012 10:14AM
Very interesting research.
Have you measured the pulses generated by Marlin?
Re: Sprinter narrow pulse width
January 07, 2012 08:02PM
I have not. I did test Teacup, the pulse width varies a bit with feedrate but the shortest pulses are about 12uS instead of 2uS. The pulse width seems to vary when more axes are used, similar to how Sprinter works with my change.
Re: Sprinter narrow pulse width
January 11, 2012 08:59PM
Teacup already does what you just altered sprinter to do, hence the saner pulse widths smiling smiley


-----------------------------------------------
Wooden Mendel
Teacup Firmware
Re: Sprinter narrow pulse width
January 12, 2012 03:14AM
Would be interesting if it did the opposite...activate all pulses moving in a given stepframe at the same time. Then you'd automatically have diagonal steps when needed.
Re: Sprinter narrow pulse width
April 20, 2012 03:37PM
I ran into this problem with a TB6560AHQ based board. I measured 60usec using Teacup and 1.4usec using Marlin.
The TB6560AHQ datasheet says in needs 30usec with a 330pF cap to set the timing. I'm not sure what frequency my TB6550AHQ is running at but this sure explains the wierd things I have been seeing.

My post is [forums.reprap.org] has scope pictures.
Re: Sprinter narrow pulse width
May 30, 2012 02:13AM
Good research.

I appriciative...
Sorry, only registered users may post in this forum.

Click here to login