Add motors off to prepare screen
[clinton/Smoothieware.git] / src / modules / utils / panel / screens / ControlScreen.cpp
1 /*
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/>.
6 */
7
8 #include "libs/Kernel.h"
9 #include "libs/SerialMessage.h"
10 #include "Panel.h"
11 #include "PanelScreen.h"
12 #include "MainMenuScreen.h"
13 #include "ControlScreen.h"
14 #include "libs/nuts_bolts.h"
15 #include "libs/utils.h"
16 #include <string>
17 #include "modules/robot/RobotPublicAccess.h"
18 using namespace std;
19
20 #define JOGGING_SPEED_MM_MIN 1200
21
22 ControlScreen::ControlScreen(){
23 this->control_mode = NULL_CONTROL_MODE;
24 }
25
26 void ControlScreen::on_enter(){
27 this->panel->enter_menu_mode();
28 this->panel->setup_menu(4);
29 get_current_pos(this->pos);
30 this->refresh_menu();
31 this->pos_changed= false;
32 }
33
34 // called in on_idle()
35 void ControlScreen::on_refresh(){
36 if( this->panel->menu_change() ){
37 this->refresh_menu();
38 }
39
40 if(this->control_mode == AXIS_CONTROL_MODE) {
41
42 if( this->panel->click() ){
43 this->enter_menu_control();
44 this->refresh_menu();
45
46 }else if(this->panel->control_value_change()) {
47 this->pos[this->controlled_axis-'X'] = this->panel->get_control_value();
48 this->panel->lcd->setCursor(0,2);
49 this->display_axis_line(this->controlled_axis);
50 this->pos_changed= true; // make the gcode in main_loop
51 }
52
53 }else{
54 if( this->panel->click() ){
55 this->clicked_menu_entry(this->panel->menu_current_line());
56 }
57 }
58 }
59
60 // queuing gcodes needs to be done from main loop
61 void ControlScreen::on_main_loop() {
62 // change actual axis value
63 if(!this->pos_changed) return;
64 this->pos_changed= false;
65
66 set_current_pos(this->controlled_axis, this->pos[this->controlled_axis-'X']);
67 }
68
69 void ControlScreen::display_menu_line(uint16_t line){
70 // in menu mode
71 switch( line ){
72 case 0: this->panel->lcd->printf("Back"); break;
73 case 1: this->display_axis_line('X'); break;
74 case 2: this->display_axis_line('Y'); break;
75 case 3: this->display_axis_line('Z'); break;
76 }
77 }
78
79 void ControlScreen::display_axis_line(char axis){
80 this->panel->lcd->printf("Move %c %8.3f", axis, this->pos[axis-'X']);
81 }
82
83
84 void ControlScreen::clicked_menu_entry(uint16_t line){
85 switch( line ){
86 case 0: this->panel->enter_screen(this->parent ); break;
87 case 1: this->enter_axis_control('X'); break;
88 case 2: this->enter_axis_control('Y'); break;
89 case 3: this->enter_axis_control('Z'); break;
90 }
91 }
92
93 void ControlScreen::enter_axis_control(char axis){
94 this->control_mode = AXIS_CONTROL_MODE;
95 this->controlled_axis = axis;
96 this->panel->enter_control_mode(this->jog_increment, this->jog_increment/10);
97 this->panel->set_control_value(this->pos[axis-'X']);
98 this->panel->lcd->clear();
99 this->panel->lcd->setCursor(0,2);
100 this->display_axis_line(this->controlled_axis);
101 }
102
103 void ControlScreen::enter_menu_control(){
104 this->control_mode = NULL_CONTROL_MODE;
105 this->panel->enter_menu_mode();
106 }
107
108
109 void ControlScreen::get_current_pos(double *cp){
110 void *returned_data;
111
112 bool ok= THEKERNEL->public_data->get_value( robot_checksum, current_position_checksum, &returned_data );
113 if(ok) {
114 double *p= static_cast<double *>(returned_data);
115 cp[0]= p[0];
116 cp[1]= p[1];
117 cp[2]= p[2];
118 }
119 }
120 void ControlScreen::set_current_pos(char axis, double p){
121 // change pos by issuing a G0 Xnnn
122 char buf[32];
123 int n= snprintf(buf, sizeof(buf), "G0 %c%f F%d", axis, p, (int)round(panel->get_jogging_speed(axis)));
124 string g(buf, n);
125 send_gcode(g);
126 }
127
128 void ControlScreen::send_gcode(std::string g) {
129 Gcode gcode(g, &(StreamOutput::NullStream));
130 THEKERNEL->call_event(ON_GCODE_RECEIVED, &gcode );
131 }
132