Welcome! Log In Create A New Profile

Advanced

Strange timings in source code

Posted by ArtemKuchin 
Strange timings in source code
February 22, 2017 08:27AM
Hello!

I decided to look at the code to understand how things work in multistepping and found some thing which bother me smiling smiley
Don't judge me too hard please and excuse me if i a blind and do not see obvious things.

1) Multistepping switch is independant of CPU speed


if (step_rate > 20000) { // If steprate > 20kHz >> step 4 times
step_rate >>= 2;
step_loops = 4;
}
else if (step_rate > 10000) { // If steprate > 10kHz >> step 2 times
step_rate >>= 1;
step_loops = 2;
}
else {
step_loops = 1;
}

step rate is calculated from total steps for the move, speed, steps per mm
oat inverse_millimeters = 1.0 / block->millimeters;
float inverse_mm_s = fr_mm_s * inverse_millimeters;
block->nominal_rate = ceil(block->step_event_count * inverse_mm_s); // (step/sec) Always > 0

So, even if i have 300Mhz overclocked nitrogen cooled atmega smiling smiley it still will switch to double stepping starting from 10000 steps per second

2) Very optimistick double/quad stepping selecttion

For calculating step_rate about the planner uses total steps for moves on each axis
block->step_event_count = MAX4(block->steps[X_AXIS], block->steps[Y_AXIS], block->steps[Z_AXIS], esteps);

Selected is only one axis, the one with maximum steps. One thing is to move just X axis 100mm/s at 100steps/mm and another
is to move XY at 100m/s at 200s/m + 3 geared extruders at 400 s/m. It is just different number of pulses for per one interupt. Maybe i am missing something

3) Strange calculation of step rate from distance

Again, maybe i don't see something, but how STEP RATE depends on DISTANCE? AFAIK it only depend on SPEED.

code uses
foat inverse_millimeters = 1.0 / block->millimeters;
float inverse_mm_s = fr_mm_s * inverse_millimeters;
block->nominal_rate = ceil(block->step_event_count * inverse_mm_s); // (step/sec) Always > 0
Lets moove 300mm at speed of 100mm/s and 200 steps per mm
total steps: 300*200=60000
inverse_millimeters = 1.0 / 300 = 1/300
inverse_mm_s = 100 / 300= 1/3
nominal_rate = 60000 /3 = 20000 step/seconds

Now, we have speed of 100m/s and 200 steps per mm, how many step per second is it?
200*100=20000
so,
block->nominal_rate = STEPS_PER_MM * fr_mm_s;

STEP_PER_MM is always loaded from EEPROM.
And now we no longer need float point math here. I am kinda lost by fr_mm_s is a float type.

4) Mixing extruder is not accounted in multstepping

If using mixing extruder the steps for all extruders are not in step_event_count variable, so, steps for all extrruders are not counted for
selecting multistepping.


5) Strange delay calculation for minimum pulse time

#define CYCLES_EATEN_BY_CODE 240
#define STEP_PULSE_CYCLES ((MINIMUM_STEPPER_PULSE) * CYCLES_PER_MICROSECOND)
#define MINIMUM_STEPPER_PULSE 0
#define CYCLES_PER_MICROSECOND (F_CPU / 1000000UL) // 16 or 20
#if STEP_PULSE_CYCLES > CYCLES_EATEN_BY_CODE
while ((uint32_t)(TCNT0 - pulse_start) < STEP_PULSE_CYCLES - CYCLES_EATEN_BY_CODE) { /* nada */ }
#endif

By default on Arduino TIMER 0 runs with prescaler 64, that is 250Khz. Means 4us per tick.
As i understand from the code CYCLES_EATEN_BY_CODE is measures in TIMER 0 ticks.
240 ticks is approximatelly 1ms
Where this number came from? If it is the time for stepping commands to complete then it is terrible, because it means no more than 1000 steps per second
are actually possible. I don't think it is actually the case, but number is strange.
Re: Strange timings in source code
February 22, 2017 05:11PM
One more thing.
while ((uint32_t)(TCNT0 - pulse_start) < STEP_PULSE_CYCLES - CYCLES_EATEN_BY_CODE) { /* nada */ }

but time counter is never reset, so, it can actually overflow during ISR and this comparison will not hold true for some time
Re: Strange timings in source code
February 26, 2017 03:03PM
Did test. Timer0 really overflows millions of times. Lucky probably nobody uses this option.
Sorry, only registered users may post in this forum.

Click here to login