splitting heater stuff out into a separate file
This commit is contained in:
parent
e5d393a592
commit
273d63f242
2
Makefile
2
Makefile
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
PROGRAM = mendel
|
||||
|
||||
SOURCES = $(PROGRAM).c serial.c dda.c gcode.c timer.c clock.c temp.c sermsg.c dda_queue.c watchdog.c debug.c sersendf.c
|
||||
SOURCES = $(PROGRAM).c serial.c dda.c gcode.c timer.c clock.c temp.c sermsg.c dda_queue.c watchdog.c debug.c sersendf.c heater.c
|
||||
|
||||
##############################################################################
|
||||
# #
|
||||
|
|
|
|||
3
gcode.c
3
gcode.c
|
|
@ -12,6 +12,7 @@
|
|||
#include "clock.h"
|
||||
#include "watchdog.h"
|
||||
#include "debug.h"
|
||||
#include "heater.h"
|
||||
|
||||
uint8_t last_field = 0;
|
||||
|
||||
|
|
@ -661,7 +662,7 @@ void process_gcode_command(GCODE_COMMAND *gcmd) {
|
|||
break;
|
||||
// M134- save PID settings to eeprom
|
||||
case 134:
|
||||
temp_save_settings();
|
||||
heater_save_settings();
|
||||
break;
|
||||
|
||||
#ifdef DEBUG
|
||||
|
|
|
|||
|
|
@ -0,0 +1,122 @@
|
|||
#include "heater.h"
|
||||
|
||||
#include <avr/eeprom.h>
|
||||
|
||||
#include "sersendf.h"
|
||||
#include "machine.h"
|
||||
#include "pinout.h"
|
||||
#include "debug.h"
|
||||
#include "arduino.h"
|
||||
|
||||
int16_t heater_p = 0;
|
||||
int16_t heater_i = 0;
|
||||
int16_t heater_d = 0;
|
||||
|
||||
#define DEFAULT_P 8192
|
||||
#define DEFAULT_I 512
|
||||
#define DEFAULT_D -24576
|
||||
#define DEFAULT_I_LIMIT 384
|
||||
int32_t p_factor = 0;
|
||||
int32_t i_factor = 0;
|
||||
int32_t d_factor = 0;
|
||||
int16_t i_limit = 0;
|
||||
|
||||
int32_t EEMEM EE_p_factor;
|
||||
int32_t EEMEM EE_i_factor;
|
||||
int32_t EEMEM EE_d_factor;
|
||||
int16_t EEMEM EE_i_limit;
|
||||
|
||||
#define TH_COUNT 8
|
||||
uint16_t temp_history[TH_COUNT] __attribute__ ((__section__ (".bss")));
|
||||
uint8_t th_p = 0;
|
||||
|
||||
uint8_t temp_residency = 0;
|
||||
|
||||
#ifndef ABSDELTA
|
||||
#define ABSDELTA(a, b) (((a) >= (b))?((a) - (b)):((b) - (a)))
|
||||
#endif
|
||||
|
||||
void heater_init() {
|
||||
p_factor = eeprom_read_dword((uint32_t *) &EE_p_factor);
|
||||
i_factor = eeprom_read_dword((uint32_t *) &EE_i_factor);
|
||||
d_factor = eeprom_read_dword((uint32_t *) &EE_d_factor);
|
||||
i_limit = eeprom_read_word((uint16_t *) &EE_i_limit);
|
||||
|
||||
if ((p_factor == 0) && (i_factor == 0) && (d_factor == 0) && (i_limit == 0)) {
|
||||
p_factor = DEFAULT_P;
|
||||
i_factor = DEFAULT_I;
|
||||
d_factor = DEFAULT_D;
|
||||
i_limit = DEFAULT_I_LIMIT;
|
||||
}
|
||||
}
|
||||
|
||||
void heater_save_settings() {
|
||||
eeprom_write_dword((uint32_t *) &EE_p_factor, p_factor);
|
||||
eeprom_write_dword((uint32_t *) &EE_i_factor, i_factor);
|
||||
eeprom_write_dword((uint32_t *) &EE_d_factor, d_factor);
|
||||
eeprom_write_word((uint16_t *) &EE_i_limit, i_limit);
|
||||
}
|
||||
|
||||
void heater_tick(int16_t current_temp, int16_t target_temp) {
|
||||
temp_history[th_p++] = current_temp;
|
||||
th_p &= (TH_COUNT - 1);
|
||||
|
||||
if (ABSDELTA(current_temp, target_temp) > TEMP_HYSTERESIS)
|
||||
temp_residency = 0;
|
||||
else if (temp_residency < TEMP_RESIDENCY_TIME)
|
||||
temp_residency++;
|
||||
|
||||
int16_t t_error = target_temp - current_temp;
|
||||
|
||||
// PID stuff
|
||||
// proportional
|
||||
heater_p = t_error;
|
||||
|
||||
// integral
|
||||
heater_i += t_error;
|
||||
// prevent integrator wind-up
|
||||
if (heater_i > i_limit)
|
||||
heater_i = i_limit;
|
||||
else if (heater_i < -i_limit)
|
||||
heater_i = -i_limit;
|
||||
|
||||
// derivative
|
||||
// note: D follows temp rather than error so there's no large derivative when the target changes
|
||||
heater_d = current_temp - temp_history[th_p];
|
||||
|
||||
// combine factors
|
||||
int32_t pid_output_intermed = (
|
||||
(
|
||||
(((int32_t) heater_p) * p_factor) +
|
||||
(((int32_t) heater_i) * i_factor) +
|
||||
(((int32_t) heater_d) * d_factor)
|
||||
) / PID_SCALE
|
||||
);
|
||||
|
||||
// rebase and limit factors
|
||||
uint8_t pid_output;
|
||||
if (pid_output_intermed > 255)
|
||||
pid_output = 255;
|
||||
else if (pid_output_intermed < 0)
|
||||
pid_output = 0;
|
||||
else
|
||||
pid_output = pid_output_intermed & 0xFF;
|
||||
|
||||
if (debug_flags & DEBUG_PID)
|
||||
sersendf_P(PSTR("T{E:%d, P:%d * %ld = %ld / I:%d * %ld = %ld / D:%d * %ld = %ld # O: %ld = %u}\n"), t_error, heater_p, p_factor, (int32_t) heater_p * p_factor / PID_SCALE, heater_i, i_factor, (int32_t) heater_i * i_factor / PID_SCALE, heater_d, d_factor, (int32_t) heater_d * d_factor / PID_SCALE, pid_output_intermed, pid_output);
|
||||
|
||||
#ifdef HEATER_PWM
|
||||
HEATER_PWM = pid_output;
|
||||
#else
|
||||
if (pid_output >= 8)
|
||||
enable_heater();
|
||||
else
|
||||
disable_heater();
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t temp_achieved() {
|
||||
if (temp_residency >= TEMP_RESIDENCY_TIME)
|
||||
return 255;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef _HEATER_H
|
||||
#define _HEATER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// extruder heater PID factors
|
||||
// google "PID without a PHD" if you don't understand this PID stuff
|
||||
extern int32_t p_factor;
|
||||
extern int32_t i_factor;
|
||||
extern int32_t d_factor;
|
||||
extern int16_t i_limit;
|
||||
|
||||
#define PID_SCALE 1024L
|
||||
#define I_LIMIT 4000
|
||||
|
||||
void heater_init(void);
|
||||
void heater_save_settings(void);
|
||||
void heater_tick(int16_t current_temp, int16_t target_temp);
|
||||
uint8_t temp_achieved(void);
|
||||
|
||||
#endif /* _HEATER_H */
|
||||
3
mendel.c
3
mendel.c
|
|
@ -18,6 +18,7 @@
|
|||
#include "watchdog.h"
|
||||
#include "debug.h"
|
||||
#include "sersendf.h"
|
||||
#include "heater.h"
|
||||
|
||||
void io_init(void) {
|
||||
// disable modules we don't use
|
||||
|
|
@ -92,7 +93,7 @@ void init(void) {
|
|||
clock_setup();
|
||||
|
||||
// read PID settings from EEPROM
|
||||
temp_init();
|
||||
heater_init();
|
||||
|
||||
// set up default feedrate
|
||||
current_position.F = startpoint.F = next_target.target.F = SEARCH_FEEDRATE_Z;
|
||||
|
|
|
|||
56
temp.c
56
temp.c
|
|
@ -29,11 +29,12 @@
|
|||
#include "dda.h"
|
||||
#include "sersendf.h"
|
||||
#include "debug.h"
|
||||
#include "heater.h"
|
||||
|
||||
uint16_t current_temp = 0;
|
||||
uint16_t target_temp = 0;
|
||||
|
||||
int16_t heater_p = 0;
|
||||
/*int16_t heater_p = 0;
|
||||
int16_t heater_i = 0;
|
||||
int16_t heater_d = 0;
|
||||
|
||||
|
|
@ -45,47 +46,26 @@ int32_t p_factor = 0;
|
|||
int32_t i_factor = 0;
|
||||
int32_t d_factor = 0;
|
||||
int16_t i_limit = 0;
|
||||
|
||||
int32_t EEMEM EE_p_factor;
|
||||
int32_t EEMEM EE_i_factor;
|
||||
int32_t EEMEM EE_d_factor;
|
||||
int16_t EEMEM EE_i_limit;
|
||||
*/
|
||||
// int32_t EEMEM EE_p_factor;
|
||||
// int32_t EEMEM EE_i_factor;
|
||||
// int32_t EEMEM EE_d_factor;
|
||||
// int16_t EEMEM EE_i_limit;
|
||||
|
||||
uint8_t temp_flags = 0;
|
||||
#define TEMP_FLAG_PRESENT 1
|
||||
#define TEMP_FLAG_TCOPEN 2
|
||||
|
||||
uint8_t temp_residency = 0;
|
||||
|
||||
#define TH_COUNT 8
|
||||
uint16_t temp_history[TH_COUNT] __attribute__ ((__section__ (".bss")));
|
||||
uint8_t th_p = 0;
|
||||
/*uint8_t temp_residency = 0;
|
||||
*/
|
||||
// #define TH_COUNT 8
|
||||
// uint16_t temp_history[TH_COUNT] __attribute__ ((__section__ (".bss")));
|
||||
// uint8_t th_p = 0;
|
||||
|
||||
#ifndef ABSDELTA
|
||||
#define ABSDELTA(a, b) (((a) >= (b))?((a) - (b)):((b) - (a)))
|
||||
#endif
|
||||
|
||||
void temp_init() {
|
||||
p_factor = eeprom_read_dword((uint32_t *) &EE_p_factor);
|
||||
i_factor = eeprom_read_dword((uint32_t *) &EE_i_factor);
|
||||
d_factor = eeprom_read_dword((uint32_t *) &EE_d_factor);
|
||||
i_limit = eeprom_read_word((uint16_t *) &EE_i_limit);
|
||||
|
||||
if ((p_factor == 0) && (i_factor == 0) && (d_factor == 0) && (i_limit == 0)) {
|
||||
p_factor = DEFAULT_P;
|
||||
i_factor = DEFAULT_I;
|
||||
d_factor = DEFAULT_D;
|
||||
i_limit = DEFAULT_I_LIMIT;
|
||||
}
|
||||
}
|
||||
|
||||
void temp_save_settings() {
|
||||
eeprom_write_dword((uint32_t *) &EE_p_factor, p_factor);
|
||||
eeprom_write_dword((uint32_t *) &EE_i_factor, i_factor);
|
||||
eeprom_write_dword((uint32_t *) &EE_d_factor, d_factor);
|
||||
eeprom_write_word((uint16_t *) &EE_i_limit, i_limit);
|
||||
}
|
||||
|
||||
uint16_t temp_read() {
|
||||
uint16_t temp;
|
||||
|
||||
|
|
@ -144,12 +124,6 @@ uint16_t temp_get_target() {
|
|||
return target_temp;
|
||||
}
|
||||
|
||||
uint8_t temp_achieved() {
|
||||
if (temp_residency >= TEMP_RESIDENCY_TIME)
|
||||
return 255;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void temp_print() {
|
||||
if (temp_flags & TEMP_FLAG_TCOPEN) {
|
||||
serial_writestr_P(PSTR("T: no thermocouple!\n"));
|
||||
|
|
@ -173,7 +147,9 @@ void temp_tick() {
|
|||
|
||||
temp_read();
|
||||
|
||||
temp_history[th_p++] = current_temp;
|
||||
heater_tick(current_temp, target_temp);
|
||||
|
||||
/* temp_history[th_p++] = current_temp;
|
||||
th_p &= (TH_COUNT - 1);
|
||||
|
||||
if (ABSDELTA(current_temp, target_temp) > TEMP_HYSTERESIS)
|
||||
|
|
@ -227,6 +203,6 @@ void temp_tick() {
|
|||
enable_heater();
|
||||
else
|
||||
disable_heater();
|
||||
#endif
|
||||
#endif*/
|
||||
}
|
||||
}
|
||||
|
|
|
|||
10
temp.h
10
temp.h
|
|
@ -6,16 +6,6 @@
|
|||
// RepRap host software isn't exactly tolerant on what it ready back.
|
||||
#define REPRAP_HOST_COMPATIBILITY
|
||||
|
||||
// extruder heater PID factors
|
||||
// google "PID without a PHD" if you don't understand this PID stuff
|
||||
extern int32_t p_factor;
|
||||
extern int32_t i_factor;
|
||||
extern int32_t d_factor;
|
||||
extern int16_t i_limit;
|
||||
|
||||
#define PID_SCALE 1024L
|
||||
#define I_LIMIT 4000
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t high;
|
||||
|
|
|
|||
Loading…
Reference in New Issue