Frästisch mit elektronischer Höhenverstellung mittels Schrittmotoren.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

Fraestisch_SFTools.ino 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. /*
  2. Steuerung für Frästisch_SFTools
  3. Diese Datei enthält den Code für die Implementierung der Steuerung eines Frästisches mit 2 Nema17 Schrittmotoren.
  4. Sie unterstützt:
  5. - Schnelles/langsames Verstellen der Fräserhöhe
  6. - Werkzeugwechsel
  7. - Automatisches Nullen mit WLS
  8. - Eintauchen mit vordefinierter Tiefe
  9. - Für obige Funktionen notwendige Konfiguration
  10. Erstellt: 05.01.2021
  11. Autor: Flo Smilari
  12. */
  13. #include <Arduino.h>
  14. #include <esp32-hal.h>
  15. #include <esp32-hal-gpio.h>
  16. #include <ESP_FlexyStepper.h>
  17. #include <HardwareSerial.h>
  18. #include <pins_arduino.h>
  19. #include <RotaryEncoder.h>
  20. #include <Wire.h>
  21. #include <WString.h>
  22. #include "Display.h"
  23. #include "ExEzButton.h"
  24. #include "RotaryControler.h"
  25. #include "RouterSetup.h"
  26. #include "Status.h"
  27. #include "WLS.h"
  28. #define SDA 22
  29. #define SCX 23
  30. #define STEP 2
  31. #define DIR 4
  32. #define LIMIT_SWITCH 5
  33. static const byte led_gpio = 15;
  34. static const int WLS_Pin = 34;
  35. static const int WLS_DETECT_Pin = 35;
  36. static const int GreenBtn_Pin = 12;
  37. static const int RedBtn_Pin = 13;
  38. static const int BlueBtn_Pin = 14;
  39. static const int RotEnc_Switch_Pin = 25;
  40. static const int RotEnc_Clk_Pin = 32;
  41. static const int RotEnc_Dta_Pin = 33;
  42. static const float MOVE_DOWNWARD = -1; // motor rotation counter clock wise
  43. static const float MOVE_UPWARD = 1; // motor rotation clock wise
  44. byte limitSwitchState = 1;
  45. int previousDirection = 0;
  46. int nullingTLS_intermediateState = 0;
  47. ExEzButton RedButton(RedBtn_Pin, false, 2000);
  48. ExEzButton GreenButton(GreenBtn_Pin, false, 2000);
  49. ExEzButton BlueButton(BlueBtn_Pin, false, 2000);
  50. //ExEzButton RotarySwitch(RotEnc_Switch_Pin, true, 2000);
  51. WLS WlsDetect(WLS_DETECT_Pin, true);
  52. WLS Wls(WLS_Pin);
  53. RotaryControler RotaryControler(RotEnc_Dta_Pin, RotEnc_Clk_Pin, RotEnc_Switch_Pin);
  54. Display Display;
  55. ESP_FlexyStepper Stepper;
  56. RouterSetup Router_Setup;
  57. Status actualStatus;
  58. Status originStatus;
  59. String oldStatus = "";
  60. void printStatus(String actualStatus) {
  61. if (!oldStatus.equals(actualStatus)) {
  62. Serial.println(actualStatus);
  63. oldStatus = actualStatus;
  64. }
  65. }
  66. //**********************************
  67. //*** Limit switch interrupt routine
  68. //**********************************
  69. void limitSwitchHandler() {
  70. limitSwitchState = digitalRead(LIMIT_SWITCH);
  71. }
  72. //*****************************************************************************************************
  73. //*** Initialization routine. Reads the eeprom first and sets the (potentially new) configured values.
  74. //*****************************************************************************************************
  75. void Initialize() {
  76. Router_Setup.readFromEEPROM();
  77. Router_Setup.printValues();
  78. Display.showInitialization();
  79. //attach an interrupt to the IO pin of the limit switch and specify the handler function
  80. attachInterrupt(digitalPinToInterrupt(LIMIT_SWITCH), limitSwitchHandler, CHANGE);
  81. Stepper.connectToPins(STEP, DIR);
  82. // set the speed and acceleration rates for the stepper motor
  83. Stepper.setSpeedInStepsPerSecond(Router_Setup.getSpeed() * Router_Setup.getStepsPerRev());
  84. Stepper.setStepsPerRevolution(Router_Setup.getStepsPerRev());
  85. Stepper.setStepsPerMillimeter(Router_Setup.getStepsPerRev() / Router_Setup.getPitch());
  86. Stepper.setAccelerationInStepsPerSecondPerSecond(Router_Setup.getAcceleration() * Router_Setup.getStepsPerRev());
  87. Stepper.setDecelerationInStepsPerSecondPerSecond(Router_Setup.getAcceleration() * Router_Setup.getStepsPerRev());
  88. Stepper.startAsService(0);
  89. if (Router_Setup.isToolChangOnPowerOn()) {
  90. actualStatus = TOOL_CHANGE;
  91. } else {
  92. actualStatus = IDLE;
  93. }
  94. }
  95. //**********************
  96. //*** SETUP ************
  97. //**********************
  98. void setup() {
  99. actualStatus = INITIALIZATION;
  100. Wire.begin(SDA, SCX);
  101. Serial.begin(115200);
  102. Display.init();
  103. Display.display();
  104. pinMode(led_gpio, OUTPUT);
  105. pinMode(GreenBtn_Pin, INPUT);
  106. pinMode(RedBtn_Pin, INPUT);
  107. pinMode(BlueBtn_Pin, INPUT);
  108. pinMode(RotEnc_Switch_Pin, INPUT);
  109. pinMode(RotEnc_Clk_Pin, INPUT);
  110. pinMode(RotEnc_Dta_Pin, INPUT);
  111. pinMode(LIMIT_SWITCH, INPUT);
  112. RedButton.setDebounceTime(50); // set debounce time to 50 millis
  113. GreenButton.setDebounceTime(50);
  114. BlueButton.setDebounceTime(50);
  115. WlsDetect.setDebounceTime(50);
  116. Wls.setDebounceTime(50);
  117. RotaryControler.setDebounceTime(50);
  118. delay(1500);
  119. Display.showBrand();
  120. delay(1500);
  121. Initialize();
  122. }
  123. //**********************
  124. //*** MAIN LOOP ********
  125. //**********************
  126. void loop() {
  127. RedButton.loop(); // MUST call the loop() function first
  128. GreenButton.loop();
  129. BlueButton.loop();
  130. WlsDetect.loop();
  131. Wls.loop();
  132. RotaryControler.loop();
  133. Display.showFrame(actualStatus);
  134. switch (actualStatus) {
  135. case INITIALIZATION:
  136. Initialize();
  137. break;
  138. case TOOL_CHANGE:
  139. printStatus("TOOL_CHANGE");
  140. if (RotaryControler.isSwitchLongPressed()) {
  141. actualStatus = CONFIGURATION;
  142. } else if (BlueButton.isPressed()) {
  143. actualStatus = IDLE;
  144. }
  145. break;
  146. case CONFIGURATION:
  147. printStatus("CONFIGURATION");
  148. if (RotaryControler.isSwitchLongPressed()) {
  149. actualStatus = INITIALIZATION;
  150. } else if (BlueButton.isPressed()) {
  151. actualStatus = IDLE;
  152. }
  153. break;
  154. case NULLING:
  155. printStatus("NULLING");
  156. if (RedButton.isPressed()) {
  157. Stepper.setCurrentPositionInMillimeters(0);
  158. Stepper.setTargetPositionRelativeInMillimeters(0);
  159. actualStatus = IDLE;
  160. }
  161. break;
  162. case NULLING_TLS:
  163. originStatus = NULLING_TLS;
  164. if (nullingTLS_intermediateState == 0) {
  165. printStatus("NULLING_TLS,0");
  166. //Move elevator to lowest point (lower limit switch triggers)
  167. Stepper.setTargetPositionRelativeInMillimeters(300 * MOVE_DOWNWARD);
  168. actualStatus = MOVING_ELEVATOR;
  169. nullingTLS_intermediateState = 1;
  170. } else if (nullingTLS_intermediateState == 1) {
  171. printStatus("NULLING_TLS,1");
  172. if (RedButton.isPressed()) {
  173. //Move elevator until it touch the TLS (WLS_PIN goes HIGH)
  174. Stepper.setTargetPositionRelativeInMillimeters(300 * MOVE_UPWARD);
  175. actualStatus = MOVING_ELEVATOR;
  176. nullingTLS_intermediateState = 2;
  177. }
  178. } else if (nullingTLS_intermediateState == 2) {
  179. printStatus("NULLING_TLS,2");
  180. //Move elevator back about toolLenghtSensorHeight (will be the 0-Position)
  181. Stepper.clearLimitSwitchActive();
  182. Stepper.setTargetPositionRelativeInMillimeters(Router_Setup.getToolLenghtSensorHeight() * MOVE_DOWNWARD);
  183. Serial.println(String(Router_Setup.getToolLenghtSensorHeight() * MOVE_DOWNWARD, 2));
  184. actualStatus = MOVING_ELEVATOR;
  185. nullingTLS_intermediateState = 3;
  186. } else { // nullingTLS_intermediateState is 3
  187. printStatus("NULLING_TLS,3");
  188. //Set the 0-Position as actual position
  189. Stepper.setCurrentPositionInMillimeters(0);
  190. Stepper.setTargetPositionRelativeInMillimeters(0);
  191. actualStatus = IDLE;
  192. nullingTLS_intermediateState = 0;
  193. }
  194. break;
  195. case IDLE:
  196. printStatus("IDLE");
  197. if (RedButton.isLongPressed()) {
  198. if (WlsDetect.isConnected()) {
  199. actualStatus = NULLING_TLS;
  200. } else {
  201. actualStatus = NULLING;
  202. }
  203. } else if (BlueButton.isLongPressed()) {
  204. actualStatus = TOOL_CHANGE;
  205. }
  206. break;
  207. case DIVING:
  208. break;
  209. case MOVING_ELEVATOR:
  210. printStatus("MOVING_ELEVATOR");
  211. if (limitSwitchState == LOW) {
  212. // this will cause to stop any motion that is currently going on and block further movement in the same direction as long as the switch is active
  213. Stepper.setLimitSwitchActive(Stepper.LIMIT_SWITCH_COMBINED_BEGIN_AND_END);
  214. delay(200);
  215. actualStatus = RELEASE_SWITCH;
  216. } else { // limitSwitchState is HIGH
  217. if (Stepper.getDistanceToTargetSigned() == 0) {
  218. actualStatus = originStatus;
  219. delay(200);
  220. } else if (WlsDetect.isConnected()) {
  221. if (Wls.isPlugged()) {
  222. Serial.println("The Tool is away from WLS");
  223. Stepper.clearLimitSwitchActive();
  224. } else if (Wls.isUnplugged()) {
  225. Serial.println("The Tool touched the WLS");
  226. Stepper.setLimitSwitchActive(Stepper.LIMIT_SWITCH_COMBINED_BEGIN_AND_END);
  227. actualStatus = originStatus;
  228. delay(200);
  229. }
  230. }
  231. Stepper.clearLimitSwitchActive();
  232. previousDirection = Stepper.getDirectionOfMotion();
  233. }
  234. break;
  235. case RELEASE_SWITCH:
  236. if (limitSwitchState == LOW) {
  237. Stepper.moveRelativeInMillimeters(0.05 * previousDirection * -1); // move in opposite direction (away from switch)
  238. } else {
  239. actualStatus = originStatus;
  240. }
  241. break;
  242. default:
  243. break;
  244. }
  245. //*********************** OLD EXAMPLE AND EXPERIMENTAL CODE ************************************
  246. // if (WlsDetect.isPlugged()) {
  247. // Serial.println("The WLS was connected");
  248. // } else if (WlsDetect.isUnplugged()) {
  249. // Serial.println("The WLS was disconnected");
  250. // }
  251. //
  252. // if (WlsDetect.getStateRaw() == HIGH) {
  253. // if (Wls.isPlugged()) {
  254. // Serial.println("The Tool is away from WLS");
  255. // } else if (Wls.isUnplugged()) {
  256. // Serial.println("The Tool touched the WLS");
  257. // }
  258. // }
  259. //
  260. // if (RedButton.isPressed()) {
  261. // Serial.println("Red button was pressed");
  262. // digitalWrite(led_gpio, HIGH);
  263. // Serial.print("Limit Switch: ");
  264. // Serial.println(digitalRead(LIMIT_SWITCH) ? "HIGH" : "LOW");
  265. // }
  266. //
  267. // if (RedButton.isLongPressed()) {
  268. // Serial.println("Red button was long pressed");
  269. // digitalWrite(led_gpio, LOW);
  270. // }
  271. //
  272. // bool greenPressed = GreenButton.isPressed();
  273. // bool bluePressed = BlueButton.isPressed();
  274. //
  275. // if (GreenButton.isPressing() && BlueButton.isPressing()) {
  276. // Serial.println("Blue and green button were simultaneous pressed");
  277. // } else if (greenPressed) {
  278. // Serial.println("Green button was pressed");
  279. // } else if (bluePressed) {
  280. // Serial.println("Blue button was pressed");
  281. // }
  282. //
  283. // if (RotarySwitch.isPressed()) {
  284. // Serial.println("Rotary switch was pressed");
  285. // }
  286. // if (RotarySwitch.isLongPressed()) {
  287. // Serial.println("Rotary switch long was pressed");
  288. // }
  289. //
  290. // static int pos = 0;
  291. //RotaryControler.tick();
  292. //int newPos = RotaryControler.getPosition();
  293. // if (pos != newPos) {
  294. // Serial.print("pos:");
  295. // Serial.print(newPos);
  296. // Serial.print(" dir:");
  297. // Serial.println((int) (RotaryControler.getDirection()));
  298. // pos = newPos;
  299. // }
  300. // if (limitSwitchState == LOW) {
  301. // stepper.setLimitSwitchActive(stepper.LIMIT_SWITCH_COMBINED_BEGIN_AND_END); // this will cause to stop any motion that is currently going on and block further movement in the same direction as long as the switch is agtive
  302. // } else {
  303. // stepper.clearLimitSwitchActive(); // clear the limit switch flag to allow movement in both directions again
  304. // }
  305. //
  306. // if (limitSwitchState == HIGH && stepper.getDistanceToTargetSigned() == 0) {
  307. // delay(100);
  308. // previousDirection *= -1;
  309. // long relativeTargetPosition = DISTANCE_TO_TRAVEL_IN_STEPS * previousDirection;
  310. // Serial.printf("Moving stepper by %ld steps\n", relativeTargetPosition);
  311. // stepper.setTargetPositionRelativeInSteps(relativeTargetPosition);
  312. // }
  313. }
  314. //void testdrawchar(void) {
  315. // OLED.clearDisplay();
  316. //
  317. // OLED.setTextSize(1); // Normal 1:1 pixel scale
  318. // OLED.setTextColor(SSD1306_WHITE); // Draw white text
  319. // OLED.setCursor(0, 0); // Start at top-left corner
  320. // OLED.cp437(true); // Use full 256 char 'Code Page 437' font
  321. //
  322. // // Not all the characters will fit on the Display. This is normal.
  323. // // Library will draw what it can and the rest will be clipped.
  324. // for (int16_t i = 0; i < 256; i++) {
  325. // if (i == '\n')
  326. // OLED.write(' ');
  327. // else
  328. // OLED.write(i);
  329. // }
  330. //
  331. // OLED.display();
  332. // delay(2000);
  333. //}
  334. //
  335. //void testdrawstyles(void) {
  336. // OLED.clearDisplay();
  337. // Display.setFont(&Rubik_Regular8pt7b);
  338. // Display.setTextSize(1); // Normal 1:1 pixel scale
  339. // Display.setTextColor(SSD1306_WHITE); // Draw white text
  340. // Display.setCursor(0, 8); // Start at top-left corner
  341. // Display.println(F("Hello, world!"));
  342. //
  343. // Display.setFont(&Rubik_Regular12pt7b);
  344. // Display.setTextSize(1); // Normal 1:1 pixel scale
  345. // Display.setTextColor(SSD1306_WHITE); // Draw white text
  346. // Display.setCursor(0, 24); // Start at top-left corner
  347. // Display.println(F("Hello, world!"));
  348. // Display.drawRect(0, 15, 128, 13, SSD1306_WHITE);
  349. // Display.setFont(&Rubik_Regular24pt7b);
  350. // Display.setTextSize(1); // Normal 1:1 pixel scale
  351. // Display.setTextColor(SSD1306_WHITE); // Draw white text
  352. // Display.setCursor(0, 55); // Start at top-left corner
  353. // Display.println(F("Hello, world!"));
  354. //
  355. // Display.display();
  356. // delay(2000);
  357. //
  358. // Display.clearDisplay();
  359. // char decimals[3];
  360. // uint16_t w = 0, h = 0;
  361. // for (int i = 0; i <= 99; i++) {
  362. // OLED.clearDisplay();
  363. // OLED.drawRect(0, 0, 128, 64, SSD1306_WHITE);
  364. // OLED.setFont(&titillium_web_semibold30pt7b);
  365. // OLED.setTextSize(1); // Normal 1:1 pixel scale
  366. // OLED.setTextColor(SSD1306_WHITE); // Draw white text
  367. // sprintf(decimals, "%02d", i);
  368. // if (i < 33) {
  369. // calculateWH("99.", w, h);
  370. // OLED.setCursor((SCREEN_WIDTH / 2 - 1) - w, SCREEN_HEIGHT / 2 + h / 2);
  371. // OLED.print("99.");
  372. // } else if (i >= 33 && i < 66) {
  373. // calculateWH("01.", w, h);
  374. // OLED.setCursor((SCREEN_WIDTH / 2 - 1) - w, SCREEN_HEIGHT / 2 + h / 2);
  375. // OLED.print("01.");
  376. // } else {
  377. // calculateWH("55.", w, h);
  378. // OLED.setCursor((SCREEN_WIDTH / 2 - 1) - w, SCREEN_HEIGHT / 2 + h / 2);
  379. // OLED.print("55.");
  380. // }
  381. // OLED.println(decimals);
  382. // OLED.display();
  383. // delay(100);
  384. // }
  385. // Display.setFont(&Rubik_Regular30pt7b);
  386. // Display.setTextSize(1); // Normal 1:1 pixel scale
  387. // Display.setTextColor(SSD1306_WHITE); // Draw white text
  388. // Display.setCursor(0, 55); // Start at top-left corner
  389. // Display.println(F("99.99"));
  390. //
  391. // Display.display();
  392. // delay(1000);
  393. //
  394. // Display.clearDisplay();
  395. //
  396. // Display.setFont(&Rubik_Regular30pt7b);
  397. // Display.setTextSize(1); // Normal 1:1 pixel scale
  398. // Display.setTextColor(SSD1306_WHITE); // Draw white text
  399. // Display.setCursor(0, 55); // Start at top-left corner
  400. // Display.println(F("01.11"));
  401. // Display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // Draw 'inverse' text
  402. // Display.println("3.141592");
  403. //
  404. // Display.setTextSize(2); // Draw 2X-scale text
  405. // Display.setTextColor(SSD1306_WHITE);
  406. // Display.print(F("0x"));
  407. // Display.println(0xDEADBEEF, HEX);
  408. //
  409. // OLED.display();
  410. // delay(2000);
  411. //}
  412. //void calculateWH(String units, uint16_t &w, uint16_t &h) {
  413. // int x = 0;
  414. // int y = 0;
  415. // int16_t x1, y1;
  416. // uint16_t w1, h1;
  417. //
  418. // OLED.getTextBounds(units, x, y, &x1, &y1, &w1, &h1);
  419. // w = w1;
  420. // h = h1;
  421. //}