Store distances in the TARGET structure always in micrometers.

This is a intrusive patch and for now, it's done for the X axis only.
To make comparison with the former approach easier ...

The advantages of this change:

- Converting from mm to steps in gcode_parse.c and back in dda.c
  wastes cycles and accuracy.

- In dda.c, UM_PER_STEP simply goes away, so distance calculations
  work now with STEPS_PER_MM > 500 just fine. 1/16 microstepping
  on threaded rods (Z axis) becomes possible.

- Distance calculations (feedrate, acceleration, ...) become much
  simpler.

- A wide range of STEPS_PER_M can now be handled at reasonable
  (4 decimal digit) accuracy with a simple macro. Formerly,
  we were limited to 500 steps/mm, now we can do 4'096 steps/mm
  and could easily raise this another digit.

Disadvantages:

- STEPS_PER_MM is gone in config.h, using STEPS_PER_M is required,
  because the preprocessor refuses to compare numbers with decimal
  points in them.

- The DDA has to store the position in steps anyways to avoid
  rounding errors.
This commit is contained in:
Markus Hitter 2011-05-17 16:42:47 +02:00
parent 22a5b428c6
commit c96ea0c773
14 changed files with 236 additions and 72 deletions

View File

@ -48,12 +48,22 @@
All numbers are fixed point integers, so no more than 3 digits to the right of the decimal point, please :-) All numbers are fixed point integers, so no more than 3 digits to the right of the decimal point, please :-)
*/ */
/// calculate these values appropriate for your machine /** \def STEPS_PER_M
/// for threaded rods, this is (steps motor per turn) / (pitch of the thread) steps per meter ( = steps per mm * 1000 )
/// for belts, this is (steps per motor turn) / (number of gear teeth) / (belt module)
/// half-stepping doubles the number, quarter stepping requires * 4, etc. calculate these values appropriate for your machine
/// valid range = 0.020 to 4194.303
#define STEPS_PER_MM_X 320.000 for threaded rods, this is
(steps motor per turn) / (pitch of the thread) * 1000
for belts, this is
(steps per motor turn) / (number of gear teeth) / (belt module) * 1000
half-stepping doubles the number, quarter stepping requires * 4, etc.
valid range = 20 to 4'0960'000 (0.02 to 40960 steps/mm)
*/
#define STEPS_PER_M_X 320000
#define STEPS_PER_MM_Y 320.000 #define STEPS_PER_MM_Y 320.000
#define STEPS_PER_MM_Z 320.000 #define STEPS_PER_MM_Z 320.000

View File

@ -45,16 +45,22 @@
*/ */
#define HOST #define HOST
/* /** \def STEPS_PER_M
Values reflecting the gearing of your machine. steps per meter ( = steps per mm * 1000 )
All numbers are fixed point integers, so no more than 3 digits to the right of the decimal point, please :-)
calculate these values appropriate for your machine calculate these values appropriate for your machine
for threaded rods, this is (steps motor per turn) / (pitch of the thread)
for belts, this is (steps per motor turn) / (number of gear teeth) / (belt module) for threaded rods, this is
(steps motor per turn) / (pitch of the thread) * 1000
for belts, this is
(steps per motor turn) / (number of gear teeth) / (belt module) * 1000
half-stepping doubles the number, quarter stepping requires * 4, etc. half-stepping doubles the number, quarter stepping requires * 4, etc.
valid range = 20 to 4'0960'000 (0.02 to 40960 steps/mm)
*/ */
#define STEPS_PER_MM_X 320.000 #define STEPS_PER_M_X 320000
#define STEPS_PER_MM_Y 320.000 #define STEPS_PER_MM_Y 320.000
#define STEPS_PER_MM_Z 200.000 #define STEPS_PER_MM_Z 200.000

View File

@ -50,11 +50,22 @@
All numbers are fixed point integers, so no more than 3 digits to the right of the decimal point, please :-) All numbers are fixed point integers, so no more than 3 digits to the right of the decimal point, please :-)
*/ */
// calculate these values appropriate for your machine /** \def STEPS_PER_M
// for threaded rods, this is (steps motor per turn) / (pitch of the thread) steps per meter ( = steps per mm * 1000 )
// for belts, this is (steps per motor turn) / (number of gear teeth) / (belt module)
// The GEN6 board uses 1/8 microstepping, so multiply your values by 8. calculate these values appropriate for your machine
#define STEPS_PER_MM_X (320.000*8)
for threaded rods, this is
(steps motor per turn) / (pitch of the thread) * 1000
for belts, this is
(steps per motor turn) / (number of gear teeth) / (belt module) * 1000
half-stepping doubles the number, quarter stepping requires * 4, etc.
valid range = 20 to 4'0960'000 (0.02 to 40960 steps/mm)
*/
#define STEPS_PER_M_X (5000*8)
#define STEPS_PER_MM_Y (320.000*8) #define STEPS_PER_MM_Y (320.000*8)
#define STEPS_PER_MM_Z (200.000*8) #define STEPS_PER_MM_Z (200.000*8)

View File

@ -53,12 +53,22 @@
All numbers are fixed point integers, so no more than 3 digits to the right of the decimal point, please :-) All numbers are fixed point integers, so no more than 3 digits to the right of the decimal point, please :-)
*/ */
/// calculate these values appropriate for your machine /** \def STEPS_PER_M
/// for threaded rods, this is (steps motor per turn) / (pitch of the thread) steps per meter ( = steps per mm * 1000 )
/// for belts, this is (steps per motor turn) / (number of gear teeth) / (belt module)
/// half-stepping doubles the number, quarter stepping requires * 4, etc. calculate these values appropriate for your machine
/// valid range = 0.020 to 4194.303
#define STEPS_PER_MM_X 40.000 for threaded rods, this is
(steps motor per turn) / (pitch of the thread) * 1000
for belts, this is
(steps per motor turn) / (number of gear teeth) / (belt module) * 1000
half-stepping doubles the number, quarter stepping requires * 4, etc.
valid range = 20 to 4'0960'000 (0.02 to 40960 steps/mm)
*/
#define STEPS_PER_M_X 40000
#define STEPS_PER_MM_Y 40.000 #define STEPS_PER_MM_Y 40.000
#define STEPS_PER_MM_Z 320.000 #define STEPS_PER_MM_Z 320.000

View File

@ -50,16 +50,27 @@
All numbers are fixed point integers, so no more than 3 digits to the right of the decimal point, please :-) All numbers are fixed point integers, so no more than 3 digits to the right of the decimal point, please :-)
*/ */
// calculate these values appropriate for your machine /** \def STEPS_PER_M
// for threaded rods, this is (steps motor per turn) / (pitch of the thread) steps per meter ( = steps per mm * 1000 )
// for belts, this is (steps per motor turn) / (number of gear teeth) / (belt module)
// half-stepping doubles the number, quarter stepping requires * 4, etc. calculate these values appropriate for your machine
for threaded rods, this is
(steps motor per turn) / (pitch of the thread) * 1000
for belts, this is
(steps per motor turn) / (number of gear teeth) / (belt module) * 1000
half-stepping doubles the number, quarter stepping requires * 4, etc.
valid range = 20 to 4'0960'000 (0.02 to 40960 steps/mm)
*/
#define MICROSTEPPING_X 16.0 #define MICROSTEPPING_X 16.0
#define MICROSTEPPING_Y 16.0 #define MICROSTEPPING_Y 16.0
#define MICROSTEPPING_Z 16.0 #define MICROSTEPPING_Z 16.0
#define MICROSTEPPING_E 4.0 #define MICROSTEPPING_E 4.0
#define STEPS_PER_MM_X (5.023*MICROSTEPPING_X) #define STEPS_PER_M_X (5023*MICROSTEPPING_X)
#define STEPS_PER_MM_Y (5.023*MICROSTEPPING_Y) #define STEPS_PER_MM_Y (5.023*MICROSTEPPING_Y)
#define STEPS_PER_MM_Z (416.699*MICROSTEPPING_Z) #define STEPS_PER_MM_Z (416.699*MICROSTEPPING_Z)

View File

@ -50,16 +50,27 @@
All numbers are fixed point integers, so no more than 3 digits to the right of the decimal point, please :-) All numbers are fixed point integers, so no more than 3 digits to the right of the decimal point, please :-)
*/ */
// calculate these values appropriate for your machine /** \def STEPS_PER_M
// for threaded rods, this is (steps motor per turn) / (pitch of the thread) steps per meter ( = steps per mm * 1000 )
// for belts, this is (steps per motor turn) / (number of gear teeth) / (belt module)
// half-stepping doubles the number, quarter stepping requires * 4, etc. calculate these values appropriate for your machine
for threaded rods, this is
(steps motor per turn) / (pitch of the thread) * 1000
for belts, this is
(steps per motor turn) / (number of gear teeth) / (belt module) * 1000
half-stepping doubles the number, quarter stepping requires * 4, etc.
valid range = 20 to 4'0960'000 (0.02 to 40960 steps/mm)
*/
#define MICROSTEPPING_X 16.0 #define MICROSTEPPING_X 16.0
#define MICROSTEPPING_Y 16.0 #define MICROSTEPPING_Y 16.0
#define MICROSTEPPING_Z 16.0 #define MICROSTEPPING_Z 16.0
#define MICROSTEPPING_E 4.0 #define MICROSTEPPING_E 4.0
#define STEPS_PER_MM_X (5.023*MICROSTEPPING_X) #define STEPS_PER_M_X (5023*MICROSTEPPING_X)
#define STEPS_PER_MM_Y (5.023*MICROSTEPPING_Y) #define STEPS_PER_MM_Y (5.023*MICROSTEPPING_Y)
#define STEPS_PER_MM_Z (416.699*MICROSTEPPING_Z) #define STEPS_PER_MM_Z (416.699*MICROSTEPPING_Z)

View File

@ -49,15 +49,27 @@
All numbers are fixed point integers, so no more than 3 digits to the right of the decimal point, please :-) All numbers are fixed point integers, so no more than 3 digits to the right of the decimal point, please :-)
*/ */
/// calculate these values appropriate for your machine /** \def STEPS_PER_M
/// for threaded rods, this is (steps motor per turn) / (pitch of the thread) steps per meter ( = steps per mm * 1000 )
/// for belts, this is (steps per motor turn) / (number of gear teeth) / (belt module)
calculate these values appropriate for your machine
for threaded rods, this is
(steps motor per turn) / (pitch of the thread) * 1000
for belts, this is
(steps per motor turn) / (number of gear teeth) / (belt module) * 1000
half-stepping doubles the number, quarter stepping requires * 4, etc.
valid range = 20 to 4'0960'000 (0.02 to 40960 steps/mm)
*/
#define MICROSTEPPING_X 16.0 #define MICROSTEPPING_X 16.0
#define MICROSTEPPING_Y 16.0 #define MICROSTEPPING_Y 16.0
#define MICROSTEPPING_Z 16.0 #define MICROSTEPPING_Z 16.0
#define MICROSTEPPING_E 4.0 #define MICROSTEPPING_E 4.0
#define STEPS_PER_MM_X (5.023*MICROSTEPPING_X) #define STEPS_PER_M_X (5023*MICROSTEPPING_X)
#define STEPS_PER_MM_Y (5.023*MICROSTEPPING_Y) #define STEPS_PER_MM_Y (5.023*MICROSTEPPING_Y)
#define STEPS_PER_MM_Z (416.699*MICROSTEPPING_Z) #define STEPS_PER_MM_Z (416.699*MICROSTEPPING_Z)

View File

@ -49,15 +49,27 @@
All numbers are fixed point integers, so no more than 3 digits to the right of the decimal point, please :-) All numbers are fixed point integers, so no more than 3 digits to the right of the decimal point, please :-)
*/ */
/// calculate these values appropriate for your machine /** \def STEPS_PER_M
/// for threaded rods, this is (steps motor per turn) / (pitch of the thread) steps per meter ( = steps per mm * 1000 )
/// for belts, this is (steps per motor turn) / (number of gear teeth) / (belt module)
calculate these values appropriate for your machine
for threaded rods, this is
(steps motor per turn) / (pitch of the thread) * 1000
for belts, this is
(steps per motor turn) / (number of gear teeth) / (belt module) * 1000
half-stepping doubles the number, quarter stepping requires * 4, etc.
valid range = 20 to 4'0960'000 (0.02 to 40960 steps/mm)
*/
#define MICROSTEPPING_X 16.0 #define MICROSTEPPING_X 16.0
#define MICROSTEPPING_Y 16.0 #define MICROSTEPPING_Y 16.0
#define MICROSTEPPING_Z 16.0 #define MICROSTEPPING_Z 16.0
#define MICROSTEPPING_E 4.0 #define MICROSTEPPING_E 4.0
#define STEPS_PER_MM_X (5.023*MICROSTEPPING_X) #define STEPS_PER_M_X (5023*MICROSTEPPING_X)
#define STEPS_PER_MM_Y (5.023*MICROSTEPPING_Y) #define STEPS_PER_MM_Y (5.023*MICROSTEPPING_Y)
#define STEPS_PER_MM_Z (416.699*MICROSTEPPING_Z) #define STEPS_PER_MM_Z (416.699*MICROSTEPPING_Z)

62
dda.c
View File

@ -24,6 +24,10 @@
#include "heater.h" #include "heater.h"
#endif #endif
#ifdef STEPS_PER_MM_X
#error STEPS_PER_MM_X is gone, review your config.h and use STEPS_PER_M_X
#endif
/// step timeout /// step timeout
volatile uint8_t steptimeout = 0; volatile uint8_t steptimeout = 0;
@ -35,6 +39,10 @@ volatile uint8_t steptimeout = 0;
/// \brief target position of last move in queue /// \brief target position of last move in queue
TARGET startpoint __attribute__ ((__section__ (".bss"))); TARGET startpoint __attribute__ ((__section__ (".bss")));
/// \var startpoint_steps
/// \brief target position of last move in queue, expressed in steps
TARGET startpoint_steps __attribute__ ((__section__ (".bss")));
/// \var current_position /// \var current_position
/// \brief actual position of extruder head /// \brief actual position of extruder head
/// \todo make current_position = real_position (from endstops) + offset from G28 and friends /// \todo make current_position = real_position (from endstops) + offset from G28 and friends
@ -174,10 +182,18 @@ void dda_init(void) {
#ifdef ACCELERATION_RAMPING #ifdef ACCELERATION_RAMPING
move_state.n = 1; move_state.n = 1;
move_state.c = ((uint32_t)((double)F_CPU / sqrt((double)(STEPS_PER_MM_X * ACCELERATION)))) << 8; move_state.c = ((uint32_t)((double)F_CPU / sqrt((double)(STEPS_PER_M_X * ACCELERATION / 1000.)))) << 8;
#endif #endif
} }
/*! Distribute a new startpoint to DDA's internal structures without any movement.
This is needed for example after homing or a G92. The new location must be in startpoint already.
*/
void dda_new_startpoint(void) {
um_to_steps_x(startpoint_steps.X, startpoint.X);
}
/*! CREATE a dda given current_position and a target, save to passed location so we can write directly into the queue /*! CREATE a dda given current_position and a target, save to passed location so we can write directly into the queue
\param *dda pointer to a dda_queue entry to overwrite \param *dda pointer to a dda_queue entry to overwrite
\param *target the target position of this move \param *target the target position of this move
@ -191,6 +207,7 @@ void dda_init(void) {
This algorithm is probably the main limiting factor to print speed in terms of firmware limitations This algorithm is probably the main limiting factor to print speed in terms of firmware limitations
*/ */
void dda_create(DDA *dda, TARGET *target) { void dda_create(DDA *dda, TARGET *target) {
uint32_t steps, x_delta_um /*, y_delta_um, z_delta_um, e_delta_um */;
uint32_t distance, c_limit, c_limit_calc; uint32_t distance, c_limit, c_limit_calc;
// initialise DDA to a known state // initialise DDA to a known state
@ -202,7 +219,12 @@ void dda_create(DDA *dda, TARGET *target) {
// we end at the passed target // we end at the passed target
memcpy(&(dda->endpoint), target, sizeof(TARGET)); memcpy(&(dda->endpoint), target, sizeof(TARGET));
dda->x_delta = labs(target->X - startpoint.X); x_delta_um = (uint32_t)labs(target->X - startpoint.X);
um_to_steps_x(steps, target->X);
dda->x_delta = labs(steps - startpoint_steps.X);
startpoint_steps.X = steps;
dda->y_delta = labs(target->Y - startpoint.Y); dda->y_delta = labs(target->Y - startpoint.Y);
dda->z_delta = labs(target->Z - startpoint.Z); dda->z_delta = labs(target->Z - startpoint.Z);
dda->e_delta = labs(target->E - startpoint.E); dda->e_delta = labs(target->E - startpoint.E);
@ -241,11 +263,11 @@ void dda_create(DDA *dda, TARGET *target) {
// since it's unusual to combine X, Y and Z changes in a single move on reprap, check if we can use simpler approximations before trying the full 3d approximation. // since it's unusual to combine X, Y and Z changes in a single move on reprap, check if we can use simpler approximations before trying the full 3d approximation.
if (dda->z_delta == 0) if (dda->z_delta == 0)
distance = approx_distance(dda->x_delta * UM_PER_STEP_X, dda->y_delta * UM_PER_STEP_Y); distance = approx_distance(x_delta_um, dda->y_delta * UM_PER_STEP_Y);
else if (dda->x_delta == 0 && dda->y_delta == 0) else if (dda->x_delta == 0 && dda->y_delta == 0)
distance = dda->z_delta * UM_PER_STEP_Z; distance = dda->z_delta * UM_PER_STEP_Z;
else else
distance = approx_distance_3(dda->x_delta * UM_PER_STEP_X, dda->y_delta * UM_PER_STEP_Y, dda->z_delta * UM_PER_STEP_Z); distance = approx_distance_3(x_delta_um, dda->y_delta * UM_PER_STEP_Y, dda->z_delta * UM_PER_STEP_Z);
if (distance < 2) if (distance < 2)
distance = dda->e_delta * UM_PER_STEP_E; distance = dda->e_delta * UM_PER_STEP_E;
@ -279,7 +301,7 @@ void dda_create(DDA *dda, TARGET *target) {
// do this for each axis individually, as the combined speed of two or more axes can be higher than the capabilities of a single one. // do this for each axis individually, as the combined speed of two or more axes can be higher than the capabilities of a single one.
c_limit = 0; c_limit = 0;
// check X axis // check X axis
c_limit_calc = ( (dda->x_delta * (UM_PER_STEP_X * 2400L)) / dda->total_steps * (F_CPU / 40000) / MAXIMUM_FEEDRATE_X) << 8; c_limit_calc = ((x_delta_um * 2400L) / dda->total_steps * (F_CPU / 40000) / MAXIMUM_FEEDRATE_X) << 8;
if (c_limit_calc > c_limit) if (c_limit_calc > c_limit)
c_limit = c_limit_calc; c_limit = c_limit_calc;
// check Y axis // check Y axis
@ -357,8 +379,12 @@ void dda_create(DDA *dda, TARGET *target) {
dda->c_min = (move_duration / target->F) << 8; dda->c_min = (move_duration / target->F) << 8;
if (dda->c_min < c_limit) if (dda->c_min < c_limit)
dda->c_min = c_limit; dda->c_min = c_limit;
// This section is plain wrong, like in it's only half of what we need. This factor 960000 is dependant on STEPS_PER_MM.
// overflows at target->F > 65535; factor 16. found by try-and-error; will overshoot target speed a bit // overflows at target->F > 65535; factor 16. found by try-and-error; will overshoot target speed a bit
dda->rampup_steps = target->F * target->F / (uint32_t)(STEPS_PER_MM_X * ACCELERATION / 16.); dda->rampup_steps = target->F * target->F / (uint32_t)(STEPS_PER_M_X * ACCELERATION / 960000.);
//sersendf_P(PSTR("rampup calc %lu\n"), dda->rampup_steps);
dda->rampup_steps = 100000; // replace mis-calculation by a safe value
// End of wrong section.
if (dda->rampup_steps > dda->total_steps / 2) if (dda->rampup_steps > dda->total_steps / 2)
dda->rampup_steps = dda->total_steps / 2; dda->rampup_steps = dda->total_steps / 2;
dda->rampdown_steps = dda->total_steps - dda->rampup_steps; dda->rampdown_steps = dda->total_steps - dda->rampup_steps;
@ -627,11 +653,20 @@ void dda_step(DDA *dda) {
move_state.c = (int32_t)move_state.c - ((int32_t)(move_state.c * 2) / (int32_t)move_state.n); move_state.c = (int32_t)move_state.c - ((int32_t)(move_state.c * 2) / (int32_t)move_state.n);
} }
move_state.step_no++; move_state.step_no++;
// Print the number of steps actually needed for ramping up
// Needed for comparing the number with the one calculated in dda_create()
//static char printed = 0;
//if (printed == 0 && dda->c_min >= move_state.c) {
// sersendf_P(PSTR("speedup %lu steps\n"), move_state.step_no);
// printed = 1;
//}
//if (move_state.step_no < 3) printed = 0;
// debug ramping algorithm // debug ramping algorithm
// for very low speeds like 10 mm/min, only // raise this 10 for higher speeds to avoid flooding the serial line
//if (move_state.step_no % 10 /* 10, 100, ...*/ == 0) //if (move_state.step_no % 10 /* 10, 50, 100, ...*/ == 0)
// sersendf_P(PSTR("\r\nc %lu c_min %lu n %d"), dda->c, dda->c_min, move_state.n); // sersendf_P(PSTR("\r\nc %lu c_min %lu n %ld"),
// move_state.c, dda->c_min, move_state.n);
#endif #endif
// TODO: If we stop axes individually, could we home two or more axes at the same time? // TODO: If we stop axes individually, could we home two or more axes at the same time?
@ -690,9 +725,14 @@ void update_current_position() {
} }
else if (dda->live) { else if (dda->live) {
if (dda->x_direction) if (dda->x_direction)
current_position.X = dda->endpoint.X - move_state.x_steps; // (STEPS_PER_M_X / 1000) is a bit inaccurate for low STEPS_PER_M numbers
current_position.X = dda->endpoint.X -
// should be: move_state.x_steps * 1000000 / STEPS_PER_M_X)
// but x_steps can be like 1000000 already, so we'd overflow
move_state.x_steps * 1000 / ((STEPS_PER_M_X + 500) / 1000);
else else
current_position.X = dda->endpoint.X + move_state.x_steps; current_position.X = dda->endpoint.X +
move_state.x_steps * 1000 / ((STEPS_PER_M_X + 500) / 1000);
if (dda->y_direction) if (dda->y_direction)
current_position.Y = dda->endpoint.Y - move_state.y_steps; current_position.Y = dda->endpoint.Y - move_state.y_steps;

40
dda.h
View File

@ -5,9 +5,30 @@
#include "config.h" #include "config.h"
/*
micrometer to steps conversion
handle a few cases to avoid overflow while keeping reasonable accuracy
input is up to 20 bits, so we can multiply by 4096 at most
*/
#if STEPS_PER_M_X >= 4096000
#define um_to_steps_x(dest, src) \
do { dest = (src * (STEPS_PER_M_X / 10000L) + 50L) / 100L; } while (0)
#elif STEPS_PER_M_X >= 409600
#define um_to_steps_x(dest, src) \
do { dest = (src * (STEPS_PER_M_X / 1000L) + 500L) / 1000L; } while (0)
#elif STEPS_PER_M_X >= 40960
#define um_to_steps_x(dest, src) \
do { dest = (src * (STEPS_PER_M_X / 100L) + 5000L) / 10000L; } while (0)
#elif STEPS_PER_M_X >= 4096
#define um_to_steps_x(dest, src) \
do { dest = (src * (STEPS_PER_M_X / 10L) + 50000L) / 100000L; } while (0)
#else
#define um_to_steps_x(dest, src) \
do { dest = (src * (STEPS_PER_M_X / 1L) + 500000L) / 1000000L; } while (0)
#endif
// Used in distance calculation during DDA setup // Used in distance calculation during DDA setup
/// micrometers per step X
#define UM_PER_STEP_X 1000L / ((uint32_t) STEPS_PER_MM_X)
/// micrometers per step Y /// micrometers per step Y
#define UM_PER_STEP_Y 1000L / ((uint32_t) STEPS_PER_MM_Y) #define UM_PER_STEP_Y 1000L / ((uint32_t) STEPS_PER_MM_Y)
/// micrometers per step Z /// micrometers per step Z
@ -25,7 +46,12 @@
types types
*/ */
// target is simply a point in space/time /**
\struct TARGET
\brief target is simply a point in space/time
X, Y, Z and E are in micrometers unless explcitely stated. F is in mm/min.
*/
typedef struct { typedef struct {
int32_t X; int32_t X;
int32_t Y; int32_t Y;
@ -59,7 +85,7 @@ typedef struct {
/// time until next step /// time until next step
uint32_t c; uint32_t c;
/// tracking variable /// tracking variable
int16_t n; int32_t n;
#endif #endif
/// Endstop debouncing /// Endstop debouncing
@ -139,6 +165,9 @@ extern volatile uint8_t steptimeout;
/// startpoint holds the endpoint of the most recently created DDA, so we know where the next one created starts. could also be called last_endpoint /// startpoint holds the endpoint of the most recently created DDA, so we know where the next one created starts. could also be called last_endpoint
extern TARGET startpoint; extern TARGET startpoint;
/// the same as above, counted in motor steps
extern TARGET startpoint_steps;
/// current_position holds the machine's current position. this is only updated when we step, or when G92 (set home) is received. /// current_position holds the machine's current position. this is only updated when we step, or when G92 (set home) is received.
extern TARGET current_position; extern TARGET current_position;
@ -155,6 +184,9 @@ const uint8_t msbloc (uint32_t v) __attribute__ ((const));
// initialize dda structures // initialize dda structures
void dda_init(void); void dda_init(void);
// distribute a new startpoint
void dda_new_startpoint(void);
// create a DDA // create a DDA
void dda_create(DDA *dda, TARGET *target); void dda_create(DDA *dda, TARGET *target);

View File

@ -147,7 +147,7 @@ void enqueue_home(TARGET *t, uint8_t endstop_check, uint8_t endstop_stop_cond) {
MEMORY_BARRIER(); MEMORY_BARRIER();
SREG = save_reg; SREG = save_reg;
} }
} }
} }
/// go to the next move. /// go to the next move.

View File

@ -29,7 +29,6 @@
which is about the worst case we have. All other machines have a bigger build volume. which is about the worst case we have. All other machines have a bigger build volume.
*/ */
#define STEPS_PER_M_X ((uint32_t) ((STEPS_PER_MM_X * 1000.0) + 0.5))
#define STEPS_PER_M_Y ((uint32_t) ((STEPS_PER_MM_Y * 1000.0) + 0.5)) #define STEPS_PER_M_Y ((uint32_t) ((STEPS_PER_MM_Y * 1000.0) + 0.5))
#define STEPS_PER_M_Z ((uint32_t) ((STEPS_PER_MM_Z * 1000.0) + 0.5)) #define STEPS_PER_M_Z ((uint32_t) ((STEPS_PER_MM_Z * 1000.0) + 0.5))
#define STEPS_PER_M_E ((uint32_t) ((STEPS_PER_MM_E * 1000.0) + 0.5)) #define STEPS_PER_M_E ((uint32_t) ((STEPS_PER_MM_E * 1000.0) + 0.5))
@ -38,7 +37,6 @@
mm -> inch conversion mm -> inch conversion
*/ */
#define STEPS_PER_IN_X ((uint32_t) ((25.4 * STEPS_PER_MM_X) + 0.5))
#define STEPS_PER_IN_Y ((uint32_t) ((25.4 * STEPS_PER_MM_Y) + 0.5)) #define STEPS_PER_IN_Y ((uint32_t) ((25.4 * STEPS_PER_MM_Y) + 0.5))
#define STEPS_PER_IN_Z ((uint32_t) ((25.4 * STEPS_PER_MM_Z) + 0.5)) #define STEPS_PER_IN_Z ((uint32_t) ((25.4 * STEPS_PER_MM_Z) + 0.5))
#define STEPS_PER_IN_E ((uint32_t) ((25.4 * STEPS_PER_MM_E) + 0.5)) #define STEPS_PER_IN_E ((uint32_t) ((25.4 * STEPS_PER_MM_E) + 0.5))
@ -81,6 +79,8 @@ GCODE_COMMAND next_target __attribute__ ((__section__ (".bss")));
*/ */
extern const uint32_t powers[]; // defined in sermsg.c extern const uint32_t powers[]; // defined in sermsg.c
// TODO: When the new approach to pass distances in micrometers instead of step
// numbers stays, this should be replaced by a simplified version.
/// convert a floating point input value into an integer with appropriate scaling. /// convert a floating point input value into an integer with appropriate scaling.
/// \param *df pointer to floating point structure that holds fp value to convert /// \param *df pointer to floating point structure that holds fp value to convert
/// \param multiplicand multiply by this amount during conversion to integer /// \param multiplicand multiply by this amount during conversion to integer
@ -137,9 +137,9 @@ void gcode_parse_char(uint8_t c) {
break; break;
case 'X': case 'X':
if (next_target.option_inches) if (next_target.option_inches)
next_target.target.X = decfloat_to_int(&read_digit, STEPS_PER_IN_X, 0); next_target.target.X = decfloat_to_int(&read_digit, 25400, 1);
else else
next_target.target.X = decfloat_to_int(&read_digit, STEPS_PER_M_X, 1); next_target.target.X = decfloat_to_int(&read_digit, 1000, 0);
if (DEBUG_ECHO && (debug_flags & DEBUG_ECHO)) if (DEBUG_ECHO && (debug_flags & DEBUG_ECHO))
serwrite_int32(next_target.target.X); serwrite_int32(next_target.target.X);
break; break;

View File

@ -9,6 +9,7 @@
#include "gcode_parse.h" #include "gcode_parse.h"
#include "dda.h"
#include "dda_queue.h" #include "dda_queue.h"
#include "watchdog.h" #include "watchdog.h"
#include "delay.h" #include "delay.h"
@ -77,12 +78,12 @@ void process_gcode_command() {
// implement axis limits // implement axis limits
#ifdef X_MIN #ifdef X_MIN
if (next_target.target.X < (X_MIN * STEPS_PER_MM_X)) if (next_target.target.X < X_MIN * 1000.)
next_target.target.X = X_MIN * STEPS_PER_MM_X; next_target.target.X = X_MIN * 1000.;
#endif #endif
#ifdef X_MAX #ifdef X_MAX
if (next_target.target.X > (X_MAX * STEPS_PER_MM_X)) if (next_target.target.X > X_MAX * 1000.))
next_target.target.X = X_MAX * STEPS_PER_MM_X; next_target.target.X = X_MAX * 1000.;
#endif #endif
#ifdef Y_MIN #ifdef Y_MIN
if (next_target.target.Y < (Y_MIN * STEPS_PER_MM_Y)) if (next_target.target.Y < (Y_MIN * STEPS_PER_MM_Y))
@ -301,6 +302,8 @@ void process_gcode_command() {
startpoint.Y = next_target.target.Y = startpoint.Y = next_target.target.Y =
startpoint.Z = next_target.target.Z = 0; startpoint.Z = next_target.target.Z = 0;
} }
dda_new_startpoint();
break; break;
case 161: case 161:
@ -575,7 +578,7 @@ void process_gcode_command() {
queue_wait(); queue_wait();
#endif #endif
update_current_position(); update_current_position();
sersendf_P(PSTR("X:%lq,Y:%lq,Z:%lq,E:%lq,F:%ld"), current_position.X * ((int32_t) UM_PER_STEP_X), current_position.Y * ((int32_t) UM_PER_STEP_Y), current_position.Z * ((int32_t) UM_PER_STEP_Z), current_position.E * ((int32_t) UM_PER_STEP_E), current_position.F); sersendf_P(PSTR("X:%lq,Y:%lq,Z:%lq,E:%lq,F:%ld"), current_position.X, current_position.Y * ((int32_t) UM_PER_STEP_Y), current_position.Z * ((int32_t) UM_PER_STEP_Z), current_position.E * ((int32_t) UM_PER_STEP_E), current_position.F);
// newline is sent from gcode_parse after we return // newline is sent from gcode_parse after we return
break; break;

18
home.c
View File

@ -36,7 +36,7 @@ void home_x_negative() {
#if defined X_MIN_PIN #if defined X_MIN_PIN
TARGET t = startpoint; TARGET t = startpoint;
t.X = -1000*STEPS_PER_MM_X; t.X = -1000000;
#ifdef SLOW_HOMING #ifdef SLOW_HOMING
// hit home soft // hit home soft
t.F = SEARCH_FEEDRATE_X; t.F = SEARCH_FEEDRATE_X;
@ -48,7 +48,7 @@ void home_x_negative() {
#ifndef SLOW_HOMING #ifndef SLOW_HOMING
// back off slowly // back off slowly
t.X = +1000*STEPS_PER_MM_X; t.X = +1000000;
t.F = SEARCH_FEEDRATE_X; t.F = SEARCH_FEEDRATE_X;
enqueue_home(&t, 0x1, 0); enqueue_home(&t, 0x1, 0);
#endif #endif
@ -56,10 +56,11 @@ void home_x_negative() {
// set X home // set X home
queue_wait(); // we have to wait here, see G92 queue_wait(); // we have to wait here, see G92
#ifdef X_MIN #ifdef X_MIN
startpoint.X = next_target.target.X = (int32_t)(X_MIN * STEPS_PER_MM_X); startpoint.X = next_target.target.X = (int32_t)(X_MIN * 1000.0);
#else #else
startpoint.X = next_target.target.X = 0; startpoint.X = next_target.target.X = 0;
#endif #endif
dda_new_startpoint();
#endif #endif
} }
@ -71,7 +72,7 @@ void home_x_positive() {
#if defined X_MAX_PIN && defined X_MAX #if defined X_MAX_PIN && defined X_MAX
TARGET t = startpoint; TARGET t = startpoint;
t.X = +1000*STEPS_PER_MM_X; t.X = +1000000;
#ifdef SLOW_HOMING #ifdef SLOW_HOMING
// hit home soft // hit home soft
t.F = SEARCH_FEEDRATE_X; t.F = SEARCH_FEEDRATE_X;
@ -83,7 +84,7 @@ void home_x_positive() {
#ifndef SLOW_HOMING #ifndef SLOW_HOMING
// back off slowly // back off slowly
t.X = -1000*STEPS_PER_MM_X; t.X = -1000000;
t.F = SEARCH_FEEDRATE_X; t.F = SEARCH_FEEDRATE_X;
enqueue_home(&t, 0x1, 0); enqueue_home(&t, 0x1, 0);
#endif #endif
@ -91,7 +92,8 @@ void home_x_positive() {
// set X home // set X home
queue_wait(); queue_wait();
// set position to MAX // set position to MAX
startpoint.X = next_target.target.X = (int32_t)(X_MAX * STEPS_PER_MM_X); startpoint.X = next_target.target.X = (int32_t)(X_MAX * 1000.0);
dda_new_startpoint();
// go to zero // go to zero
t.X = 0; t.X = 0;
t.F = MAXIMUM_FEEDRATE_X; t.F = MAXIMUM_FEEDRATE_X;
@ -128,6 +130,7 @@ void home_y_negative() {
#else #else
startpoint.Y = next_target.target.Y = 0; startpoint.Y = next_target.target.Y = 0;
#endif #endif
dda_new_startpoint();
#endif #endif
} }
@ -160,6 +163,7 @@ void home_y_positive() {
queue_wait(); queue_wait();
// set position to MAX // set position to MAX
startpoint.Y = next_target.target.Y = (int32_t)(Y_MAX * STEPS_PER_MM_Y); startpoint.Y = next_target.target.Y = (int32_t)(Y_MAX * STEPS_PER_MM_Y);
new_startpoint();
// go to zero // go to zero
t.Y = 0; t.Y = 0;
t.F = MAXIMUM_FEEDRATE_Y; t.F = MAXIMUM_FEEDRATE_Y;
@ -196,6 +200,7 @@ void home_z_negative() {
#else #else
startpoint.Z = next_target.target.Z = 0; startpoint.Z = next_target.target.Z = 0;
#endif #endif
dda_new_startpoint();
z_disable(); z_disable();
#endif #endif
} }
@ -229,6 +234,7 @@ void home_z_positive() {
queue_wait(); queue_wait();
// set position to MAX // set position to MAX
startpoint.Z = next_target.target.Z = (int32_t)(Z_MAX * STEPS_PER_MM_Z); startpoint.Z = next_target.target.Z = (int32_t)(Z_MAX * STEPS_PER_MM_Z);
dda_new_startpoint();
// go to zero // go to zero
t.Z = 0; t.Z = 0;
t.F = MAXIMUM_FEEDRATE_Z; t.F = MAXIMUM_FEEDRATE_Z;