Firmware/FiveD on Arduino

From RepRap
Revision as of 21:29, 27 February 2010 by Triffid hunter (talk | contribs) (page creation- constant acceleration section candidate for own page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Rewrite of FiveD firmware for the atmega168-based Arduino by Triffid Hunter

This firmware is loosely based on the official FiveD Firmware, however it uses 100% integer math, and works very hard to minimize/eliminate long math operations in interrupt context.

Constant Acceleration

The official FiveD firmware changes speed by a fixed amount each step, however this also alters the step time. acceleration = dv/dt, so with a fixed dv but a changing dt, acceleration changes during a move. This makes high speeds quite unattainable as the acceleration quickly outstrips the motor's ability to keep up.

FiveD on Arduino contains a constant acceleration implementation based on [this article]

I don't remember how I calculated and integrated the acceleration term into the below, feel free to work it out from the article and update this description.

  • sf and ef are start and end feedrates in mm/min
  • dx, dy and dz are move distances along each axis
  • distance is the movement distance, equivalent to sqrt(dx^2 + dy^2 + dz^2)
  • ts is total steps, equivalent to max(dx, dy, dz).
  • c and end_c are start and end step timer values
  • CF shall refer to conversion factors necessary for unit translations but mostly irrelevant to describing this process.

so, here we go

c (tick/step) = um/step * min/mm * CF[min->tick]
um/step       = distance / ts
sf            = mm/min

c             = tick/step
              = min/step * CF[min->tick]
              = distance / ts / sf * CF[min->tick]

and conversely,

end_c = distance / ts / ef * CF[min->tick]

from [the article]

n = ts * sf^2 * 4 / (sf^2 - ef^2)           [Equation 16]

and in each step we calculate

c = c - (2c / (4n + 1))                     [Equation 13]
n += 1

however I have integrated 4n+1 into the initial setup of n, which simplified this to:

n = (ts * sf^2 / ((sf^2 - ef^2) / 4)) + 1

then after each step

c = c - (2c / n)
n += 4

c must be checked against end_c - because this is an integer approximation of a recursive function, mere loss of precision causes significant cumulative error. I had to implement c and end_c as 24.8 fixed point in order to maintain usable resemblance to the ideal values.

As a result of its calculation, n is positive when accelerating and negative when decelerating so we don't need to differentiate between them.

Since sf^2, ef^2 and ((sf^2 - ef^2) / 4) are used fairly often, I precalculate them into ssq, esq and dsq respectively in my implementation.

Also, since ssq, esq and dsq are only ever used in ratio with one another, I can scale sf and ef by any factor I like in order to keep the precision within 32 bits.