# Only needed on a smoothieboard
currentcontrol_module_enable true #
+
+return_error_on_unhandled_gcode true #
+
if (gcode->has_g){
if (gcode->g == 4){
+ gcode->mark_as_taken();
bool updated = false;
if (gcode->has_letter('P')) {
updated = true;
// Called when the module has just been loaded
void GcodeDispatch::on_module_loaded() {
+ if( this->kernel->config->value( return_error_on_unhandled_gcode_checksum )->by_default(false)->as_bool() == false )
+ return_error_on_unhandled_gcode = false;
+ else
+ return_error_on_unhandled_gcode = true;
+
this->register_for_event(ON_CONSOLE_LINE_RECEIVED);
currentline = -1;
}
this->kernel->call_event(ON_GCODE_RECEIVED, gcode );
if (gcode->add_nl)
new_message.stream->printf("\r\n");
- new_message.stream->printf("ok\r\n");
+ if ( return_error_on_unhandled_gcode == true && gcode->accepted_by_module == false)
+ new_message.stream->printf("error: Command hasn't been processed.\r\n");
+ else
+ new_message.stream->printf("ok\r\n");
delete gcode;
#include "utils/Gcode.h"
#include "libs/StreamOutput.h"
+#define return_error_on_unhandled_gcode_checksum CHECKSUM("return_error_on_unhandled_gcode")
class GcodeDispatch : public Module {
public:
virtual void on_module_loaded();
virtual void on_console_line_received(void* line);
+ bool return_error_on_unhandled_gcode;
private:
int currentline;
};
Gcode::Gcode(const string& command, StreamOutput* stream) : command(command), m(0), g(0), add_nl(false), stream(stream) {
prepare_cached_values();
this->millimeters_of_travel = 0L;
+ this->accepted_by_module=false;
}
Gcode::Gcode(const Gcode& to_copy){
this->g = to_copy.g;
this->add_nl = to_copy.add_nl;
this->stream = to_copy.stream;
+ this->accepted_by_module=false;
}
Gcode& Gcode::operator= (const Gcode& to_copy){
this->add_nl = to_copy.add_nl;
this->stream = to_copy.stream;
}
+ this->accepted_by_module=false;
return *this;
}
this->has_m = false;
}
}
+
+void Gcode::mark_as_taken(){
+ this->accepted_by_module = true;
+}
\ No newline at end of file
int get_num_args();
void prepare_cached_values();
+ void mark_as_taken();
string command;
double millimeters_of_travel;
bool add_nl;
StreamOutput* stream;
+ bool accepted_by_module;
};
#endif
//G-letter Gcodes are mostly what the Robot module is interrested in, other modules also catch the gcode event and do stuff accordingly
if( gcode->has_g){
switch( gcode->g ){
- case 0: this->motion_mode = MOTION_MODE_SEEK; break;
- case 1: this->motion_mode = MOTION_MODE_LINEAR; break;
- case 2: this->motion_mode = MOTION_MODE_CW_ARC; break;
- case 3: this->motion_mode = MOTION_MODE_CCW_ARC; break;
- case 17: this->select_plane(X_AXIS, Y_AXIS, Z_AXIS); break;
- case 18: this->select_plane(X_AXIS, Z_AXIS, Y_AXIS); break;
- case 19: this->select_plane(Y_AXIS, Z_AXIS, X_AXIS); break;
- case 20: this->inch_mode = true; break;
- case 21: this->inch_mode = false; break;
- case 90: this->absolute_mode = true; break;
- case 91: this->absolute_mode = false; break;
+ case 0: this->motion_mode = MOTION_MODE_SEEK; gcode->mark_as_taken(); break;
+ case 1: this->motion_mode = MOTION_MODE_LINEAR; gcode->mark_as_taken(); break;
+ case 2: this->motion_mode = MOTION_MODE_CW_ARC; gcode->mark_as_taken(); break;
+ case 3: this->motion_mode = MOTION_MODE_CCW_ARC; gcode->mark_as_taken(); break;
+ case 17: this->select_plane(X_AXIS, Y_AXIS, Z_AXIS); gcode->mark_as_taken(); break;
+ case 18: this->select_plane(X_AXIS, Z_AXIS, Y_AXIS); gcode->mark_as_taken(); break;
+ case 19: this->select_plane(Y_AXIS, Z_AXIS, X_AXIS); gcode->mark_as_taken(); break;
+ case 20: this->inch_mode = true; gcode->mark_as_taken(); break;
+ case 21: this->inch_mode = false; gcode->mark_as_taken(); break;
+ case 90: this->absolute_mode = true; gcode->mark_as_taken(); break;
+ case 91: this->absolute_mode = false; gcode->mark_as_taken(); break;
case 92: {
if(gcode->get_num_args() == 0){
clear_vector(this->last_milestone);
}
memcpy(this->current_position, this->last_milestone, sizeof(double)*3); // current_position[] = last_milestone[];
this->arm_solution->millimeters_to_steps(this->current_position, this->kernel->planner->position);
+ gcode->mark_as_taken();
return; // TODO: Wait until queue empty
}
}
this->arm_solution->millimeters_to_steps(this->current_position, this->kernel->planner->position);
gcode->stream->printf("X:%g Y:%g Z:%g F:%g ", steps[0], steps[1], steps[2], seconds_per_minute);
gcode->add_nl = true;
+ gcode->mark_as_taken();
return;
case 114: gcode->stream->printf("C: X:%1.3f Y:%1.3f Z:%1.3f ",
from_millimeters(this->current_position[0]),
from_millimeters(this->current_position[1]),
from_millimeters(this->current_position[2]));
gcode->add_nl = true;
+ gcode->mark_as_taken();
return;
case 220: // M220 - speed override percentage
+ gcode->mark_as_taken();
if (gcode->has_letter('S'))
{
double factor = gcode->get_value('S');
if( gcode->has_m){
if( gcode->m == 17 ){
this->turn_enable_pins_on();
+ gcode->mark_as_taken();
}
if( gcode->m == 84 || gcode->m == 18 ){
this->turn_enable_pins_off();
+ gcode->mark_as_taken();
}
}
}
{
if( gcode->g == 28 )
{
+ gcode->mark_as_taken();
// G28 is received, we have homing to do
// First wait for the queue to be empty
switch(gcode->m){
case 119:
gcode->stream->printf("X min:%d max:%d Y min:%d max:%d Z min:%d max:%d\n", this->pins[0].get(), this->pins[3].get(), this->pins[1].get(), this->pins[4].get(), this->pins[2].get(), this->pins[5].get() );
+ gcode->mark_as_taken();
break;
}
}
if (gcode->m == 114){
gcode->stream->printf("E:%4.1f ", this->current_position);
gcode->add_nl = true;
+ gcode->mark_as_taken();
}
if (gcode->m == 92 ){
double spm = this->steps_per_millimeter;
spm = gcode->get_value('E');
gcode->stream->printf("E:%g ", spm);
gcode->add_nl = true;
+ gcode->mark_as_taken();
}
}
// Gcodes to pass along to on_gcode_execute
if( ( gcode->has_m && ( gcode->m == 82 || gcode->m == 83 || gcode->m == 84 || gcode->m == 92 ) ) || ( gcode->has_g && gcode->g == 92 && gcode->has_letter('E') ) || ( gcode->has_g && ( gcode->g == 90 || gcode->g == 91 ) ) ){
+ gcode->mark_as_taken();
if( this->kernel->conveyor->queue.size() == 0 ){
this->kernel->call_event(ON_GCODE_EXECUTE, gcode );
}else{
if( gcode->has_g ){
// G92: Reset extruder position
if( gcode->g == 92 ){
+ gcode->mark_as_taken();
if( gcode->has_letter('E') ){
this->current_position = gcode->get_value('E');
this->target_position = this->current_position;
Gcode* gcode = static_cast<Gcode*>(argument);
// Add the gcode to the queue ourselves if we need it
if( gcode->has_m && ( gcode->m == this->on_m_code || gcode->m == this->off_m_code ) ){
+ gcode->mark_as_taken();
if( this->kernel->conveyor->queue.size() == 0 ){
this->kernel->call_event(ON_GCODE_EXECUTE, gcode );
}else{
}
if (gcode->m == 301)
{
+ gcode->mark_as_taken();
if (gcode->has_letter('S') && (gcode->get_value('S') == this->pool_index))
{
if (gcode->has_letter('P'))
}
if (gcode->m == 303)
{
+ gcode->mark_as_taken();
if (gcode->has_letter('S') && (gcode->get_value('S') == this->pool_index))
{
double target = 150.0;
if( gcode->m == this->set_and_wait_m_code)
{
+ gcode->mark_as_taken();
this->kernel->pauser->take();
this->waiting = true;
}