chiark / gitweb /
made ultralcd compatible with folders.
authorBernhard Kubicek <kubicek@gmx.at>
Sun, 20 Nov 2011 13:43:47 +0000 (14:43 +0100)
committerBernhard Kubicek <kubicek@gmx.at>
Sun, 20 Nov 2011 13:43:47 +0000 (14:43 +0100)
Marlin/cardreader.h
Marlin/cardreader.pde
Marlin/ultralcd.h
Marlin/ultralcd.pde

index 653f59452e36d652dd8d2b093dd0610d602fdba7..44ebf0e2c1f4a014c62411b562cf6f0414ff9c34 100644 (file)
@@ -28,7 +28,8 @@ public:
   
 
   void ls();
-  
+  void chdir(const char * relpath);
+  void updir();
 
   inline bool eof() { return sdpos>=filesize ;};
   inline int16_t get() {  sdpos = file.curPosition();return (int16_t)file.read();};
@@ -40,8 +41,9 @@ public:
   bool sdprinting ;  
   bool cardOK ;
   char filename[11];
+  bool filenameIsDir;
 private:
-  SdFile root,*curDir;
+  SdFile root,*curDir,workDir,workDirParent,workDirParentParent;
   Sd2Card card;
   SdVolume volume;
   SdFile file;
index bab87834ec65d16b893fd6d328260ace383e1865..c0dbc58e475eb5827f3f6c59afd9ceece415bfd1 100644 (file)
@@ -1,4 +1,5 @@
 #include "cardreader.h"
+//#include <unistd.h>
 #ifdef SDSUPPORT
 
 CardReader::CardReader()
@@ -36,11 +37,7 @@ char *createFilename(char *buffer,const dir_t &p) //buffer>12characters
   return buffer;
 }
 
-// bool SdFat::chdir(bool set_cwd) {
-//   if (set_cwd) SdBaseFile::cwd_ = &vwd_;
-//   vwd_.close();
-//   return vwd_.openRoot(&vol_);
-// }
+
 void  CardReader::lsDive(char *prepend,SdFile parent)
 {
   dir_t p;
@@ -85,11 +82,19 @@ void  CardReader::lsDive(char *prepend,SdFile parent)
     {
       if (p.name[0] == DIR_NAME_FREE) break;
       if (p.name[0] == DIR_NAME_DELETED || p.name[0] == '.'|| p.name[0] == '_') continue;
+      if ( p.name[0] == '.')
+      {
+        if ( p.name[1] != '.')
+        continue;
+      }
       if (!DIR_IS_FILE_OR_SUBDIR(&p)) continue;
+      filenameIsDir=DIR_IS_SUBDIR(&p);
       
-      
-      if(p.name[8]!='G') continue;
-      if(p.name[9]=='~') continue;
+      if(!filenameIsDir)
+      {
+        if(p.name[8]!='G') continue;
+        if(p.name[9]=='~') continue;
+      }
       //if(cnt++!=nr) continue;
       createFilename(filename,p);
       if(lsAction==LS_SerialPrint)
@@ -126,33 +131,35 @@ void CardReader::ls()
 void CardReader::initsd()
 {
   cardOK = false;
-  #if SDSS >- 1
-    if(root.isOpen())
-      root.close();
-    if (!card.init(SPI_FULL_SPEED,SDSS))
-    {
-      //if (!card.init(SPI_HALF_SPEED,SDSS))
-      SERIAL_ECHO_START;
-      SERIAL_ECHOLNPGM("SD init fail");
-    }
-    else if (!volume.init(&card))
-    {
-      SERIAL_ERROR_START;
-      SERIAL_ERRORLNPGM("volume.init failed");
-    }
-    else if (!root.openRoot(&volume)) 
-    {
-      SERIAL_ERROR_START;
-      SERIAL_ERRORLNPGM("openRoot failed");
-    }
-    else 
-    {
-      cardOK = true;
-      SERIAL_ECHO_START;
-      SERIAL_ECHOLNPGM("SD card ok");
-    }
-    curDir=&root;
-  #endif //SDSS
+  if(root.isOpen())
+    root.close();
+  if (!card.init(SPI_FULL_SPEED,SDSS))
+  {
+    //if (!card.init(SPI_HALF_SPEED,SDSS))
+    SERIAL_ECHO_START;
+    SERIAL_ECHOLNPGM("SD init fail");
+  }
+  else if (!volume.init(&card))
+  {
+    SERIAL_ERROR_START;
+    SERIAL_ERRORLNPGM("volume.init failed");
+  }
+  else if (!root.openRoot(&volume)) 
+  {
+    SERIAL_ERROR_START;
+    SERIAL_ERRORLNPGM("openRoot failed");
+  }
+  else 
+  {
+    cardOK = true;
+    SERIAL_ECHO_START;
+    SERIAL_ECHOLNPGM("SD card ok");
+  }
+  curDir=&root;
+  if(!workDir.openRoot(&volume))
+  {
+    SERIAL_ECHOLNPGM("workDir open failed");
+  }
 }
 void CardReader::release()
 {
@@ -229,6 +236,10 @@ void CardReader::openFile(char* name,bool read)
       
     }
   }
+  else //relative path
+  {
+    curDir=&workDir;
+  }
   if(read)
   {
     if (file.open(curDir, fname, O_READ)) 
@@ -362,6 +373,7 @@ void CardReader::closefile()
 
 void CardReader::getfilename(const uint8_t nr)
 {
+  curDir=&workDir;
   lsAction=LS_GetFilename;
   nrFiles=nr;
   curDir->rewind();
@@ -371,12 +383,45 @@ void CardReader::getfilename(const uint8_t nr)
 
 uint16_t CardReader::getnrfilenames()
 {
+  curDir=&workDir;
   lsAction=LS_Count;
   nrFiles=0;
   curDir->rewind();
   lsDive("",*curDir);
+  //SERIAL_ECHOLN(nrFiles);
   return nrFiles;
 }
 
+void CardReader::chdir(const char * relpath)
+{
+  SdFile newfile;
+  SdFile *parent=&root;
+  
+  if(workDir.isOpen())
+    parent=&workDir;
+  
+  if(!newfile.open(*parent,relpath, O_READ))
+  {
+   SERIAL_ECHO_START;
+   SERIAL_ECHOPGM("Cannot enter subdir:");
+   SERIAL_ECHOLN(relpath);
+  }
+  else
+  {
+    workDirParentParent=workDirParent;
+    workDirParent=*parent;
+    
+    workDir=newfile;
+  }
+}
+
+void CardReader::updir()
+{
+  if(!workDir.isRoot())
+  {
+    workDir=workDirParent;
+    workDirParent=workDirParentParent;
+  }
+}
 
 #endif //SDSUPPORT
\ No newline at end of file
index d3496bec9808b0e17544e9b2c1f2a644f1457ecd..6222c70c2575c6b926c42eb3307d9da8caee69ab 100644 (file)
   #define blocktime 500
   #define lcdslow 5
     
-  enum MainStatus{Main_Status, Main_Menu, Main_Prepare, Main_Control, Main_SD};
+  enum MainStatus{Main_Status, Main_Menu, Main_Prepare, Main_Control, Main_SD,Sub_TempControl,Sub_MotionControl};
 
   class MainMenu{
   public:
     MainMenu();
     void update();
-    uint8_t activeline;
+    int8_t activeline;
     MainStatus status;
     uint8_t displayStartingRow;
     
@@ -65,6 +65,8 @@
     void showMainMenu();
     void showPrepare();
     void showControl();
+    void showControlMotion();
+    void showControlTemp();
     void showSD();
     bool force_lcd_update;
     int lastencoderpos;
index aa30a3dd0e7fa7d3e8ba4e9d70f47ec392540339..57f63c1061de041035fc67b25fe628d9e089c01d 100644 (file)
@@ -114,11 +114,13 @@ void lcd_init()
   };\r
   byte uplevel[8]={0x04, 0x0e, 0x1f, 0x04, 0x1c, 0x00, 0x00, 0x00};//thanks joris\r
   byte refresh[8]={0x00, 0x06, 0x19, 0x18, 0x03, 0x13, 0x0c, 0x00}; //thanks joris\r
+  byte folder [8]={0x00, 0x1c, 0x1f, 0x11, 0x11, 0x1f, 0x00, 0x00}; //thanks joris\r
   lcd.begin(LCD_WIDTH, LCD_HEIGHT);\r
   lcd.createChar(1,Degree);\r
   lcd.createChar(2,Thermometer);\r
   lcd.createChar(3,uplevel);\r
   lcd.createChar(4,refresh);\r
+  lcd.createChar(5,folder);\r
   LCD_MESSAGEPGM("UltiMarlin ready.");\r
 }\r
 \r
@@ -224,6 +226,7 @@ void buttons_check()
     buttons=~newbutton; //invert it, because a pressed switch produces a logical 0\r
   #endif\r
   \r
+  //manage encoder rotation\r
   char enc=0;\r
   if(buttons&EN_A)\r
     enc|=(1<<0);\r
@@ -311,22 +314,22 @@ void MainMenu::showStatus()
     oldtargetHotEnd0=ttHotEnd0;\r
   }\r
   #if defined BED_USES_THERMISTOR || defined BED_USES_AD595 \r
-  static int oldtBed=-1;\r
-  static int oldtargetBed=-1; \r
-  int tBed=intround(degBed());\r
-  if((tBed!=oldtBed)||force_lcd_update)\r
-  {\r
-    lcd.setCursor(1,0);\r
-    lcd.print(ftostr3(tBed));\r
-    olddegHotEnd0=tBed;\r
-  }\r
-  int targetBed=intround(degTargetBed());\r
-  if((targetBed!=oldtargetBed)||force_lcd_update)\r
-  {\r
-    lcd.setCursor(5,0);\r
-    lcd.print(ftostr3(targetBed));\r
-    oldtargetBed=targetBed;\r
-  }\r
+    static int oldtBed=-1;\r
+    static int oldtargetBed=-1; \r
+    int tBed=intround(degBed());\r
+    if((tBed!=oldtBed)||force_lcd_update)\r
+    {\r
+      lcd.setCursor(1,0);\r
+      lcd.print(ftostr3(tBed));\r
+      oldtBed=tBed;\r
+    }\r
+    int targetBed=intround(degTargetBed());\r
+    if((targetBed!=oldtargetBed)||force_lcd_update)\r
+    {\r
+      lcd.setCursor(5,0);\r
+      lcd.print(ftostr3(targetBed));\r
+      oldtargetBed=targetBed;\r
+    }\r
   #endif\r
   //starttime=2;\r
   static uint16_t oldtime=0;\r
@@ -421,6 +424,7 @@ void MainMenu::showStatus()
   }\r
 \r
 #endif\r
+  force_lcd_update=false;\r
 }\r
 \r
 enum {ItemP_exit, ItemP_home, ItemP_origin, ItemP_preheat, ItemP_extrude, ItemP_disstep};\r
@@ -466,16 +470,7 @@ void MainMenu::showPrepare()
  }\r
  updateActiveLines(ItemP_disstep,encoderpos);\r
 }\r
-enum {\r
-  ItemC_exit, ItemC_nozzle, \r
-  ItemC_PID_P,ItemC_PID_I,ItemC_PID_D,ItemC_PID_C,\r
-  ItemC_fan, \r
-  ItemC_acc, ItemC_xyjerk, \r
-  ItemC_vmaxx, ItemC_vmaxy, ItemC_vmaxz, ItemC_vmaxe, \r
-  ItemC_vtravmin,ItemC_vmin,  \r
-  ItemC_amaxx, ItemC_amaxy, ItemC_amaxz, ItemC_amaxe, \r
-  ItemC_aret,ItemC_esteps, ItemC_store, ItemC_load,ItemC_failsafe\r
-};\r
+\r
 \r
 //does not work\r
 // #define MENUCHANGEITEM(repaint_action,  enter_action, accept_action,  change_action) \\r
@@ -494,19 +489,23 @@ enum {
 //   }\r
 //   \r
 \r
-  \r
-void MainMenu::showControl()\r
+enum {\r
+  ItemCT_exit, ItemCT_nozzle, ItemCT_fan,\r
+  ItemCT_PID_P,ItemCT_PID_I,ItemCT_PID_D,ItemCT_PID_C\r
+};\r
+\r
+void MainMenu::showControlTemp()\r
 {\r
- uint8_t line=0;\r
 uint8_t line=0;\r
  clearIfNecessary();\r
  for(int8_t i=lineoffset;i<lineoffset+LCD_HEIGHT;i++)\r
  {\r
   switch(i)\r
   {\r
-    case ItemC_exit:\r
-      MENUITEM(  lcdprintPGM(" Control")  ,  BLOCK;status=Main_Menu;beepshort(); ) ;\r
+    case ItemCT_exit:\r
+      MENUITEM(  lcdprintPGM(" Temperature")  ,  BLOCK;status=Main_Control;beepshort(); ) ;\r
       break;\r
-    case ItemC_nozzle:\r
+    case ItemCT_nozzle:\r
       {\r
         if(force_lcd_update)\r
         {\r
@@ -540,7 +539,7 @@ void MainMenu::showControl()
         }\r
       }break;\r
       \r
-      case ItemC_fan:\r
+      case ItemCT_fan:\r
       {\r
         if(force_lcd_update)\r
         {\r
@@ -577,12 +576,12 @@ void MainMenu::showControl()
           }\r
         }\r
       }break;\r
-    case ItemC_acc:\r
-    {\r
+      case ItemCT_PID_P: \r
+      {\r
       if(force_lcd_update)\r
         {\r
-          lcd.setCursor(0,line);lcdprintPGM(" Acc:");\r
-          lcd.setCursor(13,line);lcd.print(itostr3(acceleration/100));lcdprintPGM("00");\r
+          lcd.setCursor(0,line);lcdprintPGM(" PID-P: ");\r
+          lcd.setCursor(13,line);lcd.print(itostr4(Kp));\r
         }\r
         \r
         if((activeline==line) )\r
@@ -592,30 +591,31 @@ void MainMenu::showControl()
             linechanging=!linechanging;\r
             if(linechanging)\r
             {\r
-               encoderpos=(int)acceleration/100;\r
+               encoderpos=(int)Kp/5;\r
             }\r
             else\r
             {\r
-              acceleration= encoderpos*100;\r
+              Kp= encoderpos*5;\r
               encoderpos=activeline*lcdslow;\r
+                \r
             }\r
             BLOCK;\r
             beepshort();\r
           }\r
           if(linechanging)\r
           {\r
-            if(encoderpos<5) encoderpos=5;\r
-            if(encoderpos>990) encoderpos=990;\r
-            lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));lcdprintPGM("00");\r
+            if(encoderpos<1) encoderpos=1;\r
+            if(encoderpos>9990/5) encoderpos=9990/5;\r
+            lcd.setCursor(13,line);lcd.print(itostr4(encoderpos*5));\r
           }\r
         }\r
       }break;\r
-    case ItemC_xyjerk: //max_xy_jerk\r
+    case ItemCT_PID_I: \r
       {\r
       if(force_lcd_update)\r
         {\r
-          lcd.setCursor(0,line);lcdprintPGM(" Vxy-jerk: ");\r
-          lcd.setCursor(13,line);lcd.print(itostr3(max_xy_jerk));\r
+          lcd.setCursor(0,line);lcdprintPGM(" PID-I: ");\r
+          lcd.setCursor(13,line);lcd.print(ftostr51(Ki));\r
         }\r
         \r
         if((activeline==line) )\r
@@ -625,11 +625,11 @@ void MainMenu::showControl()
             linechanging=!linechanging;\r
             if(linechanging)\r
             {\r
-               encoderpos=(int)max_xy_jerk;\r
+               encoderpos=(int)(Ki*10);\r
             }\r
             else\r
             {\r
-              max_xy_jerk= encoderpos;\r
+              Ki= encoderpos/10.;\r
               encoderpos=activeline*lcdslow;\r
                 \r
             }\r
@@ -638,18 +638,18 @@ void MainMenu::showControl()
           }\r
           if(linechanging)\r
           {\r
-            if(encoderpos<1) encoderpos=1;\r
-            if(encoderpos>990) encoderpos=990;\r
-            lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));\r
+            if(encoderpos<0) encoderpos=0;\r
+            if(encoderpos>9990) encoderpos=9990;\r
+            lcd.setCursor(13,line);lcd.print(ftostr51(encoderpos/10.));\r
           }\r
         }\r
       }break;\r
-      case ItemC_PID_P\r
+      case ItemCT_PID_D\r
       {\r
       if(force_lcd_update)\r
         {\r
-          lcd.setCursor(0,line);lcdprintPGM(" PID-P: ");\r
-          lcd.setCursor(13,line);lcd.print(itostr4(Kp));\r
+          lcd.setCursor(0,line);lcdprintPGM(" PID-D: ");\r
+          lcd.setCursor(13,line);lcd.print(itostr4(Kd));\r
         }\r
         \r
         if((activeline==line) )\r
@@ -659,11 +659,11 @@ void MainMenu::showControl()
             linechanging=!linechanging;\r
             if(linechanging)\r
             {\r
-               encoderpos=(int)Kp/5;\r
+               encoderpos=(int)Kd/5;\r
             }\r
             else\r
             {\r
-              Kp= encoderpos*5;\r
+              Kd= encoderpos*5;\r
               encoderpos=activeline*lcdslow;\r
                 \r
             }\r
@@ -672,18 +672,19 @@ void MainMenu::showControl()
           }\r
           if(linechanging)\r
           {\r
-            if(encoderpos<1) encoderpos=1;\r
+            if(encoderpos<0) encoderpos=0;\r
             if(encoderpos>9990/5) encoderpos=9990/5;\r
             lcd.setCursor(13,line);lcd.print(itostr4(encoderpos*5));\r
           }\r
         }\r
-      }break;\r
-    case ItemC_PID_I: \r
+      }break;   \r
+    case ItemCT_PID_C: \r
+      #ifdef PID_ADD_EXTRUSION_RATE\r
       {\r
       if(force_lcd_update)\r
         {\r
-          lcd.setCursor(0,line);lcdprintPGM(" PID-I: ");\r
-          lcd.setCursor(13,line);lcd.print(ftostr51(Ki));\r
+          lcd.setCursor(0,line);lcdprintPGM(" PID-C: ");\r
+          lcd.setCursor(13,line);lcd.print(itostr3(Kc));\r
         }\r
         \r
         if((activeline==line) )\r
@@ -693,11 +694,11 @@ void MainMenu::showControl()
             linechanging=!linechanging;\r
             if(linechanging)\r
             {\r
-               encoderpos=(int)(Ki*10);\r
+               encoderpos=(int)Kc;\r
             }\r
             else\r
             {\r
-              Ki= encoderpos/10.;\r
+              Kc= encoderpos;\r
               encoderpos=activeline*lcdslow;\r
                 \r
             }\r
@@ -707,17 +708,54 @@ void MainMenu::showControl()
           if(linechanging)\r
           {\r
             if(encoderpos<0) encoderpos=0;\r
-            if(encoderpos>9990) encoderpos=9990;\r
-            lcd.setCursor(13,line);lcd.print(ftostr51(encoderpos/10.));\r
+            if(encoderpos>990) encoderpos=990;\r
+            lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));\r
           }\r
         }\r
-      }break;\r
-      case ItemC_PID_D: \r
-      {\r
+      }\r
+      #endif\r
+      break;\r
+    default:   \r
+      break;\r
+  }\r
+  line++;\r
+ }\r
+ #ifdef PID_ADD_EXTRUSION_RATE\r
+  updateActiveLines(ItemCT_PID_C,encoderpos);\r
+ #else\r
+  updateActiveLines(ItemCT_PID_D,encoderpos);\r
+ #endif\r
+}\r
+\r
+\r
+enum {\r
+  ItemCM_exit, \r
+  ItemCM_acc, ItemCM_xyjerk, \r
+  ItemCM_vmaxx, ItemCM_vmaxy, ItemCM_vmaxz, ItemCM_vmaxe, \r
+  ItemCM_vtravmin,ItemCM_vmin,  \r
+  ItemCM_amaxx, ItemCM_amaxy, ItemCM_amaxz, ItemCM_amaxe, \r
+  ItemCM_aret,ItemCM_esteps\r
+};\r
+\r
+\r
+\r
+void MainMenu::showControlMotion()\r
+{\r
+ uint8_t line=0;\r
+ clearIfNecessary();\r
+ for(int8_t i=lineoffset;i<lineoffset+LCD_HEIGHT;i++)\r
+ {\r
+  switch(i)\r
+  {\r
+    case ItemCM_exit:\r
+      MENUITEM(  lcdprintPGM(" Motion")  ,  BLOCK;status=Main_Control;beepshort(); ) ;\r
+      break;\r
+    case ItemCM_acc:\r
+    {\r
       if(force_lcd_update)\r
         {\r
-          lcd.setCursor(0,line);lcdprintPGM(" PID-D: ");\r
-          lcd.setCursor(13,line);lcd.print(itostr4(Kd));\r
+          lcd.setCursor(0,line);lcdprintPGM(" Acc:");\r
+          lcd.setCursor(13,line);lcd.print(itostr3(acceleration/100));lcdprintPGM("00");\r
         }\r
         \r
         if((activeline==line) )\r
@@ -727,34 +765,30 @@ void MainMenu::showControl()
             linechanging=!linechanging;\r
             if(linechanging)\r
             {\r
-               encoderpos=(int)Kd/5;\r
+               encoderpos=(int)acceleration/100;\r
             }\r
             else\r
             {\r
-              Kd= encoderpos*5;\r
+              acceleration= encoderpos*100;\r
               encoderpos=activeline*lcdslow;\r
-                \r
             }\r
             BLOCK;\r
             beepshort();\r
           }\r
           if(linechanging)\r
           {\r
-            if(encoderpos<0) encoderpos=0;\r
-            if(encoderpos>9990/5) encoderpos=9990/5;\r
-            lcd.setCursor(13,line);lcd.print(itostr4(encoderpos*5));\r
+            if(encoderpos<5) encoderpos=5;\r
+            if(encoderpos>990) encoderpos=990;\r
+            lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));lcdprintPGM("00");\r
           }\r
         }\r
       }break;\r
-    \r
-    \r
-      \r
-    case ItemC_PID_C: \r
+    case ItemCM_xyjerk: //max_xy_jerk\r
       {\r
       if(force_lcd_update)\r
         {\r
-          lcd.setCursor(0,line);lcdprintPGM(" PID-C: ");\r
-          lcd.setCursor(13,line);lcd.print(itostr3(Kc));\r
+          lcd.setCursor(0,line);lcdprintPGM(" Vxy-jerk: ");\r
+          lcd.setCursor(13,line);lcd.print(itostr3(max_xy_jerk));\r
         }\r
         \r
         if((activeline==line) )\r
@@ -764,11 +798,11 @@ void MainMenu::showControl()
             linechanging=!linechanging;\r
             if(linechanging)\r
             {\r
-               encoderpos=(int)Kc;\r
+               encoderpos=(int)max_xy_jerk;\r
             }\r
             else\r
             {\r
-              Kc= encoderpos;\r
+              max_xy_jerk= encoderpos;\r
               encoderpos=activeline*lcdslow;\r
                 \r
             }\r
@@ -777,25 +811,26 @@ void MainMenu::showControl()
           }\r
           if(linechanging)\r
           {\r
-            if(encoderpos<0) encoderpos=0;\r
+            if(encoderpos<1) encoderpos=1;\r
             if(encoderpos>990) encoderpos=990;\r
             lcd.setCursor(13,line);lcd.print(itostr3(encoderpos));\r
           }\r
         }\r
       }break;\r
-    case ItemC_vmaxx:\r
-    case ItemC_vmaxy:\r
-    case ItemC_vmaxz:\r
-    case ItemC_vmaxe:\r
+      \r
+    case ItemCM_vmaxx:\r
+    case ItemCM_vmaxy:\r
+    case ItemCM_vmaxz:\r
+    case ItemCM_vmaxe:\r
       {\r
       if(force_lcd_update)\r
         {\r
           lcd.setCursor(0,line);lcdprintPGM(" Vmax ");\r
-          if(i==ItemC_vmaxx)lcdprintPGM("x:");\r
-          if(i==ItemC_vmaxy)lcdprintPGM("y:");\r
-          if(i==ItemC_vmaxz)lcdprintPGM("z:");\r
-          if(i==ItemC_vmaxe)lcdprintPGM("e:");\r
-          lcd.setCursor(13,line);lcd.print(itostr3(max_feedrate[i-ItemC_vmaxx]));\r
+          if(i==ItemCM_vmaxx)lcdprintPGM("x:");\r
+          if(i==ItemCM_vmaxy)lcdprintPGM("y:");\r
+          if(i==ItemCM_vmaxz)lcdprintPGM("z:");\r
+          if(i==ItemCM_vmaxe)lcdprintPGM("e:");\r
+          lcd.setCursor(13,line);lcd.print(itostr3(max_feedrate[i-ItemCM_vmaxx]));\r
         }\r
         \r
         if((activeline==line) )\r
@@ -805,11 +840,11 @@ void MainMenu::showControl()
             linechanging=!linechanging;\r
             if(linechanging)\r
             {\r
-               encoderpos=(int)max_feedrate[i-ItemC_vmaxx];\r
+               encoderpos=(int)max_feedrate[i-ItemCM_vmaxx];\r
             }\r
             else\r
             {\r
-              max_feedrate[i-ItemC_vmaxx]= encoderpos;\r
+              max_feedrate[i-ItemCM_vmaxx]= encoderpos;\r
               encoderpos=activeline*lcdslow;\r
                 \r
             }\r
@@ -825,7 +860,7 @@ void MainMenu::showControl()
         }\r
       }break;\r
     \r
-    case ItemC_vmin:\r
+    case ItemCM_vmin:\r
     {\r
       if(force_lcd_update)\r
         {\r
@@ -859,7 +894,7 @@ void MainMenu::showControl()
           }\r
         }\r
       }break;\r
-    case ItemC_vtravmin:\r
+    case ItemCM_vtravmin:\r
     {\r
       if(force_lcd_update)\r
         {\r
@@ -894,19 +929,19 @@ void MainMenu::showControl()
         }\r
       }break;\r
     \r
-    case ItemC_amaxx:      \r
-    case ItemC_amaxy:\r
-    case ItemC_amaxz:\r
-    case ItemC_amaxe:\r
+    case ItemCM_amaxx:      \r
+    case ItemCM_amaxy:\r
+    case ItemCM_amaxz:\r
+    case ItemCM_amaxe:\r
     {\r
       if(force_lcd_update)\r
         {\r
           lcd.setCursor(0,line);lcdprintPGM(" Amax ");\r
-          if(i==ItemC_amaxx)lcdprintPGM("x:");\r
-          if(i==ItemC_amaxy)lcdprintPGM("y:");\r
-          if(i==ItemC_amaxz)lcdprintPGM("z:");\r
-          if(i==ItemC_amaxe)lcdprintPGM("e:");\r
-          lcd.setCursor(13,line);lcd.print(itostr3(max_acceleration_units_per_sq_second[i-ItemC_amaxx]/100));lcdprintPGM("00");\r
+          if(i==ItemCM_amaxx)lcdprintPGM("x:");\r
+          if(i==ItemCM_amaxy)lcdprintPGM("y:");\r
+          if(i==ItemCM_amaxz)lcdprintPGM("z:");\r
+          if(i==ItemCM_amaxe)lcdprintPGM("e:");\r
+          lcd.setCursor(13,line);lcd.print(itostr3(max_acceleration_units_per_sq_second[i-ItemCM_amaxx]/100));lcdprintPGM("00");\r
         }\r
         \r
         if((activeline==line) )\r
@@ -916,11 +951,11 @@ void MainMenu::showControl()
             linechanging=!linechanging;\r
             if(linechanging)\r
             {\r
-               encoderpos=(int)max_acceleration_units_per_sq_second[i-ItemC_amaxx]/100;\r
+               encoderpos=(int)max_acceleration_units_per_sq_second[i-ItemCM_amaxx]/100;\r
             }\r
             else\r
             {\r
-              max_acceleration_units_per_sq_second[i-ItemC_amaxx]= encoderpos*100;\r
+              max_acceleration_units_per_sq_second[i-ItemCM_amaxx]= encoderpos*100;\r
               encoderpos=activeline*lcdslow;\r
             }\r
             BLOCK;\r
@@ -934,7 +969,7 @@ void MainMenu::showControl()
           }\r
         }\r
       }break;\r
-    case ItemC_aret://float retract_acceleration = 7000;\r
+    case ItemCM_aret://float retract_acceleration = 7000;\r
     {\r
         if(force_lcd_update)\r
         {\r
@@ -968,7 +1003,7 @@ void MainMenu::showControl()
           }\r
         }\r
       }break;\r
-    case ItemC_esteps://axis_steps_per_unit[i] = code_value();\r
+    case ItemCM_esteps://axis_steps_per_unit[i] = code_value();\r
          {\r
       if(force_lcd_update)\r
         {\r
@@ -1005,6 +1040,37 @@ void MainMenu::showControl()
           }\r
         }\r
       }break; \r
+    default:   \r
+      break;\r
+  }\r
+  line++;\r
+ }\r
+ updateActiveLines(ItemCM_esteps,encoderpos);\r
+}\r
+\r
+\r
+enum {\r
+  ItemC_exit,ItemC_temp,ItemC_move,\r
+  ItemC_store, ItemC_load,ItemC_failsafe\r
+};\r
+\r
+void MainMenu::showControl()\r
+{\r
+ uint8_t line=0;\r
+ clearIfNecessary();\r
+ for(int8_t i=lineoffset;i<lineoffset+LCD_HEIGHT;i++)\r
+ {\r
+  switch(i)\r
+  {\r
+    case ItemC_exit:\r
+      MENUITEM(  lcdprintPGM(" Control     \x7E")  ,  BLOCK;status=Main_Menu;beepshort(); ) ;\r
+      break;\r
+    case ItemC_temp:\r
+      MENUITEM(  lcdprintPGM(" Temperature \x7E")  ,  BLOCK;status=Sub_TempControl;beepshort(); ) ;\r
+      break;\r
+   case ItemC_move:\r
+      MENUITEM(  lcdprintPGM(" Motion      \x7E")  ,  BLOCK;status=Sub_MotionControl;beepshort(); ) ;\r
+      break;\r
     case ItemC_store:\r
     {\r
       if(force_lcd_update)\r
@@ -1059,7 +1125,6 @@ void MainMenu::showControl()
 \r
 \r
 \r
-\r
 void MainMenu::showSD()\r
 {\r
 #ifdef SDSUPPORT\r
@@ -1069,7 +1134,6 @@ void MainMenu::showSD()
  static uint8_t nrfiles=0;\r
  if(force_lcd_update)\r
  {\r
-  clear();\r
   if(card.cardOK)\r
   {\r
     nrfiles=card.getnrfilenames();\r
@@ -1080,7 +1144,7 @@ void MainMenu::showSD()
     lineoffset=0;\r
   }\r
  }\r
\r
+ bool enforceupdate=false;\r
  for(int8_t i=lineoffset;i<lineoffset+LCD_HEIGHT;i++)\r
  {\r
   switch(i)\r
@@ -1088,58 +1152,76 @@ void MainMenu::showSD()
     case 0:\r
       MENUITEM(  lcdprintPGM(" File")  ,  BLOCK;status=Main_Menu;beepshort(); ) ;\r
       break;\r
+//     case 1:\r
+//       {\r
+//         if(force_lcd_update)\r
+//         {\r
+//           lcd.setCursor(0,line);\r
+//            #ifdef CARDINSERTED\r
+//           if(CARDINSERTED)\r
+//           #else\r
+//           if(true)\r
+//           #endif\r
+//           {\r
+//             lcdprintPGM(" \004Refresh");\r
+//           }\r
+//           else\r
+//           {\r
+//             lcdprintPGM(" \004Insert Card");\r
+//           }\r
+//           \r
+//         }\r
+//         if((activeline==line) && CLICKED)\r
+//         {\r
+//           BLOCK;\r
+//           beepshort();\r
+//           card.initsd();\r
+//           force_lcd_update=true;\r
+//            nrfiles=card.getnrfilenames();\r
+//         }\r
+//       }break;\r
     case 1:\r
-      {\r
-        if(force_lcd_update)\r
-        {\r
-          lcd.setCursor(0,line);\r
-           #ifdef CARDINSERTED\r
-          if(CARDINSERTED)\r
-          #else\r
-          if(true)\r
-          #endif\r
-          {\r
-            lcdprintPGM(" \004Refresh");\r
-          }\r
-          else\r
-          {\r
-            lcdprintPGM(" \004Insert Card");\r
-          }\r
-          \r
-        }\r
-        if((activeline==line) && CLICKED)\r
-        {\r
-          BLOCK;\r
-          beepshort();\r
-          card.initsd();\r
-          force_lcd_update=true;\r
-           nrfiles=card.getnrfilenames();\r
-        }\r
-      }break;\r
+      MENUITEM(  lcdprintPGM(" ..")  ,  BLOCK;card.updir();enforceupdate=true;lineoffset=0;beepshort(); ) ;\r
+      \r
+      break;\r
     default:\r
     {\r
-      if(i-2<nrfiles)\r
+      #define FIRSTITEM 2\r
+      if(i-FIRSTITEM<nrfiles)\r
       {\r
         if(force_lcd_update)\r
         {\r
-          card.getfilename(i-2);\r
+          card.getfilename(i-FIRSTITEM);\r
           //Serial.print("Filenr:");Serial.println(i-2);\r
-          lcd.setCursor(0,line);lcdprintPGM(" ");lcd.print(card.filename);\r
+          lcd.setCursor(0,line);lcdprintPGM(" ");\r
+          if(card.filenameIsDir) lcd.print("\005");\r
+          lcd.print(card.filename);\r
         }\r
         if((activeline==line) && CLICKED)\r
         {\r
           BLOCK\r
-          card.getfilename(i-2);\r
-          char cmd[30];\r
-          for(int8_t i=0;i<strlen(card.filename);i++)\r
-            card.filename[i]=tolower(card.filename[i]);\r
-          sprintf(cmd,"M23 %s",card.filename);\r
-          //sprintf(cmd,"M115");\r
-          enquecommand(cmd);\r
-          enquecommand("M24");\r
-          beep(); \r
-          status=Main_Status;\r
-          lcd_status(card.filename);\r
+          card.getfilename(i-FIRSTITEM);\r
+          if(card.filenameIsDir)\r
+          {\r
+            for(int8_t i=0;i<strlen(card.filename);i++)\r
+              card.filename[i]=tolower(card.filename[i]);\r
+            card.chdir(card.filename);\r
+            lineoffset=0;\r
+            enforceupdate=true;\r
+          }\r
+          else\r
+          {\r
+            char cmd[30];\r
+            for(int8_t i=0;i<strlen(card.filename);i++)\r
+              card.filename[i]=tolower(card.filename[i]);\r
+            sprintf(cmd,"M23 %s",card.filename);\r
+            //sprintf(cmd,"M115");\r
+            enquecommand(cmd);\r
+            enquecommand("M24");\r
+            beep(); \r
+            status=Main_Status;\r
+            lcd_status(card.filename);\r
+          }\r
         }\r
       }\r
       \r
@@ -1148,7 +1230,12 @@ void MainMenu::showSD()
   }\r
   line++;\r
  }\r
- updateActiveLines(1+nrfiles,encoderpos);\r
+ updateActiveLines(FIRSTITEM+nrfiles-1,encoderpos);\r
+ if(enforceupdate)\r
+ {\r
+   force_lcd_update=true;\r
+   enforceupdate=false;\r
+ }\r
 #endif\r
 }\r
 \r
@@ -1282,6 +1369,14 @@ void MainMenu::update()
       {\r
         showControl(); \r
       }break;\r
+      case Sub_MotionControl:\r
+      {\r
+        showControlMotion(); \r
+      }break;\r
+      case Sub_TempControl:\r
+      {\r
+        showControlTemp(); \r
+      }break;\r
       case Main_SD: \r
       {\r
         showSD();\r
@@ -1290,7 +1385,7 @@ void MainMenu::update()
   \r
   if(timeoutToStatus<millis())\r
     status=Main_Status;\r
-  force_lcd_update=false;\r
+  //force_lcd_update=false;\r
   lastencoderpos=encoderpos;\r
 }\r
 \r