Frästisch mit elektronischer Höhenverstellung mittels Schrittmotoren.
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.

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. //}