Merge branch 'feature/e-endstop' into merge-abc-with-homing
[clinton/Smoothieware.git] / src / libs / StepperMotor.cpp
CommitLineData
7b49793d 1/*
feb204be
AW
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.
7b49793d 5 You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
feb204be 6*/
670fa10b 7#include "StepperMotor.h"
5673fe39
MM
8
9#include "Kernel.h"
8f91e4e6 10#include "MRI_Hooks.h"
61134a65
JM
11#include "StepTicker.h"
12
13#include <math.h>
f9a0f86d 14#include "mbed.h"
feb204be 15
728477c4
JM
16StepperMotor::StepperMotor(Pin &step, Pin &dir, Pin &en) : step_pin(step), dir_pin(dir), en_pin(en)
17{
728477c4 18 set_high_on_debug(en.port_number, en.pin);
8f91e4e6 19
df6a30f2
MM
20 steps_per_mm = 1.0F;
21 max_rate = 50.0F;
22
78d0e16a
MM
23 last_milestone_steps = 0;
24 last_milestone_mm = 0.0F;
3494f3d0 25 current_position_steps= 0;
d1d120e1 26 moving= false;
29e809e0
JM
27 acceleration= NAN;
28 selected= true;
aef2eec0 29 extruder= false;
9e6014a6 30
e1096d25
JM
31 enable(false);
32 unstep(); // initialize step pin
33 set_direction(false); // initialize dor pin
cf78dfb8 34
9e6014a6
JM
35 this->register_for_event(ON_HALT);
36 this->register_for_event(ON_ENABLE);
37}
38
39StepperMotor::~StepperMotor()
40{
41 THEKERNEL->unregister_for_event(ON_HALT, this);
42 THEKERNEL->unregister_for_event(ON_ENABLE, this);
43}
44
45void StepperMotor::on_halt(void *argument)
46{
47 if(argument == nullptr) {
48 enable(false);
a19a873f 49 moving= false;
9e6014a6
JM
50 }
51}
52
53void StepperMotor::on_enable(void *argument)
54{
d01fbc6f
JM
55 // argument is a uin32_t where bit0 is on or off, and bit 1:X, 2:Y, 3:Z, 4:A, 5:B, 6:C etc
56 // for now if bit0 is 1 we turn all on, if 0 we turn all off otherwise we turn selected axis off
57 uint32_t bm= (uint32_t)argument;
58 if(bm == 0x01) {
59 enable(true);
60
8e30d648 61 }else if(bm == 0 || ((bm&0x01) == 0 && ((bm&(0x02<<motor_id)) != 0)) ) {
d01fbc6f
JM
62 enable(false);
63 }
feb204be
AW
64}
65
78d0e16a
MM
66void StepperMotor::change_steps_per_mm(float new_steps)
67{
68 steps_per_mm = new_steps;
586cc733 69 last_milestone_steps = lroundf(last_milestone_mm * steps_per_mm);
58c32991 70 current_position_steps = last_milestone_steps;
78d0e16a
MM
71}
72
73void StepperMotor::change_last_milestone(float new_milestone)
74{
75 last_milestone_mm = new_milestone;
586cc733 76 last_milestone_steps = lroundf(last_milestone_mm * steps_per_mm);
58c32991 77 current_position_steps = last_milestone_steps;
78d0e16a
MM
78}
79
de2ee57c
JM
80void StepperMotor::set_last_milestones(float mm, int32_t steps)
81{
82 last_milestone_mm= mm;
83 last_milestone_steps= steps;
84 current_position_steps= last_milestone_steps;
85}
86
ad6a77d1
JM
87void StepperMotor::update_last_milestones(float mm, int32_t steps)
88{
89 last_milestone_steps += steps;
90 last_milestone_mm = mm;
91}
92
93int32_t StepperMotor::steps_to_target(float target)
78d0e16a 94{
de2ee57c 95 int32_t target_steps = lroundf(target * steps_per_mm);
78d0e16a
MM
96 return target_steps - last_milestone_steps;
97}
58b69de8
JM
98
99// Does a manual step pulse, used for direct encoder control of a stepper
df675215
JM
100// NOTE this is experimental and may change and/or be reomved in the future, it is an unsupported feature.
101// use at your own risk
58b69de8
JM
102void StepperMotor::manual_step(bool dir)
103{
104 if(!is_enabled()) enable(true);
105
106 // set direction if needed
107 if(this->direction != dir) {
108 this->direction= dir;
109 this->dir_pin.set(dir);
110 wait_us(1);
111 }
112
113 // pulse step pin
114 this->step_pin.set(1);
115 wait_us(3);
116 this->step_pin.set(0);
117
118
119 // keep track of actuators actual position in steps
120 this->current_position_steps += (dir ? -1 : 1);
121}