preliminary untested implementation of Markus Amsler's new extruder comms protocol

This commit is contained in:
Michael Moon 2011-02-12 23:59:19 +11:00
parent 84457ccc4b
commit b1a48994dd
13 changed files with 659 additions and 506 deletions

View File

@ -54,8 +54,8 @@ void analog_init() {
adc_counter = 0;
adc_running_mask = 1;
AIO0_DDR &= ANALOG_MASK;
DIDR0 = ANALOG_MASK & 0x3F;
AIO0_DDR &= ~(ANALOG_MASK);
DIDR0 = (ANALOG_MASK) & 0x3F;
// now we start the first conversion and leave the rest to the interrupt
ADCSRA |= MASK(ADIE) | MASK(ADSC);
@ -73,7 +73,7 @@ ISR(ADC_vect, ISR_NOBLOCK) {
adc_counter = ANALOG_START;
adc_running_mask = ANALOG_START_MASK;
}
} while ((adc_running_mask & ANALOG_MASK) == 0);
} while ((adc_running_mask & (ANALOG_MASK)) == 0);
// start next conversion
ADMUX = (adc_counter) | REFERENCE;

View File

@ -3,6 +3,9 @@
#include "arduino.h"
// controller index- bus is multidrop after all
#define THIS_CONTROLLER_NUM 0
//RS485 Interface pins
#define RX_ENABLE_PIN DIO4
#define TX_ENABLE_PIN AIO2
@ -40,33 +43,13 @@
#define TEMP_HYSTERESIS 20
#define TEMP_RESIDENCY_TIME 60
#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. *
* *
* for GEN3 set temp_type to TT_INTERCOM, temp_pin to 0 and heater index to *
* 255 *
* *
\***************************************************************************/
#ifdef DEFINE_TEMP_SENSOR
DEFINE_TEMP_SENSOR(extruder, TT_THERMISTOR, PINC3)
#endif
struct {
uint8_t temp_type;
uint8_t temp_pin;
uint8_t heater_index;
} temp_sensors[NUM_TEMP_SENSORS] =
{
{
TT_THERMISTOR,
PINC3,
0
}
};
#ifdef DEFINE_HEATER
DEFINE_HEATER(extruder, PORTD, DIO6_PIN, OCR0A)
DEFINE_HEATER(bed, PORTD, DIO5_PIN, OCR0B)
#endif
// list of PWM-able pins and corresponding timers
@ -81,49 +64,6 @@ struct {
#define TH_COUNT 8
#define PID_SCALE 1024L
#define NUM_HEATERS 2
#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,
PIND6,
&OCR0A
},
{
&PORTB,
PINB4,
0
}
};
#endif
// #define HEATER_PIN DIO11
// #define HEATER_PWM OCR2A
//
// #define BED_PIN DIO12
/*
Intercom
*/
#define enable_transmit() do { WRITE(TX_ENABLE_PIN,1); WRITE(RX_ENABLE_PIN,0); } while(0)
#define disable_transmit() do { WRITE(TX_ENABLE_PIN,0); WRITE(RX_ENABLE_PIN,0); } while(0)
/*
Motors
@ -132,16 +72,4 @@ struct {
#define enable_motors() do { TCCR0A |= MASK(COM0A1) | MASK(COM0B1); } while (0)
#define disable_motors() do { TCCR0A &= ~MASK(COM0A1) & ~MASK(COM0B1); } while (0)
/*
Heater
*/
// #ifdef HEATER_PWM
// #define enable_heater() do { TCCR2A |= MASK(COM2A1); } while (0)
// #define disable_heater() do { TCCR2A &= ~MASK(COM2A1); } while (0)
// #else
// #define enable_heater() WRITE(HEATER_PIN, 1)
// #define disable_heater() WRITE(HEATER_PIN, 0)
// #endif
#endif /* _CONFIG_H */

View File

@ -3,18 +3,12 @@
#include <stdint.h>
#ifdef DEBUG
#define DEBUG_PID 1
#define DEBUG_DDA 2
#define DEBUG_POSITION 4
#else
// by setting these to zero, the compiler should optimise the relevant code out
#define DEBUG_PID 0
#define DEBUG_DDA 0
#define DEBUG_POSITION 0
#endif
// by setting these to zero, the compiler should optimise the relevant code out
#define DEBUG_PID 0
#define DEBUG_DDA 0
#define DEBUG_POSITION 0
#define DEBUG_ECHO 128
#define DEBUG_ECHO 0
extern volatile uint8_t debug_flags;

View File

@ -187,7 +187,7 @@ int main (void)
temp_sensor_tick();
update_send_cmd(temp_get(0) >> 2);
temp_set(0, get_read_cmd());
send_temperature(0, temp_get(0));
temp_set(0, read_temperature(0));
}
}

View File

@ -9,9 +9,21 @@
#ifndef EXTRUDER
#include "sersendf.h"
#endif
#include "temp.h"
#define HEATER_C
#include "config.h"
typedef struct {
volatile uint8_t *heater_port;
uint8_t heater_pin;
volatile uint8_t *heater_pwm;
} heater_definition_t;
#undef DEFINE_HEATER
#define DEFINE_HEATER(name, port, pin, pwm) { &(port), (pin), &(pwm) },
static const heater_definition_t heaters[NUM_HEATERS] =
{
#include "config.h"
};
#undef DEFINE_HEATER
// this struct holds the heater PID factors that are stored in the EEPROM during poweroff
struct {
@ -32,6 +44,8 @@ struct {
uint16_t sanity_counter;
uint16_t sane_temperature;
#endif
uint8_t heater_output;
} heaters_runtime[NUM_HEATERS];
#define DEFAULT_P 8192
@ -50,8 +64,7 @@ typedef struct {
EE_factor EEMEM EE_factors[NUM_HEATERS];
void heater_init() {
#if NUM_HEATERS > 0
uint8_t i;
heater_t i;
// setup pins
for (i = 0; i < NUM_HEATERS; i++) {
*(heaters[i].heater_port) &= ~MASK(heaters[i].heater_pin);
@ -80,82 +93,96 @@ void heater_init() {
// 0 is a "sane" temperature when we're trying to cool down
heaters_runtime[i].sane_temperature = 0;
#endif
// read factors from eeprom
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;
}
#ifndef BANG_BANG
// read factors from eeprom
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;
}
#endif /* BANG_BANG */
}
#endif
}
void heater_save_settings() {
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);
}
#ifndef BANG_BANG
heater_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);
}
#endif /* BANG_BANG */
}
void heater_tick(uint8_t h, uint16_t current_temp, uint16_t target_temp) {
#if NUM_HEATERS > 0
int16_t heater_p;
int16_t heater_d;
void heater_tick(heater_t h, temp_sensor_t t, uint16_t current_temp, uint16_t target_temp) {
uint8_t pid_output;
int16_t t_error = target_temp - current_temp;
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;
// integral
heaters_runtime[h].heater_i += t_error;
// prevent integrator wind-up
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 = heaters_runtime[h].temp_history[heaters_runtime[h].temp_history_pointer] - current_temp;
// combine factors
int32_t pid_output_intermed = (
(
(((int32_t) heater_p) * heaters_pid[h].p_factor) +
(((int32_t) heaters_runtime[h].heater_i) * heaters_pid[h].i_factor) +
(((int32_t) heater_d) * heaters_pid[h].d_factor)
) / PID_SCALE
);
// rebase and limit factors
if (pid_output_intermed > 255)
pid_output = 255;
else if (pid_output_intermed < 0)
pid_output = 0;
else
pid_output = pid_output_intermed & 0xFF;
#ifdef DEBUG
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, heaters_pid[h].p_factor, (int32_t) 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, heater_d, heaters_pid[h].d_factor, (int32_t) heater_d * heaters_pid[h].d_factor / PID_SCALE, pid_output_intermed, pid_output);
#ifndef BANG_BANG
int16_t heater_p;
int16_t heater_d;
int16_t t_error = target_temp - current_temp;
#endif /* BANG_BANG */
if (h >= NUM_HEATERS || t >= NUM_TEMP_SENSORS)
return;
#ifndef BANG_BANG
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;
// integral
heaters_runtime[h].heater_i += t_error;
// prevent integrator wind-up
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 = heaters_runtime[h].temp_history[heaters_runtime[h].temp_history_pointer] - current_temp;
// combine factors
int32_t pid_output_intermed = (
(
(((int32_t) heater_p) * heaters_pid[h].p_factor) +
(((int32_t) heaters_runtime[h].heater_i) * heaters_pid[h].i_factor) +
(((int32_t) heater_d) * heaters_pid[h].d_factor)
) / PID_SCALE
);
// rebase and limit factors
if (pid_output_intermed > 255)
pid_output = 255;
else if (pid_output_intermed < 0)
pid_output = 0;
else
pid_output = pid_output_intermed & 0xFF;
#ifdef DEBUG
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, heaters_pid[h].p_factor, (int32_t) 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, heater_d, heaters_pid[h].d_factor, (int32_t) heater_d * heaters_pid[h].d_factor / PID_SCALE, pid_output_intermed, pid_output);
#endif
#else
if (current_temp >= target_temp)
pid_output = BANG_BANG_ON;
else
pid_output = BANG_BANG_OFF;
#endif
#ifdef HEATER_SANITY_CHECK
// check heater sanity
// implementation is a moving window with some slow-down to compensate for thermal mass
@ -208,16 +235,19 @@ void heater_tick(uint8_t h, uint16_t current_temp, uint16_t target_temp) {
if (labs(current_temp - heaters_runtime[h].sane_temperature) > TEMP_HYSTERESIS) {
// no change, or change in wrong direction for a long time- heater is broken!
pid_output = 0;
sersendf_P(PSTR("!! heater %d broken- temp is %d.%dC, target is %d.%dC, didn't reach %d.%dC in %d0 milliseconds\n"), h, current_temp >> 2, (current_temp & 3) * 25, target_temp >> 2, (target_temp & 3) * 25, heaters_runtime[h].sane_temperature >> 2, (heaters_runtime[h].sane_temperature & 3) * 25, heaters_runtime[h].sanity_counter);
sersendf_P(PSTR("!! heater %d or temp sensor %d broken- temp is %d.%dC, target is %d.%dC, didn't reach %d.%dC in %d0 milliseconds\n"), h, t, current_temp >> 2, (current_temp & 3) * 25, target_temp >> 2, (target_temp & 3) * 25, heaters_runtime[h].sane_temperature >> 2, (heaters_runtime[h].sane_temperature & 3) * 25, heaters_runtime[h].sanity_counter);
}
#endif /* HEATER_SANITY_CHECK */
heater_set(h, pid_output);
#endif /* if NUM_HEATERS > 0 */
}
void heater_set(uint8_t index, uint8_t value) {
#if NUM_HEATERS > 0
void heater_set(heater_t index, uint8_t value) {
if (index >= NUM_HEATERS)
return;
heaters_runtime[index].heater_output = value;
if (heaters[index].heater_pwm) {
*(heaters[index].heater_pwm) = value;
#ifdef DEBUG
@ -231,21 +261,50 @@ void heater_set(uint8_t index, uint8_t value) {
else
*(heaters[index].heater_port) &= ~MASK(heaters[index].heater_pin);
}
#endif /* if NUM_HEATERS > 0 */
}
void pid_set_p(uint8_t index, int32_t p) {
heaters_pid[index].p_factor = p;
uint8_t heaters_all_off() {
uint8_t i;
for (i = 0; i < NUM_HEATERS; i++) {
if (heaters_runtime[i].heater_output > 0)
return 0;
}
return 255;
}
void pid_set_i(uint8_t index, int32_t i) {
heaters_pid[index].i_factor = i;
void pid_set_p(heater_t index, int32_t p) {
#ifndef BANG_BANG
if (index >= NUM_HEATERS)
return;
heaters_pid[index].p_factor = p;
#endif /* BANG_BANG */
}
void pid_set_d(uint8_t index, int32_t d) {
heaters_pid[index].d_factor = d;
void pid_set_i(heater_t index, int32_t i) {
#ifndef BANG_BANG
if (index >= NUM_HEATERS)
return;
heaters_pid[index].i_factor = i;
#endif /* BANG_BANG */
}
void pid_set_i_limit(uint8_t index, int32_t i_limit) {
heaters_pid[index].i_limit = i_limit;
void pid_set_d(heater_t index, int32_t d) {
#ifndef BANG_BANG
if (index >= NUM_HEATERS)
return;
heaters_pid[index].d_factor = d;
#endif /* BANG_BANG */
}
void pid_set_i_limit(heater_t index, int32_t i_limit) {
#ifndef BANG_BANG
if (index >= NUM_HEATERS)
return;
heaters_pid[index].i_limit = i_limit;
#endif /* BANG_BANG */
}

View File

@ -1,20 +1,34 @@
#ifndef _HEATER_H
#define _HEATER_H
#include "config.h"
#include <stdint.h>
#include "temp.h"
#define enable_heater() heater_set(0, 64)
#define disable_heater() heater_set(0, 0)
#undef DEFINE_HEATER
#define DEFINE_HEATER(name, port, pin, pwm) HEATER_ ## name,
typedef enum
{
#include "config.h"
NUM_HEATERS,
HEATER_noheater
} heater_t;
#undef DEFINE_HEATER
void heater_init(void);
void heater_save_settings(void);
void heater_set(uint8_t index, uint8_t value);
void heater_tick(uint8_t h, uint16_t current_temp, uint16_t target_temp);
void heater_set(heater_t index, uint8_t value);
void heater_tick(heater_t h, temp_sensor_t t, uint16_t current_temp, uint16_t target_temp);
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);
uint8_t heaters_all_off(void);
void pid_set_p(heater_t index, int32_t p);
void pid_set_i(heater_t index, int32_t i);
void pid_set_d(heater_t index, int32_t d);
void pid_set_i_limit(heater_t index, int32_t i_limit);
#endif /* _HEATER_H */

View File

@ -1,47 +1,53 @@
#include "intercom.h"
#include <avr/io.h>
#include <avr/interrupt.h>
#include "config.h"
#include "delay.h"
#ifdef GEN3
#if (defined TEMP_INTERCOM) || (defined EXTRUDER)
#define INTERCOM_BAUD 57600
#define enable_transmit() do { WRITE(TX_ENABLE_PIN,1); WRITE(RX_ENABLE_PIN,0); } while(0)
#define disable_transmit() do { WRITE(TX_ENABLE_PIN,0); WRITE(RX_ENABLE_PIN,0); } while(0)
#define START 0x55
/*
Defines a super simple intercom interface using the RS485 modules
enum {
ERROR_BAD_CRC
} err_codes;
Host will say: START1 START2 PWM_CMD PWM_CHK
Extruder will reply: START1 START2 TMP_CMD TMP_CHK
typedef struct {
uint8_t start;
union {
struct {
uint8_t dio0 :1;
uint8_t dio1 :1;
uint8_t dio2 :1;
uint8_t dio3 :1;
uint8_t dio4 :1;
uint8_t dio5 :1;
uint8_t dio6 :1;
uint8_t dio7 :1;
};
uint8_t dio;
};
uint8_t controller_num;
uint16_t temp[3];
uint8_t err;
uint8_t crc;
} intercom_packet_t;
CHK = 255-CMD, if they match do the work, if not, ignore this packet
typedef union {
intercom_packet_t packet;
uint8_t data[sizeof(intercom_packet_t)];
} intercom_packet;
in a loop
*/
intercom_packet tx;
intercom_packet rx;
uint8_t packet_pointer;
uint8_t rxcrc;
#define START1 0xAA
#define START2 0x55
typedef enum {
SEND_START1,
SEND_START2,
SEND_CMD,
SEND_CHK,
SEND_DONE,
READ_START1,
READ_START2,
READ_CMD,
READ_CHK,
} intercom_state_e;
intercom_state_e state = READ_START1;
uint8_t cmd, chk, send_cmd, read_cmd;
volatile uint8_t intercom_flags;
void intercom_init(void)
{
@ -70,30 +76,60 @@ void intercom_init(void)
UCSR0B |= MASK(RXCIE0) | MASK(TXCIE0);
#endif
intercom_flags = 0;
}
void update_send_cmd(uint8_t new_send_cmd) {
send_cmd = new_send_cmd;
void send_temperature(uint8_t index, uint16_t temperature) {
tx.packet.temp[index] = temperature;
}
uint8_t get_read_cmd(void) {
return read_cmd;
uint16_t read_temperature(uint8_t index) {
return rx.packet.temp[index];
}
static void write_byte(uint8_t val) {
#ifdef HOST
UDR1 = val;
void set_dio(uint8_t index, uint8_t value) {
if (value)
tx.packet.dio |= (1 << index);
else
tx.packet.dio &= ~(1 << index);
}
#else
UDR0 = val;
uint8_t get_dio(uint8_t index) {
return rx.packet.dio & (1 << index);
}
#endif
void set_err(uint8_t err) {
tx.packet.err = err;
}
uint8_t get_err() {
return rx.packet.err;
}
void start_send(void) {
state = SEND_START1;
uint8_t txcrc = 0, i;
// atomically update flags
uint8_t sreg = SREG;
cli();
intercom_flags = (intercom_flags & ~FLAG_TX_FINISHED) | FLAG_TX_IN_PROGRESS;
SREG = sreg;
// calculate CRC for outgoing packet
for (i = 0; i < (sizeof(intercom_packet_t) - 1); i++) {
txcrc ^= tx.data[i];
}
tx.packet.crc = txcrc;
// enable transmit pin
enable_transmit();
delay_us(15);
//Enable interrupts so we can send next characters
// actually start sending the packet
packet_pointer = 0;
#ifdef HOST
UCSR1B |= MASK(UDRIE1);
#else
@ -101,119 +137,100 @@ void start_send(void) {
#endif
}
static void finish_send(void) {
state = READ_START1;
disable_transmit();
}
/*
Interrupts, UART 0 for mendel
*/
// receive data interrupt- stuff into rx
#ifdef HOST
ISR(USART1_RX_vect)
#else
ISR(USART_RX_vect)
#endif
{
// pull character
static uint8_t c;
#ifdef HOST
c = UDR1;
UCSR1A &= ~MASK(FE1) & ~MASK(DOR1) & ~MASK(UPE1);
#else
c = UDR0;
UCSR0A &= ~MASK(FE0) & ~MASK(DOR0) & ~MASK(UPE0);
#endif
if (state >= READ_START1) {
switch(state) {
case READ_START1:
if (c == START1) state = READ_START2;
break;
case READ_START2:
if (c == START2) state = READ_CMD;
else state = READ_START1;
break;
case READ_CMD:
cmd = c;
state = READ_CHK;
break;
case READ_CHK:
chk = c;
if (chk == 255 - cmd) {
//Values are correct, do something useful
WRITE(DEBUG_LED,1);
read_cmd = cmd;
#ifdef EXTRUDER
start_send();
#endif
}
else
{
state = READ_START1;
}
break;
default:
break;
}
#ifdef HOST
c = UDR1;
UCSR1A &= ~MASK(FE1) & ~MASK(DOR1) & ~MASK(UPE1);
#else
c = UDR0;
UCSR0A &= ~MASK(FE0) & ~MASK(DOR0) & ~MASK(UPE0);
#endif
// are we waiting for a start byte? is this one?
if ((packet_pointer == 0) && (c == START)) {
rxcrc = rx.packet.start = START;
packet_pointer = 1;
intercom_flags |= FLAG_RX_IN_PROGRESS;
}
// we're receiving a packet
if (packet_pointer > 0) {
// calculate CRC (except CRC character!)
if (packet_pointer < (sizeof(intercom_packet_t) - 1))
rxcrc ^= c;
// stuff byte into structure
rx.data[packet_pointer++] = c;
// last byte?
if (packet_pointer >= sizeof(intercom_packet_t)) {
// reset pointer
packet_pointer = 0;
intercom_flags = (intercom_flags & ~FLAG_RX_IN_PROGRESS) | FLAG_NEW_RX;
#ifndef HOST
if (rx.packet.controller_num == THIS_CONTROLLER_NUM) {
if (rxcrc != rx.packet.crc)
tx.packet.err = ERROR_BAD_CRC;
start_send();
}
#endif
}
}
}
// finished transmitting interrupt- only enabled at end of packet
#ifdef HOST
ISR(USART1_TX_vect)
#else
ISR(USART_TX_vect)
#endif
{
if (state == SEND_DONE) {
finish_send();
#ifdef HOST
UCSR1B &= ~MASK(TXCIE1);
#else
UCSR0B &= ~MASK(TXCIE0);
#endif
if (packet_pointer >= sizeof(intercom_packet_t)) {
disable_transmit();
packet_pointer = 0;
intercom_flags = (intercom_flags & ~FLAG_TX_IN_PROGRESS) | FLAG_TX_FINISHED;
#ifdef HOST
UCSR1B &= ~MASK(TXCIE1);
#else
UCSR0B &= ~MASK(TXCIE0);
#endif
}
}
// tx queue empty interrupt- send next byte
#ifdef HOST
ISR(USART1_UDRE_vect)
#else
ISR(USART_UDRE_vect)
#endif
{
switch(state) {
case SEND_START1:
write_byte(START1);
state = SEND_START2;
break;
case SEND_START2:
write_byte(START2);
state = SEND_CMD;
break;
case SEND_CMD:
write_byte(send_cmd);
state = SEND_CHK;
break;
case SEND_CHK:
write_byte(255 - send_cmd);
state = SEND_DONE;
#ifdef HOST
UCSR1B &= ~MASK(UDRIE1);
UCSR1B |= MASK(TXCIE1);
#else
UCSR0B &= ~MASK(UDRIE0);
UCSR0B |= MASK(TXCIE0);
#endif
break;
default:
break;
#ifdef HOST
UDR1 = tx.data[packet_pointer++];
#else
UDR0 = tx.data[packet_pointer++];
#endif
if (packet_pointer >= sizeof(intercom_packet_t)) {
#ifdef HOST
UCSR1B &= ~MASK(UDRIE1);
UCSR1B |= MASK(TXCIE1);
#else
UCSR0B &= ~MASK(UDRIE0);
UCSR0B |= MASK(TXCIE0);
#endif
}
}
#endif /* GEN3 */
#endif /* TEMP_INTERCOM */

View File

@ -3,15 +3,42 @@
#include <stdint.h>
#define enable_transmit() do { WRITE(TX_ENABLE_PIN,1); WRITE(RX_ENABLE_PIN,0); } while(0)
#define disable_transmit() do { WRITE(TX_ENABLE_PIN,0); WRITE(RX_ENABLE_PIN,0); } while(0)
// initialise serial subsystem
void intercom_init(void);
//Update the message we are sending over intercom
void update_send_cmd(uint8_t new_send_cmd);
// if host, send target temperature to extruder
// if extruder, send actual temperature to host
void send_temperature(uint8_t index, uint16_t temperature);
// if host, read actual temperature from extruder
// if extruder, read target temperature from host
uint16_t read_temperature(uint8_t index);
// if host, set DIOs on extruder controller
// if extruder, report DIO state
void set_dio(uint8_t index, uint8_t value);
// if host, read extruder DIO inputs
// if extruder, set DIO outputs
uint8_t get_dio(uint8_t index);
// set error code to send to other end
void set_err(uint8_t err);
// get error code sent from other end
uint8_t get_err(void);
// if host, send packet to extruder
// if extruder, return packet to host
void start_send(void);
//Read the message we are receiving over intercom
uint8_t get_read_cmd(void);
#define FLAG_RX_IN_PROGRESS 1
#define FLAG_TX_IN_PROGRESS 2
#define FLAG_NEW_RX 4
#define FLAG_TX_FINISHED 8
extern volatile uint8_t intercom_flags;
#endif /* _INTERCOM_H */

View File

@ -4,22 +4,6 @@
#include <avr/eeprom.h>
#include <avr/pgmspace.h>
typedef enum {
TT_THERMISTOR,
TT_MAX6675,
TT_AD595,
TT_PT100,
TT_INTERCOM
} temp_types;
typedef enum {
PRESENT,
TCOPEN
} temp_flags_enum;
#define TEMP_C
#include "config.h"
#include "arduino.h"
#include "delay.h"
#include "debug.h"
@ -27,10 +11,38 @@ typedef enum {
#include "sersendf.h"
#endif
#include "heater.h"
#ifdef GEN3
#ifdef TEMP_INTERCOM
#include "intercom.h"
#endif
typedef enum {
TT_THERMISTOR,
TT_MAX6675,
TT_AD595,
TT_PT100,
TT_INTERCOM,
TT_DUMMY,
} temp_types;
typedef enum {
PRESENT,
TCOPEN
} temp_flags_enum;
typedef struct {
uint8_t temp_type;
uint8_t temp_pin;
uint8_t heater_index;
} temp_sensor_definition_t;
#undef DEFINE_TEMP_SENSOR
#define DEFINE_TEMP_SENSOR(name, type, pin) { (type), (pin), (HEATER_ ## name) },
static const temp_sensor_definition_t temp_sensors[NUM_TEMP_SENSORS] =
{
#include "config.h"
};
#undef DEFINE_TEMP_SENSOR
// this struct holds the runtime sensor data- read temperatures, targets, etc
struct {
temp_flags_enum temp_flags;
@ -48,30 +60,7 @@ struct {
#ifdef TEMP_THERMISTOR
#include "analog.h"
#define NUMTEMPS 20
uint16_t temptable[NUMTEMPS][2] PROGMEM = {
{1, 841},
{54, 255},
{107, 209},
{160, 184},
{213, 166},
{266, 153},
{319, 142},
{372, 132},
{425, 124},
{478, 116},
{531, 108},
{584, 101},
{637, 93},
{690, 86},
{743, 78},
{796, 70},
{849, 61},
{902, 50},
{955, 34},
{1008, 3}
};
#include "ThermistorTable.h"
#endif
#ifdef TEMP_AD595
@ -79,7 +68,7 @@ uint16_t temptable[NUMTEMPS][2] PROGMEM = {
#endif
void temp_init() {
uint8_t i;
temp_sensor_t i;
for (i = 0; i < NUM_TEMP_SENSORS; i++) {
switch(temp_sensors[i].temp_type) {
#ifdef TEMP_MAX6675
@ -100,10 +89,10 @@ void temp_init() {
break;*/
#endif
#ifdef GEN3
#ifdef TEMP_INTERCOM
case TT_INTERCOM:
intercom_init();
update_send_cmd(0);
send_temperature(0, 0);
break;
#endif
}
@ -111,7 +100,7 @@ void temp_init() {
}
void temp_sensor_tick() {
uint8_t i = 0;
temp_sensor_t i = 0;
for (; i < NUM_TEMP_SENSORS; i++) {
if (temp_sensors_runtime[i].next_read_time) {
temp_sensors_runtime[i].next_read_time--;
@ -179,15 +168,50 @@ void temp_sensor_tick() {
//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])) * 4 + (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])));
// Thermistor table is already in 14.2 fixed point
#ifndef EXTRUDER
if (debug_flags & DEBUG_PID)
sersendf_P(PSTR("pin:%d Raw ADC:%d table entry: %d"),temp_sensors[i].temp_pin,temp,j);
#endif
// Linear interpolating temperature value
// y = ((x - x₀)y₁ + (x₁-x)y₀ ) / (x₁ - x₀)
// y = temp
// x = ADC reading
// x₀= temptable[j-1][0]
// x₁= temptable[j][0]
// y₀= temptable[j-1][1]
// y₁= temptable[j][1]
// y =
// Wikipedia's example linear interpolation formula.
temp = (
// ((x - x₀)y₁
((uint32_t)temp - pgm_read_word(&(temptable[j-1][0]))) * pgm_read_word(&(temptable[j][1]))
// +
+
// (x₁-x)
(pgm_read_word(&(temptable[j][0])) - (uint32_t)temp)
// y₀ )
* pgm_read_word(&(temptable[j-1][1])))
// /
/
// (x₁ - x₀)
(pgm_read_word(&(temptable[j][0])) - pgm_read_word(&(temptable[j-1][0])));
#ifndef EXTRUDER
if (debug_flags & DEBUG_PID)
sersendf_P(PSTR(" temp:%d.%d"),temp/4,(temp%4)*25);
#endif
break;
}
}
#ifndef EXTRUDER
if (debug_flags & DEBUG_PID)
sersendf_P(PSTR(" Sensor:%d\n"),i);
#endif
//Clamp for overflows
if (j == NUMTEMPS)
temp = temptable[NUMTEMPS-1][1] * 4;
temp = temptable[NUMTEMPS-1][1];
temp_sensors_runtime[i].next_read_time = 0;
} while (0);
@ -196,7 +220,7 @@ void temp_sensor_tick() {
#ifdef TEMP_AD595
case TT_AD595:
temp = analog_read(temp_pin);
temp = analog_read(temp_sensors[i].temp_pin);
// convert
// >>8 instead of >>10 because internal temp is stored as 14.2 fixed point
@ -213,16 +237,30 @@ void temp_sensor_tick() {
break
#endif /* TEMP_PT100 */
#ifdef GEN3
#ifdef TEMP_INTERCOM
case TT_INTERCOM:
temp = get_read_cmd() << 2;
temp = read_temperature(temp_sensors[i].temp_pin);
start_send();
temp_sensors_runtime[i].next_read_time = 0;
break;
#endif /* GEN3 */
#endif /* TEMP_INTERCOM */
#ifdef TEMP_DUMMY
case TT_DUMMY:
temp = temp_sensors_runtime[i].last_read_temp;
if (temp_sensors_runtime[i].target_temp > temp)
temp++;
else if (temp_sensors_runtime[i].target_temp < temp)
temp--;
temp_sensors_runtime[i].next_read_time = 0;
break;
#endif /* TEMP_DUMMY */
}
temp_sensors_runtime[i].last_read_temp = temp;
@ -235,14 +273,16 @@ void temp_sensor_tick() {
}
if (temp_sensors[i].heater_index < NUM_HEATERS) {
heater_tick(temp_sensors[i].heater_index, temp_sensors_runtime[i].last_read_temp, temp_sensors_runtime[i].target_temp);
heater_tick(temp_sensors[i].heater_index, i, temp_sensors_runtime[i].last_read_temp, temp_sensors_runtime[i].target_temp);
}
}
}
}
uint8_t temp_achieved() {
uint8_t i, all_ok = 255;
temp_sensor_t i;
uint8_t all_ok = 255;
for (i = 0; i < NUM_TEMP_SENSORS; i++) {
if (temp_sensors_runtime[i].temp_residency < TEMP_RESIDENCY_TIME)
all_ok = 0;
@ -250,26 +290,42 @@ uint8_t temp_achieved() {
return all_ok;
}
void temp_set(uint8_t index, uint16_t temperature) {
void temp_set(temp_sensor_t index, uint16_t temperature) {
if (index >= NUM_TEMP_SENSORS)
return;
temp_sensors_runtime[index].target_temp = temperature;
temp_sensors_runtime[index].temp_residency = 0;
#ifdef GEN3
#ifdef TEMP_INTERCOM
if (temp_sensors[index].temp_type == TT_INTERCOM)
update_send_cmd(temperature >> 2);
send_temperature(temp_sensors[index].temp_pin, temperature);
#endif
}
uint16_t temp_get(uint8_t index) {
uint16_t temp_get(temp_sensor_t index) {
if (index >= NUM_TEMP_SENSORS)
return 0;
return temp_sensors_runtime[index].last_read_temp;
}
// extruder doesn't have sersendf_P
#ifndef EXTRUDER
void temp_print(uint8_t index) {
void temp_print(temp_sensor_t index) {
uint8_t c = 0;
if (index >= NUM_TEMP_SENSORS)
return;
c = (temp_sensors_runtime[index].last_read_temp & 3) * 25;
sersendf_P(PSTR("T:%u.%u"), temp_sensors_runtime[index].last_read_temp >> 2, c);
#ifdef HEATER_BED
uint8_t b = 0;
b = (temp_sensors_runtime[HEATER_BED].last_read_temp & 3) * 25;
sersendf_P(PSTR("T: %u.%u\n"), temp_sensors_runtime[index].last_read_temp >> 2, c);
sersendf_P(PSTR(" B:%u.%u"), temp_sensors_runtime[HEATER_bed].last_read_temp >> 2 , b);
#endif
}
#endif

View File

@ -1,6 +1,7 @@
#ifndef _TEMP_H
#define _TEMP_H
#include "config.h"
#include <stdint.h>
/*
@ -11,6 +12,15 @@ no point in specifying a port- all the different temp sensors we have must be on
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.
*/
#undef DEFINE_TEMP_SENSOR
#define DEFINE_TEMP_SENSOR(name, type, pin) TEMP_SENSOR_ ## name,
typedef enum {
#include "config.h"
NUM_TEMP_SENSORS,
TEMP_SENSOR_none
} temp_sensor_t;
#undef DEFINE_TEMP_SENSOR
#define temp_tick temp_sensor_tick
void temp_init(void);
@ -19,11 +29,9 @@ void temp_sensor_tick(void);
uint8_t temp_achieved(void);
void temp_set(uint8_t index, uint16_t temperature);
uint16_t temp_get(uint8_t index);
void temp_set(temp_sensor_t index, uint16_t temperature);
uint16_t temp_get(temp_sensor_t index);
void temp_print(uint8_t index);
uint16_t temp_read(uint8_t index);
void temp_print(temp_sensor_t index);
#endif /* _TIMER_H */

View File

@ -1,47 +1,53 @@
#include "intercom.h"
#include <avr/io.h>
#include <avr/interrupt.h>
#include "config.h"
#include "delay.h"
#ifdef TEMP_INTERCOM
#if (defined TEMP_INTERCOM) || (defined EXTRUDER)
#define INTERCOM_BAUD 57600
#define enable_transmit() do { WRITE(TX_ENABLE_PIN,1); WRITE(RX_ENABLE_PIN,0); } while(0)
#define disable_transmit() do { WRITE(TX_ENABLE_PIN,0); WRITE(RX_ENABLE_PIN,0); } while(0)
#define START 0x55
/*
Defines a super simple intercom interface using the RS485 modules
enum {
ERROR_BAD_CRC
} err_codes;
Host will say: START1 START2 PWM_CMD PWM_CHK
Extruder will reply: START1 START2 TMP_CMD TMP_CHK
typedef struct {
uint8_t start;
union {
struct {
uint8_t dio0 :1;
uint8_t dio1 :1;
uint8_t dio2 :1;
uint8_t dio3 :1;
uint8_t dio4 :1;
uint8_t dio5 :1;
uint8_t dio6 :1;
uint8_t dio7 :1;
};
uint8_t dio;
};
uint8_t controller_num;
uint16_t temp[3];
uint8_t err;
uint8_t crc;
} intercom_packet_t;
CHK = 255-CMD, if they match do the work, if not, ignore this packet
typedef union {
intercom_packet_t packet;
uint8_t data[sizeof(intercom_packet_t)];
} intercom_packet;
in a loop
*/
intercom_packet tx;
intercom_packet rx;
uint8_t packet_pointer;
uint8_t rxcrc;
#define START1 0xAA
#define START2 0x55
typedef enum {
SEND_START1,
SEND_START2,
SEND_CMD,
SEND_CHK,
SEND_DONE,
READ_START1,
READ_START2,
READ_CMD,
READ_CHK,
} intercom_state_e;
intercom_state_e state = READ_START1;
uint8_t cmd, chk, send_cmd, read_cmd;
volatile uint8_t intercom_flags;
void intercom_init(void)
{
@ -70,30 +76,60 @@ void intercom_init(void)
UCSR0B |= MASK(RXCIE0) | MASK(TXCIE0);
#endif
intercom_flags = 0;
}
void update_send_cmd(uint8_t new_send_cmd) {
send_cmd = new_send_cmd;
void send_temperature(uint8_t index, uint16_t temperature) {
tx.packet.temp[index] = temperature;
}
uint8_t get_read_cmd(void) {
return read_cmd;
uint16_t read_temperature(uint8_t index) {
return rx.packet.temp[index];
}
static void write_byte(uint8_t val) {
#ifdef HOST
UDR1 = val;
void set_dio(uint8_t index, uint8_t value) {
if (value)
tx.packet.dio |= (1 << index);
else
tx.packet.dio &= ~(1 << index);
}
#else
UDR0 = val;
uint8_t get_dio(uint8_t index) {
return rx.packet.dio & (1 << index);
}
#endif
void set_err(uint8_t err) {
tx.packet.err = err;
}
uint8_t get_err() {
return rx.packet.err;
}
void start_send(void) {
state = SEND_START1;
uint8_t txcrc = 0, i;
// atomically update flags
uint8_t sreg = SREG;
cli();
intercom_flags = (intercom_flags & ~FLAG_TX_FINISHED) | FLAG_TX_IN_PROGRESS;
SREG = sreg;
// calculate CRC for outgoing packet
for (i = 0; i < (sizeof(intercom_packet_t) - 1); i++) {
txcrc ^= tx.data[i];
}
tx.packet.crc = txcrc;
// enable transmit pin
enable_transmit();
delay_us(15);
//Enable interrupts so we can send next characters
// actually start sending the packet
packet_pointer = 0;
#ifdef HOST
UCSR1B |= MASK(UDRIE1);
#else
@ -101,118 +137,99 @@ void start_send(void) {
#endif
}
static void finish_send(void) {
state = READ_START1;
disable_transmit();
}
/*
Interrupts, UART 0 for mendel
*/
// receive data interrupt- stuff into rx
#ifdef HOST
ISR(USART1_RX_vect)
#else
ISR(USART_RX_vect)
#endif
{
// pull character
static uint8_t c;
#ifdef HOST
c = UDR1;
UCSR1A &= ~MASK(FE1) & ~MASK(DOR1) & ~MASK(UPE1);
#else
c = UDR0;
UCSR0A &= ~MASK(FE0) & ~MASK(DOR0) & ~MASK(UPE0);
#endif
if (state >= READ_START1) {
switch(state) {
case READ_START1:
if (c == START1) state = READ_START2;
break;
case READ_START2:
if (c == START2) state = READ_CMD;
else state = READ_START1;
break;
case READ_CMD:
cmd = c;
state = READ_CHK;
break;
case READ_CHK:
chk = c;
if (chk == 255 - cmd) {
//Values are correct, do something useful
WRITE(DEBUG_LED,1);
read_cmd = cmd;
#ifdef EXTRUDER
start_send();
#endif
}
else
{
state = READ_START1;
}
break;
default:
break;
}
#ifdef HOST
c = UDR1;
UCSR1A &= ~MASK(FE1) & ~MASK(DOR1) & ~MASK(UPE1);
#else
c = UDR0;
UCSR0A &= ~MASK(FE0) & ~MASK(DOR0) & ~MASK(UPE0);
#endif
// are we waiting for a start byte? is this one?
if ((packet_pointer == 0) && (c == START)) {
rxcrc = rx.packet.start = START;
packet_pointer = 1;
intercom_flags |= FLAG_RX_IN_PROGRESS;
}
// we're receiving a packet
if (packet_pointer > 0) {
// calculate CRC (except CRC character!)
if (packet_pointer < (sizeof(intercom_packet_t) - 1))
rxcrc ^= c;
// stuff byte into structure
rx.data[packet_pointer++] = c;
// last byte?
if (packet_pointer >= sizeof(intercom_packet_t)) {
// reset pointer
packet_pointer = 0;
intercom_flags = (intercom_flags & ~FLAG_RX_IN_PROGRESS) | FLAG_NEW_RX;
#ifndef HOST
if (rx.packet.controller_num == THIS_CONTROLLER_NUM) {
if (rxcrc != rx.packet.crc)
tx.packet.err = ERROR_BAD_CRC;
start_send();
}
#endif
}
}
}
// finished transmitting interrupt- only enabled at end of packet
#ifdef HOST
ISR(USART1_TX_vect)
#else
ISR(USART_TX_vect)
#endif
{
if (state == SEND_DONE) {
finish_send();
#ifdef HOST
UCSR1B &= ~MASK(TXCIE1);
#else
UCSR0B &= ~MASK(TXCIE0);
#endif
if (packet_pointer >= sizeof(intercom_packet_t)) {
disable_transmit();
packet_pointer = 0;
intercom_flags = (intercom_flags & ~FLAG_TX_IN_PROGRESS) | FLAG_TX_FINISHED;
#ifdef HOST
UCSR1B &= ~MASK(TXCIE1);
#else
UCSR0B &= ~MASK(TXCIE0);
#endif
}
}
// tx queue empty interrupt- send next byte
#ifdef HOST
ISR(USART1_UDRE_vect)
#else
ISR(USART_UDRE_vect)
#endif
{
switch(state) {
case SEND_START1:
write_byte(START1);
state = SEND_START2;
break;
case SEND_START2:
write_byte(START2);
state = SEND_CMD;
break;
case SEND_CMD:
write_byte(send_cmd);
state = SEND_CHK;
break;
case SEND_CHK:
write_byte(255 - send_cmd);
state = SEND_DONE;
#ifdef HOST
UCSR1B &= ~MASK(UDRIE1);
UCSR1B |= MASK(TXCIE1);
#else
UCSR0B &= ~MASK(UDRIE0);
UCSR0B |= MASK(TXCIE0);
#endif
break;
default:
break;
#ifdef HOST
UDR1 = tx.data[packet_pointer++];
#else
UDR0 = tx.data[packet_pointer++];
#endif
if (packet_pointer >= sizeof(intercom_packet_t)) {
#ifdef HOST
UCSR1B &= ~MASK(UDRIE1);
UCSR1B |= MASK(TXCIE1);
#else
UCSR0B &= ~MASK(UDRIE0);
UCSR0B |= MASK(TXCIE0);
#endif
}
}

View File

@ -3,15 +3,42 @@
#include <stdint.h>
#define enable_transmit() do { WRITE(TX_ENABLE_PIN,1); WRITE(RX_ENABLE_PIN,0); } while(0)
#define disable_transmit() do { WRITE(TX_ENABLE_PIN,0); WRITE(RX_ENABLE_PIN,0); } while(0)
// initialise serial subsystem
void intercom_init(void);
//Update the message we are sending over intercom
void update_send_cmd(uint8_t new_send_cmd);
// if host, send target temperature to extruder
// if extruder, send actual temperature to host
void send_temperature(uint8_t index, uint16_t temperature);
// if host, read actual temperature from extruder
// if extruder, read target temperature from host
uint16_t read_temperature(uint8_t index);
// if host, set DIOs on extruder controller
// if extruder, report DIO state
void set_dio(uint8_t index, uint8_t value);
// if host, read extruder DIO inputs
// if extruder, set DIO outputs
uint8_t get_dio(uint8_t index);
// set error code to send to other end
void set_err(uint8_t err);
// get error code sent from other end
uint8_t get_err(void);
// if host, send packet to extruder
// if extruder, return packet to host
void start_send(void);
//Read the message we are receiving over intercom
uint8_t get_read_cmd(void);
#define FLAG_RX_IN_PROGRESS 1
#define FLAG_TX_IN_PROGRESS 2
#define FLAG_NEW_RX 4
#define FLAG_TX_FINISHED 8
extern volatile uint8_t intercom_flags;
#endif /* _INTERCOM_H */

14
temp.c
View File

@ -92,7 +92,7 @@ void temp_init() {
#ifdef TEMP_INTERCOM
case TT_INTERCOM:
intercom_init();
update_send_cmd(0);
send_temperature(0, 0);
break;
#endif
}
@ -169,8 +169,10 @@ void temp_sensor_tick() {
for (j = 1; j < NUMTEMPS; j++) {
if (pgm_read_word(&(temptable[j][0])) > temp) {
// Thermistor table is already in 14.2 fixed point
#ifndef EXTRUDER
if (debug_flags & DEBUG_PID)
sersendf_P(PSTR("pin:%d Raw ADC:%d table entry: %d"),temp_sensors[i].temp_pin,temp,j);
#endif
// Linear interpolating temperature value
// y = ((x - x₀)y₁ + (x₁-x)y₀ ) / (x₁ - x₀)
// y = temp
@ -194,13 +196,17 @@ void temp_sensor_tick() {
/
// (x₁ - x₀)
(pgm_read_word(&(temptable[j][0])) - pgm_read_word(&(temptable[j-1][0])));
#ifndef EXTRUDER
if (debug_flags & DEBUG_PID)
sersendf_P(PSTR(" temp:%d.%d"),temp/4,(temp%4)*25);
#endif
break;
}
}
#ifndef EXTRUDER
if (debug_flags & DEBUG_PID)
sersendf_P(PSTR(" Sensor:%d\n"),i);
#endif
//Clamp for overflows
@ -214,7 +220,7 @@ void temp_sensor_tick() {
#ifdef TEMP_AD595
case TT_AD595:
temp = analog_read(temp_pin);
temp = analog_read(temp_sensors[i].temp_pin);
// convert
// >>8 instead of >>10 because internal temp is stored as 14.2 fixed point
@ -233,7 +239,7 @@ void temp_sensor_tick() {
#ifdef TEMP_INTERCOM
case TT_INTERCOM:
temp = get_read_cmd() << 2;
temp = read_temperature(temp_sensors[i].temp_pin);
start_send();
@ -292,7 +298,7 @@ void temp_set(temp_sensor_t index, uint16_t temperature) {
temp_sensors_runtime[index].temp_residency = 0;
#ifdef TEMP_INTERCOM
if (temp_sensors[index].temp_type == TT_INTERCOM)
update_send_cmd(temperature >> 2);
send_temperature(temp_sensors[index].temp_pin, temperature);
#endif
}