My Marlin configs for Fabrikator Mini and CTC i3 Pro B
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

ultralcd.pde 37KB

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