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.pde 36KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504
  1. #include "ultralcd.h"
  2. #ifdef ULTRA_LCD
  3. //===========================================================================
  4. //=============================imported variables============================
  5. //===========================================================================
  6. extern volatile int feedmultiply;
  7. extern volatile bool feedmultiplychanged;
  8. extern long position[4];
  9. extern CardReader card;
  10. //===========================================================================
  11. //=============================public variables============================
  12. //===========================================================================
  13. volatile char buttons=0; //the last checked buttons in a bit array.
  14. int encoderpos=0;
  15. short lastenc=0;
  16. //===========================================================================
  17. //=============================private variables============================
  18. //===========================================================================
  19. static char messagetext[LCD_WIDTH]="";
  20. //return for string conversion routines
  21. static char conv[8];
  22. #include <LiquidCrystal.h>
  23. 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
  24. static unsigned long previous_millis_lcd=0;
  25. static long previous_millis_buttons=0;
  26. #ifdef NEWPANEL
  27. static long blocking=0;
  28. #else
  29. static long blocking[8]={0,0,0,0,0,0,0,0};
  30. #endif
  31. static MainMenu menu;
  32. #include <avr/pgmspace.h>
  33. void lcdProgMemprint(const char *str)
  34. {
  35. char ch=pgm_read_byte(str);
  36. while(ch)
  37. {
  38. lcd.print(ch);
  39. ch=pgm_read_byte(++str);
  40. }
  41. }
  42. #define lcdprintPGM(x) lcdProgMemprint(PSTR(x))
  43. //===========================================================================
  44. //=============================functions ============================
  45. //===========================================================================
  46. inline int intround(const float &x){return int(0.5+x);}
  47. void lcd_status(const char* message)
  48. {
  49. strncpy(messagetext,message,LCD_WIDTH);
  50. }
  51. void lcd_statuspgm(const char* message)
  52. {
  53. char ch=pgm_read_byte(message);
  54. char *target=messagetext;
  55. uint8_t cnt=0;
  56. while(ch &&cnt<LCD_WIDTH)
  57. {
  58. *target=ch;
  59. target++;
  60. cnt++;
  61. ch=pgm_read_byte(++message);
  62. }
  63. }
  64. inline void clear()
  65. {
  66. lcd.clear();
  67. }
  68. void lcd_init()
  69. {
  70. //beep();
  71. byte Degree[8] =
  72. {
  73. B01100,
  74. B10010,
  75. B10010,
  76. B01100,
  77. B00000,
  78. B00000,
  79. B00000,
  80. B00000
  81. };
  82. byte Thermometer[8] =
  83. {
  84. B00100,
  85. B01010,
  86. B01010,
  87. B01010,
  88. B01010,
  89. B10001,
  90. B10001,
  91. B01110
  92. };
  93. byte uplevel[8]={0x04, 0x0e, 0x1f, 0x04, 0x1c, 0x00, 0x00, 0x00};//thanks joris
  94. byte refresh[8]={0x00, 0x06, 0x19, 0x18, 0x03, 0x13, 0x0c, 0x00}; //thanks joris
  95. byte folder [8]={0x00, 0x1c, 0x1f, 0x11, 0x11, 0x1f, 0x00, 0x00}; //thanks joris
  96. lcd.begin(LCD_WIDTH, LCD_HEIGHT);
  97. lcd.createChar(1,Degree);
  98. lcd.createChar(2,Thermometer);
  99. lcd.createChar(3,uplevel);
  100. lcd.createChar(4,refresh);
  101. lcd.createChar(5,folder);
  102. LCD_MESSAGEPGM("UltiMarlin ready.");
  103. }
  104. void beep()
  105. {
  106. //return;
  107. #ifdef ULTIPANEL
  108. pinMode(BEEPER,OUTPUT);
  109. for(int8_t i=0;i<20;i++){
  110. WRITE(BEEPER,HIGH);
  111. delay(5);
  112. WRITE(BEEPER,LOW);
  113. delay(5);
  114. }
  115. #endif
  116. }
  117. void beepshort()
  118. {
  119. //return;
  120. #ifdef ULTIPANEL
  121. pinMode(BEEPER,OUTPUT);
  122. for(int8_t i=0;i<10;i++){
  123. WRITE(BEEPER,HIGH);
  124. delay(3);
  125. WRITE(BEEPER,LOW);
  126. delay(3);
  127. }
  128. #endif
  129. }
  130. void lcd_status()
  131. {
  132. #ifdef ULTIPANEL
  133. static uint8_t oldbuttons=0;
  134. static long previous_millis_buttons=0;
  135. static long previous_lcdinit=0;
  136. // buttons_check(); // Done in temperature interrupt
  137. //previous_millis_buttons=millis();
  138. if((buttons==oldbuttons) && ((millis() - previous_millis_lcd) < LCD_UPDATE_INTERVAL) )
  139. return;
  140. oldbuttons=buttons;
  141. #else
  142. if(((millis() - previous_millis_lcd) < LCD_UPDATE_INTERVAL) )
  143. return;
  144. #endif
  145. previous_millis_lcd=millis();
  146. menu.update();
  147. }
  148. #ifdef ULTIPANEL
  149. void buttons_init()
  150. {
  151. #ifdef NEWPANEL
  152. pinMode(BTN_EN1,INPUT);
  153. pinMode(BTN_EN2,INPUT);
  154. pinMode(BTN_ENC,INPUT);
  155. pinMode(SDCARDDETECT,INPUT);
  156. WRITE(BTN_EN1,HIGH);
  157. WRITE(BTN_EN2,HIGH);
  158. WRITE(BTN_ENC,HIGH);
  159. WRITE(SDCARDDETECT,HIGH);
  160. #else
  161. pinMode(SHIFT_CLK,OUTPUT);
  162. pinMode(SHIFT_LD,OUTPUT);
  163. pinMode(SHIFT_EN,OUTPUT);
  164. pinMode(SHIFT_OUT,INPUT);
  165. WRITE(SHIFT_OUT,HIGH);
  166. WRITE(SHIFT_LD,HIGH);
  167. WRITE(SHIFT_EN,LOW);
  168. #endif
  169. }
  170. void buttons_check()
  171. {
  172. #ifdef NEWPANEL
  173. uint8_t newbutton=0;
  174. if(READ(BTN_EN1)==0) newbutton|=EN_A;
  175. if(READ(BTN_EN2)==0) newbutton|=EN_B;
  176. if((blocking<millis()) &&(READ(BTN_ENC)==0))
  177. newbutton|=EN_C;
  178. buttons=newbutton;
  179. #else //read it from the shift register
  180. uint8_t newbutton=0;
  181. WRITE(SHIFT_LD,LOW);
  182. WRITE(SHIFT_LD,HIGH);
  183. unsigned char tmp_buttons=0;
  184. for(int8_t i=0;i<8;i++)
  185. {
  186. newbutton = newbutton>>1;
  187. if(READ(SHIFT_OUT))
  188. newbutton|=(1<<7);
  189. WRITE(SHIFT_CLK,HIGH);
  190. WRITE(SHIFT_CLK,LOW);
  191. }
  192. buttons=~newbutton; //invert it, because a pressed switch produces a logical 0
  193. #endif
  194. //manage encoder rotation
  195. char enc=0;
  196. if(buttons&EN_A)
  197. enc|=(1<<0);
  198. if(buttons&EN_B)
  199. enc|=(1<<1);
  200. if(enc!=lastenc)
  201. {
  202. switch(enc)
  203. {
  204. case encrot0:
  205. if(lastenc==encrot3)
  206. encoderpos++;
  207. else if(lastenc==encrot1)
  208. encoderpos--;
  209. break;
  210. case encrot1:
  211. if(lastenc==encrot0)
  212. encoderpos++;
  213. else if(lastenc==encrot2)
  214. encoderpos--;
  215. break;
  216. case encrot2:
  217. if(lastenc==encrot1)
  218. encoderpos++;
  219. else if(lastenc==encrot3)
  220. encoderpos--;
  221. break;
  222. case encrot3:
  223. if(lastenc==encrot2)
  224. encoderpos++;
  225. else if(lastenc==encrot0)
  226. encoderpos--;
  227. break;
  228. default:
  229. ;
  230. }
  231. }
  232. lastenc=enc;
  233. }
  234. #endif
  235. MainMenu::MainMenu()
  236. {
  237. status=Main_Status;
  238. displayStartingRow=0;
  239. activeline=0;
  240. force_lcd_update=true;
  241. #ifdef ULTIPANEL
  242. buttons_init();
  243. #endif
  244. lcd_init();
  245. linechanging=false;
  246. }
  247. void MainMenu::showStatus()
  248. {
  249. #if LCD_HEIGHT==4
  250. static int olddegHotEnd0=-1;
  251. static int oldtargetHotEnd0=-1;
  252. //force_lcd_update=true;
  253. if(force_lcd_update||feedmultiplychanged) //initial display of content
  254. {
  255. feedmultiplychanged=false;
  256. encoderpos=feedmultiply;
  257. clear();
  258. lcd.setCursor(0,0);lcdprintPGM("\002123/567\001 ");
  259. #if defined BED_USES_THERMISTOR || defined BED_USES_AD595
  260. lcd.setCursor(10,0);lcdprintPGM("B123/567\001 ");
  261. #endif
  262. }
  263. int tHotEnd0=intround(degHotend0());
  264. if((abs(tHotEnd0-olddegHotEnd0)>1)||force_lcd_update) //>1 because otherwise the lcd is refreshed to often.
  265. {
  266. lcd.setCursor(1,0);
  267. lcd.print(ftostr3(tHotEnd0));
  268. olddegHotEnd0=tHotEnd0;
  269. }
  270. int ttHotEnd0=intround(degTargetHotend0());
  271. if((ttHotEnd0!=oldtargetHotEnd0)||force_lcd_update)
  272. {
  273. lcd.setCursor(5,0);
  274. lcd.print(ftostr3(ttHotEnd0));
  275. oldtargetHotEnd0=ttHotEnd0;
  276. }
  277. #if defined BED_USES_THERMISTOR || defined BED_USES_AD595
  278. static int oldtBed=-1;
  279. static int oldtargetBed=-1;
  280. int tBed=intround(degBed());
  281. if((tBed!=oldtBed)||force_lcd_update)
  282. {
  283. lcd.setCursor(1,0);
  284. lcd.print(ftostr3(tBed));
  285. oldtBed=tBed;
  286. }
  287. int targetBed=intround(degTargetBed());
  288. if((targetBed!=oldtargetBed)||force_lcd_update)
  289. {
  290. lcd.setCursor(5,0);
  291. lcd.print(ftostr3(targetBed));
  292. oldtargetBed=targetBed;
  293. }
  294. #endif
  295. //starttime=2;
  296. static uint16_t oldtime=0;
  297. if(starttime!=0)
  298. {
  299. lcd.setCursor(0,1);
  300. uint16_t time=millis()/60000-starttime/60000;
  301. if(starttime!=oldtime)
  302. {
  303. lcd.print(itostr2(time/60));lcdprintPGM("h ");lcd.print(itostr2(time%60));lcdprintPGM("m");
  304. oldtime=time;
  305. }
  306. }
  307. static int oldzpos=0;
  308. int currentz=current_position[2]*10;
  309. if((currentz!=oldzpos)||force_lcd_update)
  310. {
  311. lcd.setCursor(10,1);
  312. lcdprintPGM("Z:");lcd.print(itostr31(currentz));
  313. oldzpos=currentz;
  314. }
  315. static int oldfeedmultiply=0;
  316. int curfeedmultiply=feedmultiply;
  317. if(encoderpos!=curfeedmultiply||force_lcd_update)
  318. {
  319. curfeedmultiply=encoderpos;
  320. if(curfeedmultiply<10)
  321. curfeedmultiply=10;
  322. if(curfeedmultiply>999)
  323. curfeedmultiply=999;
  324. feedmultiply=curfeedmultiply;
  325. encoderpos=curfeedmultiply;
  326. }
  327. if((curfeedmultiply!=oldfeedmultiply)||force_lcd_update)
  328. {
  329. oldfeedmultiply=curfeedmultiply;
  330. lcd.setCursor(0,2);
  331. lcd.print(itostr3(curfeedmultiply));lcdprintPGM("% ");
  332. }
  333. if(messagetext[0]!='\0')
  334. {
  335. lcd.setCursor(0,LCD_HEIGHT-1);
  336. lcd.print(fillto(LCD_WIDTH,messagetext));
  337. messagetext[0]='\0';
  338. }
  339. static uint8_t oldpercent=101;
  340. uint8_t percent=card.percentDone();
  341. if(oldpercent!=percent ||force_lcd_update)
  342. {
  343. lcd.setCursor(7,2);
  344. lcd.print(itostr3((int)percent));
  345. lcdprintPGM("%SD");
  346. }
  347. #else //smaller LCDS----------------------------------
  348. static int olddegHotEnd0=-1;
  349. static int oldtargetHotEnd0=-1;
  350. if(force_lcd_update) //initial display of content
  351. {
  352. encoderpos=feedmultiply;
  353. lcd.setCursor(0,0);lcdprintPGM("\002123/567\001 ");
  354. #if defined BED_USES_THERMISTOR || defined BED_USES_AD595
  355. lcd.setCursor(10,0);lcdprintPGM("B123/567\001 ");
  356. #endif
  357. }
  358. int tHotEnd0=intround(degHotend0());
  359. int ttHotEnd0=intround(degTargetHotend0());
  360. if((abs(tHotEnd0-olddegHotEnd0)>1)||force_lcd_update)
  361. {
  362. lcd.setCursor(1,0);
  363. lcd.print(ftostr3(tHotEnd0));
  364. olddegHotEnd0=tHotEnd0;
  365. }
  366. if((ttHotEnd0!=oldtargetHotEnd0)||force_lcd_update)
  367. {
  368. lcd.setCursor(5,0);
  369. lcd.print(ftostr3(ttHotEnd0));
  370. oldtargetHotEnd0=ttHotEnd0;
  371. }
  372. if(messagetext[0]!='\0')
  373. {
  374. lcd.setCursor(0,LCD_HEIGHT-1);
  375. lcd.print(fillto(LCD_WIDTH,messagetext));
  376. messagetext[0]='\0';
  377. }
  378. #endif
  379. force_lcd_update=false;
  380. }
  381. enum {ItemP_exit, ItemP_home, ItemP_origin, ItemP_preheat, ItemP_extrude, ItemP_disstep};
  382. //any action must not contain a ',' character anywhere, or this breaks:
  383. #define MENUITEM(repaint_action, click_action) \
  384. {\
  385. if(force_lcd_update) { lcd.setCursor(0,line); repaint_action; } \
  386. if((activeline==line) && CLICKED) {click_action} \
  387. }
  388. void MainMenu::showPrepare()
  389. {
  390. uint8_t line=0;
  391. clearIfNecessary();
  392. for(int8_t i=lineoffset;i<lineoffset+LCD_HEIGHT;i++)
  393. {
  394. //Serial.println((int)(line-lineoffset));
  395. switch(i)
  396. {
  397. case ItemP_exit:
  398. MENUITEM( lcdprintPGM(" Prepare") , BLOCK;status=Main_Menu;beepshort(); ) ;
  399. break;
  400. case ItemP_home:
  401. MENUITEM( lcdprintPGM(" Auto Home") , BLOCK;enquecommand("G28 X-105 Y-105 Z0");beepshort(); ) ;
  402. break;
  403. case ItemP_origin:
  404. MENUITEM( lcdprintPGM(" Set Origin") , BLOCK;enquecommand("G92 X0 Y0 Z0");beepshort(); ) ;
  405. break;
  406. case ItemP_preheat:
  407. MENUITEM( lcdprintPGM(" Preheat") , BLOCK;setTargetHotend0(170);beepshort(); ) ;
  408. break;
  409. case ItemP_extrude:
  410. MENUITEM( lcdprintPGM(" Extrude") , BLOCK;enquecommand("G92 E0");enquecommand("G1 F700 E50");beepshort(); ) ;
  411. break;
  412. case ItemP_disstep:
  413. MENUITEM( lcdprintPGM(" Disable Steppers") , BLOCK;enquecommand("M84");beepshort(); ) ;
  414. break;
  415. default:
  416. break;
  417. }
  418. line++;
  419. }
  420. updateActiveLines(ItemP_disstep,encoderpos);
  421. }
  422. //does not work
  423. // #define MENUCHANGEITEM(repaint_action, enter_action, accept_action, change_action) \
  424. // {\
  425. // if(force_lcd_update) { lcd.setCursor(0,line); repaint_action; } \
  426. // if(activeline==line) \
  427. // { \
  428. // if(CLICKED) \
  429. // { \
  430. // linechanging=!linechanging; \
  431. // if(linechanging) {enter_action;} \
  432. // else {accept_action;} \
  433. // } \
  434. // else \
  435. // if(linechanging) {change_action};}\
  436. // }
  437. //
  438. enum {
  439. ItemCT_exit, ItemCT_nozzle, ItemCT_fan,
  440. ItemCT_PID_P,ItemCT_PID_I,ItemCT_PID_D,ItemCT_PID_C
  441. };
  442. void MainMenu::showControlTemp()
  443. {
  444. uint8_t line=0;
  445. clearIfNecessary();
  446. for(int8_t i=lineoffset;i<lineoffset+LCD_HEIGHT;i++)
  447. {
  448. switch(i)
  449. {
  450. case ItemCT_exit:
  451. MENUITEM( lcdprintPGM(" Temperature") , BLOCK;status=Main_Control;beepshort(); ) ;
  452. break;
  453. case ItemCT_nozzle:
  454. {
  455. if(force_lcd_update)
  456. {
  457. lcd.setCursor(0,line);lcdprintPGM(" \002Nozzle:");
  458. lcd.setCursor(13,line);lcd.print(ftostr3(intround(degHotend0())));
  459. }
  460. if((activeline==line) )
  461. {
  462. if(CLICKED)
  463. {
  464. linechanging=!linechanging;
  465. if(linechanging)
  466. {
  467. encoderpos=intround(degHotend0());
  468. }
  469. else
  470. {
  471. setTargetHotend0(encoderpos);
  472. encoderpos=activeline*lcdslow;
  473. beepshort();
  474. }
  475. BLOCK;
  476. }
  477. if(linechanging)
  478. {
  479. if(encoderpos<0) encoderpos=0;
  480. if(encoderpos>260) encoderpos=260;
  481. lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));
  482. }
  483. }
  484. }break;
  485. case ItemCT_fan:
  486. {
  487. if(force_lcd_update)
  488. {
  489. lcd.setCursor(0,line);lcdprintPGM(" Fan speed:");
  490. lcd.setCursor(13,line);lcd.print(ftostr3(fanpwm));
  491. }
  492. if((activeline==line) )
  493. {
  494. if(CLICKED) //nalogWrite(FAN_PIN, fanpwm);
  495. {
  496. linechanging=!linechanging;
  497. if(linechanging)
  498. {
  499. encoderpos=fanpwm;
  500. }
  501. else
  502. {
  503. fanpwm = constrain(encoderpos,0,255);
  504. encoderpos=fanpwm;
  505. analogWrite(FAN_PIN, fanpwm);
  506. beepshort();
  507. }
  508. BLOCK;
  509. }
  510. if(linechanging)
  511. {
  512. if(encoderpos<0) encoderpos=0;
  513. if(encoderpos>255) encoderpos=255;
  514. fanpwm=encoderpos;
  515. analogWrite(FAN_PIN, fanpwm);
  516. lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));
  517. }
  518. }
  519. }break;
  520. case ItemCT_PID_P:
  521. {
  522. if(force_lcd_update)
  523. {
  524. lcd.setCursor(0,line);lcdprintPGM(" PID-P: ");
  525. lcd.setCursor(13,line);lcd.print(itostr4(Kp));
  526. }
  527. if((activeline==line) )
  528. {
  529. if(CLICKED)
  530. {
  531. linechanging=!linechanging;
  532. if(linechanging)
  533. {
  534. encoderpos=(int)Kp/5;
  535. }
  536. else
  537. {
  538. Kp= encoderpos*5;
  539. encoderpos=activeline*lcdslow;
  540. }
  541. BLOCK;
  542. beepshort();
  543. }
  544. if(linechanging)
  545. {
  546. if(encoderpos<1) encoderpos=1;
  547. if(encoderpos>9990/5) encoderpos=9990/5;
  548. lcd.setCursor(13,line);lcd.print(itostr4(encoderpos*5));
  549. }
  550. }
  551. }break;
  552. case ItemCT_PID_I:
  553. {
  554. if(force_lcd_update)
  555. {
  556. lcd.setCursor(0,line);lcdprintPGM(" PID-I: ");
  557. lcd.setCursor(13,line);lcd.print(ftostr51(Ki));
  558. }
  559. if((activeline==line) )
  560. {
  561. if(CLICKED)
  562. {
  563. linechanging=!linechanging;
  564. if(linechanging)
  565. {
  566. encoderpos=(int)(Ki*10);
  567. }
  568. else
  569. {
  570. Ki= encoderpos/10.;
  571. encoderpos=activeline*lcdslow;
  572. }
  573. BLOCK;
  574. beepshort();
  575. }
  576. if(linechanging)
  577. {
  578. if(encoderpos<0) encoderpos=0;
  579. if(encoderpos>9990) encoderpos=9990;
  580. lcd.setCursor(13,line);lcd.print(ftostr51(encoderpos/10.));
  581. }
  582. }
  583. }break;
  584. case ItemCT_PID_D:
  585. {
  586. if(force_lcd_update)
  587. {
  588. lcd.setCursor(0,line);lcdprintPGM(" PID-D: ");
  589. lcd.setCursor(13,line);lcd.print(itostr4(Kd));
  590. }
  591. if((activeline==line) )
  592. {
  593. if(CLICKED)
  594. {
  595. linechanging=!linechanging;
  596. if(linechanging)
  597. {
  598. encoderpos=(int)Kd/5;
  599. }
  600. else
  601. {
  602. Kd= encoderpos*5;
  603. encoderpos=activeline*lcdslow;
  604. }
  605. BLOCK;
  606. beepshort();
  607. }
  608. if(linechanging)
  609. {
  610. if(encoderpos<0) encoderpos=0;
  611. if(encoderpos>9990/5) encoderpos=9990/5;
  612. lcd.setCursor(13,line);lcd.print(itostr4(encoderpos*5));
  613. }
  614. }
  615. }break;
  616. case ItemCT_PID_C:
  617. #ifdef PID_ADD_EXTRUSION_RATE
  618. {
  619. if(force_lcd_update)
  620. {
  621. lcd.setCursor(0,line);lcdprintPGM(" PID-C: ");
  622. lcd.setCursor(13,line);lcd.print(itostr3(Kc));
  623. }
  624. if((activeline==line) )
  625. {
  626. if(CLICKED)
  627. {
  628. linechanging=!linechanging;
  629. if(linechanging)
  630. {
  631. encoderpos=(int)Kc;
  632. }
  633. else
  634. {
  635. Kc= encoderpos;
  636. encoderpos=activeline*lcdslow;
  637. }
  638. BLOCK;
  639. beepshort();
  640. }
  641. if(linechanging)
  642. {
  643. if(encoderpos<0) encoderpos=0;
  644. if(encoderpos>990) encoderpos=990;
  645. lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));
  646. }
  647. }
  648. }
  649. #endif
  650. break;
  651. default:
  652. break;
  653. }
  654. line++;
  655. }
  656. #ifdef PID_ADD_EXTRUSION_RATE
  657. updateActiveLines(ItemCT_PID_C,encoderpos);
  658. #else
  659. updateActiveLines(ItemCT_PID_D,encoderpos);
  660. #endif
  661. }
  662. enum {
  663. ItemCM_exit,
  664. ItemCM_acc, ItemCM_xyjerk,
  665. ItemCM_vmaxx, ItemCM_vmaxy, ItemCM_vmaxz, ItemCM_vmaxe,
  666. ItemCM_vtravmin,ItemCM_vmin,
  667. ItemCM_amaxx, ItemCM_amaxy, ItemCM_amaxz, ItemCM_amaxe,
  668. ItemCM_aret,ItemCM_esteps
  669. };
  670. void MainMenu::showControlMotion()
  671. {
  672. uint8_t line=0;
  673. clearIfNecessary();
  674. for(int8_t i=lineoffset;i<lineoffset+LCD_HEIGHT;i++)
  675. {
  676. switch(i)
  677. {
  678. case ItemCM_exit:
  679. MENUITEM( lcdprintPGM(" Motion") , BLOCK;status=Main_Control;beepshort(); ) ;
  680. break;
  681. case ItemCM_acc:
  682. {
  683. if(force_lcd_update)
  684. {
  685. lcd.setCursor(0,line);lcdprintPGM(" Acc:");
  686. lcd.setCursor(13,line);lcd.print(itostr3(acceleration/100));lcdprintPGM("00");
  687. }
  688. if((activeline==line) )
  689. {
  690. if(CLICKED)
  691. {
  692. linechanging=!linechanging;
  693. if(linechanging)
  694. {
  695. encoderpos=(int)acceleration/100;
  696. }
  697. else
  698. {
  699. acceleration= encoderpos*100;
  700. encoderpos=activeline*lcdslow;
  701. }
  702. BLOCK;
  703. beepshort();
  704. }
  705. if(linechanging)
  706. {
  707. if(encoderpos<5) encoderpos=5;
  708. if(encoderpos>990) encoderpos=990;
  709. lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));lcdprintPGM("00");
  710. }
  711. }
  712. }break;
  713. case ItemCM_xyjerk: //max_xy_jerk
  714. {
  715. if(force_lcd_update)
  716. {
  717. lcd.setCursor(0,line);lcdprintPGM(" Vxy-jerk: ");
  718. lcd.setCursor(13,line);lcd.print(itostr3(max_xy_jerk));
  719. }
  720. if((activeline==line) )
  721. {
  722. if(CLICKED)
  723. {
  724. linechanging=!linechanging;
  725. if(linechanging)
  726. {
  727. encoderpos=(int)max_xy_jerk;
  728. }
  729. else
  730. {
  731. max_xy_jerk= encoderpos;
  732. encoderpos=activeline*lcdslow;
  733. }
  734. BLOCK;
  735. beepshort();
  736. }
  737. if(linechanging)
  738. {
  739. if(encoderpos<1) encoderpos=1;
  740. if(encoderpos>990) encoderpos=990;
  741. lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));
  742. }
  743. }
  744. }break;
  745. case ItemCM_vmaxx:
  746. case ItemCM_vmaxy:
  747. case ItemCM_vmaxz:
  748. case ItemCM_vmaxe:
  749. {
  750. if(force_lcd_update)
  751. {
  752. lcd.setCursor(0,line);lcdprintPGM(" Vmax ");
  753. if(i==ItemCM_vmaxx)lcdprintPGM("x:");
  754. if(i==ItemCM_vmaxy)lcdprintPGM("y:");
  755. if(i==ItemCM_vmaxz)lcdprintPGM("z:");
  756. if(i==ItemCM_vmaxe)lcdprintPGM("e:");
  757. lcd.setCursor(13,line);lcd.print(itostr3(max_feedrate[i-ItemCM_vmaxx]));
  758. }
  759. if((activeline==line) )
  760. {
  761. if(CLICKED)
  762. {
  763. linechanging=!linechanging;
  764. if(linechanging)
  765. {
  766. encoderpos=(int)max_feedrate[i-ItemCM_vmaxx];
  767. }
  768. else
  769. {
  770. max_feedrate[i-ItemCM_vmaxx]= encoderpos;
  771. encoderpos=activeline*lcdslow;
  772. }
  773. BLOCK;
  774. beepshort();
  775. }
  776. if(linechanging)
  777. {
  778. if(encoderpos<1) encoderpos=1;
  779. if(encoderpos>990) encoderpos=990;
  780. lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));
  781. }
  782. }
  783. }break;
  784. case ItemCM_vmin:
  785. {
  786. if(force_lcd_update)
  787. {
  788. lcd.setCursor(0,line);lcdprintPGM(" Vmin:");
  789. lcd.setCursor(13,line);lcd.print(itostr3(minimumfeedrate));
  790. }
  791. if((activeline==line) )
  792. {
  793. if(CLICKED)
  794. {
  795. linechanging=!linechanging;
  796. if(linechanging)
  797. {
  798. encoderpos=(int)(minimumfeedrate);
  799. }
  800. else
  801. {
  802. minimumfeedrate= encoderpos;
  803. encoderpos=activeline*lcdslow;
  804. }
  805. BLOCK;
  806. beepshort();
  807. }
  808. if(linechanging)
  809. {
  810. if(encoderpos<0) encoderpos=0;
  811. if(encoderpos>990) encoderpos=990;
  812. lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));
  813. }
  814. }
  815. }break;
  816. case ItemCM_vtravmin:
  817. {
  818. if(force_lcd_update)
  819. {
  820. lcd.setCursor(0,line);lcdprintPGM(" VTrav min:");
  821. lcd.setCursor(13,line);lcd.print(itostr3(mintravelfeedrate));
  822. }
  823. if((activeline==line) )
  824. {
  825. if(CLICKED)
  826. {
  827. linechanging=!linechanging;
  828. if(linechanging)
  829. {
  830. encoderpos=(int)mintravelfeedrate;
  831. }
  832. else
  833. {
  834. mintravelfeedrate= encoderpos;
  835. encoderpos=activeline*lcdslow;
  836. }
  837. BLOCK;
  838. beepshort();
  839. }
  840. if(linechanging)
  841. {
  842. if(encoderpos<0) encoderpos=0;
  843. if(encoderpos>990) encoderpos=990;
  844. lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));
  845. }
  846. }
  847. }break;
  848. case ItemCM_amaxx:
  849. case ItemCM_amaxy:
  850. case ItemCM_amaxz:
  851. case ItemCM_amaxe:
  852. {
  853. if(force_lcd_update)
  854. {
  855. lcd.setCursor(0,line);lcdprintPGM(" Amax ");
  856. if(i==ItemCM_amaxx)lcdprintPGM("x:");
  857. if(i==ItemCM_amaxy)lcdprintPGM("y:");
  858. if(i==ItemCM_amaxz)lcdprintPGM("z:");
  859. if(i==ItemCM_amaxe)lcdprintPGM("e:");
  860. lcd.setCursor(13,line);lcd.print(itostr3(max_acceleration_units_per_sq_second[i-ItemCM_amaxx]/100));lcdprintPGM("00");
  861. }
  862. if((activeline==line) )
  863. {
  864. if(CLICKED)
  865. {
  866. linechanging=!linechanging;
  867. if(linechanging)
  868. {
  869. encoderpos=(int)max_acceleration_units_per_sq_second[i-ItemCM_amaxx]/100;
  870. }
  871. else
  872. {
  873. max_acceleration_units_per_sq_second[i-ItemCM_amaxx]= encoderpos*100;
  874. encoderpos=activeline*lcdslow;
  875. }
  876. BLOCK;
  877. beepshort();
  878. }
  879. if(linechanging)
  880. {
  881. if(encoderpos<1) encoderpos=1;
  882. if(encoderpos>990) encoderpos=990;
  883. lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));lcdprintPGM("00");
  884. }
  885. }
  886. }break;
  887. case ItemCM_aret://float retract_acceleration = 7000;
  888. {
  889. if(force_lcd_update)
  890. {
  891. lcd.setCursor(0,line);lcdprintPGM(" A-retract:");
  892. lcd.setCursor(13,line);lcd.print(ftostr3(retract_acceleration/100));lcdprintPGM("00");
  893. }
  894. if((activeline==line) )
  895. {
  896. if(CLICKED)
  897. {
  898. linechanging=!linechanging;
  899. if(linechanging)
  900. {
  901. encoderpos=(int)retract_acceleration/100;
  902. }
  903. else
  904. {
  905. retract_acceleration= encoderpos*100;
  906. encoderpos=activeline*lcdslow;
  907. }
  908. BLOCK;
  909. beepshort();
  910. }
  911. if(linechanging)
  912. {
  913. if(encoderpos<10) encoderpos=10;
  914. if(encoderpos>990) encoderpos=990;
  915. lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));lcdprintPGM("00");
  916. }
  917. }
  918. }break;
  919. case ItemCM_esteps://axis_steps_per_unit[i] = code_value();
  920. {
  921. if(force_lcd_update)
  922. {
  923. lcd.setCursor(0,line);lcdprintPGM(" Esteps/mm:");
  924. lcd.setCursor(13,line);lcd.print(itostr4(axis_steps_per_unit[3]));
  925. }
  926. if((activeline==line) )
  927. {
  928. if(CLICKED)
  929. {
  930. linechanging=!linechanging;
  931. if(linechanging)
  932. {
  933. encoderpos=(int)axis_steps_per_unit[3];
  934. }
  935. else
  936. {
  937. float factor=float(encoderpos)/float(axis_steps_per_unit[3]);
  938. position[E_AXIS]=lround(position[E_AXIS]*factor);
  939. //current_position[3]*=factor;
  940. axis_steps_per_unit[E_AXIS]= encoderpos;
  941. encoderpos=activeline*lcdslow;
  942. }
  943. BLOCK;
  944. beepshort();
  945. }
  946. if(linechanging)
  947. {
  948. if(encoderpos<5) encoderpos=5;
  949. if(encoderpos>9999) encoderpos=9999;
  950. lcd.setCursor(13,line);lcd.print(itostr4(encoderpos));
  951. }
  952. }
  953. }break;
  954. default:
  955. break;
  956. }
  957. line++;
  958. }
  959. updateActiveLines(ItemCM_esteps,encoderpos);
  960. }
  961. enum {
  962. ItemC_exit,ItemC_temp,ItemC_move,
  963. ItemC_store, ItemC_load,ItemC_failsafe
  964. };
  965. void MainMenu::showControl()
  966. {
  967. uint8_t line=0;
  968. clearIfNecessary();
  969. for(int8_t i=lineoffset;i<lineoffset+LCD_HEIGHT;i++)
  970. {
  971. switch(i)
  972. {
  973. case ItemC_exit:
  974. MENUITEM( lcdprintPGM(" Control \x7E") , BLOCK;status=Main_Menu;beepshort(); ) ;
  975. break;
  976. case ItemC_temp:
  977. MENUITEM( lcdprintPGM(" Temperature \x7E") , BLOCK;status=Sub_TempControl;beepshort(); ) ;
  978. break;
  979. case ItemC_move:
  980. MENUITEM( lcdprintPGM(" Motion \x7E") , BLOCK;status=Sub_MotionControl;beepshort(); ) ;
  981. break;
  982. case ItemC_store:
  983. {
  984. if(force_lcd_update)
  985. {
  986. lcd.setCursor(0,line);lcdprintPGM(" Store EPROM");
  987. }
  988. if((activeline==line) && CLICKED)
  989. {
  990. //enquecommand("M84");
  991. beepshort();
  992. BLOCK;
  993. StoreSettings();
  994. }
  995. }break;
  996. case ItemC_load:
  997. {
  998. if(force_lcd_update)
  999. {
  1000. lcd.setCursor(0,line);lcdprintPGM(" Load EPROM");
  1001. }
  1002. if((activeline==line) && CLICKED)
  1003. {
  1004. //enquecommand("M84");
  1005. beepshort();
  1006. BLOCK;
  1007. RetrieveSettings();
  1008. }
  1009. }break;
  1010. case ItemC_failsafe:
  1011. {
  1012. if(force_lcd_update)
  1013. {
  1014. lcd.setCursor(0,line);lcdprintPGM(" Restore Failsafe");
  1015. }
  1016. if((activeline==line) && CLICKED)
  1017. {
  1018. //enquecommand("M84");
  1019. beepshort();
  1020. BLOCK;
  1021. RetrieveSettings(true);
  1022. }
  1023. }break;
  1024. default:
  1025. break;
  1026. }
  1027. line++;
  1028. }
  1029. updateActiveLines(ItemC_failsafe,encoderpos);
  1030. }
  1031. void MainMenu::showSD()
  1032. {
  1033. #ifdef SDSUPPORT
  1034. uint8_t line=0;
  1035. clearIfNecessary();
  1036. static uint8_t nrfiles=0;
  1037. if(force_lcd_update)
  1038. {
  1039. if(card.cardOK)
  1040. {
  1041. nrfiles=card.getnrfilenames();
  1042. }
  1043. else
  1044. {
  1045. nrfiles=0;
  1046. lineoffset=0;
  1047. }
  1048. }
  1049. bool enforceupdate=false;
  1050. for(int8_t i=lineoffset;i<lineoffset+LCD_HEIGHT;i++)
  1051. {
  1052. switch(i)
  1053. {
  1054. case 0:
  1055. MENUITEM( lcdprintPGM(" File") , BLOCK;status=Main_Menu;beepshort(); ) ;
  1056. break;
  1057. // case 1:
  1058. // {
  1059. // if(force_lcd_update)
  1060. // {
  1061. // lcd.setCursor(0,line);
  1062. // #ifdef CARDINSERTED
  1063. // if(CARDINSERTED)
  1064. // #else
  1065. // if(true)
  1066. // #endif
  1067. // {
  1068. // lcdprintPGM(" \004Refresh");
  1069. // }
  1070. // else
  1071. // {
  1072. // lcdprintPGM(" \004Insert Card");
  1073. // }
  1074. //
  1075. // }
  1076. // if((activeline==line) && CLICKED)
  1077. // {
  1078. // BLOCK;
  1079. // beepshort();
  1080. // card.initsd();
  1081. // force_lcd_update=true;
  1082. // nrfiles=card.getnrfilenames();
  1083. // }
  1084. // }break;
  1085. case 1:
  1086. MENUITEM( lcdprintPGM(" ..") , BLOCK;card.updir();enforceupdate=true;lineoffset=0;beepshort(); ) ;
  1087. break;
  1088. default:
  1089. {
  1090. #define FIRSTITEM 2
  1091. if(i-FIRSTITEM<nrfiles)
  1092. {
  1093. if(force_lcd_update)
  1094. {
  1095. card.getfilename(i-FIRSTITEM);
  1096. //Serial.print("Filenr:");Serial.println(i-2);
  1097. lcd.setCursor(0,line);lcdprintPGM(" ");
  1098. if(card.filenameIsDir) lcd.print("\005");
  1099. lcd.print(card.filename);
  1100. }
  1101. if((activeline==line) && CLICKED)
  1102. {
  1103. BLOCK
  1104. card.getfilename(i-FIRSTITEM);
  1105. if(card.filenameIsDir)
  1106. {
  1107. for(int8_t i=0;i<strlen(card.filename);i++)
  1108. card.filename[i]=tolower(card.filename[i]);
  1109. card.chdir(card.filename);
  1110. lineoffset=0;
  1111. enforceupdate=true;
  1112. }
  1113. else
  1114. {
  1115. char cmd[30];
  1116. for(int8_t i=0;i<strlen(card.filename);i++)
  1117. card.filename[i]=tolower(card.filename[i]);
  1118. sprintf(cmd,"M23 %s",card.filename);
  1119. //sprintf(cmd,"M115");
  1120. enquecommand(cmd);
  1121. enquecommand("M24");
  1122. beep();
  1123. status=Main_Status;
  1124. lcd_status(card.filename);
  1125. }
  1126. }
  1127. }
  1128. }
  1129. break;
  1130. }
  1131. line++;
  1132. }
  1133. updateActiveLines(FIRSTITEM+nrfiles-1,encoderpos);
  1134. if(enforceupdate)
  1135. {
  1136. force_lcd_update=true;
  1137. enforceupdate=false;
  1138. }
  1139. #endif
  1140. }
  1141. enum {ItemM_watch, ItemM_prepare, ItemM_control, ItemM_file };
  1142. void MainMenu::showMainMenu()
  1143. {
  1144. #ifndef ULTIPANEL
  1145. force_lcd_update=false;
  1146. #endif
  1147. clearIfNecessary();
  1148. for(int8_t line=0;line<LCD_HEIGHT;line++)
  1149. {
  1150. switch(line)
  1151. {
  1152. case ItemM_watch:
  1153. MENUITEM( lcdprintPGM(" Watch") , BLOCK;status=Main_Status;beepshort(); ) ;
  1154. break;
  1155. case ItemM_prepare:
  1156. MENUITEM( lcdprintPGM(" Prepare \x7E") , BLOCK;status=Main_Prepare;beepshort(); ) ;
  1157. break;
  1158. case ItemM_control:
  1159. MENUITEM( lcdprintPGM(" Control \x7E") , BLOCK;status=Main_Control;beepshort(); ) ;
  1160. break;
  1161. #ifdef SDSUPPORT
  1162. case ItemM_file:
  1163. {
  1164. if(force_lcd_update)
  1165. {
  1166. lcd.setCursor(0,line);
  1167. #ifdef CARDINSERTED
  1168. if(CARDINSERTED)
  1169. #else
  1170. if(true)
  1171. #endif
  1172. {
  1173. if(card.sdprinting)
  1174. lcdprintPGM(" Stop Print \x7E");
  1175. else
  1176. lcdprintPGM(" Card Menu \x7E");
  1177. }
  1178. else
  1179. {
  1180. lcdprintPGM(" No Card");
  1181. }
  1182. }
  1183. #ifdef CARDINSERTED
  1184. if(CARDINSERTED)
  1185. #endif
  1186. if((activeline==line)&&CLICKED)
  1187. {
  1188. card.sdprinting = false;
  1189. BLOCK;
  1190. status=Main_SD;
  1191. beepshort();
  1192. }
  1193. }break;
  1194. #else
  1195. case ItemM_file:
  1196. break;
  1197. #endif
  1198. default:
  1199. SERIAL_ERROR_START;
  1200. SERIAL_ERRORLNPGM("Something is wrong in the MenuStructure.");
  1201. break;
  1202. }
  1203. }
  1204. updateActiveLines(3,encoderpos);
  1205. }
  1206. void MainMenu::update()
  1207. {
  1208. static MainStatus oldstatus=Main_Menu; //init automatically causes foce_lcd_update=true
  1209. static long timeoutToStatus=0;
  1210. static bool oldcardstatus=false;
  1211. #ifdef CARDINSERTED
  1212. if((CARDINSERTED != oldcardstatus))
  1213. {
  1214. force_lcd_update=true;
  1215. oldcardstatus=CARDINSERTED;
  1216. //Serial.println("echo: SD CHANGE");
  1217. if(CARDINSERTED)
  1218. {
  1219. card.initsd();
  1220. LCD_MESSAGEPGM("Card inserted");
  1221. }
  1222. else
  1223. {
  1224. card.release();
  1225. LCD_MESSAGEPGM("Card removed");
  1226. }
  1227. }
  1228. #endif
  1229. if(status!=oldstatus)
  1230. {
  1231. force_lcd_update=true;
  1232. encoderpos=0;
  1233. lineoffset=0;
  1234. oldstatus=status;
  1235. }
  1236. if( (encoderpos!=lastencoderpos) || CLICKED)
  1237. timeoutToStatus=millis()+STATUSTIMEOUT;
  1238. switch(status)
  1239. {
  1240. case Main_Status:
  1241. {
  1242. showStatus();
  1243. if(CLICKED)
  1244. {
  1245. linechanging=false;
  1246. BLOCK
  1247. status=Main_Menu;
  1248. timeoutToStatus=millis()+STATUSTIMEOUT;
  1249. }
  1250. }break;
  1251. case Main_Menu:
  1252. {
  1253. showMainMenu();
  1254. linechanging=false;
  1255. }break;
  1256. case Main_Prepare:
  1257. {
  1258. showPrepare();
  1259. }break;
  1260. case Main_Control:
  1261. {
  1262. showControl();
  1263. }break;
  1264. case Sub_MotionControl:
  1265. {
  1266. showControlMotion();
  1267. }break;
  1268. case Sub_TempControl:
  1269. {
  1270. showControlTemp();
  1271. }break;
  1272. case Main_SD:
  1273. {
  1274. showSD();
  1275. }break;
  1276. }
  1277. if(timeoutToStatus<millis())
  1278. status=Main_Status;
  1279. //force_lcd_update=false;
  1280. lastencoderpos=encoderpos;
  1281. }
  1282. // convert float to string with +123.4 format
  1283. char *ftostr3(const float &x)
  1284. {
  1285. //sprintf(conv,"%5.1f",x);
  1286. int xx=x;
  1287. conv[0]=(xx/100)%10+'0';
  1288. conv[1]=(xx/10)%10+'0';
  1289. conv[2]=(xx)%10+'0';
  1290. conv[3]=0;
  1291. return conv;
  1292. }
  1293. char *itostr2(const uint8_t &x)
  1294. {
  1295. //sprintf(conv,"%5.1f",x);
  1296. int xx=x;
  1297. conv[0]=(xx/10)%10+'0';
  1298. conv[1]=(xx)%10+'0';
  1299. conv[2]=0;
  1300. return conv;
  1301. }
  1302. // convert float to string with +123.4 format
  1303. char *ftostr31(const float &x)
  1304. {
  1305. int xx=x*10;
  1306. conv[0]=(xx>=0)?'+':'-';
  1307. xx=abs(xx);
  1308. conv[1]=(xx/1000)%10+'0';
  1309. conv[2]=(xx/100)%10+'0';
  1310. conv[3]=(xx/10)%10+'0';
  1311. conv[4]='.';
  1312. conv[5]=(xx)%10+'0';
  1313. conv[6]=0;
  1314. return conv;
  1315. }
  1316. char *itostr31(const int &xx)
  1317. {
  1318. conv[0]=(xx>=0)?'+':'-';
  1319. conv[1]=(xx/1000)%10+'0';
  1320. conv[2]=(xx/100)%10+'0';
  1321. conv[3]=(xx/10)%10+'0';
  1322. conv[4]='.';
  1323. conv[5]=(xx)%10+'0';
  1324. conv[6]=0;
  1325. return conv;
  1326. }
  1327. char *itostr3(const int &xx)
  1328. {
  1329. conv[0]=(xx/100)%10+'0';
  1330. conv[1]=(xx/10)%10+'0';
  1331. conv[2]=(xx)%10+'0';
  1332. conv[3]=0;
  1333. return conv;
  1334. }
  1335. char *itostr4(const int &xx)
  1336. {
  1337. conv[0]=(xx/1000)%10+'0';
  1338. conv[1]=(xx/100)%10+'0';
  1339. conv[2]=(xx/10)%10+'0';
  1340. conv[3]=(xx)%10+'0';
  1341. conv[4]=0;
  1342. return conv;
  1343. }
  1344. // convert float to string with +1234.5 format
  1345. char *ftostr51(const float &x)
  1346. {
  1347. int xx=x*10;
  1348. conv[0]=(xx>=0)?'+':'-';
  1349. xx=abs(xx);
  1350. conv[1]=(xx/10000)%10+'0';
  1351. conv[2]=(xx/1000)%10+'0';
  1352. conv[3]=(xx/100)%10+'0';
  1353. conv[4]=(xx/10)%10+'0';
  1354. conv[5]='.';
  1355. conv[6]=(xx)%10+'0';
  1356. conv[7]=0;
  1357. return conv;
  1358. }
  1359. char *fillto(int8_t n,char *c)
  1360. {
  1361. static char ret[25];
  1362. bool endfound=false;
  1363. for(int8_t i=0;i<n;i++)
  1364. {
  1365. ret[i]=c[i];
  1366. if(c[i]==0)
  1367. {
  1368. endfound=true;
  1369. }
  1370. if(endfound)
  1371. {
  1372. ret[i]=' ';
  1373. }
  1374. }
  1375. ret[n]=0;
  1376. return ret;
  1377. }
  1378. #endif //ULTRA_LCD