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

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