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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. /*
  2. * Display.cpp
  3. *
  4. * Wrapper class for Adafruit OLED display.
  5. *
  6. * Created on: 28.01.2022
  7. * Author: FSmilari
  8. */
  9. #include "Display.h"
  10. // Array of all bitmaps for convenience. (Total bytes used to store images in PROGMEM = 48)
  11. const int epd_rotate_bitmap_allArray_LEN = 8;
  12. const static unsigned char *epd_rotate_bitmap_allArray[epd_rotate_bitmap_allArray_LEN] = {
  13. epd_bitmap_Rotate_0,
  14. epd_bitmap_Rotate_45,
  15. epd_bitmap_Rotate_90,
  16. epd_bitmap_Rotate_135,
  17. epd_bitmap_Rotate_180,
  18. epd_bitmap_Rotate_225,
  19. epd_bitmap_Rotate_270,
  20. epd_bitmap_Rotate_315
  21. };
  22. /*****************
  23. ** Constructors.
  24. ****************/
  25. Display::Display() : mode(FAST) {
  26. ssd1306 = Adafruit_SSD1306(SCREEN_WIDTH, SCREEN_HEIGHT);
  27. u8g2_gfx.begin(ssd1306);
  28. wlsConnected = false;
  29. angle = 0;
  30. starttime = millis();
  31. refreshScreen = true;
  32. distanceValue = 0.0;
  33. distanceUnit = "mm";
  34. maxDiveDistance = 0.0;
  35. levelHeightDiving = 0.0;
  36. }
  37. /******************
  38. ** Public methods
  39. *****************/
  40. void Display::init() {
  41. if (!ssd1306.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS, true, true)) {
  42. Serial.println(F("SSD1306 allocation failed"));
  43. for (;;)
  44. ; // Don't proceed, loop forever
  45. }
  46. }
  47. void Display::setRefreshScreen() {
  48. refreshScreen = true;
  49. }
  50. void Display::display() {
  51. if (refreshScreen) {
  52. refreshScreen = false;
  53. ssd1306.display();
  54. }
  55. }
  56. void Display::clearDisplay() {
  57. ssd1306.clearDisplay();
  58. }
  59. void Display::showBrand() {
  60. ssd1306.clearDisplay();
  61. ssd1306.drawBitmap(0, 0, epd_bitmap_SFTools_Logo, imageWidth, imageHeight, SSD1306_WHITE);
  62. char *s = &String("Frästisch N172")[0];
  63. int16_t w = 0, h = 0;
  64. u8g2_gfx.setFont(u8g2_font_helvB12_tf);
  65. w = u8g2_gfx.getUTF8Width(s);
  66. h = u8g2_gfx.getFontAscent() - u8g2_gfx.getFontDescent();
  67. u8g2_gfx.setForegroundColor(SSD1306_WHITE);
  68. u8g2_gfx.setCursor((SCREEN_WIDTH - w) / 2, 63 - (30 - h) / 2);
  69. u8g2_gfx.println(F(s));
  70. display();
  71. }
  72. void Display::showInitialization() {
  73. ssd1306.clearDisplay();
  74. char *s = &String("Initialisieren")[0];
  75. int16_t w = 0;
  76. u8g2_gfx.setFont(u8g2_font_helvB12_tf);
  77. w = u8g2_gfx.getUTF8Width(s);
  78. u8g2_gfx.setForegroundColor(SSD1306_WHITE);
  79. u8g2_gfx.setCursor((SCREEN_WIDTH - w) / 2, 30);
  80. u8g2_gfx.println(F(s));
  81. char *g;
  82. w = u8g2_gfx.getUTF8Width(". . . . .");
  83. u8g2_gfx.setCursor((SCREEN_WIDTH - w) / 2, 50);
  84. String gauge = "";
  85. for (int i = 0; i < 6; i++) {
  86. g = &gauge[0];
  87. u8g2_gfx.print(g);
  88. setRefreshScreen();
  89. display();
  90. delay(500);
  91. if (i < 4) {
  92. gauge = ". ";
  93. g = &gauge[0];
  94. } else {
  95. gauge = ".";
  96. g = &gauge[0];
  97. }
  98. }
  99. }
  100. void Display::showFrame(Status status) {
  101. switch (status) {
  102. case MOVING_ELEVATOR:
  103. rotateAndDrawRotationBitmap();
  104. break;
  105. case TOOL_CHANGE:
  106. redrawFrame();
  107. drawStatusText(STATUS_TXT_TOOLCHG);
  108. drawBitmap(37 + (SCREEN_WIDTH - 37 - imageSide) / 2, (SCREEN_HEIGHT - imageSide) / 2, imageSide, imageSide, epd_bitmap_Tools);
  109. break;
  110. case CONFIGURATION:
  111. redrawFrame();
  112. ssd1306.drawLine(37, SCREEN_HEIGHT / 2 - 1, SCREEN_WIDTH - 1, SCREEN_HEIGHT / 2 - 1, SSD1306_WHITE);
  113. drawStatusText(STATUS_TXT_CFG);
  114. drawConfigText(this->configText);
  115. drawConfigOption(this->configOption);
  116. break;
  117. case IDLE:
  118. redrawFrame();
  119. ssd1306.drawLine(37, 43, SCREEN_WIDTH - 1, 43, SSD1306_WHITE);
  120. drawStatusText(STATUS_TXT_IDLE);
  121. drawDistanceValue(distanceValue);
  122. drawDistanceUnit(distanceUnit);
  123. drawMode(this->mode);
  124. break;
  125. case NULLING:
  126. case NULLING_TLS:
  127. redrawFrame();
  128. drawStatusText(STATUS_TXT_NULLING);
  129. drawBitmap(37 + (SCREEN_WIDTH - 37 - imageSide) / 2, (SCREEN_HEIGHT - imageSide) / 2, imageSide, imageSide, epd_bitmap_Nulling);
  130. break;
  131. case DIVING:
  132. redrawFrame();
  133. drawStatusText(STATUS_TXT_DIVING);
  134. drawBitmap((37 - imageSide_R) / 2, 47, imageSide_D, imageSide_D, epd_bitmap_Dive);
  135. drawDistanceValue(distanceValue);
  136. drawDistanceUnit(distanceUnit);
  137. drawActualDiveStep(maxDiveDistance, levelHeightDiving, distanceValue);
  138. drawMaxDiveDistance(maxDiveDistance);
  139. break;
  140. default:
  141. break;
  142. }
  143. display();
  144. }
  145. void Display::drawConfigText(String txt) {
  146. char *s = &txt[0];
  147. int16_t w = 0, h = 0;
  148. u8g2_gfx.setFont(u8g2_font_helvB12_tf); // select u8g2 font from here: https://github.com/olikraus/u8g2/wiki/fntlistall
  149. w = u8g2_gfx.getUTF8Width(s);
  150. h = u8g2_gfx.getFontAscent() - u8g2_gfx.getFontDescent();
  151. u8g2_gfx.setCursor((SCREEN_WIDTH + 37 - w) / 2, SCREEN_HEIGHT / 4 + h / 2 - 1); // start writing at this position
  152. u8g2_gfx.println(F(s));
  153. }
  154. void Display::drawConfigOption(String txt) {
  155. char *s = &txt[0];
  156. int16_t w = 0, h = 0;
  157. u8g2_gfx.setFont(u8g2_font_helvB12_tf);
  158. w = u8g2_gfx.getUTF8Width(s);
  159. h = u8g2_gfx.getFontAscent() - u8g2_gfx.getFontDescent();
  160. u8g2_gfx.setCursor((SCREEN_WIDTH + 37 - w) / 2, SCREEN_HEIGHT / 4 * 3 + h / 2 - 1);
  161. u8g2_gfx.println(F(s));
  162. }
  163. const String& Display::getConfigOption() const {
  164. return configOption;
  165. }
  166. void Display::setConfigOption(const String &configOption) {
  167. if (!this->configOption.equals(configOption)) {
  168. this->configOption = configOption;
  169. setRefreshScreen();
  170. }
  171. }
  172. const String& Display::getConfigText() const {
  173. return configText;
  174. }
  175. void Display::setConfigText(const String &configText) {
  176. if (!this->configText.equals(configText)) {
  177. this->configText = configText;
  178. setRefreshScreen();
  179. }
  180. }
  181. void Display::setWlsConnected(bool wlsConnected) {
  182. if (this->wlsConnected != wlsConnected) {
  183. this->wlsConnected = wlsConnected;
  184. setRefreshScreen();
  185. }
  186. }
  187. void Display::setLevelHeightDiving(float levelHeightDiving) {
  188. if (this->levelHeightDiving != levelHeightDiving) {
  189. this->levelHeightDiving = levelHeightDiving;
  190. setRefreshScreen();
  191. }
  192. }
  193. void Display::setMaxDiveDistance(float maxDiveDistance) {
  194. if (this->maxDiveDistance != maxDiveDistance) {
  195. this->maxDiveDistance = maxDiveDistance;
  196. setRefreshScreen();
  197. }
  198. }
  199. void Display::setDistanceUnit(const String &distanceUnit) {
  200. if (this->distanceUnit != distanceUnit) {
  201. this->distanceUnit = distanceUnit;
  202. setRefreshScreen();
  203. }
  204. }
  205. void Display::setDistanceValue(const float &distanceValue) {
  206. if (this->distanceValue != distanceValue) {
  207. this->distanceValue = distanceValue;
  208. setRefreshScreen();
  209. }
  210. }
  211. void Display::setMode(const ValueMode &mode) {
  212. if (!this->mode.equals(mode)) {
  213. this->mode = mode;
  214. setRefreshScreen();
  215. }
  216. }
  217. void Display::drawWLSStatus() {
  218. String txt = wlsConnected ? "WLS" : "";
  219. char *s = &txt[0];
  220. int16_t w = 0;
  221. u8g2_gfx.setFont(u8g2_font_helvR08_tf); // select u8g2 font from here: https://github.com/olikraus/u8g2/wiki/fntlistall
  222. w = u8g2_gfx.getUTF8Width(s);
  223. u8g2_gfx.setCursor((37 - w) / 2, 27);
  224. u8g2_gfx.println(F(s));
  225. }
  226. void Display::drawMode(ValueMode mode) {
  227. String txt = mode.toString();
  228. char *s = &txt[0];
  229. int16_t w = 0;
  230. u8g2_gfx.setFont(u8g2_font_helvB08_tf);
  231. w = u8g2_gfx.getUTF8Width(s);
  232. u8g2_gfx.setCursor((SCREEN_WIDTH - w - 6), 63 - 6);
  233. u8g2_gfx.println(F(s));
  234. }
  235. void Display::drawDistanceValue(float distance) {
  236. String txt = String(distance, 2);
  237. if (txt.equals("-0.00")) {
  238. txt.replace("-", "");
  239. }
  240. char *s = &txt[0];
  241. int16_t w = 0, h = 0;
  242. u8g2_gfx.setFont(u8g2_font_logisoso22_tf);
  243. w = u8g2_gfx.getUTF8Width(s);
  244. h = u8g2_gfx.getFontAscent() - u8g2_gfx.getFontDescent();
  245. u8g2_gfx.setCursor((SCREEN_WIDTH - w - 6), h);
  246. u8g2_gfx.println(F(s));
  247. }
  248. void Display::drawDistanceUnit(String unit) {
  249. String txt = unit;
  250. char *s = &txt[0];
  251. int16_t w = 0;
  252. u8g2_gfx.setFont(u8g2_font_helvB12_tf);
  253. w = u8g2_gfx.getUTF8Width(s);
  254. u8g2_gfx.setCursor((SCREEN_WIDTH - w - 6), 41);
  255. u8g2_gfx.println(F(s));
  256. }
  257. void Display::drawMaxDiveDistance(float maxDiveDistance) {
  258. String txt = String(maxDiveDistance, 2) + "mm";
  259. char *s = &txt[0];
  260. int16_t w = 0;
  261. u8g2_gfx.setFont(u8g2_font_helvB10_tf);
  262. w = u8g2_gfx.getUTF8Width(s);
  263. u8g2_gfx.setCursor((SCREEN_WIDTH - w - 6), 59);
  264. u8g2_gfx.println(F(s));
  265. }
  266. void Display::drawActualDiveStep(float maxDiveDistance, float levelHeightDiving, float distance) {
  267. int totalSteps = ceil(maxDiveDistance / levelHeightDiving);
  268. int actualStep = ceil(distance / levelHeightDiving);
  269. String txt = String(actualStep) + "/" + String(totalSteps);
  270. char *s = &txt[0];
  271. int16_t w = 0;
  272. u8g2_gfx.setFont(u8g2_font_helvB10_tf);
  273. w = u8g2_gfx.getUTF8Width(s);
  274. u8g2_gfx.setCursor(42, 59);
  275. u8g2_gfx.println(F(s));
  276. }
  277. /********************************
  278. ** Private methods
  279. *******************************/
  280. void Display::drawStatusText(String txt) {
  281. char *s = &txt[0];
  282. int16_t w = 0;
  283. u8g2_gfx.setFont(u8g2_font_helvR08_tf); // select u8g2 font from here: https://github.com/olikraus/u8g2/wiki/fntlistall
  284. w = u8g2_gfx.getUTF8Width(s);
  285. u8g2_gfx.setCursor((37 - w) / 2, 12);
  286. u8g2_gfx.println(F(s));
  287. }
  288. void Display::drawBitmap(int x, int y, int w, int h, const uint8_t bitmap[]) {
  289. ssd1306.drawBitmap(x, y, bitmap, w, h, SSD1306_WHITE);
  290. }
  291. void Display::redrawFrame() {
  292. ssd1306.clearDisplay();
  293. ssd1306.drawRoundRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 3, SSD1306_WHITE);
  294. ssd1306.drawLine(37, 0, 37, SCREEN_HEIGHT - 1, SSD1306_WHITE);
  295. ssd1306.drawLine(0, 15, 37, 15, SSD1306_WHITE);
  296. drawWLSStatus();
  297. }
  298. void Display::rotateAndDrawRotationBitmap() {
  299. if (millis() - starttime >= 125) {
  300. int xOffset = 0;
  301. int yOffset = 0;
  302. switch (angle) {
  303. case 0:
  304. xOffset = imageSide_R / 2;
  305. yOffset = 0;
  306. break;
  307. case 1:
  308. xOffset = imageSide_R / 2;
  309. yOffset = imageSide_R / 4;
  310. break;
  311. case 2:
  312. xOffset = imageSide_R / 2;
  313. yOffset = imageSide_R / 2;
  314. break;
  315. case 3:
  316. xOffset = imageSide_R / 4;
  317. yOffset = imageSide_R / 2;
  318. break;
  319. case 4:
  320. xOffset = 0;
  321. yOffset = imageSide_R / 2;
  322. break;
  323. case 5:
  324. xOffset = 0;
  325. yOffset = imageSide_R / 4;
  326. break;
  327. case 6:
  328. xOffset = 0;
  329. yOffset = 0;
  330. break;
  331. case 7:
  332. xOffset = imageSide_R / 4;
  333. yOffset = 0;
  334. break;
  335. default:
  336. break;
  337. }
  338. ssd1306.fillRect((37 - imageSide_R) / 2 + xOffset, 30 + yOffset, imageSide_R / 2 + 1, imageSide_R / 2 + 1, SSD1306_BLACK);
  339. ssd1306.display();
  340. drawBitmap((37 - imageSide_R) / 2, 30, imageSide_R, imageSide_R, epd_rotate_bitmap_allArray[angle]);
  341. angle = (angle + 1) % 8;
  342. starttime = millis();
  343. setRefreshScreen();
  344. display();
  345. }
  346. }