new firmware: Jagon by Hardtoe November 08, 2011 02:15AM |
Registered: 12 years ago Posts: 74 |
Re: new firmware: Jagon by Hardtoe November 08, 2011 02:29AM |
Registered: 12 years ago Posts: 74 |
Re: new firmware: Jagon by Hardtoe November 08, 2011 03:44AM |
Registered: 14 years ago Posts: 7,616 |
Generation 7 Electronics | Teacup Firmware | RepRap DIY |
Re: new firmware: Jagon by Hardtoe November 08, 2011 04:08AM |
Registered: 12 years ago Posts: 74 |
Re: new firmware: Jagon by Hardtoe November 08, 2011 06:46PM |
Registered: 12 years ago Posts: 74 |
Re: new firmware: Jagon by Hardtoe November 09, 2011 01:32PM |
Registered: 12 years ago Posts: 74 |
// divide 1000000 by divisor inline unsigned int fastDivide(unsigned int divisor) { if (divisor >= 50000) { return 20; } else { return 1000000 / divisor; } }
// divide 1000000 by divisor inline unsigned int fastDivide(unsigned int divisor) { if (divisor >= 50000) { return 20; } else if (divisor >= 47619) { return 21; } else if (divisor >= 45455) { return 22; } else if (divisor >= 43478) { return 23; } else if (divisor >= 41667) { return 24; } else if (divisor >= 40000) { return 25; } else { return 1000000 / divisor; } }
subi // compare lower byte of divisor (1 clk) sbci // compare upper byte (1 clk) br // compare failed, jump to next if statement (2 clk) ldi // load lower byte of constant (1 clk) ldi // load upper byte of constant (1 clk) br // jump to end of subroutine (2 clk)
// divide 1000000 by divisor inline unsigned int fastDivide(unsigned int divisor) { if (divisor < 40000) { if (divisor >= 50000) { return 20; } else if (divisor >= 47619) { return 21; } else if (divisor >= 45455) { return 22; } else if (divisor >= 43478) { return 23; } else if (divisor >= 41667) { return 24; } else { return 25; } } else { if (divisor > 30303) { if (divisor > 33333) { if (divisor > 35714) { if (divisor > 38461) { return 26; } else { return 27; } } else { if (divisor > 34482) { return 28; } else { return 29; } } } else { if (divisor > 35714) { if (divisor > 38461) { return 30; } else { return 31; } } else { if (divisor > 34482) { return 32; } else { return 33; } } } } else { return 1000000 / divisor; } } }
Re: new firmware: Jagon by Hardtoe November 09, 2011 03:46PM |
Registered: 12 years ago Posts: 74 |
Re: new firmware: Jagon by Hardtoe November 09, 2011 08:28PM |
Registered: 13 years ago Posts: 64 |
Re: new firmware: Jagon by Hardtoe November 09, 2011 08:56PM |
Registered: 12 years ago Posts: 74 |
Re: new firmware: Jagon by Hardtoe November 10, 2011 12:30AM |
Registered: 12 years ago Posts: 74 |
for 12000 steps per second or more: Jagon fastDivide (us): 2.14 Marlin calc_timer (us): 3.18 avr-gcc unsigned int divide (us): 30.98
Re: new firmware: Jagon by Hardtoe November 10, 2011 03:55AM |
Registered: 12 years ago Posts: 74 |
Re: new firmware: Jagon by Hardtoe November 10, 2011 11:03AM |
Registered: 12 years ago Posts: 74 |
Re: new firmware: Jagon by Hardtoe November 10, 2011 01:51PM |
Registered: 13 years ago Posts: 2,705 |
Re: new firmware: Jagon by Hardtoe November 10, 2011 02:21PM |
Registered: 12 years ago Posts: 74 |
Re: new firmware: Jagon by Hardtoe November 10, 2011 10:53PM |
Registered: 12 years ago Posts: 74 |
void TimerOne::setPeriod(long microseconds) // AR modified for atomic access { long cycles = (F_CPU / 2000000) * microseconds; // the counter runs backwards after TOP, interrupt is at BOTTOM so divide microseconds by 2 if(cycles < RESOLUTION) clockSelectBits = _BV(CS10); // no prescale, full xtal else if((cycles >>= 3) < RESOLUTION) clockSelectBits = _BV(CS11); // prescale by /8 else if((cycles >>= 3) < RESOLUTION) clockSelectBits = _BV(CS11) | _BV(CS10); // prescale by /64 else if((cycles >>= 2) < RESOLUTION) clockSelectBits = _BV(CS12); // prescale by /256 else if((cycles >>= 2) < RESOLUTION) clockSelectBits = _BV(CS12) | _BV(CS10); // prescale by /1024 else cycles = RESOLUTION - 1, clockSelectBits = _BV(CS12) | _BV(CS10); // request was out of bounds, set as maximum oldSREG = SREG; cli(); // Disable interrupts for 16 bit register access ICR1 = pwmPeriod = cycles; // ICR1 is TOP in p & f correct pwm mode SREG = oldSREG; TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12)); TCCR1B |= clockSelectBits; // reset clock select register, and starts the clock }
Re: new firmware: Jagon by Hardtoe November 10, 2011 11:38PM |
Registered: 12 years ago Posts: 74 |
Re: new firmware: Jagon by Hardtoe November 11, 2011 02:56AM |
Registered: 13 years ago Posts: 2,705 |
Re: new firmware: Jagon by Hardtoe November 11, 2011 03:36AM |
Registered: 12 years ago Posts: 74 |
Re: new firmware: Jagon by Hardtoe November 11, 2011 03:38AM |
Registered: 14 years ago Posts: 7,616 |
(F_CPU / 2000000)This is not really a divide, as both are constant, so optimisation will replace that with the also constant result.
Generation 7 Electronics | Teacup Firmware | RepRap DIY |
Re: new firmware: Jagon by Hardtoe November 11, 2011 03:43AM |
Registered: 14 years ago Posts: 3,742 |
Re: new firmware: Jagon by Hardtoe November 11, 2011 04:52AM |
Registered: 16 years ago Posts: 1,094 |
Re: new firmware: Jagon by Hardtoe November 11, 2011 06:38PM |
Registered: 12 years ago Posts: 74 |
Quote
repetier
Acceleration to 18000 is not fast enough. Some peaple have extruder with 1300 Steps/mm and want it to run at 25 mm/s for fast retracts. That's 32500 Hz. I never thought of this, until they complained some errors due to this high frequency. Off couse, you can always clamp this to possible speeds. Still better then missing steps or nothing.
Quote
Triffid_Hunter
How do you handle the junction between moves? With a trajectory planner, you can have one axis slow down and reverse while another keeps barreling along at full speed, don't want to have to queue-flush then hope to pick up the other side quick enough..
please use macros or calculations in your divide optimiser and timer stuff, it's more common than you may think to have alternate crystals in our arduinos. one of mine has a 16MHz, the other has a 20MHz.
Re: new firmware: Jagon by Hardtoe November 11, 2011 09:14PM |
Registered: 12 years ago Posts: 74 |
Re: new firmware: Jagon by Hardtoe November 12, 2011 05:42AM |
Registered: 14 years ago Posts: 7,616 |
Quote
i was able to get the min step period down to 36us from 48us.
Generation 7 Electronics | Teacup Firmware | RepRap DIY |
Re: new firmware: Jagon by Hardtoe November 12, 2011 06:04AM |
Registered: 12 years ago Posts: 74 |
Quote
Traumflug
A side question: how do you get such numbers? By counting instructions? By moving the axis faster until you get an interrupt flood?
inline void interrupt() { StepCommand* currentCommand; if (stepCommandBuffer->notEmpty()) { // cutting out all of the actual stepping code to keep the forum post shorter skippedLast = false; } else { if (!skippedLast) { Serial.println((unsigned int) skips++); } skippedLast = true; } }
#define MIN_STEP_DELAY 35
Re: new firmware: Jagon by Hardtoe November 12, 2011 06:26AM |
Registered: 12 years ago Posts: 74 |
inline void calculateVelocity() { if (accelerationConstant != 0) { // check if we need to update velocity currentVelocityError += currentStepDelay; if (currentVelocityError > accelerationConstant) { do { currentVelocityError -= accelerationConstant; if (numStepsLeft < (numSteps >> 1)) { currentVelocity += VELOCITY_RESOLUTION; } else { currentVelocity -= VELOCITY_RESOLUTION; } } while (currentVelocityError > accelerationConstant); currentStepDelay = fastDivide(currentVelocity); if (currentVelocity <= maxVelocity) { prototypeStep.setStepDelay(currentStepDelay); } } } }
Re: new firmware: Jagon by Hardtoe November 12, 2011 08:06AM |
Registered: 16 years ago Posts: 1,094 |
Re: new firmware: Jagon by Hardtoe November 12, 2011 01:34PM |
Registered: 12 years ago Posts: 74 |
Quote
Triffid_Hunter
Getting rid of the reliance on speedy ramp generation for eradicating inter-move delays is interesting with this architecture- you need to somehow insert a marker to pull the next set of directions and step masks into the step time queue- perhaps a zero value, or a -1? Then you can queue up multiple blended moves if possible/necessary complete with direction changes.
Quote
Triffid_Hunter
Does that create a linear increase and decrease in velocity? There are a surprising number of simple algorithms that sound good at first, until you realise that they cause exponential increase in velocity, eg; the original FiveD firmware algorithm.
/** * calculate velocity for next step. this can be thought of as a 2D Bresenham * algorithm where one dimension is the velocity in steps per second, and the * other dimension is time in microseconds. * * runtime is slower for long periods due to looping through the velocity * calculation multiple times. * * runtime for short periods is very fast *per period* because we may only * loop once or even not at all. * * runtime for constant velocity moves should be very good as the entire * algorithm will be skipped. */ inline void calculateVelocity() { if (accelerationConstant != 0) { // accumulate how long its been since the last velocity increase currentVelocityError += currentStepDelay; // if it's been longer than the period we need to increase velocity linearly... if (currentVelocityError > accelerationConstant) { do { // ...then remove the length of the period to increase velocity... currentVelocityError -= accelerationConstant; // ...figure out whether we should increase or decrease our velocity using // a cheapo ramp function... if (numStepsLeft < (numSteps >> 1)) { currentVelocity += VELOCITY_RESOLUTION; } else { currentVelocity -= VELOCITY_RESOLUTION; } // ...and keep looping until we have accumulated the correct velocity } while (currentVelocityError > accelerationConstant); // convert the calculated velocity into a step delay using a fast division algorithm currentStepDelay = fastDivide(currentVelocity); // clamp the max velocity if (currentVelocity <= maxVelocity) { prototypeStep.setStepDelay(currentStepDelay); } } } }
Quote
Triffid_Hunter
on a totally unrelated note, in your heatercontroller.h, it looks like M109 Snnn won't set the heater to nnn first then wait for it to catch up. Please support both M109 by itself, and M109 Snnn
inline int waitExtruderTemp(float targetTemp) { PT_YIELDING(); PT_BEGIN(&subState); // if targetTemp is a real number... if (!isnan(targetTemp)) { // ...tell heaterZero (extruder) to warm up to targetTemp heaterZero->setTarget(targetTemp); } // while heaterZero (extruder) has not yet reached the target temp... while (!heaterZero->atTargetTemp()) { // ...delay for 1 second (allowing other threads to execute in the meantime)... PT_DELAY(&subState, 1000); // ...and report the current temperatures back to the host readCurrentTemp(); } PT_END(&subState); }
Re: new firmware: Jagon by Hardtoe November 12, 2011 06:52PM |
Registered: 16 years ago Posts: 1,094 |
Re: new firmware: Jagon by Hardtoe November 12, 2011 07:33PM |
Registered: 12 years ago Posts: 74 |
Quote
Triffid_Hunter
If I understand your architecture correctly, the step timer buffer is emptied at the end of the first move, so you can switch the step mask then start re-filling the buffer with Y's ramp-up. I'm suggesting that it would be best to buffer the step and direction masks too, and use some sort of marker in the step timer buffer to mark when to pull the new mask.
Quote
Triffid_Hunter
ah ok I see now, but at line 61, what happens if there's no S parameter, ie just a bare M109?
My start.gcode has a bare M109, so it sits and waits for whatever temperature user has set previously, and I can reuse the same gcode with different temperatures and it'll behave correctly (in sprinter at least, and teacup too I think).
There' s no guarantee that you can use a leftover S, what happens if someone sends M104 S210, M140 S60, M109 ?