new module adc (analog2digital)

temperature.cpp - adc sampling state machine removed
new dcode D9 (adc read/write + simulator)
temporarily DEBUG_DISABLE_STARTMSGS because UI blocked
SILENT_MAX_FEEDRATE reduced to 172mm/s
hexfile removed
build number 137x
This commit is contained in:
Robert Pelnar 2017-12-20 13:42:20 +01:00
parent 9639b58f4d
commit 25dd6dd673
10 changed files with 257 additions and 15298 deletions

View File

@ -8,10 +8,10 @@
#define STR(x) STR_HELPER(x)
// Firmware version
#define FW_version "3.1.1-RC1"
#define FW_build 136
#define FW_version "3.1.1-RC2"
#define FW_build 137
//#define FW_build --BUILD-NUMBER--
#define FW_version_build FW_version " b" STR(FW_build)
#define FW_version_build FW_version " b" STR(FW_build) "x"
#define FW_PRUSA3D_MAGIC "PRUSA3DFW"

View File

@ -79,7 +79,7 @@ const bool Z_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic o
#define SILENT_MAX_ACCEL_Y 1024 // Y-axis max axxeleration in silent mode in mm/s^2
#define SILENT_MAX_ACCEL_X_ST (100*SILENT_MAX_ACCEL_X) // X max accel in steps/s^2
#define SILENT_MAX_ACCEL_Y_ST (100*SILENT_MAX_ACCEL_Y) // Y max accel in steps/s^2
#define SILENT_MAX_FEEDRATE 192 //max feedrate in mm/s, because mode switched to normal for homming , this value limits also homing, it should be greater (120mm/s=7200mm/min>2700mm/min)
#define SILENT_MAX_FEEDRATE 172 //max feedrate in mm/s, because mode switched to normal for homming , this value limits also homing, it should be greater (160mm/s=9600mm/min>2700mm/min)
//number of bytes from end of the file to start check
#define END_FILE_SECTION 10000
@ -114,7 +114,7 @@ const bool Z_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic o
//#define DEBUG_DISABLE_YMAXLIMIT //y max limit ignored
//#define DEBUG_DISABLE_ZMINLIMIT //z min limit ignored
//#define DEBUG_DISABLE_ZMAXLIMIT //z max limit ignored
//#define DEBUG_DISABLE_STARTMSGS //no startup messages
#define DEBUG_DISABLE_STARTMSGS //no startup messages
//#define DEBUG_DISABLE_MINTEMP //mintemp error ignored
//#define DEBUG_DISABLE_SWLIMITS //sw limits ignored
//#define DEBUG_DISABLE_LCD_STATUS_LINE //empty four lcd line

View File

@ -6,6 +6,8 @@
#include "ConfigurationStore.h"
#include "cmdqueue.h"
#include "pat9125.h"
#include "adc.h"
#include "temperature.h"
#include <avr/wdt.h>
@ -377,6 +379,67 @@ void dcode_8()
printf_P(PSTR("temp_pinda=%d offset_z=%d.%03d\n"), (int)temp_pinda, (int)offset_z, ((int)(1000 * offset_z) % 1000));
}
const char* dcode_9_ADC_name(uint8_t i)
{
switch (i)
{
case 0: return PSTR("TEMP_HEATER0");
case 1: return PSTR("TEMP_HEATER1");
case 2: return PSTR("TEMP_BED");
case 3: return PSTR("TEMP_PINDA");
case 4: return PSTR("VOLT_PWR");
case 5: return PSTR("TEMP_AMBIENT");
case 6: return PSTR("VOLT_BED");
}
return 0;
}
extern int current_temperature_raw[EXTRUDERS];
extern int current_temperature_bed_raw;
extern int current_temperature_raw_pinda;
extern int current_temperature_raw_ambient;
extern int current_voltage_raw_pwr;
extern int current_voltage_raw_bed;
uint16_t dcode_9_ADC_val(uint8_t i)
{
switch (i)
{
case 0: return current_temperature_raw[0];
case 1: return 0;
case 2: return current_temperature_bed_raw;
case 3: return current_temperature_raw_pinda;
case 4: return current_voltage_raw_pwr;
case 5: return current_temperature_raw_ambient;
case 6: return current_voltage_raw_bed;
}
return 0;
}
void dcode_9()
{
printf_P(PSTR("D9 - Read/Write ADC\n"));
if ((strchr_pointer[1+1] == '?') || (strchr_pointer[1+1] == 0))
{
for (uint8_t i = 0; i < ADC_CHAN_CNT; i++)
printf_P(PSTR("\tADC%d=%4d\t(%S)\n"), i, dcode_9_ADC_val(i) >> 4, dcode_9_ADC_name(i));
}
else
{
uint8_t index = 0xff;
if (code_seen('I')) // index (index of used channel, not avr channel index)
index = code_value();
if (index < ADC_CHAN_CNT)
{
if (code_seen('V')) // value to be written as simulated
{
adc_sim_mask |= (1 << index);
adc_values[index] = (((int)code_value()) << 4);
printf_P(PSTR("ADC%d=%4d\n"), index, adc_values[index] >> 4);
}
}
}
}
void dcode_10()
{//Tell the printer that XYZ calibration went OK
LOG("D10 - XYZ calibration = OK\n");

View File

@ -12,6 +12,7 @@ extern void dcode_5(); //D5 - Read/Write FLASH
extern void dcode_6(); //D6 - Read/Write external FLASH
extern void dcode_7(); //D7 - Read/Write Bootloader
extern void dcode_8(); //D8 - Read/Write PINDA
extern void dcode_9(); //D9 - Read/Write ADC (Write=enable simulated, Read=disable simulated)
extern void dcode_10(); //D10 - XYZ calibration = OK
extern void dcode_12(); //D12 - Reset failstat counters

File diff suppressed because it is too large Load Diff

View File

@ -6111,6 +6111,8 @@ case 404: //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp
dcode_7(); break;
case 8: // D8 - Read/Write PINDA
dcode_8(); break;
case 9: // D9 - Read/Write ADC
dcode_9(); break;
case 10: // D10 - XYZ calibration = OK
dcode_10(); break;

88
Firmware/adc.c Normal file
View File

@ -0,0 +1,88 @@
//adc.c
#include "adc.h"
#include <avr/io.h>
uint8_t adc_state;
uint8_t adc_count;
uint16_t adc_values[ADC_CHAN_CNT];
uint16_t adc_sim_mask;
#ifdef ADC_CALLBACK
extern void ADC_CALLBACK(void);
#endif //ADC_CALLBACK
void adc_init(void)
{
printf(("adc_init\n"));
adc_sim_mask = 0x00;
ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
ADMUX |= (1 << REFS0);
ADCSRA |= (1 << ADEN);
// ADCSRA |= (1 << ADIF) | (1 << ADSC);
DIDR0 = (ADC_CHAN_MSK & 0xff);
DIDR2 = (ADC_CHAN_MSK >> 8);
adc_reset();
}
void adc_reset(void)
{
adc_state = 0;
adc_count = 0;
uint8_t i; for (i = 0; i < ADC_CHAN_CNT; i++)
if ((adc_sim_mask & (1 << i)) == 0)
adc_values[i] = 0;
}
void adc_setmux(uint8_t ch)
{
ch &= 0x0f;
if (ch & 0x08) ADCSRB |= (1 << MUX5);
else ADCSRB &= ~(1 << MUX5);
ADMUX = (ADMUX & ~(0x07)) | (ch & 0x07);
}
uint8_t adc_chan(uint8_t index)
{
uint8_t chan = 0;
uint16_t mask = 1;
while (mask)
{
if ((mask & ADC_CHAN_MSK) && (index-- == 0)) break;
mask <<= 1;
chan++;
}
return chan;
}
void adc_cycle(void)
{
if (adc_state & 0x80)
{
uint8_t index = adc_state & 0x0f;
if ((adc_sim_mask & (1 << index)) == 0)
adc_values[index] += ADC;
if (index++ >= ADC_CHAN_CNT)
{
index = 0;
adc_count++;
if (adc_count >= ADC_OVRSAMPL)
{
#ifdef ADC_CALLBACK
ADC_CALLBACK();
#endif //ADC_CALLBACK
adc_reset();
}
}
adc_setmux(adc_chan(index));
adc_state = index;
}
else
{
ADCSRA |= (1 << ADSC); //start conversion
adc_state |= 0x80;
}
}

34
Firmware/adc.h Normal file
View File

@ -0,0 +1,34 @@
//adc.h
#ifndef _ADC_H
#define _ADC_H
#include <inttypes.h>
#include "config.h"
#if defined(__cplusplus)
extern "C" {
#endif //defined(__cplusplus)
extern uint8_t adc_state;
extern uint8_t adc_count;
extern uint16_t adc_values[ADC_CHAN_CNT];
extern uint16_t adc_sim_mask;
extern void adc_init(void);
extern void adc_reset(void);
extern void adc_setmux(uint8_t ch);
extern uint8_t adc_chan(uint8_t index);
extern void adc_cycle(void);
#if defined(__cplusplus)
}
#endif //defined(__cplusplus)
#endif //_ADC_H

12
Firmware/config.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef _CONFIG_H
#define _CONFIG_H
//ADC configuration
#define ADC_CHAN_MSK 0b0000001001011111 //used AD channels bit mask (0,1,2,3,4,6,9)
#define ADC_CHAN_CNT 7 //number of used channels)
#define ADC_OVRSAMPL 16 //oversampling multiplier
#define ADC_CALLBACK adc_ready //callback function ()
#endif //_CONFIG_H

View File

@ -38,6 +38,7 @@
#include "Sd2PinMap.h"
#include <avr/wdt.h>
#include "adc.h"
//===========================================================================
@ -1081,52 +1082,8 @@ void tp_init()
digitalWrite(MAX6675_SS,1);
#endif
// Set analog inputs
ADCSRA = 1<<ADEN | 1<<ADSC | 1<<ADIF | 0x07;
DIDR0 = 0;
#ifdef DIDR2
DIDR2 = 0;
#endif
#if defined(TEMP_0_PIN) && (TEMP_0_PIN > -1)
#if TEMP_0_PIN < 8
DIDR0 |= 1 << TEMP_0_PIN;
#else
DIDR2 |= 1<<(TEMP_0_PIN - 8);
#endif
#endif
#if defined(TEMP_1_PIN) && (TEMP_1_PIN > -1)
#if TEMP_1_PIN < 8
DIDR0 |= 1<<TEMP_1_PIN;
#else
DIDR2 |= 1<<(TEMP_1_PIN - 8);
#endif
#endif
#if defined(TEMP_2_PIN) && (TEMP_2_PIN > -1)
#if TEMP_2_PIN < 8
DIDR0 |= 1 << TEMP_2_PIN;
#else
DIDR2 |= 1<<(TEMP_2_PIN - 8);
#endif
#endif
#if defined(TEMP_BED_PIN) && (TEMP_BED_PIN > -1)
#if TEMP_BED_PIN < 8
DIDR0 |= 1<<TEMP_BED_PIN;
#else
DIDR2 |= 1<<(TEMP_BED_PIN - 8);
#endif
#endif
//Added for Filament Sensor
#ifdef FILAMENT_SENSOR
#if defined(FILWIDTH_PIN) && (FILWIDTH_PIN > -1)
#if FILWIDTH_PIN < 8
DIDR0 |= 1<<FILWIDTH_PIN;
#else
DIDR2 |= 1<<(FILWIDTH_PIN - 8);
#endif
#endif
#endif
adc_init();
// Use timer0 for temperature measurement
// Interleave temperature interrupt with millies interrupt
OCR0B = 128;
@ -1578,21 +1535,28 @@ int read_max6675()
#endif
extern "C" {
void adc_ready(void) //callback from adc when sampling finished
{
current_temperature_raw[0] = adc_values[0];
current_temperature_bed_raw = adc_values[2];
current_temperature_raw_pinda = adc_values[3];
current_voltage_raw_pwr = adc_values[4];
current_temperature_raw_ambient = adc_values[5];
current_voltage_raw_bed = adc_values[6];
temp_meas_ready = true;
}
} // extern "C"
// Timer 0 is shared with millies
ISR(TIMER0_COMPB_vect)
{
// if (UVLO) uvlo();
//these variables are only accesible from the ISR, but static, so they don't lose their value
static unsigned char temp_count = 0;
static unsigned long raw_temp_0_value = 0;
static unsigned long raw_temp_1_value = 0;
static unsigned long raw_temp_2_value = 0;
static unsigned long raw_temp_bed_value = 0;
static unsigned long raw_temp_pinda_value = 0;
static unsigned long raw_temp_ambient_value = 0;
static unsigned long raw_volt_pwr_value = 0;
static unsigned long raw_volt_bed_value = 0;
static unsigned char temp_state = 18;
if (!temp_meas_ready) adc_cycle();
static unsigned char pwm_count = (1 << SOFT_PWM_SCALE);
static unsigned char soft_pwm_0;
#ifdef SLOW_PWM_HEATERS
@ -1926,252 +1890,33 @@ ISR(TIMER0_COMPB_vect)
} //if ((pwm_count % 64) == 0) {
#endif //ifndef SLOW_PWM_HEATERS
switch(temp_state) {
case 0: // Prepare TEMP_0
#if defined(TEMP_0_PIN) && (TEMP_0_PIN > -1)
#if TEMP_0_PIN > 7
ADCSRB = 1<<MUX5;
#else
ADCSRB = 0;
#endif
ADMUX = ((1 << REFS0) | (TEMP_0_PIN & 0x07));
ADCSRA |= 1<<ADSC; // Start conversion
#endif
lcd_buttons_update();
temp_state = 1;
break;
case 1: // Measure TEMP_0
#if defined(TEMP_0_PIN) && (TEMP_0_PIN > -1)
raw_temp_0_value += ADC;
#endif
#ifdef HEATER_0_USES_MAX6675 // TODO remove the blocking
raw_temp_0_value = read_max6675();
#endif
temp_state = 2;
break;
case 2: // Prepare TEMP_BED
#if defined(TEMP_BED_PIN) && (TEMP_BED_PIN > -1)
#if TEMP_BED_PIN > 7
ADCSRB = 1<<MUX5;
#else
ADCSRB = 0;
#endif
ADMUX = ((1 << REFS0) | (TEMP_BED_PIN & 0x07));
ADCSRA |= 1<<ADSC; // Start conversion
#endif
lcd_buttons_update();
temp_state = 3;
break;
case 3: // Measure TEMP_BED
#if defined(TEMP_BED_PIN) && (TEMP_BED_PIN > -1)
raw_temp_bed_value += ADC;
#endif
temp_state = 4;
break;
case 4: // Prepare TEMP_1
#if defined(TEMP_1_PIN) && (TEMP_1_PIN > -1)
#if TEMP_1_PIN > 7
ADCSRB = 1<<MUX5;
#else
ADCSRB = 0;
#endif
ADMUX = ((1 << REFS0) | (TEMP_1_PIN & 0x07));
ADCSRA |= 1<<ADSC; // Start conversion
#endif
lcd_buttons_update();
temp_state = 5;
break;
case 5: // Measure TEMP_1
#if defined(TEMP_1_PIN) && (TEMP_1_PIN > -1)
raw_temp_1_value += ADC;
#endif
temp_state = 6;
break;
case 6: // Prepare TEMP_2
#if defined(TEMP_2_PIN) && (TEMP_2_PIN > -1)
#if TEMP_2_PIN > 7
ADCSRB = 1<<MUX5;
#else
ADCSRB = 0;
#endif
ADMUX = ((1 << REFS0) | (TEMP_2_PIN & 0x07));
ADCSRA |= 1<<ADSC; // Start conversion
#endif
lcd_buttons_update();
temp_state = 7;
break;
case 7: // Measure TEMP_2
#if defined(TEMP_2_PIN) && (TEMP_2_PIN > -1)
raw_temp_2_value += ADC;
#endif
temp_state = 8;//change so that Filament Width is also measured
break;
case 8: //Prepare FILWIDTH
#if defined(FILWIDTH_PIN) && (FILWIDTH_PIN> -1)
#if FILWIDTH_PIN>7
ADCSRB = 1<<MUX5;
#else
ADCSRB = 0;
#endif
ADMUX = ((1 << REFS0) | (FILWIDTH_PIN & 0x07));
ADCSRA |= 1<<ADSC; // Start conversion
#endif
lcd_buttons_update();
temp_state = 9;
break;
case 9: //Measure FILWIDTH
#if defined(FILWIDTH_PIN) &&(FILWIDTH_PIN > -1)
//raw_filwidth_value += ADC; //remove to use an IIR filter approach
if(ADC>102) //check that ADC is reading a voltage > 0.5 volts, otherwise don't take in the data.
{
raw_filwidth_value= raw_filwidth_value-(raw_filwidth_value>>7); //multipliy raw_filwidth_value by 127/128
raw_filwidth_value= raw_filwidth_value + ((unsigned long)ADC<<7); //add new ADC reading
}
#endif
temp_state = 10;
break;
case 10: // Prepare TEMP_AMBIENT
#if defined(TEMP_AMBIENT_PIN) && (TEMP_AMBIENT_PIN > -1)
#if TEMP_AMBIENT_PIN > 7
ADCSRB = 1<<MUX5;
#else
ADCSRB = 0;
#endif
ADMUX = ((1 << REFS0) | (TEMP_AMBIENT_PIN & 0x07));
ADCSRA |= 1<<ADSC; // Start conversion
#endif
lcd_buttons_update();
temp_state = 11;
break;
case 11: // Measure TEMP_AMBIENT
#if defined(TEMP_AMBIENT_PIN) && (TEMP_AMBIENT_PIN > -1)
raw_temp_ambient_value += ADC;
#endif
temp_state = 12;
break;
case 12: // Prepare TEMP_PINDA
#if defined(TEMP_PINDA_PIN) && (TEMP_PINDA_PIN > -1)
#if TEMP_PINDA_PIN > 7
ADCSRB = 1<<MUX5;
#else
ADCSRB = 0;
#endif
ADMUX = ((1 << REFS0) | (TEMP_PINDA_PIN & 0x07));
ADCSRA |= 1<<ADSC; // Start conversion
#endif
lcd_buttons_update();
temp_state = 13;
break;
case 13: // Measure TEMP_PINDA
#if defined(TEMP_PINDA_PIN) && (TEMP_PINDA_PIN > -1)
raw_temp_pinda_value += ADC;
#endif
temp_state = 14;
break;
case 14: // Prepare VOLT_PWR
#if defined(VOLT_PWR_PIN) && (VOLT_PWR_PIN > -1)
#if VOLT_PWR_PIN > 7
ADCSRB = 1<<MUX5;
#else
ADCSRB = 0;
#endif
ADMUX = ((1 << REFS0) | (VOLT_PWR_PIN & 0x07));
ADCSRA |= 1<<ADSC; // Start conversion
#endif
lcd_buttons_update();
temp_state = 15;
break;
case 15: // Measure VOLT_PWR
#if defined(VOLT_PWR_PIN) && (VOLT_PWR_PIN > -1)
raw_volt_pwr_value += ADC;
#endif
temp_state = 16;
break;
case 16: // Prepare VOLT_BED
#if defined(VOLT_BED_PIN) && (VOLT_BED_PIN > -1)
#if VOLT_BED_PIN > 7
ADCSRB = 1<<MUX5;
#else
ADCSRB = 0;
#endif
ADMUX = ((1 << REFS0) | (VOLT_BED_PIN & 0x07));
ADCSRA |= 1<<ADSC; // Start conversion
#endif
lcd_buttons_update();
temp_state = 17;
break;
case 17: // Measure VOLT_BED
#if defined(VOLT_BED_PIN) && (VOLT_BED_PIN > -1)
raw_volt_bed_value += ADC;
#endif
temp_state = 0;
temp_count++;
break;
case 18: //Startup, delay initial temp reading a tiny bit so the hardware can settle.
temp_state = 0;
break;
// default:
// SERIAL_ERROR_START;
// SERIAL_ERRORLNPGM("Temp measurement error!");
// break;
}
if(temp_count >= OVERSAMPLENR) // 10 * 16 * 1/(16000000/64/256) = 164ms.
#ifdef BABYSTEPPING
for(uint8_t axis=0;axis<3;axis++)
{
if (!temp_meas_ready) //Only update the raw values if they have been read. Else we could be updating them during reading.
int curTodo=babystepsTodo[axis]; //get rid of volatile for performance
if(curTodo>0)
{
current_temperature_raw[0] = raw_temp_0_value;
#if EXTRUDERS > 1
current_temperature_raw[1] = raw_temp_1_value;
#endif
#ifdef TEMP_SENSOR_1_AS_REDUNDANT
redundant_temperature_raw = raw_temp_1_value;
#endif
#if EXTRUDERS > 2
current_temperature_raw[2] = raw_temp_2_value;
#endif
#ifdef PINDA_THERMISTOR
current_temperature_raw_pinda = raw_temp_pinda_value;
#endif //PINDA_THERMISTOR
#ifdef AMBIENT_THERMISTOR
current_temperature_raw_ambient = raw_temp_ambient_value;
#endif //AMBIENT_THERMISTOR
#ifdef VOLT_PWR_PIN
current_voltage_raw_pwr = raw_volt_pwr_value;
#endif
#ifdef VOLT_BED_PIN
current_voltage_raw_bed = raw_volt_bed_value;
#endif
current_temperature_bed_raw = raw_temp_bed_value;
babystep(axis,/*fwd*/true);
babystepsTodo[axis]--; //less to do next time
}
else
if(curTodo<0)
{
babystep(axis,/*fwd*/false);
babystepsTodo[axis]++; //less to do next time
}
}
#endif //BABYSTEPPING
//Add similar code for Filament Sensor - can be read any time since IIR filtering is used
#if defined(FILWIDTH_PIN) &&(FILWIDTH_PIN > -1)
current_raw_filwidth = raw_filwidth_value>>10; //need to divide to get to 0-16384 range since we used 1/128 IIR filter approach
#endif
temp_meas_ready = true;
temp_count = 0;
raw_temp_0_value = 0;
raw_temp_1_value = 0;
raw_temp_2_value = 0;
raw_temp_bed_value = 0;
raw_temp_pinda_value = 0;
raw_temp_ambient_value = 0;
raw_volt_pwr_value = 0;
raw_volt_bed_value = 0;
check_fans();
}
void check_min_max_temp()
{
/*
#if HEATER_0_RAW_LO_TEMP > HEATER_0_RAW_HI_TEMP
if(current_temperature_raw[0] <= maxttemp_raw[0]) {
#else
@ -2218,8 +1963,14 @@ ISR(TIMER0_COMPB_vect)
min_temp_error(2);
}
#endif
/* No bed MINTEMP error? */
// No bed MINTEMP error?
#if defined(BED_MAXTEMP) && (TEMP_SENSOR_BED != 0)
@ -2241,28 +1992,7 @@ ISR(TIMER0_COMPB_vect)
bed_min_temp_error();
}
#endif
#ifdef BABYSTEPPING
for(uint8_t axis=0;axis<3;axis++)
{
int curTodo=babystepsTodo[axis]; //get rid of volatile for performance
if(curTodo>0)
{
babystep(axis,/*fwd*/true);
babystepsTodo[axis]--; //less to do next time
}
else
if(curTodo<0)
{
babystep(axis,/*fwd*/false);
babystepsTodo[axis]++; //less to do next time
}
}
#endif //BABYSTEPPING
check_fans();
#endif*/
}
void check_fans() {