Changes to laser module PWM config.
[clinton/Smoothieware.git] / src / modules / tools / laser / Laser.cpp
CommitLineData
de91760a 1/*
58baeec1
MM
2 This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
3 Smoothie is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
4 Smoothie is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
5 You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
4cff3ded
AW
6*/
7
4cff3ded
AW
8#include "libs/Module.h"
9#include "libs/Kernel.h"
10#include "modules/communication/utils/Gcode.h"
11#include "modules/robot/Stepper.h"
12#include "Laser.h"
a2cd92c0 13#include "libs/nuts_bolts.h"
61134a65
JM
14#include "Config.h"
15#include "StreamOutputPool.h"
16#include "Block.h"
7af0714f 17#include "checksumm.h"
8d54c34c 18#include "ConfigValue.h"
4cff3ded 19
1f19c40d
JM
20#include "libs/Pin.h"
21#include "Gcode.h"
22#include "PwmOut.h" // mbed.h lib
23
24#define laser_module_enable_checksum CHECKSUM("laser_module_enable")
25#define laser_module_pin_checksum CHECKSUM("laser_module_pin")
26#define laser_module_pwm_period_checksum CHECKSUM("laser_module_pwm_period")
27#define laser_module_max_power_checksum CHECKSUM("laser_module_max_power")
024545c5 28#define laser_module_min_power_checksum CHECKSUM("laser_module_min_power")
1f19c40d 29#define laser_module_tickle_power_checksum CHECKSUM("laser_module_tickle_power")
024545c5 30#define laser_module_power_checksum CHECKSUM("laser_module_power")
1f19c40d 31
e605a0d6 32Laser::Laser(){
4cff3ded
AW
33}
34
35void Laser::on_module_loaded() {
314ab8f7 36 if( !THEKERNEL->config->value( laser_module_enable_checksum )->by_default(false)->as_bool() ){
0b1e8fd1
BG
37 // as not needed free up resource
38 delete this;
39 return;
40 }
e605a0d6 41
dad4ecfc
AW
42 // Get smoothie-style pin from config
43 Pin* dummy_pin = new Pin();
314ab8f7 44 dummy_pin->from_string(THEKERNEL->config->value(laser_module_pin_checksum)->by_default("nc")->as_string())->as_output();
61134a65 45
1c73b86f 46 laser_pin = dummy_pin->hardware_pwm();
820ee962
MM
47
48 if (laser_pin == NULL)
49 {
580cad4c 50 THEKERNEL->streams->printf("Error: Laser cannot use P%d.%d (P2.0 - P2.5, P1.18, P1.20, P1.21, P1.23, P1.24, P1.26, P3.25, P3.26 only). Laser module disabled.\n", dummy_pin->port_number, dummy_pin->pin);
820ee962
MM
51 delete dummy_pin;
52 delete this;
53 return;
54 }
55
9f9d7939 56 this->laser_inverting = dummy_pin->inverting;
dad4ecfc 57
820ee962
MM
58 delete dummy_pin;
59 dummy_pin = NULL;
60
9548623d 61 this->laser_pin->period_us(THEKERNEL->config->value(laser_module_pwm_period_checksum)->by_default(20)->as_number());
9f9d7939 62 this->laser_pin->write(this->laser_inverting ? 1 : 0);
e605a0d6 63
024545c5
BC
64 this->laser_max_power = THEKERNEL->config->value(laser_module_max_power_checksum )->by_default(1.0f)->as_number() ;
65 this->laser_min_power = THEKERNEL->config->value(laser_module_min_power_checksum)->by_default(0 )->as_number() ;
66 this->laser_power = THEKERNEL->config->value(laser_module_power_checksum)->by_default(0.8f)->as_number() ;
67
68 // either the minimum value wasnt set, or it is 0. Overwrite with old tickle value config.
69 if (this->laser_min_power == 0) {
70 this->laser_min_power = THEKERNEL->config->value(laser_module_tickle_power_checksum)->by_default(0 )->as_number() ;
71 }
0b1e8fd1 72
e605a0d6 73 //register for events
4cff3ded
AW
74 this->register_for_event(ON_GCODE_EXECUTE);
75 this->register_for_event(ON_SPEED_CHANGE);
befcf5cc
AW
76 this->register_for_event(ON_PLAY);
77 this->register_for_event(ON_PAUSE);
a2cd92c0
AW
78 this->register_for_event(ON_BLOCK_BEGIN);
79 this->register_for_event(ON_BLOCK_END);
4cff3ded
AW
80}
81
a2cd92c0
AW
82// Turn laser off laser at the end of a move
83void Laser::on_block_end(void* argument){
9f9d7939 84 this->laser_pin->write(this->laser_inverting ? 1 : 0);
a2cd92c0
AW
85}
86
87// Set laser power at the beginning of a block
88void Laser::on_block_begin(void* argument){
89 this->set_proportional_power();
90}
befcf5cc
AW
91
92// When the play/pause button is set to pause, or a module calls the ON_PAUSE event
93void Laser::on_pause(void* argument){
9f9d7939 94 this->laser_pin->write(this->laser_inverting ? 1 : 0);
befcf5cc
AW
95}
96
97// When the play/pause button is set to play, or a module calls the ON_PLAY event
98void Laser::on_play(void* argument){
a2cd92c0 99 this->set_proportional_power();
befcf5cc
AW
100}
101
4cff3ded
AW
102// Turn laser on/off depending on received GCodes
103void Laser::on_gcode_execute(void* argument){
104 Gcode* gcode = static_cast<Gcode*>(argument);
b66fb830 105 this->laser_on = false;
0fe213e1
AW
106 if( gcode->has_g){
107 int code = gcode->g;
a2cd92c0 108 if( code == 0 ){ // G0
024545c5 109 this->laser_pin->write(this->laser_inverting ? 1 - this->laser_min_power : this->laser_min_power);
4cff3ded 110 this->laser_on = false;
a2cd92c0 111 }else if( code >= 1 && code <= 3 ){ // G1, G2, G3
4cff3ded
AW
112 this->laser_on = true;
113 }
114 }
de91760a 115 if ( gcode->has_letter('S' )){
024545c5 116 this->laser_power = gcode->get_value('S');
de91760a
GM
117 }
118
4cff3ded
AW
119}
120
6f57fb56 121// We follow the stepper module here, so speed must be proportional
4cff3ded 122void Laser::on_speed_change(void* argument){
58ecb87d
MC
123 if( this->laser_on ){
124 this->set_proportional_power();
125 }
a2cd92c0
AW
126}
127
128void Laser::set_proportional_power(){
38bf9a1c 129 if( this->laser_on && THEKERNEL->stepper->get_current_block() ){
58baeec1 130 // adjust power to maximum power and actual velocity
024545c5 131 float proportional_power = (((this->laser_max_power-this->laser_min_power)*(this->laser_power * THEKERNEL->stepper->get_trapezoid_adjusted_rate() / THEKERNEL->stepper->get_current_block()->nominal_rate))+this->laser_min_power);
9f9d7939 132 this->laser_pin->write(this->laser_inverting ? 1 - proportional_power : proportional_power);
4cff3ded 133 }
2f37949e 134}