暫無描述
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.

lcd.cpp 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. #include <Arduino.h>
  2. #include "config.h"
  3. #include "config_pins.h"
  4. #include "lcd.h"
  5. #if (defined(USE_20X4_TEXT_LCD) && defined(USE_FULL_GRAPHIC_LCD)) || (!defined(USE_20X4_TEXT_LCD) && !defined(USE_FULL_GRAPHIC_LCD))
  6. #error define one of USE_20X4_TEXT_LCD or USE_FULL_GRAPHIC_LCD
  7. #endif
  8. #ifdef USE_20X4_TEXT_LCD
  9. #include <LiquidCrystal.h>
  10. #define LCD_HEADING_LINES 1
  11. #define LCD_HEADING_WIDTH 20
  12. #define LCD_TEXT_LINES 3
  13. #define LCD_TEXT_WIDTH 20
  14. LiquidCrystal lcd(LCD_PINS_RS, LCD_PINS_ENABLE, LCD_PINS_D4, LCD_PINS_D5, LCD_PINS_D6, LCD_PINS_D7);
  15. #endif // USE_20X4_TEXT_LCD
  16. #ifdef USE_FULL_GRAPHIC_LCD
  17. #include <U8g2lib.h>
  18. #define LCD_HEADING_LINES 1
  19. #define LCD_HEADING_WIDTH 15
  20. #define LCD_TEXT_LINES 5
  21. #define LCD_TEXT_WIDTH 25
  22. #define LCD_HEADING_FONT u8g2_font_torussansbold8_8r
  23. #define LCD_TEXT_FONT u8g2_font_5x7_tr
  24. #define LCD_HEADING_TEXT_OFFSET 3
  25. #define LCD_HEADING_HEIGHT 8
  26. #define LCD_TEXT_HEIGHT 9
  27. U8G2_ST7920_128X64_1_SW_SPI lcd(U8G2_R0, LCD_PINS_SCK, LCD_PINS_MOSI, LCD_PINS_CS);
  28. #endif // USE_FULL_GRAPHIC_LCD
  29. String heading[LCD_HEADING_LINES];
  30. String text[LCD_TEXT_LINES];
  31. String heading_pre, heading_post;
  32. String text_pre, text_post;
  33. int heading_direction, text_direction;
  34. String menu_pre[LCD_TEXT_LINES], menu_post[LCD_TEXT_LINES];
  35. int menu_dir[LCD_TEXT_LINES];
  36. boolean redraw = false;
  37. enum lcd_text_mode {
  38. lcd_mode_none,
  39. lcd_mode_multiline,
  40. lcd_mode_menu
  41. };
  42. enum lcd_text_mode text_mode = lcd_mode_none;
  43. #define SCROLL_DELAY 500
  44. unsigned long last_scroll_time = 0;
  45. void lcd_shorten_multiline(String s[], int n, int w, String *remainder) {
  46. // if a line is longer then w, take end off and put in front of next line
  47. String for_next_line = "";
  48. for (int i = 0; i < n; i++) {
  49. s[i] = for_next_line + s[i];
  50. for_next_line = "";
  51. if (s[i].length() > w) {
  52. for_next_line = s[i].substring(w);
  53. s[i] = s[i].substring(0, w);
  54. }
  55. }
  56. // if something remains at end, store remainder, if given, otherwise leave at last line
  57. if (remainder != NULL) {
  58. *remainder = for_next_line;
  59. } else {
  60. s[n - 1] = s[n - 1] + for_next_line;
  61. }
  62. last_scroll_time = millis();
  63. }
  64. void lcd_scroll_multiline(String s[], int n, int w, String &pre, String &post, int &dir) {
  65. if (dir == 0) {
  66. // switch directions if done scrolling in current direction
  67. if (post.length() == 0) {
  68. dir = 1;
  69. return;
  70. }
  71. // take first char of first line, append to pre
  72. pre = pre + s[0][0];
  73. s[0] = s[0].substring(1);
  74. // shift now empty spot to the left through lines
  75. for (int i = 1; i < n; i++) {
  76. s[i - 1] = s[i - 1] + s[i][0];
  77. s[i] = s[i].substring(1);
  78. }
  79. // fill empty spot at end of last line with first char of post
  80. s[n - 1] = s[n - 1] + post[0];
  81. post = post.substring(1);
  82. } else {
  83. // switch directions if done scrolling in current direction
  84. if (pre.length() == 0) {
  85. dir = 0;
  86. return;
  87. }
  88. // take last char of last line, prepend to post
  89. post = s[n - 1][s[n - 1].length() - 1] + post;
  90. s[n - 1] = s[n - 1].substring(0, s[n - 1].length() - 1);
  91. // shift now empty sport to the right through lines
  92. for (int i = n - 1; i >= 1; i--) {
  93. s[i] = s[i - 1][s[i - 1].length() - 1] + s[i];
  94. s[i - 1] = s[i - 1].substring(0, s[i - 1].length() - 1);
  95. }
  96. // fill empty spot at beginning with last char of pre
  97. s[0] = pre[pre.length() - 1] + s[0];
  98. pre = pre.substring(0, pre.length() - 1);
  99. }
  100. redraw = true;
  101. }
  102. void lcd_scrolling(void) {
  103. if (text_mode != lcd_mode_none) {
  104. if ((heading_pre.length() > 0) || (heading_post.length() > 0)) {
  105. lcd_scroll_multiline(heading, LCD_HEADING_LINES, LCD_HEADING_WIDTH,
  106. heading_pre, heading_post, heading_direction);
  107. }
  108. }
  109. if (text_mode == lcd_mode_multiline) {
  110. if ((text_pre.length() > 0) || (text_post.length() > 0)) {
  111. lcd_scroll_multiline(text, LCD_TEXT_LINES, LCD_TEXT_WIDTH,
  112. text_pre, text_post, text_direction);
  113. }
  114. } else if (text_mode == lcd_mode_menu) {
  115. for (int i = 0; i < LCD_TEXT_LINES; i++) {
  116. if ((menu_pre[i].length() > 0) || (menu_post[i].length() > 0)) {
  117. lcd_scroll_multiline(text + i, 1, LCD_TEXT_WIDTH,
  118. menu_pre[i], menu_post[i], menu_dir[i]);
  119. }
  120. }
  121. }
  122. }
  123. int lcd_text_lines(void) {
  124. return LCD_TEXT_LINES;
  125. }
  126. void lcd_init(void) {
  127. #ifdef USE_20X4_TEXT_LCD
  128. lcd.begin(20, 4);
  129. lcd.clear();
  130. lcd.print(F(" Fuellfix v2 "));
  131. lcd.print(F(" Initializing.... "));
  132. lcd.print(F("Software Version "));
  133. lcd.print(F(FIRMWARE_VERSION));
  134. lcd.print(F("made by: xythobuz.de"));
  135. #endif // USE_20X4_TEXT_LCD
  136. #ifdef USE_FULL_GRAPHIC_LCD
  137. lcd.begin();
  138. lcd.firstPage();
  139. do {
  140. lcd.setFont(u8g2_font_luBS12_tr);
  141. lcd.drawStr(0, 14 * 1, "Fuellfix v2");
  142. lcd.drawStr(0, 14 * 2, "Initializing");
  143. lcd.setFont(u8g2_font_t0_12b_tr);
  144. lcd.drawStr(0, 14 * 2 + 8 + 12 * 1, "Software Version " FIRMWARE_VERSION);
  145. lcd.drawStr(0, 14 * 2 + 8 + 12 * 2, "made by: xythobuz.de");
  146. } while (lcd.nextPage());
  147. #endif // USE_FULL_GRAPHIC_LCD
  148. }
  149. void lcd_loop(void) {
  150. if ((millis() - last_scroll_time) >= SCROLL_DELAY) {
  151. last_scroll_time = millis();
  152. lcd_scrolling();
  153. }
  154. #ifdef USE_FULL_GRAPHIC_LCD
  155. if (redraw) {
  156. lcd.firstPage();
  157. do {
  158. lcd.setFont(LCD_HEADING_FONT);
  159. for (int i = 0; i < LCD_HEADING_LINES; i++) {
  160. lcd.drawStr(0, LCD_HEADING_HEIGHT * (i + 1), heading[i].c_str());
  161. }
  162. lcd.setFont(LCD_TEXT_FONT);
  163. for (int i = 0; i < LCD_TEXT_LINES; i++) {
  164. lcd.drawStr(0, LCD_HEADING_HEIGHT * LCD_HEADING_LINES + LCD_HEADING_TEXT_OFFSET + LCD_TEXT_HEIGHT * (i + 1), text[i].c_str());
  165. }
  166. } while (lcd.nextPage());
  167. redraw = false;
  168. }
  169. #endif // USE_FULL_GRAPHIC_LCD
  170. }
  171. void lcd_clear(void) {
  172. Serial.println();
  173. text_mode = lcd_mode_none;
  174. #ifdef USE_20X4_TEXT_LCD
  175. lcd.clear();
  176. #endif // USE_20X4_TEXT_LCD
  177. #ifdef USE_FULL_GRAPHIC_LCD
  178. for (int i = 0; i < LCD_HEADING_LINES; i++) {
  179. heading[i] = "";
  180. }
  181. for (int i = 0; i < LCD_TEXT_LINES; i++) {
  182. text[i] = "";
  183. }
  184. redraw = true;
  185. #endif // USE_FULL_GRAPHIC_LCD
  186. }
  187. void lcd_set_heading(const char *h) {
  188. Serial.println(h);
  189. #ifdef USE_20X4_TEXT_LCD
  190. lcd.setCursor(0, 0);
  191. lcd.print(h);
  192. #endif // USE_20X4_TEXT_LCD
  193. #ifdef USE_FULL_GRAPHIC_LCD
  194. heading[0] = h;
  195. heading_pre = "";
  196. heading_direction = 0;
  197. lcd_shorten_multiline(heading, LCD_HEADING_LINES, LCD_HEADING_WIDTH, &heading_post);
  198. redraw = true;
  199. #endif // USE_FULL_GRAPHIC_LCD
  200. }
  201. void lcd_set_text(const char *t) {
  202. Serial.println(t);
  203. text_mode = lcd_mode_multiline;
  204. #ifdef USE_20X4_TEXT_LCD
  205. lcd.setCursor(0, LCD_HEADING_LINES);
  206. lcd.print(t);
  207. #endif // USE_20X4_TEXT_LCD
  208. #ifdef USE_FULL_GRAPHIC_LCD
  209. text[0] = t;
  210. text_pre = "";
  211. text_direction = 0;
  212. lcd_shorten_multiline(text, LCD_TEXT_LINES, LCD_TEXT_WIDTH, &text_post);
  213. redraw = true;
  214. #endif // USE_FULL_GRAPHIC_LCD
  215. }
  216. void lcd_set_menu_text(int line, const char *t) {
  217. Serial.print(line);
  218. Serial.print(": ");
  219. Serial.println(t);
  220. text_mode = lcd_mode_menu;
  221. #ifdef USE_20X4_TEXT_LCD
  222. lcd.setCursor(0, LCD_HEADING_LINES + line);
  223. lcd.print(t);
  224. #endif // USE_20X4_TEXT_LCD
  225. #ifdef USE_FULL_GRAPHIC_LCD
  226. text[line] = t;
  227. menu_pre[line] = "";
  228. menu_dir[line] = 0;
  229. lcd_shorten_multiline(text + line, 1, LCD_TEXT_WIDTH, menu_post + line);
  230. redraw = true;
  231. #endif // USE_FULL_GRAPHIC_LCD
  232. }