heater.c File Reference

Manage heaters. More...

#include "heater.h"
#include <stdlib.h>
#include <avr/eeprom.h>
#include <avr/pgmspace.h>
#include "arduino.h"
#include <avr/io.h>
#include <stdint.h>
#include "temp.h"
#include "crc.h"
#include "sersendf.h"

Data Structures

struct  heater_definition_t
 simply holds pinout data- port, pin, pwm channel if used More...
struct  EE_factor
 this lives in the eeprom so we can save our PID settings for each heater More...

Defines

#define DEFINE_HEATER(name, pin)   { &(pin ## _WPORT), pin ## _PIN, (pin ## _PWM) },
 helper macro to fill heater definition struct from config.h
#define HOST
#define STEPS_PER_M_X   333333
#define STEPS_PER_M_Y   333333
#define STEPS_PER_M_Z   333333
#define MAXIMUM_FEEDRATE_X   2000
#define MAXIMUM_FEEDRATE_Y   2000
#define MAXIMUM_FEEDRATE_Z   2000
#define SEARCH_FEEDRATE_X   60
#define SEARCH_FEEDRATE_Y   60
#define SEARCH_FEEDRATE_Z   60
#define X_MIN   0.0
#define X_MAX   720.0
#define Y_MIN   0.0
#define Y_MAX   420.0
#define Z_MIN   0.0
#define Z_MAX   110.0
#define ACCELERATION_RAMPING
#define ACCELERATION   50.
#define MASK(PIN)   (1 << PIN)
#define _READ(IO)   (IO ## _RPORT & MASK(IO ## _PIN))
#define _WRITE(IO, v)   do { if (v) { IO ## _WPORT |= MASK(IO ## _PIN); } else { IO ## _WPORT &= ~MASK(IO ## _PIN); }; } while (0)
#define _TOGGLE(IO)   do { IO ## _RPORT = MASK(IO ## _PIN); } while (0)
#define _SET_INPUT(IO)   do { IO ## _DDR &= ~MASK(IO ## _PIN); } while (0)
#define _SET_OUTPUT(IO)   do { IO ## _DDR |= MASK(IO ## _PIN); } while (0)
#define _GET_INPUT(IO)   ((IO ## _DDR & MASK(IO ## _PIN)) == 0)
#define _GET_OUTPUT(IO)   ((IO ## _DDR & MASK(IO ## _PIN)) != 0)
#define READ(IO)   _READ(IO)
#define WRITE(IO, v)   _WRITE(IO, v)
#define TOGGLE(IO)   _TOGGLE(IO)
#define SET_INPUT(IO)   _SET_INPUT(IO)
#define SET_OUTPUT(IO)   _SET_OUTPUT(IO)
#define GET_INPUT(IO)   _GET_INPUT(IO)
#define GET_OUTPUT(IO)   _GET_OUTPUT(IO)
#define X_STEP_PIN   AIO0
#define X_DIR_PIN   AIO1
#define X_MIN_PIN   AIO2
#define X_INVERT_DIR   1
#define X_INVERT_MIN   1
#define Y_STEP_PIN   AIO3
#define Y_DIR_PIN   AIO4
#define Y_MIN_PIN   AIO5
#define Y_INVERT_MIN   1
#define Z_STEP_PIN   DIO2
#define Z_DIR_PIN   DIO4
#define Z_MIN_PIN   DIO7
#define Z_INVERT_MIN   1
#define CHARGEPUMP_PIN   DIO3
#define ESTOP_IN_PIN   DIO8
#define ESTOP_INVERT_IN   1
#define BAUD   115200
#define XONXOFF
#define MOVEBUFFER_SIZE   8
#define USE_WATCHDOG
#define STEP_INTERRUPT_INTERRUPTIBLE   0
#define ENDSTOP_STEPS   4
#define DEFAULT_P   8192
 default scaled P factor, equivalent to 8.0
#define DEFAULT_I   512
 default scaled I factor, equivalent to 0.5
#define DEFAULT_D   24576
 default scaled D factor, equivalent to 24
#define DEFAULT_I_LIMIT   384
 default scaled I limit

Functions

void heater_init ()
 initialise heater subsystem Set directions, initialise PWM timers, read PID factors from eeprom, etc
void heater_save_settings ()
 Write PID factors to eeprom.
void heater_tick (heater_t h, temp_sensor_t t, uint16_t current_temp, uint16_t target_temp)
 run heater PID algorithm
void heater_set (heater_t index, uint8_t value)
 manually set PWM output
uint8_t heaters_all_off ()
 turn off all heaters
void pid_set_p (heater_t index, int32_t p)
 set heater P factor
void pid_set_i (heater_t index, int32_t i)
 set heater I factor
void pid_set_d (heater_t index, int32_t d)
 set heater D factor
void pid_set_i_limit (heater_t index, int32_t i_limit)
 set heater I limit
void heater_print (uint16_t i)
 send heater debug info to host

Variables

struct {
   int32_t   p_factor
 scaled P factor
   int32_t   i_factor
 scaled I factor
   int32_t   d_factor
 scaled D factor
   int16_t   i_limit
 scaled I limit, such that $-i_{limit} < i_{factor} < i_{limit}$
heaters_pid [NUM_HEATERS]
 this struct holds the heater PID factors
struct {
   int16_t   heater_i
 integrator, $-i_{limit} < \sum{\Delta t} < i_{limit}$
   uint16_t   temp_history [TH_COUNT]
 store last TH_COUNT readings in a ring, so we can smooth out our differentiator
   uint8_t   temp_history_pointer
 pointer to last entry in ring
   uint8_t   heater_output
 this is the PID value we eventually send to the heater
heaters_runtime [NUM_HEATERS]
 this struct holds the runtime heater data- PID integrator history, temperature history, sanity checker
EE_factor EEMEM EE_factors [NUM_HEATERS]

Detailed Description

Manage heaters.


Function Documentation

void heater_print ( uint16_t  i  ) 

send heater debug info to host

Parameters:
i index of heater to send info for
void heater_set ( heater_t  index,
uint8_t  value 
)

manually set PWM output

Parameters:
index the heater we're setting the output for
value the PWM value to write

anything done by this function is overwritten by heater_tick above if the heater has an associated temp sensor

Referenced by heater_tick().

void heater_tick ( heater_t  h,
temp_sensor_t  t,
uint16_t  current_temp,
uint16_t  target_temp 
)

run heater PID algorithm

Parameters:
h which heater we're running the loop for
t which temp sensor this heater is attached to
current_temp the temperature that the associated temp sensor is reporting
target_temp the temperature we're trying to achieve

Referenced by temp_sensor_tick().

uint8_t heaters_all_off ( void   ) 

turn off all heaters

for emergency stop

void pid_set_d ( heater_t  index,
int32_t  d 
)

set heater D factor

Parameters:
index heater to change D factor for
d scaled D factor
void pid_set_i ( heater_t  index,
int32_t  i 
)

set heater I factor

Parameters:
index heater to change I factor for
i scaled I factor
void pid_set_i_limit ( heater_t  index,
int32_t  i_limit 
)

set heater I limit

Parameters:
index heater to set I limit for
i_limit scaled I limit
void pid_set_p ( heater_t  index,
int32_t  p 
)

set heater P factor

Parameters:
index heater to change factor for
p scaled P factor

Variable Documentation

this struct holds the heater PID factors

PID is a fascinating way to control any closed loop control, combining the error (P), cumulative error (I) and rate at which we're approacing the setpoint (D) in such a way that when correctly tuned, the system will achieve target temperature quickly and with little to no overshoot

At every sample, we calculate $OUT = k_P (S - T) + k_I \int (S - T) + k_D \frac{dT}{dt}$ where S is setpoint and T is temperature.

The three factors kP, kI, kD are chosen to give the desired behaviour given the dynamics of the system.

See http://www.eetimes.com/design/embedded/4211211/PID-without-a-PhD for the full story

Referenced by heater_init(), heater_print(), heater_save_settings(), heater_tick(), pid_set_d(), pid_set_i(), pid_set_i_limit(), and pid_set_p().

 All Data Structures Files Functions Variables Defines
Generated on Mon Jul 30 16:33:58 2012 for Teacup by  doxygen 1.6.3