merge intercom-protocol into master
This commit is contained in:
commit
8188ff3593
|
|
@ -126,6 +126,16 @@ pins
|
|||
#define AIO5_WPORT PORTC
|
||||
#define AIO5_DDR DDRC
|
||||
|
||||
#define AIO6_PIN PINC6
|
||||
#define AIO6_RPORT PINC
|
||||
#define AIO6_WPORT PORTC
|
||||
#define AIO6_DDR DDRC
|
||||
|
||||
#define AIO7_PIN PINC7
|
||||
#define AIO7_RPORT PINC
|
||||
#define AIO7_WPORT PORTC
|
||||
#define AIO7_DDR DDRC
|
||||
|
||||
#define PB0_PIN PINB0
|
||||
#define PB0_RPORT PINB
|
||||
#define PB0_WPORT PORTB
|
||||
|
|
|
|||
3
clock.c
3
clock.c
|
|
@ -31,6 +31,9 @@ void clock_250ms() {
|
|||
/* if (temp_get_target())
|
||||
temp_print();*/
|
||||
}
|
||||
#ifdef TEMP_INTERCOM
|
||||
start_send();
|
||||
#endif
|
||||
}
|
||||
|
||||
void clock_10ms() {
|
||||
|
|
|
|||
|
|
@ -1,48 +1,21 @@
|
|||
#include "analog.h"
|
||||
#include "temp.h"
|
||||
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
#ifndef ANALOG_MASK
|
||||
#warning ANALOG_MASK not defined - analog subsystem disabled
|
||||
#define ANALOG_MASK 0
|
||||
#endif
|
||||
/* OR-combined mask of all channels */
|
||||
#undef DEFINE_TEMP_SENSOR
|
||||
#define DEFINE_TEMP_SENSOR(name, type, pin) | (((type == TT_THERMISTOR) || (type == TT_AD595)) ? 1 << (pin) : 0)
|
||||
static const uint8_t analog_mask = 0
|
||||
#include "config.h"
|
||||
;
|
||||
#undef DEFINE_TEMP_SENSOR
|
||||
|
||||
uint8_t adc_running_mask, adc_counter;
|
||||
|
||||
#if ANALOG_MASK & 1
|
||||
#define ANALOG_START 0
|
||||
#define ANALOG_START_MASK 1
|
||||
#elif ANALOG_MASK & 2
|
||||
#define ANALOG_START 1
|
||||
#define ANALOG_START_MASK 2
|
||||
#elif ANALOG_MASK & 4
|
||||
#define ANALOG_START 2
|
||||
#define ANALOG_START_MASK 4
|
||||
#elif ANALOG_MASK & 8
|
||||
#define ANALOG_START 3
|
||||
#define ANALOG_START_MASK 8
|
||||
#elif ANALOG_MASK & 16
|
||||
#define ANALOG_START 4
|
||||
#define ANALOG_START_MASK 16
|
||||
#elif ANALOG_MASK & 32
|
||||
#define ANALOG_START 5
|
||||
#define ANALOG_START_MASK 32
|
||||
#elif ANALOG_MASK & 64
|
||||
#define ANALOG_START 6
|
||||
#define ANALOG_START_MASK 64
|
||||
#elif ANALOG_MASK & 128
|
||||
#define ANALOG_START 7
|
||||
#define ANALOG_START_MASK 128
|
||||
#else
|
||||
// ANALOG_MASK == 0
|
||||
#define ANALOG_START 0
|
||||
#define ANALOG_START_MASK 1
|
||||
#endif
|
||||
|
||||
volatile uint16_t adc_result[8] __attribute__ ((__section__ (".bss")));
|
||||
static uint8_t adc_counter;
|
||||
static volatile uint16_t adc_result[8] __attribute__ ((__section__ (".bss")));
|
||||
|
||||
void analog_init() {
|
||||
#if ANALOG_MASK > 0
|
||||
if (analog_mask > 0) {
|
||||
#ifdef PRR
|
||||
PRR &= ~MASK(PRADC);
|
||||
#elif defined PRR0
|
||||
|
|
@ -55,36 +28,32 @@ void analog_init() {
|
|||
ADCSRA = MASK(ADEN) | MASK(ADPS2) | MASK(ADPS1) | MASK(ADPS0);
|
||||
|
||||
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);
|
||||
#endif /* ANALOG_MASK > 0 */
|
||||
} /* analog_mask > 0 */
|
||||
}
|
||||
|
||||
ISR(ADC_vect, ISR_NOBLOCK) {
|
||||
// emulate free-running mode but be more deterministic about exactly which result we have, since this project has long-running interrupts
|
||||
if (analog_mask > 0) {
|
||||
adc_result[ADMUX & 0x0F] = ADC;
|
||||
// find next channel
|
||||
do {
|
||||
adc_counter++;
|
||||
adc_running_mask <<= 1;
|
||||
if (adc_counter == 8) {
|
||||
adc_counter = ANALOG_START;
|
||||
adc_running_mask = ANALOG_START_MASK;
|
||||
}
|
||||
} while ((adc_running_mask & ANALOG_MASK) == 0);
|
||||
adc_counter &= 0x07;
|
||||
} while ((analog_mask & (1 << adc_counter)) == 0);
|
||||
|
||||
// start next conversion
|
||||
ADMUX = (adc_counter) | REFERENCE;
|
||||
ADCSRA |= MASK(ADSC);
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t analog_read(uint8_t channel) {
|
||||
#if ANALOG_MASK > 0
|
||||
if (analog_mask > 0) {
|
||||
uint16_t r;
|
||||
|
||||
uint8_t sreg;
|
||||
|
|
@ -100,7 +69,7 @@ uint16_t analog_read(uint8_t channel) {
|
|||
SREG = sreg;
|
||||
|
||||
return r;
|
||||
#else
|
||||
} else {
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -126,6 +126,16 @@ pins
|
|||
#define AIO5_WPORT PORTC
|
||||
#define AIO5_DDR DDRC
|
||||
|
||||
#define AIO6_PIN PINC6
|
||||
#define AIO6_RPORT PINC
|
||||
#define AIO6_WPORT PORTC
|
||||
#define AIO6_DDR DDRC
|
||||
|
||||
#define AIO7_PIN PINC7
|
||||
#define AIO7_RPORT PINC
|
||||
#define AIO7_WPORT PORTC
|
||||
#define AIO7_DDR DDRC
|
||||
|
||||
#define PB0_PIN PINB0
|
||||
#define PB0_RPORT PINB
|
||||
#define PB0_WPORT PORTB
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -30,43 +33,33 @@
|
|||
#define TEMP_PIN AIO3
|
||||
#define TEMP_PIN_CHANNEL 3
|
||||
|
||||
//Read analog voltage from thermistor
|
||||
#define TEMP_BED_PIN AIO6
|
||||
#define TEMP_BED_PIN_CHANNEL 6
|
||||
|
||||
|
||||
#define REFERENCE REFERENCE_AVCC
|
||||
|
||||
#define ANALOG_MASK (MASK(TRIM_POT_CHANNEL) | MASK(TEMP_PIN_CHANNEL))
|
||||
#define ANALOG_MASK (MASK(TRIM_POT_CHANNEL) | MASK(TEMP_PIN_CHANNEL) | MASK(TEMP_BED_PIN_CHANNEL))
|
||||
|
||||
#define TEMP_THERMISTOR
|
||||
|
||||
#define HEATER_PIN DIO11
|
||||
#define BED_PIN AIO1
|
||||
#define FAN_PIN DIO12
|
||||
|
||||
// extruder settings
|
||||
#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, TEMP_PIN_CHANNEL)
|
||||
DEFINE_TEMP_SENSOR(bed, TT_THERMISTOR, TEMP_BED_PIN_CHANNEL)
|
||||
#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, HEATER_PIN, OCR0A)
|
||||
DEFINE_HEATER(bed, PORTD, BED_PIN, OCR0B)
|
||||
#endif
|
||||
|
||||
// list of PWM-able pins and corresponding timers
|
||||
|
|
@ -81,49 +74,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 +82,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 */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
#define DEBUG_ECHO 128
|
||||
#define DEBUG_ECHO 0
|
||||
|
||||
extern volatile uint8_t debug_flags;
|
||||
|
||||
|
|
|
|||
|
|
@ -22,12 +22,18 @@ void io_init(void) {
|
|||
|
||||
SET_INPUT(TRIM_POT);
|
||||
SET_INPUT(TEMP_PIN);
|
||||
SET_INPUT(TEMP_BED_PIN);
|
||||
SET_INPUT(E_STEP_PIN);
|
||||
SET_INPUT(E_DIR_PIN);
|
||||
|
||||
// use pull up resistors to avoid noise
|
||||
WRITE(E_STEP_PIN, 1);
|
||||
WRITE(E_DIR_PIN, 1);
|
||||
|
||||
//Enable the RS485 transceiver
|
||||
SET_OUTPUT(RX_ENABLE_PIN);
|
||||
SET_OUTPUT(TX_ENABLE_PIN);
|
||||
WRITE(RX_ENABLE_PIN,0);
|
||||
disable_transmit();
|
||||
|
||||
#ifdef HEATER_PIN
|
||||
|
|
@ -38,6 +44,10 @@ void io_init(void) {
|
|||
WRITE(BED_PIN, 0); SET_OUTPUT(BED_PIN);
|
||||
#endif
|
||||
|
||||
#ifdef FAN_PIN
|
||||
WRITE(FAN_PIN, 0); SET_OUTPUT(FAN_PIN);
|
||||
#endif
|
||||
|
||||
// #if defined(HEATER_PWM) || defined(FAN_PWM) || defined(BED_PWM)
|
||||
// setup PWM timer: fast PWM, no prescaler
|
||||
TCCR2A = MASK(WGM21) | MASK(WGM20);
|
||||
|
|
@ -64,13 +74,10 @@ void motor_init(void) {
|
|||
}
|
||||
|
||||
ISR(PCINT0_vect) {
|
||||
static uint8_t coil_pos, pwm, flag;
|
||||
|
||||
if (flag == 1) flag = 0;
|
||||
else flag = 1;
|
||||
static uint8_t coil_pos, pwm;
|
||||
|
||||
//if the step pin is high, we advance the motor
|
||||
if (flag) {
|
||||
if (READ(E_STEP_PIN)) {
|
||||
|
||||
//Turn on motors only on first tick to save power I guess
|
||||
enable_motors();
|
||||
|
|
@ -81,12 +88,12 @@ ISR(PCINT0_vect) {
|
|||
else
|
||||
coil_pos--;
|
||||
|
||||
coil_pos &= 31;
|
||||
coil_pos &= 7;
|
||||
|
||||
//Grab the latest motor power to use
|
||||
pwm = motor_pwm;
|
||||
|
||||
switch(coil_pos >> 2) {
|
||||
switch(coil_pos) {
|
||||
case 0:
|
||||
WRITE(H1D, 0);
|
||||
WRITE(H2D, 0);
|
||||
|
|
@ -187,7 +194,9 @@ 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));
|
||||
send_temperature(1, temp_get(1));
|
||||
temp_set(0, read_temperature(0));
|
||||
temp_set(1, read_temperature(1));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,9 +9,21 @@
|
|||
#ifndef EXTRUDER
|
||||
#include "sersendf.h"
|
||||
#endif
|
||||
#include "temp.h"
|
||||
|
||||
#define HEATER_C
|
||||
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);
|
||||
|
|
@ -81,6 +94,7 @@ void heater_init() {
|
|||
heaters_runtime[i].sane_temperature = 0;
|
||||
#endif
|
||||
|
||||
#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);
|
||||
|
|
@ -93,28 +107,35 @@ void heater_init() {
|
|||
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;
|
||||
#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;
|
||||
|
||||
#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);
|
||||
|
||||
|
|
@ -155,6 +176,12 @@ void heater_tick(uint8_t h, uint16_t current_temp, uint16_t target_temp) {
|
|||
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
|
||||
|
|
@ -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) {
|
||||
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_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_i(uint8_t index, int32_t i) {
|
||||
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_d(uint8_t index, int32_t d) {
|
||||
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(uint8_t index, int32_t i_limit) {
|
||||
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 */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -1,47 +1,55 @@
|
|||
#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; // this packet will be send
|
||||
intercom_packet rx; // the last received packet with correct checksum
|
||||
intercom_packet _tx; // current packet in transmission
|
||||
intercom_packet _rx; // receiving packet
|
||||
|
||||
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 +78,67 @@ 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;
|
||||
|
||||
// set start byte
|
||||
tx.packet.start = START;
|
||||
|
||||
// calculate CRC for outgoing packet
|
||||
for (i = 0; i < (sizeof(intercom_packet_t) - 1); i++) {
|
||||
txcrc ^= tx.data[i];
|
||||
}
|
||||
tx.packet.crc = txcrc;
|
||||
|
||||
for (i = 0; i < (sizeof(intercom_packet_t) ); i++) {
|
||||
_tx.data[i] = tx.data[i];
|
||||
}
|
||||
|
||||
// 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,21 +146,18 @@ 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
|
||||
|
|
@ -126,53 +168,62 @@ ISR(USART_RX_vect)
|
|||
UCSR0A &= ~MASK(FE0) & ~MASK(DOR0) & ~MASK(UPE0);
|
||||
#endif
|
||||
|
||||
if (state >= READ_START1) {
|
||||
// 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;
|
||||
}
|
||||
else if (packet_pointer > 0) {
|
||||
// we're receiving a packet
|
||||
// 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;
|
||||
|
||||
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;
|
||||
#ifndef HOST
|
||||
if (rxcrc == _rx.packet.crc &&
|
||||
_rx.packet.controller_num == THIS_CONTROLLER_NUM){
|
||||
#else
|
||||
if (rxcrc == _rx.packet.crc){
|
||||
#endif
|
||||
// correct crc copy packet
|
||||
static uint8_t i;
|
||||
for (i = 0; i < (sizeof(intercom_packet_t) ); i++) {
|
||||
rx.data[i] = _rx.data[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (chk == 255 - cmd) {
|
||||
//Values are correct, do something useful
|
||||
WRITE(DEBUG_LED,1);
|
||||
read_cmd = cmd;
|
||||
#ifdef EXTRUDER
|
||||
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;
|
||||
// not sure why exactly this delay is needed, but wihtout it first byte never arrives.
|
||||
delay_us(150);
|
||||
start_send();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
state = READ_START1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 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();
|
||||
|
||||
|
||||
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
|
||||
|
|
@ -181,28 +232,20 @@ ISR(USART_TX_vect)
|
|||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
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);
|
||||
|
|
@ -210,10 +253,7 @@ ISR(USART_UDRE_vect)
|
|||
UCSR0B &= ~MASK(UDRIE0);
|
||||
UCSR0B |= MASK(TXCIE0);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* GEN3 */
|
||||
#endif /* TEMP_INTERCOM */
|
||||
|
|
|
|||
|
|
@ -2,16 +2,49 @@
|
|||
#define _INTERCOM_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HOST
|
||||
#define enable_transmit() do { WRITE(TX_ENABLE_PIN,1); UCSR1B &= ~MASK(RXEN1); } while(0)
|
||||
#define disable_transmit() do { WRITE(TX_ENABLE_PIN,0); UCSR1B |= MASK(RXEN1); } while(0)
|
||||
#else
|
||||
#define enable_transmit() do { WRITE(TX_ENABLE_PIN,1); UCSR0B &= ~MASK(RXEN0); } while(0)
|
||||
#define disable_transmit() do { WRITE(TX_ENABLE_PIN,0); UCSR0B |= MASK(RXEN0); } while(0)
|
||||
#endif
|
||||
|
||||
// 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 */
|
||||
|
|
|
|||
176
extruder/temp.c
176
extruder/temp.c
|
|
@ -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\n"), temp_sensors_runtime[index].last_read_temp >> 2, c);
|
||||
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(" B:%u.%u"), temp_sensors_runtime[HEATER_bed].last_read_temp >> 2 , b);
|
||||
#endif
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
12
home.c
12
home.c
|
|
@ -45,7 +45,7 @@ void home_x_negative() {
|
|||
delay(5);
|
||||
unstep();
|
||||
// wait until next step time
|
||||
delay((uint32_t) (60.0 * ((float) F_CPU) / STEPS_PER_MM_X / ((float) MAXIMUM_FEEDRATE_X)));
|
||||
delay((uint32_t) (60.0 * 1000000.0 / STEPS_PER_MM_X / ((float) MAXIMUM_FEEDRATE_X)));
|
||||
}
|
||||
denoise_count = 0;
|
||||
|
||||
|
|
@ -95,7 +95,7 @@ void home_x_positive() {
|
|||
delay(5);
|
||||
unstep();
|
||||
// wait until next step time
|
||||
delay((uint32_t) (60.0 * ((float) F_CPU) / STEPS_PER_MM_X / ((float) SEARCH_FEEDRATE_X)));
|
||||
delay((uint32_t) (60.0 * 1000000.0 / STEPS_PER_MM_X / ((float) SEARCH_FEEDRATE_X)));
|
||||
}
|
||||
|
||||
// set X home
|
||||
|
|
@ -126,7 +126,7 @@ void home_y_negative() {
|
|||
delay(5);
|
||||
unstep();
|
||||
// wait until neyt step time
|
||||
delay((uint32_t) (60.0 * ((float) F_CPU) / STEPS_PER_MM_Y / ((float) MAXIMUM_FEEDRATE_Y)));
|
||||
delay((uint32_t) (60.0 * 1000000.0 / STEPS_PER_MM_Y / ((float) MAXIMUM_FEEDRATE_Y)));
|
||||
}
|
||||
denoise_count = 0;
|
||||
|
||||
|
|
@ -176,7 +176,7 @@ void home_y_positive() {
|
|||
delay(5);
|
||||
unstep();
|
||||
// wait until next step time
|
||||
delay((uint32_t) (60.0 * ((float) F_CPU) / STEPS_PER_MM_Y / ((float) SEARCH_FEEDRATE_Y)));
|
||||
delay((uint32_t) (60.0 * 1000000.0 / STEPS_PER_MM_Y / ((float) SEARCH_FEEDRATE_Y)));
|
||||
}
|
||||
|
||||
// set Y home
|
||||
|
|
@ -207,7 +207,7 @@ void home_z_negative() {
|
|||
delay(5);
|
||||
unstep();
|
||||
// wait until next step time
|
||||
delay((uint32_t) (60.0 * ((float) F_CPU) / STEPS_PER_MM_Z / ((float) MAXIMUM_FEEDRATE_Z)));
|
||||
delay((uint32_t) (60.0 * 1000000.0 / STEPS_PER_MM_Z / ((float) MAXIMUM_FEEDRATE_Z)));
|
||||
}
|
||||
denoise_count = 0;
|
||||
|
||||
|
|
@ -257,7 +257,7 @@ void home_z_positive() {
|
|||
delay(5);
|
||||
unstep();
|
||||
// wait until next step time
|
||||
delay((uint32_t) (60.0 * ((float) F_CPU) / STEPS_PER_MM_Z / ((float) SEARCH_FEEDRATE_Z)));
|
||||
delay((uint32_t) (60.0 * 1000000.0 / STEPS_PER_MM_Z / ((float) SEARCH_FEEDRATE_Z)));
|
||||
}
|
||||
|
||||
// set Z home
|
||||
|
|
|
|||
232
intercom.c
232
intercom.c
|
|
@ -1,47 +1,55 @@
|
|||
#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; // this packet will be send
|
||||
intercom_packet rx; // the last received packet with correct checksum
|
||||
intercom_packet _tx; // current packet in transmission
|
||||
intercom_packet _rx; // receiving packet
|
||||
|
||||
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 +78,67 @@ 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;
|
||||
|
||||
// set start byte
|
||||
tx.packet.start = START;
|
||||
|
||||
// calculate CRC for outgoing packet
|
||||
for (i = 0; i < (sizeof(intercom_packet_t) - 1); i++) {
|
||||
txcrc ^= tx.data[i];
|
||||
}
|
||||
tx.packet.crc = txcrc;
|
||||
|
||||
for (i = 0; i < (sizeof(intercom_packet_t) ); i++) {
|
||||
_tx.data[i] = tx.data[i];
|
||||
}
|
||||
|
||||
// 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,21 +146,18 @@ 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
|
||||
|
|
@ -126,53 +168,62 @@ ISR(USART_RX_vect)
|
|||
UCSR0A &= ~MASK(FE0) & ~MASK(DOR0) & ~MASK(UPE0);
|
||||
#endif
|
||||
|
||||
if (state >= READ_START1) {
|
||||
// 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;
|
||||
}
|
||||
else if (packet_pointer > 0) {
|
||||
// we're receiving a packet
|
||||
// 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;
|
||||
|
||||
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;
|
||||
#ifndef HOST
|
||||
if (rxcrc == _rx.packet.crc &&
|
||||
_rx.packet.controller_num == THIS_CONTROLLER_NUM){
|
||||
#else
|
||||
if (rxcrc == _rx.packet.crc){
|
||||
#endif
|
||||
// correct crc copy packet
|
||||
static uint8_t i;
|
||||
for (i = 0; i < (sizeof(intercom_packet_t) ); i++) {
|
||||
rx.data[i] = _rx.data[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (chk == 255 - cmd) {
|
||||
//Values are correct, do something useful
|
||||
WRITE(DEBUG_LED,1);
|
||||
read_cmd = cmd;
|
||||
#ifdef EXTRUDER
|
||||
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;
|
||||
// not sure why exactly this delay is needed, but wihtout it first byte never arrives.
|
||||
delay_us(150);
|
||||
start_send();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
state = READ_START1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 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();
|
||||
|
||||
|
||||
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
|
||||
|
|
@ -181,28 +232,20 @@ ISR(USART_TX_vect)
|
|||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
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);
|
||||
|
|
@ -210,9 +253,6 @@ ISR(USART_UDRE_vect)
|
|||
UCSR0B &= ~MASK(UDRIE0);
|
||||
UCSR0B |= MASK(TXCIE0);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
41
intercom.h
41
intercom.h
|
|
@ -2,16 +2,49 @@
|
|||
#define _INTERCOM_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HOST
|
||||
#define enable_transmit() do { WRITE(TX_ENABLE_PIN,1); UCSR1B &= ~MASK(RXEN1); } while(0)
|
||||
#define disable_transmit() do { WRITE(TX_ENABLE_PIN,0); UCSR1B |= MASK(RXEN1); } while(0)
|
||||
#else
|
||||
#define enable_transmit() do { WRITE(TX_ENABLE_PIN,1); UCSR0B &= ~MASK(RXEN0); } while(0)
|
||||
#define disable_transmit() do { WRITE(TX_ENABLE_PIN,0); UCSR0B |= MASK(RXEN0); } while(0)
|
||||
#endif
|
||||
|
||||
// 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 */
|
||||
|
|
|
|||
9
mendel.c
9
mendel.c
|
|
@ -20,6 +20,7 @@
|
|||
#include "pinio.h"
|
||||
#include "arduino.h"
|
||||
#include "clock.h"
|
||||
#include "intercom.h"
|
||||
|
||||
void io_init(void) {
|
||||
// disable modules we don't use
|
||||
|
|
@ -123,6 +124,14 @@ void io_init(void) {
|
|||
WRITE(MOSI, 1); SET_OUTPUT(MOSI);
|
||||
WRITE(MISO, 1); SET_INPUT(MISO);
|
||||
WRITE(SS, 1); SET_OUTPUT(SS);
|
||||
|
||||
#ifdef TEMP_INTERCOM
|
||||
// Enable the RS485 transceiver
|
||||
SET_OUTPUT(RX_ENABLE_PIN);
|
||||
SET_OUTPUT(TX_ENABLE_PIN);
|
||||
WRITE(RX_ENABLE_PIN,0);
|
||||
disable_transmit();
|
||||
#endif
|
||||
}
|
||||
|
||||
void init(void) {
|
||||
|
|
|
|||
14
temp.c
14
temp.c
|
|
@ -83,7 +83,7 @@ void temp_init() {
|
|||
#ifdef TEMP_INTERCOM
|
||||
case TT_INTERCOM:
|
||||
intercom_init();
|
||||
update_send_cmd(0);
|
||||
send_temperature(0, 0);
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
|
@ -163,8 +163,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
|
||||
|
|
@ -188,13 +190,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
|
||||
|
|
@ -227,9 +233,7 @@ void temp_sensor_tick() {
|
|||
|
||||
#ifdef TEMP_INTERCOM
|
||||
case TT_INTERCOM:
|
||||
temp = get_read_cmd() << 2;
|
||||
|
||||
start_send();
|
||||
temp = read_temperature(temp_sensors[i].temp_pin);
|
||||
|
||||
temp_sensors_runtime[i].next_read_time = 0;
|
||||
|
||||
|
|
@ -289,7 +293,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
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue