merge multi_temp stuff

This commit is contained in:
Michael Moon 2010-10-25 22:45:22 +11:00
parent c5e544b1fe
commit d93dcff378
7 changed files with 361 additions and 313 deletions

View File

@ -71,6 +71,63 @@
#define TEMP_THERMISTOR
// #define TEMP_AD595
#define NUM_TEMP_SENSORS 1
#ifdef TEMP_C
/***************************************************************************\
* *
* Fill in the following struct according to your hardware *
* *
* If your temperature sensor has no associated heater, enter '255' as the *
* heater index. *
* *
\***************************************************************************/
struct {
uint8_t temp_type;
uint8_t temp_pin;
uint8_t heater_index;
} temp_sensors[NUM_TEMP_SENSORS] =
{
{
TT_MAX6675,
0,
0
}
};
#endif
#define NUM_HEATERS 1
#ifdef HEATER_C
/***************************************************************************\
* *
* Fill in the following struct according to your hardware *
* *
* For the atmega168/328, timer/pin mappings are as follows *
* *
* OCR0A - PD6 *
* OCR0B - PD5 *
* OCR2A - PB3 *
* OCR2B - PD3 *
* *
\***************************************************************************/
struct {
volatile uint8_t *heater_port;
uint8_t heater_pin;
volatile uint8_t *heater_pwm;
} heaters[NUM_HEATERS] =
{
{
&PORTD,
PIND0,
&OCR0A
}
};
#endif
// temperature history count. higher values make PID derivative term more stable at the expense of reaction time
#define TH_COUNT 8
// if you selected thermistor or AD595, what pin is it on?
#define TEMP_PIN_CHANNEL AIO0_PIN
#define ANALOG_MASK MASK(TEMP_PIN_CHANNEL)
@ -224,6 +281,8 @@
#define FAN_PIN DIO5
#define FAN_PWM OCR0B
#define PID_SCALE 1024L
// --------------------------------------------------------------------------
// you shouldn't need to edit anything below this line

View File

@ -197,7 +197,7 @@ void process_gcode_command() {
// M104- set temperature
case 104:
temp_set(next_target.S);
temp_set(next_target.P, next_target.S);
if (next_target.S) {
enable_heater();
power_on();
@ -209,7 +209,7 @@ void process_gcode_command() {
// M105- get temperature
case 105:
temp_print();
temp_print(next_target.P);
break;
// M106- fan on
@ -225,7 +225,7 @@ void process_gcode_command() {
// M109- set temp and wait
case 109:
temp_set(next_target.S);
temp_set(next_target.P, next_target.S);
if (next_target.S) {
enable_heater();
power_on();
@ -266,22 +266,26 @@ void process_gcode_command() {
// M130- heater P factor
case 130:
if (next_target.seen_S)
p_factor = next_target.S;
// p_factor = next_target.S;
pid_set_p(next_target.P, next_target.S);
break;
// M131- heater I factor
case 131:
if (next_target.seen_S)
i_factor = next_target.S;
// i_factor = next_target.S;
pid_set_i(next_target.P, next_target.S);
break;
// M132- heater D factor
case 132:
if (next_target.seen_S)
d_factor = next_target.S;
// d_factor = next_target.S;
pid_set_d(next_target.P, next_target.S);
break;
// M133- heater I limit
case 133:
if (next_target.seen_S)
i_limit = next_target.S;
// i_limit = next_target.S;
pid_set_i_limit(next_target.P, next_target.S);
break;
// M134- save PID settings to eeprom
case 134:

164
heater.c
View File

@ -1,107 +1,149 @@
#include "heater.h"
#ifdef HEATER_PIN
#include <avr/eeprom.h>
#include <avr/pgmspace.h>
#include "sersendf.h"
#include "arduino.h"
#include "timer.h"
#include "debug.h"
#include "sersendf.h"
int16_t heater_p = 0;
int16_t heater_i = 0;
int16_t heater_d = 0;
#define HEATER_C
#include "config.h"
// this struct holds the heater PID factors that are stored in the EEPROM during poweroff
struct {
int32_t p_factor;
int32_t i_factor;
int32_t d_factor;
int16_t i_limit;
} heaters_pid[NUM_HEATERS];
// this struct holds the runtime heater data- PID counters and such
struct {
int16_t heater_p;
int16_t heater_i;
int16_t heater_d;
uint8_t pid_output;
uint16_t temp_history[TH_COUNT];
uint8_t temp_history_pointer;
} heaters_runtime[NUM_HEATERS];
#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;
// this lives in the eeprom so we can save our PID settings for each heater
typedef struct {
int32_t EE_p_factor;
int32_t EE_i_factor;
int32_t EE_d_factor;
int16_t EE_i_limit;
} EE_factor;
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;
EE_factor EEMEM EE_factors[NUM_HEATERS];
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;
// read factors from eeprom
uint8_t i;
for (i = 0; i < NUM_HEATERS; i++) {
heaters_pid[i].p_factor = eeprom_read_dword((uint32_t *) &EE_factors[i].EE_p_factor);
heaters_pid[i].i_factor = eeprom_read_dword((uint32_t *) &EE_factors[i].EE_i_factor);
heaters_pid[i].d_factor = eeprom_read_dword((uint32_t *) &EE_factors[i].EE_d_factor);
heaters_pid[i].i_limit = eeprom_read_word((uint16_t *) &EE_factors[i].EE_i_limit);
if ((heaters_pid[i].p_factor == 0) && (heaters_pid[i].i_factor == 0) && (heaters_pid[i].d_factor == 0) && (heaters_pid[i].i_limit == 0)) {
heaters_pid[i].p_factor = DEFAULT_P;
heaters_pid[i].i_factor = DEFAULT_I;
heaters_pid[i].d_factor = DEFAULT_D;
heaters_pid[i].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);
uint8_t i;
for (i = 0; i < NUM_HEATERS; i++) {
eeprom_write_dword((uint32_t *) &EE_factors[i].EE_p_factor, heaters_pid[i].p_factor);
eeprom_write_dword((uint32_t *) &EE_factors[i].EE_i_factor, heaters_pid[i].i_factor);
eeprom_write_dword((uint32_t *) &EE_factors[i].EE_d_factor, heaters_pid[i].d_factor);
eeprom_write_word((uint16_t *) &EE_factors[i].EE_i_limit, heaters_pid[i].i_limit);
}
}
void heater_tick(int16_t current_temp, int16_t target_temp) {
void heater_tick(uint8_t h, uint16_t current_temp, uint16_t target_temp) {
// now for heater stuff
int16_t t_error = target_temp - current_temp;
temp_history[th_p++] = current_temp;
th_p &= (TH_COUNT - 1);
heaters_runtime[h].temp_history[heaters_runtime[h].temp_history_pointer++] = current_temp;
heaters_runtime[h].temp_history_pointer &= (TH_COUNT - 1);
// PID stuff
// proportional
heater_p = t_error;
heaters_runtime[h].heater_p = t_error;
// integral
heater_i += t_error;
heaters_runtime[h].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;
if (heaters_runtime[h].heater_i > heaters_pid[h].i_limit)
heaters_runtime[h].heater_i = heaters_pid[h].i_limit;
else if (heaters_runtime[h].heater_i < -heaters_pid[h].i_limit)
heaters_runtime[h].heater_i = -heaters_pid[h].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];
heaters_runtime[h].heater_d = current_temp - heaters_runtime[h].temp_history[heaters_runtime[h].temp_history_pointer];
// 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
(
(((int32_t) heaters_runtime[h].heater_p) * heaters_pid[h].p_factor) +
(((int32_t) heaters_runtime[h].heater_i) * heaters_pid[h].i_factor) +
(((int32_t) heaters_runtime[h].heater_d) * heaters_pid[h].d_factor)
) / PID_SCALE
);
// rebase and limit factors
uint8_t pid_output;
if (pid_output_intermed > 255)
pid_output = 255;
heaters_runtime[h].pid_output = 255;
else if (pid_output_intermed < 0)
pid_output = 0;
heaters_runtime[h].pid_output = 0;
else
pid_output = pid_output_intermed & 0xFF;
heaters_runtime[h].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);
sersendf_P(PSTR("T{E:%d, P:%d * %ld = %ld / I:%d * %ld = %ld / D:%d * %ld = %ld # O: %ld = %u}\n"), t_error, heaters_runtime[h].heater_p, heaters_pid[h].p_factor, (int32_t) heaters_runtime[h].heater_p * heaters_pid[h].p_factor / PID_SCALE, heaters_runtime[h].heater_i, heaters_pid[h].i_factor, (int32_t) heaters_runtime[h].heater_i * heaters_pid[h].i_factor / PID_SCALE, heaters_runtime[h].heater_d, heaters_pid[h].d_factor, (int32_t) heaters_runtime[h].heater_d * heaters_pid[h].d_factor / PID_SCALE, pid_output_intermed, heaters_runtime[h].pid_output);
#ifdef HEATER_PWM
HEATER_PWM = pid_output;
#else
if (pid_output >= 8)
enable_heater();
else
disable_heater();
#endif
heater_set(h, heaters_runtime[h].pid_output);
}
#endif /* HEATER_PIN */
void heater_set(uint8_t index, uint8_t value) {
if (heaters[index].heater_pwm) {
*heaters[index].heater_pwm = value;
}
else {
if (value >= 8)
*heaters[index].heater_port |= MASK(heaters[index].heater_pin);
else
*heaters[index].heater_port &= ~MASK(heaters[index].heater_pin);
}
}
void pid_set_p(uint8_t index, int32_t p) {
heaters_pid[index].p_factor = p;
}
void pid_set_i(uint8_t index, int32_t i) {
heaters_pid[index].i_factor = i;
}
void pid_set_d(uint8_t index, int32_t d) {
heaters_pid[index].d_factor = d;
}
void pid_set_i_limit(uint8_t index, int32_t i_limit) {
heaters_pid[index].i_limit = i_limit;
}

View File

@ -1,40 +1,20 @@
#ifndef _HEATER_H
#define _HEATER_H
#include "config.h"
#include <stdint.h>
#ifdef HEATER_PIN
#ifdef HEATER_PWM
#define enable_heater() do { TCCR0A |= MASK(COM0A1); } while (0)
#define disable_heater() do { TCCR0A &= ~MASK(COM0A1); } while (0)
#else
#define enable_heater() WRITE(HEATER_PIN, 1)
#define disable_heater() WRITE(HEATER_PIN, 0)
#endif
// 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
#define enable_heater() heater_set(0, 64)
#define disable_heater() heater_set(0, 0)
void heater_init(void);
void heater_save_settings(void);
void heater_tick(int16_t current_temp, int16_t target_temp);
#else /* HEATER_PIN */
void heater_set(uint8_t index, uint8_t value);
void heater_tick(uint8_t h, uint16_t current_temp, uint16_t target_temp);
// if there is no heater pin, there is no heater
#define enable_heater() /* empty */
#define disable_heater() /* empty */
#define heater_init() /* empty */
#define heater_save_settings() /* empty */
#define heater_tick(p1, p2) /* empty */
void pid_set_p(uint8_t index, int32_t p);
void pid_set_i(uint8_t index, int32_t i);
void pid_set_d(uint8_t index, int32_t d);
void pid_set_i_limit(uint8_t index, int32_t i_limit);
#endif /* HEATER_PIN */
#endif /* _HEATER_H */

View File

@ -62,6 +62,12 @@ void io_init(void) {
TIMSK0 = 0;
OCR0A = 0;
OCR0B = 255;
TCCR2A = MASK(WGM21) | MASK(WGM20);
TCCR2B = MASK(CS20);
TIMSK2 = 0;
OCR2A = 0;
OCR2B = 0;
#endif
#ifdef STEPPER_ENABLE_PIN

333
temp.c
View File

@ -1,34 +1,41 @@
/*
temp.c
This file currently reads temp from a MAX6675 on the SPI bus.
temp fields are 14.2 fixed point, so temp_set(500) will set the temperature to 125 celsius, and temp_get() = 600 is reporting a temperature of 150 celsius.
the conversion to/from this unit is done in gcode.c, near:
if (next_target.M == 104)
next_target.S = decfloat_to_int(&read_digit, 4, 1);
and
// M105- get temperature
case 105:
uint16_t t = temp_get();
note that the MAX6675 can't do more than approx 5 conversions per second- we go for 4 so the timing isn't too tight
*/
#include "temp.h"
#include "temp.h"
#include <stdlib.h>
#include <avr/eeprom.h>
#include <avr/pgmspace.h>
#include "clock.h"
#include "serial.h"
#include "sermsg.h"
#include "arduino.h"
#include "timer.h"
#include "dda.h"
#include "sersendf.h"
#include "debug.h"
#include "sersendf.h"
#include "heater.h"
typedef enum {
TT_THERMISTOR,
TT_MAX6675,
TT_AD595
} temp_types;
typedef enum {
PRESENT,
TCOPEN
} temp_flags_enum;
#define TEMP_C
#include "config.h"
// this struct holds the runtime sensor data- read temperatures, targets, etc
struct {
temp_flags_enum temp_flags;
uint16_t last_read_temp;
uint16_t target_temp;
uint8_t temp_residency;
uint16_t next_read_time;
} temp_sensors_runtime[NUM_TEMP_SENSORS];
#ifdef TEMP_MAX6675
#endif
@ -64,157 +71,143 @@ uint16_t temptable[NUMTEMPS][2] PROGMEM = {
#include "analog.h"
#endif
#ifndef TEMP_MAX6675
#ifndef TEMP_THERMISTOR
#ifndef TEMP_AD595
#error none of TEMP_MAX6675, TEMP_THERMISTOR or TEMP_AD595 are defined! What type of temp sensor are you using?
#endif
#endif
#endif
uint16_t current_temp = 0;
uint16_t target_temp = 0;
uint8_t temp_flags = 0;
uint8_t temp_residency = 0;
#ifndef ABSDELTA
#define ABSDELTA(a, b) (((a) >= (b))?((a) - (b)):((b) - (a)))
#endif
uint16_t temp_read() {
uint16_t temp;
#ifdef TEMP_MAX6675
#ifdef PRR
PRR &= ~MASK(PRSPI);
#elif defined PRR0
PRR0 &= ~MASK(PRSPI);
#endif
SPCR = MASK(MSTR) | MASK(SPE) | MASK(SPR0);
// enable MAX6675
WRITE(SS, 0);
// ensure 100ns delay - a bit extra is fine
delay(1);
// read MSB
SPDR = 0;
for (;(SPSR & MASK(SPIF)) == 0;);
temp = SPDR;
temp <<= 8;
// read LSB
SPDR = 0;
for (;(SPSR & MASK(SPIF)) == 0;);
temp |= SPDR;
// disable MAX6675
WRITE(SS, 1);
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;
void temp_sensor_tick() {
uint8_t i = 0, all_within_range = 1;
for (; i < NUM_TEMP_SENSORS; i++) {
if (temp_sensors_runtime[i].next_read_time) {
temp_sensors_runtime[i].next_read_time--;
}
else {
current_temp = temp >> 3;
return current_temp;
uint16_t temp = 0;
#ifdef TEMP_THERMISTOR
uint8_t j;
#endif
//time to deal with this temp sensor
switch(temp_sensors[i].temp_type) {
#ifdef TEMP_MAX6675
case TT_MAX6675:
#ifdef PRR
PRR &= ~MASK(PRSPI);
#elif defined PRR0
PRR0 &= ~MASK(PRSPI);
#endif
SPCR = MASK(MSTR) | MASK(SPE) | MASK(SPR0);
// enable TT_MAX6675
WRITE(SS, 0);
// ensure 100ns delay - a bit extra is fine
delay(1);
// read MSB
SPDR = 0;
for (;(SPSR & MASK(SPIF)) == 0;);
temp = SPDR;
temp <<= 8;
// read LSB
SPDR = 0;
for (;(SPSR & MASK(SPIF)) == 0;);
temp |= SPDR;
// disable TT_MAX6675
WRITE(SS, 1);
temp_sensors_runtime[i].temp_flags = 0;
if ((temp & 0x8002) == 0) {
// got "device id"
temp_sensors_runtime[i].temp_flags |= PRESENT;
if (temp & 4) {
// thermocouple open
temp_sensors_runtime[i].temp_flags |= TCOPEN;
}
else {
temp = temp >> 3;
}
}
// FIXME: placeholder number
temp_sensors_runtime[i].next_read_time = 25;
break;
#endif /* TEMP_MAX6675 */
#ifdef TEMP_THERMISTOR
case TT_THERMISTOR:
//Read current temperature
temp = analog_read(temp_sensors[i].temp_pin);
//Calculate real temperature based on lookup table
for (j = 1; j < NUMTEMPS; j++) {
if (pgm_read_word(&(temptable[j][0])) > temp) {
// multiply by 4 because internal temp is stored as 14.2 fixed point
temp = pgm_read_word(&(temptable[j][1])) + (pgm_read_word(&(temptable[j][0])) - temp) * 4 * (pgm_read_word(&(temptable[j-1][1])) - pgm_read_word(&(temptable[j][1]))) / (pgm_read_word(&(temptable[j][0])) - pgm_read_word(&(temptable[j-1][0])));
break;
}
}
//Clamp for overflows
if (j == NUMTEMPS)
temp = temptable[NUMTEMPS-1][1];
// FIXME: placeholder number
temp_sensors_runtime[i].next_read_time = 0;
break;
#endif /* TEMP_THERMISTOR */
#ifdef TEMP_AD595
case TT_AD595:
temp = analog_read(temp_pin);
// convert
// >>8 instead of >>10 because internal temp is stored as 14.2 fixed point
temp = (temp * 500L) >> 8;
// FIXME: placeholder number
temp_sensors[i].next_read_time = 0;
break;
#endif /* TEMP_AD595 */
}
temp_sensors_runtime[i].last_read_temp = temp;
if (labs(temp - temp_sensors_runtime[i].target_temp) < TEMP_HYSTERESIS) {
if (temp_sensors_runtime[i].temp_residency < TEMP_RESIDENCY_TIME)
temp_sensors_runtime[i].temp_residency++;
}
else {
temp_sensors_runtime[i].temp_residency = 0;
all_within_range = 0;
}
if (temp_sensors[i].heater_index != 255) {
heater_tick(temp_sensors[i].heater_index, temp_sensors_runtime[i].last_read_temp, temp_sensors_runtime[i].target_temp);
}
}
}
#endif /* TEMP_MAX6675 */
#ifdef TEMP_THERMISTOR
uint8_t i;
//Read current temperature
temp = analog_read(TEMP_PIN_CHANNEL);
//Calculate real temperature based on lookup table
for (i = 1; i < NUMTEMPS; i++) {
if (pgm_read_word(&(temptable[i][0])) > temp) {
// multiply by 4 because internal temp is stored as 14.2 fixed point
temp = pgm_read_word(&(temptable[i][1])) + (pgm_read_word(&(temptable[i][0])) - temp) * 4 * (pgm_read_word(&(temptable[i-1][1])) - pgm_read_word(&(temptable[i][1]))) / (pgm_read_word(&(temptable[i][0])) - pgm_read_word(&(temptable[i-1][0])));
break;
}
}
//Clamp for overflows
if (i == NUMTEMPS)
temp = temptable[NUMTEMPS-1][1];
return temp;
#endif /* TEMP_THERMISTOR */
#ifdef TEMP_AD595
temp = analog_read(TEMP_PIN_CHANNEL);
// convert
// >>8 instead of >>10 because internal temp is stored as 14.2 fixed point
temp = (temp * 500L) >> 8;
return temp;
#endif /* TEMP_AD595 */
return 0;
}
void temp_set(uint16_t t) {
if (t) {
steptimeout = 0;
power_on();
}
target_temp = t;
}
uint16_t temp_get() {
return current_temp;
}
uint16_t temp_get_target() {
return target_temp;
}
void temp_print() {
if (temp_flags & TEMP_FLAG_TCOPEN) {
serial_writestr_P(PSTR("T: no thermocouple!\n"));
}
else {
uint8_t c = 0, t = 0;
c = (current_temp & 3) * 25;
t = (target_temp & 3) * 25;
#ifdef REPRAP_HOST_COMPATIBILITY
sersendf_P(PSTR(" T: %u.%u\n"), current_temp >> 2, c);
#else
sersendf_P(PSTR("T: %u.%u/%u.%u :%u\n"), current_temp >> 2, c, target_temp >> 2, t, temp_residency);
#endif
}
}
void temp_tick() {
if (target_temp) {
steptimeout = 0;
temp_read();
heater_tick(current_temp, target_temp);
if (ABSDELTA(current_temp, target_temp) > TEMP_HYSTERESIS)
temp_residency = 0;
else if (temp_residency < TEMP_RESIDENCY_TIME)
temp_residency++;
}
}
uint8_t temp_achieved() {
if (temp_residency >= TEMP_RESIDENCY_TIME)
return 255;
return 0;
uint8_t i, all_ok = 255;
for (i = 0; i < NUM_TEMP_SENSORS; i++) {
if (temp_sensors_runtime[i].temp_residency < TEMP_RESIDENCY_TIME)
all_ok = 0;
}
return all_ok;
}
void temp_set(uint8_t index, uint16_t temperature) {
temp_sensors_runtime[index].target_temp = temperature;
temp_sensors_runtime[index].temp_residency = 0;
}
void temp_print(uint8_t index) {
uint8_t c = 0;
c = (temp_sensors_runtime[index].last_read_temp & 3) * 25;
sersendf_P(PSTR("T: %u.%u\n"), temp_sensors_runtime[index].last_read_temp >> 2, c);
}

56
temp.h
View File

@ -3,59 +3,23 @@
#include <stdint.h>
#include "config.h"
/*
NOTES
#define TEMP_FLAG_PRESENT 1
#define TEMP_FLAG_TCOPEN 2
no point in specifying a port- all the different temp sensors we have must be on a particular port. The MAX6675 must be on the SPI, and the thermistor and AD595 must be on an analog port.
#ifdef TEMP_MAX6675
typedef union {
struct {
uint8_t high;
uint8_t low;
} buf;
struct {
uint16_t dummy :1;
uint16_t reading :12;
uint16_t tc_open :1;
uint16_t device_id :1;
uint16_t tristate :1;
} interpret;
} max6675_data_format;
#endif
we still need to specify which analog pins we use in machine.h for the analog sensors however, otherwise the analog subsystem won't read them.
*/
#ifdef TEMP_THERMISTOR
#include <avr/pgmspace.h>
#endif
#define temp_tick temp_sensor_tick
#ifdef TEMP_AD595
#endif
void temp_sensor_tick(void);
// setup temperature system
void temp_init(void);
// save PID factors to EEPROM
void temp_save_settings(void);
// read temperature from sensor
uint16_t temp_read(void);
// set target temperature
void temp_set(uint16_t t);
// return last read temperature
uint16_t temp_get(void);
// return target temperature
uint16_t temp_get_target(void);
// true if last read temp is close to target temp, false otherwise
uint8_t temp_achieved(void);
// send current temperature to host
void temp_print(void);
void temp_set(uint8_t index, uint16_t temperature);
void temp_print(uint8_t index);
// periodically read temperature and update heater with PID
void temp_tick(void);
uint16_t temp_read(uint8_t index);
#endif /* _TIMER_H */