Skip to content

Commit

Permalink
✨ Add PANELDUE support
Browse files Browse the repository at this point in the history
  • Loading branch information
thinkyhead committed Aug 4, 2023
1 parent fe4819a commit 289df2e
Show file tree
Hide file tree
Showing 12 changed files with 455 additions and 8 deletions.
6 changes: 6 additions & 0 deletions Marlin/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -3177,6 +3177,12 @@
//
//#define NEXTION_TFT

//
// PanelDue touch controller by Escher3D
// http://escher3d.com/pages/order/products/product2.php
//
//#define PANELDUE

//
// Third-party or vendor-customized controller interfaces.
// Sources should be installed in 'src/lcd/extui'.
Expand Down
4 changes: 4 additions & 0 deletions Marlin/src/gcode/gcode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
case 407: M407(); break; // M407: Display measured filament diameter
#endif

#if ENABLED(PANELDUE)
case 408: M408(); break; // M408: Report machine state in JSON format
#endif

#if HAS_FILAMENT_SENSOR
case 412: M412(); break; // M412: Enable/Disable filament runout detection
#endif
Expand Down
5 changes: 5 additions & 0 deletions Marlin/src/gcode/gcode.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@
* M405 - Enable Filament Sensor flow control. "M405 D<delay_cm>". (Requires FILAMENT_WIDTH_SENSOR)
* M406 - Disable Filament Sensor flow control. (Requires FILAMENT_WIDTH_SENSOR)
* M407 - Display measured filament diameter in millimeters. (Requires FILAMENT_WIDTH_SENSOR)
* M408 - Report machine state in JSON format. (Requires PANELDUE)
* M410 - Quickstop. Abort all planned moves.
* M412 - Enable / Disable Filament Runout Detection. (Requires FILAMENT_RUNOUT_SENSOR)
* M413 - Enable / Disable Power-Loss Recovery. (Requires POWER_LOSS_RECOVERY)
Expand Down Expand Up @@ -1022,6 +1023,10 @@ class GcodeSuite {
static void M407();
#endif

#if ENABLED(PANELDUE)
static void M408();
#endif

#if HAS_FILAMENT_SENSOR
static void M412();
static void M412_report(const bool forReplay=true);
Expand Down
186 changes: 186 additions & 0 deletions Marlin/src/gcode/lcd/M408.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2022 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/

#include "../../inc/MarlinConfig.h"

#if ENABLED(PANELDUE)

#include "../gcode.h"
#include "../../module/planner.h"
#include "../../module/printcounter.h"
#include "../../module/temperature.h"
#include "../../sd/cardreader.h"
#include "../../lcd/marlinui.h"

#if ENABLED(LCD_SET_PROGRESS_MANUALLY)
extern uint8_t progress_bar_percent;
#endif

/**
* M408: Report machine state in JSON format for PanelDue
*
* S<style> Include static values with S1
*
* Since Marlin doesn't use sequence numbers, the R parameter is omitted.
*
*/

inline void json_key(const char * const name) {
SERIAL_ECHOPGM(",\"", name, "\":");
}

inline void json_array_print(const char * const name, const float val[], const int8_t size) {
json_key(name);
SERIAL_CHAR('[');
for (uint8_t i = 0; i < size; i++) {
SERIAL_ECHO(val[i]);
if (i < size - 1) SERIAL_CHAR(',');
}
SERIAL_CHAR(']');
safe_delay(1);
}

void GcodeSuite::M408() {
float tmp[10];
SERIAL_CHAR('{');

// status: SD printing or idle
json_key(PSTR("status"));
SERIAL_ECHO(IS_SD_PRINTING() ? F("\"P\"") : F("\"I\""));

// heaters: current bed, hotend temperatures
tmp[0] = TERN0(HAS_HEATED_BED, thermalManager.degBed());
HOTEND_LOOP() tmp[e + 1] = thermalManager.degHotend(e);
json_array_print(PSTR("heaters"), tmp, HOTENDS + 1);

// active: target bed, hotend temperatures
tmp[0] = TERN0(HAS_HEATED_BED, thermalManager.degTargetBed());
HOTEND_LOOP() tmp[e + 1] = thermalManager.degTargetHotend(e);
json_array_print(PSTR("active"), tmp, HOTENDS + 1);

// standby: in Marlin, same as active
json_array_print(PSTR("standby"), tmp, HOTENDS + 1);

// hstat: in Marlin, heating or off
json_key(PSTR("hstat"));
SERIAL_CHAR('[');
SERIAL_CHAR(TERN0(HAS_HEATED_BED, thermalManager.degTargetBed()) ? '2' : '0');
HOTEND_LOOP() {
SERIAL_CHAR(',');
SERIAL_CHAR(thermalManager.degTargetHotend(e) ? '2' : '0');
}
SERIAL_CHAR(']');

// pos: tool position
tmp[0] = current_position.x; tmp[1] = current_position.y; tmp[2] = current_position.z;
json_array_print(PSTR("pos"), tmp, 3);

// extr: extruder position
for (uint8_t e = 0; e < EXTRUDERS; e++) tmp[e] = current_position.e;
json_array_print(PSTR("extr"), tmp, EXTRUDERS);

// sfactor: feedrate %
json_key(PSTR("sfactor"));
SERIAL_ECHO(feedrate_percentage);

// efactor: flow %
for (uint8_t e = 0; e < EXTRUDERS; e++) tmp[e] = planner.flow_percentage[e];
json_array_print(PSTR("efactor"), tmp, EXTRUDERS);

// tool: selected extruder
json_key(PSTR("tool"));
SERIAL_ECHO(active_extruder);

// probe: the last Z probe reading (just 0 for now)
json_key(PSTR("probe"));
SERIAL_ECHOPGM("\"0\"");

#if FAN_COUNT > 0
// fanPercent: the last Z probe reading
for (uint8_t i = 0; i < FAN_COUNT; i++) tmp[i] = map(thermalManager.fan_speed[i], 0, 255, 0, 100);
json_array_print(PSTR("fanPercent"), tmp, FAN_COUNT);

// fanRPM: print cooling fan faux RPM
json_key(PSTR("fanRPM"));
SERIAL_ECHO(int(thermalManager.fan_speed[0] * 10));
#endif

// homed: axis homed status
json_key(PSTR("homed"));
LOOP_NUM_AXES(i) {
SERIAL_CHAR(i ? ',' : '[');
SERIAL_ECHO(int(TEST(axes_homed, i)));
}
SERIAL_CHAR(']');

#if ENABLED(SDSUPPORT)
// fraction_printed: print progress
json_key(PSTR("fraction_printed"));
SERIAL_ECHO(0.01 * ui.get_progress_percent());
#endif

#if HAS_DISPLAY
// message
if (ui.status_message[0]) {
json_key(PSTR("message"));
SERIAL_ECHOPGM("\"", &ui.status_message);
SERIAL_CHAR('"');
}
#endif

// Extra fields
if (parser.intval('S') == 1) {
// myName
json_key(PSTR("myName"));
SERIAL_ECHOPGM("\"" MACHINE_NAME "\"");
// firmwareName
json_key(PSTR("firmwareName"));
SERIAL_ECHOPGM("\"Marlin\"");
// geometry
json_key(PSTR("geometry"));
SERIAL_ECHOPGM("\""
TERN_(IS_FULL_CARTESIAN, "cartesian")
TERN_(IS_SCARA, "scara")
TERN_(DELTA, "delta")
TERN_(COREXY, "corexy")
TERN_(COREXZ, "corexz")
TERN_(COREYZ, "coreyz")
TERN_(COREYX, "coreyx")
TERN_(COREZX, "corezx")
TERN_(COREZY, "corezy")
"\""
);
// axes
json_key(PSTR("axes"));
SERIAL_CHAR('3');
// volumes: the number of SD card slots available
json_key(PSTR("volumes"));
SERIAL_CHAR(TERN(SDSUPPORT, '1', '0'));
// numTools: extruder count
json_key(PSTR("numTools"));
SERIAL_CHAR('0' + EXTRUDERS);
}

SERIAL_EOL();
}

#endif // PANELDUE
53 changes: 48 additions & 5 deletions Marlin/src/gcode/sd/M20.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,54 @@
*/
void GcodeSuite::M20() {
if (card.flag.mounted) {
SERIAL_ECHOLNPGM(STR_BEGIN_FILE_LIST);
card.ls(TERN0(CUSTOM_FIRMWARE_UPLOAD, parser.boolval('F') << LS_ONLY_BIN)
| TERN0(LONG_FILENAME_HOST_SUPPORT, parser.boolval('L') << LS_LONG_FILENAME)
| TERN0(M20_TIMESTAMP_SUPPORT, parser.boolval('T') << LS_TIMESTAMP));
SERIAL_ECHOLNPGM(STR_END_FILE_LIST);
#if ENABLED(PANELDUE)
const bool json = parser.intval('S') == 2;
if (json) {
// The P parameter gives the path
char *path = parser.stringval('P');

#if DISABLED(GCODE_QUOTED_STRINGS)
// 'S' before 'P' or 'S' is part of the path
if (path < parser.stringval('S')) path = nullptr;
#endif

// Get the CWD as the root for dive
SdFile *listDirPtr;

bool ok = true;

// If any path was specified, dive into it
if (path && path[0]) {
// Ensure the path ends with a slash
const size_t len = strlen(path);
if (len > 1 && path[len - 1] != '/') strcat(path, "/");
// Dive listDirPtr down to the path
ok = (bool)card.diveToFile(false, listDirPtr, path);
}
else
path = (char*)".";

if (ok) {
// Remove the slash at the end
const size_t len = strlen(path);
if (len > 1 && path[len - 1] == '/') path[len - 1] = '\0';
// Print a flat listing of the folder in JSON
SERIAL_ECHOPGM("{\"dir\":\"", path, "\",");
card.lsJSON(0, *listDirPtr); // Don't enter subfolders (but list folders)
SERIAL_ECHOLNPGM("}");
}
}
#else
constexpr bool json = false;
#endif

if (!json) {
SERIAL_ECHOLNPGM(STR_BEGIN_FILE_LIST);
card.ls(TERN0(CUSTOM_FIRMWARE_UPLOAD, parser.boolval('F') << LS_ONLY_BIN)
| TERN0(LONG_FILENAME_HOST_SUPPORT, parser.boolval('L') << LS_LONG_FILENAME)
| TERN0(M20_TIMESTAMP_SUPPORT, parser.boolval('T') << LS_TIMESTAMP));
SERIAL_ECHOLNPGM(STR_END_FILE_LIST);
}
}
else
SERIAL_ECHO_MSG(STR_NO_MEDIA);
Expand Down
4 changes: 2 additions & 2 deletions Marlin/src/inc/Conditionals_LCD.h
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@
#endif

// Extensible UI serial touch screens. (See src/lcd/extui)
#if ANY(HAS_DGUS_LCD, MALYAN_LCD, ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON, NEXTION_TFT, TOUCH_UI_FTDI_EVE)
#if ANY(HAS_DGUS_LCD, MALYAN_LCD, ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON, NEXTION_TFT, TOUCH_UI_FTDI_EVE, PANELDUE)
#define IS_EXTUI 1
#define EXTENSIBLE_UI
#endif
Expand All @@ -515,7 +515,7 @@
#endif

// Serial Controllers require LCD_SERIAL_PORT
#if ANY(IS_DWIN_MARLINUI, HAS_DWIN_E3V2, HAS_DGUS_LCD, MALYAN_LCD, ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON, NEXTION_TFT)
#if ANY(IS_DWIN_MARLINUI, HAS_DWIN_E3V2, HAS_DGUS_LCD, MALYAN_LCD, ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON, NEXTION_TFT, PANELDUE)
#define LCD_IS_SERIAL_HOST 1
#endif

Expand Down
1 change: 1 addition & 0 deletions Marlin/src/inc/SanityCheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -2610,6 +2610,7 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L
+ ENABLED(MAKRPANEL) \
+ ENABLED(MALYAN_LCD) \
+ ENABLED(NEXTION_TFT) \
+ ENABLED(PANELDUE) \
+ ENABLED(MKS_LCD12864A) \
+ ENABLED(MKS_LCD12864B) \
+ ENABLED(OLED_PANEL_TINYBOY2) \
Expand Down
Loading

0 comments on commit 289df2e

Please sign in to comment.