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 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677
  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. extern volatile uint8_t buttons; //the last checked buttons in a bit array.
  8. ////////////////////////////////////
  9. // Setup button and encode mappings for each panel (into 'buttons' variable)
  10. //
  11. // This is just to map common functions (across different panels) onto the same
  12. // macro name. The mapping is independent of whether the button is directly connected or
  13. // via a shift/i2c register.
  14. #ifdef ULTIPANEL
  15. // All Ultipanels might have an encoder - so this is always be mapped onto first two bits
  16. #define BLEN_B 1
  17. #define BLEN_A 0
  18. #define EN_B (1<<BLEN_B) // The two encoder pins are connected through BTN_EN1 and BTN_EN2
  19. #define EN_A (1<<BLEN_A)
  20. //
  21. // Setup other button mappings of each panel
  22. //
  23. #if defined(LCD_I2C_VIKI)
  24. #define BLEN_C 2 // == pause/stop/restart button connected to BTN_ENC pin (named for consistency with NEWPANEL code)
  25. #define EN_C (1<<BLEN_C)
  26. #define B_I2C_BTN_OFFSET (BLEN_C+1) // (the first three bit positions reserved for EN_A, EN_B, EN_C)
  27. // button and encoder bit positions within 'buttons'
  28. #define B_ST (EN_C) // Map the pause/stop/resume button into its normalized functional name
  29. #define B_LE (BUTTON_LEFT<<B_I2C_BTN_OFFSET) // The remaining normalized buttons are all read via I2C
  30. #define B_UP (BUTTON_UP<<B_I2C_BTN_OFFSET)
  31. #define B_MI (BUTTON_SELECT<<B_I2C_BTN_OFFSET)
  32. #define B_DW (BUTTON_DOWN<<B_I2C_BTN_OFFSET)
  33. #define B_RI (BUTTON_RIGHT<<B_I2C_BTN_OFFSET)
  34. #define LCD_CLICKED (buttons&(B_MI|B_RI|B_ST)) // pause/stop button also acts as click until we implement proper pause/stop.
  35. // I2C buttons take too long to read inside an interrupt context and so we read them during lcd_update
  36. #define LCD_HAS_SLOW_BUTTONS
  37. #elif defined(NEWPANEL)
  38. // Standard Newpanel has just a single button (all direclty connected)
  39. #define BLEN_C 2 // == select button
  40. #define EN_C (1<<BLEN_C)
  41. #define LCD_CLICKED (buttons&EN_C)
  42. #else // old style ULTIPANEL
  43. //bits in the shift register that carry the buttons for:
  44. // left up center down right red(stop)
  45. #define BL_LE 7
  46. #define BL_UP 6
  47. #define BL_MI 5
  48. #define BL_DW 4
  49. #define BL_RI 3
  50. #define BL_ST 2
  51. //automatic, do not change
  52. #define B_LE (1<<BL_LE)
  53. #define B_UP (1<<BL_UP)
  54. #define B_MI (1<<BL_MI)
  55. #define B_DW (1<<BL_DW)
  56. #define B_RI (1<<BL_RI)
  57. #define B_ST (1<<BL_ST)
  58. #define LCD_CLICKED (buttons&(B_MI|B_ST))
  59. #endif//else NEWPANEL
  60. ////////////////////////
  61. // Setup Rotary Encoder Bit Values (for two pin encoders to indicate movement)
  62. // These values are independent of which pins are used for EN_A and EN_B indications
  63. // The rotary encoder part is also independent to the chipset used for the LCD
  64. #if defined(EN_A) && defined(EN_B)
  65. #ifndef ULTIMAKERCONTROLLER
  66. #define encrot0 0
  67. #define encrot1 2
  68. #define encrot2 3
  69. #define encrot3 1
  70. #else
  71. #define encrot0 0
  72. #define encrot1 1
  73. #define encrot2 3
  74. #define encrot3 2
  75. #endif
  76. #endif
  77. #endif //ULTIPANEL
  78. ////////////////////////////////////
  79. // Create LCD class instance and chipset-specific information
  80. #if defined(LCD_I2C_TYPE_PCF8575)
  81. // note: these are register mapped pins on the PCF8575 controller not Arduino pins
  82. #define LCD_I2C_PIN_BL 3
  83. #define LCD_I2C_PIN_EN 2
  84. #define LCD_I2C_PIN_RW 1
  85. #define LCD_I2C_PIN_RS 0
  86. #define LCD_I2C_PIN_D4 4
  87. #define LCD_I2C_PIN_D5 5
  88. #define LCD_I2C_PIN_D6 6
  89. #define LCD_I2C_PIN_D7 7
  90. #include <Wire.h>
  91. #include <LCD.h>
  92. #include <LiquidCrystal_I2C.h>
  93. #define LCD_CLASS LiquidCrystal_I2C
  94. LCD_CLASS lcd(LCD_I2C_ADDRESS,LCD_I2C_PIN_EN,LCD_I2C_PIN_RW,LCD_I2C_PIN_RS,LCD_I2C_PIN_D4,LCD_I2C_PIN_D5,LCD_I2C_PIN_D6,LCD_I2C_PIN_D7);
  95. #elif defined(LCD_I2C_TYPE_MCP23017)
  96. //for the LED indicators (which maybe mapped to different things in lcd_implementation_update_indicators())
  97. #define LED_A 0x04 //100
  98. #define LED_B 0x02 //010
  99. #define LED_C 0x01 //001
  100. #define LCD_HAS_STATUS_INDICATORS
  101. #include <Wire.h>
  102. #include <LiquidTWI2.h>
  103. #define LCD_CLASS LiquidTWI2
  104. LCD_CLASS lcd(LCD_I2C_ADDRESS);
  105. #elif defined(LCD_I2C_TYPE_MCP23008)
  106. #include <Wire.h>
  107. #include <LiquidTWI2.h>
  108. #define LCD_CLASS LiquidTWI2
  109. LCD_CLASS lcd(LCD_I2C_ADDRESS);
  110. #else
  111. // Standard directly connected LCD implementations
  112. #if LANGUAGE_CHOICE == 6
  113. #include "LiquidCrystalRus.h"
  114. #define LCD_CLASS LiquidCrystalRus
  115. #else
  116. #include <LiquidCrystal.h>
  117. #define LCD_CLASS LiquidCrystal
  118. #endif
  119. LCD_CLASS 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
  120. #endif
  121. /* Custom characters defined in the first 8 characters of the LCD */
  122. #define LCD_STR_BEDTEMP "\x00"
  123. #define LCD_STR_DEGREE "\x01"
  124. #define LCD_STR_THERMOMETER "\x02"
  125. #define LCD_STR_UPLEVEL "\x03"
  126. #define LCD_STR_REFRESH "\x04"
  127. #define LCD_STR_FOLDER "\x05"
  128. #define LCD_STR_FEEDRATE "\x06"
  129. #define LCD_STR_CLOCK "\x07"
  130. #define LCD_STR_ARROW_RIGHT "\x7E" /* from the default character set */
  131. static void lcd_implementation_init()
  132. {
  133. byte bedTemp[8] =
  134. {
  135. B00000,
  136. B11111,
  137. B10101,
  138. B10001,
  139. B10101,
  140. B11111,
  141. B00000,
  142. B00000
  143. }; //thanks Sonny Mounicou
  144. byte degree[8] =
  145. {
  146. B01100,
  147. B10010,
  148. B10010,
  149. B01100,
  150. B00000,
  151. B00000,
  152. B00000,
  153. B00000
  154. };
  155. byte thermometer[8] =
  156. {
  157. B00100,
  158. B01010,
  159. B01010,
  160. B01010,
  161. B01010,
  162. B10001,
  163. B10001,
  164. B01110
  165. };
  166. byte uplevel[8]={
  167. B00100,
  168. B01110,
  169. B11111,
  170. B00100,
  171. B11100,
  172. B00000,
  173. B00000,
  174. B00000
  175. }; //thanks joris
  176. byte refresh[8]={
  177. B00000,
  178. B00110,
  179. B11001,
  180. B11000,
  181. B00011,
  182. B10011,
  183. B01100,
  184. B00000,
  185. }; //thanks joris
  186. byte folder [8]={
  187. B00000,
  188. B11100,
  189. B11111,
  190. B10001,
  191. B10001,
  192. B11111,
  193. B00000,
  194. B00000
  195. }; //thanks joris
  196. byte feedrate [8]={
  197. B11100,
  198. B10000,
  199. B11000,
  200. B10111,
  201. B00101,
  202. B00110,
  203. B00101,
  204. B00000
  205. }; //thanks Sonny Mounicou
  206. byte clock [8]={
  207. B00000,
  208. B01110,
  209. B10011,
  210. B10101,
  211. B10001,
  212. B01110,
  213. B00000,
  214. B00000
  215. }; //thanks Sonny Mounicou
  216. #if defined(LCDI2C_TYPE_PCF8575)
  217. lcd.begin(LCD_WIDTH, LCD_HEIGHT);
  218. #ifdef LCD_I2C_PIN_BL
  219. lcd.setBacklightPin(LCD_I2C_PIN_BL,POSITIVE);
  220. lcd.setBacklight(HIGH);
  221. #endif
  222. #elif defined(LCD_I2C_TYPE_MCP23017)
  223. lcd.setMCPType(LTI_TYPE_MCP23017);
  224. lcd.begin(LCD_WIDTH, LCD_HEIGHT);
  225. lcd.setBacklight(0); //set all the LEDs off to begin with
  226. #elif defined(LCD_I2C_TYPE_MCP23008)
  227. lcd.setMCPType(LTI_TYPE_MCP23008);
  228. lcd.begin(LCD_WIDTH, LCD_HEIGHT);
  229. #else
  230. lcd.begin(LCD_WIDTH, LCD_HEIGHT);
  231. #endif
  232. lcd.createChar(LCD_STR_BEDTEMP[0], bedTemp);
  233. lcd.createChar(LCD_STR_DEGREE[0], degree);
  234. lcd.createChar(LCD_STR_THERMOMETER[0], thermometer);
  235. lcd.createChar(LCD_STR_UPLEVEL[0], uplevel);
  236. lcd.createChar(LCD_STR_REFRESH[0], refresh);
  237. lcd.createChar(LCD_STR_FOLDER[0], folder);
  238. lcd.createChar(LCD_STR_FEEDRATE[0], feedrate);
  239. lcd.createChar(LCD_STR_CLOCK[0], clock);
  240. lcd.clear();
  241. }
  242. static void lcd_implementation_clear()
  243. {
  244. lcd.clear();
  245. }
  246. /* Arduino < 1.0.0 is missing a function to print PROGMEM strings, so we need to implement our own */
  247. static void lcd_printPGM(const char* str)
  248. {
  249. char c;
  250. while((c = pgm_read_byte(str++)) != '\0')
  251. {
  252. lcd.write(c);
  253. }
  254. }
  255. /*
  256. Possible status screens:
  257. 16x2 |0123456789012345|
  258. |000/000 B000/000|
  259. |Status line.....|
  260. 16x4 |0123456789012345|
  261. |000/000 B000/000|
  262. |SD100% Z000.0|
  263. |F100% T--:--|
  264. |Status line.....|
  265. 20x2 |01234567890123456789|
  266. |T000/000D B000/000D |
  267. |Status line.........|
  268. 20x4 |01234567890123456789|
  269. |T000/000D B000/000D |
  270. |X+000.0 Y+000.0 Z+000.0|
  271. |F100% SD100% T--:--|
  272. |Status line.........|
  273. 20x4 |01234567890123456789|
  274. |T000/000D B000/000D |
  275. |T000/000D Z000.0|
  276. |F100% SD100% T--:--|
  277. |Status line.........|
  278. */
  279. static void lcd_implementation_status_screen()
  280. {
  281. int tHotend=int(degHotend(0) + 0.5);
  282. int tTarget=int(degTargetHotend(0) + 0.5);
  283. #if LCD_WIDTH < 20
  284. lcd.setCursor(0, 0);
  285. lcd.print(itostr3(tHotend));
  286. lcd.print('/');
  287. lcd.print(itostr3left(tTarget));
  288. # if EXTRUDERS > 1 || TEMP_SENSOR_BED != 0
  289. //If we have an 2nd extruder or heated bed, show that in the top right corner
  290. lcd.setCursor(8, 0);
  291. # if EXTRUDERS > 1
  292. tHotend = int(degHotend(1) + 0.5);
  293. tTarget = int(degTargetHotend(1) + 0.5);
  294. lcd.print(LCD_STR_THERMOMETER[0]);
  295. # else//Heated bed
  296. tHotend=int(degBed() + 0.5);
  297. tTarget=int(degTargetBed() + 0.5);
  298. lcd.print(LCD_STR_BEDTEMP[0]);
  299. # endif
  300. lcd.print(itostr3(tHotend));
  301. lcd.print('/');
  302. lcd.print(itostr3left(tTarget));
  303. # endif//EXTRUDERS > 1 || TEMP_SENSOR_BED != 0
  304. #else//LCD_WIDTH > 19
  305. lcd.setCursor(0, 0);
  306. lcd.print(LCD_STR_THERMOMETER[0]);
  307. lcd.print(itostr3(tHotend));
  308. lcd.print('/');
  309. lcd.print(itostr3left(tTarget));
  310. lcd_printPGM(PSTR(LCD_STR_DEGREE " "));
  311. if (tTarget < 10)
  312. lcd.print(' ');
  313. # if EXTRUDERS > 1 || TEMP_SENSOR_BED != 0
  314. //If we have an 2nd extruder or heated bed, show that in the top right corner
  315. lcd.setCursor(10, 0);
  316. # if EXTRUDERS > 1
  317. tHotend = int(degHotend(1) + 0.5);
  318. tTarget = int(degTargetHotend(1) + 0.5);
  319. lcd.print(LCD_STR_THERMOMETER[0]);
  320. # else//Heated bed
  321. tHotend=int(degBed() + 0.5);
  322. tTarget=int(degTargetBed() + 0.5);
  323. lcd.print(LCD_STR_BEDTEMP[0]);
  324. # endif
  325. lcd.print(itostr3(tHotend));
  326. lcd.print('/');
  327. lcd.print(itostr3left(tTarget));
  328. lcd_printPGM(PSTR(LCD_STR_DEGREE " "));
  329. if (tTarget < 10)
  330. lcd.print(' ');
  331. # endif//EXTRUDERS > 1 || TEMP_SENSOR_BED != 0
  332. #endif//LCD_WIDTH > 19
  333. #if LCD_HEIGHT > 2
  334. //Lines 2 for 4 line LCD
  335. # if LCD_WIDTH < 20
  336. # ifdef SDSUPPORT
  337. lcd.setCursor(0, 2);
  338. lcd_printPGM(PSTR("SD"));
  339. if (IS_SD_PRINTING)
  340. lcd.print(itostr3(card.percentDone()));
  341. else
  342. lcd_printPGM(PSTR("---"));
  343. lcd.print('%');
  344. # endif//SDSUPPORT
  345. # else//LCD_WIDTH > 19
  346. # if EXTRUDERS > 1 && TEMP_SENSOR_BED != 0
  347. //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
  348. tHotend=int(degBed() + 0.5);
  349. tTarget=int(degTargetBed() + 0.5);
  350. lcd.setCursor(0, 1);
  351. lcd.print(LCD_STR_BEDTEMP[0]);
  352. lcd.print(itostr3(tHotend));
  353. lcd.print('/');
  354. lcd.print(itostr3left(tTarget));
  355. lcd_printPGM(PSTR(LCD_STR_DEGREE " "));
  356. if (tTarget < 10)
  357. lcd.print(' ');
  358. # else
  359. lcd.setCursor(0,1);
  360. lcd.print('X');
  361. lcd.print(ftostr3(current_position[X_AXIS]));
  362. lcd_printPGM(PSTR(" Y"));
  363. lcd.print(ftostr3(current_position[Y_AXIS]));
  364. # endif//EXTRUDERS > 1 || TEMP_SENSOR_BED != 0
  365. # endif//LCD_WIDTH > 19
  366. lcd.setCursor(LCD_WIDTH - 8, 1);
  367. lcd.print('Z');
  368. lcd.print(ftostr32(current_position[Z_AXIS]));
  369. #endif//LCD_HEIGHT > 2
  370. #if LCD_HEIGHT > 3
  371. lcd.setCursor(0, 2);
  372. lcd.print(LCD_STR_FEEDRATE[0]);
  373. lcd.print(itostr3(feedmultiply));
  374. lcd.print('%');
  375. # if LCD_WIDTH > 19
  376. # ifdef SDSUPPORT
  377. lcd.setCursor(7, 2);
  378. lcd_printPGM(PSTR("SD"));
  379. if (IS_SD_PRINTING)
  380. lcd.print(itostr3(card.percentDone()));
  381. else
  382. lcd_printPGM(PSTR("---"));
  383. lcd.print('%');
  384. # endif//SDSUPPORT
  385. # endif//LCD_WIDTH > 19
  386. lcd.setCursor(LCD_WIDTH - 6, 2);
  387. lcd.print(LCD_STR_CLOCK[0]);
  388. if(starttime != 0)
  389. {
  390. uint16_t time = millis()/60000 - starttime/60000;
  391. lcd.print(itostr2(time/60));
  392. lcd.print(':');
  393. lcd.print(itostr2(time%60));
  394. }else{
  395. lcd_printPGM(PSTR("--:--"));
  396. }
  397. #endif
  398. //Status message line on the last line
  399. lcd.setCursor(0, LCD_HEIGHT - 1);
  400. lcd.print(lcd_status_message);
  401. }
  402. static void lcd_implementation_drawmenu_generic(uint8_t row, const char* pstr, char pre_char, char post_char)
  403. {
  404. char c;
  405. //Use all characters in narrow LCDs
  406. #if LCD_WIDTH < 20
  407. uint8_t n = LCD_WIDTH - 1 - 1;
  408. #else
  409. uint8_t n = LCD_WIDTH - 1 - 2;
  410. #endif
  411. lcd.setCursor(0, row);
  412. lcd.print(pre_char);
  413. while((c = pgm_read_byte(pstr)) != '\0')
  414. {
  415. lcd.print(c);
  416. pstr++;
  417. n--;
  418. }
  419. while(n--)
  420. lcd.print(' ');
  421. lcd.print(post_char);
  422. lcd.print(' ');
  423. }
  424. static void lcd_implementation_drawmenu_setting_edit_generic(uint8_t row, const char* pstr, char pre_char, char* data)
  425. {
  426. char c;
  427. //Use all characters in narrow LCDs
  428. #if LCD_WIDTH < 20
  429. uint8_t n = LCD_WIDTH - 1 - 1 - strlen(data);
  430. #else
  431. uint8_t n = LCD_WIDTH - 1 - 2 - strlen(data);
  432. #endif
  433. lcd.setCursor(0, row);
  434. lcd.print(pre_char);
  435. while((c = pgm_read_byte(pstr)) != '\0')
  436. {
  437. lcd.print(c);
  438. pstr++;
  439. n--;
  440. }
  441. lcd.print(':');
  442. while(n--)
  443. lcd.print(' ');
  444. lcd.print(data);
  445. }
  446. static void lcd_implementation_drawmenu_setting_edit_generic_P(uint8_t row, const char* pstr, char pre_char, const char* data)
  447. {
  448. char c;
  449. //Use all characters in narrow LCDs
  450. #if LCD_WIDTH < 20
  451. uint8_t n = LCD_WIDTH - 1 - 1 - strlen_P(data);
  452. #else
  453. uint8_t n = LCD_WIDTH - 1 - 2 - strlen_P(data);
  454. #endif
  455. lcd.setCursor(0, row);
  456. lcd.print(pre_char);
  457. while((c = pgm_read_byte(pstr)) != '\0')
  458. {
  459. lcd.print(c);
  460. pstr++;
  461. n--;
  462. }
  463. lcd.print(':');
  464. while(n--)
  465. lcd.print(' ');
  466. lcd_printPGM(data);
  467. }
  468. #define lcd_implementation_drawmenu_setting_edit_int3_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', itostr3(*(data)))
  469. #define lcd_implementation_drawmenu_setting_edit_int3(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', itostr3(*(data)))
  470. #define lcd_implementation_drawmenu_setting_edit_float3_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr3(*(data)))
  471. #define lcd_implementation_drawmenu_setting_edit_float3(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr3(*(data)))
  472. #define lcd_implementation_drawmenu_setting_edit_float32_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr32(*(data)))
  473. #define lcd_implementation_drawmenu_setting_edit_float32(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr32(*(data)))
  474. #define lcd_implementation_drawmenu_setting_edit_float5_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data)))
  475. #define lcd_implementation_drawmenu_setting_edit_float5(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data)))
  476. #define lcd_implementation_drawmenu_setting_edit_float52_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr52(*(data)))
  477. #define lcd_implementation_drawmenu_setting_edit_float52(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr52(*(data)))
  478. #define lcd_implementation_drawmenu_setting_edit_float51_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr51(*(data)))
  479. #define lcd_implementation_drawmenu_setting_edit_float51(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr51(*(data)))
  480. #define lcd_implementation_drawmenu_setting_edit_long5_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data)))
  481. #define lcd_implementation_drawmenu_setting_edit_long5(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data)))
  482. #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))
  483. #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))
  484. void lcd_implementation_drawedit(const char* pstr, char* value)
  485. {
  486. lcd.setCursor(1, 1);
  487. lcd_printPGM(pstr);
  488. lcd.print(':');
  489. #if LCD_WIDTH < 20
  490. lcd.setCursor(LCD_WIDTH - strlen(value), 1);
  491. #else
  492. lcd.setCursor(LCD_WIDTH -1 - strlen(value), 1);
  493. #endif
  494. lcd.print(value);
  495. }
  496. static void lcd_implementation_drawmenu_sdfile_selected(uint8_t row, const char* pstr, const char* filename, char* longFilename)
  497. {
  498. char c;
  499. uint8_t n = LCD_WIDTH - 1;
  500. lcd.setCursor(0, row);
  501. lcd.print('>');
  502. if (longFilename[0] != '\0')
  503. {
  504. filename = longFilename;
  505. longFilename[LCD_WIDTH-1] = '\0';
  506. }
  507. while((c = *filename) != '\0')
  508. {
  509. lcd.print(c);
  510. filename++;
  511. n--;
  512. }
  513. while(n--)
  514. lcd.print(' ');
  515. }
  516. static void lcd_implementation_drawmenu_sdfile(uint8_t row, const char* pstr, const char* filename, char* longFilename)
  517. {
  518. char c;
  519. uint8_t n = LCD_WIDTH - 1;
  520. lcd.setCursor(0, row);
  521. lcd.print(' ');
  522. if (longFilename[0] != '\0')
  523. {
  524. filename = longFilename;
  525. longFilename[LCD_WIDTH-1] = '\0';
  526. }
  527. while((c = *filename) != '\0')
  528. {
  529. lcd.print(c);
  530. filename++;
  531. n--;
  532. }
  533. while(n--)
  534. lcd.print(' ');
  535. }
  536. static void lcd_implementation_drawmenu_sddirectory_selected(uint8_t row, const char* pstr, const char* filename, char* longFilename)
  537. {
  538. char c;
  539. uint8_t n = LCD_WIDTH - 2;
  540. lcd.setCursor(0, row);
  541. lcd.print('>');
  542. lcd.print(LCD_STR_FOLDER[0]);
  543. if (longFilename[0] != '\0')
  544. {
  545. filename = longFilename;
  546. longFilename[LCD_WIDTH-2] = '\0';
  547. }
  548. while((c = *filename) != '\0')
  549. {
  550. lcd.print(c);
  551. filename++;
  552. n--;
  553. }
  554. while(n--)
  555. lcd.print(' ');
  556. }
  557. static void lcd_implementation_drawmenu_sddirectory(uint8_t row, const char* pstr, const char* filename, char* longFilename)
  558. {
  559. char c;
  560. uint8_t n = LCD_WIDTH - 2;
  561. lcd.setCursor(0, row);
  562. lcd.print(' ');
  563. lcd.print(LCD_STR_FOLDER[0]);
  564. if (longFilename[0] != '\0')
  565. {
  566. filename = longFilename;
  567. longFilename[LCD_WIDTH-2] = '\0';
  568. }
  569. while((c = *filename) != '\0')
  570. {
  571. lcd.print(c);
  572. filename++;
  573. n--;
  574. }
  575. while(n--)
  576. lcd.print(' ');
  577. }
  578. #define lcd_implementation_drawmenu_back_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0])
  579. #define lcd_implementation_drawmenu_back(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', LCD_STR_UPLEVEL[0])
  580. #define lcd_implementation_drawmenu_submenu_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, '>', LCD_STR_ARROW_RIGHT[0])
  581. #define lcd_implementation_drawmenu_submenu(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', LCD_STR_ARROW_RIGHT[0])
  582. #define lcd_implementation_drawmenu_gcode_selected(row, pstr, gcode) lcd_implementation_drawmenu_generic(row, pstr, '>', ' ')
  583. #define lcd_implementation_drawmenu_gcode(row, pstr, gcode) lcd_implementation_drawmenu_generic(row, pstr, ' ', ' ')
  584. #define lcd_implementation_drawmenu_function_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, '>', ' ')
  585. #define lcd_implementation_drawmenu_function(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', ' ')
  586. static void lcd_implementation_quick_feedback()
  587. {
  588. #ifdef LCD_USE_I2C_BUZZER
  589. lcd.buzz(300,4000);
  590. #elif defined(BEEPER) && BEEPER > -1
  591. SET_OUTPUT(BEEPER);
  592. for(int8_t i=0;i<10;i++)
  593. {
  594. WRITE(BEEPER,HIGH);
  595. delay(3);
  596. WRITE(BEEPER,LOW);
  597. delay(3);
  598. }
  599. #endif
  600. }
  601. #ifdef LCD_HAS_STATUS_INDICATORS
  602. static void lcd_implementation_update_indicators()
  603. {
  604. #if defined(LCD_I2C_PANELOLU2) || defined(LCD_I2C_VIKI)
  605. //set the LEDS - referred to as backlights by the LiquidTWI2 library
  606. static uint8_t ledsprev = 0;
  607. uint8_t leds = 0;
  608. if (isHeatingBed()) leds |= LED_A;
  609. if (isHeatingHotend(0)) leds |= LED_B;
  610. if (fanSpeed) leds |= LED_C;
  611. #if EXTRUDERS > 1
  612. if (isHeatingHotend(1)) leds |= LED_C;
  613. #endif
  614. if (leds != ledsprev) {
  615. lcd.setBacklight(leds);
  616. ledsprev = leds;
  617. }
  618. #endif
  619. }
  620. #endif
  621. #ifdef LCD_HAS_SLOW_BUTTONS
  622. static uint8_t lcd_implementation_read_slow_buttons()
  623. {
  624. #ifdef LCD_I2C_TYPE_MCP23017
  625. // Reading these buttons this is likely to be too slow to call inside interrupt context
  626. // so they are called during normal lcd_update
  627. return lcd.readButtons() << B_I2C_BTN_OFFSET;
  628. #endif
  629. }
  630. #endif
  631. #endif//ULTRA_LCD_IMPLEMENTATION_HITACHI_HD44780_H