split up dda and its queue, moved clock tick functions from main loop so I can call them from M101 while waiting for heater to reach target temperature, added thermal hysteresis setting
This commit is contained in:
parent
5b1245e41d
commit
8cc6fa6937
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
PROGRAM = mendel
|
||||
|
||||
SOURCES = $(PROGRAM).c ringbuffer.c serial.c dda.c gcode.c timer.c clock.c temp.c sermsg.c
|
||||
SOURCES = $(PROGRAM).c ringbuffer.c serial.c dda.c gcode.c timer.c clock.c temp.c sermsg.c dda_queue.c
|
||||
|
||||
##############################################################################
|
||||
# #
|
||||
|
|
|
|||
|
|
@ -11,9 +11,10 @@ uint32_t clock_read(void);
|
|||
|
||||
extern volatile uint8_t clock_flag_250ms;
|
||||
|
||||
#define CLOCK_FLAG_250MS_TEMPCHECK 1
|
||||
#define CLOCK_FLAG_250MS_REPORT 2
|
||||
#define CLOCK_FLAG_250MS_STEPTIMEOUT 4
|
||||
#define CLOCK_FLAG_250MS 1
|
||||
// #define CLOCK_FLAG_250MS_TEMPCHECK 1
|
||||
// #define CLOCK_FLAG_250MS_REPORT 2
|
||||
// #define CLOCK_FLAG_250MS_STEPTIMEOUT 4
|
||||
|
||||
/*
|
||||
ifclock() {}
|
||||
|
|
|
|||
75
mendel/dda.c
75
mendel/dda.c
|
|
@ -5,6 +5,7 @@
|
|||
#include "timer.h"
|
||||
#include "serial.h"
|
||||
#include "sermsg.h"
|
||||
#include "dda_queue.h"
|
||||
|
||||
#ifndef ABS
|
||||
#define ABS(v) (((v) >= 0)?(v):(-(v)))
|
||||
|
|
@ -31,78 +32,6 @@ uint8_t steptimeout = 0;
|
|||
TARGET startpoint = { 0, 0, 0, 0, 0 };
|
||||
TARGET current_position = { 0, 0, 0, 0, 0 };
|
||||
|
||||
/*
|
||||
move queue
|
||||
*/
|
||||
|
||||
uint8_t mb_head = 0;
|
||||
uint8_t mb_tail = 0;
|
||||
DDA movebuffer[MOVEBUFFER_SIZE];
|
||||
|
||||
|
||||
uint8_t queue_full() {
|
||||
if (mb_tail == 0)
|
||||
return mb_head == (MOVEBUFFER_SIZE - 1);
|
||||
else
|
||||
return mb_head == (mb_tail - 1);
|
||||
}
|
||||
|
||||
uint8_t queue_empty() {
|
||||
return ((mb_tail == mb_head) && (movebuffer[mb_tail].live == 0))?255:0;
|
||||
}
|
||||
|
||||
void enqueue(TARGET *t) {
|
||||
while (queue_full())
|
||||
delay(WAITING_DELAY);
|
||||
|
||||
uint8_t h = mb_head;
|
||||
h++;
|
||||
if (h == MOVEBUFFER_SIZE)
|
||||
h = 0;
|
||||
|
||||
dda_create(t, &movebuffer[h]);
|
||||
|
||||
// if queue only has one space left, stop transmition
|
||||
if (((h + 2) & (MOVEBUFFER_SIZE - 1)) == mb_tail)
|
||||
xoff();
|
||||
|
||||
mb_head = h;
|
||||
|
||||
// fire up in case we're not running yet
|
||||
enableTimerInterrupt();
|
||||
}
|
||||
|
||||
void next_move() {
|
||||
if (queue_empty()) {
|
||||
// queue is empty
|
||||
// disable_steppers();
|
||||
// setTimer(DEFAULT_TICK);
|
||||
disableTimerInterrupt();
|
||||
}
|
||||
else {
|
||||
uint8_t t = mb_tail;
|
||||
t++;
|
||||
if (t == MOVEBUFFER_SIZE)
|
||||
t = 0;
|
||||
dda_start(&movebuffer[t]);
|
||||
mb_tail = t;
|
||||
}
|
||||
// restart transmission
|
||||
xon();
|
||||
}
|
||||
|
||||
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');
|
||||
}
|
||||
|
||||
/*
|
||||
utility functions
|
||||
*/
|
||||
|
|
@ -180,7 +109,7 @@ uint32_t delta32(uint32_t v1, uint32_t v2) {
|
|||
CREATE a dda given current_position and a target, save to passed location so we can write directly into the queue
|
||||
*/
|
||||
|
||||
void dda_create(TARGET *target, DDA *dda) {
|
||||
void dda_create(DDA *dda, TARGET *target) {
|
||||
uint32_t distance;
|
||||
|
||||
// initialise DDA to a known state
|
||||
|
|
|
|||
25
mendel/dda.h
25
mendel/dda.h
|
|
@ -6,6 +6,10 @@
|
|||
#include "pinout.h"
|
||||
#include "machine.h"
|
||||
|
||||
/*
|
||||
types
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
int32_t X;
|
||||
int32_t Y;
|
||||
|
|
@ -43,24 +47,23 @@ typedef struct {
|
|||
uint32_t move_duration;
|
||||
} DDA;
|
||||
|
||||
extern uint8_t mb_head;
|
||||
extern uint8_t mb_tail;
|
||||
extern DDA movebuffer[MOVEBUFFER_SIZE];
|
||||
extern TARGET startpoint;
|
||||
extern TARGET current_position;
|
||||
/*
|
||||
variables
|
||||
*/
|
||||
|
||||
extern uint8_t steptimeout;
|
||||
|
||||
uint8_t queue_full(void);
|
||||
uint8_t queue_empty(void);
|
||||
void enqueue(TARGET *t);
|
||||
void next_move(void);
|
||||
void print_queue(void);
|
||||
extern TARGET startpoint;
|
||||
extern TARGET current_position;
|
||||
|
||||
/*
|
||||
methods
|
||||
*/
|
||||
|
||||
uint32_t approx_distance( uint32_t dx, uint32_t dy );
|
||||
uint32_t approx_distance_3( uint32_t dx, uint32_t dy, uint32_t dz );
|
||||
|
||||
void dda_create(TARGET *target, DDA *dda);
|
||||
void dda_create(DDA *dda, TARGET *target);
|
||||
void dda_start(DDA *dda);
|
||||
void dda_step(DDA *dda);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,73 @@
|
|||
#include "dda_queue.h"
|
||||
|
||||
#include "timer.h"
|
||||
#include "serial.h"
|
||||
#include "sermsg.h"
|
||||
|
||||
uint8_t mb_head = 0;
|
||||
uint8_t mb_tail = 0;
|
||||
DDA movebuffer[MOVEBUFFER_SIZE];
|
||||
|
||||
|
||||
uint8_t queue_full() {
|
||||
if (mb_tail == 0)
|
||||
return mb_head == (MOVEBUFFER_SIZE - 1);
|
||||
else
|
||||
return mb_head == (mb_tail - 1);
|
||||
}
|
||||
|
||||
uint8_t queue_empty() {
|
||||
return ((mb_tail == mb_head) && (movebuffer[mb_tail].live == 0))?255:0;
|
||||
}
|
||||
|
||||
void enqueue(TARGET *t) {
|
||||
while (queue_full())
|
||||
delay(WAITING_DELAY);
|
||||
|
||||
uint8_t h = mb_head;
|
||||
h++;
|
||||
if (h == MOVEBUFFER_SIZE)
|
||||
h = 0;
|
||||
|
||||
dda_create(&movebuffer[h], t);
|
||||
|
||||
// if queue only has one space left, stop transmition
|
||||
if (((h + 2) & (MOVEBUFFER_SIZE - 1)) == mb_tail)
|
||||
xoff();
|
||||
|
||||
mb_head = h;
|
||||
|
||||
// fire up in case we're not running yet
|
||||
enableTimerInterrupt();
|
||||
}
|
||||
|
||||
void next_move() {
|
||||
if (queue_empty()) {
|
||||
// queue is empty
|
||||
// disable_steppers();
|
||||
// setTimer(DEFAULT_TICK);
|
||||
disableTimerInterrupt();
|
||||
}
|
||||
else {
|
||||
uint8_t t = mb_tail;
|
||||
t++;
|
||||
if (t == MOVEBUFFER_SIZE)
|
||||
t = 0;
|
||||
dda_start(&movebuffer[t]);
|
||||
mb_tail = t;
|
||||
}
|
||||
// restart transmission
|
||||
xon();
|
||||
}
|
||||
|
||||
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');
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef _DDA_QUEUE
|
||||
#define _DDA_QUEUE
|
||||
|
||||
#include "dda.h"
|
||||
|
||||
/*
|
||||
variables
|
||||
*/
|
||||
|
||||
extern uint8_t mb_head;
|
||||
extern uint8_t mb_tail;
|
||||
extern DDA movebuffer[MOVEBUFFER_SIZE];
|
||||
|
||||
/*
|
||||
methods
|
||||
*/
|
||||
|
||||
uint8_t queue_full(void);
|
||||
uint8_t queue_empty(void);
|
||||
void enqueue(TARGET *t);
|
||||
void next_move(void);
|
||||
void print_queue(void);
|
||||
|
||||
#endif /* _DDA_QUEUE */
|
||||
|
|
@ -7,6 +7,9 @@
|
|||
#include "sermsg.h"
|
||||
#include "temp.h"
|
||||
#include "timer.h"
|
||||
#include "dda_queue.h"
|
||||
#include "dda.h"
|
||||
#include "clock.h"
|
||||
|
||||
uint8_t option_bitfield;
|
||||
#define OPTION_COMMENT 128
|
||||
|
|
@ -382,6 +385,14 @@ void process_gcode_command(GCODE_COMMAND *gcmd) {
|
|||
switch (gcmd->M) {
|
||||
// M101- extruder on
|
||||
case 101:
|
||||
// here we wait until target temperature is reached, and emulate main loop so the temperature can actually be updated
|
||||
while (!temp_achieved()) {
|
||||
ifclock(CLOCK_FLAG_250MS) {
|
||||
// this is cosmetically nasty, but exactly what needs to happen
|
||||
void clock_250ms(void);
|
||||
clock_250ms();
|
||||
}
|
||||
}
|
||||
SpecialMoveE(E_STARTSTOP_STEPS, FEEDRATE_FAST_E);
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,12 @@
|
|||
#define E_STARTSTOP_STEPS 20
|
||||
#define FEEDRATE_FAST_E 1200
|
||||
|
||||
/*
|
||||
extruder settings
|
||||
*/
|
||||
|
||||
#define TEMP_HYSTERESIS 2
|
||||
|
||||
/*
|
||||
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!
|
||||
|
|
|
|||
183
mendel/mendel.c
183
mendel/mendel.c
|
|
@ -8,6 +8,7 @@
|
|||
#include "machine.h"
|
||||
|
||||
#include "serial.h"
|
||||
#include "dda_queue.h"
|
||||
#include "dda.h"
|
||||
#include "gcode.h"
|
||||
#include "timer.h"
|
||||
|
|
@ -87,79 +88,141 @@ inline void init(void) {
|
|||
//enableTimerInterrupt();
|
||||
}
|
||||
|
||||
void clock_250ms() {
|
||||
static uint8_t report = 0;
|
||||
|
||||
temp_tick();
|
||||
|
||||
if (steptimeout > (30 * 4))
|
||||
disable_steppers();
|
||||
else
|
||||
steptimeout++;
|
||||
|
||||
report++;
|
||||
if (report == 4) {
|
||||
report = 0;
|
||||
|
||||
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_int32(current_position.E);
|
||||
serial_writechar(',');
|
||||
serwrite_uint32(current_position.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_int32(movebuffer[mb_tail].endpoint.E);
|
||||
serial_writechar(',');
|
||||
serwrite_uint32(movebuffer[mb_tail].endpoint.F);
|
||||
serial_writechar('\n');
|
||||
|
||||
// Queue
|
||||
print_queue();
|
||||
}
|
||||
|
||||
// temperature
|
||||
temp_print();
|
||||
}
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
uint8_t report = 0;
|
||||
|
||||
init();
|
||||
|
||||
// main loop
|
||||
for (;;)
|
||||
{
|
||||
if (serial_rxchars()) {
|
||||
// if queue is full, no point in reading chars- host will just have to wait
|
||||
if (serial_rxchars() && !queue_full()) {
|
||||
uint8_t c = serial_popchar();
|
||||
scan_char(c);
|
||||
}
|
||||
|
||||
ifclock(CLOCK_FLAG_250MS_TEMPCHECK) {
|
||||
temp_tick();
|
||||
ifclock(CLOCK_FLAG_250MS) {
|
||||
clock_250ms();
|
||||
}
|
||||
|
||||
ifclock(CLOCK_FLAG_250MS_STEPTIMEOUT) {
|
||||
if (steptimeout > (30 * 4))
|
||||
disable_steppers();
|
||||
else
|
||||
steptimeout++;
|
||||
}
|
||||
|
||||
ifclock(CLOCK_FLAG_250MS_REPORT) {
|
||||
report++;
|
||||
if (report == 4) {
|
||||
report = 0;
|
||||
|
||||
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);
|
||||
// ifclock(CLOCK_FLAG_250MS_TEMPCHECK) {
|
||||
// temp_tick();
|
||||
// }
|
||||
//
|
||||
// ifclock(CLOCK_FLAG_250MS_STEPTIMEOUT) {
|
||||
// if (steptimeout > (30 * 4))
|
||||
// disable_steppers();
|
||||
// else
|
||||
// steptimeout++;
|
||||
// }
|
||||
//
|
||||
// ifclock(CLOCK_FLAG_250MS_REPORT) {
|
||||
// report++;
|
||||
// if (report == 4) {
|
||||
// report = 0;
|
||||
//
|
||||
// if (DEBUG) {
|
||||
// // current move
|
||||
// serial_writestr_P(PSTR("DDA: f#"));
|
||||
// serwrite_int32(movebuffer[mb_head].f_counter);
|
||||
// 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_int32(current_position.E);
|
||||
serial_writechar(',');
|
||||
serwrite_uint32(current_position.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_int32(movebuffer[mb_tail].endpoint.E);
|
||||
serial_writechar(',');
|
||||
serwrite_uint32(movebuffer[mb_tail].endpoint.F);
|
||||
serial_writechar('\n');
|
||||
}
|
||||
|
||||
// Queue
|
||||
print_queue();
|
||||
|
||||
// temperature
|
||||
temp_print();
|
||||
}
|
||||
}
|
||||
// // 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_int32(current_position.E);
|
||||
// serial_writechar(',');
|
||||
// serwrite_uint32(current_position.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_int32(movebuffer[mb_tail].endpoint.E);
|
||||
// serial_writechar(',');
|
||||
// serwrite_uint32(movebuffer[mb_tail].endpoint.F);
|
||||
// serial_writechar('\n');
|
||||
// }
|
||||
//
|
||||
// // Queue
|
||||
// print_queue();
|
||||
//
|
||||
// // temperature
|
||||
// temp_print();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,6 +84,16 @@ uint16_t temp_get() {
|
|||
return current_temp;
|
||||
}
|
||||
|
||||
uint8_t temp_achieved() {
|
||||
if (current_temp >= target_temp)
|
||||
if ((current_temp - target_temp) < TEMP_HYSTERESIS)
|
||||
return 255;
|
||||
if (current_temp < target_temp)
|
||||
if ((target_temp - current_temp) < TEMP_HYSTERESIS)
|
||||
return 255;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void temp_print() {
|
||||
serial_writestr_P(PSTR("T: "));
|
||||
if (temp_flags & TEMP_FLAG_TCOPEN) {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
uint16_t temp_read(void);
|
||||
void temp_set(uint16_t t);
|
||||
uint16_t temp_get(void);
|
||||
uint8_t temp_achieved(void);
|
||||
void temp_print(void);
|
||||
void temp_tick(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include <avr/interrupt.h>
|
||||
|
||||
#include "pinout.h"
|
||||
#include "dda_queue.h"
|
||||
#include "dda.h"
|
||||
|
||||
ISR(TIMER1_COMPA_vect) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue