From d302329eee79bd2b29d570317c71551be347b9b8 Mon Sep 17 00:00:00 2001 From: Michael Moon Date: Wed, 27 Jan 2010 09:11:46 +1100 Subject: [PATCH] time to save, made debug output (524 bytes) and global clock (50 bytes) optional --- mendel/Makefile | 2 +- mendel/clock.c | 7 +++- mendel/clock.h | 3 ++ mendel/dda.c | 78 +++++++++++++++++++++++++++-------------- mendel/dda.h | 1 + mendel/machine.h | 62 +++++++++++++++++++++++---------- mendel/mendel.c | 91 ++++++++++++++++++++++++------------------------ mendel/temp.c | 23 ++++++++++++ mendel/temp.h | 1 + 9 files changed, 176 insertions(+), 92 deletions(-) diff --git a/mendel/Makefile b/mendel/Makefile index c9a8053..5dc45dd 100644 --- a/mendel/Makefile +++ b/mendel/Makefile @@ -32,7 +32,7 @@ F_CPU = 16000000L ############################################################################## ARCH = avr- -OPTIMIZE = -Os -ffunction-sections -finline-functions-called-once +OPTIMIZE = -Os -ffunction-sections -finline-functions-called-once -DDEBUG=0 # OPTIMIZE = -O0 CFLAGS = -g -Wall -Wstrict-prototypes $(OPTIMIZE) -mmcu=$(MCU_TARGET) -DF_CPU=$(F_CPU) $(DEFS) -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -save-temps LDFLAGS = -Wl,--as-needed -Wl,--gc-sections diff --git a/mendel/clock.c b/mendel/clock.c index 70ef0b6..9eb9486 100644 --- a/mendel/clock.c +++ b/mendel/clock.c @@ -12,7 +12,9 @@ #include "arduino.h" // global clock +#ifdef GLOBAL_CLOCK volatile uint32_t clock = 0; +#endif // 1/4 second tick uint8_t clock_counter_250ms = 0; @@ -37,8 +39,9 @@ void clock_setup() { ISR(TIMER2_COMPA_vect) { // global clock +#ifdef GLOBAL_CLOCK clock++; - +#endif // 1/4 second tick if (++clock_counter_250ms == 250) { clock_flag_250ms = 255; @@ -46,6 +49,7 @@ ISR(TIMER2_COMPA_vect) { } } +#ifdef GLOBAL_CLOCK uint32_t clock_read() { uint32_t c; @@ -55,3 +59,4 @@ uint32_t clock_read() { return c; } +#endif diff --git a/mendel/clock.h b/mendel/clock.h index d20500e..a0a5b17 100644 --- a/mendel/clock.h +++ b/mendel/clock.h @@ -4,7 +4,10 @@ #include void clock_setup(void); + +#ifdef GLOBAL_CLOCK uint32_t clock_read(void); +#endif extern volatile uint8_t clock_flag_250ms; diff --git a/mendel/dda.c b/mendel/dda.c index 74fa32d..fa98230 100644 --- a/mendel/dda.c +++ b/mendel/dda.c @@ -14,6 +14,10 @@ #define ABSDELTA(a, b) (((a) >= (b))?((a) - (b)):((b) - (a))) #endif +#ifndef DEBUG +#define DEBUG 0 +#endif + /* move queue */ @@ -136,6 +140,19 @@ uint32_t abs32(int32_t v) { return (uint32_t) (v); } + +void print_queue() { + serial_writechar('Q'); + serwrite_uint8(mb_tail); + serial_writechar('/'); + serwrite_uint8(mb_head); + if (queue_full()) + serial_writechar('F'); + if (queue_empty()) + serial_writechar('E'); + serial_writechar('\n'); +} + /* CREATE */ @@ -143,7 +160,8 @@ uint32_t abs32(int32_t v) { void dda_create(TARGET *target, DDA *dda) { uint32_t distance; - serial_writestr_P(PSTR("\n{DDA_CREATE: [")); + if (DEBUG) + serial_writestr_P(PSTR("\n{DDA_CREATE: [")); // we end at the passed target memcpy(&(dda->endpoint), target, sizeof(TARGET)); @@ -154,11 +172,13 @@ void dda_create(TARGET *target, DDA *dda) { dda->e_delta = abs32(dda->endpoint.E - startpoint.E); dda->f_delta = abs32(dda->endpoint.F - startpoint.F); - serwrite_uint32(dda->x_delta); serial_writechar(','); - serwrite_uint32(dda->y_delta); serial_writechar(','); - serwrite_uint32(dda->z_delta); serial_writechar(','); - serwrite_uint32(dda->e_delta); serial_writechar(','); - serwrite_uint32(dda->f_delta); serial_writestr_P(PSTR("] [")); + if (DEBUG) { + serwrite_uint32(dda->x_delta); serial_writechar(','); + serwrite_uint32(dda->y_delta); serial_writechar(','); + serwrite_uint32(dda->z_delta); serial_writechar(','); + serwrite_uint32(dda->e_delta); serial_writechar(','); + serwrite_uint32(dda->f_delta); serial_writestr_P(PSTR("] [")); + } dda->total_steps = dda->x_delta; if (dda->y_delta > dda->total_steps) @@ -172,7 +192,8 @@ void dda_create(TARGET *target, DDA *dda) { if (dda->total_steps == 0) dda->nullmove = 1; - serwrite_uint32(dda->total_steps); serial_writechar(','); + if (DEBUG) + serwrite_uint32(dda->total_steps); serial_writechar(','); if (dda->f_delta > dda->total_steps) { dda->f_scale = dda->f_delta / dda->total_steps; @@ -188,7 +209,8 @@ void dda_create(TARGET *target, DDA *dda) { dda->f_scale = 1; } - serwrite_uint32(dda->total_steps); serial_writechar(','); + if (DEBUG) + serwrite_uint32(dda->total_steps); serial_writechar(','); dda->x_direction = (dda->endpoint.X >= startpoint.X)?1:0; dda->y_direction = (dda->endpoint.Y >= startpoint.Y)?1:0; @@ -201,19 +223,20 @@ void dda_create(TARGET *target, DDA *dda) { // 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) - distance = approx_distance(dda->x_delta * 1000, dda->y_delta * 1000) / ((uint32_t) STEPS_PER_MM_X); + distance = approx_distance(dda->x_delta * UM_PER_STEP_X, dda->y_delta * UM_PER_STEP_Y); else if (dda->x_delta == 0 && dda->y_delta == 0) - distance = dda->z_delta * ((uint32_t) (1000 / STEPS_PER_MM_Z)); + distance = dda->z_delta * UM_PER_STEP_Z; else - distance = approx_distance_3(dda->x_delta * ((uint32_t) (1000 * STEPS_PER_MM_Z / STEPS_PER_MM_X)), dda->y_delta * ((uint32_t) (1000 * STEPS_PER_MM_Z / STEPS_PER_MM_Y)), dda->z_delta * 1000) / ((uint32_t) STEPS_PER_MM_Z); + 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); if (distance < 2) - distance = dda->e_delta * ((uint32_t) (1000 / STEPS_PER_MM_E)); + distance = dda->e_delta * UM_PER_STEP_E; if (distance < 2) distance = dda->f_delta; // pre-calculate move speed in millimeter microseconds per step minute for less math in interrupt context - // mm (distance) * 1000 us/ms * 60000000 us/min / step (total_steps) = mm.us per step.min + // mm (distance) * 60000000 us/min / step (total_steps) = mm.us per step.min + // note: um (distance) * 60000 == mm * 60000000 // so in the interrupt we must simply calculate // mm.us per step.min / mm per min (F) = us per step if (dda->total_steps > 0) @@ -221,7 +244,8 @@ void dda_create(TARGET *target, DDA *dda) { else dda->move_duration = 0; - serwrite_uint32(dda->move_duration); serial_writestr_P(PSTR("] }\n")); + if (DEBUG) + serwrite_uint32(dda->move_duration); serial_writestr_P(PSTR("] }\n")); // next dda starts where we finish memcpy(&startpoint, target, sizeof(TARGET)); @@ -393,17 +417,19 @@ void dda_step(DDA *dda) { } } - serial_writechar('['); - serwrite_hex8(step_option); - serial_writechar(':'); - serwrite_uint16(dda->f_scale); - serial_writechar(','); - serwrite_int32(current_position.F); - serial_writechar('/'); - serwrite_int32(dda->endpoint.F); - serial_writechar('#'); - serwrite_uint32(dda->move_duration); - serial_writechar(']'); + if (DEBUG) { + serial_writechar('['); + serwrite_hex8(step_option); + serial_writechar(':'); + serwrite_uint16(dda->f_scale); + serial_writechar(','); + serwrite_int32(current_position.F); + serial_writechar('/'); + serwrite_int32(dda->endpoint.F); + serial_writechar('#'); + serwrite_uint32(dda->move_duration); + serial_writechar(']'); + } } while ( ((step_option & REAL_MOVE ) == 0) && ((step_option & F_CAN_STEP) != 0) ); @@ -411,7 +437,7 @@ void dda_step(DDA *dda) { unstep(); // we have stepped in speed and now need to recalculate our delay - if ((step_option & REAL_MOVE) && ((step_option & F_REAL_STEP) || (dda->firstep))) { + if (((step_option & REAL_MOVE) && (step_option & F_REAL_STEP)) || (dda->firstep)) { setTimer(dda->move_duration / current_position.F); dda->firstep = 0; } diff --git a/mendel/dda.h b/mendel/dda.h index 4b0b744..368c693 100644 --- a/mendel/dda.h +++ b/mendel/dda.h @@ -55,6 +55,7 @@ uint8_t queue_full(void); uint8_t queue_empty(void); void enqueue(TARGET *t); void next_move(void); +void print_queue(void); uint32_t approx_distance( uint32_t dx, uint32_t dy ); uint32_t approx_distance_3( uint32_t dx, uint32_t dy, uint32_t dz ); diff --git a/mendel/machine.h b/mendel/machine.h index 1ab57b2..7853ffd 100644 --- a/mendel/machine.h +++ b/mendel/machine.h @@ -2,38 +2,64 @@ #define _MACHINE_H /* - machine variables + move buffer size, in number of moves + note that each move takes a fair chunk of ram (71 bytes as of this writing) so don't make the buffer too big - a bigger serial readbuffer may help more than increasing this unless your gcodes are more than 70 characters long on average. + however, a larger movebuffer will probably help with lots of short moves, as each move takes a bunch of math to set up */ - #define MOVEBUFFER_SIZE 8 /* axis calculations, adjust as necessary */ -#define XY_STEPS_PER_REV 1600.0 -#define XY_COG_CIRCUMFERENCE (4.77 * 16.0) +#define X_STEPS_PER_REV 1600.0 +#define Y_STEPS_PER_REV X_STEPS_PER_REV +// we need more speed than precision on Z, turn off microstepping +#define Z_STEPS_PER_REV 200.0 +// we need more torque and smoothness at very low speeds on E, maximum microstepping +#define E_STEPS_PER_REV 3200.0 -#define EXTRUDER_STEPS_PER_REV 3200 -#define EXTRUDER_SHAFT_RADIUS 5 -#define EXTRUDER_INLET_DIAMETER 3 +#define X_COG_CIRCUMFERENCE (4.77 * 16.0) +#define Y_COG_CIRCUMFERENCE X_COG_CIRCUMFERENCE +// also try: +// #define XY_COG_RADIUS 9.5 +// #define XY_COG_CIRCUMFERENCE (XY_COG_RADIUS * PI * 2) +#define Z_GEAR_RATIO 1.0 + +#define EXTRUDER_STEPS_PER_REV 3200.0 +#define EXTRUDER_SHAFT_RADIUS 5.0 +#define EXTRUDER_INLET_DIAMETER 3.0 #define EXTRUDER_NOZZLE_DIAMETER 0.8 -#define STEPS_PER_MM_X ((XY_STEPS_PER_REV / XY_COG_CIRCUMFERENCE) + 0.5) -#define STEPS_PER_MM_Y ((XY_STEPS_PER_REV / XY_COG_CIRCUMFERENCE) + 0.5) -#define STEPS_PER_MM_Z (200L) -#define STEPS_PER_MM_E (EXTRUDER_STEPS_PER_REV * EXTRUDER_SHAFT_RADIUS * PI * EXTRUDER_INLET_DIAMETER / EXTRUDER_NOZZLE_DIAMETER) +#define STEPS_PER_MM_X ((uint32_t) ((X_STEPS_PER_REV / X_COG_CIRCUMFERENCE) + 0.5)) +#define STEPS_PER_MM_Y ((uint32_t) ((Y_STEPS_PER_REV / Y_COG_CIRCUMFERENCE) + 0.5)) +#define STEPS_PER_MM_Z ((uint32_t) ((Z_STEPS_PER_REV * Z_GEAR_RATIO) + 0.5)) -#define FEEDRATE_FAST_XY 2400 -#define FEEDRATE_SLOW_XY 120 -#define FEEDRATE_FAST_Z 240 -#define FEEDRATE_SLOW_Z 12 +// http://blog.arcol.hu/?p=157 may help with this next one +// I haven't tuned this at all- it's just a placeholder until I read the above carefully enough +// does this refer to filament or extrudate? extrudate depends on layer thickness.. hm +#define STEPS_PER_MM_E ((uint32_t) ((EXTRUDER_STEPS_PER_REV / (EXTRUDER_SHAFT_RADIUS * PI * EXTRUDER_INLET_DIAMETER / EXTRUDER_NOZZLE_DIAMETER)) + 0.5)) -#define E_STARTSTOP_STEPS 20 -#define FEEDRATE_FAST_E 1200 +#define FEEDRATE_FAST_XY 2400 +#define FEEDRATE_SLOW_XY 120 +#define FEEDRATE_FAST_Z 240 +#define FEEDRATE_SLOW_Z 12 + +#define E_STARTSTOP_STEPS 20 +#define FEEDRATE_FAST_E 1200 /* - should be the same for all machines ;) + calculated values - you shouldn't need to touch these + however feel free to put in your own values if they can be more precise than the calculated approximations, remembering that they must end up being integers- floating point by preprocessor only thanks! +*/ + +#define UM_PER_STEP_X ((uint32_t) ((1000.0 / STEPS_PER_MM_X) + 0.5)) +#define UM_PER_STEP_Y ((uint32_t) ((1000.0 / STEPS_PER_MM_Y) + 0.5)) +#define UM_PER_STEP_Z ((uint32_t) ((1000.0 / STEPS_PER_MM_Z) + 0.5)) +#define UM_PER_STEP_E ((uint32_t) ((1000.0 / STEPS_PER_MM_E) + 0.5)) + +/* + should be the same for all machines! ;) */ #define PI 3.1415926535 diff --git a/mendel/mendel.c b/mendel/mendel.c index f7e339f..f34426e 100644 --- a/mendel/mendel.c +++ b/mendel/mendel.c @@ -15,6 +15,10 @@ #include "temp.h" #include "sermsg.h" +#ifndef DEBUG +#define DEBUG 0 +#endif + int main (void) { uint8_t report; @@ -72,10 +76,10 @@ int main (void) scan_char(c); } -// if (clock_flag_250ms & CLOCK_FLAG_250MS_TEMPCHECK) { -// clock_flag_250ms &= ~CLOCK_FLAG_250MS_TEMPCHECK; -// temp_tick(); -// } + if (clock_flag_250ms & CLOCK_FLAG_250MS_TEMPCHECK) { + clock_flag_250ms &= ~CLOCK_FLAG_250MS_TEMPCHECK; + temp_tick(); + } if (clock_flag_250ms & CLOCK_FLAG_250MS_REPORT) { clock_flag_250ms &= ~CLOCK_FLAG_250MS_REPORT; @@ -83,53 +87,48 @@ int main (void) if (report == 4) { report = 0; - // current move - serial_writestr_P(PSTR("DDA: f#")); - serwrite_int32(movebuffer[mb_head].f_counter); - serial_writechar('/'); - serwrite_uint16(movebuffer[mb_head].f_scale); - serial_writechar('/'); - serwrite_int16(movebuffer[mb_head].f_delta); - serial_writechar('\n'); + if (DEBUG) { + // current move + serial_writestr_P(PSTR("DDA: f#")); + serwrite_int32(movebuffer[mb_head].f_counter); + serial_writechar('/'); + serwrite_uint16(movebuffer[mb_head].f_scale); + serial_writechar('/'); + serwrite_int16(movebuffer[mb_head].f_delta); + serial_writechar('\n'); - // current position - serial_writestr_P(PSTR("Pos: ")); - serwrite_int32(current_position.X); - serial_writechar(','); - serwrite_int32(current_position.Y); - serial_writechar(','); - serwrite_int32(current_position.Z); - serial_writechar(','); - serwrite_uint32(current_position.E); - serial_writechar(','); - serwrite_uint32(current_position.F); - serial_writechar('\n'); + // current position + serial_writestr_P(PSTR("Pos: ")); + serwrite_int32(current_position.X); + serial_writechar(','); + serwrite_int32(current_position.Y); + serial_writechar(','); + serwrite_int32(current_position.Z); + serial_writechar(','); + serwrite_uint32(current_position.E); + serial_writechar(','); + serwrite_uint32(current_position.F); + serial_writechar('\n'); - // target position - serial_writestr_P(PSTR("Tar: ")); - serwrite_int32(movebuffer[mb_tail].endpoint.X); - serial_writechar(','); - serwrite_int32(movebuffer[mb_tail].endpoint.Y); - serial_writechar(','); - serwrite_int32(movebuffer[mb_tail].endpoint.Z); - serial_writechar(','); - serwrite_uint32(movebuffer[mb_tail].endpoint.E); - serial_writechar(','); - serwrite_uint32(movebuffer[mb_tail].endpoint.F); - serial_writechar('\n'); + // target position + serial_writestr_P(PSTR("Dst: ")); + serwrite_int32(movebuffer[mb_tail].endpoint.X); + serial_writechar(','); + serwrite_int32(movebuffer[mb_tail].endpoint.Y); + serial_writechar(','); + serwrite_int32(movebuffer[mb_tail].endpoint.Z); + serial_writechar(','); + serwrite_uint32(movebuffer[mb_tail].endpoint.E); + serial_writechar(','); + serwrite_uint32(movebuffer[mb_tail].endpoint.F); + serial_writechar('\n'); + } // Queue - serial_writestr_P(PSTR("Q : ")); -// serwrite_uint8((mb_head - mb_tail) & (MOVEBUFFER_SIZE - 1)); - serwrite_uint8(mb_head); - serial_writechar('/'); - serwrite_uint8(mb_tail); + print_queue(); - if (queue_full()) - serial_writechar('F'); - if (queue_empty()) - serial_writechar('E'); - serial_writechar('\n'); + // temperature + temp_print(); } } } diff --git a/mendel/temp.c b/mendel/temp.c index c650774..6e4633a 100644 --- a/mendel/temp.c +++ b/mendel/temp.c @@ -12,6 +12,8 @@ // M105- get temperature case 105: uint16_t t = temp_get(); + + note that the MAX6675 can't do more than approx 4 conversions per second */ #include "temp.h" @@ -19,6 +21,8 @@ #include "machine.h" #include "pinout.h" #include "clock.h" +#include "serial.h" +#include "sermsg.h" uint16_t current_temp = 0; uint16_t target_temp = 0; @@ -31,6 +35,10 @@ int32_t p_factor = 680; int32_t i_factor = 18; int32_t d_factor = 200; +uint8_t temp_flags = 0; +#define TEMP_FLAG_PRESENT 1 +#define TEMP_FLAG_TCOPEN 2 + #define PID_SCALE 1024L uint16_t temp_read() { @@ -47,10 +55,13 @@ uint16_t temp_read() { for (;(SPSR & MASK(SPIF)) == 0;); temp |= SPDR; + temp_flags = 0; if ((temp & 0x8002) == 0) { // got "device id" + temp_flags |= TEMP_FLAG_PRESENT; if (temp & 4) { // thermocouple open + temp_flags |= TEMP_FLAG_TCOPEN; } else { current_temp = temp >> 3; @@ -71,6 +82,18 @@ uint16_t temp_get() { return current_temp; } +void temp_print() { + serial_writestr_P(PSTR("T: ")); + if (temp_flags & TEMP_FLAG_TCOPEN) { + serial_writestr_P(PSTR("no thermocouple!")); + } + else { + serwrite_uint16(temp_get()); + serial_writestr_P(PSTR("°C")); + } + serial_writechar('\n'); +} + void temp_tick() { uint16_t last_temp = current_temp; temp_read(); diff --git a/mendel/temp.h b/mendel/temp.h index 3441512..b2eaca0 100644 --- a/mendel/temp.h +++ b/mendel/temp.h @@ -6,6 +6,7 @@ uint16_t temp_read(void); void temp_set(uint16_t t); uint16_t temp_get(void); +void temp_print(void); void temp_tick(void); #endif /* _TIMER_H */