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-
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

View File

@ -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

View File

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

View File

@ -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,6 +160,7 @@ uint32_t abs32(int32_t v) {
void dda_create(TARGET *target, DDA *dda) {
uint32_t distance;
if (DEBUG)
serial_writestr_P(PSTR("\n{DDA_CREATE: ["));
// we end at the passed 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);
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,6 +192,7 @@ void dda_create(TARGET *target, DDA *dda) {
if (dda->total_steps == 0)
dda->nullmove = 1;
if (DEBUG)
serwrite_uint32(dda->total_steps); serial_writechar(',');
if (dda->f_delta > dda->total_steps) {
@ -188,6 +209,7 @@ void dda_create(TARGET *target, DDA *dda) {
dda->f_scale = 1;
}
if (DEBUG)
serwrite_uint32(dda->total_steps); serial_writechar(',');
dda->x_direction = (dda->endpoint.X >= startpoint.X)?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,6 +244,7 @@ void dda_create(TARGET *target, DDA *dda) {
else
dda->move_duration = 0;
if (DEBUG)
serwrite_uint32(dda->move_duration); serial_writestr_P(PSTR("] }\n"));
// next dda starts where we finish
@ -393,6 +417,7 @@ void dda_step(DDA *dda) {
}
}
if (DEBUG) {
serial_writechar('[');
serwrite_hex8(step_option);
serial_writechar(':');
@ -404,6 +429,7 @@ void dda_step(DDA *dda) {
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;
}

View File

@ -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 );

View File

@ -2,27 +2,43 @@
#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))
// 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 FEEDRATE_FAST_XY 2400
#define FEEDRATE_SLOW_XY 120
@ -33,7 +49,17 @@
#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

View File

@ -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,6 +87,7 @@ int main (void)
if (report == 4) {
report = 0;
if (DEBUG) {
// current move
serial_writestr_P(PSTR("DDA: f#"));
serwrite_int32(movebuffer[mb_head].f_counter);
@ -106,7 +111,7 @@ int main (void)
serial_writechar('\n');
// target position
serial_writestr_P(PSTR("Tar: "));
serial_writestr_P(PSTR("Dst: "));
serwrite_int32(movebuffer[mb_tail].endpoint.X);
serial_writechar(',');
serwrite_int32(movebuffer[mb_tail].endpoint.Y);
@ -117,19 +122,13 @@ int main (void)
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();
}
}
}

View File

@ -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();

View File

@ -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 */