No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

steppers.cpp 22KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738
  1. #include <Arduino.h>
  2. #include <AccelStepper.h>
  3. #include "config.h"
  4. #include "config_pins.h"
  5. #include "common.h"
  6. #include "lcd.h"
  7. #include "data.h"
  8. #include "states.h"
  9. #include "steppers.h"
  10. static AccelStepper stepper_x(AccelStepper::DRIVER, X_STEP_PIN, X_DIR_PIN, 0, 0, false);
  11. static AccelStepper stepper_y(AccelStepper::DRIVER, Y_STEP_PIN, Y_DIR_PIN, 0, 0, false);
  12. static AccelStepper stepper_z(AccelStepper::DRIVER, Z_STEP_PIN, Z_DIR_PIN, 0, 0, false);
  13. static AccelStepper stepper_e(AccelStepper::DRIVER, E0_STEP_PIN, E0_DIR_PIN, 0, 0, false);
  14. #define HOME_PHASE_START 0
  15. #define HOME_PHASE_BACK 1
  16. #define HOME_PHASE_FINE 2
  17. enum stepper_states {
  18. step_disabled,
  19. step_not_homed,
  20. step_homing_x_fast,
  21. step_homing_x_back,
  22. step_homing_x_slow,
  23. step_homing_y_fast,
  24. step_homing_y_back,
  25. step_homing_y_slow,
  26. step_homing_z_fast,
  27. step_homing_z_back,
  28. step_homing_z_slow,
  29. step_homing_e_fast,
  30. step_homing_e_back,
  31. step_homing_e_slow,
  32. step_homed
  33. };
  34. static volatile stepper_states state = step_disabled;
  35. static volatile unsigned long steppers_home_move_start_time = 0;
  36. static volatile bool x_finished = true;
  37. static volatile bool y_finished = true;
  38. static volatile bool z_finished = true;
  39. static volatile bool e_finished = true;
  40. void steppers_init(void) {
  41. pinMode(X_ENDSTOP_PIN, INPUT_PULLUP);
  42. pinMode(Y_ENDSTOP_PIN, INPUT_PULLUP);
  43. pinMode(Z_ENDSTOP_PIN, INPUT_PULLUP);
  44. pinMode(E_ENDSTOP_PIN, INPUT_PULLUP);
  45. pinMode(X_ENABLE_PIN, OUTPUT);
  46. pinMode(X_STEP_PIN, OUTPUT);
  47. pinMode(X_DIR_PIN, OUTPUT);
  48. pinMode(Y_ENABLE_PIN, OUTPUT);
  49. pinMode(Y_STEP_PIN, OUTPUT);
  50. pinMode(Y_DIR_PIN, OUTPUT);
  51. pinMode(Z_ENABLE_PIN, OUTPUT);
  52. pinMode(Z_STEP_PIN, OUTPUT);
  53. pinMode(Z_DIR_PIN, OUTPUT);
  54. pinMode(E0_ENABLE_PIN, OUTPUT);
  55. pinMode(E0_STEP_PIN, OUTPUT);
  56. pinMode(E0_DIR_PIN, OUTPUT);
  57. // fan connected to D8 for electronics
  58. pinMode(FAN_PIN, OUTPUT);
  59. digitalWrite(FAN_PIN, LOW);
  60. stepper_x.setEnablePin(X_ENABLE_PIN);
  61. stepper_x.setPinsInverted(false, false, true);
  62. steppers_set_speed_x(data_options()->speed_x);
  63. steppers_set_accel_x(data_options()->accel_x);
  64. stepper_y.setEnablePin(Y_ENABLE_PIN);
  65. stepper_y.setPinsInverted(false, false, true);
  66. steppers_set_speed_y(data_options()->speed_y);
  67. steppers_set_accel_y(data_options()->accel_y);
  68. stepper_z.setEnablePin(Z_ENABLE_PIN);
  69. stepper_z.setPinsInverted(false, false, true);
  70. steppers_set_speed_z(data_options()->speed_z);
  71. steppers_set_accel_z(data_options()->accel_z);
  72. stepper_e.setEnablePin(E0_ENABLE_PIN);
  73. stepper_e.setPinsInverted(false, false, true);
  74. steppers_set_speed_e(data_options()->speed_e);
  75. steppers_set_accel_e(data_options()->accel_e);
  76. }
  77. static void steppers_initiate_home(int axis, int phase) {
  78. #if 0
  79. Serial.print(F("steppers_initiate_home("));
  80. if (axis == 0) {
  81. Serial.print('X');
  82. } else if (axis == 1) {
  83. Serial.print('Y');
  84. } else if (axis == 2) {
  85. Serial.print('Z');
  86. } else if (axis == 3) {
  87. Serial.print('E');
  88. } else {
  89. Serial.print(axis);
  90. }
  91. Serial.print(F(", "));
  92. Serial.print(phase);
  93. Serial.println(F(")"));
  94. #endif
  95. CLEAR_STORE_INTERRUPTS();
  96. steppers_home_move_start_time = millis();
  97. if (axis == X_AXIS) {
  98. // x
  99. if (phase == HOME_PHASE_START) {
  100. if (steppers_home_switch(axis)) {
  101. #if (X_MIN_PIN == -1)
  102. stepper_x.setCurrentPosition(X_AXIS_MAX * XY_STEPS_PER_MM * X_AXIS_MOVEMENT_DIR);
  103. #else
  104. stepper_x.setCurrentPosition(X_AXIS_MIN * XY_STEPS_PER_MM * X_AXIS_MOVEMENT_DIR);
  105. #endif
  106. // TODO order of homing
  107. steppers_initiate_home(Y_AXIS, HOME_PHASE_START);
  108. } else {
  109. state = step_homing_x_fast;
  110. stepper_x.setSpeed(X_HOMING_DIR * X_AXIS_MOVEMENT_DIR * XY_FAST_HOME_SPEED * XY_STEPS_PER_MM);
  111. }
  112. } else if (phase == HOME_PHASE_BACK) {
  113. state = step_homing_x_back;
  114. stepper_x.setSpeed(-1.0 * X_HOMING_DIR * X_AXIS_MOVEMENT_DIR * XY_FAST_HOME_SPEED * XY_STEPS_PER_MM);
  115. } else if (phase == HOME_PHASE_FINE) {
  116. state = step_homing_x_slow;
  117. stepper_x.setSpeed(X_HOMING_DIR * X_AXIS_MOVEMENT_DIR * XY_SLOW_HOME_SPEED * XY_STEPS_PER_MM);
  118. }
  119. } else if (axis == Y_AXIS) {
  120. // y
  121. if (phase == HOME_PHASE_START) {
  122. if (steppers_home_switch(axis)) {
  123. #if (Y_MIN_PIN == -1)
  124. stepper_y.setCurrentPosition(Y_AXIS_MAX * XY_STEPS_PER_MM * Y_AXIS_MOVEMENT_DIR);
  125. #else
  126. stepper_y.setCurrentPosition(Y_AXIS_MIN * XY_STEPS_PER_MM * Y_AXIS_MOVEMENT_DIR);
  127. #endif
  128. // TODO order of homing
  129. //steppers_initiate_home(Z_AXIS, HOME_PHASE_START);
  130. state = step_homed;
  131. } else {
  132. state = step_homing_y_fast;
  133. stepper_y.setSpeed(Y_HOMING_DIR * Y_AXIS_MOVEMENT_DIR * XY_FAST_HOME_SPEED * XY_STEPS_PER_MM);
  134. }
  135. } else if (phase == HOME_PHASE_BACK) {
  136. state = step_homing_y_back;
  137. stepper_y.setSpeed(-1.0 * Y_HOMING_DIR * Y_AXIS_MOVEMENT_DIR * XY_FAST_HOME_SPEED * XY_STEPS_PER_MM);
  138. } else if (phase == HOME_PHASE_FINE) {
  139. state = step_homing_y_slow;
  140. stepper_y.setSpeed(Y_HOMING_DIR * Y_AXIS_MOVEMENT_DIR * XY_SLOW_HOME_SPEED * XY_STEPS_PER_MM);
  141. }
  142. } else if (axis == Z_AXIS) {
  143. // z
  144. if (phase == HOME_PHASE_START) {
  145. state = step_homing_z_fast;
  146. stepper_z.setSpeed(Z_HOMING_DIR * Z_AXIS_MOVEMENT_DIR * Z_FAST_HOME_SPEED * Z_STEPS_PER_MM);
  147. } else if (phase == HOME_PHASE_BACK) {
  148. state = step_homing_z_back;
  149. stepper_z.setSpeed(-1.0 * Z_HOMING_DIR * Z_AXIS_MOVEMENT_DIR * Z_FAST_HOME_SPEED * Z_STEPS_PER_MM);
  150. } else if (phase == HOME_PHASE_FINE) {
  151. state = step_homing_z_slow;
  152. stepper_z.setSpeed(Z_HOMING_DIR * Z_AXIS_MOVEMENT_DIR * Z_SLOW_HOME_SPEED * Z_STEPS_PER_MM);
  153. }
  154. } else if (axis == E_AXIS) {
  155. // e
  156. if (phase == HOME_PHASE_START) {
  157. state = step_homing_e_fast;
  158. stepper_e.setSpeed(E_HOMING_DIR * E_AXIS_MOVEMENT_DIR * E_FAST_HOME_SPEED * E_STEPS_PER_PERCENT);
  159. } else if (phase == HOME_PHASE_BACK) {
  160. state = step_homing_e_back;
  161. stepper_e.setSpeed(-1.0 * E_HOMING_DIR * E_AXIS_MOVEMENT_DIR * E_FAST_HOME_SPEED * E_STEPS_PER_PERCENT);
  162. } else if (phase == HOME_PHASE_FINE) {
  163. state = step_homing_e_slow;
  164. stepper_e.setSpeed(E_HOMING_DIR * E_AXIS_MOVEMENT_DIR * E_SLOW_HOME_SPEED * E_STEPS_PER_PERCENT);
  165. }
  166. } else {
  167. Serial.println(F("home_init error: invalid axis"));
  168. }
  169. RESTORE_INTERRUPTS();
  170. }
  171. bool steppers_home_switch(int axis) {
  172. bool r = true;
  173. CLEAR_STORE_INTERRUPTS();
  174. if (axis == X_AXIS) {
  175. r = digitalRead(X_ENDSTOP_PIN) == LOW;
  176. } else if (axis == Y_AXIS) {
  177. r = digitalRead(Y_ENDSTOP_PIN) == LOW;
  178. } else if (axis == Z_AXIS) {
  179. r = digitalRead(Z_ENDSTOP_PIN) == LOW;
  180. } else if (axis == E_AXIS) {
  181. r = digitalRead(E_ENDSTOP_PIN) == LOW;
  182. } else {
  183. Serial.println(F("home_switch error: invalid axis"));
  184. }
  185. RESTORE_INTERRUPTS();
  186. return r;
  187. }
  188. bool stepper_reached_target(int axis) {
  189. if (axis == X_AXIS) {
  190. return x_finished;
  191. } else if (axis == Y_AXIS) {
  192. return y_finished;
  193. } else if (axis == Z_AXIS) {
  194. return z_finished;
  195. } else if (axis == E_AXIS) {
  196. return e_finished;
  197. } else {
  198. Serial.println(F("stepper_reached_target error: invalid axis"));
  199. return false;
  200. }
  201. }
  202. float steppers_current_pos(int axis) {
  203. float r = 0.0;
  204. CLEAR_STORE_INTERRUPTS();
  205. if (axis == X_AXIS) {
  206. float v = stepper_x.currentPosition();
  207. r = v / XY_STEPS_PER_MM / X_AXIS_MOVEMENT_DIR;
  208. } else if (axis == Y_AXIS) {
  209. float v = stepper_y.currentPosition();
  210. r = v / XY_STEPS_PER_MM / Y_AXIS_MOVEMENT_DIR;
  211. } else if (axis == Z_AXIS) {
  212. float v = stepper_z.currentPosition();
  213. r = v / Z_STEPS_PER_MM / Z_AXIS_MOVEMENT_DIR;
  214. } else if (axis == E_AXIS) {
  215. float v = stepper_e.currentPosition();
  216. r = E_PERCENT_TO_MM(v / E_STEPS_PER_PERCENT / E_AXIS_MOVEMENT_DIR);
  217. } else {
  218. Serial.println(F("steppers_pos error: invalid axis"));
  219. }
  220. RESTORE_INTERRUPTS();
  221. return r;
  222. }
  223. // TODO split into separate run funcs for running and homing
  224. // TODO only enable timer1 when either homing or moving
  225. // TODO disable timer1 when no longer homing/moving
  226. // TODO (when timer is disabled, still call in normal loop?)
  227. void steppers_run(void) {
  228. if ((state == step_homed) || (state == step_not_homed)) {
  229. for (int i = 0; i < AXIS_COUNT; i++) {
  230. #if 0
  231. Serial.print(i);
  232. Serial.print(": ");
  233. Serial.println(steppers_current_pos(i));
  234. #endif
  235. if (steppers_home_switch(i)) {
  236. float compare = 0.0, epsilon = 0.0;
  237. if (i == X_AXIS) {
  238. epsilon = X_AXIS_EPSILON;
  239. #if (X_HOMING_DIR == 1)
  240. compare = X_AXIS_MAX;
  241. #else
  242. compare = X_AXIS_MIN;
  243. #endif
  244. } else if (i == Y_AXIS) {
  245. epsilon = Y_AXIS_EPSILON;
  246. #if (Y_HOMING_DIR == 1)
  247. compare = Y_AXIS_MAX;
  248. #else
  249. compare = Y_AXIS_MIN;
  250. #endif
  251. } else if (i == Z_AXIS) {
  252. epsilon = Z_AXIS_EPSILON;
  253. #if (Z_HOMING_DIR == 1)
  254. compare = Z_AXIS_MAX;
  255. #else
  256. compare = Z_AXIS_MIN;
  257. #endif
  258. } else if (i == E_AXIS) {
  259. epsilon = E_AXIS_EPSILON;
  260. #if (E_HOMING_DIR == 1)
  261. compare = E_AXIS_MAX;
  262. #else
  263. compare = E_AXIS_MIN;
  264. #endif
  265. }
  266. if (fabs(steppers_current_pos(i) - compare) > epsilon) {
  267. #if 0
  268. Serial.print(F("Endstop hit at "));
  269. Serial.println(steppers_current_pos(i));
  270. #endif
  271. steppers_kill();
  272. if (i == X_AXIS) {
  273. sm_error.setText("Enstop hit on X axis");
  274. } else if (i == Y_AXIS) {
  275. sm_error.setText("Enstop hit on Y axis");
  276. } else if (i == Z_AXIS) {
  277. sm_error.setText("Enstop hit on Z axis");
  278. } else if (i == E_AXIS) {
  279. sm_error.setText("Enstop hit on E axis");
  280. } else {
  281. sm_error.setText("Enstop hit on unknown axis");
  282. }
  283. states_go_to(&sm_error);
  284. }
  285. }
  286. }
  287. x_finished = !stepper_x.run();
  288. y_finished = !stepper_y.run();
  289. z_finished = !stepper_z.run();
  290. e_finished = !stepper_e.run();
  291. } else if (state == step_homing_x_fast) {
  292. if (steppers_home_switch(X_AXIS)) {
  293. steppers_initiate_home(X_AXIS, HOME_PHASE_BACK);
  294. } else {
  295. stepper_x.runSpeed();
  296. }
  297. } else if (state == step_homing_x_back) {
  298. unsigned long end_time = steppers_home_move_start_time + XY_HOME_BACK_OFF_TIME;
  299. if ((!steppers_home_switch(X_AXIS)) && (millis() >= end_time)) {
  300. steppers_initiate_home(X_AXIS, HOME_PHASE_FINE);
  301. } else {
  302. stepper_x.runSpeed();
  303. }
  304. } else if (state == step_homing_x_slow) {
  305. if (steppers_home_switch(X_AXIS)) {
  306. stepper_x.setSpeed(0);
  307. #if (X_MIN_PIN == -1)
  308. stepper_x.setCurrentPosition(X_AXIS_MAX * XY_STEPS_PER_MM * X_AXIS_MOVEMENT_DIR);
  309. #else
  310. stepper_x.setCurrentPosition(X_AXIS_MIN * XY_STEPS_PER_MM * X_AXIS_MOVEMENT_DIR);
  311. #endif
  312. steppers_initiate_home(Y_AXIS, HOME_PHASE_START);
  313. } else {
  314. stepper_x.runSpeed();
  315. }
  316. } else if (state == step_homing_y_fast) {
  317. if (steppers_home_switch(Y_AXIS)) {
  318. steppers_initiate_home(Y_AXIS, HOME_PHASE_BACK);
  319. } else {
  320. stepper_y.runSpeed();
  321. }
  322. } else if (state == step_homing_y_back) {
  323. unsigned long end_time = steppers_home_move_start_time + XY_HOME_BACK_OFF_TIME;
  324. if ((!steppers_home_switch(Y_AXIS)) && (millis() >= end_time)) {
  325. steppers_initiate_home(Y_AXIS, HOME_PHASE_FINE);
  326. } else {
  327. stepper_y.runSpeed();
  328. }
  329. } else if (state == step_homing_y_slow) {
  330. if (steppers_home_switch(Y_AXIS)) {
  331. stepper_y.setSpeed(0);
  332. #if (Y_MIN_PIN == -1)
  333. stepper_y.setCurrentPosition(Y_AXIS_MAX * XY_STEPS_PER_MM * Y_AXIS_MOVEMENT_DIR);
  334. #else
  335. stepper_y.setCurrentPosition(Y_AXIS_MIN * XY_STEPS_PER_MM * Y_AXIS_MOVEMENT_DIR);
  336. #endif
  337. //steppers_initiate_home(E_AXIS, HOME_PHASE_START);
  338. // TODO
  339. state = step_homed;
  340. } else {
  341. stepper_y.runSpeed();
  342. }
  343. } else if (state == step_homing_z_fast) {
  344. if (steppers_home_switch(Z_AXIS)) {
  345. steppers_initiate_home(Z_AXIS, HOME_PHASE_BACK);
  346. } else {
  347. stepper_z.runSpeed();
  348. }
  349. } else if (state == step_homing_z_back) {
  350. unsigned long end_time = steppers_home_move_start_time + Z_HOME_BACK_OFF_TIME;
  351. if ((!steppers_home_switch(Z_AXIS)) && (millis() >= end_time)) {
  352. steppers_initiate_home(Z_AXIS, HOME_PHASE_FINE);
  353. } else {
  354. stepper_z.runSpeed();
  355. }
  356. } else if (state == step_homing_z_slow) {
  357. if (steppers_home_switch(Z_AXIS)) {
  358. stepper_z.setSpeed(0);
  359. #if (Z_MIN_PIN == -1)
  360. stepper_z.setCurrentPosition(Z_AXIS_MAX * Z_STEPS_PER_MM * Z_AXIS_MOVEMENT_DIR);
  361. #else
  362. stepper_z.setCurrentPosition(Z_AXIS_MIN * Z_STEPS_PER_MM * Z_AXIS_MOVEMENT_DIR);
  363. #endif
  364. steppers_initiate_home(X_AXIS, HOME_PHASE_START);
  365. } else {
  366. stepper_z.runSpeed();
  367. }
  368. } else if (state == step_homing_e_fast) {
  369. if (steppers_home_switch(E_AXIS)) {
  370. steppers_initiate_home(E_AXIS, HOME_PHASE_BACK);
  371. } else {
  372. stepper_e.runSpeed();
  373. }
  374. } else if (state == step_homing_e_back) {
  375. unsigned long end_time = steppers_home_move_start_time + E_HOME_BACK_OFF_TIME;
  376. if ((!steppers_home_switch(E_AXIS)) && (millis() >= end_time)) {
  377. steppers_initiate_home(E_AXIS, HOME_PHASE_FINE);
  378. } else {
  379. stepper_e.runSpeed();
  380. }
  381. } else if (state == step_homing_e_slow) {
  382. if (steppers_home_switch(E_AXIS)) {
  383. stepper_e.setSpeed(0);
  384. #if (E_MIN_PIN == -1)
  385. stepper_e.setCurrentPosition(E_MM_TO_PERCENT(E_AXIS_MAX) * E_STEPS_PER_PERCENT * E_AXIS_MOVEMENT_DIR);
  386. #else
  387. stepper_e.setCurrentPosition(E_MM_TO_PERCENT(E_AXIS_MIN) * E_STEPS_PER_PERCENT * E_AXIS_MOVEMENT_DIR);
  388. #endif
  389. state = step_homed;
  390. } else {
  391. stepper_e.runSpeed();
  392. }
  393. }
  394. }
  395. bool steppers_homed(void) {
  396. CLEAR_STORE_INTERRUPTS();
  397. bool r = (state == step_homed);
  398. RESTORE_INTERRUPTS();
  399. return r;
  400. }
  401. char steppers_homing_axis(void) {
  402. CLEAR_STORE_INTERRUPTS();
  403. char r = ' ';
  404. if ((state == step_homing_x_fast) || (state == step_homing_x_back) || (state == step_homing_x_slow)) {
  405. r = 'X';
  406. } else if ((state == step_homing_y_fast) || (state == step_homing_y_back) || (state == step_homing_y_slow)) {
  407. r = 'Y';
  408. } else if ((state == step_homing_z_fast) || (state == step_homing_z_back) || (state == step_homing_z_slow)) {
  409. r = 'Z';
  410. } else if ((state == step_homing_e_fast) || (state == step_homing_e_back) || (state == step_homing_e_slow)) {
  411. r = 'E';
  412. }
  413. RESTORE_INTERRUPTS();
  414. return r;
  415. }
  416. void steppers_start_homing(void) {
  417. CLEAR_STORE_INTERRUPTS();
  418. digitalWrite(FAN_PIN, HIGH);
  419. stepper_x.enableOutputs();
  420. stepper_y.enableOutputs();
  421. stepper_z.enableOutputs();
  422. stepper_e.enableOutputs();
  423. //steppers_initiate_home(Z_AXIS, HOME_PHASE_START);
  424. // TODO
  425. steppers_initiate_home(X_AXIS, HOME_PHASE_START);
  426. RESTORE_INTERRUPTS();
  427. }
  428. static int steppers_move_axis(AccelStepper &axis, long pos) {
  429. CLEAR_STORE_INTERRUPTS();
  430. if (state == step_disabled) {
  431. Serial.println(F("Enabling stepper drivers"));
  432. digitalWrite(FAN_PIN, HIGH);
  433. stepper_x.enableOutputs();
  434. stepper_y.enableOutputs();
  435. stepper_z.enableOutputs();
  436. stepper_e.enableOutputs();
  437. state = step_not_homed;
  438. }
  439. if (!steppers_homed()) {
  440. Serial.println(F("WARNING: un-homed move!"));
  441. }
  442. axis.moveTo(pos);
  443. RESTORE_INTERRUPTS();
  444. return 0;
  445. }
  446. int steppers_move_x(float pos) {
  447. Serial.print(F("Moving X to "));
  448. Serial.print(pos);
  449. Serial.print(F(" mm ("));
  450. Serial.print(pos * XY_STEPS_PER_MM * X_AXIS_MOVEMENT_DIR);
  451. Serial.println(F(" steps)"));
  452. if (pos < X_AXIS_MIN) {
  453. Serial.println(F("Move below X_AXIS_MIN!"));
  454. return -1;
  455. }
  456. if (pos > X_AXIS_MAX) {
  457. Serial.println(F("Move above X_AXIS_MAX!"));
  458. return -1;
  459. }
  460. return steppers_move_axis(stepper_x, pos * XY_STEPS_PER_MM * X_AXIS_MOVEMENT_DIR);
  461. }
  462. int steppers_move_y(float pos) {
  463. Serial.print(F("Moving Y to "));
  464. Serial.print(pos);
  465. Serial.print(F(" mm ("));
  466. Serial.print(pos * XY_STEPS_PER_MM * Y_AXIS_MOVEMENT_DIR);
  467. Serial.println(F(" steps)"));
  468. if (pos < Y_AXIS_MIN) {
  469. Serial.println(F("Move below Y_AXIS_MIN!"));
  470. return -1;
  471. }
  472. if (pos > Y_AXIS_MAX) {
  473. Serial.println(F("Move above Y_AXIS_MAX!"));
  474. return -1;
  475. }
  476. return steppers_move_axis(stepper_y, pos * XY_STEPS_PER_MM * Y_AXIS_MOVEMENT_DIR);
  477. }
  478. int steppers_move_z(float pos) {
  479. Serial.print(F("Moving Z to "));
  480. Serial.print(pos);
  481. Serial.print(F(" mm ("));
  482. Serial.print(pos * Z_STEPS_PER_MM * Z_AXIS_MOVEMENT_DIR);
  483. Serial.println(F(" steps)"));
  484. if (pos < Z_AXIS_MIN) {
  485. Serial.println(F("Move below Z_AXIS_MIN!"));
  486. return -1;
  487. }
  488. if (pos > Z_AXIS_MAX) {
  489. Serial.println(F("Move above Z_AXIS_MAX!"));
  490. return -1;
  491. }
  492. return steppers_move_axis(stepper_z, pos * Z_STEPS_PER_MM * Z_AXIS_MOVEMENT_DIR);
  493. }
  494. int steppers_move_e(float pos) {
  495. Serial.print(F("Moving E to "));
  496. Serial.print(pos);
  497. Serial.print(F(" mm ("));
  498. Serial.print(E_MM_TO_PERCENT(pos));
  499. Serial.println(F("% = "));
  500. Serial.print(E_MM_TO_PERCENT(pos) * E_STEPS_PER_PERCENT * E_AXIS_MOVEMENT_DIR);
  501. Serial.println(F(" steps)"));
  502. if (pos < E_AXIS_MIN) {
  503. Serial.println(F("Move below E_AXIS_MIN!"));
  504. return -1;
  505. }
  506. if (pos > E_AXIS_MAX) {
  507. Serial.println(F("Move above E_AXIS_MAX!"));
  508. return -1;
  509. }
  510. return steppers_move_axis(stepper_e, E_MM_TO_PERCENT(pos) * E_STEPS_PER_PERCENT * E_AXIS_MOVEMENT_DIR);
  511. }
  512. float steppers_pos_x(void) {
  513. CLEAR_STORE_INTERRUPTS();
  514. float v = stepper_x.targetPosition();
  515. RESTORE_INTERRUPTS();
  516. return v / XY_STEPS_PER_MM / X_AXIS_MOVEMENT_DIR;
  517. }
  518. float steppers_pos_y(void) {
  519. CLEAR_STORE_INTERRUPTS();
  520. float v = stepper_y.targetPosition();
  521. RESTORE_INTERRUPTS();
  522. return v / XY_STEPS_PER_MM / Y_AXIS_MOVEMENT_DIR;
  523. }
  524. float steppers_pos_z(void) {
  525. CLEAR_STORE_INTERRUPTS();
  526. float v = stepper_z.targetPosition();
  527. RESTORE_INTERRUPTS();
  528. return v / Z_STEPS_PER_MM / Z_AXIS_MOVEMENT_DIR;
  529. }
  530. float steppers_pos_e(void) {
  531. CLEAR_STORE_INTERRUPTS();
  532. float v = stepper_e.targetPosition();
  533. RESTORE_INTERRUPTS();
  534. return E_PERCENT_TO_MM(v / E_STEPS_PER_PERCENT / E_AXIS_MOVEMENT_DIR);
  535. }
  536. void steppers_kill(void) {
  537. CLEAR_STORE_INTERRUPTS();
  538. stepper_x.setCurrentPosition(0);
  539. stepper_y.setCurrentPosition(0);
  540. stepper_z.setCurrentPosition(0);
  541. stepper_e.setCurrentPosition(0);
  542. stepper_x.disableOutputs();
  543. stepper_y.disableOutputs();
  544. stepper_z.disableOutputs();
  545. stepper_e.disableOutputs();
  546. digitalWrite(FAN_PIN, LOW);
  547. state = step_disabled;
  548. RESTORE_INTERRUPTS();
  549. }
  550. void steppers_set_speed_x(float speed) {
  551. if (speed < 0.0) {
  552. speed = 0.0;
  553. }
  554. if (speed > XY_MAX_SPEED) {
  555. speed = XY_MAX_SPEED;
  556. }
  557. CLEAR_STORE_INTERRUPTS();
  558. stepper_x.setMaxSpeed(speed * XY_STEPS_PER_MM);
  559. RESTORE_INTERRUPTS();
  560. }
  561. void steppers_set_speed_y(float speed) {
  562. if (speed < 0.0) {
  563. speed = 0.0;
  564. }
  565. if (speed > XY_MAX_SPEED) {
  566. speed = XY_MAX_SPEED;
  567. }
  568. CLEAR_STORE_INTERRUPTS();
  569. stepper_y.setMaxSpeed(speed * XY_STEPS_PER_MM);
  570. RESTORE_INTERRUPTS();
  571. }
  572. void steppers_set_speed_z(float speed) {
  573. if (speed < 0.0) {
  574. speed = 0.0;
  575. }
  576. if (speed > Z_MAX_SPEED) {
  577. speed = Z_MAX_SPEED;
  578. }
  579. CLEAR_STORE_INTERRUPTS();
  580. stepper_z.setMaxSpeed(speed * Z_STEPS_PER_MM);
  581. RESTORE_INTERRUPTS();
  582. }
  583. void steppers_set_speed_e(float speed) {
  584. if (speed < 0.0) {
  585. speed = 0.0;
  586. }
  587. if (speed > E_MAX_SPEED) {
  588. speed = E_MAX_SPEED;
  589. }
  590. CLEAR_STORE_INTERRUPTS();
  591. stepper_e.setMaxSpeed(speed * E_STEPS_PER_PERCENT);
  592. RESTORE_INTERRUPTS();
  593. }
  594. void steppers_set_accel_x(float accel) {
  595. if (accel < 0.0) {
  596. accel = 0.0;
  597. }
  598. if (accel > XY_MAX_ACCEL) {
  599. accel = XY_MAX_ACCEL;
  600. }
  601. CLEAR_STORE_INTERRUPTS();
  602. stepper_x.setAcceleration(accel * XY_STEPS_PER_MM);
  603. RESTORE_INTERRUPTS();
  604. }
  605. void steppers_set_accel_y(float accel) {
  606. if (accel < 0.0) {
  607. accel = 0.0;
  608. }
  609. if (accel > XY_MAX_ACCEL) {
  610. accel = XY_MAX_ACCEL;
  611. }
  612. CLEAR_STORE_INTERRUPTS();
  613. stepper_y.setAcceleration(accel * XY_STEPS_PER_MM);
  614. RESTORE_INTERRUPTS();
  615. }
  616. void steppers_set_accel_z(float accel) {
  617. if (accel < 0.0) {
  618. accel = 0.0;
  619. }
  620. if (accel > Z_MAX_ACCEL) {
  621. accel = Z_MAX_ACCEL;
  622. }
  623. CLEAR_STORE_INTERRUPTS();
  624. stepper_z.setAcceleration(accel * Z_STEPS_PER_MM);
  625. RESTORE_INTERRUPTS();
  626. }
  627. void steppers_set_accel_e(float accel) {
  628. if (accel < 0.0) {
  629. accel = 0.0;
  630. }
  631. if (accel > E_MAX_ACCEL) {
  632. accel = E_MAX_ACCEL;
  633. }
  634. CLEAR_STORE_INTERRUPTS();
  635. stepper_e.setAcceleration(accel * E_STEPS_PER_PERCENT);
  636. RESTORE_INTERRUPTS();
  637. }