yarf 0.1
Yet Another RepRap Firmware
|
00001 /* 00002 * commands.c 00003 * 00004 * Copyright 2011 Pieter Agten 00005 * 00006 * This file is part of Yarf. 00007 * 00008 * Yarf is free software: you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation, either version 3 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * Yarf is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with Yarf. If not, see <http://www.gnu.org/licenses/>. 00020 */ 00021 00029 #include "commands.h" 00030 00031 #include "movement/planner.h" 00032 #include "movement/block_handler.h" 00033 #include "hardware/steppers.h" 00034 #include "temperature/temperature.h" 00035 #include "util/delays.h" 00036 00037 #include <math.h> 00038 #include <stdbool.h> 00039 00044 #define MIN_TEMP_C 0.0 00045 00050 #define MAX_TEMP_C 300.0 00051 00052 00056 static bool use_relative_coordinates; 00057 00061 static speed_t last_feed_rate; 00062 00068 static void 00069 ok(cmd_response_t *r) 00070 { 00071 r->status = OK; 00072 r->T = NAN; 00073 r->B = NAN; 00074 r->X = NAN; 00075 r->Y = NAN; 00076 r->Z = NAN; 00077 r->E = NAN; 00078 r->info = NULL; 00079 } 00080 00088 static void 00089 invalid(cmd_response_t *r, char *info) 00090 { 00091 r->status = INVALID; 00092 r->T = NAN; 00093 r->B = NAN; 00094 r->X = NAN; 00095 r->Y = NAN; 00096 r->Z = NAN; 00097 r->E = NAN; 00098 r->info = info; 00099 } 00100 00108 static void 00109 temperatures(cmd_response_t *r, float t, float b) 00110 { 00111 r->status = OK; 00112 r->T = t; 00113 r->B = b; 00114 r->X = NAN; 00115 r->Y = NAN; 00116 r->Z = NAN; 00117 r->E = NAN; 00118 r->info = NULL; 00119 } 00120 00130 static void 00131 coordinates(cmd_response_t *r, float x, float y, float z, float e) 00132 { 00133 r->status = OK; 00134 r->T = NAN; 00135 r->B = NAN; 00136 r->X = x; 00137 r->Y = y; 00138 r->Z = z; 00139 r->E = e; 00140 r->info = NULL; 00141 } 00142 00143 00144 void 00145 cmd_init() 00146 { 00147 use_relative_coordinates = false; 00148 last_feed_rate = START_FEED_RATE; 00149 } 00150 00151 00152 void 00153 cmd_controlled_move(cmd_response_t *r, float x, float y, float z, float e, float f) 00154 { 00155 steps_t steps_x, steps_y, steps_z, steps_e; 00156 speed_t feed_rate; 00157 if (use_relative_coordinates) { 00158 steps_x = isnan(x) ? 0 : lround(x * X_STEPS_PER_MM); 00159 steps_y = isnan(y) ? 0 : lround(y * Y_STEPS_PER_MM); 00160 steps_z = isnan(z) ? 0 : lround(z * Z_STEPS_PER_MM); 00161 steps_e = isnan(e) ? 0 : lround(e * E_STEPS_PER_MM); 00162 feed_rate = isnan(f) ? 0 : lround(f); 00163 plan_linear_movement_rel(steps_x,steps_y,steps_z,steps_e,feed_rate); 00164 } else { 00165 steps_x = isnan(x) ? plan_get_virtual_position(X_AXIS) : lround(x * X_STEPS_PER_MM); 00166 steps_y = isnan(y) ? plan_get_virtual_position(Y_AXIS) : lround(y * Y_STEPS_PER_MM); 00167 steps_z = isnan(z) ? plan_get_virtual_position(Z_AXIS) : lround(z * Z_STEPS_PER_MM); 00168 steps_e = isnan(e) ? plan_get_virtual_position(E_AXIS) : lround(e * E_STEPS_PER_MM); 00169 feed_rate = isnan(f) ? last_feed_rate : lround(f); 00170 plan_linear_movement_abs(steps_x,steps_y,steps_z,steps_e,feed_rate); 00171 } 00172 last_feed_rate = feed_rate; 00173 block_handler_start(); 00174 ok(r); 00175 } 00176 00177 00178 void 00179 cmd_set_units_inches(cmd_response_t *r) 00180 { 00181 invalid(r,"inches are not supported"); 00182 } 00183 00184 00185 void 00186 cmd_set_units_millimeters(cmd_response_t *r) 00187 { 00188 // Units are always in millimeters 00189 ok(r); 00190 } 00191 00192 00193 void 00194 cmd_move_to_origin(cmd_response_t *r, bool x, bool y, bool z) 00195 { 00196 if (!x && !y && !z) { 00197 // Move all axes to origin 00198 plan_home_axes(true, true, true); 00199 } else { 00200 // Move only the specified axes to origin 00201 plan_home_axes(x, y, z); 00202 } 00203 block_handler_start(); 00204 ok(r); 00205 } 00206 00207 00208 void 00209 cmd_set_absolute_positioning(cmd_response_t *r) 00210 { 00211 use_relative_coordinates = false; 00212 ok(r); 00213 } 00214 00215 00216 void 00217 cmd_set_relative_positioning(cmd_response_t *r) 00218 { 00219 use_relative_coordinates = true; 00220 ok(r); 00221 } 00222 00223 00224 void 00225 cmd_set_position(cmd_response_t *r, float x, float y, float z, float e) 00226 { 00227 if (use_relative_coordinates) { 00228 steps_t steps_x = isnan(x) ? 0 : lround(x * X_STEPS_PER_MM); 00229 steps_t steps_y = isnan(y) ? 0 : lround(y * Y_STEPS_PER_MM); 00230 steps_t steps_z = isnan(z) ? 0 : lround(z * Z_STEPS_PER_MM); 00231 steps_t steps_e = isnan(e) ? 0 : lround(e * E_STEPS_PER_MM); 00232 plan_set_virtual_position_rel(steps_x,steps_y,steps_z,steps_e); 00233 } else { 00234 steps_t steps_x = isnan(x) ? plan_get_virtual_position(X_AXIS) : lround(x * X_STEPS_PER_MM); 00235 steps_t steps_y = isnan(y) ? plan_get_virtual_position(Y_AXIS) : lround(y * Y_STEPS_PER_MM); 00236 steps_t steps_z = isnan(z) ? plan_get_virtual_position(Z_AXIS) : lround(z * Z_STEPS_PER_MM); 00237 steps_t steps_e = isnan(e) ? plan_get_virtual_position(E_AXIS) : lround(e * E_STEPS_PER_MM); 00238 plan_set_virtual_position_abs(steps_x,steps_y,steps_z,steps_e); 00239 } 00240 ok(r); 00241 } 00242 00243 00244 void 00245 cmd_stop_idle_hold(cmd_response_t *r) 00246 { 00247 steppers_disable(); 00248 ok(r); 00249 } 00250 00251 static bool 00252 _is_valid_temperature(float c) 00253 { 00254 return !isnan(c) && c >= MIN_TEMP_C && c <= MAX_TEMP_C; 00255 } 00256 00257 00258 void 00259 cmd_set_extruder_temp_async(cmd_response_t *r, float c) 00260 { 00261 if (_is_valid_temperature(c)) { 00262 temp_set_nozzle_target(c); 00263 ok(r); 00264 } else { 00265 invalid(r,"requested temperature invalid"); 00266 } 00267 } 00268 00269 00270 void 00271 cmd_read_nozzle_and_printbed_temp(cmd_response_t *r) 00272 { 00273 return temperatures(r, temp_get_nozzle_temp(), temp_get_printbed_temp()); 00274 } 00275 00276 00277 void 00278 cmd_set_extruder_temp_sync(cmd_response_t *r, float c) 00279 { 00280 cmd_set_extruder_temp_async(r, c); 00281 if (r->status == OK) { 00282 cmd_wait(r); 00283 } 00284 } 00285 00286 00287 void 00288 cmd_set_extruder_pwm(cmd_response_t *r, float s) 00289 { 00290 if (isnan(s)) { 00291 // The extruder stepper power is always controlled by the potentiometer on 00292 // driver board 00293 ok(r); 00294 } else { 00295 invalid(r,"M113 with S parameter is not supported"); 00296 } 00297 } 00298 00299 00300 void 00301 cmd_get_position(cmd_response_t *r) 00302 { 00303 coordinates(r, 00304 ((float)plan_get_virtual_position(X_AXIS)) / X_STEPS_PER_MM, 00305 ((float)plan_get_virtual_position(Y_AXIS)) / Y_STEPS_PER_MM, 00306 ((float)plan_get_virtual_position(Z_AXIS)) / Z_STEPS_PER_MM, 00307 ((float)plan_get_virtual_position(E_AXIS)) / E_STEPS_PER_MM 00308 ); 00309 } 00310 00311 00312 00316 static void 00317 nozzle_temperature_wait(void) 00318 { 00319 while (! temp_nozzle_temperature_reached()) { 00320 printf("// T:%.1f B:%.1f\n",(double)temp_get_nozzle_temp(), (double)temp_get_printbed_temp()); 00321 delay_ms_long(1000); 00322 } 00323 } 00324 00328 static void 00329 printbed_temperature_wait(void) 00330 { 00331 while (! temp_printbed_temperature_reached()) { 00332 printf("// T:%.1f B:%.1f\n",(double)temp_get_nozzle_temp(), (double)temp_get_printbed_temp()); 00333 delay_ms_long(1000); 00334 } 00335 } 00336 00337 00338 void 00339 cmd_wait(cmd_response_t *r) 00340 { 00341 if (! temp_nozzle_temperature_reached() || 00342 ! temp_printbed_temperature_reached()) { 00343 while (! temp_nozzle_temperature_reached() || 00344 ! temp_printbed_temperature_reached()) { 00345 nozzle_temperature_wait(); 00346 printbed_temperature_wait(); 00347 printf("// waiting 20s for temps to stabilize\n"); 00348 delay_ms_long(20000); // TODO: measure how long the temperatures have been stabile instead of this simple delay 00349 } 00350 } 00351 00352 ok(r); 00353 } 00354 00355 00356 void 00357 cmd_set_printbed_temp_async(cmd_response_t *r, float c) 00358 { 00359 if (_is_valid_temperature(c)) { 00360 temp_set_printbed_target(c); 00361 ok(r); 00362 } else { 00363 invalid(r,"requested temperature invalid"); 00364 } 00365 } 00366 00367 00368 void 00369 cmd_select_tool(cmd_response_t *r, int tool) 00370 { 00371 if (tool == 0) { 00372 ok(r); 00373 } else { 00374 invalid(r,"only tool 0 is supported"); 00375 } 00376 }