#include "libs/StreamOutput.h"
#include "Gcode.h"
#include "checksumm.h"
-#include "Pauser.h"
#include "Config.h"
#include "ConfigValue.h"
#include "SDFAT.h"
this->register_for_event(ON_GET_PUBLIC_DATA);
this->register_for_event(ON_SET_PUBLIC_DATA);
this->register_for_event(ON_GCODE_RECEIVED);
+ this->register_for_event(ON_HALT);
this->on_boot_gcode = THEKERNEL->config->value(on_boot_gcode_checksum)->by_default("/sd/on_boot.gcode")->as_string();
this->on_boot_gcode_enable = THEKERNEL->config->value(on_boot_gcode_enable_checksum)->by_default(true)->as_bool();
this->leave_heaters_on = THEKERNEL->config->value(leave_heaters_on_suspend_checksum)->by_default(false)->as_bool();
}
+void Player::on_halt(void* argument)
+{
+ if(argument == nullptr && this->playing_file ) {
+ abort_command("1", &(StreamOutput::NullStream));
+ }
+}
+
void Player::on_second_tick(void *)
{
if(this->playing_file) this->elapsed_secs++;
} else if (gcode->m == 23) { // select file
this->filename = "/sd/" + args; // filename is whatever is in args
- this->current_stream = &(StreamOutput::NullStream);
+ this->current_stream = nullptr;
if(this->current_file_handler != NULL) {
this->playing_file = false;
} else {
this->filename = currentfn;
this->file_size = old_size;
- this->current_stream = &(StreamOutput::NullStream);
+ this->current_stream = nullptr;
}
}
} else {
} else if (gcode->m == 32) { // select file and start print
// Get filename
this->filename = "/sd/" + args; // filename is whatever is in args including spaces
- this->current_stream = &(StreamOutput::NullStream);
+ this->current_stream = nullptr;
if(this->current_file_handler != NULL) {
this->playing_file = false;
this->played_cnt = 0;
this->elapsed_secs = 0;
- } else if (gcode->m == 600) { // suspend print, Not entirely Marlin compliant
- this->suspend_command("", gcode->stream);
+ } else if (gcode->m == 600) { // suspend print, Not entirely Marlin compliant, M600.1 will leave the heaters on
+ this->suspend_command((gcode->subcode == 1)?"h":"", gcode->stream);
} else if (gcode->m == 601) { // resume print
this->resume_command("", gcode->stream);
}
+
+ }else if(gcode->has_g) {
+ if(gcode->g == 28) { // homing cancels suspend
+ if(this->suspended) {
+ // clean up
+ this->suspended= false;
+ THEROBOT->pop_state();
+ this->saved_temperatures.clear();
+ this->was_playing_file= false;
+ this->suspend_loops= 0;
+ }
+ }
}
}
// Output to the current stream if we were passed the -v ( verbose ) option
if( options.find_first_of("Vv") == string::npos ) {
- this->current_stream = &(StreamOutput::NullStream);
+ this->current_stream = nullptr;
} else {
// we send to the kernels stream as it cannot go away
this->current_stream = THEKERNEL->streams;
THEKERNEL->conveyor->flush_queue();
// now the position will think it is at the last received pos, so we need to do FK to get the actuator position and reset the current position
- THEKERNEL->robot->reset_position_from_current_actuator_position();
+ THEROBOT->reset_position_from_current_actuator_position();
+ stream->printf("Aborted playing or paused file. Please turn any heaters off manually\r\n");
}
- stream->printf("Aborted playing or paused file. Please turn any heaters off manually\r\n");
}
void Player::on_main_loop(void *argument)
if( this->playing_file ) {
if(THEKERNEL->is_halted()) {
- abort_command("1", &(StreamOutput::NullStream));
return;
}
}
if(len == 1) continue; // empty line
- this->current_stream->printf("%s", buf);
+ if(this->current_stream != nullptr) {
+ this->current_stream->printf("%s", buf);
+ }
+
struct SerialMessage message;
message.message = buf;
- message.stream = this->current_stream;
+ message.stream = this->current_stream == nullptr ? &(StreamOutput::NullStream) : this->current_stream;
// waits for the queue to have enough room
THEKERNEL->call_event(ON_CONSOLE_LINE_RECEIVED, &message);
} else {
// discard long line
- this->current_stream->printf("Warning: Discarded long line\n");
+ if(this->current_stream != nullptr) { this->current_stream->printf("Warning: Discarded long line\n"); }
discard = true;
}
}
stream->printf("Suspending print, waiting for queue to empty...\n");
+ // override the leave_heaters_on setting
+ this->override_leave_heaters_on= (parameters == "h");
+
suspended= true;
if( this->playing_file ) {
// pause an sd print
// need to use streams here as the original stream may have changed
THEKERNEL->streams->printf("// Waiting for queue to empty (Host must stop sending)...\n");
// wait for queue to empty
- THEKERNEL->conveyor->wait_for_empty_queue();
+ THEKERNEL->conveyor->wait_for_idle();
THEKERNEL->streams->printf("// Saving current state...\n");
// save current XYZ position
- THEKERNEL->robot->get_axis_position(this->saved_position);
+ THEROBOT->get_axis_position(this->saved_position);
// save current extruder state
PublicData::set_value( extruder_checksum, save_state_checksum, nullptr );
// save state use M120
- THEKERNEL->robot->push_state();
+ THEROBOT->push_state();
// TODO retract by optional amount...
this->saved_temperatures.clear();
- if(!this->leave_heaters_on) {
+ if(!this->leave_heaters_on && !this->override_leave_heaters_on) {
// save current temperatures, get a vector of all the controllers data
std::vector<struct pad_temperature> controllers;
bool ok = PublicData::get_value(temperature_control_checksum, poll_controls_checksum, &controllers);
if(THEKERNEL->is_halted()) {
// abort temp wait and rest of resume
THEKERNEL->streams->printf("Resume aborted by kill\n");
- THEKERNEL->robot->pop_state();
+ THEROBOT->pop_state();
this->saved_temperatures.clear();
suspended= false;
return;
// Restore position
stream->printf("Restoring saved XYZ positions and state...\n");
- THEKERNEL->robot->pop_state();
- bool abs_mode= THEKERNEL->robot->absolute_mode; // what mode we were in
+ THEROBOT->pop_state();
+ bool abs_mode= THEROBOT->absolute_mode; // what mode we were in
// force absolute mode for restoring position, then set to the saved relative/absolute mode
- THEKERNEL->robot->absolute_mode= true;
+ THEROBOT->absolute_mode= true;
{
+ // NOTE position was saved in MCS so must use G53 to restore position
char buf[128];
- int n = snprintf(buf, sizeof(buf), "G1 X%f Y%f Z%f", saved_position[0], saved_position[1], saved_position[2]);
- string g(buf, n);
- Gcode gcode(g, &(StreamOutput::NullStream));
- THEKERNEL->call_event(ON_GCODE_RECEIVED, &gcode );
+ snprintf(buf, sizeof(buf), "G53 G0 X%f Y%f Z%f", saved_position[0], saved_position[1], saved_position[2]);
+ struct SerialMessage message;
+ message.message = buf;
+ message.stream = &(StreamOutput::NullStream);
+ THEKERNEL->call_event(ON_CONSOLE_LINE_RECEIVED, &message );
}
- THEKERNEL->robot->absolute_mode= abs_mode;
+ THEROBOT->absolute_mode= abs_mode;
// restore extruder state
PublicData::set_value( extruder_checksum, restore_state_checksum, nullptr );