time to save, made debug output (524 bytes) and global clock (50 bytes) optional
This commit is contained in:
parent
098f277713
commit
d302329eee
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
38
mendel/dda.c
38
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,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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Reference in New Issue