chiark / gitweb /
Fixed AD595 define
[marlin.git] / Marlin / ultralcd.pde
1 #include "language.h"
2 #include "temperature.h"
3 #include "ultralcd.h"
4 #ifdef ULTRA_LCD
5 #include "Marlin.h"
6 #include "language.h"
7 #include "temperature.h"
8 #include "EEPROMwrite.h"
9 #include <LiquidCrystal.h>
10 //===========================================================================
11 //=============================imported variables============================
12 //===========================================================================
13
14 extern volatile int feedmultiply;
15 extern volatile bool feedmultiplychanged;
16
17 extern volatile int extrudemultiply;
18
19 extern long position[4];   
20 #ifdef SDSUPPORT
21 #include "cardreader.h"
22 extern CardReader card;
23 #endif
24
25 //===========================================================================
26 //=============================public variables============================
27 //===========================================================================
28 volatile char buttons=0;  //the last checked buttons in a bit array.
29 long encoderpos=0;
30 short lastenc=0;
31
32
33 //===========================================================================
34 //=============================private  variables============================
35 //===========================================================================
36 static char messagetext[LCD_WIDTH]="";
37
38 //return for string conversion routines
39 static char conv[8];
40
41 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 
42
43 static unsigned long previous_millis_lcd=0;
44 //static long previous_millis_buttons=0;
45
46
47 #ifdef NEWPANEL
48  static long blocking=0;
49 #else
50  static long blocking[8]={0,0,0,0,0,0,0,0};
51 #endif
52  
53 static MainMenu menu;
54
55
56 void lcdProgMemprint(const char *str)
57 {
58   char ch=pgm_read_byte(str);
59   while(ch)
60   {
61     lcd.print(ch);
62     ch=pgm_read_byte(++str);
63   }
64 }
65 #define lcdprintPGM(x) lcdProgMemprint(MYPGM(x))
66
67
68 //===========================================================================
69 //=============================functions         ============================
70 //===========================================================================
71
72 int intround(const float &x){return int(0.5+x);}
73
74 void lcd_status(const char* message)
75 {
76   strncpy(messagetext,message,LCD_WIDTH);
77   messagetext[strlen(message)]=0;
78 }
79
80 void lcd_statuspgm(const char* message)
81 {
82   char ch=pgm_read_byte(message);
83   char *target=messagetext;
84   uint8_t cnt=0;
85   while(ch &&cnt<LCD_WIDTH)
86   {
87     *target=ch;
88     target++;
89     cnt++;
90     ch=pgm_read_byte(++message);
91   }
92   *target=0;
93 }
94
95 FORCE_INLINE void clear()
96 {
97   lcd.clear();
98 }
99
100
101 void lcd_init()
102 {
103   //beep();
104   #ifdef ULTIPANEL
105     buttons_init();
106   #endif
107   
108   byte Degree[8] =
109   {
110     B01100,
111     B10010,
112     B10010,
113     B01100,
114     B00000,
115     B00000,
116     B00000,
117     B00000
118   };
119   byte Thermometer[8] =
120   {
121     B00100,
122     B01010,
123     B01010,
124     B01010,
125     B01010,
126     B10001,
127     B10001,
128     B01110
129   };
130   byte uplevel[8]={0x04, 0x0e, 0x1f, 0x04, 0x1c, 0x00, 0x00, 0x00};//thanks joris
131   byte refresh[8]={0x00, 0x06, 0x19, 0x18, 0x03, 0x13, 0x0c, 0x00}; //thanks joris
132   byte folder [8]={0x00, 0x1c, 0x1f, 0x11, 0x11, 0x1f, 0x00, 0x00}; //thanks joris
133   lcd.begin(LCD_WIDTH, LCD_HEIGHT);
134   lcd.createChar(1,Degree);
135   lcd.createChar(2,Thermometer);
136   lcd.createChar(3,uplevel);
137   lcd.createChar(4,refresh);
138   lcd.createChar(5,folder);
139   LCD_MESSAGEPGM(WELCOME_MSG);
140 }
141
142
143 void beep()
144 {
145   //return;
146   #ifdef ULTIPANEL
147         #if (BEEPER > -1)
148         {
149                 pinMode(BEEPER,OUTPUT);
150                 for(int8_t i=0;i<20;i++){
151                 WRITE(BEEPER,HIGH);
152                 delay(5);
153                 WRITE(BEEPER,LOW);
154                 delay(5);
155                 }
156         }
157         #endif
158   #endif
159 }
160
161 void beepshort()
162 {
163   //return;
164   #ifdef ULTIPANEL
165         #if (BEEPER > -1)
166         {
167                 pinMode(BEEPER,OUTPUT);
168                 for(int8_t i=0;i<10;i++){
169                 WRITE(BEEPER,HIGH);
170                 delay(3);
171                 WRITE(BEEPER,LOW);
172                 delay(3);
173                 }
174         }
175         #endif
176   #endif  
177 }
178
179 void lcd_status()
180 {
181   #ifdef ULTIPANEL
182     static uint8_t oldbuttons=0;
183     //static long previous_millis_buttons=0;
184     //static long previous_lcdinit=0;
185   //  buttons_check(); // Done in temperature interrupt
186     //previous_millis_buttons=millis();
187     long ms=millis();
188     for(int8_t i=0; i<8; i++) {
189       #ifndef NEWPANEL
190       if((blocking[i]>ms))
191         buttons &= ~(1<<i);
192       #else
193       if((blocking>ms))
194         buttons &= ~(1<<i);        
195       #endif
196     }
197     if((buttons==oldbuttons) &&  ((millis() - previous_millis_lcd) < LCD_UPDATE_INTERVAL)   )
198       return;
199     oldbuttons=buttons;
200   #else
201   
202     if(((millis() - previous_millis_lcd) < LCD_UPDATE_INTERVAL)   )
203       return;
204   #endif
205     
206   previous_millis_lcd=millis();
207   menu.update();
208 }
209 #ifdef ULTIPANEL  
210
211
212 void buttons_init()
213 {
214   #ifdef NEWPANEL
215     pinMode(BTN_EN1,INPUT);
216     pinMode(BTN_EN2,INPUT); 
217     pinMode(BTN_ENC,INPUT); 
218     pinMode(SDCARDDETECT,INPUT);
219     WRITE(BTN_EN1,HIGH);
220     WRITE(BTN_EN2,HIGH);
221     WRITE(BTN_ENC,HIGH);
222     #if (SDCARDDETECT > -1)
223     {
224       WRITE(SDCARDDETECT,HIGH);
225     }
226     #endif
227   #else
228     pinMode(SHIFT_CLK,OUTPUT);
229     pinMode(SHIFT_LD,OUTPUT);
230     pinMode(SHIFT_EN,OUTPUT);
231     pinMode(SHIFT_OUT,INPUT);
232     WRITE(SHIFT_OUT,HIGH);
233     WRITE(SHIFT_LD,HIGH); 
234     WRITE(SHIFT_EN,LOW); 
235   #endif
236 }
237
238
239 void buttons_check()
240 {
241   
242   #ifdef NEWPANEL
243     uint8_t newbutton=0;
244     if(READ(BTN_EN1)==0)  newbutton|=EN_A;
245     if(READ(BTN_EN2)==0)  newbutton|=EN_B;
246     if((blocking<millis()) &&(READ(BTN_ENC)==0))
247       newbutton|=EN_C;
248     buttons=newbutton;
249   #else   //read it from the shift register
250     uint8_t newbutton=0;
251     WRITE(SHIFT_LD,LOW);
252     WRITE(SHIFT_LD,HIGH);
253     unsigned char tmp_buttons=0;
254     for(int8_t i=0;i<8;i++)
255     { 
256       newbutton = newbutton>>1;
257       if(READ(SHIFT_OUT))
258         newbutton|=(1<<7);
259       WRITE(SHIFT_CLK,HIGH);
260       WRITE(SHIFT_CLK,LOW);
261     }
262     buttons=~newbutton; //invert it, because a pressed switch produces a logical 0
263   #endif
264   
265   //manage encoder rotation
266   char enc=0;
267   if(buttons&EN_A)
268     enc|=(1<<0);
269   if(buttons&EN_B)
270     enc|=(1<<1);
271   if(enc!=lastenc)
272         {
273     switch(enc)
274     {
275     case encrot0:
276       if(lastenc==encrot3)
277         encoderpos++;
278       else if(lastenc==encrot1)
279         encoderpos--;
280       break;
281     case encrot1:
282       if(lastenc==encrot0)
283         encoderpos++;
284       else if(lastenc==encrot2)
285         encoderpos--;
286       break;
287     case encrot2:
288       if(lastenc==encrot1)
289         encoderpos++;
290       else if(lastenc==encrot3)
291         encoderpos--;
292       break;
293     case encrot3:
294       if(lastenc==encrot2)
295         encoderpos++;
296       else if(lastenc==encrot0)
297         encoderpos--;
298       break;
299     default:
300       ;
301     }
302   }
303   lastenc=enc;
304 }
305
306 #endif
307
308 MainMenu::MainMenu()
309 {
310   status=Main_Status;
311   displayStartingRow=0;
312   activeline=0;
313   force_lcd_update=true;
314   linechanging=false;
315   tune=false;
316 }
317
318 void MainMenu::showStatus()
319
320 #if LCD_HEIGHT==4
321   static int olddegHotEnd0=-1;
322   static int oldtargetHotEnd0=-1;
323   //force_lcd_update=true;
324   if(force_lcd_update)  //initial display of content
325   {
326     encoderpos=feedmultiply;
327     clear();
328     lcd.setCursor(0,0);lcdprintPGM("\002---/---\001 ");
329     #if defined BED_USES_THERMISTOR || defined BED_USES_AD595 
330       lcd.setCursor(10,0);lcdprintPGM("B---/---\001 ");
331     #elif EXTRUDERS > 1
332       lcd.setCursor(10,0);lcdprintPGM("\002---/---\001 ");
333     #endif
334   }
335     
336   int tHotEnd0=intround(degHotend0());
337   if((tHotEnd0!=olddegHotEnd0)||force_lcd_update)
338   {
339     lcd.setCursor(1,0);
340     lcd.print(ftostr3(tHotEnd0));
341     olddegHotEnd0=tHotEnd0;
342   }
343   int ttHotEnd0=intround(degTargetHotend0());
344   if((ttHotEnd0!=oldtargetHotEnd0)||force_lcd_update)
345   {
346     lcd.setCursor(5,0);
347     lcd.print(ftostr3(ttHotEnd0));
348     oldtargetHotEnd0=ttHotEnd0;
349   }
350   #if defined BED_USES_THERMISTOR || defined BED_USES_AD595 
351     static int oldtBed=-1;
352     static int oldtargetBed=-1; 
353     int tBed=intround(degBed());
354     if((tBed!=oldtBed)||force_lcd_update)
355     {
356       lcd.setCursor(11,0);
357       lcd.print(ftostr3(tBed));
358       oldtBed=tBed;
359     }
360     int targetBed=intround(degTargetBed());
361     if((targetBed!=oldtargetBed)||force_lcd_update)
362     {
363       lcd.setCursor(15,0);
364       lcd.print(ftostr3(targetBed));
365       oldtargetBed=targetBed;
366     }
367   #elif EXTRUDERS > 1
368     static int olddegHotEnd1=-1;
369     static int oldtargetHotEnd1=-1;
370     int tHotEnd1=intround(degHotend1());
371     if((tHotEnd1!=olddegHotEnd1)||force_lcd_update)
372     {
373       lcd.setCursor(11,0);
374       lcd.print(ftostr3(tHotEnd1));
375       olddegHotEnd1=tHotEnd1;
376     }
377     int ttHotEnd1=intround(degTargetHotend1());
378     if((ttHotEnd1!=oldtargetHotEnd1)||force_lcd_update)
379     {
380       lcd.setCursor(15,0);
381       lcd.print(ftostr3(ttHotEnd1));
382       oldtargetHotEnd1=ttHotEnd1;
383     }
384   #endif
385   //starttime=2;
386   static uint16_t oldtime=0;
387   if(starttime!=0)
388   {
389     lcd.setCursor(0,1);
390     uint16_t time=millis()/60000-starttime/60000;
391     
392     if(starttime!=oldtime)
393     {
394       lcd.print(itostr2(time/60));lcdprintPGM("h ");lcd.print(itostr2(time%60));lcdprintPGM("m");
395       oldtime=time;
396     }
397   }
398   static int oldzpos=0;
399   int currentz=current_position[2]*100;
400   if((currentz!=oldzpos)||force_lcd_update)
401   {
402     lcd.setCursor(10,1);
403     lcdprintPGM("Z:");lcd.print(ftostr52(current_position[2]));
404     oldzpos=currentz;
405   }
406   
407   static int oldfeedmultiply=0;
408   int curfeedmultiply=feedmultiply;
409   
410   if(feedmultiplychanged == true) {
411     feedmultiplychanged = false;
412     encoderpos = curfeedmultiply;
413   }
414   
415   if(encoderpos!=curfeedmultiply||force_lcd_update)
416   {
417    curfeedmultiply=encoderpos;
418    if(curfeedmultiply<10)
419      curfeedmultiply=10;
420    if(curfeedmultiply>999)
421      curfeedmultiply=999;
422    feedmultiply=curfeedmultiply;
423    encoderpos=curfeedmultiply;
424   }
425   
426   if((curfeedmultiply!=oldfeedmultiply)||force_lcd_update)
427   {
428    oldfeedmultiply=curfeedmultiply;
429    lcd.setCursor(0,2);
430    lcd.print(itostr3(curfeedmultiply));lcdprintPGM("% ");
431   }
432   
433   if(messagetext[0]!='\0')
434   {
435     lcd.setCursor(0,LCD_HEIGHT-1);
436     lcd.print(messagetext);
437     uint8_t n=strlen(messagetext);
438     for(int8_t i=0;i<LCD_WIDTH-n;i++)
439       lcd.print(" ");
440     messagetext[0]='\0';
441   }
442 #ifdef SDSUPPORT
443   static uint8_t oldpercent=101;
444   uint8_t percent=card.percentDone();
445   if(oldpercent!=percent ||force_lcd_update)
446   {
447      lcd.setCursor(10,2);
448     lcd.print(itostr3((int)percent));
449     lcdprintPGM("%SD");
450   }
451 #endif
452 #else //smaller LCDS----------------------------------
453   static int olddegHotEnd0=-1;
454   static int oldtargetHotEnd0=-1;
455   if(force_lcd_update)  //initial display of content
456   {
457     encoderpos=feedmultiply;
458     lcd.setCursor(0,0);lcdprintPGM("\002---/---\001 ");
459   }
460     
461   int tHotEnd0=intround(degHotend0());
462   int ttHotEnd0=intround(degTargetHotend0());
463
464
465   if((abs(tHotEnd0-olddegHotEnd0)>1)||force_lcd_update)
466   {
467     lcd.setCursor(1,0);
468     lcd.print(ftostr3(tHotEnd0));
469     olddegHotEnd0=tHotEnd0;
470   }
471   if((ttHotEnd0!=oldtargetHotEnd0)||force_lcd_update)
472   {
473     lcd.setCursor(5,0);
474     lcd.print(ftostr3(ttHotEnd0));
475     oldtargetHotEnd0=ttHotEnd0;
476   }
477
478   if(messagetext[0]!='\0')
479   {
480     lcd.setCursor(0,LCD_HEIGHT-1);
481     lcd.print(messagetext);
482     uint8_t n=strlen(messagetext);
483     for(int8_t i=0;i<LCD_WIDTH-n;i++)
484       lcd.print(" ");
485     messagetext[0]='\0';
486   }
487
488 #endif
489   force_lcd_update=false;
490 }
491
492 enum {ItemP_exit, ItemP_autostart,ItemP_disstep,ItemP_home, ItemP_origin, ItemP_preheat_pla, ItemP_preheat_abs, ItemP_cooldown,/*ItemP_extrude,*/ItemP_move};
493
494 //any action must not contain a ',' character anywhere, or this breaks:
495 #define MENUITEM(repaint_action, click_action) \
496   {\
497     if(force_lcd_update)  { lcd.setCursor(0,line);  repaint_action; } \
498     if((activeline==line) && CLICKED) {click_action} \
499   }
500   
501 void MainMenu::showPrepare()
502 {
503 #ifdef ULTIPANEL
504  uint8_t line=0;
505  clearIfNecessary();
506  for(int8_t i=lineoffset;i<lineoffset+LCD_HEIGHT;i++)
507  {
508    //Serial.println((int)(line-lineoffset));
509   switch(i)
510   {
511     case ItemP_exit:
512       MENUITEM(  lcdprintPGM(MSG_MAIN)  ,  BLOCK;status=Main_Menu;beepshort(); ) ;
513       break;
514     case ItemP_autostart:
515       MENUITEM(  lcdprintPGM(MSG_AUTOSTART)  ,  BLOCK;
516 #ifdef SDSUPPORT
517           card.lastnr=0;card.setroot();card.checkautostart(true);
518 #endif
519           beepshort(); ) ;
520       break;
521     case ItemP_disstep:
522       MENUITEM(  lcdprintPGM(MSG_DISABLE_STEPPERS)  ,  BLOCK;enquecommand("M84");beepshort(); ) ;
523       break;
524     case ItemP_home:
525       MENUITEM(  lcdprintPGM(MSG_AUTO_HOME)  ,  BLOCK;enquecommand("G28");beepshort(); ) ;
526       break;
527     case ItemP_origin:
528       MENUITEM(  lcdprintPGM(MSG_SET_ORIGIN)  ,  BLOCK;enquecommand("G92 X0 Y0 Z0");beepshort(); ) ;
529       break;
530     case ItemP_preheat_pla:
531       MENUITEM(  lcdprintPGM(MSG_PREHEAT_PLA)  ,  BLOCK;setTargetHotend0(PLA_PREHEAT_HOTEND_TEMP);setTargetBed(PLA_PREHEAT_HPB_TEMP);
532       #if FAN_PIN > -1
533         analogWrite(FAN_PIN, PLA_PREHEAT_FAN_SPEED);
534       #endif
535       beepshort(); );
536       break;
537     case ItemP_preheat_abs:
538       MENUITEM(  lcdprintPGM(MSG_PREHEAT_ABS)  ,  BLOCK;setTargetHotend0(ABS_PREHEAT_HOTEND_TEMP);setTargetBed(ABS_PREHEAT_HPB_TEMP); 
539       #if FAN_PIN > -1
540         analogWrite(FAN_PIN, ABS_PREHEAT_FAN_SPEED);
541       #endif
542       beepshort(); );
543       break;
544     case ItemP_cooldown:
545       MENUITEM(  lcdprintPGM(MSG_COOLDOWN)  ,  BLOCK;setTargetHotend0(0);setTargetHotend1(0);setTargetHotend2(0);setTargetBed(0);beepshort(); ) ;
546       break;
547 //    case ItemP_extrude:
548   //    MENUITEM(  lcdprintPGM(" Extrude")  ,  BLOCK;enquecommand("G92 E0");enquecommand("G1 F700 E50");beepshort(); ) ;
549     //  break;
550     case ItemP_move:
551       MENUITEM(  lcdprintPGM(MSG_MOVE_AXIS) , BLOCK;status=Sub_PrepareMove;beepshort(); );
552       break;
553         default:   
554       break;
555   }
556   line++;
557  }
558  updateActiveLines(ItemP_move,encoderpos);
559 #endif
560 }
561
562 enum {
563   ItemAM_exit,
564   ItemAM_X, ItemAM_Y, ItemAM_Z, ItemAM_E
565 };
566
567 void MainMenu::showAxisMove()
568 {
569    uint8_t line=0;
570    int oldencoderpos=0;
571    clearIfNecessary();
572    for(int8_t i=lineoffset;i<lineoffset+LCD_HEIGHT;i++)
573    {
574      switch(i)
575       {
576           case ItemAM_exit:
577           MENUITEM(  lcdprintPGM(MSG_PREPARE_ALT)  ,  BLOCK;status=Main_Menu;beepshort(); ) ;
578           break;
579           case ItemAM_X:
580           {
581                   //oldencoderpos=0;
582                   if(force_lcd_update)
583                   {
584                     lcd.setCursor(0,line);lcdprintPGM(" X:");
585                     lcd.setCursor(11,line);lcd.print(ftostr52(current_position[X_AXIS]));
586                   }
587       
588                   if((activeline!=line) )
589                   break;
590                   
591                   if(CLICKED) 
592                   {
593                     linechanging=!linechanging;
594                     if(linechanging)
595                     {
596                         enquecommand("G91");
597                     }
598                     else
599                     {
600                       enquecommand("G90");
601                       encoderpos=activeline*lcdslow;
602                       beepshort();
603                     }
604                     BLOCK;
605                   }
606                   if(linechanging)
607                   {
608                     if (encoderpos >0) 
609                    { 
610                         enquecommand("G1 F700 X0.1");
611                         oldencoderpos=encoderpos;
612                         encoderpos=0;
613                     }
614                   
615                     else if (encoderpos < 0)
616                     {
617                         enquecommand("G1 F700 X-0.1");
618                         oldencoderpos=encoderpos;
619                         encoderpos=0;
620                     }
621                     lcd.setCursor(11,line);lcd.print(ftostr52(current_position[X_AXIS]));
622                   }
623           }
624           break;
625           case ItemAM_Y:
626             {
627                   if(force_lcd_update)
628                   {
629                     lcd.setCursor(0,line);lcdprintPGM(" Y:");
630                     lcd.setCursor(11,line);lcd.print(ftostr52(current_position[Y_AXIS]));
631                   }
632       
633                   if((activeline!=line) )
634                   break;
635                   
636                   if(CLICKED) 
637                   {
638                     linechanging=!linechanging;
639                     if(linechanging)
640                     {
641                         enquecommand("G91");
642                     }
643                     else
644                     {
645                       enquecommand("G90");
646                       encoderpos=activeline*lcdslow;
647                       beepshort();
648                     }
649                     BLOCK;
650                   }
651                   if(linechanging)
652                   {
653                     if (encoderpos >0) 
654                    { 
655                         enquecommand("G1 F700 Y0.1");
656                         oldencoderpos=encoderpos;
657                         encoderpos=0;
658                     }
659                   
660                     else if (encoderpos < 0)
661                     {
662                         enquecommand("G1 F700 Y-0.1");
663                         oldencoderpos=encoderpos;
664                         encoderpos=0;
665                     }
666                     lcd.setCursor(11,line);lcd.print(ftostr52(current_position[Y_AXIS]));
667                   }
668           }
669           break;
670           case ItemAM_Z:
671           {
672                   if(force_lcd_update)
673                   {
674                     lcd.setCursor(0,line);lcdprintPGM(" Z:");
675                     lcd.setCursor(11,line);lcd.print(ftostr52(current_position[Z_AXIS]));
676                   }
677       
678                   if((activeline!=line) )
679                   break;
680                   
681                    if(CLICKED) 
682                   {
683                     linechanging=!linechanging;
684                     if(linechanging)
685                     {
686                         enquecommand("G91");
687                     }
688                     else
689                     {
690                       enquecommand("G90");
691                       encoderpos=activeline*lcdslow;
692                       beepshort();
693                     }
694                     BLOCK;
695                   }
696                   if(linechanging)
697                   {
698                     if (encoderpos >0) 
699                    { 
700                         enquecommand("G1 F70 Z0.1");
701                         oldencoderpos=encoderpos;
702                         encoderpos=0;
703                     }
704                   
705                     else if (encoderpos < 0)
706                     {
707                         enquecommand("G1 F70 Z-0.1");
708                         oldencoderpos=encoderpos;
709                         encoderpos=0;
710                     }
711                     lcd.setCursor(11,line);lcd.print(ftostr52(current_position[Z_AXIS]));
712                   }
713           }
714           break;
715           case ItemAM_E:
716           // ErikDB: TODO: this length should be changed for volumetric.
717           MENUITEM(  lcdprintPGM(MSG_EXTRUDE)  ,  BLOCK;enquecommand("G92 E0");enquecommand("G1 F700 E5");beepshort(); ) ;
718           break;
719           default:
720           break;
721       }
722       line++;
723    }
724    updateActiveLines(ItemAM_E,encoderpos);
725 }
726
727 enum {ItemT_exit,ItemT_speed,ItemT_flow,ItemT_nozzle,
728 #if (HEATER_BED_PIN > -1)
729 ItemT_bed,
730 #endif
731 ItemT_fan};
732
733 void MainMenu::showTune()
734
735   uint8_t line=0;
736   clearIfNecessary();
737  for(int8_t i=lineoffset;i<lineoffset+LCD_HEIGHT;i++)
738  {
739    //Serial.println((int)(line-lineoffset));
740   switch(i)
741   {
742   case ItemT_exit:
743       MENUITEM(  lcdprintPGM(MSG_MAIN)  ,  BLOCK;status=Main_Menu;beepshort(); ) ;
744       break;
745   case ItemT_speed:
746     {
747       if(force_lcd_update)
748       {
749         lcd.setCursor(0,line);lcdprintPGM(MSG_SPEED);
750         lcd.setCursor(13,line);lcd.print(ftostr3(feedmultiply));
751       }
752       
753       if((activeline!=line) )
754         break;
755       
756       if(CLICKED) //AnalogWrite(FAN_PIN,  fanpwm);
757       {
758         linechanging=!linechanging;
759         if(linechanging)
760         {
761             encoderpos=feedmultiply;
762         }
763         else
764         {
765           encoderpos=activeline*lcdslow;
766           beepshort();
767         }
768         BLOCK;
769       }
770       if(linechanging)
771       {
772         if(encoderpos<1) encoderpos=1;
773         if(encoderpos>400) encoderpos=400;
774         feedmultiply = encoderpos;
775         feedmultiplychanged=true;
776         lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));
777       }
778       
779     }break;
780     case ItemT_nozzle:
781       {
782         if(force_lcd_update)
783         {
784           lcd.setCursor(0,line);lcdprintPGM(MSG_NOZZLE);
785           lcd.setCursor(13,line);lcd.print(ftostr3(intround(degTargetHotend0())));
786         }
787         
788         if((activeline!=line) )
789           break;
790         
791         if(CLICKED)
792         {
793           linechanging=!linechanging;
794           if(linechanging)
795           {
796               encoderpos=intround(degTargetHotend0());
797           }
798           else
799           {
800             setTargetHotend0(encoderpos);
801             encoderpos=activeline*lcdslow;
802             beepshort();
803           }
804           BLOCK;
805         }
806         if(linechanging)
807         {
808           if(encoderpos<0) encoderpos=0;
809           if(encoderpos>260) encoderpos=260;
810           lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));
811         }
812       }break;
813       #if (HEATER_BED_PIN > -1)
814       case ItemT_bed:
815       {
816         if(force_lcd_update)
817         {
818           lcd.setCursor(0,line);lcdprintPGM(MSG_BED);
819           lcd.setCursor(13,line);lcd.print(ftostr3(intround(degTargetBed())));
820         }
821         
822         if((activeline!=line) )
823           break;
824         
825         if(CLICKED)
826         {
827           linechanging=!linechanging;
828           if(linechanging)
829           {
830               encoderpos=intround(degTargetBed());
831           }
832           else
833           {
834             setTargetBed(encoderpos);
835             encoderpos=activeline*lcdslow;
836             beepshort();
837           }
838           BLOCK;
839         }
840         if(linechanging)
841         {
842           if(encoderpos<0) encoderpos=0;
843           if(encoderpos>260) encoderpos=260;
844           lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));
845         }
846       }break;
847       #endif
848
849       
850       case ItemT_fan:
851       {
852         if(force_lcd_update)
853         {
854           lcd.setCursor(0,line);lcdprintPGM(MSG_FAN_SPEED);
855           lcd.setCursor(13,line);lcd.print(ftostr3(FanSpeed));
856         }
857         
858         if((activeline!=line) )
859           break;
860         
861         if(CLICKED) //nalogWrite(FAN_PIN,  fanpwm);
862         {
863           linechanging=!linechanging;
864           if(linechanging)
865           {
866               encoderpos=FanSpeed;
867           }
868           else
869           {
870             encoderpos=activeline*lcdslow;
871             beepshort();
872           }
873           BLOCK;
874         }
875         if(linechanging)
876         {
877           if(encoderpos<0) encoderpos=0;
878           if(encoderpos>255) encoderpos=255;
879           FanSpeed=encoderpos;
880             analogWrite(FAN_PIN,  FanSpeed);
881           lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));
882         }
883         
884       }break;
885       case ItemT_flow://axis_steps_per_unit[i] = code_value();
886          {
887       if(force_lcd_update)
888         {
889           lcd.setCursor(0,line);lcdprintPGM(MSG_FLOW);
890           lcd.setCursor(13,line);lcd.print(ftostr52(axis_steps_per_unit[E_AXIS]));
891         }
892         
893         if((activeline!=line) )
894           break;
895         
896         if(CLICKED)
897         {
898           linechanging=!linechanging;
899           if(linechanging)
900           {
901               encoderpos=(long)(axis_steps_per_unit[E_AXIS]*100.0);
902           }
903           else
904           {
905             float factor=float(encoderpos)/100.0/float(axis_steps_per_unit[E_AXIS]);
906             position[E_AXIS]=lround(position[E_AXIS]*factor);
907             //current_position[E_AXIS]*=factor;
908             axis_steps_per_unit[E_AXIS]= encoderpos/100.0;
909             encoderpos=activeline*lcdslow;
910               
911           }
912           BLOCK;
913           beepshort();
914         }
915         if(linechanging)
916         {
917           if(encoderpos<5) encoderpos=5;
918           if(encoderpos>999999) encoderpos=999999;
919           lcd.setCursor(13,line);lcd.print(ftostr52(encoderpos/100.0));
920         }
921         
922       }break; 
923     default:   
924       break;
925   }
926   line++;
927  }
928  updateActiveLines(ItemT_fan,encoderpos);
929 }
930
931 //does not work
932 // #define MENUCHANGEITEM(repaint_action,  enter_action, accept_action,  change_action) \
933 //   {\
934 //     if(force_lcd_update)  { lcd.setCursor(0,line);  repaint_action; } \
935 //     if(activeline==line)  \
936 //     { \
937 //       if(CLICKED) \
938 //       { \
939 //         linechanging=!linechanging; \
940 //         if(linechanging)  {enter_action;} \
941 //         else {accept_action;} \
942 //       }  \
943 //       else \
944 //       if(linechanging) {change_action};}\
945 //   }
946 //   
947
948 enum {
949   ItemCT_exit,ItemCT_nozzle0,
950 #ifdef AUTOTEMP
951   ItemCT_autotempactive,
952   ItemCT_autotempmin,ItemCT_autotempmax,ItemCT_autotempfact,
953 #endif
954 #if EXTRUDERS > 1
955   ItemCT_nozzle1,
956 #endif
957 #if EXTRUDERS > 2
958   ItemCT_nozzle2,
959 #endif
960 #if defined BED_USES_THERMISTOR || defined BED_USES_AD595
961 ItemCT_bed,
962 #endif  
963   ItemCT_fan,
964   ItemCT_PID_P,ItemCT_PID_I,ItemCT_PID_D,ItemCT_PID_C
965 };
966
967 void MainMenu::showControlTemp()
968 {
969   uint8_t line=0;
970  clearIfNecessary();
971  for(int8_t i=lineoffset;i<lineoffset+LCD_HEIGHT;i++)
972  {
973   switch(i)
974   {
975     case ItemCT_exit:
976       MENUITEM(  lcdprintPGM(MSG_CONTROL)  ,  BLOCK;status=Main_Control;beepshort(); ) ;
977       break;
978     case ItemCT_nozzle0:
979       {
980         if(force_lcd_update)
981         {
982           lcd.setCursor(0,line);lcdprintPGM(MSG_NOZZLE);
983           lcd.setCursor(13,line);lcd.print(ftostr3(intround(degTargetHotend0())));
984         }
985         
986         if((activeline!=line) )
987           break;
988         
989         if(CLICKED)
990         {
991           linechanging=!linechanging;
992           if(linechanging)
993           {
994               encoderpos=intround(degTargetHotend0());
995           }
996           else
997           {
998             setTargetHotend0(encoderpos);
999             encoderpos=activeline*lcdslow;
1000             beepshort();
1001           }
1002           BLOCK;
1003         }
1004         if(linechanging)
1005         {
1006           if(encoderpos<0) encoderpos=0;
1007           if(encoderpos>260) encoderpos=260;
1008           lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));
1009         }
1010         
1011       }break;
1012     #if EXTRUDERS > 1
1013     case ItemCT_nozzle1:
1014       {
1015         if(force_lcd_update)
1016         {
1017           lcd.setCursor(0,line);lcdprintPGM(MSG_NOZZLE1);
1018           lcd.setCursor(13,line);lcd.print(ftostr3(intround(degTargetHotend1())));
1019         }
1020         
1021         if((activeline!=line) )
1022           break;
1023         
1024         if(CLICKED)
1025         {
1026           linechanging=!linechanging;
1027           if(linechanging)
1028           {
1029               encoderpos=intround(degTargetHotend1());
1030           }
1031           else
1032           {
1033             setTargetHotend1(encoderpos);
1034             encoderpos=activeline*lcdslow;
1035             beepshort();
1036           }
1037           BLOCK;
1038         }
1039         if(linechanging)
1040         {
1041           if(encoderpos<0) encoderpos=0;
1042           if(encoderpos>260) encoderpos=260;
1043           lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));
1044         }
1045         
1046       }break;
1047     #endif
1048     #if EXTRUDERS > 2
1049     case ItemCT_nozzle2:
1050       {
1051         if(force_lcd_update)
1052         {
1053           lcd.setCursor(0,line);lcdprintPGM(MSG_NOZZLE2);
1054           lcd.setCursor(13,line);lcd.print(ftostr3(intround(degTargetHotend2())));
1055         }
1056         
1057         if((activeline!=line) )
1058           break;
1059         
1060         if(CLICKED)
1061         {
1062           linechanging=!linechanging;
1063           if(linechanging)
1064           {
1065               encoderpos=intround(degTargetHotend2());
1066           }
1067           else
1068           {
1069             setTargetHotend1(encoderpos);
1070             encoderpos=activeline*lcdslow;
1071             beepshort();
1072           }
1073           BLOCK;
1074         }
1075         if(linechanging)
1076         {
1077           if(encoderpos<0) encoderpos=0;
1078           if(encoderpos>260) encoderpos=260;
1079           lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));
1080         }
1081         
1082       }break;
1083     #endif
1084     #ifdef AUTOTEMP
1085     case ItemCT_autotempmin:
1086       {
1087         if(force_lcd_update)
1088         {
1089           lcd.setCursor(0,line);lcdprintPGM(MSG_MIN);
1090           lcd.setCursor(13,line);lcd.print(ftostr3(autotemp_min));
1091         }
1092         
1093         if((activeline!=line) )
1094           break;
1095         
1096         if(CLICKED)
1097         {
1098           linechanging=!linechanging;
1099           if(linechanging)
1100           {
1101               encoderpos=intround(autotemp_min);
1102           }
1103           else
1104           {
1105             autotemp_min=encoderpos;
1106             encoderpos=activeline*lcdslow;
1107             beepshort();
1108           }
1109           BLOCK;
1110         }
1111         if(linechanging)
1112         {
1113           if(encoderpos<0) encoderpos=0;
1114           if(encoderpos>260) encoderpos=260;
1115           lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));
1116         }
1117         
1118       }break;  
1119     case ItemCT_autotempmax:
1120       {
1121         if(force_lcd_update)
1122         {
1123           lcd.setCursor(0,line);lcdprintPGM(MSG_MAX);
1124           lcd.setCursor(13,line);lcd.print(ftostr3(autotemp_max));
1125         }
1126         
1127         if((activeline!=line) )
1128           break;
1129         
1130         if(CLICKED)
1131         {
1132           linechanging=!linechanging;
1133           if(linechanging)
1134           {
1135               encoderpos=intround(autotemp_max);
1136           }
1137           else
1138           {
1139             autotemp_max=encoderpos;
1140             encoderpos=activeline*lcdslow;
1141             beepshort();
1142           }
1143           BLOCK;
1144         }
1145         if(linechanging)
1146         {
1147           if(encoderpos<0) encoderpos=0;
1148           if(encoderpos>260) encoderpos=260;
1149           lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));
1150         }
1151         
1152       }break;  
1153     case ItemCT_autotempfact:
1154       {
1155         if(force_lcd_update)
1156         {
1157           lcd.setCursor(0,line);lcdprintPGM(MSG_FACTOR);
1158           lcd.setCursor(13,line);lcd.print(ftostr32(autotemp_factor));
1159         }
1160         
1161         if((activeline!=line) )
1162           break;
1163         
1164         if(CLICKED)
1165         {
1166           linechanging=!linechanging;
1167           if(linechanging)
1168           {
1169               encoderpos=intround(autotemp_factor*100);
1170           }
1171           else
1172           {
1173             autotemp_max=encoderpos;
1174             encoderpos=activeline*lcdslow;
1175             beepshort();
1176           }
1177           BLOCK;
1178         }
1179         if(linechanging)
1180         {
1181           if(encoderpos<0) encoderpos=0;
1182           if(encoderpos>99) encoderpos=99;
1183           lcd.setCursor(13,line);lcd.print(ftostr32(encoderpos/100.));
1184         }
1185         
1186       }break;
1187     case ItemCT_autotempactive:
1188       {
1189         if(force_lcd_update)
1190         {
1191           lcd.setCursor(0,line);lcdprintPGM(MSG_AUTOTEMP);
1192           lcd.setCursor(13,line);
1193           if(autotemp_enabled)
1194             lcdprintPGM(MSG_ON);
1195           else
1196             lcdprintPGM(MSG_OFF);
1197         }
1198         
1199         if((activeline!=line) )
1200           break;
1201         
1202         if(CLICKED)
1203         {
1204           autotemp_enabled=!autotemp_enabled;
1205           lcd.setCursor(13,line);
1206           if(autotemp_enabled)
1207             lcdprintPGM(MSG_ON);
1208           else
1209             lcdprintPGM(MSG_OFF);
1210           BLOCK;
1211         }
1212         
1213       }break;  
1214     #endif //autotemp
1215     #if defined BED_USES_THERMISTOR || defined BED_USES_AD595
1216     case ItemCT_bed:
1217       {
1218         if(force_lcd_update)
1219         {
1220           lcd.setCursor(0,line);lcdprintPGM(MSG_BED);
1221           lcd.setCursor(13,line);lcd.print(ftostr3(intround(degTargetBed())));
1222         }
1223         
1224         if((activeline!=line) )
1225           break;
1226         
1227         if(CLICKED)
1228         {
1229           linechanging=!linechanging;
1230           if(linechanging)
1231           {
1232               encoderpos=intround(degTargetBed());
1233           }
1234           else
1235           {
1236             setTargetBed(encoderpos);
1237             encoderpos=activeline*lcdslow;
1238             beepshort();
1239           }
1240           BLOCK;
1241         }
1242         if(linechanging)
1243         {
1244           if(encoderpos<0) encoderpos=0;
1245           if(encoderpos>260) encoderpos=260;
1246           lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));
1247         }
1248       }break;
1249     #endif
1250     case ItemCT_fan:
1251       {
1252         if(force_lcd_update)
1253         {
1254           lcd.setCursor(0,line);lcdprintPGM(MSG_FAN_SPEED);
1255           lcd.setCursor(13,line);lcd.print(ftostr3(FanSpeed));
1256         }
1257         
1258         if((activeline!=line) )
1259           break;
1260         
1261         if(CLICKED) //nalogWrite(FAN_PIN,  fanpwm);
1262         {
1263           linechanging=!linechanging;
1264           if(linechanging)
1265           {
1266               encoderpos=FanSpeed;
1267           }
1268           else
1269           {
1270             encoderpos=activeline*lcdslow;
1271             beepshort();
1272           }
1273           BLOCK;
1274         }
1275         if(linechanging)
1276         {
1277           if(encoderpos<0) encoderpos=0;
1278           if(encoderpos>255) encoderpos=255;
1279           FanSpeed=encoderpos;
1280             analogWrite(FAN_PIN,  FanSpeed);
1281           lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));
1282         }
1283         
1284       }break;
1285     #ifdef PIDTEMP
1286     case ItemCT_PID_P: 
1287       {
1288       if(force_lcd_update)
1289         {
1290           lcd.setCursor(0,line);lcdprintPGM(" PID-P: ");
1291           lcd.setCursor(13,line);lcd.print(itostr4(Kp));
1292         }
1293         
1294         if((activeline!=line) )
1295           break;
1296         
1297         if(CLICKED)
1298         {
1299           linechanging=!linechanging;
1300           if(linechanging)
1301           {
1302               encoderpos=(long)Kp;
1303           }
1304           else
1305           {
1306             Kp= encoderpos;
1307             encoderpos=activeline*lcdslow;
1308               
1309           }
1310           BLOCK;
1311           beepshort();
1312         }
1313         if(linechanging)
1314         {
1315           if(encoderpos<1) encoderpos=1;
1316           if(encoderpos>9990) encoderpos=9990;
1317           lcd.setCursor(13,line);lcd.print(itostr4(encoderpos));
1318         }
1319         
1320       }break;
1321     case ItemCT_PID_I: 
1322       {
1323       if(force_lcd_update)
1324         {
1325           lcd.setCursor(0,line);lcdprintPGM(MSG_PID_I);
1326           lcd.setCursor(13,line);lcd.print(ftostr51(Ki/PID_dT));
1327         }
1328         
1329         if((activeline!=line) )
1330           break;
1331         
1332         if(CLICKED)
1333         {
1334           linechanging=!linechanging;
1335           if(linechanging)
1336           {
1337               encoderpos=(long)(Ki*10/PID_dT);
1338           }
1339           else
1340           {
1341             Ki= encoderpos/10.*PID_dT;
1342             encoderpos=activeline*lcdslow;
1343               
1344           }
1345           BLOCK;
1346           beepshort();
1347         }
1348         if(linechanging)
1349         {
1350           if(encoderpos<0) encoderpos=0;
1351           if(encoderpos>9990) encoderpos=9990;
1352           lcd.setCursor(13,line);lcd.print(ftostr51(encoderpos/10.));
1353         }
1354         
1355       }break;
1356     case ItemCT_PID_D: 
1357       {
1358       if(force_lcd_update)
1359         {
1360           lcd.setCursor(0,line);lcdprintPGM(MSG_PID_D);
1361           lcd.setCursor(13,line);lcd.print(itostr4(Kd*PID_dT));
1362         }
1363         
1364         if((activeline!=line) )
1365           break;
1366         
1367         
1368         if(CLICKED)
1369         {
1370           linechanging=!linechanging;
1371           if(linechanging)
1372           {
1373               encoderpos=(long)(Kd/5./PID_dT);
1374           }
1375           else
1376           {
1377             Kd= encoderpos;
1378             encoderpos=activeline*lcdslow;
1379               
1380           }
1381           BLOCK;
1382           beepshort();
1383         }
1384         if(linechanging)
1385         {
1386           if(encoderpos<0) encoderpos=0;
1387           if(encoderpos>9990) encoderpos=9990;
1388           lcd.setCursor(13,line);lcd.print(itostr4(encoderpos));
1389         }
1390        
1391       }break;   
1392     case ItemCT_PID_C: 
1393       #ifdef PID_ADD_EXTRUSION_RATE
1394       {
1395       if(force_lcd_update)
1396         {
1397           lcd.setCursor(0,line);lcdprintPGM(MSG_PID_C);
1398           lcd.setCursor(13,line);lcd.print(itostr3(Kc));
1399         }
1400         
1401         if((activeline!=line) )
1402           break;
1403         
1404         if(CLICKED)
1405         {
1406           linechanging=!linechanging;
1407           if(linechanging)
1408           {
1409               encoderpos=(long)Kc;
1410           }
1411           else
1412           {
1413             Kc= encoderpos;
1414             encoderpos=activeline*lcdslow;
1415               
1416           }
1417           BLOCK;
1418           beepshort();
1419         }
1420         if(linechanging)
1421         {
1422           if(encoderpos<0) encoderpos=0;
1423           if(encoderpos>990) encoderpos=990;
1424           lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));
1425         }
1426         
1427       }
1428       #endif
1429     #endif
1430       break;
1431     default:   
1432       break;
1433   }
1434   line++;
1435  }
1436  #ifdef PID_ADD_EXTRUSION_RATE
1437   updateActiveLines(ItemCT_PID_C,encoderpos);
1438  #else
1439   updateActiveLines(ItemCT_PID_D,encoderpos);
1440  #endif
1441 }
1442
1443
1444 enum {
1445   ItemCM_exit, 
1446   ItemCM_acc, ItemCM_xyjerk, 
1447   ItemCM_vmaxx, ItemCM_vmaxy, ItemCM_vmaxz, ItemCM_vmaxe, 
1448   ItemCM_vtravmin,ItemCM_vmin,  
1449   ItemCM_amaxx, ItemCM_amaxy, ItemCM_amaxz, ItemCM_amaxe, 
1450   ItemCM_aret, ItemCM_xsteps,ItemCM_ysteps, ItemCM_zsteps, ItemCM_esteps
1451 };
1452
1453
1454
1455 void MainMenu::showControlMotion()
1456 {
1457  uint8_t line=0;
1458  clearIfNecessary();
1459  for(int8_t i=lineoffset;i<lineoffset+LCD_HEIGHT;i++)
1460  {
1461   switch(i)
1462   {
1463     case ItemCM_exit:
1464       MENUITEM(  lcdprintPGM(MSG_CONTROL)  ,  BLOCK;status=Main_Control;beepshort(); ) ;
1465       break;
1466     case ItemCM_acc:
1467     {
1468       if(force_lcd_update)
1469         {
1470           lcd.setCursor(0,line);lcdprintPGM(MSG_ACC);
1471           lcd.setCursor(13,line);lcd.print(itostr3(acceleration/100));lcdprintPGM("00");
1472         }
1473         
1474         if((activeline!=line) )
1475           break;
1476         
1477         if(CLICKED)
1478         {
1479           linechanging=!linechanging;
1480           if(linechanging)
1481           {
1482               encoderpos=(long)acceleration/100;
1483           }
1484           else
1485           {
1486             acceleration= encoderpos*100;
1487             encoderpos=activeline*lcdslow;
1488           }
1489           BLOCK;
1490           beepshort();
1491         }
1492         if(linechanging)
1493         {
1494           if(encoderpos<5) encoderpos=5;
1495           if(encoderpos>990) encoderpos=990;
1496           lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));lcdprintPGM("00");
1497         }
1498         
1499       }break;
1500     case ItemCM_xyjerk: //max_xy_jerk
1501       {
1502       if(force_lcd_update)
1503         {
1504           lcd.setCursor(0,line);lcdprintPGM(MSG_VXY_JERK);
1505           lcd.setCursor(13,line);lcd.print(itostr3(max_xy_jerk));
1506         }
1507         
1508         if((activeline!=line) )
1509           break;
1510         
1511         if(CLICKED)
1512         {
1513           linechanging=!linechanging;
1514           if(linechanging)
1515           {
1516               encoderpos=(long)max_xy_jerk;
1517           }
1518           else
1519           {
1520             max_xy_jerk= encoderpos;
1521             encoderpos=activeline*lcdslow;
1522               
1523           }
1524           BLOCK;
1525           beepshort();
1526         }
1527         if(linechanging)
1528         {
1529           if(encoderpos<1) encoderpos=1;
1530           if(encoderpos>990) encoderpos=990;
1531           lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));
1532         }
1533         
1534       }break;
1535       
1536     case ItemCM_vmaxx:
1537     case ItemCM_vmaxy:
1538     case ItemCM_vmaxz:
1539     case ItemCM_vmaxe:
1540       {
1541       if(force_lcd_update)
1542         {
1543           lcd.setCursor(0,line);lcdprintPGM(MSG_VMAX);
1544           if(i==ItemCM_vmaxx)lcdprintPGM(MSG_X);
1545           if(i==ItemCM_vmaxy)lcdprintPGM(MSG_Y);
1546           if(i==ItemCM_vmaxz)lcdprintPGM(MSG_Z);
1547           if(i==ItemCM_vmaxe)lcdprintPGM(MSG_E);
1548           lcd.setCursor(13,line);lcd.print(itostr3(max_feedrate[i-ItemCM_vmaxx]));
1549         }
1550         
1551         if((activeline!=line) )
1552           break;
1553         
1554         if(CLICKED)
1555         {
1556           linechanging=!linechanging;
1557           if(linechanging)
1558           {
1559               encoderpos=(long)max_feedrate[i-ItemCM_vmaxx];
1560           }
1561           else
1562           {
1563             max_feedrate[i-ItemCM_vmaxx]= encoderpos;
1564             encoderpos=activeline*lcdslow;
1565               
1566           }
1567           BLOCK;
1568           beepshort();
1569         }
1570         if(linechanging)
1571         {
1572           if(encoderpos<1) encoderpos=1;
1573           if(encoderpos>990) encoderpos=990;
1574           lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));
1575         }
1576         
1577       }break;
1578     
1579     case ItemCM_vmin:
1580     {
1581       if(force_lcd_update)
1582         {
1583           lcd.setCursor(0,line);lcdprintPGM(MSG_VMIN);
1584           lcd.setCursor(13,line);lcd.print(itostr3(minimumfeedrate));
1585         }
1586         
1587         if((activeline!=line) )
1588           break;
1589         
1590         if(CLICKED)
1591         {
1592           linechanging=!linechanging;
1593           if(linechanging)
1594           {
1595               encoderpos=(long)(minimumfeedrate);
1596           }
1597           else
1598           {
1599             minimumfeedrate= encoderpos;
1600             encoderpos=activeline*lcdslow;
1601               
1602           }
1603           BLOCK;
1604           beepshort();
1605         }
1606         if(linechanging)
1607         {
1608           if(encoderpos<0) encoderpos=0;
1609           if(encoderpos>990) encoderpos=990;
1610           lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));
1611         }
1612         
1613       }break;
1614     case ItemCM_vtravmin:
1615     {
1616       if(force_lcd_update)
1617         {
1618           lcd.setCursor(0,line);lcdprintPGM(MSG_VTRAV_MIN);
1619           lcd.setCursor(13,line);lcd.print(itostr3(mintravelfeedrate));
1620         }
1621         
1622         if((activeline!=line) )
1623           break;
1624         
1625         if(CLICKED)
1626         {
1627           linechanging=!linechanging;
1628           if(linechanging)
1629           {
1630               encoderpos=(long)mintravelfeedrate;
1631           }
1632           else
1633           {
1634             mintravelfeedrate= encoderpos;
1635             encoderpos=activeline*lcdslow;
1636               
1637           }
1638           BLOCK;
1639           beepshort();
1640         }
1641         if(linechanging)
1642         {
1643           if(encoderpos<0) encoderpos=0;
1644           if(encoderpos>990) encoderpos=990;
1645           lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));
1646         }
1647         
1648       }break;
1649     
1650     case ItemCM_amaxx:      
1651     case ItemCM_amaxy:
1652     case ItemCM_amaxz:
1653     case ItemCM_amaxe:
1654     {
1655       if(force_lcd_update)
1656         {
1657           lcd.setCursor(0,line);lcdprintPGM(" Amax ");
1658           if(i==ItemCM_amaxx)lcdprintPGM(MSG_X);
1659           if(i==ItemCM_amaxy)lcdprintPGM(MSG_Y);
1660           if(i==ItemCM_amaxz)lcdprintPGM(MSG_Z);
1661           if(i==ItemCM_amaxe)lcdprintPGM(MSG_E);
1662           lcd.setCursor(13,line);lcd.print(itostr3(max_acceleration_units_per_sq_second[i-ItemCM_amaxx]/100));lcdprintPGM("00");
1663         }
1664         
1665         if((activeline!=line) )
1666           break;
1667         
1668         if(CLICKED)
1669         {
1670           linechanging=!linechanging;
1671           if(linechanging)
1672           {
1673               encoderpos=(long)max_acceleration_units_per_sq_second[i-ItemCM_amaxx]/100;
1674           }
1675           else
1676           {
1677             max_acceleration_units_per_sq_second[i-ItemCM_amaxx]= encoderpos*100;
1678             encoderpos=activeline*lcdslow;
1679           }
1680           BLOCK;
1681           beepshort();
1682         }
1683         if(linechanging)
1684         {
1685           if(encoderpos<1) encoderpos=1;
1686           if(encoderpos>990) encoderpos=990;
1687           lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));lcdprintPGM("00");
1688         }
1689         
1690       }break;
1691      
1692     
1693     case ItemCM_aret://float retract_acceleration = 7000;
1694     {
1695         if(force_lcd_update)
1696         {
1697           lcd.setCursor(0,line);lcdprintPGM(MSG_A_RETRACT);
1698           lcd.setCursor(13,line);lcd.print(ftostr3(retract_acceleration/100));lcdprintPGM("00");
1699         }
1700         
1701         if((activeline!=line) )
1702           break;
1703         
1704         if(CLICKED)
1705         {
1706           linechanging=!linechanging;
1707           if(linechanging)
1708           {
1709               encoderpos=(long)retract_acceleration/100;
1710           }
1711           else
1712           {
1713             retract_acceleration= encoderpos*100;
1714             encoderpos=activeline*lcdslow;
1715               
1716           }
1717           BLOCK;
1718           beepshort();
1719         }
1720         if(linechanging)
1721         {
1722           if(encoderpos<10) encoderpos=10;
1723           if(encoderpos>990) encoderpos=990;
1724           lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));lcdprintPGM("00");
1725         }
1726         
1727       }break;
1728        case ItemCM_xsteps://axis_steps_per_unit[i] = code_value();
1729          {
1730       if(force_lcd_update)
1731         {
1732           lcd.setCursor(0,line);lcdprintPGM(MSG_XSTEPS);
1733           lcd.setCursor(11,line);lcd.print(ftostr52(axis_steps_per_unit[X_AXIS]));
1734         }
1735         
1736         if((activeline!=line) )
1737           break;
1738         
1739         if(CLICKED)
1740         {
1741           linechanging=!linechanging;
1742           if(linechanging)
1743           {
1744               encoderpos=(long)(axis_steps_per_unit[X_AXIS]*100.0);
1745           }
1746           else
1747           {
1748             float factor=float(encoderpos)/100.0/float(axis_steps_per_unit[X_AXIS]);
1749             position[X_AXIS]=lround(position[X_AXIS]*factor);
1750             //current_position[X_AXIS]*=factor;
1751             axis_steps_per_unit[X_AXIS]= encoderpos/100.0;
1752             encoderpos=activeline*lcdslow;
1753           }
1754           BLOCK;
1755           beepshort();
1756         }
1757         if(linechanging)
1758         {
1759           if(encoderpos<5) encoderpos=5;
1760           if(encoderpos>999999) encoderpos=999999;
1761           lcd.setCursor(11,line);lcd.print(ftostr52(encoderpos/100.0));
1762         }
1763         
1764       }break;
1765        case ItemCM_ysteps://axis_steps_per_unit[i] = code_value();
1766          {
1767       if(force_lcd_update)
1768         {
1769           lcd.setCursor(0,line);lcdprintPGM(MSG_YSTEPS);
1770           lcd.setCursor(11,line);lcd.print(ftostr52(axis_steps_per_unit[Y_AXIS]));
1771         }
1772         
1773         if((activeline!=line) )
1774           break;
1775         
1776         if(CLICKED)
1777         {
1778           linechanging=!linechanging;
1779           if(linechanging)
1780           {
1781               encoderpos=(long)(axis_steps_per_unit[Y_AXIS]*100.0);
1782           }
1783           else
1784           {
1785             float factor=float(encoderpos)/100.0/float(axis_steps_per_unit[Y_AXIS]);
1786             position[Y_AXIS]=lround(position[Y_AXIS]*factor);
1787             //current_position[Y_AXIS]*=factor;
1788             axis_steps_per_unit[Y_AXIS]= encoderpos/100.0;
1789             encoderpos=activeline*lcdslow;
1790               
1791           }
1792           BLOCK;
1793           beepshort();
1794         }
1795         if(linechanging)
1796         {
1797           if(encoderpos<5) encoderpos=5;
1798           if(encoderpos>999999) encoderpos=999999;
1799           lcd.setCursor(11,line);lcd.print(ftostr52(encoderpos/100.0));
1800         }
1801         
1802       }break;
1803        case ItemCM_zsteps://axis_steps_per_unit[i] = code_value();
1804          {
1805       if(force_lcd_update)
1806         {
1807           lcd.setCursor(0,line);lcdprintPGM(MSG_ZSTEPS);
1808           lcd.setCursor(11,line);lcd.print(ftostr52(axis_steps_per_unit[Z_AXIS]));
1809         }
1810         
1811         if((activeline!=line) )
1812           break;
1813         
1814         if(CLICKED)
1815         {
1816           linechanging=!linechanging;
1817           if(linechanging)
1818           {
1819               encoderpos=(long)(axis_steps_per_unit[Z_AXIS]*100.0);
1820           }
1821           else
1822           {
1823             float factor=float(encoderpos)/100.0/float(axis_steps_per_unit[Z_AXIS]);
1824             position[Z_AXIS]=lround(position[Z_AXIS]*factor);
1825             //current_position[Z_AXIS]*=factor;
1826             axis_steps_per_unit[Z_AXIS]= encoderpos/100.0;
1827             encoderpos=activeline*lcdslow;
1828               
1829           }
1830           BLOCK;
1831           beepshort();
1832         }
1833         if(linechanging)
1834         {
1835           if(encoderpos<5) encoderpos=5;
1836           if(encoderpos>999999) encoderpos=999999;
1837           lcd.setCursor(11,line);lcd.print(ftostr52(encoderpos/100.0));
1838         }
1839         
1840       }break;
1841       
1842     case ItemCM_esteps://axis_steps_per_unit[i] = code_value();
1843          {
1844       if(force_lcd_update)
1845         {
1846           lcd.setCursor(0,line);lcdprintPGM(MSG_ESTEPS);
1847           lcd.setCursor(11,line);lcd.print(ftostr52(axis_steps_per_unit[E_AXIS]));
1848         }
1849         
1850         if((activeline!=line) )
1851           break;
1852         
1853         if(CLICKED)
1854         {
1855           linechanging=!linechanging;
1856           if(linechanging)
1857           {
1858               encoderpos=(long)(axis_steps_per_unit[E_AXIS]*100.0);
1859           }
1860           else
1861           {
1862             float factor=float(encoderpos)/100.0/float(axis_steps_per_unit[E_AXIS]);
1863             position[E_AXIS]=lround(position[E_AXIS]*factor);
1864             //current_position[E_AXIS]*=factor;
1865             axis_steps_per_unit[E_AXIS]= encoderpos/100.0;
1866             encoderpos=activeline*lcdslow;
1867               
1868           }
1869           BLOCK;
1870           beepshort();
1871         }
1872         if(linechanging)
1873         {
1874           if(encoderpos<5) encoderpos=5;
1875           if(encoderpos>999999) encoderpos=999999;
1876           lcd.setCursor(11,line);lcd.print(ftostr52(encoderpos/100.0));
1877         }
1878         
1879       }break; 
1880     default:   
1881       break;
1882   }
1883   line++;
1884  }
1885  updateActiveLines(ItemCM_esteps,encoderpos);
1886 }
1887
1888
1889 enum {
1890   ItemR_exit,
1891   ItemR_autoretract,
1892   ItemR_retract_length,ItemR_retract_feedrate,ItemR_retract_zlift,
1893   ItemR_unretract_length,ItemR_unretract_feedrate,
1894   
1895 };
1896
1897
1898
1899 void MainMenu::showControlRetract()
1900 {
1901 #ifdef FWRETRACT
1902  uint8_t line=0;
1903  clearIfNecessary();
1904  for(int8_t i=lineoffset;i<lineoffset+LCD_HEIGHT;i++)
1905  {
1906   switch(i)
1907   {
1908     case ItemR_exit:
1909       MENUITEM(  lcdprintPGM(MSG_CONTROL)  ,  BLOCK;status=Main_Control;beepshort(); ) ;
1910       break;
1911     
1912       //float retract_length=2, retract_feedrate=1200, retract_zlift=0.4;
1913   //float retract_recover_length=0, retract_recover_feedrate=500;
1914       case ItemR_autoretract:
1915       {
1916         if(force_lcd_update)
1917         {
1918           lcd.setCursor(0,line);lcdprintPGM(MSG_AUTORETRACT);
1919           lcd.setCursor(13,line);
1920           if(autoretract_enabled)
1921             lcdprintPGM(MSG_ON);
1922           else
1923             lcdprintPGM(MSG_OFF);
1924         }
1925         
1926         if((activeline!=line) )
1927           break;
1928         
1929         if(CLICKED)
1930         {
1931           autoretract_enabled=!autoretract_enabled;
1932           lcd.setCursor(13,line);
1933           if(autoretract_enabled)
1934             lcdprintPGM(MSG_ON);
1935           else
1936             lcdprintPGM(MSG_OFF);
1937           BLOCK;
1938         }
1939         
1940       }break;  
1941     
1942       case ItemR_retract_length:
1943     {
1944         if(force_lcd_update)
1945         {
1946           lcd.setCursor(0,line);lcdprintPGM(MSG_CONTROL_RETRACT);
1947           lcd.setCursor(13,line);lcd.print(ftostr52(retract_length));
1948         }
1949         
1950         if((activeline!=line) )
1951           break;
1952         
1953         if(CLICKED)
1954         {
1955           linechanging=!linechanging;
1956           if(linechanging)
1957           {
1958               encoderpos=(long)(retract_length*100);
1959           }
1960           else
1961           {
1962             retract_length= encoderpos/100.;
1963             encoderpos=activeline*lcdslow;
1964               
1965           }
1966           BLOCK;
1967           beepshort();
1968         }
1969         if(linechanging)
1970         {
1971           if(encoderpos<1) encoderpos=1;
1972           if(encoderpos>990) encoderpos=990;
1973           lcd.setCursor(13,line);lcd.print(ftostr52(encoderpos/100.));
1974         }
1975         
1976       }break;
1977       case ItemR_retract_feedrate:
1978     {
1979         if(force_lcd_update)
1980         {
1981           lcd.setCursor(0,line);lcdprintPGM(MSG_CONTROL_RETRACTF);
1982           lcd.setCursor(13,line);lcd.print(itostr4(retract_feedrate));
1983         }
1984         
1985         if((activeline!=line) )
1986           break;
1987         
1988         if(CLICKED)
1989         {
1990           linechanging=!linechanging;
1991           if(linechanging)
1992           {
1993               encoderpos=(long)(retract_feedrate/5);
1994           }
1995           else
1996           {
1997             retract_feedrate= encoderpos*5.;
1998             encoderpos=activeline*lcdslow;
1999               
2000           }
2001           BLOCK;
2002           beepshort();
2003         }
2004         if(linechanging)
2005         {
2006           if(encoderpos<1) encoderpos=1;
2007           if(encoderpos>990) encoderpos=990;
2008           lcd.setCursor(13,line);lcd.print(itostr4(encoderpos*5));
2009         }
2010         
2011       }break;
2012       case ItemR_retract_zlift://float retract_acceleration = 7000;
2013     {
2014         if(force_lcd_update)
2015         {
2016           lcd.setCursor(0,line);lcdprintPGM(MSG_CONTROL_RETRACT_ZLIFT);
2017           lcd.setCursor(13,line);lcd.print(ftostr52(retract_zlift));;
2018         }
2019         
2020         if((activeline!=line) )
2021           break;
2022         
2023         if(CLICKED)
2024         {
2025           linechanging=!linechanging;
2026           if(linechanging)
2027           {
2028               encoderpos=(long)(retract_zlift*10);
2029           }
2030           else
2031           {
2032             retract_zlift= encoderpos/10.;
2033             encoderpos=activeline*lcdslow;
2034               
2035           }
2036           BLOCK;
2037           beepshort();
2038         }
2039         if(linechanging)
2040         {
2041           if(encoderpos<0) encoderpos=0;
2042           if(encoderpos>990) encoderpos=990;
2043           lcd.setCursor(13,line);lcd.print(ftostr52(encoderpos/10.));
2044         }
2045         
2046       }break;
2047       case ItemR_unretract_length:
2048     {
2049         if(force_lcd_update)
2050         {
2051           lcd.setCursor(0,line);lcdprintPGM(MSG_CONTROL_RETRACT_RECOVER);
2052           lcd.setCursor(13,line);lcd.print(ftostr52(retract_recover_length));;
2053         }
2054         
2055         if((activeline!=line) )
2056           break;
2057         
2058         if(CLICKED)
2059         {
2060           linechanging=!linechanging;
2061           if(linechanging)
2062           {
2063               encoderpos=(long)(retract_recover_length*100);
2064           }
2065           else
2066           {
2067             retract_recover_length= encoderpos/100.;
2068             encoderpos=activeline*lcdslow;
2069               
2070           }
2071           BLOCK;
2072           beepshort();
2073         }
2074         if(linechanging)
2075         {
2076           if(encoderpos<0) encoderpos=0;
2077           if(encoderpos>990) encoderpos=990;
2078           lcd.setCursor(13,line);lcd.print(ftostr52(encoderpos/100.));
2079         }
2080         
2081       }break;
2082       
2083       case ItemR_unretract_feedrate:
2084     {
2085         if(force_lcd_update)
2086         {
2087           lcd.setCursor(0,line);lcdprintPGM(MSG_CONTROL_RETRACT_RECOVERF);
2088           lcd.setCursor(13,line);lcd.print(itostr4(retract_recover_feedrate));
2089         }
2090         
2091         if((activeline!=line) )
2092           break;
2093         
2094         if(CLICKED)
2095         {
2096           linechanging=!linechanging;
2097           if(linechanging)
2098           {
2099               encoderpos=(long)retract_recover_feedrate/5;
2100           }
2101           else
2102           {
2103             retract_recover_feedrate= encoderpos*5.;
2104             encoderpos=activeline*lcdslow;
2105               
2106           }
2107           BLOCK;
2108           beepshort();
2109         }
2110         if(linechanging)
2111         {
2112           if(encoderpos<1) encoderpos=1;
2113           if(encoderpos>990) encoderpos=990;
2114           lcd.setCursor(13,line);lcd.print(itostr4(encoderpos*5));
2115         }
2116         
2117       }break;
2118     
2119     default:   
2120       break;
2121   }
2122   line++;
2123  }
2124  updateActiveLines(ItemR_unretract_feedrate,encoderpos);
2125 #endif
2126 }
2127
2128
2129
2130 enum {
2131   ItemC_exit,ItemC_temp,ItemC_move,
2132 #ifdef FWRETRACT
2133   ItemC_rectract,
2134 #endif
2135   ItemC_store, ItemC_load,ItemC_failsafe
2136 };
2137
2138 void MainMenu::showControl()
2139 {
2140  uint8_t line=0;
2141  clearIfNecessary();
2142  for(int8_t i=lineoffset;i<lineoffset+LCD_HEIGHT;i++)
2143  {
2144   switch(i)
2145   {
2146     case ItemC_exit:
2147       MENUITEM(  lcdprintPGM(MSG_MAIN_WIDE)  ,  BLOCK;status=Main_Menu;beepshort(); ) ;
2148       break;
2149     case ItemC_temp:
2150       MENUITEM(  lcdprintPGM(MSG_TEMPERATURE_WIDE)  ,  BLOCK;status=Sub_TempControl;beepshort(); ) ;
2151       break;
2152    case ItemC_move:
2153       MENUITEM(  lcdprintPGM(MSG_MOTION_WIDE)  ,  BLOCK;status=Sub_MotionControl;beepshort(); ) ;
2154       break;
2155 #ifdef FWRETRACT
2156     case ItemC_rectract:
2157       MENUITEM(  lcdprintPGM(MSG_RECTRACT_WIDE)  ,  BLOCK;status=Sub_RetractControl;beepshort(); ) ;
2158       break;
2159 #endif
2160     case ItemC_store:
2161     {
2162       if(force_lcd_update)
2163       {
2164         lcd.setCursor(0,line);lcdprintPGM(MSG_STORE_EPROM);
2165       }
2166       if((activeline==line) && CLICKED)
2167       {
2168         //enquecommand("M84");
2169         beepshort();
2170         BLOCK;
2171         EEPROM_StoreSettings();
2172       }
2173     }break;
2174     case ItemC_load:
2175     {
2176       if(force_lcd_update)
2177       {
2178         lcd.setCursor(0,line);lcdprintPGM(MSG_LOAD_EPROM);
2179       }
2180       if((activeline==line) && CLICKED)
2181       {
2182         //enquecommand("M84");
2183         beepshort();
2184         BLOCK;
2185         EEPROM_RetrieveSettings();
2186       }
2187     }break;
2188     case ItemC_failsafe:
2189     {
2190       if(force_lcd_update)
2191       {
2192         lcd.setCursor(0,line);lcdprintPGM(MSG_RESTORE_FAILSAFE);
2193       }
2194       if((activeline==line) && CLICKED)
2195       {
2196         //enquecommand("M84");
2197         beepshort();
2198         BLOCK;
2199         EEPROM_RetrieveSettings(true);
2200       }
2201     }break;
2202     default:   
2203       break;
2204   }
2205   line++;
2206  }
2207  updateActiveLines(ItemC_failsafe,encoderpos);
2208 }
2209
2210
2211
2212
2213
2214 void MainMenu::showSD()
2215 {
2216 #ifdef SDSUPPORT
2217  uint8_t line=0;
2218
2219  clearIfNecessary();
2220  static uint8_t nrfiles=0;
2221  if(force_lcd_update)
2222  {
2223   if(card.cardOK)
2224   {
2225     nrfiles=card.getnrfilenames();
2226   }
2227   else
2228   {
2229     nrfiles=0;
2230     lineoffset=0;
2231   }
2232  }
2233  bool enforceupdate=false;
2234  for(int8_t i=lineoffset;i<lineoffset+LCD_HEIGHT;i++)
2235  {
2236   switch(i)
2237   {
2238     case 0:
2239       MENUITEM(  lcdprintPGM(MSG_MAIN)  ,  BLOCK;status=Main_Menu;beepshort(); ) ;
2240       break;
2241 //     case 1:
2242 //       {
2243 //         if(force_lcd_update)
2244 //         {
2245 //           lcd.setCursor(0,line);
2246 //            #ifdef CARDINSERTED
2247 //           if(CARDINSERTED)
2248 //           #else
2249 //           if(true)
2250 //           #endif
2251 //           {
2252 //             lcdprintPGM(" \004Refresh");
2253 //           }
2254 //           else
2255 //           {
2256 //             lcdprintPGM(" \004Insert Card");
2257 //           }
2258 //           
2259 //         }
2260 //         if((activeline==line) && CLICKED)
2261 //         {
2262 //           BLOCK;
2263 //           beepshort();
2264 //           card.initsd();
2265 //           force_lcd_update=true;
2266 //            nrfiles=card.getnrfilenames();
2267 //         }
2268 //       }break;
2269     case 1:
2270       MENUITEM(  lcd.print(" ");card.getWorkDirName();
2271           if(card.filename[0]=='/') lcdprintPGM(MSG_REFRESH);
2272           else {
2273                   lcd.print("\005");
2274                   lcd.print(card.filename);
2275                   lcd.print("/..");
2276                         }  ,  
2277         BLOCK;
2278                         if(SDCARDDETECT == -1) card.initsd();
2279                         card.updir();
2280                         enforceupdate=true;
2281                         lineoffset=0;
2282                         beepshort(); ) ;
2283       
2284       break;
2285     default:
2286     {
2287       #define FIRSTITEM 2
2288       if(i-FIRSTITEM<nrfiles)
2289       {
2290         if(force_lcd_update)
2291         {
2292           card.getfilename(i-FIRSTITEM);
2293           //Serial.print("Filenr:");Serial.println(i-2);
2294           lcd.setCursor(0,line);lcdprintPGM(" ");
2295           if(card.filenameIsDir) lcd.print("\005");
2296           lcd.print(card.filename);
2297         }
2298         if((activeline==line) && CLICKED)
2299         {
2300           BLOCK
2301           card.getfilename(i-FIRSTITEM);
2302           if(card.filenameIsDir)
2303           {
2304             for(int8_t i=0;i<strlen(card.filename);i++)
2305               card.filename[i]=tolower(card.filename[i]);
2306             card.chdir(card.filename);
2307             lineoffset=0;
2308             enforceupdate=true;
2309           }
2310           else
2311           {
2312             char cmd[30];
2313             for(int8_t i=0;i<strlen(card.filename);i++)
2314               card.filename[i]=tolower(card.filename[i]);
2315             sprintf(cmd,"M23 %s",card.filename);
2316             //sprintf(cmd,"M115");
2317             enquecommand(cmd);
2318             enquecommand("M24");
2319             beep(); 
2320             status=Main_Status;
2321             lcd_status(card.filename);
2322           }
2323         } 
2324       }
2325       
2326     }
2327       break;
2328   }
2329   line++;
2330  }
2331  updateActiveLines(FIRSTITEM+nrfiles-1,encoderpos);
2332  if(enforceupdate)
2333  {
2334    force_lcd_update=true;
2335    enforceupdate=false;
2336  }
2337 #endif
2338 }
2339
2340
2341 enum {ItemM_watch, ItemM_prepare, ItemM_control, ItemM_file };
2342 void MainMenu::showMainMenu()
2343 {
2344
2345   #ifndef ULTIPANEL
2346     force_lcd_update=false;
2347   #endif
2348   if(tune)
2349   {
2350     if(!(movesplanned() || IS_SD_PRINTING))
2351     {
2352       force_lcd_update=true;
2353       tune=false;
2354     }
2355   }
2356   else 
2357   {
2358     if(movesplanned() || IS_SD_PRINTING)
2359     {
2360       force_lcd_update=true;
2361       tune=true;
2362     }
2363   } 
2364   clearIfNecessary();
2365   uint8_t line=0;
2366   for(int8_t i=lineoffset;i<lineoffset+LCD_HEIGHT;i++)
2367   {
2368     switch(i)
2369     { 
2370       case ItemM_watch:
2371         MENUITEM(  lcdprintPGM(MSG_WATCH)  ,  BLOCK;status=Main_Status;beepshort(); ) ;
2372        break;
2373       case ItemM_prepare:
2374         MENUITEM(  if(!tune) lcdprintPGM(MSG_PREPARE);else  lcdprintPGM(MSG_TUNE); ,  BLOCK;status=Main_Prepare;beepshort(); ) ;
2375       break;
2376        
2377       case ItemM_control:
2378         MENUITEM(  lcdprintPGM(MSG_CONTROL_ARROW)  ,  BLOCK;status=Main_Control;beepshort(); ) ;
2379       break;
2380       #ifdef SDSUPPORT
2381       case ItemM_file:    
2382       {
2383         if(force_lcd_update) 
2384         {
2385           lcd.setCursor(0,line);
2386           #ifdef CARDINSERTED
2387             if(CARDINSERTED)
2388           #else
2389             if(true)
2390           #endif
2391           {
2392             if(card.sdprinting)
2393               lcdprintPGM(MSG_STOP_PRINT);
2394             else
2395               lcdprintPGM(MSG_CARD_MENU);
2396           }
2397           else
2398           {
2399            lcdprintPGM(MSG_NO_CARD); 
2400           }
2401         }
2402         #ifdef CARDINSERTED
2403           if(CARDINSERTED)
2404         #endif
2405         if((activeline==line)&&CLICKED)
2406         {
2407           card.printingHasFinished();
2408           BLOCK;
2409           status=Main_SD;
2410           beepshort();
2411         }
2412       }break;
2413       #else
2414       case ItemM_file:
2415         break;
2416       #endif
2417       default: 
2418         SERIAL_ERROR_START;
2419         SERIAL_ERRORLNPGM(MSG_SERIAL_ERROR_MENU_STRUCTURE);
2420       break;
2421     }
2422     line++;
2423   }
2424   updateActiveLines(3,encoderpos);
2425 }
2426
2427 void MainMenu::update()
2428 {
2429   static MainStatus oldstatus=Main_Menu;  //init automatically causes foce_lcd_update=true
2430   static long timeoutToStatus=0;
2431   static bool oldcardstatus=false;
2432   #ifdef CARDINSERTED
2433     if((CARDINSERTED != oldcardstatus))
2434     {
2435       force_lcd_update=true;
2436       oldcardstatus=CARDINSERTED;
2437       lcd_init(); // to maybe revive the lcd if static electricty killed it.
2438       //Serial.println("echo: SD CHANGE");
2439       if(CARDINSERTED)
2440       {
2441         card.initsd();
2442         LCD_MESSAGEPGM(MSG_SD_INSERTED);
2443       }
2444       else
2445       {
2446         card.release();
2447         LCD_MESSAGEPGM(MSG_SD_REMOVED);
2448       }
2449     }
2450   #endif
2451  
2452   if(status!=oldstatus)
2453   {
2454     force_lcd_update=true;
2455     encoderpos=0;
2456     lineoffset=0;
2457     
2458     oldstatus=status;
2459   }
2460   if( (encoderpos!=lastencoderpos) || CLICKED)
2461     timeoutToStatus=millis()+STATUSTIMEOUT;
2462
2463   switch(status)
2464   { 
2465       case Main_Status: 
2466       {  
2467         showStatus();
2468         if(CLICKED)
2469         {
2470            linechanging=false;
2471            BLOCK
2472            status=Main_Menu;
2473            timeoutToStatus=millis()+STATUSTIMEOUT;
2474         }
2475       }break;
2476       case Main_Menu: 
2477       {
2478         showMainMenu();
2479         linechanging=false;
2480       }break;
2481       case Main_Prepare: 
2482       {
2483         if(tune)
2484         {
2485           showTune();
2486         }
2487         else
2488         {
2489           showPrepare(); 
2490         }
2491       }break;
2492       case Sub_PrepareMove:
2493       {        
2494             showAxisMove();
2495       }break;
2496       case Main_Control:
2497       {
2498         showControl(); 
2499       }break;
2500       case Sub_MotionControl:
2501       {
2502         showControlMotion(); 
2503       }break;
2504       case Sub_RetractControl:
2505       {
2506         showControlRetract(); 
2507       }break;
2508       case Sub_TempControl:
2509       {
2510         showControlTemp(); 
2511       }break;
2512       case Main_SD: 
2513       {
2514         showSD();
2515       }break;
2516   }
2517   
2518   if(timeoutToStatus<millis())
2519     status=Main_Status;
2520   //force_lcd_update=false;
2521   lastencoderpos=encoderpos;
2522 }
2523
2524
2525
2526
2527
2528
2529 //  convert float to string with +123.4 format
2530 char *ftostr3(const float &x)
2531 {
2532   //sprintf(conv,"%5.1f",x);
2533   int xx=x;
2534   conv[0]=(xx/100)%10+'0';
2535   conv[1]=(xx/10)%10+'0';
2536   conv[2]=(xx)%10+'0';
2537   conv[3]=0;
2538   return conv;
2539 }
2540
2541 char *itostr2(const uint8_t &x)
2542 {
2543   //sprintf(conv,"%5.1f",x);
2544   int xx=x;
2545   conv[0]=(xx/10)%10+'0';
2546   conv[1]=(xx)%10+'0';
2547   conv[2]=0;
2548   return conv;
2549 }
2550
2551 //  convert float to string with +123.4 format
2552 char *ftostr31(const float &x)
2553 {
2554   int xx=x*10;
2555   conv[0]=(xx>=0)?'+':'-';
2556   xx=abs(xx);
2557   conv[1]=(xx/1000)%10+'0';
2558   conv[2]=(xx/100)%10+'0';
2559   conv[3]=(xx/10)%10+'0';
2560   conv[4]='.';
2561   conv[5]=(xx)%10+'0';
2562   conv[6]=0;
2563   return conv;
2564 }
2565
2566 char *ftostr32(const float &x)
2567 {
2568   int xx=x*100;
2569   conv[0]=(xx>=0)?'+':'-';
2570   xx=abs(xx);
2571   conv[1]=(xx/100)%10+'0';
2572   conv[2]='.';
2573   conv[3]=(xx/10)%10+'0';
2574   conv[4]=(xx)%10+'0';
2575   conv[6]=0;
2576   return conv;
2577 }
2578
2579 char *itostr31(const int &xx)
2580 {
2581   conv[0]=(xx>=0)?'+':'-';
2582   conv[1]=(xx/1000)%10+'0';
2583   conv[2]=(xx/100)%10+'0';
2584   conv[3]=(xx/10)%10+'0';
2585   conv[4]='.';
2586   conv[5]=(xx)%10+'0';
2587   conv[6]=0;
2588   return conv;
2589 }
2590
2591 char *itostr3(const int &xx)
2592 {
2593   conv[0]=(xx/100)%10+'0';
2594   conv[1]=(xx/10)%10+'0';
2595   conv[2]=(xx)%10+'0';
2596   conv[3]=0;
2597   return conv;
2598 }
2599
2600 char *itostr4(const int &xx)
2601 {
2602   conv[0]=(xx/1000)%10+'0';
2603   conv[1]=(xx/100)%10+'0';
2604   conv[2]=(xx/10)%10+'0';
2605   conv[3]=(xx)%10+'0';
2606   conv[4]=0;
2607   return conv;
2608 }
2609
2610 //  convert float to string with +1234.5 format
2611 char *ftostr51(const float &x)
2612 {
2613   int xx=x*10;
2614   conv[0]=(xx>=0)?'+':'-';
2615   xx=abs(xx);
2616   conv[1]=(xx/10000)%10+'0';
2617   conv[2]=(xx/1000)%10+'0';
2618   conv[3]=(xx/100)%10+'0';
2619   conv[4]=(xx/10)%10+'0';
2620   conv[5]='.';
2621   conv[6]=(xx)%10+'0';
2622   conv[7]=0;
2623   return conv;
2624 }
2625
2626 //  convert float to string with +123.45 format
2627 char *ftostr52(const float &x)
2628 {
2629   int xx=x*100;
2630   conv[0]=(xx>=0)?'+':'-';
2631   xx=abs(xx);
2632   conv[1]=(xx/10000)%10+'0';
2633   conv[2]=(xx/1000)%10+'0';
2634   conv[3]=(xx/100)%10+'0';
2635   conv[4]='.';
2636   conv[5]=(xx/10)%10+'0';
2637   conv[6]=(xx)%10+'0';
2638   conv[7]=0;
2639   return conv;
2640 }
2641
2642 #endif //ULTRA_LCD
2643
2644