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 15KB

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