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/>.
8 #include "DirectJogScreen.h"
10 #include "libs/Kernel.h"
11 #include "libs/SerialMessage.h"
13 #include "PanelScreen.h"
14 #include "MainMenuScreen.h"
15 #include "libs/nuts_bolts.h"
16 #include "libs/utils.h"
18 #include "PublicData.h"
19 #include "checksumm.h"
21 #include "StepperMotor.h"
22 #include "BaseSolution.h"
31 DirectJogScreen::DirectJogScreen(){}
33 void DirectJogScreen::on_enter()
35 THEPANEL
->enter_menu_mode();
37 THEPANEL
->setup_menu(7);
39 this->pos_changed
= false;
43 // called in on_idle()
44 void DirectJogScreen::on_refresh()
46 if ( THEPANEL
->menu_change() ) {
50 if ( THEPANEL
->click() ) {
53 THEROBOT
->reset_position_from_current_actuator_position(); // needed as we were changing the actuator only
54 this->enter_menu_control();
60 this->clicked_menu_entry(THEPANEL
->get_menu_current_line());
64 } else if(pos_changed
) {
67 THEPANEL
->lcd
->setCursor(0, 2);
68 this->display_axis_line(this->axis
);
73 void DirectJogScreen::display_menu_line(uint16_t line
)
76 if(mode
== MULTIPLIER
) {
78 case 0: THEPANEL
->lcd
->printf("Back"); break;
79 case 1: THEPANEL
->lcd
->printf("x1"); break;
80 case 2: THEPANEL
->lcd
->printf("x4"); break;
81 case 3: THEPANEL
->lcd
->printf("x8"); break;
82 case 4: THEPANEL
->lcd
->printf("x16"); break;
83 case 5: THEPANEL
->lcd
->printf("x32"); break;
84 case 6: THEPANEL
->lcd
->printf("x64"); break;
87 }else if(mode
== AXIS_SELECT
){
89 case 0: THEPANEL
->lcd
->printf("Back"); break;
90 case 1: this->display_axis_line(X_AXIS
); break;
91 case 2: this->display_axis_line(Y_AXIS
); break;
92 case 3: this->display_axis_line(Z_AXIS
); break;
97 void DirectJogScreen::display_axis_line(uint8_t axis
)
99 THEPANEL
->lcd
->printf("%c %8.3f", 'X' + axis
, this->pos
[axis
]);
103 void DirectJogScreen::clicked_menu_entry(uint16_t line
)
105 if(mode
== MULTIPLIER
) {
107 case 0: THEPANEL
->enter_screen(this->parent
); break;
108 case 1: multiplier
= 1; break;
109 case 2: multiplier
= 4; break;
110 case 3: multiplier
= 8; break;
111 case 4: multiplier
= 16; break;
112 case 5: multiplier
= 32; break;
113 case 6: multiplier
= 64; break;
117 enter_menu_control();
120 }else if(mode
== AXIS_SELECT
){
122 case 0: THEPANEL
->enter_screen(this->parent
); break;
123 case 1: this->enter_axis_control(X_AXIS
); break;
124 case 2: this->enter_axis_control(Y_AXIS
); break;
125 case 3: this->enter_axis_control(Z_AXIS
); break;
130 void DirectJogScreen::on_exit()
132 // we need to update the positions after manually ticking
133 THEROBOT
->reset_position_from_current_actuator_position();
137 void DirectJogScreen::get_actuator_pos()
139 // get real time positions
140 ActuatorCoordinates current_position
{
141 THEROBOT
->actuators
[X_AXIS
]->get_current_position(),
142 THEROBOT
->actuators
[Y_AXIS
]->get_current_position(),
143 THEROBOT
->actuators
[Z_AXIS
]->get_current_position()
146 // get machine position from the actuator position using FK
148 THEROBOT
->arm_solution
->actuator_to_cartesian(current_position
, mpos
);
149 Robot::wcs_t wpos
= THEROBOT
->mcs2wcs(mpos
);
150 this->pos
[0]= THEROBOT
->from_millimeters(std::get
<X_AXIS
>(wpos
));
151 this->pos
[1]= THEROBOT
->from_millimeters(std::get
<Y_AXIS
>(wpos
));
152 this->pos
[2]= THEROBOT
->from_millimeters(std::get
<Z_AXIS
>(wpos
));
155 // encoder tick, called in an interrupt everytime we get an encoder tick
156 // fastest is 200pulses/sec
157 void DirectJogScreen::tick(int change
)
159 for (int i
= 0; i
< multiplier
; ++i
) {
160 if(i
!= 0) wait_us(100); // if you go faster than this you miss encoder changes
161 THEROBOT
->actuators
[axis
]->manual_step(change
< 0);
166 void DirectJogScreen::enter_axis_control(uint8_t axis
)
170 THEPANEL
->lcd
->clear();
171 THEPANEL
->lcd
->setCursor(0, 0);
172 THEPANEL
->lcd
->printf("MPG mode x%d", multiplier
);
173 THEPANEL
->lcd
->setCursor(0, 2);
175 this->display_axis_line(this->axis
);
177 using std::placeholders::_1
;
178 THEPANEL
->enter_direct_encoder_mode(std::bind(&DirectJogScreen::tick
, this, _1
));
181 void DirectJogScreen::enter_menu_control()
183 this->mode
= AXIS_SELECT
;
184 THEPANEL
->setup_menu(4);
185 THEPANEL
->enter_menu_mode(true);