Alternative less ambiguous name for laser_module_pwm_pin
[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")
39b0a65d 26#define laser_module_pwm_pin_checksum CHECKSUM("laser_module_pwm_pin")
4287ba0c 27#define laser_module_ttl_pin_checksum CHECKSUM("laser_module_ttl_pin")
1f19c40d 28#define laser_module_pwm_period_checksum CHECKSUM("laser_module_pwm_period")
6e986d7e
BC
29#define laser_module_maximum_power_checksum CHECKSUM("laser_module_maximum_power")
30#define laser_module_minimum_power_checksum CHECKSUM("laser_module_minimum_power")
31#define laser_module_default_power_checksum CHECKSUM("laser_module_default_power")
1f19c40d 32#define laser_module_tickle_power_checksum CHECKSUM("laser_module_tickle_power")
6e986d7e 33#define laser_module_max_power_checksum CHECKSUM("laser_module_max_power")
1f19c40d 34
e605a0d6 35Laser::Laser(){
4cff3ded
AW
36}
37
38void Laser::on_module_loaded() {
314ab8f7 39 if( !THEKERNEL->config->value( laser_module_enable_checksum )->by_default(false)->as_bool() ){
0b1e8fd1
BG
40 // as not needed free up resource
41 delete this;
42 return;
43 }
e605a0d6 44
dad4ecfc
AW
45 // Get smoothie-style pin from config
46 Pin* dummy_pin = new Pin();
314ab8f7 47 dummy_pin->from_string(THEKERNEL->config->value(laser_module_pin_checksum)->by_default("nc")->as_string())->as_output();
61134a65 48
39b0a65d
FM
49 // Alternative less ambiguous name for pwm_pin
50 if (!dummy_pin->connected())
51 dummy_pin->from_string(THEKERNEL->config->value(laser_module_pwm_pin_checksum)->by_default("nc")->as_string())->as_output();
52
4287ba0c 53 pwm_pin = dummy_pin->hardware_pwm();
820ee962 54
4287ba0c 55 if (pwm_pin == NULL)
820ee962 56 {
580cad4c 57 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
58 delete dummy_pin;
59 delete this;
60 return;
61 }
62
4287ba0c
FM
63
64 this->pwm_inverting = dummy_pin->inverting;
dad4ecfc 65
820ee962
MM
66 delete dummy_pin;
67 dummy_pin = NULL;
68
4287ba0c
FM
69 // TTL settings
70 this->ttl_pin = new Pin();
71 ttl_pin->from_string( THEKERNEL->config->value(laser_module_ttl_pin_checksum)->by_default("nc" )->as_string())->as_output();
72 this->ttl_used = ttl_pin->connected();
73 this->ttl_inverting = ttl_pin->inverting;
74 if (ttl_used)
75 ttl_pin->set(0);
76
77 this->pwm_pin->period_us(THEKERNEL->config->value(laser_module_pwm_period_checksum)->by_default(20)->as_number());
78 this->pwm_pin->write(this->pwm_inverting ? 1 : 0);
6e986d7e 79 this->laser_maximum_power = THEKERNEL->config->value(laser_module_maximum_power_checksum )->by_default(1.0f)->as_number() ;
e605a0d6 80
6e986d7e
BC
81 // These config variables are deprecated, they have been replaced with laser_module_default_power and laser_module_minimum_power
82 this->laser_minimum_power = THEKERNEL->config->value(laser_module_tickle_power_checksum)->by_default(0)->as_number() ;
83 this->laser_power = THEKERNEL->config->value(laser_module_max_power_checksum)->by_default(0.8f)->as_number() ;
024545c5 84
6e986d7e
BC
85 // Load in our preferred config variables
86 this->laser_minimum_power = THEKERNEL->config->value(laser_module_minimum_power_checksum)->by_default(this->laser_minimum_power)->as_number() ;
87 this->laser_power = THEKERNEL->config->value(laser_module_default_power_checksum)->by_default(this->laser_power)->as_number() ;
0b1e8fd1 88
e605a0d6 89 //register for events
4cff3ded
AW
90 this->register_for_event(ON_GCODE_EXECUTE);
91 this->register_for_event(ON_SPEED_CHANGE);
a2cd92c0
AW
92 this->register_for_event(ON_BLOCK_BEGIN);
93 this->register_for_event(ON_BLOCK_END);
4cff3ded
AW
94}
95
a2cd92c0
AW
96// Turn laser off laser at the end of a move
97void Laser::on_block_end(void* argument){
4287ba0c
FM
98 this->pwm_pin->write(this->pwm_inverting ? 1 : 0);
99
100 if (this->ttl_used)
101 this->ttl_pin->set(0);
a2cd92c0
AW
102}
103
104// Set laser power at the beginning of a block
105void Laser::on_block_begin(void* argument){
106 this->set_proportional_power();
107}
befcf5cc 108
4cff3ded
AW
109// Turn laser on/off depending on received GCodes
110void Laser::on_gcode_execute(void* argument){
111 Gcode* gcode = static_cast<Gcode*>(argument);
b66fb830 112 this->laser_on = false;
0fe213e1
AW
113 if( gcode->has_g){
114 int code = gcode->g;
a2cd92c0 115 if( code == 0 ){ // G0
4287ba0c 116 this->pwm_pin->write(this->pwm_inverting ? 1 - this->laser_minimum_power : this->laser_minimum_power);
4cff3ded 117 this->laser_on = false;
a2cd92c0 118 }else if( code >= 1 && code <= 3 ){ // G1, G2, G3
4cff3ded
AW
119 this->laser_on = true;
120 }
121 }
de91760a 122 if ( gcode->has_letter('S' )){
024545c5 123 this->laser_power = gcode->get_value('S');
de91760a
GM
124 }
125
4287ba0c
FM
126 if (this->ttl_used)
127 this->ttl_pin->set(this->laser_on);
128
4cff3ded
AW
129}
130
6f57fb56 131// We follow the stepper module here, so speed must be proportional
4cff3ded 132void Laser::on_speed_change(void* argument){
58ecb87d
MC
133 if( this->laser_on ){
134 this->set_proportional_power();
135 }
a2cd92c0
AW
136}
137
138void Laser::set_proportional_power(){
38bf9a1c 139 if( this->laser_on && THEKERNEL->stepper->get_current_block() ){
58baeec1 140 // adjust power to maximum power and actual velocity
6e986d7e 141 float proportional_power = (((this->laser_maximum_power-this->laser_minimum_power)*(this->laser_power * THEKERNEL->stepper->get_trapezoid_adjusted_rate() / THEKERNEL->stepper->get_current_block()->nominal_rate))+this->laser_minimum_power);
4287ba0c 142 this->pwm_pin->write(this->pwm_inverting ? 1 - proportional_power : proportional_power);
4cff3ded 143 }
2f37949e 144}