My Marlin configs for Fabrikator Mini and CTC i3 Pro B
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.

ultralcd_implementation_hitachi_HD44780.h 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. #ifndef ULTRA_LCD_IMPLEMENTATION_HITACHI_HD44780_H
  2. #define ULTRA_LCD_IMPLEMENTATION_HITACHI_HD44780_H
  3. /**
  4. * Implementation of the LCD display routines for a hitachi HD44780 display. These are common LCD character displays.
  5. * When selecting the rusian language, a slightly different LCD implementation is used to handle UTF8 characters.
  6. **/
  7. #if LANGUAGE_CHOICE == 6
  8. #include "LiquidCrystalRus.h"
  9. #define LCD_CLASS LiquidCrystalRus
  10. #else
  11. #include <LiquidCrystal.h>
  12. #define LCD_CLASS LiquidCrystal
  13. #endif
  14. /* Custom characters defined in the first 8 characters of the LCD */
  15. #define LCD_STR_BEDTEMP "\x00"
  16. #define LCD_STR_DEGREE "\x01"
  17. #define LCD_STR_THERMOMETER "\x02"
  18. #define LCD_STR_UPLEVEL "\x03"
  19. #define LCD_STR_REFRESH "\x04"
  20. #define LCD_STR_FOLDER "\x05"
  21. #define LCD_STR_FEEDRATE "\x06"
  22. #define LCD_STR_CLOCK "\x07"
  23. #define LCD_STR_ARROW_RIGHT "\x7E" /* from the default character set */
  24. LiquidCrystal lcd(LCD_PINS_RS, LCD_PINS_ENABLE, LCD_PINS_D4, LCD_PINS_D5,LCD_PINS_D6,LCD_PINS_D7); //RS,Enable,D4,D5,D6,D7
  25. static void lcd_implementation_init()
  26. {
  27. byte bedTemp[8] =
  28. {
  29. B00000,
  30. B11111,
  31. B10101,
  32. B10001,
  33. B10101,
  34. B11111,
  35. B00000,
  36. B00000
  37. }; //thanks Sonny Mounicou
  38. byte degree[8] =
  39. {
  40. B01100,
  41. B10010,
  42. B10010,
  43. B01100,
  44. B00000,
  45. B00000,
  46. B00000,
  47. B00000
  48. };
  49. byte thermometer[8] =
  50. {
  51. B00100,
  52. B01010,
  53. B01010,
  54. B01010,
  55. B01010,
  56. B10001,
  57. B10001,
  58. B01110
  59. };
  60. byte uplevel[8]={
  61. B00100,
  62. B01110,
  63. B11111,
  64. B00100,
  65. B11100,
  66. B00000,
  67. B00000,
  68. B00000
  69. }; //thanks joris
  70. byte refresh[8]={
  71. B00000,
  72. B00110,
  73. B11001,
  74. B11000,
  75. B00011,
  76. B10011,
  77. B01100,
  78. B00000,
  79. }; //thanks joris
  80. byte folder [8]={
  81. B00000,
  82. B11100,
  83. B11111,
  84. B10001,
  85. B10001,
  86. B11111,
  87. B00000,
  88. B00000
  89. }; //thanks joris
  90. byte feedrate [8]={
  91. B11100,
  92. B10000,
  93. B11000,
  94. B10111,
  95. B00101,
  96. B00110,
  97. B00101,
  98. B00000
  99. }; //thanks Sonny Mounicou
  100. byte clock [8]={
  101. B00000,
  102. B01110,
  103. B10011,
  104. B10101,
  105. B10001,
  106. B01110,
  107. B00000,
  108. B00000
  109. }; //thanks Sonny Mounicou
  110. lcd.begin(LCD_WIDTH, LCD_HEIGHT);
  111. lcd.createChar(LCD_STR_BEDTEMP[0], bedTemp);
  112. lcd.createChar(LCD_STR_DEGREE[0], degree);
  113. lcd.createChar(LCD_STR_THERMOMETER[0], thermometer);
  114. lcd.createChar(LCD_STR_UPLEVEL[0], uplevel);
  115. lcd.createChar(LCD_STR_REFRESH[0], refresh);
  116. lcd.createChar(LCD_STR_FOLDER[0], folder);
  117. lcd.createChar(LCD_STR_FEEDRATE[0], feedrate);
  118. lcd.createChar(LCD_STR_CLOCK[0], clock);
  119. lcd.clear();
  120. }
  121. static void lcd_implementation_clear()
  122. {
  123. lcd.clear();
  124. }
  125. /*
  126. Possible status screens:
  127. 16x2 |0123456789012345|
  128. |000/000 B000/000|
  129. |Status line.....|
  130. 16x4 |0123456789012345|
  131. |000/000 B000/000|
  132. |SD100% Z000.0|
  133. |F100% T--:--|
  134. |Status line.....|
  135. 20x2 |01234567890123456789|
  136. |T000/000D B000/000D |
  137. |Status line.........|
  138. 20x4 |01234567890123456789|
  139. |T000/000D B000/000D |
  140. |X+000.0 Y+000.0 Z+000.0|
  141. |F100% SD100% T--:--|
  142. |Status line.........|
  143. 20x4 |01234567890123456789|
  144. |T000/000D B000/000D |
  145. |T000/000D Z000.0|
  146. |F100% SD100% T--:--|
  147. |Status line.........|
  148. */
  149. static void lcd_implementation_status_screen()
  150. {
  151. int tHotend=int(degHotend(0) + 0.5);
  152. int tTarget=int(degTargetHotend(0) + 0.5);
  153. #if LCD_WIDTH < 20
  154. lcd.setCursor(0, 0);
  155. lcd.print(itostr3(tHotend));
  156. lcd.print('/');
  157. lcd.print(itostr3left(tTarget));
  158. # if EXTRUDERS > 1 || TEMP_SENSOR_BED != 0
  159. //If we have an 2nd extruder or heated bed, show that in the top right corner
  160. lcd.setCursor(8, 0);
  161. # if EXTRUDERS > 1
  162. tHotend = int(degHotend(1) + 0.5);
  163. tTarget = int(degTargetHotend(1) + 0.5);
  164. lcd.print(LCD_STR_THERMOMETER[0]);
  165. # else//Heated bed
  166. tHotend=int(degBed() + 0.5);
  167. tTarget=int(degTargetBed() + 0.5);
  168. lcd.print(LCD_STR_BEDTEMP[0]);
  169. # endif
  170. lcd.print(itostr3(tHotend));
  171. lcd.print('/');
  172. lcd.print(itostr3left(tTarget));
  173. # endif//EXTRUDERS > 1 || TEMP_SENSOR_BED != 0
  174. #else//LCD_WIDTH > 19
  175. lcd.setCursor(0, 0);
  176. lcd.print(LCD_STR_THERMOMETER[0]);
  177. lcd.print(itostr3(tHotend));
  178. lcd.print('/');
  179. lcd.print(itostr3left(tTarget));
  180. lcd.print(F(LCD_STR_DEGREE " "));
  181. # if EXTRUDERS > 1 || TEMP_SENSOR_BED != 0
  182. //If we have an 2nd extruder or heated bed, show that in the top right corner
  183. lcd.setCursor(10, 0);
  184. # if EXTRUDERS > 1
  185. tHotend = int(degHotend(1) + 0.5);
  186. tTarget = int(degTargetHotend(1) + 0.5);
  187. lcd.print(LCD_STR_THERMOMETER[0]);
  188. # else//Heated bed
  189. tHotend=int(degBed() + 0.5);
  190. tTarget=int(degTargetBed() + 0.5);
  191. lcd.print(LCD_STR_BEDTEMP[0]);
  192. # endif
  193. lcd.print(itostr3(tHotend));
  194. lcd.print('/');
  195. lcd.print(itostr3left(tTarget));
  196. lcd.print(F(LCD_STR_DEGREE " "));
  197. # endif//EXTRUDERS > 1 || TEMP_SENSOR_BED != 0
  198. #endif//LCD_WIDTH > 19
  199. #if LCD_HEIGHT > 2
  200. //Lines 2 for 4 line LCD
  201. # if LCD_WIDTH < 20
  202. # ifdef SDSUPPORT
  203. lcd.setCursor(0, 2);
  204. lcd.print(F("SD"));
  205. if (IS_SD_PRINTING)
  206. lcd.print(itostr3(card.percentDone()));
  207. else
  208. lcd.print(F("---"));
  209. lcd.print('%');
  210. # endif//SDSUPPORT
  211. # else//LCD_WIDTH > 19
  212. # if EXTRUDERS > 1 && TEMP_SENSOR_BED != 0
  213. //If we both have a 2nd extruder and a heated bed, show the heated bed temp on the 2nd line on the left, as the first line is filled with extruder temps
  214. tHotend=int(degBed() + 0.5);
  215. tTarget=int(degTargetBed() + 0.5);
  216. lcd.setCursor(0, 1);
  217. lcd.print(LCD_STR_BEDTEMP[0]);
  218. lcd.print(itostr3(tHotend));
  219. lcd.print('/');
  220. lcd.print(itostr3left(tTarget));
  221. lcd.print(F(LCD_STR_DEGREE " "));
  222. # else
  223. lcd.setCursor(0,1);
  224. lcd.print('X');
  225. lcd.print(ftostr3(current_position[X_AXIS]));
  226. lcd.print(F(" Y"));
  227. lcd.print(ftostr3(current_position[Y_AXIS]));
  228. # endif//EXTRUDERS > 1 || TEMP_SENSOR_BED != 0
  229. # endif//LCD_WIDTH > 19
  230. lcd.setCursor(LCD_WIDTH - 7, 1);
  231. lcd.print('Z');
  232. lcd.print(ftostr31(current_position[Z_AXIS]));
  233. #endif//LCD_HEIGHT > 2
  234. #if LCD_HEIGHT > 3
  235. lcd.setCursor(0, 2);
  236. lcd.print(LCD_STR_FEEDRATE[0]);
  237. lcd.print(itostr3(feedmultiply));
  238. lcd.print(F("%"));
  239. # if LCD_WIDTH > 19
  240. # ifdef SDSUPPORT
  241. lcd.setCursor(7, 2);
  242. lcd.print(F("SD"));
  243. if (IS_SD_PRINTING)
  244. lcd.print(itostr3(card.percentDone()));
  245. else
  246. lcd.print(F("---"));
  247. lcd.print(F("%"));
  248. # endif//SDSUPPORT
  249. # endif//LCD_WIDTH > 19
  250. lcd.setCursor(LCD_WIDTH - 6, 2);
  251. lcd.print(LCD_STR_CLOCK[0]);
  252. if(starttime != 0)
  253. {
  254. uint16_t time = millis()/60000 - starttime/60000;
  255. lcd.print(itostr2(time/60));
  256. lcd.print(F(":"));
  257. lcd.print(itostr2(time%60));
  258. }else{
  259. lcd.print(F("--:--"));
  260. }
  261. #endif
  262. //Status message line on the last line
  263. lcd.setCursor(0, LCD_HEIGHT - 1);
  264. lcd.print(lcd_status_message);
  265. }
  266. static void lcd_implementation_drawmenu_generic(uint8_t row, const char* pstr, char pre_char, char post_char)
  267. {
  268. char c;
  269. uint8_t n = LCD_WIDTH - 1 - 2;
  270. lcd.setCursor(0, row);
  271. lcd.print(pre_char);
  272. while((c = pgm_read_byte(pstr)) != '\0')
  273. {
  274. lcd.print(c);
  275. pstr++;
  276. n--;
  277. }
  278. while(n--)
  279. lcd.print(' ');
  280. lcd.print(post_char);
  281. lcd.print(' ');
  282. }
  283. static void lcd_implementation_drawmenu_setting_edit_generic(uint8_t row, const char* pstr, char pre_char, char* data)
  284. {
  285. char c;
  286. uint8_t n = LCD_WIDTH - 1 - 2 - strlen(data);
  287. lcd.setCursor(0, row);
  288. lcd.print(pre_char);
  289. while((c = pgm_read_byte(pstr)) != '\0')
  290. {
  291. lcd.print(c);
  292. pstr++;
  293. n--;
  294. }
  295. lcd.print(':');
  296. while(n--)
  297. lcd.print(' ');
  298. lcd.print(data);
  299. }
  300. static void lcd_implementation_drawmenu_setting_edit_generic_P(uint8_t row, const char* pstr, char pre_char, const char* data)
  301. {
  302. char c;
  303. uint8_t n = LCD_WIDTH - 1 - 2 - strlen_P(data);
  304. lcd.setCursor(0, row);
  305. lcd.print(pre_char);
  306. while((c = pgm_read_byte(pstr)) != '\0')
  307. {
  308. lcd.print(c);
  309. pstr++;
  310. n--;
  311. }
  312. lcd.print(':');
  313. while(n--)
  314. lcd.print(' ');
  315. lcd.print(reinterpret_cast<const __FlashStringHelper *>(data));
  316. }
  317. #define lcd_implementation_drawmenu_setting_edit_int3_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', itostr3(*(data)))
  318. #define lcd_implementation_drawmenu_setting_edit_int3(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', itostr3(*(data)))
  319. #define lcd_implementation_drawmenu_setting_edit_float3_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr3(*(data)))
  320. #define lcd_implementation_drawmenu_setting_edit_float3(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr3(*(data)))
  321. #define lcd_implementation_drawmenu_setting_edit_float32_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr32(*(data)))
  322. #define lcd_implementation_drawmenu_setting_edit_float32(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr32(*(data)))
  323. #define lcd_implementation_drawmenu_setting_edit_float5_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data)))
  324. #define lcd_implementation_drawmenu_setting_edit_float5(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data)))
  325. #define lcd_implementation_drawmenu_setting_edit_float52_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr52(*(data)))
  326. #define lcd_implementation_drawmenu_setting_edit_float52(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr52(*(data)))
  327. #define lcd_implementation_drawmenu_setting_edit_float51_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr51(*(data)))
  328. #define lcd_implementation_drawmenu_setting_edit_float51(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr51(*(data)))
  329. #define lcd_implementation_drawmenu_setting_edit_long5_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data)))
  330. #define lcd_implementation_drawmenu_setting_edit_long5(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data)))
  331. #define lcd_implementation_drawmenu_setting_edit_bool_selected(row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, '>', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))
  332. #define lcd_implementation_drawmenu_setting_edit_bool(row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, ' ', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))
  333. void lcd_implementation_drawedit(const char* pstr, char* value)
  334. {
  335. lcd.setCursor(0, 1);
  336. lcd.print(reinterpret_cast<const __FlashStringHelper *>(pstr));
  337. lcd.print(':');
  338. lcd.setCursor(19 - strlen(value), 1);
  339. lcd.print(value);
  340. }
  341. static void lcd_implementation_drawmenu_sdfile_selected(uint8_t row, const char* pstr, const char* filename, char* longFilename)
  342. {
  343. char c;
  344. uint8_t n = LCD_WIDTH - 1;
  345. lcd.setCursor(0, row);
  346. lcd.print('>');
  347. if (longFilename[0] != '\0')
  348. {
  349. filename = longFilename;
  350. longFilename[LCD_WIDTH-1] = '\0';
  351. }
  352. while((c = *filename) != '\0')
  353. {
  354. lcd.print(c);
  355. filename++;
  356. n--;
  357. }
  358. while(n--)
  359. lcd.print(' ');
  360. }
  361. static void lcd_implementation_drawmenu_sdfile(uint8_t row, const char* pstr, const char* filename, char* longFilename)
  362. {
  363. char c;
  364. uint8_t n = LCD_WIDTH - 1;
  365. lcd.setCursor(0, row);
  366. lcd.print(' ');
  367. if (longFilename[0] != '\0')
  368. {
  369. filename = longFilename;
  370. longFilename[LCD_WIDTH-1] = '\0';
  371. }
  372. while((c = *filename) != '\0')
  373. {
  374. lcd.print(c);
  375. filename++;
  376. n--;
  377. }
  378. while(n--)
  379. lcd.print(' ');
  380. }
  381. static void lcd_implementation_drawmenu_sddirectory_selected(uint8_t row, const char* pstr, const char* filename, char* longFilename)
  382. {
  383. char c;
  384. uint8_t n = LCD_WIDTH - 2;
  385. lcd.setCursor(0, row);
  386. lcd.print('>');
  387. lcd.print(LCD_STR_FOLDER[0]);
  388. if (longFilename[0] != '\0')
  389. {
  390. filename = longFilename;
  391. longFilename[LCD_WIDTH-2] = '\0';
  392. }
  393. while((c = *filename) != '\0')
  394. {
  395. lcd.print(c);
  396. filename++;
  397. n--;
  398. }
  399. while(n--)
  400. lcd.print(' ');
  401. }
  402. static void lcd_implementation_drawmenu_sddirectory(uint8_t row, const char* pstr, const char* filename, char* longFilename)
  403. {
  404. char c;
  405. uint8_t n = LCD_WIDTH - 2;
  406. lcd.setCursor(0, row);
  407. lcd.print(' ');
  408. lcd.print(LCD_STR_FOLDER[0]);
  409. if (longFilename[0] != '\0')
  410. {
  411. filename = longFilename;
  412. longFilename[LCD_WIDTH-2] = '\0';
  413. }
  414. while((c = *filename) != '\0')
  415. {
  416. lcd.print(c);
  417. filename++;
  418. n--;
  419. }
  420. while(n--)
  421. lcd.print(' ');
  422. }
  423. #define lcd_implementation_drawmenu_back_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0])
  424. #define lcd_implementation_drawmenu_back(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', LCD_STR_UPLEVEL[0])
  425. #define lcd_implementation_drawmenu_submenu_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, '>', LCD_STR_ARROW_RIGHT[0])
  426. #define lcd_implementation_drawmenu_submenu(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', LCD_STR_ARROW_RIGHT[0])
  427. #define lcd_implementation_drawmenu_gcode_selected(row, pstr, gcode) lcd_implementation_drawmenu_generic(row, pstr, '>', ' ')
  428. #define lcd_implementation_drawmenu_gcode(row, pstr, gcode) lcd_implementation_drawmenu_generic(row, pstr, ' ', ' ')
  429. #define lcd_implementation_drawmenu_function_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, '>', ' ')
  430. #define lcd_implementation_drawmenu_function(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', ' ')
  431. static void lcd_implementation_quick_feedback()
  432. {
  433. #if BEEPER > -1
  434. SET_OUTPUT(BEEPER);
  435. for(int8_t i=0;i<10;i++)
  436. {
  437. WRITE(BEEPER,HIGH);
  438. delay(3);
  439. WRITE(BEEPER,LOW);
  440. delay(3);
  441. }
  442. #endif
  443. }
  444. #endif//ULTRA_LCD_IMPLEMENTATION_HITACHI_HD44780_H