Marlinを改造して残り時間を表示させたい

2016-10-18 20:22:31   #3DPrinter  #flyingbear  #Marlin-Firmware 
ETE.jpg

同じことを考えている人はいる。
Display time remaining on the LCD screen ?

SDカードの読み取り状況と現状の印刷時間から逆算する方針なら情報は出揃っているから簡単でした。

実装結果

Marlinのコードはこちらにあります。 flyingbearP902用の設定になっています https://github.com/m0a/flyingbearMarlin/archive/lcd_kai.zip

実際のところSDカードの進捗は正確ではなくコレを元に印刷時間を表示するとあまり正確な値にならない。
ただ後半90%以上進行するとまぁまぁ正確にはなる(当たり前か)

M73というGCODEをMarlinに実装すると正確になるかもしれない。

変更内容

ちょっとテスト的に弄ったものも含まれています。
あと中華ArduinoだったせいかBAUDRATEも25000では上手く動かず115200に変更しています

diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index ad869b7..a730543 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -113,7 +113,7 @@
 
 // This determines the communication speed of the printer
 // :[2400,9600,19200,38400,57600,115200,250000]
-#define BAUDRATE 250000
+#define BAUDRATE 115200
 
 // Enable the Bluetooth serial interface on AT90USB devices
 //#define BLUETOOTH
@@ -126,7 +126,7 @@
 
 // Optional custom name for your RepStrap or other custom machine
 // Displayed in the LCD "Ready" message
-//#define CUSTOM_MACHINE_NAME "3D Printer"
+#define CUSTOM_MACHINE_NAME "Flyingbear"
 
 // Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines)
 // You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4)
@@ -229,7 +229,7 @@
 #define TEMP_SENSOR_1 0
 #define TEMP_SENSOR_2 0
 #define TEMP_SENSOR_3 0
-#define TEMP_SENSOR_BED 0
+#define TEMP_SENSOR_BED 1
 
 // This makes temp sensor 1 a redundant sensor for sensor 0. If the temperatures difference between these sensors is to high the print will be aborted.
 //#define TEMP_SENSOR_1_AS_REDUNDANT
@@ -419,13 +419,22 @@
   //#define ENDSTOPPULLUP_ZMIN_PROBE
 #endif
 
+#ifdef ENDSTOPPULLUPS
+  #define ENDSTOPPULLUP_XMAX
+  #define ENDSTOPPULLUP_YMAX
+  #define ENDSTOPPULLUP_ZMAX
+  #define ENDSTOPPULLUP_XMIN
+  #define ENDSTOPPULLUP_YMIN
+  #define ENDSTOPPULLUP_ZMIN
+#endif
+
 // Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup).
-#define X_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop.
-#define Y_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop.
-#define Z_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop.
-#define X_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop.
-#define Y_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop.
-#define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop.
+#define X_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop.
+#define Y_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop.
+#define Z_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop.
+#define X_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop.
+#define Y_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop.
+#define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop.
 #define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop.
 
 //===========================================================================
@@ -576,13 +585,13 @@
 
 // Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way.
 #define INVERT_X_DIR false
-#define INVERT_Y_DIR true
-#define INVERT_Z_DIR false
+#define INVERT_Y_DIR false
+#define INVERT_Z_DIR true
 
 // @section extruder
 
 // For direct drive extruder v9 set to true, for geared extruder set to false.
-#define INVERT_E0_DIR false
+#define INVERT_E0_DIR true
 #define INVERT_E1_DIR false
 #define INVERT_E2_DIR false
 #define INVERT_E3_DIR false
@@ -608,9 +617,9 @@
 #define X_MIN_POS 0
 #define Y_MIN_POS 0
 #define Z_MIN_POS 0
-#define X_MAX_POS 200
-#define Y_MAX_POS 200
-#define Z_MAX_POS 200
+#define X_MAX_POS 220
+#define Y_MAX_POS 220
+#define Z_MAX_POS 270
 
 //===========================================================================
 //========================= Filament Runout Sensor ==========================
@@ -749,12 +758,12 @@
 
 // default settings
 
-#define DEFAULT_AXIS_STEPS_PER_UNIT   {80,80,4000,500}  // default steps per unit for Ultimaker
-#define DEFAULT_MAX_FEEDRATE          {300, 300, 5, 25}    // (mm/sec)
-#define DEFAULT_MAX_ACCELERATION      {3000,3000,100,10000}    // X, Y, Z, E maximum start speed for accelerated moves. E default values are good for Skeinforge 40+, for older versions raise them a lot.
+#define DEFAULT_AXIS_STEPS_PER_UNIT   {100,100,800,92.6}  // default steps per unit for Ultimaker
+#define DEFAULT_MAX_FEEDRATE          {330, 330, 5, 25}    // (mm/sec)
+#define DEFAULT_MAX_ACCELERATION      {4000,4000,90,8000}    // X, Y, Z, E maximum start speed for accelerated moves. E default values are good for Skeinforge 40+, for older versions raise them a lot.
 
-#define DEFAULT_ACCELERATION          3000    // X, Y, Z and E acceleration in mm/s^2 for printing moves
-#define DEFAULT_RETRACT_ACCELERATION  3000    // E acceleration in mm/s^2 for retracts
+#define DEFAULT_ACCELERATION          500    // X, Y, Z and E acceleration in mm/s^2 for printing moves
+#define DEFAULT_RETRACT_ACCELERATION  1500    // E acceleration in mm/s^2 for retracts
 #define DEFAULT_TRAVEL_ACCELERATION   3000    // X, Y, Z acceleration in mm/s^2 for travel (non printing) moves
 
 // The speed change that does not require acceleration (i.e. the software might assume it can be done instantaneously)
@@ -811,13 +820,13 @@
 // @section temperature
 
 // Preheat Constants
-#define PREHEAT_1_TEMP_HOTEND 180
-#define PREHEAT_1_TEMP_BED     70
-#define PREHEAT_1_FAN_SPEED     0 // Value from 0 to 255
+#define PREHEAT_1_TEMP_HOTEND 206
+#define PREHEAT_1_TEMP_BED     65
+#define PREHEAT_1_FAN_SPEED   255 // Value from 0 to 255
 
 #define PREHEAT_2_TEMP_HOTEND 240
-#define PREHEAT_2_TEMP_BED    110
-#define PREHEAT_2_FAN_SPEED     0 // Value from 0 to 255
+#define PREHEAT_2_TEMP_BED     65
+#define PREHEAT_2_FAN_SPEED   255 // Value from 0 to 255
 
 //
 // Nozzle Park -- EXPERIMENTAL
@@ -918,7 +927,7 @@
 //  - Total time printing
 //
 // This information can be viewed by the M78 command.
-//#define PRINTCOUNTER
+#define PRINTCOUNTER
 
 //=============================================================================
 //============================= LCD and SD support ============================
@@ -981,7 +990,7 @@
 // SD Card support is disabled by default. If your controller has an SD slot,
 // you must uncomment the following option or it won't work.
 //
-//#define SDSUPPORT
+#define SDSUPPORT
 
 //
 // SD CARD: SPI SPEED
@@ -991,14 +1000,14 @@
 //
 //#define SPI_SPEED SPI_HALF_SPEED
 //#define SPI_SPEED SPI_QUARTER_SPEED
-//#define SPI_SPEED SPI_EIGHTH_SPEED
+#define SPI_SPEED SPI_EIGHTH_SPEED
 
 //
 // SD CARD: ENABLE CRC
 //
 // Use CRC checks and retries on the SD communication.
 //
-//#define SD_CHECK_AND_RETRY
+#define SD_CHECK_AND_RETRY
 
 //
 // ENCODER SETTINGS
@@ -1125,7 +1134,7 @@
 //
 // Note: Usually sold with a white PCB.
 //
-//#define REPRAP_DISCOUNT_SMART_CONTROLLER
+#define REPRAP_DISCOUNT_SMART_CONTROLLER
 
 //
 // GADGETS3D G3D LCD/SD Controller
@@ -1308,7 +1317,7 @@
 // Uncomment below to enable
 //#define FILAMENT_WIDTH_SENSOR
 
-#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00  //Enter the diameter (in mm) of the filament generally used (3.0 mm or 1.75 mm) - this is then used in the slicer software.  Used for sensor reading validation
+#define DEFAULT_NOMINAL_FILAMENT_DIA 1.75  //Enter the diameter (in mm) of the filament generally used (3.0 mm or 1.75 mm) - this is then used in the slicer software.  Used for sensor reading validation
 
 #if ENABLED(FILAMENT_WIDTH_SENSOR)
   #define FILAMENT_SENSOR_EXTRUDER_NUM 0   //The number of the extruder that has the filament sensor (0,1,2)
diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h
index a822c83..82bc149 100644
--- a/Marlin/Configuration_adv.h
+++ b/Marlin/Configuration_adv.h
@@ -403,7 +403,7 @@
 // @section lcd
 
 // Include a page of printer information in the LCD Main Menu
-//#define LCD_INFO_MENU
+#define LCD_INFO_MENU
 
 #if ENABLED(SDSUPPORT)
 
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index d1c4876..fe36013 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -3996,6 +3996,7 @@ inline void gcode_M17() {
    */
   inline void gcode_M23() {
     card.openFile(current_command_args, true);
+    print_job_timer.setFileSize(card.getFileSize());
   }
 
   /**
diff --git a/Marlin/cardreader.h b/Marlin/cardreader.h
index 8c22e58..3bb11f3 100644
--- a/Marlin/cardreader.h
+++ b/Marlin/cardreader.h
@@ -75,7 +75,9 @@ public:
   FORCE_INLINE int16_t get() { sdpos = file.curPosition(); return (int16_t)file.read(); }
   FORCE_INLINE void setIndex(long index) { sdpos = index; file.seekSet(index); }
   FORCE_INLINE uint8_t percentDone() { return (isFileOpen() && filesize) ? sdpos / ((filesize + 99) / 100) : 0; }
+  FORCE_INLINE float   percentDoneF() { return (isFileOpen() && filesize) ? sdpos / ((filesize + 99.0) / 100.0): 0.0; }
   FORCE_INLINE char* getWorkDirName() { workDir.getFilename(filename); return filename; }
+  FORCE_INLINE uint32_t getFileSize() { return (isFileOpen()) ? filesize: 0; }
 
 public:
   bool saving, logging, sdprinting, cardOK, filenameIsDir;
diff --git a/Marlin/printcounter.cpp b/Marlin/printcounter.cpp
index b6cef6e..4314ca4 100644
--- a/Marlin/printcounter.cpp
+++ b/Marlin/printcounter.cpp
@@ -51,6 +51,7 @@ void PrintCounter::incFilamentUsed(double const &amount) {
   if (!this->isLoaded()) return;
 
   this->data.filamentUsed += amount; // mm
+  this->currentFile.filamentUsed += amount; // mm
 }
 
 
@@ -60,7 +61,11 @@ void PrintCounter::initStats() {
   #endif
 
   this->loaded = true;
-  this->data = { 0, 0, 0, 0, 0.0 };
+  this->data = { 0, 0, 0, 0, 0.0,
+      {0, 0, 0.0},
+      {0, 0, 0.0},
+      {0, 0, 0.0}
+    };
 
   this->saveStats();
   eeprom_write_byte((uint8_t *) this->address, 0x16);
@@ -143,6 +148,55 @@ void PrintCounter::showStats() {
   SERIAL_ECHOPGM("m");
 
   SERIAL_EOL;
+
+  SERIAL_PROTOCOLPGM(MSG_STATS);
+
+  SERIAL_ECHOPGM("current file size: ");
+  SERIAL_ECHO(this->currentFile.size);
+  SERIAL_ECHOPGM("filament used: ");
+  SERIAL_ECHO(this->currentFile.filamentUsed);
+  SERIAL_ECHOPGM("mm");
+  SERIAL_ECHOPGM(" print time: ");
+  SERIAL_ECHO(this->currentFile.printTime);
+
+  SERIAL_EOL;
+
+  SERIAL_PROTOCOLPGM(MSG_STATS);
+
+  SERIAL_ECHOPGM("file1 size: ");
+  SERIAL_ECHO(this->data.file1.size);
+  SERIAL_ECHOPGM(" filament used: ");
+  SERIAL_ECHO(this->data.file1.filamentUsed);
+  SERIAL_ECHOPGM("mm");
+  SERIAL_ECHOPGM(" print time: ");
+  SERIAL_ECHO(this->data.file1.printTime);
+
+  SERIAL_EOL;
+
+  SERIAL_PROTOCOLPGM(MSG_STATS);
+
+  SERIAL_ECHOPGM("file2 size: ");
+  SERIAL_ECHO(this->data.file2.size);
+  SERIAL_ECHOPGM("filament used: ");
+  SERIAL_ECHO(this->data.file2.filamentUsed);
+  SERIAL_ECHOPGM("mm");
+  SERIAL_ECHOPGM(" print time: ");
+  SERIAL_ECHO(this->data.file2.printTime);
+
+  SERIAL_EOL;
+
+  SERIAL_PROTOCOLPGM(MSG_STATS);
+
+  SERIAL_ECHOPGM("file3 size: ");
+  SERIAL_ECHO(this->data.file3.size);
+  SERIAL_ECHOPGM("filament used: ");
+  SERIAL_ECHO(this->data.file3.filamentUsed);
+  SERIAL_ECHOPGM("mm");
+  SERIAL_ECHOPGM(" print time: ");
+  SERIAL_ECHO(this->data.file3.printTime);
+
+  SERIAL_EOL;
+
 }
 
 void PrintCounter::tick() {
@@ -162,6 +216,7 @@ void PrintCounter::tick() {
     #endif
 
     this->data.printTime += this->deltaDuration();
+    this->currentFile.printTime = this->duration();
     update_last = now;
   }
 
@@ -185,6 +240,8 @@ bool PrintCounter::start() {
     if (!paused) {
       this->data.totalPrints++;
       this->lastDuration = 0;
+      this -> currentFile.printTime = 0;
+      this -> currentFile.filamentUsed = 0;
     }
     return true;
   }
@@ -204,6 +261,11 @@ bool PrintCounter::stop() {
     if (this->duration() > this->data.longestPrint)
       this->data.longestPrint = this->duration();
 
+    this->currentFile.printTime = this->duration();
+    this->data.file3 = this->data.file2;
+    this->data.file2 = this->data.file1;
+    this->data.file1 = this->currentFile;
+
     this->saveStats();
     return true;
   }
@@ -218,8 +280,17 @@ void PrintCounter::reset() {
 
   super::reset();
   this->lastDuration = 0;
+  this->currentFile.filamentUsed = 0.0;
+  this->currentFile.printTime = 0;
 }
 
+void PrintCounter::setFileSize(uint32_t size) {
+  this->currentFile.size = size;
+}
+
+printFile PrintCounter::getCurrentFile() {
+  return this->currentFile;
+}
 #if ENABLED(DEBUG_PRINTCOUNTER)
 
   void PrintCounter::debug(const char func[]) {
diff --git a/Marlin/printcounter.h b/Marlin/printcounter.h
index 0e9d06f..f81e006 100644
--- a/Marlin/printcounter.h
+++ b/Marlin/printcounter.h
@@ -31,6 +31,11 @@
 
 // Print debug messages with M111 S2
 //#define DEBUG_PRINTCOUNTER
+struct printFile {
+  uint32_t size;
+  uint32_t printTime;
+  double filamentUsed;
+};
 
 struct printStatistics {    // 13 bytes
   //const uint8_t magic;    // Magic header, it will always be 0x16
@@ -39,6 +44,11 @@ struct printStatistics {    // 13 bytes
   uint32_t printTime;       // Accumulated printing time
   uint32_t longestPrint;    // Longest successfull print job
   double   filamentUsed;    // Accumulated filament consumed in mm
+
+  printFile file1;
+  printFile file2;
+  printFile file3;
+
 };
 
 class PrintCounter: public Stopwatch {
@@ -46,6 +56,7 @@ class PrintCounter: public Stopwatch {
     typedef Stopwatch super;
 
     printStatistics data;
+    printFile currentFile;
 
     /**
      * @brief EEPROM address
@@ -161,6 +172,9 @@ class PrintCounter: public Stopwatch {
     bool stop();
     void reset();
 
+    void setFileSize(uint32_t size);
+    printFile getCurrentFile();
+
     #if ENABLED(DEBUG_PRINTCOUNTER)
 
       /**
diff --git a/Marlin/ultralcd_impl_HD44780.h b/Marlin/ultralcd_impl_HD44780.h
index ab120c2..c96366d 100644
--- a/Marlin/ultralcd_impl_HD44780.h
+++ b/Marlin/ultralcd_impl_HD44780.h
@@ -785,6 +785,33 @@ static void lcd_implementation_status_screen() {
 
   #endif // FILAMENT_LCD_DISPLAY
 
+  #define M0A
+  #ifdef M0A //remain time calc
+    if (IS_SD_PRINTING) {
+      float percent = card.percentDoneF();
+      if (percent >= 1.0 && percent < 100.0) {
+          char buffer[21];
+          memset(buffer, 0, sizeof(buffer));
+          duration_t d = print_job_timer.duration();
+          uint32_t remainTime = uint32_t(d.value  * (100.0 - percent) / percent);
+          d.value = remainTime;
+          d.toString(buffer);
+          lcd.print("ETE:");
+          lcd.print(buffer);
+          lcd.print("   ");
+          return;
+      } else {
+        printFile pf = print_job_timer.getCurrentFile();
+        lcd.print(ftostr12ns(pf.size/1024.0/1024.0));
+        lcd.print("MB E:");
+        lcd.print(itostr3(pf.filamentUsed));
+        lcd.print("mm");
+        return;
+      }
+    }
+
+  #endif
+
   lcd_print(lcd_status_message);
 }
 

メインのコードはM0Aで囲んだ部分です

#define M0A
#ifdef M0A //remain time calc
  if (IS_SD_PRINTING) {
    float percent = card.percentDoneF();
    if (percent >= 1.0 && percent < 100.0) {
        char buffer[21];
        memset(buffer, 0, sizeof(buffer));
        duration_t d = print_job_timer.duration();
        uint32_t remainTime = uint32_t(d.value  * (100.0 - percent) / percent);
        d.value = remainTime;
        d.toString(buffer);
        lcd.print("ETE:");
        lcd.print(buffer);
        lcd.print("   ");
        return;
    } else {
      printFile pf = print_job_timer.getCurrentFile();
      lcd.print(ftostr12ns(pf.size/1024.0/1024.0));
      lcd.print("MB E:");
      lcd.print(itostr3(pf.filamentUsed));
      lcd.print("mm");
      return;
    }
  }
#endif