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

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