time to save, made debug output (524 bytes) and global clock (50 bytes) optional

This commit is contained in:
Michael Moon 2010-01-27 09:11:46 +11:00
parent 098f277713
commit d302329eee
9 changed files with 176 additions and 92 deletions

View File

@ -32,7 +32,7 @@ F_CPU = 16000000L
############################################################################## ##############################################################################
ARCH = avr- ARCH = avr-
OPTIMIZE = -Os -ffunction-sections -finline-functions-called-once OPTIMIZE = -Os -ffunction-sections -finline-functions-called-once -DDEBUG=0
# OPTIMIZE = -O0 # 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 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 LDFLAGS = -Wl,--as-needed -Wl,--gc-sections

View File

@ -12,7 +12,9 @@
#include "arduino.h" #include "arduino.h"
// global clock // global clock
#ifdef GLOBAL_CLOCK
volatile uint32_t clock = 0; volatile uint32_t clock = 0;
#endif
// 1/4 second tick // 1/4 second tick
uint8_t clock_counter_250ms = 0; uint8_t clock_counter_250ms = 0;
@ -37,8 +39,9 @@ void clock_setup() {
ISR(TIMER2_COMPA_vect) { ISR(TIMER2_COMPA_vect) {
// global clock // global clock
#ifdef GLOBAL_CLOCK
clock++; clock++;
#endif
// 1/4 second tick // 1/4 second tick
if (++clock_counter_250ms == 250) { if (++clock_counter_250ms == 250) {
clock_flag_250ms = 255; clock_flag_250ms = 255;
@ -46,6 +49,7 @@ ISR(TIMER2_COMPA_vect) {
} }
} }
#ifdef GLOBAL_CLOCK
uint32_t clock_read() { uint32_t clock_read() {
uint32_t c; uint32_t c;
@ -55,3 +59,4 @@ uint32_t clock_read() {
return c; return c;
} }
#endif

View File

@ -4,7 +4,10 @@
#include <stdint.h> #include <stdint.h>
void clock_setup(void); void clock_setup(void);
#ifdef GLOBAL_CLOCK
uint32_t clock_read(void); uint32_t clock_read(void);
#endif
extern volatile uint8_t clock_flag_250ms; extern volatile uint8_t clock_flag_250ms;

View File

@ -14,6 +14,10 @@
#define ABSDELTA(a, b) (((a) >= (b))?((a) - (b)):((b) - (a))) #define ABSDELTA(a, b) (((a) >= (b))?((a) - (b)):((b) - (a)))
#endif #endif
#ifndef DEBUG
#define DEBUG 0
#endif
/* /*
move queue move queue
*/ */
@ -136,6 +140,19 @@ uint32_t abs32(int32_t v) {
return (uint32_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 CREATE
*/ */
@ -143,7 +160,8 @@ uint32_t abs32(int32_t v) {
void dda_create(TARGET *target, DDA *dda) { void dda_create(TARGET *target, DDA *dda) {
uint32_t distance; 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 // we end at the passed target
memcpy(&(dda->endpoint), target, sizeof(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->e_delta = abs32(dda->endpoint.E - startpoint.E);
dda->f_delta = abs32(dda->endpoint.F - startpoint.F); dda->f_delta = abs32(dda->endpoint.F - startpoint.F);
serwrite_uint32(dda->x_delta); serial_writechar(','); if (DEBUG) {
serwrite_uint32(dda->y_delta); serial_writechar(','); serwrite_uint32(dda->x_delta); serial_writechar(',');
serwrite_uint32(dda->z_delta); serial_writechar(','); serwrite_uint32(dda->y_delta); serial_writechar(',');
serwrite_uint32(dda->e_delta); serial_writechar(','); serwrite_uint32(dda->z_delta); serial_writechar(',');
serwrite_uint32(dda->f_delta); serial_writestr_P(PSTR("] [")); serwrite_uint32(dda->e_delta); serial_writechar(',');
serwrite_uint32(dda->f_delta); serial_writestr_P(PSTR("] ["));
}
dda->total_steps = dda->x_delta; dda->total_steps = dda->x_delta;
if (dda->y_delta > dda->total_steps) if (dda->y_delta > dda->total_steps)
@ -172,7 +192,8 @@ void dda_create(TARGET *target, DDA *dda) {
if (dda->total_steps == 0) if (dda->total_steps == 0)
dda->nullmove = 1; 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) { if (dda->f_delta > dda->total_steps) {
dda->f_scale = 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; 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->x_direction = (dda->endpoint.X >= startpoint.X)?1:0;
dda->y_direction = (dda->endpoint.Y >= startpoint.Y)?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. // 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 * 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) 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 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) 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) if (distance < 2)
distance = dda->f_delta; distance = dda->f_delta;
// pre-calculate move speed in millimeter microseconds per step minute for less math in interrupt context // 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 // so in the interrupt we must simply calculate
// mm.us per step.min / mm per min (F) = us per step // mm.us per step.min / mm per min (F) = us per step
if (dda->total_steps > 0) if (dda->total_steps > 0)
@ -221,7 +244,8 @@ void dda_create(TARGET *target, DDA *dda) {
else else
dda->move_duration = 0; 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 // next dda starts where we finish
memcpy(&startpoint, target, sizeof(TARGET)); memcpy(&startpoint, target, sizeof(TARGET));
@ -393,17 +417,19 @@ void dda_step(DDA *dda) {
} }
} }
serial_writechar('['); if (DEBUG) {
serwrite_hex8(step_option); serial_writechar('[');
serial_writechar(':'); serwrite_hex8(step_option);
serwrite_uint16(dda->f_scale); serial_writechar(':');
serial_writechar(','); serwrite_uint16(dda->f_scale);
serwrite_int32(current_position.F); serial_writechar(',');
serial_writechar('/'); serwrite_int32(current_position.F);
serwrite_int32(dda->endpoint.F); serial_writechar('/');
serial_writechar('#'); serwrite_int32(dda->endpoint.F);
serwrite_uint32(dda->move_duration); serial_writechar('#');
serial_writechar(']'); serwrite_uint32(dda->move_duration);
serial_writechar(']');
}
} while ( ((step_option & REAL_MOVE ) == 0) && } while ( ((step_option & REAL_MOVE ) == 0) &&
((step_option & F_CAN_STEP) != 0) ); ((step_option & F_CAN_STEP) != 0) );
@ -411,7 +437,7 @@ void dda_step(DDA *dda) {
unstep(); unstep();
// we have stepped in speed and now need to recalculate our delay // 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); setTimer(dda->move_duration / current_position.F);
dda->firstep = 0; dda->firstep = 0;
} }

View File

@ -55,6 +55,7 @@ uint8_t queue_full(void);
uint8_t queue_empty(void); uint8_t queue_empty(void);
void enqueue(TARGET *t); void enqueue(TARGET *t);
void next_move(void); void next_move(void);
void print_queue(void);
uint32_t approx_distance( uint32_t dx, uint32_t dy ); uint32_t approx_distance( uint32_t dx, uint32_t dy );
uint32_t approx_distance_3( uint32_t dx, uint32_t dy, uint32_t dz ); uint32_t approx_distance_3( uint32_t dx, uint32_t dy, uint32_t dz );

View File

@ -2,38 +2,64 @@
#define _MACHINE_H #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 #define MOVEBUFFER_SIZE 8
/* /*
axis calculations, adjust as necessary axis calculations, adjust as necessary
*/ */
#define XY_STEPS_PER_REV 1600.0 #define X_STEPS_PER_REV 1600.0
#define XY_COG_CIRCUMFERENCE (4.77 * 16.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 X_COG_CIRCUMFERENCE (4.77 * 16.0)
#define EXTRUDER_SHAFT_RADIUS 5 #define Y_COG_CIRCUMFERENCE X_COG_CIRCUMFERENCE
#define EXTRUDER_INLET_DIAMETER 3 // 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 EXTRUDER_NOZZLE_DIAMETER 0.8
#define STEPS_PER_MM_X ((XY_STEPS_PER_REV / XY_COG_CIRCUMFERENCE) + 0.5) #define STEPS_PER_MM_X ((uint32_t) ((X_STEPS_PER_REV / X_COG_CIRCUMFERENCE) + 0.5))
#define STEPS_PER_MM_Y ((XY_STEPS_PER_REV / XY_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 (200L) #define STEPS_PER_MM_Z ((uint32_t) ((Z_STEPS_PER_REV * Z_GEAR_RATIO) + 0.5))
#define STEPS_PER_MM_E (EXTRUDER_STEPS_PER_REV * EXTRUDER_SHAFT_RADIUS * PI * EXTRUDER_INLET_DIAMETER / EXTRUDER_NOZZLE_DIAMETER)
#define FEEDRATE_FAST_XY 2400 // http://blog.arcol.hu/?p=157 may help with this next one
#define FEEDRATE_SLOW_XY 120 // I haven't tuned this at all- it's just a placeholder until I read the above carefully enough
#define FEEDRATE_FAST_Z 240 // does this refer to filament or extrudate? extrudate depends on layer thickness.. hm
#define FEEDRATE_SLOW_Z 12 #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_XY 2400
#define FEEDRATE_FAST_E 1200 #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 #define PI 3.1415926535

View File

@ -15,6 +15,10 @@
#include "temp.h" #include "temp.h"
#include "sermsg.h" #include "sermsg.h"
#ifndef DEBUG
#define DEBUG 0
#endif
int main (void) int main (void)
{ {
uint8_t report; uint8_t report;
@ -72,10 +76,10 @@ int main (void)
scan_char(c); scan_char(c);
} }
// if (clock_flag_250ms & CLOCK_FLAG_250MS_TEMPCHECK) { if (clock_flag_250ms & CLOCK_FLAG_250MS_TEMPCHECK) {
// clock_flag_250ms &= ~CLOCK_FLAG_250MS_TEMPCHECK; clock_flag_250ms &= ~CLOCK_FLAG_250MS_TEMPCHECK;
// temp_tick(); temp_tick();
// } }
if (clock_flag_250ms & CLOCK_FLAG_250MS_REPORT) { if (clock_flag_250ms & CLOCK_FLAG_250MS_REPORT) {
clock_flag_250ms &= ~CLOCK_FLAG_250MS_REPORT; clock_flag_250ms &= ~CLOCK_FLAG_250MS_REPORT;
@ -83,53 +87,48 @@ int main (void)
if (report == 4) { if (report == 4) {
report = 0; report = 0;
// current move if (DEBUG) {
serial_writestr_P(PSTR("DDA: f#")); // current move
serwrite_int32(movebuffer[mb_head].f_counter); serial_writestr_P(PSTR("DDA: f#"));
serial_writechar('/'); serwrite_int32(movebuffer[mb_head].f_counter);
serwrite_uint16(movebuffer[mb_head].f_scale); serial_writechar('/');
serial_writechar('/'); serwrite_uint16(movebuffer[mb_head].f_scale);
serwrite_int16(movebuffer[mb_head].f_delta); serial_writechar('/');
serial_writechar('\n'); serwrite_int16(movebuffer[mb_head].f_delta);
serial_writechar('\n');
// current position // current position
serial_writestr_P(PSTR("Pos: ")); serial_writestr_P(PSTR("Pos: "));
serwrite_int32(current_position.X); serwrite_int32(current_position.X);
serial_writechar(','); serial_writechar(',');
serwrite_int32(current_position.Y); serwrite_int32(current_position.Y);
serial_writechar(','); serial_writechar(',');
serwrite_int32(current_position.Z); serwrite_int32(current_position.Z);
serial_writechar(','); serial_writechar(',');
serwrite_uint32(current_position.E); serwrite_uint32(current_position.E);
serial_writechar(','); serial_writechar(',');
serwrite_uint32(current_position.F); serwrite_uint32(current_position.F);
serial_writechar('\n'); serial_writechar('\n');
// target position // target position
serial_writestr_P(PSTR("Tar: ")); serial_writestr_P(PSTR("Dst: "));
serwrite_int32(movebuffer[mb_tail].endpoint.X); serwrite_int32(movebuffer[mb_tail].endpoint.X);
serial_writechar(','); serial_writechar(',');
serwrite_int32(movebuffer[mb_tail].endpoint.Y); serwrite_int32(movebuffer[mb_tail].endpoint.Y);
serial_writechar(','); serial_writechar(',');
serwrite_int32(movebuffer[mb_tail].endpoint.Z); serwrite_int32(movebuffer[mb_tail].endpoint.Z);
serial_writechar(','); serial_writechar(',');
serwrite_uint32(movebuffer[mb_tail].endpoint.E); serwrite_uint32(movebuffer[mb_tail].endpoint.E);
serial_writechar(','); serial_writechar(',');
serwrite_uint32(movebuffer[mb_tail].endpoint.F); serwrite_uint32(movebuffer[mb_tail].endpoint.F);
serial_writechar('\n'); serial_writechar('\n');
}
// Queue // Queue
serial_writestr_P(PSTR("Q : ")); print_queue();
// serwrite_uint8((mb_head - mb_tail) & (MOVEBUFFER_SIZE - 1));
serwrite_uint8(mb_head);
serial_writechar('/');
serwrite_uint8(mb_tail);
if (queue_full()) // temperature
serial_writechar('F'); temp_print();
if (queue_empty())
serial_writechar('E');
serial_writechar('\n');
} }
} }
} }

View File

@ -12,6 +12,8 @@
// M105- get temperature // M105- get temperature
case 105: case 105:
uint16_t t = temp_get(); uint16_t t = temp_get();
note that the MAX6675 can't do more than approx 4 conversions per second
*/ */
#include "temp.h" #include "temp.h"
@ -19,6 +21,8 @@
#include "machine.h" #include "machine.h"
#include "pinout.h" #include "pinout.h"
#include "clock.h" #include "clock.h"
#include "serial.h"
#include "sermsg.h"
uint16_t current_temp = 0; uint16_t current_temp = 0;
uint16_t target_temp = 0; uint16_t target_temp = 0;
@ -31,6 +35,10 @@ int32_t p_factor = 680;
int32_t i_factor = 18; int32_t i_factor = 18;
int32_t d_factor = 200; int32_t d_factor = 200;
uint8_t temp_flags = 0;
#define TEMP_FLAG_PRESENT 1
#define TEMP_FLAG_TCOPEN 2
#define PID_SCALE 1024L #define PID_SCALE 1024L
uint16_t temp_read() { uint16_t temp_read() {
@ -47,10 +55,13 @@ uint16_t temp_read() {
for (;(SPSR & MASK(SPIF)) == 0;); for (;(SPSR & MASK(SPIF)) == 0;);
temp |= SPDR; temp |= SPDR;
temp_flags = 0;
if ((temp & 0x8002) == 0) { if ((temp & 0x8002) == 0) {
// got "device id" // got "device id"
temp_flags |= TEMP_FLAG_PRESENT;
if (temp & 4) { if (temp & 4) {
// thermocouple open // thermocouple open
temp_flags |= TEMP_FLAG_TCOPEN;
} }
else { else {
current_temp = temp >> 3; current_temp = temp >> 3;
@ -71,6 +82,18 @@ uint16_t temp_get() {
return current_temp; 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() { void temp_tick() {
uint16_t last_temp = current_temp; uint16_t last_temp = current_temp;
temp_read(); temp_read();

View File

@ -6,6 +6,7 @@
uint16_t temp_read(void); uint16_t temp_read(void);
void temp_set(uint16_t t); void temp_set(uint16_t t);
uint16_t temp_get(void); uint16_t temp_get(void);
void temp_print(void);
void temp_tick(void); void temp_tick(void);
#endif /* _TIMER_H */ #endif /* _TIMER_H */