yarf 0.1
Yet Another RepRap Firmware
src/input/commands.c
Go to the documentation of this file.
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 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines