Commit f52d793d authored by MagoKimbra's avatar MagoKimbra

Add Support Filament Sensor

Add support for filament sensor
parent 5af7632a
...@@ -589,6 +589,29 @@ ...@@ -589,6 +589,29 @@
//define BlinkM/CyzRgb Support //define BlinkM/CyzRgb Support
//#define BLINKM //#define BLINKM
/**********************************************************************\
* Support for a filament diameter sensor
* Also allows adjustment of diameter at print time (vs at slicing)
* Single extruder only at this point (extruder 0)
*
* Motherboards
* 34 - RAMPS1.4 - uses Analog input 5 on the AUX2 connector
* 81 - Printrboard - Uses Analog input 2 on the Aux 2 connector
* 301 - Rambo - uses Analog input 3
* Note may require analog pins to be defined for different motherboards
**********************************************************************/
// #define FILAMENT_SENSOR
#define FILAMENT_SENSOR_EXTRUDER_NUM 0 //The number of the extruder that has the filament sensor (0,1,2)
#define MEASUREMENT_DELAY_CM 14 //measurement delay in cm. This is the distance from filament sensor to middle of barrel
#define DEFAULT_NOMINAL_FILAMENT_DIA 3.0 //Enter the diameter (in mm) of the filament generally used (3.0 mm or 1.75 mm) - this is then used in the slicer software. Used for sensor reading validation
#define MEASURED_UPPER_LIMIT 3.30 //upper limit factor used for sensor reading validation in mm
#define MEASURED_LOWER_LIMIT 1.90 //lower limit factor for sensor reading validation in mm
#define MAX_MEASUREMENT_DELAY 20 //delay buffer size in bytes (1 byte = 1cm)- limits maximum measurement delay allowable (must be larger than MEASUREMENT_DELAY_CM and lower number saves RAM)
//defines used in the code
#define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA //set measured to nominal initially
#include "Configuration_adv.h" #include "Configuration_adv.h"
#include "thermistortables.h" #include "thermistortables.h"
......
...@@ -270,6 +270,16 @@ extern int EtoPPressure; ...@@ -270,6 +270,16 @@ extern int EtoPPressure;
extern unsigned char fanSpeedSoftPwm; extern unsigned char fanSpeedSoftPwm;
#endif #endif
#ifdef FILAMENT_SENSOR
extern float filament_width_nominal; //holds the theoretical filament diameter ie., 3.00 or 1.75
extern bool filament_sensor; //indicates that filament sensor readings should control extrusion
extern float filament_width_meas; //holds the filament diameter as accurately measured
extern signed char measurement_delay[]; //ring buffer to delay measurement
extern int delay_index1, delay_index2; //index into ring buffer
extern float delay_dist; //delay distance counter
extern int meas_delay_cm; //delay distance
#endif
#ifdef FWRETRACT #ifdef FWRETRACT
extern bool autoretract_enabled; extern bool autoretract_enabled;
extern bool retracted[EXTRUDERS]; extern bool retracted[EXTRUDERS];
......
...@@ -162,6 +162,10 @@ ...@@ -162,6 +162,10 @@
// M400 - Finish all moves // M400 - Finish all moves
// M401 - Lower z-probe if present // M401 - Lower z-probe if present
// M402 - Raise z-probe if present // M402 - Raise z-probe if present
// M404 - N<dia in mm> Enter the nominal filament width (3mm, 1.75mm ) or will display nominal filament width without parameters
// M405 - Turn on Filament Sensor extrusion control. Optional D<delay in cm> to set delay in centimeters between sensor and extruder
// M406 - Turn off Filament Sensor extrusion control
// M407 - Displays measured filament diameter
// M500 - stores parameters in EEPROM // M500 - stores parameters in EEPROM
// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). // M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily).
// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. // M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to.
...@@ -360,6 +364,18 @@ float axis_scaling[3]={1,1,1}; // Build size scaling, default to 1 ...@@ -360,6 +364,18 @@ float axis_scaling[3]={1,1,1}; // Build size scaling, default to 1
bool cancel_heatup = false ; bool cancel_heatup = false ;
#ifdef FILAMENT_SENSOR
//Variables for Filament Sensor input
float filament_width_nominal=DEFAULT_NOMINAL_FILAMENT_DIA; //Set nominal filament width, can be changed with M404
bool filament_sensor=false; //M405 turns on filament_sensor control, M406 turns it off
float filament_width_meas=DEFAULT_MEASURED_FILAMENT_DIA; //Stores the measured filament diameter
signed char measurement_delay[MAX_MEASUREMENT_DELAY+1]; //ring buffer to delay measurement store extruder factor after subtracting 100
int delay_index1=0; //index into ring buffer
int delay_index2=-1; //index into ring buffer - set to -1 on startup to indicate ring buffer needs to be initialized
float delay_dist=0; //delay distance counter
int meas_delay_cm = MEASUREMENT_DELAY_CM; //distance delay setting
#endif
//=========================================================================== //===========================================================================
//=============================Private Variables============================= //=============================Private Variables=============================
//=========================================================================== //===========================================================================
...@@ -1834,64 +1850,59 @@ void process_commands() ...@@ -1834,64 +1850,59 @@ void process_commands()
{ {
switch((int)code_value()) switch((int)code_value())
{ {
case 0: // G0 -> G1 case 0: // G0 -> G1
case 1: // G1
case 1: // G1 if(Stopped == false) {
if(Stopped == false) { get_coordinates(); // For X Y Z E F
get_coordinates(); // For X Y Z E F #ifdef FWRETRACT
#ifdef FWRETRACT if(autoretract_enabled)
if(autoretract_enabled) if( !(code_seen('X') || code_seen('Y') || code_seen('Z')) && code_seen('E')) {
if( !(code_seen('X') || code_seen('Y') || code_seen('Z')) && code_seen('E')) { float echange=destination[E_AXIS]-current_position[E_AXIS];
float echange=destination[E_AXIS]-current_position[E_AXIS]; if((echange<-MIN_RETRACT && !retracted) || (echange>MIN_RETRACT && retracted)) { //move appears to be an attempt to retract or recover
if((echange<-MIN_RETRACT && !retracted) || (echange>MIN_RETRACT && retracted)) { //move appears to be an attempt to retract or recover current_position[E_AXIS] = destination[E_AXIS]; //hide the slicer-generated retract/recover from calculations
current_position[E_AXIS] = destination[E_AXIS]; //hide the slicer-generated retract/recover from calculations plan_set_e_position(current_position[E_AXIS]); //AND from the planner
plan_set_e_position(current_position[E_AXIS]); //AND from the planner retract(!retracted);
retract(!retracted); return;
return; }
} }
} #endif //FWRETRACT
#endif //FWRETRACT prepare_move();
prepare_move(); //ClearToSend();
//ClearToSend(); return;
return; }
}
break; break;
#ifndef SCARA //disable arc support
#ifndef SCARA //disable arc support case 2: // G2 - CW ARC
case 2: // G2 - CW ARC if(Stopped == false) {
if(Stopped == false) { get_arc_coordinates();
get_arc_coordinates(); prepare_arc_move(true);
prepare_arc_move(true); return;
return; }
}
break; break;
case 3: // G3 - CCW ARC
case 3: // G3 - CCW ARC if(Stopped == false) {
if(Stopped == false) { get_arc_coordinates();
get_arc_coordinates(); prepare_arc_move(false);
prepare_arc_move(false); return;
return; }
}
break; break;
#endif #endif // no SCARA
case 4: // G4 dwell
case 4: // G4 dwell LCD_MESSAGEPGM(MSG_DWELL);
LCD_MESSAGEPGM(MSG_DWELL); codenum = 0;
codenum = 0; if(code_seen('P')) codenum = code_value(); // milliseconds to wait
if(code_seen('P')) codenum = code_value(); // milliseconds to wait if(code_seen('S')) codenum = code_value() * 1000; // seconds to wait
if(code_seen('S')) codenum = code_value() * 1000; // seconds to wait
st_synchronize(); st_synchronize();
codenum += millis(); // keep track of when we started waiting codenum += millis(); // keep track of when we started waiting
previous_millis_cmd = millis(); previous_millis_cmd = millis();
while(millis() < codenum ){ while(millis() < codenum ){
manage_heater(); manage_heater();
manage_inactivity(); manage_inactivity();
lcd_update(); lcd_update();
} }
break; break;
#ifdef FWRETRACT
#ifdef FWRETRACT
case 10: // G10 retract case 10: // G10 retract
#if EXTRUDERS > 1 #if EXTRUDERS > 1
retracted_swap[active_extruder]=(code_seen('S') && code_value_long() == 1); // checks for swap retract argument retracted_swap[active_extruder]=(code_seen('S') && code_value_long() == 1); // checks for swap retract argument
...@@ -2900,39 +2911,40 @@ void process_commands() ...@@ -2900,39 +2911,40 @@ void process_commands()
} }
} }
else if(code_seen('M')) { else if(code_seen('M'))
switch( (int)code_value() ) { {
switch( (int)code_value() )
#ifdef ULTIPANEL {
case 0: // M0 - Unconditional stop - Wait for user button press on LCD #ifdef ULTIPANEL
case 0: // M0 - Unconditional stop - Wait for user button press on LCD
case 1: // M1 - Conditional stop - Wait for user button press on LCD case 1: // M1 - Conditional stop - Wait for user button press on LCD
LCD_MESSAGEPGM(MSG_USERWAIT); {
codenum = 0; LCD_MESSAGEPGM(MSG_USERWAIT);
if(code_seen('P')) codenum = code_value(); // milliseconds to wait codenum = 0;
if(code_seen('S')) codenum = code_value() * 1000; // seconds to wait if(code_seen('P')) codenum = code_value(); // milliseconds to wait
if(code_seen('S')) codenum = code_value() * 1000; // seconds to wait
st_synchronize(); st_synchronize();
previous_millis_cmd = millis(); previous_millis_cmd = millis();
if (codenum > 0) { if (codenum > 0){
codenum += millis(); // keep track of when we started waiting codenum += millis(); // keep track of when we started waiting
while(millis() < codenum && !lcd_clicked()) { while(millis() < codenum && !lcd_clicked()){
manage_heater(); manage_heater();
manage_inactivity(); manage_inactivity();
lcd_update(); lcd_update();
}
} else {
while(!lcd_clicked()){
manage_heater();
manage_inactivity();
lcd_update();
}
} }
LCD_MESSAGEPGM(MSG_RESUMING); }else{
break; while(!lcd_clicked()){
#endif // ULTIPANEL manage_heater();
manage_inactivity();
case 17: lcd_update();
}
}
LCD_MESSAGEPGM(MSG_RESUMING);
}
break;
#endif
case 17:
LCD_MESSAGEPGM(MSG_NO_MOVE); LCD_MESSAGEPGM(MSG_NO_MOVE);
enable_x(); enable_x();
enable_y(); enable_y();
...@@ -3138,6 +3150,7 @@ void process_commands() ...@@ -3138,6 +3150,7 @@ void process_commands()
if (verbose_level > 0) { if (verbose_level > 0) {
SERIAL_PROTOCOLPGM("M49 Z-Probe Repeatability test. Version 2.00\n"); SERIAL_PROTOCOLPGM("M49 Z-Probe Repeatability test. Version 2.00\n");
SERIAL_PROTOCOLPGM("Full support at: http://3dprintboard.com/forum.php\n");
} }
if (code_seen('n')) { if (code_seen('n')) {
...@@ -3373,7 +3386,7 @@ Sigma_Exit: ...@@ -3373,7 +3386,7 @@ Sigma_Exit:
if(setTargetedHotend(104)){ if(setTargetedHotend(104)){
break; break;
} }
if (code_seen('S')) setTargetHotend(code_value(), tmp_extruder); if (code_seen('S')) setTargetHotend(code_value(), tmp_extruder);
#ifdef DUAL_X_CARRIAGE #ifdef DUAL_X_CARRIAGE
if (dual_x_carriage_mode == DXC_DUPLICATION_MODE && tmp_extruder == 0) if (dual_x_carriage_mode == DXC_DUPLICATION_MODE && tmp_extruder == 0)
setTargetHotend1(code_value() == 0.0 ? 0.0 : code_value() + duplicate_extruder_temp_offset); setTargetHotend1(code_value() == 0.0 ? 0.0 : code_value() + duplicate_extruder_temp_offset);
...@@ -3395,13 +3408,12 @@ Sigma_Exit: ...@@ -3395,13 +3408,12 @@ Sigma_Exit:
SERIAL_PROTOCOL_F(degHotend(tmp_extruder),1); SERIAL_PROTOCOL_F(degHotend(tmp_extruder),1);
SERIAL_PROTOCOLPGM(" /"); SERIAL_PROTOCOLPGM(" /");
SERIAL_PROTOCOL_F(degTargetHotend(tmp_extruder),1); SERIAL_PROTOCOL_F(degTargetHotend(tmp_extruder),1);
#if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1 #if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1
SERIAL_PROTOCOLPGM(" B:"); SERIAL_PROTOCOLPGM(" B:");
SERIAL_PROTOCOL_F(degBed(),1); SERIAL_PROTOCOL_F(degBed(),1);
SERIAL_PROTOCOLPGM(" /"); SERIAL_PROTOCOLPGM(" /");
SERIAL_PROTOCOL_F(degTargetBed(),1); SERIAL_PROTOCOL_F(degTargetBed(),1);
#endif //TEMP_BED_PIN #endif //TEMP_BED_PIN
for (int8_t cur_extruder = 0; cur_extruder < EXTRUDERS; ++cur_extruder) { for (int8_t cur_extruder = 0; cur_extruder < EXTRUDERS; ++cur_extruder) {
SERIAL_PROTOCOLPGM(" T"); SERIAL_PROTOCOLPGM(" T");
SERIAL_PROTOCOL(cur_extruder); SERIAL_PROTOCOL(cur_extruder);
...@@ -3431,22 +3443,22 @@ Sigma_Exit: ...@@ -3431,22 +3443,22 @@ Sigma_Exit:
SERIAL_PROTOCOL(getHeaterPower(-1)); SERIAL_PROTOCOL(getHeaterPower(-1));
#endif #endif
#ifdef SHOW_TEMP_ADC_VALUES #ifdef SHOW_TEMP_ADC_VALUES
#if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1 #if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1
SERIAL_PROTOCOLPGM(" ADC B:"); SERIAL_PROTOCOLPGM(" ADC B:");
SERIAL_PROTOCOL_F(degBed(),1); SERIAL_PROTOCOL_F(degBed(),1);
SERIAL_PROTOCOLPGM("C->"); SERIAL_PROTOCOLPGM("C->");
SERIAL_PROTOCOL_F(rawBedTemp()/OVERSAMPLENR,0); SERIAL_PROTOCOL_F(rawBedTemp()/OVERSAMPLENR,0);
#endif #endif
for (int8_t cur_extruder = 0; cur_extruder < EXTRUDERS; ++cur_extruder) { for (int8_t cur_extruder = 0; cur_extruder < EXTRUDERS; ++cur_extruder) {
SERIAL_PROTOCOLPGM(" T"); SERIAL_PROTOCOLPGM(" T");
SERIAL_PROTOCOL(cur_extruder); SERIAL_PROTOCOL(cur_extruder);
SERIAL_PROTOCOLPGM(":"); SERIAL_PROTOCOLPGM(":");
SERIAL_PROTOCOL_F(degHotend(cur_extruder),1); SERIAL_PROTOCOL_F(degHotend(cur_extruder),1);
SERIAL_PROTOCOLPGM("C->"); SERIAL_PROTOCOLPGM("C->");
SERIAL_PROTOCOL_F(rawHotendTemp(cur_extruder)/OVERSAMPLENR,0); SERIAL_PROTOCOL_F(rawHotendTemp(cur_extruder)/OVERSAMPLENR,0);
} }
#endif #endif
SERIAL_PROTOCOLLN(""); SERIAL_PROTOCOLLN("");
return; return;
...@@ -3503,41 +3515,41 @@ Sigma_Exit: ...@@ -3503,41 +3515,41 @@ Sigma_Exit:
#else #else
while ( target_direction ? (isHeatingHotend(tmp_extruder)) : (isCoolingHotend(tmp_extruder)&&(CooldownNoWait==false)) ) { while ( target_direction ? (isHeatingHotend(tmp_extruder)) : (isCoolingHotend(tmp_extruder)&&(CooldownNoWait==false)) ) {
#endif //TEMP_RESIDENCY_TIME #endif //TEMP_RESIDENCY_TIME
if( (millis() - codenum) > 1000UL ) if( (millis() - codenum) > 1000UL )
{ //Print Temp Reading and remaining time every 1 second while heating up/cooling down { //Print Temp Reading and remaining time every 1 second while heating up/cooling down
SERIAL_PROTOCOLPGM("T:"); SERIAL_PROTOCOLPGM("T:");
SERIAL_PROTOCOL_F(degHotend(tmp_extruder),1); SERIAL_PROTOCOL_F(degHotend(tmp_extruder),1);
SERIAL_PROTOCOLPGM(" E:"); SERIAL_PROTOCOLPGM(" E:");
SERIAL_PROTOCOL((int)tmp_extruder); SERIAL_PROTOCOL((int)tmp_extruder);
#ifdef TEMP_RESIDENCY_TIME #ifdef TEMP_RESIDENCY_TIME
SERIAL_PROTOCOLPGM(" W:"); SERIAL_PROTOCOLPGM(" W:");
if(residencyStart > -1) if(residencyStart > -1)
{ {
codenum = ((TEMP_RESIDENCY_TIME * 1000UL) - (millis() - residencyStart)) / 1000UL; codenum = ((TEMP_RESIDENCY_TIME * 1000UL) - (millis() - residencyStart)) / 1000UL;
SERIAL_PROTOCOLLN( codenum ); SERIAL_PROTOCOLLN( codenum );
}
else
{
SERIAL_PROTOCOLLN( "?" );
}
#else
SERIAL_PROTOCOLLN("");
#endif
codenum = millis();
} }
else manage_heater();
manage_inactivity();
lcd_update();
#ifdef TEMP_RESIDENCY_TIME
/* start/restart the TEMP_RESIDENCY_TIME timer whenever we reach target temp for the first time
or when current temp falls outside the hysteresis after target temp was reached */
if ((residencyStart == -1 && target_direction && (degHotend(tmp_extruder) >= (degTargetHotend(tmp_extruder)-TEMP_WINDOW))) ||
(residencyStart == -1 && !target_direction && (degHotend(tmp_extruder) <= (degTargetHotend(tmp_extruder)+TEMP_WINDOW))) ||
(residencyStart > -1 && labs(degHotend(tmp_extruder) - degTargetHotend(tmp_extruder)) > TEMP_HYSTERESIS) )
{ {
SERIAL_PROTOCOLLN( "?" ); residencyStart = millis();
} }
#else #endif //TEMP_RESIDENCY_TIME
SERIAL_PROTOCOLLN("");
#endif
codenum = millis();
}
manage_heater();
manage_inactivity();
lcd_update();
#ifdef TEMP_RESIDENCY_TIME
/* start/restart the TEMP_RESIDENCY_TIME timer whenever we reach target temp for the first time
or when current temp falls outside the hysteresis after target temp was reached */
if ((residencyStart == -1 && target_direction && (degHotend(tmp_extruder) >= (degTargetHotend(tmp_extruder)-TEMP_WINDOW))) ||
(residencyStart == -1 && !target_direction && (degHotend(tmp_extruder) <= (degTargetHotend(tmp_extruder)+TEMP_WINDOW))) ||
(residencyStart > -1 && labs(degHotend(tmp_extruder) - degTargetHotend(tmp_extruder)) > TEMP_HYSTERESIS) )
{
residencyStart = millis();
}
#endif //TEMP_RESIDENCY_TIME
} }
LCD_MESSAGEPGM(MSG_HEATING_COMPLETE); LCD_MESSAGEPGM(MSG_HEATING_COMPLETE);
starttime=millis(); starttime=millis();
...@@ -3845,6 +3857,8 @@ Sigma_Exit: ...@@ -3845,6 +3857,8 @@ Sigma_Exit:
} else { } else {
//reserved for setting filament diameter via UFID or filament measuring device //reserved for setting filament diameter via UFID or filament measuring device
break; break;
} }
tmp_extruder = active_extruder; tmp_extruder = active_extruder;
if(code_seen('T')) { if(code_seen('T')) {
...@@ -3887,32 +3901,33 @@ Sigma_Exit: ...@@ -3887,32 +3901,33 @@ Sigma_Exit:
if(code_seen('T')) retract_acceleration = code_value() ; if(code_seen('T')) retract_acceleration = code_value() ;
} }
break; break;
case 205: //M205 advanced settings: minimum travel speed S=while printing T=travel only, B=minimum segment time X= maximum xy jerk, Z=maximum Z jerk case 205: //M205 advanced settings: minimum travel speed S=while printing T=travel only, B=minimum segment time X= maximum xy jerk, Z=maximum Z jerk
{
if(code_seen('S')) minimumfeedrate = code_value();
if(code_seen('T')) mintravelfeedrate = code_value();
if(code_seen('B')) minsegmenttime = code_value() ;
if(code_seen('X')) max_xy_jerk = code_value() ;
if(code_seen('Z')) max_z_jerk = code_value() ;
if(code_seen('E')) max_e_jerk = code_value() ;
}
break;
case 206: // M206 additional homing offset
for(int8_t i=0; i < 3; i++)
{ {
if(code_seen('S')) minimumfeedrate = code_value(); if(code_seen(axis_codes[i])) add_homing[i] = code_value();
if(code_seen('T')) mintravelfeedrate = code_value();
if(code_seen('B')) minsegmenttime = code_value() ;
if(code_seen('X')) max_xy_jerk = code_value() ;
if(code_seen('Z')) max_z_jerk = code_value() ;
if(code_seen('E')) max_e_jerk = code_value() ;
} }
#ifdef SCARA
if(code_seen('T')) // Theta
{
add_homing[0] = code_value() ;
}
if(code_seen('P')) // Psi
{
add_homing[1] = code_value() ;
}
#endif
break; break;
case 206: // M206 additional homeing offset
for(int8_t i=0; i < 3; i++)
{
if(code_seen(axis_codes[i])) add_homing[i] = code_value();
}
#ifdef SCARA
if(code_seen('T')) // Theta
{
add_homing[0] = code_value() ;
}
if(code_seen('P')) // Psi
{
add_homing[1] = code_value() ;
}
#endif
break;
#ifdef DELTA #ifdef DELTA
case 666: // M666 set delta endstop and geometry adjustment case 666: // M666 set delta endstop and geometry adjustment
if ( !(code_seen('P'))) { if ( !(code_seen('P'))) {
...@@ -3999,231 +4014,224 @@ Sigma_Exit: ...@@ -3999,231 +4014,224 @@ Sigma_Exit:
} }
break; break;
#endif // Delta #endif // Delta
#ifdef FWRETRACT
#ifdef FWRETRACT case 207: //M207 - set retract length S[positive mm] F[feedrate mm/min] Z[additional zlift/hop]
case 207: //M207 - set retract length S[positive mm] F[feedrate mm/min] Z[additional zlift/hop] {
if(code_seen('S'))
{ {
if(code_seen('S')) retract_length = code_value() ;
{
retract_length = code_value() ;
}
if(code_seen('F'))
{
retract_feedrate = code_value()/60 ;
}
if(code_seen('Z'))
{
retract_zlift = code_value() ;
}
} }
break; if(code_seen('F'))
case 208: // M208 - set retract recover length S[positive mm surplus to the M207 S*] F[feedrate mm/min]
{ {
if(code_seen('S')) retract_feedrate = code_value()/60 ;
{
retract_recover_length = code_value() ;
}
if(code_seen('F'))
{
retract_recover_feedrate = code_value()/60 ;
}
} }
break; if(code_seen('Z'))
case 209: // M209 - S<1=true/0=false> enable automatic retract detect if the slicer did not support G10/11: every normal extrude-only move will be classified as retract depending on the direction.
{ {
if(code_seen('S')) retract_zlift = code_value() ;
}
}break;
case 208: // M208 - set retract recover length S[positive mm surplus to the M207 S*] F[feedrate mm/min]
{
if(code_seen('S'))
{
retract_recover_length = code_value() ;
}
if(code_seen('F'))
{
retract_recover_feedrate = code_value()/60 ;
}
}break;
case 209: // M209 - S<1=true/0=false> enable automatic retract detect if the slicer did not support G10/11: every normal extrude-only move will be classified as retract depending on the direction.
{
if(code_seen('S'))
{
int t= code_value() ;
switch(t)
{ {
int t= code_value() ; case 0:
switch(t)
{ {
case 0: autoretract_enabled=false;
{ retracted[0]=false;
autoretract_enabled=false; #if EXTRUDERS > 1
retracted[0]=false; retracted[1]=false;
#if EXTRUDERS > 1 #endif
retracted[1]=false; #if EXTRUDERS > 2
#endif retracted[2]=false;
#if EXTRUDERS > 2 #endif
retracted[2]=false; #if EXTRUDERS > 3
#endif retracted[3]=false;
#if EXTRUDERS > 3 #endif
retracted[3]=false; }break;
#endif case 1:
} {
break; autoretract_enabled=true;
case 1: retracted[0]=false;
{ #if EXTRUDERS > 1
autoretract_enabled=true; retracted[1]=false;
retracted[0]=false; #endif
#if EXTRUDERS > 1 #if EXTRUDERS > 2
retracted[1]=false; retracted[2]=false;
#endif #endif
#if EXTRUDERS > 2 #if EXTRUDERS > 3
retracted[2]=false;
#endif
#if EXTRUDERS > 3
retracted[3]=false; retracted[3]=false;
#endif #endif
} }break;
break; default:
default: SERIAL_ECHO_START;
SERIAL_ECHO_START; SERIAL_ECHOPGM(MSG_UNKNOWN_COMMAND);
SERIAL_ECHOPGM(MSG_UNKNOWN_COMMAND); SERIAL_ECHO(cmdbuffer[bufindr]);
SERIAL_ECHO(cmdbuffer[bufindr]); SERIAL_ECHOLNPGM("\"");
SERIAL_ECHOLNPGM("\"");
}
} }
} }
break;
#endif // FWRETRACT
#if EXTRUDERS > 1 && !defined(SINGLENOZZLE) }break;
case 218: // M218 - set hotend offset (in mm), T<extruder_number> X<offset_on_X> Y<offset_on_Y> #endif // FWRETRACT
#ifndef SINGLENOZZLE
#if EXTRUDERS > 1
case 218: // M218 - set hotend offset (in mm), T<extruder_number> X<offset_on_X> Y<offset_on_Y>
{
if(setTargetedHotend(218)){
break;
}
if(code_seen('X'))
{ {
if(setTargetedHotend(218)){ extruder_offset[X_AXIS][tmp_extruder] = code_value();
break;
}
if(code_seen('X'))
{
extruder_offset[X_AXIS][tmp_extruder] = code_value();
}
if(code_seen('Y'))
{
extruder_offset[Y_AXIS][tmp_extruder] = code_value();
}
#ifdef DUAL_X_CARRIAGE
if(code_seen('Z'))
{
extruder_offset[Z_AXIS][tmp_extruder] = code_value();
}
#endif // DUAL_X_CARRIAGE
SERIAL_ECHO_START;
SERIAL_ECHOPGM(MSG_HOTEND_OFFSET);
for(tmp_extruder = 0; tmp_extruder < EXTRUDERS; tmp_extruder++)
{
SERIAL_ECHO(" ");
SERIAL_ECHO(extruder_offset[X_AXIS][tmp_extruder]);
SERIAL_ECHO(",");
SERIAL_ECHO(extruder_offset[Y_AXIS][tmp_extruder]);
#ifdef DUAL_X_CARRIAGE
SERIAL_ECHO(",");
SERIAL_ECHO(extruder_offset[Z_AXIS][tmp_extruder]);
#endif // DUAL_X_CARRIAGE
}
SERIAL_ECHOLN("");
} }
break; if(code_seen('Y'))
#endif //EXTRUDERS and SINGLENOZZLE
case 220: // M220 S<factor in percent>- set speed factor override percentage
{ {
if(code_seen('S')) extruder_offset[Y_AXIS][tmp_extruder] = code_value();
{
feedmultiply = code_value() ;
}
} }
break; #ifdef DUAL_X_CARRIAGE
case 221: // M221 S<factor in percent>- set extrude factor override percentage if(code_seen('Z'))
{ {
if(code_seen('S')) extruder_offset[Z_AXIS][tmp_extruder] = code_value();
}
#endif
SERIAL_ECHO_START;
SERIAL_ECHOPGM(MSG_HOTEND_OFFSET);
for(tmp_extruder = 0; tmp_extruder < EXTRUDERS; tmp_extruder++)
{
SERIAL_ECHO(" ");
SERIAL_ECHO(extruder_offset[X_AXIS][tmp_extruder]);
SERIAL_ECHO(",");
SERIAL_ECHO(extruder_offset[Y_AXIS][tmp_extruder]);
#ifdef DUAL_X_CARRIAGE
SERIAL_ECHO(",");
SERIAL_ECHO(extruder_offset[Z_AXIS][tmp_extruder]);
#endif
}
SERIAL_ECHOLN("");
}break;
#endif //EXTRUDERS
#endif // SINGLENOZZLE
case 220: // M220 S<factor in percent>- set speed factor override percentage
{
if(code_seen('S'))
{
feedmultiply = code_value() ;
}
}
break;
case 221: // M221 S<factor in percent>- set extrude factor override percentage
{
if(code_seen('S'))
{
int tmp_code = code_value();
if (code_seen('T'))
{ {
int tmp_code = code_value(); if(setTargetedHotend(221)){
if (code_seen('T')) break;
{
if(setTargetedHotend(221)){
break;
}
extruder_multiply[tmp_extruder] = tmp_code;
}
else
{
extrudemultiply = tmp_code ;
} }
extruder_multiply[tmp_extruder] = tmp_code;
}
else
{
extrudemultiply = tmp_code ;
} }
} }
break; }
break;
case 226: // M226 P<pin number> S<pin state>- Wait until the specified pin reaches the state required case 226: // M226 P<pin number> S<pin state>- Wait until the specified pin reaches the state required
{ {
if(code_seen('P')) if(code_seen('P')){
{ int pin_number = code_value(); // pin number
int pin_number = code_value(); // pin number int pin_state = -1; // required pin state - default is inverted
int pin_state = -1; // required pin state - default is inverted
if(code_seen('S')) pin_state = code_value(); // required pin state if(code_seen('S')) pin_state = code_value(); // required pin state
if(pin_state >= -1 && pin_state <= 1) if(pin_state >= -1 && pin_state <= 1){
for(int8_t i = 0; i < (int8_t)(sizeof(sensitive_pins)/sizeof(int)); i++)
{ {
for(int8_t i = 0; i < (int8_t)(sizeof(sensitive_pins)/sizeof(int)); i++) if (sensitive_pins[i] == pin_number)
{ {
if (sensitive_pins[i] == pin_number) pin_number = -1;
{ break;
pin_number = -1;
break;
}
} }
}
if (pin_number > -1) if (pin_number > -1)
{ {
st_synchronize(); st_synchronize();
pinMode(pin_number, INPUT);
int target;
switch(pin_state)
{
case 1:
target = HIGH;
break;
case 0:
target = LOW;
break;
case -1:
target = !digitalRead(pin_number);
break;
}
while(digitalRead(pin_number) != target) pinMode(pin_number, INPUT);
{
manage_heater(); int target;
manage_inactivity(); switch(pin_state){
lcd_update(); case 1:
} target = HIGH;
break;
case 0:
target = LOW;
break;
case -1:
target = !digitalRead(pin_number);
break;
}
while(digitalRead(pin_number) != target){
manage_heater();
manage_inactivity();
lcd_update();
} }
} }
} }
} }
break; }
break;
#if NUM_SERVOS > 0 #if NUM_SERVOS > 0
case 280: // M280 - set servo position absolute. P: servo index, S: angle or microseconds case 280: // M280 - set servo position absolute. P: servo index, S: angle or microseconds
{ {
int servo_index = -1; int servo_index = -1;
int servo_position = 0; int servo_position = 0;
if (code_seen('P')) if (code_seen('P'))
servo_index = code_value(); servo_index = code_value();
if (code_seen('S')) if (code_seen('S')) {
{
servo_position = code_value(); servo_position = code_value();
if ((servo_index >= 0) && (servo_index < NUM_SERVOS)) if ((servo_index >= 0) && (servo_index < NUM_SERVOS)) {
{
#if defined (ENABLE_AUTO_BED_LEVELING) && (PROBE_SERVO_DEACTIVATION_DELAY > 0) #if defined (ENABLE_AUTO_BED_LEVELING) && (PROBE_SERVO_DEACTIVATION_DELAY > 0)
servos[servo_index].attach(0); servos[servo_index].attach(0);
#endif #endif
servos[servo_index].write(servo_position); servos[servo_index].write(servo_position);
#if defined (ENABLE_AUTO_BED_LEVELING) && (PROBE_SERVO_DEACTIVATION_DELAY > 0) #if defined (ENABLE_AUTO_BED_LEVELING) && (PROBE_SERVO_DEACTIVATION_DELAY > 0)
delay(PROBE_SERVO_DEACTIVATION_DELAY); delay(PROBE_SERVO_DEACTIVATION_DELAY);
servos[servo_index].detach(); servos[servo_index].detach();
#endif #endif
} }
else else {
{
SERIAL_ECHO_START; SERIAL_ECHO_START;
SERIAL_ECHO("Servo "); SERIAL_ECHO("Servo ");
SERIAL_ECHO(servo_index); SERIAL_ECHO(servo_index);
SERIAL_ECHOLN(" out of range"); SERIAL_ECHOLN(" out of range");
} }
} }
else if (servo_index >= 0) else if (servo_index >= 0) {
{
SERIAL_PROTOCOL(MSG_OK); SERIAL_PROTOCOL(MSG_OK);
SERIAL_PROTOCOL(" Servo "); SERIAL_PROTOCOL(" Servo ");
SERIAL_PROTOCOL(servo_index); SERIAL_PROTOCOL(servo_index);
...@@ -4233,43 +4241,43 @@ Sigma_Exit: ...@@ -4233,43 +4241,43 @@ Sigma_Exit:
} }
} }
break; break;
#endif // NUM_SERVOS > 0 #endif // NUM_SERVOS > 0
#if (LARGE_FLASH == true && ( BEEPER > 0 || defined(ULTRALCD) || defined(LCD_USE_I2C_BUZZER))) #if (LARGE_FLASH == true && ( BEEPER > 0 || defined(ULTRALCD) || defined(LCD_USE_I2C_BUZZER)))
case 300: // M300 case 300: // M300
{
int beepS = code_seen('S') ? code_value() : 110;
int beepP = code_seen('P') ? code_value() : 1000;
if (beepS > 0)
{ {
int beepS = code_seen('S') ? code_value() : 110; #if BEEPER > 0
int beepP = code_seen('P') ? code_value() : 1000;
if (beepS > 0)
{
#if BEEPER > 0
tone(BEEPER, beepS); tone(BEEPER, beepS);
delay(beepP); delay(beepP);
noTone(BEEPER); noTone(BEEPER);
#elif defined(ULTRALCD) #elif defined(ULTRALCD)
lcd_buzz(beepS, beepP); lcd_buzz(beepS, beepP);
#elif defined(LCD_USE_I2C_BUZZER) #elif defined(LCD_USE_I2C_BUZZER)
lcd_buzz(beepP, beepS); lcd_buzz(beepP, beepS);
#endif // defined(ULTRALCD) #endif
}
else
{
delay(beepP);
}
} }
break; else
#endif // M300 {
delay(beepP);
}
}
break;
#endif // M300
#ifdef PIDTEMP #ifdef PIDTEMP
case 301: // M301 case 301: // M301
{ {
if(code_seen('P')) Kp = code_value(); if(code_seen('P')) Kp = code_value();
if(code_seen('I')) Ki = scalePID_i(code_value()); if(code_seen('I')) Ki = scalePID_i(code_value());
if(code_seen('D')) Kd = scalePID_d(code_value()); if(code_seen('D')) Kd = scalePID_d(code_value());
#ifdef PID_ADD_EXTRUSION_RATE #ifdef PID_ADD_EXTRUSION_RATE
if(code_seen('C')) Kc = code_value(); if(code_seen('C')) Kc = code_value();
#endif // PID_ADD_EXTRUSION_RATE #endif
updatePID(); updatePID();
SERIAL_PROTOCOL(MSG_OK); SERIAL_PROTOCOL(MSG_OK);
...@@ -4279,18 +4287,17 @@ Sigma_Exit: ...@@ -4279,18 +4287,17 @@ Sigma_Exit:
SERIAL_PROTOCOL(unscalePID_i(Ki)); SERIAL_PROTOCOL(unscalePID_i(Ki));
SERIAL_PROTOCOL(" d:"); SERIAL_PROTOCOL(" d:");
SERIAL_PROTOCOL(unscalePID_d(Kd)); SERIAL_PROTOCOL(unscalePID_d(Kd));
#ifdef PID_ADD_EXTRUSION_RATE #ifdef PID_ADD_EXTRUSION_RATE
SERIAL_PROTOCOL(" c:"); SERIAL_PROTOCOL(" c:");
//Kc does not have scaling applied above, or in resetting defaults //Kc does not have scaling applied above, or in resetting defaults
SERIAL_PROTOCOL(Kc); SERIAL_PROTOCOL(Kc);
#endif // PID_ADD_EXTRUSION_RATE #endif
SERIAL_PROTOCOLLN(""); SERIAL_PROTOCOLLN("");
} }
break; break;
#endif //PIDTEMP #endif //PIDTEMP
#ifdef PIDTEMPBED
#ifdef PIDTEMPBED case 304: // M304
case 304: // M304
{ {
if(code_seen('P')) bedKp = code_value(); if(code_seen('P')) bedKp = code_value();
if(code_seen('I')) bedKi = scalePID_i(code_value()); if(code_seen('I')) bedKi = scalePID_i(code_value());
...@@ -4307,282 +4314,322 @@ Sigma_Exit: ...@@ -4307,282 +4314,322 @@ Sigma_Exit:
SERIAL_PROTOCOLLN(""); SERIAL_PROTOCOLLN("");
} }
break; break;
#endif //PIDTEMPBED #endif //PIDTEMP
case 240: // M240 Triggers a camera by emulating a Canon RC-1 : http://www.doc-diy.net/photo/rc-1_hacked/
case 240: // M240 Triggers a camera by emulating a Canon RC-1 : http://www.doc-diy.net/photo/rc-1_hacked/ {
{ #ifdef CHDK
#ifdef CHDK
SET_OUTPUT(CHDK); SET_OUTPUT(CHDK);
WRITE(CHDK, HIGH); WRITE(CHDK, HIGH);
chdkHigh = millis(); chdkHigh = millis();
chdkActive = true; chdkActive = true;
#else
#if defined(PHOTOGRAPH_PIN) && PHOTOGRAPH_PIN > -1 #else
const uint8_t NUM_PULSES=16;
#if defined(PHOTOGRAPH_PIN) && PHOTOGRAPH_PIN > -1
const uint8_t NUM_PULSES=16;
const float PULSE_LENGTH=0.01524; const float PULSE_LENGTH=0.01524;
for(int i=0; i < NUM_PULSES; i++) for(int i=0; i < NUM_PULSES; i++) {
{ WRITE(PHOTOGRAPH_PIN, HIGH);
WRITE(PHOTOGRAPH_PIN, HIGH); _delay_ms(PULSE_LENGTH);
_delay_ms(PULSE_LENGTH); WRITE(PHOTOGRAPH_PIN, LOW);
WRITE(PHOTOGRAPH_PIN, LOW); _delay_ms(PULSE_LENGTH);
_delay_ms(PULSE_LENGTH);
} }
delay(7.33); delay(7.33);
for(int i=0; i < NUM_PULSES; i++) for(int i=0; i < NUM_PULSES; i++) {
{ WRITE(PHOTOGRAPH_PIN, HIGH);
WRITE(PHOTOGRAPH_PIN, HIGH); _delay_ms(PULSE_LENGTH);
_delay_ms(PULSE_LENGTH); WRITE(PHOTOGRAPH_PIN, LOW);
WRITE(PHOTOGRAPH_PIN, LOW); _delay_ms(PULSE_LENGTH);
_delay_ms(PULSE_LENGTH);
} }
#endif // PHOTOGRAPH_PIN #endif
#endif // CHDK #endif //chdk end if
} }
break; break;
#ifdef DOGLCD #ifdef DOGLCD
case 250: // M250 Set LCD contrast value: C<value> (value 0..63) case 250: // M250 Set LCD contrast value: C<value> (value 0..63)
{ {
if (code_seen('C')) { if (code_seen('C')) {
lcd_setcontrast( ((int)code_value())&63 ); lcd_setcontrast( ((int)code_value())&63 );
} }
SERIAL_PROTOCOLPGM("lcd contrast value: "); SERIAL_PROTOCOLPGM("lcd contrast value: ");
SERIAL_PROTOCOL(lcd_contrast); SERIAL_PROTOCOL(lcd_contrast);
SERIAL_PROTOCOLLN(""); SERIAL_PROTOCOLLN("");
} }
break; break;
#endif // DOGLCD #endif
#ifdef PREVENT_DANGEROUS_EXTRUDE
#ifdef PREVENT_DANGEROUS_EXTRUDE case 302: // allow cold extrudes, or set the minimum extrude temperature
case 302: // allow cold extrudes, or set the minimum extrude temperature {
{ float temp = .0;
float temp = .0; if (code_seen('S')) temp=code_value();
if (code_seen('S')) temp=code_value(); set_extrude_min_temp(temp);
set_extrude_min_temp(temp); }
} break;
break; #endif
#endif // PREVENT_DANGEROUS_EXTRUDE case 303: // M303 PID autotune
{
case 303: // M303 PID autotune float temp = 150.0;
{ int e=0;
float temp = 150.0; int c=5;
int e=0; if (code_seen('E')) e=code_value();
int c=5; if (e<0)
if (code_seen('E')) e=code_value(); temp=70;
if (e<0) temp=70; if (code_seen('S')) temp=code_value();
if (code_seen('S')) temp=code_value(); if (code_seen('C')) c=code_value();
if (code_seen('C')) c=code_value(); PID_autotune(temp, e, c);
PID_autotune(temp, e, c); }
} break;
break;
#ifdef SCARA #ifdef SCARA
case 360: // M360 SCARA Theta pos1 case 360: // M360 SCARA Theta pos1
{ SERIAL_ECHOLN(" Cal: Theta 0 ");
SERIAL_ECHOLN(" Cal: Theta 0 "); //SoftEndsEnabled = false; // Ignore soft endstops during calibration
//SoftEndsEnabled = false; // Ignore soft endstops during calibration //SERIAL_ECHOLN(" Soft endstops disabled ");
//SERIAL_ECHOLN(" Soft endstops disabled "); if(Stopped == false) {
if(Stopped == false) //get_coordinates(); // For X Y Z E F
{ delta[0] = 0;
//get_coordinates(); // For X Y Z E F delta[1] = 120;
delta[0] = 0; calculate_SCARA_forward_Transform(delta);
delta[1] = 120; destination[0] = delta[0]/axis_scaling[X_AXIS];
calculate_SCARA_forward_Transform(delta); destination[1] = delta[1]/axis_scaling[Y_AXIS];
destination[0] = delta[0]/axis_scaling[X_AXIS];
destination[1] = delta[1]/axis_scaling[Y_AXIS]; prepare_move();
//ClearToSend();
prepare_move(); return;
//ClearToSend();
return;
}
} }
break; break;
case 361: // SCARA Theta pos2 case 361: // SCARA Theta pos2
{ SERIAL_ECHOLN(" Cal: Theta 90 ");
SERIAL_ECHOLN(" Cal: Theta 90 "); //SoftEndsEnabled = false; // Ignore soft endstops during calibration
//SoftEndsEnabled = false; // Ignore soft endstops during calibration //SERIAL_ECHOLN(" Soft endstops disabled ");
//SERIAL_ECHOLN(" Soft endstops disabled "); if(Stopped == false) {
if(Stopped == false) //get_coordinates(); // For X Y Z E F
{ delta[0] = 90;
//get_coordinates(); // For X Y Z E F delta[1] = 130;
delta[0] = 90; calculate_SCARA_forward_Transform(delta);
delta[1] = 130; destination[0] = delta[0]/axis_scaling[X_AXIS];
calculate_SCARA_forward_Transform(delta); destination[1] = delta[1]/axis_scaling[Y_AXIS];
destination[0] = delta[0]/axis_scaling[X_AXIS];
destination[1] = delta[1]/axis_scaling[Y_AXIS]; prepare_move();
//ClearToSend();
prepare_move(); return;
//ClearToSend();
return;
}
} }
break; break;
case 362: // SCARA Psi pos1
case 362: // SCARA Psi pos1 SERIAL_ECHOLN(" Cal: Psi 0 ");
{ //SoftEndsEnabled = false; // Ignore soft endstops during calibration
SERIAL_ECHOLN(" Cal: Psi 0 "); //SERIAL_ECHOLN(" Soft endstops disabled ");
//SoftEndsEnabled = false; // Ignore soft endstops during calibration if(Stopped == false) {
//SERIAL_ECHOLN(" Soft endstops disabled "); //get_coordinates(); // For X Y Z E F
if(Stopped == false) delta[0] = 60;
{ delta[1] = 180;
//get_coordinates(); // For X Y Z E F calculate_SCARA_forward_Transform(delta);
delta[0] = 60; destination[0] = delta[0]/axis_scaling[X_AXIS];
delta[1] = 180; destination[1] = delta[1]/axis_scaling[Y_AXIS];
calculate_SCARA_forward_Transform(delta);
destination[0] = delta[0]/axis_scaling[X_AXIS]; prepare_move();
destination[1] = delta[1]/axis_scaling[Y_AXIS]; //ClearToSend();
return;
prepare_move();
//ClearToSend();
return;
}
} }
break; break;
case 363: // SCARA Psi pos2
case 363: // SCARA Psi pos2 SERIAL_ECHOLN(" Cal: Psi 90 ");
{ //SoftEndsEnabled = false; // Ignore soft endstops during calibration
SERIAL_ECHOLN(" Cal: Psi 90 "); //SERIAL_ECHOLN(" Soft endstops disabled ");
//SoftEndsEnabled = false; // Ignore soft endstops during calibration if(Stopped == false) {
//SERIAL_ECHOLN(" Soft endstops disabled "); //get_coordinates(); // For X Y Z E F
if(Stopped == false) delta[0] = 50;
{ delta[1] = 90;
//get_coordinates(); // For X Y Z E F calculate_SCARA_forward_Transform(delta);
delta[0] = 50; destination[0] = delta[0]/axis_scaling[X_AXIS];
delta[1] = 90; destination[1] = delta[1]/axis_scaling[Y_AXIS];
calculate_SCARA_forward_Transform(delta);
destination[0] = delta[0]/axis_scaling[X_AXIS]; prepare_move();
destination[1] = delta[1]/axis_scaling[Y_AXIS]; //ClearToSend();
return;
prepare_move();
//ClearToSend();
return;
}
} }
break; break;
case 364: // SCARA Psi pos3 (90 deg to Theta)
case 364: // SCARA Psi pos3 (90 deg to Theta) SERIAL_ECHOLN(" Cal: Theta-Psi 90 ");
{ // SoftEndsEnabled = false; // Ignore soft endstops during calibration
SERIAL_ECHOLN(" Cal: Theta-Psi 90 "); //SERIAL_ECHOLN(" Soft endstops disabled ");
// SoftEndsEnabled = false; // Ignore soft endstops during calibration if(Stopped == false) {
//SERIAL_ECHOLN(" Soft endstops disabled "); //get_coordinates(); // For X Y Z E F
if(Stopped == false) delta[0] = 45;
{ delta[1] = 135;
//get_coordinates(); // For X Y Z E F calculate_SCARA_forward_Transform(delta);
delta[0] = 45; destination[0] = delta[0]/axis_scaling[X_AXIS];
delta[1] = 135; destination[1] = delta[1]/axis_scaling[Y_AXIS];
calculate_SCARA_forward_Transform(delta);
destination[0] = delta[0]/axis_scaling[X_AXIS]; prepare_move();
destination[1] = delta[1]/axis_scaling[Y_AXIS]; //ClearToSend();
return;
prepare_move();
//ClearToSend();
return;
}
} }
break; break;
case 365: // M364 Set SCARA scaling for X Y Z
case 365: // M364 Set SCARA scaling for X Y Z for(int8_t i=0; i < 3; i++)
{ {
for(int8_t i=0; i < 3; i++) if(code_seen(axis_codes[i]))
{ {
if(code_seen(axis_codes[i]))
{
axis_scaling[i] = code_value(); axis_scaling[i] = code_value();
}
} }
} }
break; break;
#endif // SCARA #endif // SCARA
case 400: // M400 finish all moves case 400: // M400 finish all moves
{ {
st_synchronize(); st_synchronize();
} }
break; break;
#if defined(ENABLE_AUTO_BED_LEVELING) && defined(SERVO_ENDSTOPS) && not defined(Z_PROBE_SLED) #if defined(ENABLE_AUTO_BED_LEVELING) && defined(SERVO_ENDSTOPS) && not defined(Z_PROBE_SLED)
case 401: case 401:
{ {
engage_z_probe(); // Engage Z Servo endstop if available engage_z_probe(); // Engage Z Servo endstop if available
} }
break; break;
case 402: case 402:
{ {
retract_z_probe(); // Retract Z Servo endstop if enabled retract_z_probe(); // Retract Z Servo endstop if enabled
} }
break; break;
#endif // ENABLE_AUTO_BED_LEVELING #endif // ENABLE_AUTO_BED_LEVELING
case 500: // M500 Store settings in EEPROM #ifdef FILAMENT_SENSOR
{ case 404: //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or display nominal filament width
{
#if (FILWIDTH_PIN > -1)
if(code_seen('N')) filament_width_nominal=code_value();
else{
SERIAL_PROTOCOLPGM("Filament dia (nominal mm):");
SERIAL_PROTOCOLLN(filament_width_nominal);
}
#endif
}
break;
case 405: //M405 Turn on filament sensor for control
{
if(code_seen('D')) meas_delay_cm=code_value();
if(meas_delay_cm> MAX_MEASUREMENT_DELAY)
meas_delay_cm = MAX_MEASUREMENT_DELAY;
if(delay_index2 == -1) //initialize the ring buffer if it has not been done since startup
{
int temp_ratio = widthFil_to_size_ratio();
for (delay_index1=0; delay_index1<(MAX_MEASUREMENT_DELAY+1); ++delay_index1 ){
measurement_delay[delay_index1]=temp_ratio-100; //subtract 100 to scale within a signed byte
}
delay_index1=0;
delay_index2=0;
}
filament_sensor = true ;
//SERIAL_PROTOCOLPGM("Filament dia (measured mm):");
//SERIAL_PROTOCOL(filament_width_meas);
//SERIAL_PROTOCOLPGM("Extrusion ratio(%):");
//SERIAL_PROTOCOL(extrudemultiply);
}
break;
case 406: //M406 Turn off filament sensor for control
{
filament_sensor = false ;
}
break;
case 407: //M407 Display measured filament diameter
{
SERIAL_PROTOCOLPGM("Filament dia (measured mm):");
SERIAL_PROTOCOLLN(filament_width_meas);
}
break;
#endif // FILAMENT_SENSOR
case 500: // M500 Store settings in EEPROM
{
Config_StoreSettings(); Config_StoreSettings();
} }
break; break;
case 501: // M501 Read settings from EEPROM case 501: // M501 Read settings from EEPROM
{ {
Config_RetrieveSettings(); Config_RetrieveSettings();
} }
break; break;
case 502: // M502 Revert to default settings case 502: // M502 Revert to default settings
{ {
Config_ResetDefault(); Config_ResetDefault();
} }
break; break;
case 503: // M503 print settings currently in memory case 503: // M503 print settings currently in memory
{ {
Config_PrintSettings(); Config_PrintSettings();
} }
break; break;
#ifdef ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED
#ifdef ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED case 540:
case 540: {
{
if(code_seen('S')) abort_on_endstop_hit = code_value() > 0; if(code_seen('S')) abort_on_endstop_hit = code_value() > 0;
} }
break; break;
#endif // ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED #endif
#ifdef CUSTOM_M_CODE_SET_Z_PROBE_OFFSET #ifdef CUSTOM_M_CODE_SET_Z_PROBE_OFFSET
case CUSTOM_M_CODE_SET_Z_PROBE_OFFSET: case CUSTOM_M_CODE_SET_Z_PROBE_OFFSET:
{
float value;
if (code_seen('Z'))
{ {
float value; value = code_value();
if (code_seen('Z')) if ((Z_PROBE_OFFSET_RANGE_MIN <= value) && (value <= Z_PROBE_OFFSET_RANGE_MAX))
{ {
value = code_value(); zprobe_zoffset = -value; // compare w/ line 278 of ConfigurationStore.cpp
if ((Z_PROBE_OFFSET_RANGE_MIN <= value) && (value <= Z_PROBE_OFFSET_RANGE_MAX)) SERIAL_ECHO_START;
{ SERIAL_ECHOLNPGM(MSG_ZPROBE_ZOFFSET " " MSG_OK);
zprobe_zoffset = -value; // compare w/ line 278 of ConfigurationStore.cpp SERIAL_PROTOCOLLN("");
SERIAL_ECHO_START;
SERIAL_ECHOLNPGM(MSG_ZPROBE_ZOFFSET " " MSG_OK);
SERIAL_PROTOCOLLN("");
}
else
{
SERIAL_ECHO_START;
SERIAL_ECHOPGM(MSG_ZPROBE_ZOFFSET);
SERIAL_ECHOPGM(MSG_Z_MIN);
SERIAL_ECHO(Z_PROBE_OFFSET_RANGE_MIN);
SERIAL_ECHOPGM(MSG_Z_MAX);
SERIAL_ECHO(Z_PROBE_OFFSET_RANGE_MAX);
SERIAL_PROTOCOLLN("");
}
} }
else else
{ {
SERIAL_ECHO_START;
SERIAL_ECHOPGM(MSG_ZPROBE_ZOFFSET);
SERIAL_ECHOPGM(MSG_Z_MIN);
SERIAL_ECHO(Z_PROBE_OFFSET_RANGE_MIN);
SERIAL_ECHOPGM(MSG_Z_MAX);
SERIAL_ECHO(Z_PROBE_OFFSET_RANGE_MAX);
SERIAL_PROTOCOLLN("");
}
}
else
{
SERIAL_ECHO_START; SERIAL_ECHO_START;
SERIAL_ECHOLNPGM(MSG_ZPROBE_ZOFFSET " : "); SERIAL_ECHOLNPGM(MSG_ZPROBE_ZOFFSET " : ");
SERIAL_ECHO(-zprobe_zoffset); SERIAL_ECHO(-zprobe_zoffset);
SERIAL_PROTOCOLLN(""); SERIAL_PROTOCOLLN("");
}
} }
break; break;
#endif // CUSTOM_M_CODE_SET_Z_PROBE_OFFSET }
#endif // CUSTOM_M_CODE_SET_Z_PROBE_OFFSET
#ifdef FILAMENTCHANGEENABLE #ifdef FILAMENTCHANGEENABLE
case 600: // M600 - Pause for filament change X[pos] Y[pos] Z[relative lift] E[initial retract] L[later retract distance for removal] case 600: //Pause for filament change X[pos] Y[pos] Z[relative lift] E[initial retract] L[later retract distance for removal]
{ {
float target[4]; float target[4];
target[X_AXIS]=current_position[X_AXIS]; target[X_AXIS]=current_position[X_AXIS];
target[Y_AXIS]=current_position[Y_AXIS]; target[Y_AXIS]=current_position[Y_AXIS];
...@@ -4599,9 +4646,9 @@ Sigma_Exit: ...@@ -4599,9 +4646,9 @@ Sigma_Exit:
} }
else else
{ {
#ifdef FILAMENTCHANGE_FIRSTRETRACT #ifdef FILAMENTCHANGE_FIRSTRETRACT
target[E_AXIS]+= FILAMENTCHANGE_FIRSTRETRACT ; target[E_AXIS]+= FILAMENTCHANGE_FIRSTRETRACT ;
#endif // FILAMENTCHANGE_FIRSTRETRACT #endif
} }
plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], feedrate/60, active_extruder, active_driver); plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], feedrate/60, active_extruder, active_driver);
...@@ -4612,9 +4659,9 @@ Sigma_Exit: ...@@ -4612,9 +4659,9 @@ Sigma_Exit:
} }
else else
{ {
#ifdef FILAMENTCHANGE_ZADD #ifdef FILAMENTCHANGE_ZADD
target[Z_AXIS]+= FILAMENTCHANGE_ZADD ; target[Z_AXIS]+= FILAMENTCHANGE_ZADD ;
#endif // FILAMENTCHANGE_ZADD #endif
} }
plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], feedrate/60, active_extruder, active_driver); plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], feedrate/60, active_extruder, active_driver);
...@@ -4625,9 +4672,9 @@ Sigma_Exit: ...@@ -4625,9 +4672,9 @@ Sigma_Exit:
} }
else else
{ {
#ifdef FILAMENTCHANGE_XPOS #ifdef FILAMENTCHANGE_XPOS
target[X_AXIS]= FILAMENTCHANGE_XPOS ; target[X_AXIS]= FILAMENTCHANGE_XPOS ;
#endif // FILAMENTCHANGE_XPOS #endif
} }
if(code_seen('Y')) if(code_seen('Y'))
{ {
...@@ -4635,9 +4682,9 @@ Sigma_Exit: ...@@ -4635,9 +4682,9 @@ Sigma_Exit:
} }
else else
{ {
#ifdef FILAMENTCHANGE_YPOS #ifdef FILAMENTCHANGE_YPOS
target[Y_AXIS]= FILAMENTCHANGE_YPOS ; target[Y_AXIS]= FILAMENTCHANGE_YPOS ;
#endif // FILAMENTCHANGE_YPOS #endif
} }
plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], feedrate/60, active_extruder, active_driver); plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], feedrate/60, active_extruder, active_driver);
...@@ -4648,9 +4695,9 @@ Sigma_Exit: ...@@ -4648,9 +4695,9 @@ Sigma_Exit:
} }
else else
{ {
#ifdef FILAMENTCHANGE_FINALRETRACT #ifdef FILAMENTCHANGE_FINALRETRACT
target[E_AXIS]+= FILAMENTCHANGE_FINALRETRACT ; target[E_AXIS]+= FILAMENTCHANGE_FINALRETRACT ;
#endif // FILAMENTCHANGE_FINALRETRACT #endif
} }
plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], feedrate/60, active_extruder, active_driver); plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], feedrate/60, active_extruder, active_driver);
...@@ -4910,15 +4957,12 @@ Sigma_Exit: ...@@ -4910,15 +4957,12 @@ Sigma_Exit:
else if (dual_x_carriage_mode == DXC_DUPLICATION_MODE) else if (dual_x_carriage_mode == DXC_DUPLICATION_MODE)
{ {
active_extruder_parked = (active_extruder == 0); // this triggers the second extruder to move into the duplication position active_extruder_parked = (active_extruder == 0); // this triggers the second extruder to move into the duplication position
if (active_extruder == 0 || active_extruder_parked) { if (active_extruder == 0 || active_extruder_parked)
current_position[X_AXIS] = inactive_extruder_x_pos; current_position[X_AXIS] = inactive_extruder_x_pos;
}
else else
{
current_position[X_AXIS] = destination[X_AXIS] + duplicate_extruder_x_offset; current_position[X_AXIS] = destination[X_AXIS] + duplicate_extruder_x_offset;
inactive_extruder_x_pos = destination[X_AXIS]; inactive_extruder_x_pos = destination[X_AXIS];
extruder_duplication_enabled = false; extruder_duplication_enabled = false;
}
} }
else else
{ {
...@@ -5707,7 +5751,7 @@ bool setTargetedHotend(int code){ ...@@ -5707,7 +5751,7 @@ bool setTargetedHotend(int code){
tmp_extruder = active_extruder; tmp_extruder = active_extruder;
if(code_seen('T')) { if(code_seen('T')) {
tmp_extruder = code_value(); tmp_extruder = code_value();
if(tmp_extruder >= EXTRUDERS){ if(tmp_extruder >= EXTRUDERS) {
SERIAL_ECHO_START; SERIAL_ECHO_START;
switch(code){ switch(code){
case 104: case 104:
......
...@@ -628,6 +628,15 @@ ...@@ -628,6 +628,15 @@
#define E1_DIR_PIN 34 #define E1_DIR_PIN 34
#define E1_ENABLE_PIN 30 #define E1_ENABLE_PIN 30
#if MOTHERBOARD == 34 //FMM added for Filament Extruder
#ifdef FILAMENT_SENSOR
//define analog pin for the filament width sensor input
//Use the RAMPS 1.4 Analog input 5 on the AUX2 connector
#define FILWIDTH_PIN 5
#endif
#endif
#if MOTHERBOARD == 68 #if MOTHERBOARD == 68
#define E2_STEP_PIN 23 #define E2_STEP_PIN 23
#define E2_DIR_PIN 25 #define E2_DIR_PIN 25
...@@ -1762,6 +1771,9 @@ ...@@ -1762,6 +1771,9 @@
#define Z_STOP_PIN 36 #define Z_STOP_PIN 36
#define TEMP_0_PIN 1 // Extruder / Analog pin numbering #define TEMP_0_PIN 1 // Extruder / Analog pin numbering
#define TEMP_BED_PIN 0 // Bed / Analog pin numbering #define TEMP_BED_PIN 0 // Bed / Analog pin numbering
#ifdef FILAMENT_SENSOR
#define FILWIDTH_PIN 2
#endif //FILAMENT_SENSOR
#endif #endif
#define TEMP_1_PIN -1 #define TEMP_1_PIN -1
...@@ -2396,6 +2408,10 @@ DaveX plan for Teensylu/printrboard-type pinouts (ref teensylu & sprinter) for a ...@@ -2396,6 +2408,10 @@ DaveX plan for Teensylu/printrboard-type pinouts (ref teensylu & sprinter) for a
#endif #endif
#endif //ULTRA_LCD #endif //ULTRA_LCD
#ifdef FILAMENT_SENSOR
//Filip added pin for Filament sensor analog input
#define FILWIDTH_PIN 3
#endif //FILAMENT_SENSOR
#endif #endif
......
...@@ -120,6 +120,10 @@ static long x_segment_time[3]={MAX_FREQ_TIME + 1,0,0}; // Segment times (in ...@@ -120,6 +120,10 @@ static long x_segment_time[3]={MAX_FREQ_TIME + 1,0,0}; // Segment times (in
static long y_segment_time[3]={MAX_FREQ_TIME + 1,0,0}; static long y_segment_time[3]={MAX_FREQ_TIME + 1,0,0};
#endif #endif
#ifdef FILAMENT_SENSOR
static char meas_sample; //temporary variable to hold filament measurement sample
#endif
// Returns the index of the next block in the ring buffer // Returns the index of the next block in the ring buffer
// NOTE: Removed modulo (%) operator, which uses an expensive divide and multiplication. // NOTE: Removed modulo (%) operator, which uses an expensive divide and multiplication.
static int8_t next_block_index(int8_t block_index) { static int8_t next_block_index(int8_t block_index) {
...@@ -624,10 +628,10 @@ block->steps_y = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-positi ...@@ -624,10 +628,10 @@ block->steps_y = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-positi
} }
block->fan_speed = fanSpeed; block->fan_speed = fanSpeed;
#ifdef BARICUDA #ifdef BARICUDA
block->valve_pressure = ValvePressure; block->valve_pressure = ValvePressure;
block->e_to_p_pressure = EtoPPressure; block->e_to_p_pressure = EtoPPressure;
#endif #endif
// Compute direction bits for this block // Compute direction bits for this block
block->direction_bits = 0; block->direction_bits = 0;
...@@ -662,16 +666,16 @@ block->steps_y = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-positi ...@@ -662,16 +666,16 @@ block->steps_y = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-positi
block->active_driver = driver; block->active_driver = driver;
//enable active axes //enable active axes
#ifdef COREXY #ifdef COREXY
if((block->steps_x != 0) || (block->steps_y != 0)) if((block->steps_x != 0) || (block->steps_y != 0))
{ {
enable_x(); enable_x();
enable_y(); enable_y();
} }
#else #else
if(block->steps_x != 0) enable_x(); if(block->steps_x != 0) enable_x();
if(block->steps_y != 0) enable_y(); if(block->steps_y != 0) enable_y();
#endif // COREXY #endif // COREXY
#ifndef Z_LATE_ENABLE #ifndef Z_LATE_ENABLE
if(block->steps_z != 0) enable_z(); if(block->steps_z != 0) enable_z();
#endif #endif
...@@ -742,13 +746,13 @@ block->steps_y = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-positi ...@@ -742,13 +746,13 @@ block->steps_y = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-positi
} }
float delta_mm[4]; float delta_mm[4];
#ifndef COREXY #ifndef COREXY
delta_mm[X_AXIS] = (target[X_AXIS]-position[X_AXIS])/axis_steps_per_unit[X_AXIS]; delta_mm[X_AXIS] = (target[X_AXIS]-position[X_AXIS])/axis_steps_per_unit[X_AXIS];
delta_mm[Y_AXIS] = (target[Y_AXIS]-position[Y_AXIS])/axis_steps_per_unit[Y_AXIS]; delta_mm[Y_AXIS] = (target[Y_AXIS]-position[Y_AXIS])/axis_steps_per_unit[Y_AXIS];
#else #else
delta_mm[X_AXIS] = ((target[X_AXIS]-position[X_AXIS]) + (target[Y_AXIS]-position[Y_AXIS]))/axis_steps_per_unit[X_AXIS]; delta_mm[X_AXIS] = ((target[X_AXIS]-position[X_AXIS]) + (target[Y_AXIS]-position[Y_AXIS]))/axis_steps_per_unit[X_AXIS];
delta_mm[Y_AXIS] = ((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-position[Y_AXIS]))/axis_steps_per_unit[Y_AXIS]; delta_mm[Y_AXIS] = ((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-position[Y_AXIS]))/axis_steps_per_unit[Y_AXIS];
#endif // COREXY #endif // COREXY
delta_mm[Z_AXIS] = (target[Z_AXIS]-position[Z_AXIS])/axis_steps_per_unit[Z_AXIS]; delta_mm[Z_AXIS] = (target[Z_AXIS]-position[Z_AXIS])/axis_steps_per_unit[Z_AXIS];
delta_mm[E_AXIS] = ((target[E_AXIS]-position[E_AXIS])/axis_steps_per_unit[active_extruder+3])*volumetric_multiplier[active_extruder]*extrudemultiply/100.0; delta_mm[E_AXIS] = ((target[E_AXIS]-position[E_AXIS])/axis_steps_per_unit[active_extruder+3])*volumetric_multiplier[active_extruder]*extrudemultiply/100.0;
if ( block->steps_x <=dropsegments && block->steps_y <=dropsegments && block->steps_z <=dropsegments ) if ( block->steps_x <=dropsegments && block->steps_y <=dropsegments && block->steps_z <=dropsegments )
...@@ -792,6 +796,49 @@ block->steps_y = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-positi ...@@ -792,6 +796,49 @@ block->steps_y = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-positi
block->nominal_speed = block->millimeters * inverse_second; // (mm/sec) Always > 0 block->nominal_speed = block->millimeters * inverse_second; // (mm/sec) Always > 0
block->nominal_rate = ceil(block->step_event_count * inverse_second); // (step/sec) Always > 0 block->nominal_rate = ceil(block->step_event_count * inverse_second); // (step/sec) Always > 0
#ifdef FILAMENT_SENSOR
//FMM update ring buffer used for delay with filament measurements
if((extruder==FILAMENT_SENSOR_EXTRUDER_NUM) && (delay_index2 > -1)) //only for extruder with filament sensor and if ring buffer is initialized
{
delay_dist = delay_dist + delta_mm[E_AXIS]; //increment counter with next move in e axis
while (delay_dist >= (10*(MAX_MEASUREMENT_DELAY+1))) //check if counter is over max buffer size in mm
delay_dist = delay_dist - 10*(MAX_MEASUREMENT_DELAY+1); //loop around the buffer
while (delay_dist<0)
delay_dist = delay_dist + 10*(MAX_MEASUREMENT_DELAY+1); //loop around the buffer
delay_index1=delay_dist/10.0; //calculate index
//ensure the number is within range of the array after converting from floating point
if(delay_index1<0)
delay_index1=0;
else if (delay_index1>MAX_MEASUREMENT_DELAY)
delay_index1=MAX_MEASUREMENT_DELAY;
if(delay_index1 != delay_index2) //moved index
{
meas_sample=widthFil_to_size_ratio()-100; //subtract off 100 to reduce magnitude - to store in a signed char
}
while( delay_index1 != delay_index2)
{
delay_index2 = delay_index2 + 1;
if(delay_index2>MAX_MEASUREMENT_DELAY)
delay_index2=delay_index2-(MAX_MEASUREMENT_DELAY+1); //loop around buffer when incrementing
if(delay_index2<0)
delay_index2=0;
else if (delay_index2>MAX_MEASUREMENT_DELAY)
delay_index2=MAX_MEASUREMENT_DELAY;
measurement_delay[delay_index2]=meas_sample;
}
}
#endif
// Calculate and limit speed in mm/sec for each axis // Calculate and limit speed in mm/sec for each axis
float current_speed[4]; float current_speed[4];
float speed_factor = 1.0; //factor <=1 do decrease speed float speed_factor = 1.0; //factor <=1 do decrease speed
......
...@@ -80,7 +80,10 @@ unsigned char soft_pwm_bed; ...@@ -80,7 +80,10 @@ unsigned char soft_pwm_bed;
#ifdef BABYSTEPPING #ifdef BABYSTEPPING
volatile int babystepsTodo[3]={0,0,0}; volatile int babystepsTodo[3]={0,0,0};
#endif #endif
#ifdef FILAMENT_SENSOR
int current_raw_filwidth = 0; //Holds measured filament diameter - one extruder only
#endif
//=========================================================================== //===========================================================================
//=============================private variables============================ //=============================private variables============================
//=========================================================================== //===========================================================================
...@@ -205,6 +208,9 @@ static void updateTemperaturesFromRawValues(); ...@@ -205,6 +208,9 @@ static void updateTemperaturesFromRawValues();
#define SOFT_PWM_SCALE 0 #define SOFT_PWM_SCALE 0
#endif #endif
#ifdef FILAMENT_SENSOR
static int meas_shift_index; //used to point to a delayed sample in buffer for filament width sensor
#endif
//=========================================================================== //===========================================================================
//============================= functions ============================ //============================= functions ============================
//=========================================================================== //===========================================================================
...@@ -658,6 +664,28 @@ void manage_heater() ...@@ -658,6 +664,28 @@ void manage_heater()
} }
#endif #endif
#endif #endif
//code for controlling the extruder rate based on the width sensor
#ifdef FILAMENT_SENSOR
if(filament_sensor)
{
meas_shift_index=delay_index1-meas_delay_cm;
if(meas_shift_index<0)
meas_shift_index = meas_shift_index + (MAX_MEASUREMENT_DELAY+1); //loop around buffer if needed
//get the delayed info and add 100 to reconstitute to a percent of the nominal filament diameter
//then square it to get an area
if(meas_shift_index<0)
meas_shift_index=0;
else if (meas_shift_index>MAX_MEASUREMENT_DELAY)
meas_shift_index=MAX_MEASUREMENT_DELAY;
volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] = pow((float)(100+measurement_delay[meas_shift_index])/100.0,2);
if (volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] <0.01)
volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]=0.01;
}
#endif
} }
#define PGM_RD_W(x) (short)pgm_read_word(&x) #define PGM_RD_W(x) (short)pgm_read_word(&x)
...@@ -756,6 +784,9 @@ static void updateTemperaturesFromRawValues() ...@@ -756,6 +784,9 @@ static void updateTemperaturesFromRawValues()
#ifdef TEMP_SENSOR_1_AS_REDUNDANT #ifdef TEMP_SENSOR_1_AS_REDUNDANT
redundant_temperature = analog2temp(redundant_temperature_raw, 1); redundant_temperature = analog2temp(redundant_temperature_raw, 1);
#endif #endif
#ifdef FILAMENT_SENSOR && (FILWIDTH_PIN > -1) //check if a sensor is supported
filament_width_meas = analog2widthFil();
#endif
//Reset the watchdog after we know we have a temperature measurement. //Reset the watchdog after we know we have a temperature measurement.
watchdog_reset(); watchdog_reset();
...@@ -764,6 +795,36 @@ static void updateTemperaturesFromRawValues() ...@@ -764,6 +795,36 @@ static void updateTemperaturesFromRawValues()
CRITICAL_SECTION_END; CRITICAL_SECTION_END;
} }
// For converting raw Filament Width to milimeters
#ifdef FILAMENT_SENSOR
float analog2widthFil() {
return current_raw_filwidth/16383.0*5.0;
//return current_raw_filwidth;
}
// For converting raw Filament Width to a ratio
int widthFil_to_size_ratio() {
float temp;
temp=filament_width_meas;
if(filament_width_meas<MEASURED_LOWER_LIMIT)
temp=filament_width_nominal; //assume sensor cut out
else if (filament_width_meas>MEASURED_UPPER_LIMIT)
temp= MEASURED_UPPER_LIMIT;
return(filament_width_nominal/temp*100);
}
#endif
void tp_init() void tp_init()
{ {
#if (MOTHERBOARD == 80) && ((TEMP_SENSOR_0==-1)||(TEMP_SENSOR_1==-1)||(TEMP_SENSOR_2==-1)||(TEMP_SENSOR_BED==-1)) #if (MOTHERBOARD == 80) && ((TEMP_SENSOR_0==-1)||(TEMP_SENSOR_1==-1)||(TEMP_SENSOR_2==-1)||(TEMP_SENSOR_BED==-1))
...@@ -885,6 +946,17 @@ void tp_init() ...@@ -885,6 +946,17 @@ void tp_init()
#endif #endif
#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
// Use timer0 for temperature measurement // Use timer0 for temperature measurement
// Interleave temperature interrupt with millies interrupt // Interleave temperature interrupt with millies interrupt
OCR0B = 128; OCR0B = 128;
...@@ -1240,7 +1312,7 @@ ISR(TIMER0_COMPB_vect) ...@@ -1240,7 +1312,7 @@ ISR(TIMER0_COMPB_vect)
static unsigned long raw_temp_2_value = 0; static unsigned long raw_temp_2_value = 0;
static unsigned long raw_temp_3_value = 0; static unsigned long raw_temp_3_value = 0;
static unsigned long raw_temp_bed_value = 0; static unsigned long raw_temp_bed_value = 0;
static unsigned char temp_state = 10; static unsigned char temp_state = 12;
static unsigned char pwm_count = (1 << SOFT_PWM_SCALE); static unsigned char pwm_count = (1 << SOFT_PWM_SCALE);
static unsigned char soft_pwm_0; static unsigned char soft_pwm_0;
#ifndef SINGLENOZZLE #ifndef SINGLENOZZLE
...@@ -1258,6 +1330,10 @@ ISR(TIMER0_COMPB_vect) ...@@ -1258,6 +1330,10 @@ ISR(TIMER0_COMPB_vect)
static unsigned char soft_pwm_b; static unsigned char soft_pwm_b;
#endif #endif
#if defined(FILWIDTH_PIN) &&(FILWIDTH_PIN > -1)
static unsigned long raw_filwidth_value = 0; //added for filament width sensor
#endif
if(pwm_count == 0){ if(pwm_count == 0){
soft_pwm_0 = soft_pwm[0]; soft_pwm_0 = soft_pwm[0];
if(soft_pwm_0 > 0) { if(soft_pwm_0 > 0) {
...@@ -1415,10 +1491,39 @@ ISR(TIMER0_COMPB_vect) ...@@ -1415,10 +1491,39 @@ ISR(TIMER0_COMPB_vect)
#if defined(TEMP_3_PIN) && (TEMP_3_PIN > -1) #if defined(TEMP_3_PIN) && (TEMP_3_PIN > -1)
raw_temp_3_value += ADC; raw_temp_3_value += ADC;
#endif #endif
temp_state = 0; temp_state = 10; //change so that Filament Width is also measured
temp_count++; temp_count++;
break; break;
case 10: //Startup, delay initial temp reading a tiny bit so the hardware can settle. case 10: //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 = 11;
break;
case 11: //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 = 0;
temp_count++;
break;
case 12: //Startup, delay initial temp reading a tiny bit so the hardware can settle.
temp_state = 0; temp_state = 0;
break; break;
// default: // default:
...@@ -1427,7 +1532,7 @@ ISR(TIMER0_COMPB_vect) ...@@ -1427,7 +1532,7 @@ ISR(TIMER0_COMPB_vect)
// break; // break;
} }
if(temp_count >= OVERSAMPLENR) // 8 * 16 * 1/(16000000/64/256) = 131ms. if(temp_count >= OVERSAMPLENR) // 12 * 16 * 1/(16000000/64/256) = 197ms.
{ {
if (!temp_meas_ready) //Only update the raw values if they have been read. Else we could be updating them during reading. if (!temp_meas_ready) //Only update the raw values if they have been read. Else we could be updating them during reading.
{ {
...@@ -1448,6 +1553,12 @@ ISR(TIMER0_COMPB_vect) ...@@ -1448,6 +1553,12 @@ ISR(TIMER0_COMPB_vect)
#endif #endif
current_temperature_bed_raw = raw_temp_bed_value; current_temperature_bed_raw = raw_temp_bed_value;
} }
//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_meas_ready = true;
temp_count = 0; temp_count = 0;
......
...@@ -236,6 +236,10 @@ M Codes ...@@ -236,6 +236,10 @@ M Codes
* M400 - Finish all moves * M400 - Finish all moves
* M401 - Lower z-probe if present * M401 - Lower z-probe if present
* M402 - Raise z-probe if present * M402 - Raise z-probe if present
* M404 - N<dia in mm> Enter the nominal filament width (3mm, 1.75mm ) or will display nominal filament width without parameters
* M405 - Turn on Filament Sensor extrusion control. Optional D<delay in cm> to set delay in centimeters between sensor and extruder
* M406 - Turn off Filament Sensor extrusion control
* M407 - Displays measured filament diameter
* M500 - stores paramters in EEPROM * M500 - stores paramters in EEPROM
* M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). * M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily).
* M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. * M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment