| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340 | #ifndef ULTRA_LCD_IMPLEMENTATION_HITACHI_HD44780_H#define ULTRA_LCD_IMPLEMENTATION_HITACHI_HD44780_Hint scrollstuff = 0;char longFilenameOLD[LONG_FILENAME_LENGTH];#include "Configuration_prusa.h"#include "Marlin.h"/*** Implementation of the LCD display routines for a Hitachi HD44780 display. These are common LCD character displays.* When selecting the Russian language, a slightly different LCD implementation is used to handle UTF8 characters.**/#ifndef REPRAPWORLD_KEYPADextern volatile uint8_t buttons;  //the last checked buttons in a bit array.#elseextern volatile uint16_t buttons;  //an extended version of the last checked buttons in a bit array.#endif////////////////////////////////////// Setup button and encode mappings for each panel (into 'buttons' variable//// This is just to map common functions (across different panels) onto the same // macro name. The mapping is independent of whether the button is directly connected or // via a shift/i2c register.#ifdef ULTIPANEL// All UltiPanels might have an encoder - so this is always be mapped onto first two bits#define BLEN_B 1#define BLEN_A 0#define EN_B (1<<BLEN_B) // The two encoder pins are connected through BTN_EN1 and BTN_EN2#define EN_A (1<<BLEN_A)#if defined(BTN_ENC) && BTN_ENC > -1  // encoder click is directly connected  #define BLEN_C 2   #define EN_C (1<<BLEN_C) #endif   //// Setup other button mappings of each panel//#if defined(LCD_I2C_VIKI)  #define B_I2C_BTN_OFFSET 3 // (the first three bit positions reserved for EN_A, EN_B, EN_C)    // button and encoder bit positions within 'buttons'  #define B_LE (BUTTON_LEFT<<B_I2C_BTN_OFFSET)    // The remaining normalized buttons are all read via I2C  #define B_UP (BUTTON_UP<<B_I2C_BTN_OFFSET)  #define B_MI (BUTTON_SELECT<<B_I2C_BTN_OFFSET)  #define B_DW (BUTTON_DOWN<<B_I2C_BTN_OFFSET)  #define B_RI (BUTTON_RIGHT<<B_I2C_BTN_OFFSET)  #if defined(BTN_ENC) && BTN_ENC > -1     // the pause/stop/restart button is connected to BTN_ENC when used    #define B_ST (EN_C)                            // Map the pause/stop/resume button into its normalized functional name     #define LCD_CLICKED (buttons&(B_MI|B_RI|B_ST)) // pause/stop button also acts as click until we implement proper pause/stop.  #else    #define LCD_CLICKED (buttons&(B_MI|B_RI))  #endif    // I2C buttons take too long to read inside an interrupt context and so we read them during lcd_update  #define LCD_HAS_SLOW_BUTTONS#elif defined(LCD_I2C_PANELOLU2)  // encoder click can be read through I2C if not directly connected  #if BTN_ENC <= 0     #define B_I2C_BTN_OFFSET 3 // (the first three bit positions reserved for EN_A, EN_B, EN_C)      #define B_MI (PANELOLU2_ENCODER_C<<B_I2C_BTN_OFFSET) // requires LiquidTWI2 library v1.2.3 or later    #define LCD_CLICKED (buttons&B_MI)    // I2C buttons take too long to read inside an interrupt context and so we read them during lcd_update    #define LCD_HAS_SLOW_BUTTONS  #else    #define LCD_CLICKED (buttons&EN_C)    #endif#elif defined(REPRAPWORLD_KEYPAD)    // define register bit values, don't change it    #define BLEN_REPRAPWORLD_KEYPAD_F3 0    #define BLEN_REPRAPWORLD_KEYPAD_F2 1    #define BLEN_REPRAPWORLD_KEYPAD_F1 2    #define BLEN_REPRAPWORLD_KEYPAD_UP 3    #define BLEN_REPRAPWORLD_KEYPAD_RIGHT 4    #define BLEN_REPRAPWORLD_KEYPAD_MIDDLE 5    #define BLEN_REPRAPWORLD_KEYPAD_DOWN 6    #define BLEN_REPRAPWORLD_KEYPAD_LEFT 7        #define REPRAPWORLD_BTN_OFFSET 3 // bit offset into buttons for shift register values    #define EN_REPRAPWORLD_KEYPAD_F3 (1<<(BLEN_REPRAPWORLD_KEYPAD_F3+REPRAPWORLD_BTN_OFFSET))    #define EN_REPRAPWORLD_KEYPAD_F2 (1<<(BLEN_REPRAPWORLD_KEYPAD_F2+REPRAPWORLD_BTN_OFFSET))    #define EN_REPRAPWORLD_KEYPAD_F1 (1<<(BLEN_REPRAPWORLD_KEYPAD_F1+REPRAPWORLD_BTN_OFFSET))    #define EN_REPRAPWORLD_KEYPAD_UP (1<<(BLEN_REPRAPWORLD_KEYPAD_UP+REPRAPWORLD_BTN_OFFSET))    #define EN_REPRAPWORLD_KEYPAD_RIGHT (1<<(BLEN_REPRAPWORLD_KEYPAD_RIGHT+REPRAPWORLD_BTN_OFFSET))    #define EN_REPRAPWORLD_KEYPAD_MIDDLE (1<<(BLEN_REPRAPWORLD_KEYPAD_MIDDLE+REPRAPWORLD_BTN_OFFSET))    #define EN_REPRAPWORLD_KEYPAD_DOWN (1<<(BLEN_REPRAPWORLD_KEYPAD_DOWN+REPRAPWORLD_BTN_OFFSET))    #define EN_REPRAPWORLD_KEYPAD_LEFT (1<<(BLEN_REPRAPWORLD_KEYPAD_LEFT+REPRAPWORLD_BTN_OFFSET))    #define LCD_CLICKED ((buttons&EN_C) || (buttons&EN_REPRAPWORLD_KEYPAD_F1))    #define REPRAPWORLD_KEYPAD_MOVE_Y_DOWN (buttons&EN_REPRAPWORLD_KEYPAD_DOWN)    #define REPRAPWORLD_KEYPAD_MOVE_Y_UP (buttons&EN_REPRAPWORLD_KEYPAD_UP)    #define REPRAPWORLD_KEYPAD_MOVE_HOME (buttons&EN_REPRAPWORLD_KEYPAD_MIDDLE)#elif defined(NEWPANEL)  #define LCD_CLICKED (buttons&EN_C)  #else // old style ULTIPANEL  //bits in the shift register that carry the buttons for:  // left up center down right red(stop)  #define BL_LE 7  #define BL_UP 6  #define BL_MI 5  #define BL_DW 4  #define BL_RI 3  #define BL_ST 2  //automatic, do not change  #define B_LE (1<<BL_LE)  #define B_UP (1<<BL_UP)  #define B_MI (1<<BL_MI)  #define B_DW (1<<BL_DW)  #define B_RI (1<<BL_RI)  #define B_ST (1<<BL_ST)    #define LCD_CLICKED (buttons&(B_MI|B_ST))#endif////////////////////////// Setup Rotary Encoder Bit Values (for two pin encoders to indicate movement)// These values are independent of which pins are used for EN_A and EN_B indications// The rotary encoder part is also independent to the chipset used for the LCD#if defined(EN_A) && defined(EN_B)    #define encrot0 0    #define encrot1 2    #define encrot2 3    #define encrot3 1#endif #endif //ULTIPANEL////////////////////////////////////// Create LCD class instance and chipset-specific information#if defined(LCD_I2C_TYPE_PCF8575)  // note: these are register mapped pins on the PCF8575 controller not Arduino pins  #define LCD_I2C_PIN_BL  3  #define LCD_I2C_PIN_EN  2  #define LCD_I2C_PIN_RW  1  #define LCD_I2C_PIN_RS  0  #define LCD_I2C_PIN_D4  4  #define LCD_I2C_PIN_D5  5  #define LCD_I2C_PIN_D6  6  #define LCD_I2C_PIN_D7  7  #include <Wire.h>  #include <LCD.h>  #include <LiquidCrystal_I2C.h>  #define LCD_CLASS LiquidCrystal_I2C  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);  #elif defined(LCD_I2C_TYPE_MCP23017)  //for the LED indicators (which maybe mapped to different things in lcd_implementation_update_indicators())  #define LED_A 0x04 //100  #define LED_B 0x02 //010  #define LED_C 0x01 //001  #define LCD_HAS_STATUS_INDICATORS  #include <Wire.h>  #include <LiquidTWI2.h>  #define LCD_CLASS LiquidTWI2  #if defined(DETECT_DEVICE)     LCD_CLASS lcd(LCD_I2C_ADDRESS, 1);  #else     LCD_CLASS lcd(LCD_I2C_ADDRESS);  #endif  #elif defined(LCD_I2C_TYPE_MCP23008)  #include <Wire.h>  #include <LiquidTWI2.h>  #define LCD_CLASS LiquidTWI2  #if defined(DETECT_DEVICE)     LCD_CLASS lcd(LCD_I2C_ADDRESS, 1);  #else     LCD_CLASS lcd(LCD_I2C_ADDRESS);  #endif#elif defined(LCD_I2C_TYPE_PCA8574)    #include <LiquidCrystal_I2C.h>    #define LCD_CLASS LiquidCrystal_I2C    LCD_CLASS lcd(LCD_I2C_ADDRESS, LCD_WIDTH, LCD_HEIGHT);    // 2 wire Non-latching LCD SR from:// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/schematics#!shiftregister-connection #elif defined(SR_LCD_2W_NL)  extern "C" void __cxa_pure_virtual() { while (1); }  #include <LCD.h>  #include <LiquidCrystal_SR.h>  #define LCD_CLASS LiquidCrystal_SR  LCD_CLASS lcd(SR_DATA_PIN, SR_CLK_PIN);#else  // Standard directly connected LCD implementations  #ifdef LANGUAGE_RU    #include "LiquidCrystalRus.h"    #define LCD_CLASS LiquidCrystalRus  #else     #include "LiquidCrystal.h"    #define LCD_CLASS LiquidCrystal  #endif    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#endif#if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT)  static uint16_t progressBarTick = 0;  #if PROGRESS_MSG_EXPIRE > 0    static uint16_t messageTick = 0;  #endif  #define LCD_STR_PROGRESS  "\x03\x04\x05"#endif/* Custom characters defined in the first 8 characters of the LCD */#define LCD_STR_BEDTEMP     "\x00"#define LCD_STR_DEGREE      "\x01"#define LCD_STR_THERMOMETER "\x02"#define LCD_STR_UPLEVEL     "\x03"#define LCD_STR_REFRESH     "\x04"#define LCD_STR_FOLDER      "\x05"#define LCD_STR_FEEDRATE    "\x06"#define LCD_STR_CLOCK       "\x07"#define LCD_STR_ARROW_UP    "\x0B"#define LCD_STR_ARROW_DOWN  "\x01"#define LCD_STR_ARROW_RIGHT "\x7E"  /* from the default character set */static void lcd_set_custom_characters(  #if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT)    bool progress_bar_set=true  #endif) {  byte bedTemp[8] = {    B00000,    B11111,    B10101,    B10001,    B10101,    B11111,    B00000,    B00000  }; //thanks Sonny Mounicou  byte degree[8] = {    B01100,    B10010,    B10010,    B01100,    B00000,    B00000,    B00000,    B00000  };  byte thermometer[8] = {    B00100,    B01010,    B01010,    B01010,    B01010,    B10001,    B10001,    B01110  };  byte uplevel[8] = {    B00100,    B01110,    B11111,    B00100,    B11100,    B00000,    B00000,    B00000  }; //thanks joris  byte refresh[8] = {    B00000,    B00110,    B11001,    B11000,    B00011,    B10011,    B01100,    B00000,  }; //thanks joris  byte folder[8] = {    B00000,    B11100,    B11111,    B10001,    B10001,    B11111,    B00000,    B00000  }; //thanks joris  #ifdef LANGUAGE_EN_H  byte feedrate[8] = {    B11100,    B10000,    B11000,    B10111,    B00101,    B00110,    B00101,    B00000  }; //thanks Sonny Mounicou  #else /*  byte feedrate[8] = {        B11100,        B10100,        B11000,        B10100,        B00000,        B00111,        B00010,        B00010  };  */  /*  byte feedrate[8] = {        B01100,        B10011,        B00000,        B01100,        B10011,        B00000,        B01100,        B10011  };  */  byte feedrate[8] = {        B00000,        B00100,        B10010,        B01001,        B10010,        B00100,        B00000,        B00000  };  #endif  byte clock[8] = {    B00000,    B01110,    B10011,    B10101,    B10001,    B01110,    B00000,    B00000  }; //thanks Sonny Mounicou  byte arrup[8] = {    B00100,    B01110,    B11111,    B00000,    B00000,    B00000,    B00000,    B00000  };   byte arrdown[8] = {    B00000,    B00000,    B00000,    B00000,    B00000,    B10001,    B01010,    B00100  };   #if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT)    static bool char_mode = false;    byte progress[3][8] = { {      B00000,      B10000,      B10000,      B10000,      B10000,      B10000,      B10000,      B00000    }, {      B00000,      B10100,      B10100,      B10100,      B10100,      B10100,      B10100,      B00000    }, {      B00000,      B10101,      B10101,      B10101,      B10101,      B10101,      B10101,      B00000    } };    if (progress_bar_set != char_mode) {      char_mode = progress_bar_set;      lcd.createChar(LCD_STR_BEDTEMP[0], bedTemp);      lcd.createChar(LCD_STR_DEGREE[0], degree);      lcd.createChar(LCD_STR_THERMOMETER[0], thermometer);      lcd.createChar(LCD_STR_FEEDRATE[0], feedrate);      lcd.createChar(LCD_STR_CLOCK[0], clock);      if (progress_bar_set) {        // Progress bar characters for info screen        for (int i=3; i--;) lcd.createChar(LCD_STR_PROGRESS[i], progress[i]);      }      else {        // Custom characters for submenus        lcd.createChar(LCD_STR_UPLEVEL[0], uplevel);        lcd.createChar(LCD_STR_REFRESH[0], refresh);        lcd.createChar(LCD_STR_FOLDER[0], folder);      }    }  #else    lcd.createChar(LCD_STR_BEDTEMP[0], bedTemp);    lcd.createChar(LCD_STR_DEGREE[0], degree);    lcd.createChar(LCD_STR_THERMOMETER[0], thermometer);    lcd.createChar(LCD_STR_UPLEVEL[0], uplevel);    lcd.createChar(LCD_STR_REFRESH[0], refresh);    lcd.createChar(LCD_STR_FOLDER[0], folder);    lcd.createChar(LCD_STR_FEEDRATE[0], feedrate);    lcd.createChar(LCD_STR_CLOCK[0], clock);    //lcd.createChar(LCD_STR_ARROW_UP[0], arrup);    //lcd.createChar(LCD_STR_ARROW_DOWN[0], arrdown);  #endif}void lcd_set_custom_characters_arrows() {  byte arrdown[8] = {    B00000,    B00000,    B00000,    B00000,    B00000,    B10001,    B01010,    B00100  };     lcd.createChar(1, arrdown);}void lcd_set_custom_characters_nextpage() {  byte arrdown[8] = {    B00000,    B00000,    B10001,    B01010,    B00100,    B10001,    B01010,    B00100  };     lcd.createChar(1, arrdown);}void lcd_set_custom_characters_degree() {  byte degree[8] = {    B01100,    B10010,    B10010,    B01100,    B00000,    B00000,    B00000,    B00000  };    lcd.createChar(1, degree);}static void lcd_implementation_init(  #if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT)    bool progress_bar_set=true  #endif) {#if defined(LCD_I2C_TYPE_PCF8575)    lcd.begin(LCD_WIDTH, LCD_HEIGHT);  #ifdef LCD_I2C_PIN_BL    lcd.setBacklightPin(LCD_I2C_PIN_BL,POSITIVE);    lcd.setBacklight(HIGH);  #endif  #elif defined(LCD_I2C_TYPE_MCP23017)    lcd.setMCPType(LTI_TYPE_MCP23017);    lcd.begin(LCD_WIDTH, LCD_HEIGHT);    lcd.setBacklight(0); //set all the LEDs off to begin with    #elif defined(LCD_I2C_TYPE_MCP23008)    lcd.setMCPType(LTI_TYPE_MCP23008);    lcd.begin(LCD_WIDTH, LCD_HEIGHT);#elif defined(LCD_I2C_TYPE_PCA8574)      lcd.init();      lcd.backlight();    #else    lcd.begin(LCD_WIDTH, LCD_HEIGHT);#endif    lcd_set_custom_characters(        #if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT)            progress_bar_set        #endif    );    lcd.clear();}static void lcd_implementation_init_noclear(  #if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT)    bool progress_bar_set=true  #endif) {#if defined(LCD_I2C_TYPE_PCF8575)    lcd.begin_noclear(LCD_WIDTH, LCD_HEIGHT);  #ifdef LCD_I2C_PIN_BL    lcd.setBacklightPin(LCD_I2C_PIN_BL,POSITIVE);    lcd.setBacklight(HIGH);  #endif  #elif defined(LCD_I2C_TYPE_MCP23017)    lcd.setMCPType(LTI_TYPE_MCP23017);    lcd.begin_noclear(LCD_WIDTH, LCD_HEIGHT);    lcd.setBacklight(0); //set all the LEDs off to begin with    #elif defined(LCD_I2C_TYPE_MCP23008)    lcd.setMCPType(LTI_TYPE_MCP23008);    lcd.begin_noclear(LCD_WIDTH, LCD_HEIGHT);#elif defined(LCD_I2C_TYPE_PCA8574)      lcd.init();      lcd.backlight();    #else    lcd.begin_noclear(LCD_WIDTH, LCD_HEIGHT);#endif    lcd_set_custom_characters(        #if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT)            progress_bar_set        #endif    );}static void lcd_implementation_nodisplay(){    lcd.noDisplay();}static void lcd_implementation_display(){    lcd.display();}void lcd_implementation_clear(){    lcd.clear();}/* Arduino < 1.0.0 is missing a function to print PROGMEM strings, so we need to implement our own */void lcd_printPGM(const char* str){    char c;    while((c = pgm_read_byte(str++)) != '\0')    {        lcd.write(c);    }}void lcd_print_at_PGM(uint8_t x, uint8_t y, const char* str){    lcd.setCursor(x, y);    char c;    while((c = pgm_read_byte(str++)) != '\0')    {        lcd.write(c);    }}void lcd_implementation_write(char c){    lcd.write(c);}void lcd_implementation_print(int8_t i){    lcd.print(i);}void lcd_implementation_print_at(uint8_t x, uint8_t y, int8_t i){    lcd.setCursor(x, y);    lcd.print(i);}void lcd_implementation_print(int i){    lcd.print(i);}void lcd_implementation_print_at(uint8_t x, uint8_t y, int i){    lcd.setCursor(x, y);    lcd.print(i);}void lcd_implementation_print(float f){    lcd.print(f);}void lcd_implementation_print(const char *str){    lcd.print(str);}void lcd_implementation_print_at(uint8_t x, uint8_t y, const char *str){    lcd.setCursor(x, y);    lcd.print(str);}/*20x4   |01234567890123456789|       |T 000/000D  Z000.0  |       |B 000/000D  F100%   |       |SD100%      T--:--  |       |Status line.........|*/static void lcd_implementation_status_screen(){       int tHotend=int(degHotend(0) + 0.5);    int tTarget=int(degTargetHotend(0) + 0.5);    //Print the hotend temperature    lcd.setCursor(0, 0);    lcd.print(LCD_STR_THERMOMETER[0]);    lcd.print(itostr3(tHotend));    lcd.print('/');    lcd.print(itostr3left(tTarget));    lcd_printPGM(PSTR(LCD_STR_DEGREE " "));    lcd_printPGM(PSTR("  "));    //Print the Z coordinates    lcd.setCursor(LCD_WIDTH - 8-2, 0);#if 1    lcd_printPGM(PSTR("  Z"));    if (custom_message_type == 1) {        // In a bed calibration mode.        lcd_printPGM(PSTR("   --- "));    } else {        lcd.print(ftostr32sp(current_position[Z_AXIS] + 0.00001));        lcd.print(' ');    }#else    lcd_printPGM(PSTR(" Queue:"));    lcd.print(int(moves_planned()));    lcd.print(' ');#endif    //Print the Bedtemperature    lcd.setCursor(0, 1);    tHotend=int(degBed() + 0.5);    tTarget=int(degTargetBed() + 0.5);    lcd.print(LCD_STR_BEDTEMP[0]);    lcd.print(itostr3(tHotend));    lcd.print('/');    lcd.print(itostr3left(tTarget));    lcd_printPGM(PSTR(LCD_STR_DEGREE " "));    lcd_printPGM(PSTR("  "));#if 1    //Print Feedrate    lcd.setCursor(LCD_WIDTH - 8-2, 1);    lcd_printPGM(PSTR("  "));    lcd.print(LCD_STR_FEEDRATE[0]);    lcd.print(itostr3(feedmultiply));	lcd_printPGM(PSTR("%     "));	lcd.setCursor(8, 0);	lcd.print(itostr3(fan_speed[0]));	lcd.setCursor(8, 1);	lcd.print(itostr3(fan_speed[1]));#else    //Print Feedrate    lcd.setCursor(LCD_WIDTH - 8-2, 1);    lcd.print(LCD_STR_FEEDRATE[0]);    lcd.print(itostr3(feedmultiply));    lcd_printPGM(PSTR("%  Q"));    {      uint8_t queue = planner_queue_min();      if (queue < (BLOCK_BUFFER_SIZE >> 1)) {        lcd.print('!');      } else {        lcd.print((char)(queue / 10) + '0');        queue %= 10;      }      lcd.print((char)queue + '0');      planner_queue_min_reset();    }#endif	    //Print SD status    lcd.setCursor(0, 2);	if (is_usb_printing)	{		lcd_printPGM(PSTR("--"));	}	else	{		lcd_printPGM(PSTR("SD"));	}	if (IS_SD_PRINTING)	{		lcd.print(itostr3(card.percentDone()));		lcd.print('%');	}	else	{		if (is_usb_printing)		{			lcd_printPGM(PSTR(">USB"));		}		else		{			lcd_printPGM(PSTR("---"));			lcd.print('%');		}	}    	// Farm number display	if (farm_mode)	{		lcd_printPGM(PSTR(" F"));		lcd.print(farm_no);		lcd_printPGM(PSTR("  "));                // Beat display        lcd.setCursor(LCD_WIDTH - 1, 0);        if ( (millis() - kicktime) < 60000 ) {                    lcd_printPGM(PSTR("L"));                }else{            lcd_printPGM(PSTR(" "));        }        	}	else {		lcd.setCursor(LCD_WIDTH - 8 - 2, 2);		lcd_printPGM(PSTR(" "));	}#ifdef SNMM		lcd_printPGM(PSTR(" E"));		lcd.print(get_ext_nr()+1);	#endif    //Print time elapsed    lcd.setCursor(LCD_WIDTH - 8 -1, 2);    lcd_printPGM(PSTR(" "));    lcd.print(LCD_STR_CLOCK[0]);    if(starttime != 0)    {        uint16_t time = millis()/60000 - starttime/60000;        lcd.print(itostr2(time/60));        lcd.print(':');        lcd.print(itostr2(time%60));    }else{        lcd_printPGM(PSTR("--:--"));    }    lcd_printPGM(PSTR("  "));    //Print status line    lcd.setCursor(0, 3);    // If heating in progress, set flag	if (heating_status != 0) { custom_message = true; }    // If printing from SD, show what we are printing	if ((IS_SD_PRINTING) && !custom_message)	{      if(strcmp(longFilenameOLD, card.longFilename) != 0)	  {        memset(longFilenameOLD,'\0',strlen(longFilenameOLD));        sprintf_P(longFilenameOLD, PSTR("%s"), card.longFilename);        scrollstuff = 0;      }      if(strlen(card.longFilename) > LCD_WIDTH)	  {        int inters = 0;        int gh = scrollstuff;        while( ((gh-scrollstuff)<LCD_WIDTH) && (inters == 0)  )		{                    if(card.longFilename[gh] == '\0')		  {            lcd.setCursor(gh-scrollstuff, 3);            lcd.print(card.longFilename[gh-1]);            scrollstuff = 0;            gh = scrollstuff;            inters = 1;          }		  else		  {            lcd.setCursor(gh-scrollstuff, 3);            lcd.print(card.longFilename[gh-1]);            gh++;          }                  }        scrollstuff++;      }	  else	  {        lcd.print(longFilenameOLD);      }    }    // If not, check for other special events	else	{        		if (custom_message)		{            // If heating flag, show progress of heating.			if (heating_status != 0)			{				heating_status_counter++;				if (heating_status_counter > 13)				{					heating_status_counter = 0;				}				lcd.setCursor(7, 3);				lcd_printPGM(PSTR("             "));				for (int dots = 0; dots < heating_status_counter; dots++)				{					lcd.setCursor(7 + dots, 3);					lcd.print('.');				}				switch (heating_status)				{				case 1:					lcd.setCursor(0, 3);					lcd_printPGM(MSG_HEATING);					break;				case 2:					lcd.setCursor(0, 3);					lcd_printPGM(MSG_HEATING_COMPLETE);					heating_status = 0;					heating_status_counter = 0;					custom_message = false;					break;				case 3:					lcd.setCursor(0, 3);					lcd_printPGM(MSG_BED_HEATING);					break;				case 4:					lcd.setCursor(0, 3);					lcd_printPGM(MSG_BED_DONE);					heating_status = 0;					heating_status_counter = 0;					custom_message = false;					break;				default:					break;				}			}                        // If mesh bed leveling in progress, show the status            			if (custom_message_type == 1)			{				if (custom_message_state > 10)				{					lcd.setCursor(0, 3);					lcd_printPGM(PSTR("                    "));					lcd.setCursor(0, 3);					lcd_printPGM(MSG_HOMEYZ_PROGRESS);					lcd_printPGM(PSTR(" : "));					lcd.print(custom_message_state-10);				}				else				{					if (custom_message_state == 3)					{						lcd_printPGM(WELCOME_MSG);						lcd_setstatuspgm(WELCOME_MSG);						custom_message = false;						custom_message_type = 0;					}					if (custom_message_state > 3 && custom_message_state < 10 )					{						lcd.setCursor(0, 3);						lcd_printPGM(PSTR("                   "));						lcd.setCursor(0, 3);						lcd_printPGM(MSG_HOMEYZ_DONE);						custom_message_state--;					}					if (custom_message_state == 10)					{						lcd_printPGM(MSG_HOMEYZ_DONE);						custom_message_state = 9;					}				}			}            // If loading filament, print status			if (custom_message_type == 2)			{				lcd.print(lcd_status_message);			}		}	else		{            // Nothing special, print status message normally			lcd.print(lcd_status_message);		}	}        // Fill the rest of line to have nice and clean output    for(int fillspace = 0; fillspace<20;fillspace++)	{      if((lcd_status_message[fillspace] > 31 ))	  {      }	  else	  {        lcd.print(' ');      }    }	}static void lcd_implementation_drawmenu_generic(uint8_t row, const char* pstr, char pre_char, char post_char){    char c;    //Use all characters in narrow LCDs  #if LCD_WIDTH < 20      uint8_t n = LCD_WIDTH - 1 - 1;    #else      uint8_t n = LCD_WIDTH - 1 - 2;  #endif    lcd.setCursor(0, row);    lcd.print(pre_char);    while( ((c = pgm_read_byte(pstr)) != '\0') && (n>0) )    {        lcd.print(c);        pstr++;        n--;    }    while(n--)        lcd.print(' ');    lcd.print(post_char);    lcd.print(' ');}static void lcd_implementation_drawmenu_generic_RAM(uint8_t row, const char* str, char pre_char, char post_char){    char c;    //Use all characters in narrow LCDs  #if LCD_WIDTH < 20      uint8_t n = LCD_WIDTH - 1 - 1;    #else      uint8_t n = LCD_WIDTH - 1 - 2;  #endif    lcd.setCursor(0, row);    lcd.print(pre_char);    while( ((c = *str) != '\0') && (n>0) )    {        lcd.print(c);        str++;        n--;    }    while(n--)        lcd.print(' ');    lcd.print(post_char);    lcd.print(' ');}static void lcd_implementation_drawmenu_setting_edit_generic(uint8_t row, const char* pstr, char pre_char, char* data){    char c;    //Use all characters in narrow LCDs  #if LCD_WIDTH < 20      uint8_t n = LCD_WIDTH - 1 - 1 - strlen(data);    #else      uint8_t n = LCD_WIDTH - 1 - 2 - strlen(data);  #endif    lcd.setCursor(0, row);    lcd.print(pre_char);    while( ((c = pgm_read_byte(pstr)) != '\0') && (n>0) )    {        lcd.print(c);        pstr++;        n--;    }    lcd.print(':');    while(n--)        lcd.print(' ');    lcd.print(data);}static void lcd_implementation_drawmenu_setting_edit_generic_P(uint8_t row, const char* pstr, char pre_char, const char* data){    char c;    //Use all characters in narrow LCDs  #if LCD_WIDTH < 20      uint8_t n = LCD_WIDTH - 1 - 1 - strlen_P(data);    #else      uint8_t n = LCD_WIDTH - 1 - 2 - strlen_P(data);  #endif    lcd.setCursor(0, row);    lcd.print(pre_char);    while( ((c = pgm_read_byte(pstr)) != '\0') && (n>0) )    {        lcd.print(c);        pstr++;        n--;    }    lcd.print(':');    while(n--)        lcd.print(' ');    lcd_printPGM(data);}#define lcd_implementation_drawmenu_setting_edit_int3_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', itostr3(*(data)))#define lcd_implementation_drawmenu_setting_edit_int3(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', itostr3(*(data)))#define lcd_implementation_drawmenu_setting_edit_float3_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr3(*(data)))#define lcd_implementation_drawmenu_setting_edit_float3(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr3(*(data)))#define lcd_implementation_drawmenu_setting_edit_float32_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr32(*(data)))#define lcd_implementation_drawmenu_setting_edit_float32(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr32(*(data)))#define lcd_implementation_drawmenu_setting_edit_float43_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr43(*(data)))#define lcd_implementation_drawmenu_setting_edit_float43(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr43(*(data)))#define lcd_implementation_drawmenu_setting_edit_float5_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data)))#define lcd_implementation_drawmenu_setting_edit_float5(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data)))#define lcd_implementation_drawmenu_setting_edit_float52_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr52(*(data)))#define lcd_implementation_drawmenu_setting_edit_float52(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr52(*(data)))#define lcd_implementation_drawmenu_setting_edit_float51_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr51(*(data)))#define lcd_implementation_drawmenu_setting_edit_float51(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr51(*(data)))#define lcd_implementation_drawmenu_setting_edit_long5_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data)))#define lcd_implementation_drawmenu_setting_edit_long5(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data)))#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))#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))//Add version for callback functions#define lcd_implementation_drawmenu_setting_edit_callback_int3_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', itostr3(*(data)))#define lcd_implementation_drawmenu_setting_edit_callback_int3(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', itostr3(*(data)))#define lcd_implementation_drawmenu_setting_edit_callback_float3_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr3(*(data)))#define lcd_implementation_drawmenu_setting_edit_callback_float3(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr3(*(data)))#define lcd_implementation_drawmenu_setting_edit_callback_float32_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr32(*(data)))#define lcd_implementation_drawmenu_setting_edit_callback_float32(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr32(*(data)))#define lcd_implementation_drawmenu_setting_edit_callback_float43_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr43(*(data)))#define lcd_implementation_drawmenu_setting_edit_callback_float43(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr43(*(data)))#define lcd_implementation_drawmenu_setting_edit_callback_float5_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data)))#define lcd_implementation_drawmenu_setting_edit_callback_float5(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data)))#define lcd_implementation_drawmenu_setting_edit_callback_float52_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr52(*(data)))#define lcd_implementation_drawmenu_setting_edit_callback_float52(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr52(*(data)))#define lcd_implementation_drawmenu_setting_edit_callback_float51_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr51(*(data)))#define lcd_implementation_drawmenu_setting_edit_callback_float51(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr51(*(data)))#define lcd_implementation_drawmenu_setting_edit_callback_long5_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data)))#define lcd_implementation_drawmenu_setting_edit_callback_long5(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data)))#define lcd_implementation_drawmenu_setting_edit_callback_bool_selected(row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, '>', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))#define lcd_implementation_drawmenu_setting_edit_callback_bool(row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, ' ', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))void lcd_implementation_drawedit(const char* pstr, char* value){    lcd.setCursor(1, 1);    lcd_printPGM(pstr);    lcd.print(':');   #if LCD_WIDTH < 20      lcd.setCursor(LCD_WIDTH - strlen(value), 1);    #else      lcd.setCursor(LCD_WIDTH -1 - strlen(value), 1);   #endif    lcd.print(value);}void lcd_implementation_drawedit_2(const char* pstr, char* value){    lcd.setCursor(0, 1);    lcd_printPGM(pstr);    lcd.print(':');    lcd.setCursor((LCD_WIDTH - strlen(value))/2, 3);    lcd.print(value);    lcd.print(" mm");}static void lcd_implementation_drawmenu_sdfile_selected(uint8_t row, const char* pstr, const char* filename, char* longFilename){    char c;    int enc_dif = encoderDiff;    uint8_t n = LCD_WIDTH - 1;    for(int g = 0; g<4;g++){      lcd.setCursor(0, g);    lcd.print(' ');    }    lcd.setCursor(0, row);    lcd.print('>');    if (longFilename[0] != '\0')    {        filename = longFilename;        //longFilename[LCD_WIDTH-1] = '\0';    }    int i = 1;    int j = 0;    int inter = 0;    char* longFilenameTMP = longFilename;    while( ((c = *longFilenameTMP) != '\0') && (inter == 0) )    {        lcd.setCursor(i, row);        lcd.print(c);        i++;        longFilenameTMP++;        if(i==LCD_WIDTH){          i=1;          j++;          longFilenameTMP = longFilename;          longFilenameTMP = longFilenameTMP+j;          n = LCD_WIDTH - 1;          for(int g = 0; ((g<300)&&(inter == 0)) ;g++){            if(LCD_CLICKED || ( enc_dif != encoderDiff )){                            //  inter = 1;            }else{              delay(1);            }          }        }    }    if(c!='\0'){      lcd.setCursor(i, row);        lcd.print(c);        i++;    }    n=n-i+1;    while(n--)        lcd.print(' ');}static void lcd_implementation_drawmenu_sdfile(uint8_t row, const char* pstr, const char* filename, char* longFilename){    char c;    uint8_t n = LCD_WIDTH - 1;    lcd.setCursor(0, row);    lcd.print(' ');    if (longFilename[0] != '\0')    {        filename = longFilename;        longFilename[LCD_WIDTH-1] = '\0';    }    while( ((c = *filename) != '\0') && (n>0) )    {        lcd.print(c);        filename++;        n--;    }    while(n--)        lcd.print(' ');}static void lcd_implementation_drawmenu_sddirectory_selected(uint8_t row, const char* pstr, const char* filename, char* longFilename){    char c;    uint8_t n = LCD_WIDTH - 2;    lcd.setCursor(0, row);    lcd.print('>');    lcd.print(LCD_STR_FOLDER[0]);    if (longFilename[0] != '\0')    {        filename = longFilename;        longFilename[LCD_WIDTH-2] = '\0';    }    while( ((c = *filename) != '\0') && (n>0) )    {        lcd.print(c);        filename++;        n--;    }    while(n--)        lcd.print(' ');}static void lcd_implementation_drawmenu_sddirectory(uint8_t row, const char* pstr, const char* filename, char* longFilename){    char c;    uint8_t n = LCD_WIDTH - 2;    lcd.setCursor(0, row);    lcd.print(' ');    lcd.print(LCD_STR_FOLDER[0]);    if (longFilename[0] != '\0')    {        filename = longFilename;        longFilename[LCD_WIDTH-2] = '\0';    }    while( ((c = *filename) != '\0') && (n>0) )    {        lcd.print(c);        filename++;        n--;    }    while(n--)        lcd.print(' ');}#define lcd_implementation_drawmenu_back_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0])#define lcd_implementation_drawmenu_back(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', LCD_STR_UPLEVEL[0])#define lcd_implementation_drawmenu_back_RAM_selected(row, str, data) lcd_implementation_drawmenu_generic_RAM(row, str, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0])#define lcd_implementation_drawmenu_back_RAM(row, str, data) lcd_implementation_drawmenu_generic_RAM(row, str, ' ', LCD_STR_UPLEVEL[0])#define lcd_implementation_drawmenu_submenu_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, '>', LCD_STR_ARROW_RIGHT[0])#define lcd_implementation_drawmenu_submenu(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', LCD_STR_ARROW_RIGHT[0])#define lcd_implementation_drawmenu_gcode_selected(row, pstr, gcode) lcd_implementation_drawmenu_generic(row, pstr, '>', ' ')#define lcd_implementation_drawmenu_gcode(row, pstr, gcode) lcd_implementation_drawmenu_generic(row, pstr, ' ', ' ')#define lcd_implementation_drawmenu_function_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, '>', ' ')#define lcd_implementation_drawmenu_function(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', ' ')#define lcd_implementation_drawmenu_setlang_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, '>', ' ')#define lcd_implementation_drawmenu_setlang(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', ' ')static void lcd_implementation_quick_feedback(){#ifdef LCD_USE_I2C_BUZZER	#if !defined(LCD_FEEDBACK_FREQUENCY_HZ) || !defined(LCD_FEEDBACK_FREQUENCY_DURATION_MS)	  lcd_buzz(1000/6,100);	#else	  lcd_buzz(LCD_FEEDBACK_FREQUENCY_DURATION_MS,LCD_FEEDBACK_FREQUENCY_HZ);	#endif#elif defined(BEEPER) && BEEPER > -1    SET_OUTPUT(BEEPER);	#if !defined(LCD_FEEDBACK_FREQUENCY_HZ) || !defined(LCD_FEEDBACK_FREQUENCY_DURATION_MS)    for(int8_t i=0;i<10;i++)    {      WRITE(BEEPER,HIGH);      delayMicroseconds(100);      WRITE(BEEPER,LOW);      delayMicroseconds(100);    }    #else    for(int8_t i=0;i<(LCD_FEEDBACK_FREQUENCY_DURATION_MS / (1000 / LCD_FEEDBACK_FREQUENCY_HZ));i++)    {      WRITE(BEEPER,HIGH);      delayMicroseconds(1000000 / LCD_FEEDBACK_FREQUENCY_HZ / 2);      WRITE(BEEPER,LOW);      delayMicroseconds(1000000 / LCD_FEEDBACK_FREQUENCY_HZ / 2);    }    #endif#endif}#ifdef LCD_HAS_STATUS_INDICATORSstatic void lcd_implementation_update_indicators(){  #if defined(LCD_I2C_PANELOLU2) || defined(LCD_I2C_VIKI)    //set the LEDS - referred to as backlights by the LiquidTWI2 library     static uint8_t ledsprev = 0;    uint8_t leds = 0;    if (target_temperature_bed > 0) leds |= LED_A;    if (target_temperature[0] > 0) leds |= LED_B;    if (fanSpeed) leds |= LED_C;    #if EXTRUDERS > 1        if (target_temperature[1] > 0) leds |= LED_C;    #endif    if (leds != ledsprev) {      lcd.setBacklight(leds);      ledsprev = leds;    }  #endif}#endif#ifdef LCD_HAS_SLOW_BUTTONSextern uint32_t blocking_enc;static uint8_t lcd_implementation_read_slow_buttons(){  #ifdef LCD_I2C_TYPE_MCP23017  uint8_t slow_buttons;    // Reading these buttons this is likely to be too slow to call inside interrupt context    // so they are called during normal lcd_update    slow_buttons = lcd.readButtons() << B_I2C_BTN_OFFSET;     #if defined(LCD_I2C_VIKI)    if(slow_buttons & (B_MI|B_RI)) { //LCD clicked       if(blocking_enc > millis()) {         slow_buttons &= ~(B_MI|B_RI); // Disable LCD clicked buttons if screen is updated       }    }    #endif    return slow_buttons;   #endif}#endif#endif//ULTRA_LCD_IMPLEMENTATION_HITACHI_HD44780_H
 |