+ if(THEKERNEL->is_halted()) return; // if in halted state ignore any commands
+
+ SerialMessage *msgp = static_cast<SerialMessage *>(argument);
+ string possible_command = msgp->message;
+
+ // ignore anything that is not lowercase or a letter
+ if(possible_command.empty() || !islower(possible_command[0]) || !isalpha(possible_command[0])) {
+ return;
+ }
+
+ string cmd = shift_parameter(possible_command);
+
+ // Act depending on command
+ if (cmd == "fire") {
+ string power = shift_parameter(possible_command);
+ if(power.empty()) {
+ msgp->stream->printf("Usage: fire power%% [durationms]|off|status\n");
+ return;
+ }
+
+ float p;
+ fire_duration = 0; // By default unlimited
+ if(power == "status") {
+ msgp->stream->printf("laser manual state: %s\n", manual_fire ? "on" : "off");
+ return;
+ }
+ if(power == "off" || power == "0") {
+ p= 0;
+ msgp->stream->printf("turning laser off and returning to auto mode\n");
+ }else{
+ p= strtof(power.c_str(), NULL);
+ p= confine(p, 0.0F, 100.0F);
+ string duration = shift_parameter(possible_command);
+ if(!duration.empty()) {
+ fire_duration=atoi(duration.c_str());
+ // Avoid negative values, its just incorrect
+ if (fire_duration < ms_per_tick) {
+ msgp->stream->printf("WARNING: Minimal duration is %d ms, not firing\n", ms_per_tick);
+ return;
+ }
+ // rounding to minimal value
+ if (fire_duration % ms_per_tick != 0) {
+ fire_duration = (fire_duration / ms_per_tick) * ms_per_tick;
+ }
+ msgp->stream->printf("WARNING: Firing laser at %1.2f%% power, for %ld ms, use fire off to stop test fire earlier\n", p, fire_duration);
+ } else {
+ msgp->stream->printf("WARNING: Firing laser at %1.2f%% power, entering manual mode use fire off to return to auto mode\n", p);
+ }
+ }
+
+ p= p/100.0F;
+ manual_fire= set_laser_power(p);
+ }
+}
+
+// returns instance
+void Laser::on_get_public_data(void* argument)
+{
+ PublicDataRequest* pdr = static_cast<PublicDataRequest*>(argument);
+
+ if(!pdr->starts_with(laser_checksum)) return;
+ pdr->set_data_ptr(this);
+ pdr->set_taken();
+}
+
+
+void Laser::on_gcode_received(void *argument)
+{
+ Gcode *gcode = static_cast<Gcode *>(argument);
+
+ // M codes execute immediately
+ if (gcode->has_m) {
+ if (gcode->m == 221) { // M221 S100 change laser power by percentage S
+ if(gcode->has_letter('S')) {
+ this->scale= gcode->get_value('S') / 100.0F;
+
+ } else {
+ gcode->stream->printf("Laser power scale at %6.2f %%\n", this->scale * 100.0F);
+ }
+ }
+ }