Nick
4 years ago
committed by
Scott Lahteine
16 changed files with 1735 additions and 573 deletions
@ -0,0 +1,162 @@ |
|||||
|
/**
|
||||
|
* Marlin 3D Printer Firmware |
||||
|
* Copyright (c) 2020 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/>.
|
||||
|
* |
||||
|
*/ |
||||
|
|
||||
|
/**
|
||||
|
* lcd/extui/lib/FileNavigator.cpp |
||||
|
* |
||||
|
* Extensible_UI implementation for Anycubic Chiron |
||||
|
* Written By Nick Wells, 2020 [https://github.com/SwiftNick]
|
||||
|
* (not affiliated with Anycubic, Ltd.) |
||||
|
*/ |
||||
|
|
||||
|
/***************************************************************************
|
||||
|
* The AC panel wants files in block of 4 and can only display a flat list * |
||||
|
* This library allows full folder traversal. * |
||||
|
***************************************************************************/ |
||||
|
|
||||
|
#include "../../../../inc/MarlinConfigPre.h" |
||||
|
|
||||
|
#if ENABLED(ANYCUBIC_LCD_CHIRON) |
||||
|
|
||||
|
#include "FileNavigator.h" |
||||
|
#include "chiron_tft.h" |
||||
|
|
||||
|
using namespace ExtUI; |
||||
|
|
||||
|
namespace Anycubic { |
||||
|
|
||||
|
FileList FileNavigator::filelist; // Instance of the Marlin file API
|
||||
|
char FileNavigator::currentfoldername[MAX_PATH_LEN]; // Current folder path
|
||||
|
uint16_t FileNavigator::lastindex; |
||||
|
uint8_t FileNavigator::folderdepth; |
||||
|
uint16_t FileNavigator::currentindex; // override the panel request
|
||||
|
|
||||
|
FileNavigator::FileNavigator() { reset(); } |
||||
|
|
||||
|
void FileNavigator::reset() { |
||||
|
currentfoldername[0] = '\0'; |
||||
|
folderdepth = 0; |
||||
|
currentindex = 0; |
||||
|
lastindex = 0; |
||||
|
// Start at root folder
|
||||
|
while (!filelist.isAtRootDir()) filelist.upDir(); |
||||
|
refresh(); |
||||
|
} |
||||
|
|
||||
|
void FileNavigator::refresh() { filelist.refresh(); } |
||||
|
|
||||
|
void FileNavigator::getFiles(uint16_t index) { |
||||
|
uint8_t files = 4; |
||||
|
if (index == 0) currentindex = 0; |
||||
|
|
||||
|
// Each time we change folder we reset the file index to 0 and keep track
|
||||
|
// of the current position as the TFT panel isnt aware of folders trees.
|
||||
|
if (index > 0) { |
||||
|
--currentindex; // go back a file to take account off the .. we added to the root.
|
||||
|
if (index > lastindex) |
||||
|
currentindex += files; |
||||
|
else |
||||
|
currentindex = currentindex < 4 ? 0 : currentindex - files; |
||||
|
} |
||||
|
lastindex = index; |
||||
|
|
||||
|
#if ACDEBUG(AC_FILE) |
||||
|
SERIAL_ECHOLNPAIR("index=", index, " currentindex=", currentindex); |
||||
|
#endif |
||||
|
|
||||
|
if (currentindex == 0 && folderdepth > 0) { // Add a link to go up a folder
|
||||
|
TFTSer.println("<<"); |
||||
|
TFTSer.println(".."); |
||||
|
files--; |
||||
|
} |
||||
|
|
||||
|
for (uint16_t seek = currentindex; seek < currentindex + files; seek++) { |
||||
|
if (filelist.seek(seek)) { |
||||
|
sendFile(); |
||||
|
#if ACDEBUG(AC_FILE) |
||||
|
SERIAL_ECHOLNPAIR("-", seek, " '", filelist.longFilename(), "' '", currentfoldername, "", filelist.shortFilename(), "'\n"); |
||||
|
#endif |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void FileNavigator::sendFile() { |
||||
|
// send the file and folder info to the panel
|
||||
|
// this info will be returned when the file is selected
|
||||
|
// Permitted special characters in file name -_*#~
|
||||
|
// Panel can display 22 characters per line
|
||||
|
if (filelist.isDir()) { |
||||
|
//TFTSer.print(currentfoldername);
|
||||
|
TFTSer.println(filelist.shortFilename()); |
||||
|
TFTSer.print(filelist.shortFilename()); |
||||
|
TFTSer.println("/"); |
||||
|
} |
||||
|
else { |
||||
|
// Logical Name
|
||||
|
TFTSer.print("/"); |
||||
|
if (folderdepth > 0) TFTSer.print(currentfoldername); |
||||
|
|
||||
|
TFTSer.println(filelist.shortFilename()); |
||||
|
|
||||
|
// Display Name
|
||||
|
TFTSer.println(filelist.longFilename()); |
||||
|
} |
||||
|
} |
||||
|
void FileNavigator::changeDIR(char *folder) { |
||||
|
#if ACDEBUG(AC_FILE) |
||||
|
SERIAL_ECHOLNPAIR("currentfolder: ", currentfoldername, " New: ", folder); |
||||
|
#endif |
||||
|
if (folderdepth >= MAX_FOLDER_DEPTH) return; // limit the folder depth
|
||||
|
strcat(currentfoldername, folder); |
||||
|
strcat(currentfoldername, "/"); |
||||
|
filelist.changeDir(folder); |
||||
|
refresh(); |
||||
|
folderdepth++; |
||||
|
currentindex = 0; |
||||
|
} |
||||
|
|
||||
|
void FileNavigator::upDIR() { |
||||
|
filelist.upDir(); |
||||
|
refresh(); |
||||
|
folderdepth--; |
||||
|
currentindex = 0; |
||||
|
// Remove the last child folder from the stored path
|
||||
|
if (folderdepth == 0) { |
||||
|
currentfoldername[0] = '\0'; |
||||
|
reset(); |
||||
|
} |
||||
|
else { |
||||
|
char *pos = nullptr; |
||||
|
for (uint8_t f = 0; f < folderdepth; f++) |
||||
|
pos = strchr(currentfoldername, '/'); |
||||
|
|
||||
|
*(pos + 1) = '\0'; |
||||
|
} |
||||
|
#if ACDEBUG(AC_FILE) |
||||
|
SERIAL_ECHOLNPAIR("depth: ", folderdepth, " currentfoldername: ", currentfoldername); |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
char* FileNavigator::getCurrentFolderName() { return currentfoldername; } |
||||
|
} |
||||
|
|
||||
|
#endif // ANYCUBIC_LCD_CHIRON
|
@ -0,0 +1,56 @@ |
|||||
|
/**
|
||||
|
* Marlin 3D Printer Firmware |
||||
|
* Copyright (c) 2020 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/>.
|
||||
|
* |
||||
|
*/ |
||||
|
#pragma once |
||||
|
|
||||
|
/**
|
||||
|
* lcd/extui/lib/FileNavigator.h |
||||
|
* |
||||
|
* Extensible_UI implementation for Anycubic Chiron |
||||
|
* Written By Nick Wells, 2020 [https://github.com/SwiftNick]
|
||||
|
* (not affiliated with Anycubic, Ltd.) |
||||
|
*/ |
||||
|
|
||||
|
#include "chiron_tft_defs.h" |
||||
|
#include "../../ui_api.h" |
||||
|
|
||||
|
using namespace ExtUI; |
||||
|
|
||||
|
namespace Anycubic { |
||||
|
class FileNavigator { |
||||
|
public: |
||||
|
FileNavigator(); |
||||
|
void reset(); |
||||
|
void getFiles(uint16_t); |
||||
|
void upDIR(); |
||||
|
void changeDIR(char *); |
||||
|
void sendFile(); |
||||
|
void refresh(); |
||||
|
char * getCurrentFolderName(); |
||||
|
private: |
||||
|
static FileList filelist; |
||||
|
static char currentfoldername[MAX_PATH_LEN]; |
||||
|
static uint16_t lastindex; |
||||
|
static uint8_t folderdepth; |
||||
|
static uint16_t currentindex; |
||||
|
}; |
||||
|
extern FileNavigator filenavigator; |
||||
|
} |
@ -0,0 +1,62 @@ |
|||||
|
/**
|
||||
|
* Marlin 3D Printer Firmware |
||||
|
* Copyright (c) 2020 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/>.
|
||||
|
* |
||||
|
*/ |
||||
|
|
||||
|
/**
|
||||
|
* lcd/extui/lib/Tunes.cpp |
||||
|
* |
||||
|
* Extensible_UI implementation for Anycubic Chiron |
||||
|
* Written By Nick Wells, 2020 [https://github.com/SwiftNick]
|
||||
|
* (not affiliated with Anycubic, Ltd.) |
||||
|
*/ |
||||
|
|
||||
|
/***********************************************************************
|
||||
|
* A Utility to play tunes using the buzzer in the printer controller. * |
||||
|
* See Tunes.h for note and tune definitions. * |
||||
|
***********************************************************************/ |
||||
|
|
||||
|
#include "../../../../inc/MarlinConfigPre.h" |
||||
|
|
||||
|
#if ENABLED(ANYCUBIC_LCD_CHIRON) |
||||
|
|
||||
|
#include "Tunes.h" |
||||
|
#include "../../ui_api.h" |
||||
|
|
||||
|
namespace Anycubic { |
||||
|
|
||||
|
void PlayTune(uint8_t beeperPin, const uint16_t *tune, uint8_t speed=1) { |
||||
|
uint8_t pos = 1; |
||||
|
uint16_t wholenotelen = tune[0] / speed; |
||||
|
do { |
||||
|
uint16_t freq = tune[pos]; |
||||
|
uint16_t notelen = wholenotelen / tune[pos + 1]; |
||||
|
|
||||
|
::tone(beeperPin, freq, notelen); |
||||
|
ExtUI::delay_ms(notelen); |
||||
|
pos += 2; |
||||
|
|
||||
|
if (pos >= MAX_TUNE_LENGTH) break; |
||||
|
} while (tune[pos] != n_END); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
#endif // ANYCUBIC_LCD_CHIRON
|
@ -0,0 +1,224 @@ |
|||||
|
/**
|
||||
|
* Marlin 3D Printer Firmware |
||||
|
* Copyright (c) 2020 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/>.
|
||||
|
* |
||||
|
*/ |
||||
|
#pragma once |
||||
|
|
||||
|
/**
|
||||
|
* lcd/extui/lib/Tunes.h |
||||
|
* |
||||
|
* Extensible_UI implementation for Anycubic Chiron |
||||
|
* Written By Nick Wells, 2020 [https://github.com/SwiftNick]
|
||||
|
* (not affiliated with Anycubic, Ltd.) |
||||
|
*/ |
||||
|
|
||||
|
/**************************************************************************
|
||||
|
* Notes definition from https://pages.mtu.edu/~suits/NoteFreqCalcs.html *
|
||||
|
* * |
||||
|
* The format of a tune is: * |
||||
|
* {<whole note time>,<note1>,<length1>, <note2>,<length2>, ... <END>} * |
||||
|
* * |
||||
|
* 1) The first value is the length of a whole note in milliseconds * |
||||
|
* 2) Then a sequence of pitch and duration pairs * |
||||
|
* 3) Finally the END marker so your tunes can be any length up to * |
||||
|
* MAX_TUNE_LEN * |
||||
|
*************************************************************************/ |
||||
|
|
||||
|
#include <stdint.h> |
||||
|
|
||||
|
#define MAX_TUNE_LENGTH 128 |
||||
|
|
||||
|
// Special notes!
|
||||
|
#define n_P 0 // silence or pause
|
||||
|
#define n_END 10000 // end of tune marker
|
||||
|
|
||||
|
// Note duration divisors
|
||||
|
#define l_T1 1 |
||||
|
#define l_T2 2 |
||||
|
#define l_T3 3 |
||||
|
#define l_T4 4 |
||||
|
#define l_T8 8 |
||||
|
#define l_T16 16 |
||||
|
|
||||
|
// Note Frequency
|
||||
|
#define n_C0 16 |
||||
|
#define n_CS0 17 |
||||
|
#define n_D0 18 |
||||
|
#define n_DS0 19 |
||||
|
#define n_E0 21 |
||||
|
#define n_F0 22 |
||||
|
#define n_FS0 23 |
||||
|
#define n_G0 25 |
||||
|
#define n_GS0 26 |
||||
|
#define n_A0 28 |
||||
|
#define n_AS0 29 |
||||
|
#define n_B0 31 |
||||
|
#define n_C1 33 |
||||
|
#define n_CS1 35 |
||||
|
#define n_D1 37 |
||||
|
#define n_DS1 39 |
||||
|
#define n_E1 41 |
||||
|
#define n_F1 44 |
||||
|
#define n_FS1 46 |
||||
|
#define n_G1 49 |
||||
|
#define n_GS1 52 |
||||
|
#define n_A1 55 |
||||
|
#define n_AS1 58 |
||||
|
#define n_B1 62 |
||||
|
#define n_C2 65 |
||||
|
#define n_CS2 69 |
||||
|
#define n_D2 73 |
||||
|
#define n_DS2 78 |
||||
|
#define n_E2 82 |
||||
|
#define n_F2 87 |
||||
|
#define n_FS2 93 |
||||
|
#define n_G2 98 |
||||
|
#define n_GS2 104 |
||||
|
#define n_A2 110 |
||||
|
#define n_AS2 117 |
||||
|
#define n_B2 123 |
||||
|
#define n_C3 131 |
||||
|
#define n_CS3 139 |
||||
|
#define n_D3 147 |
||||
|
#define n_DS3 156 |
||||
|
#define n_E3 165 |
||||
|
#define n_F3 175 |
||||
|
#define n_FS3 185 |
||||
|
#define n_G3 196 |
||||
|
#define n_GS3 208 |
||||
|
#define n_A3 220 |
||||
|
#define n_AS3 233 |
||||
|
#define n_B3 247 |
||||
|
#define n_C4 262 |
||||
|
#define n_CS4 277 |
||||
|
#define n_D4 294 |
||||
|
#define n_DS4 311 |
||||
|
#define n_E4 330 |
||||
|
#define n_F4 349 |
||||
|
#define n_FS4 370 |
||||
|
#define n_G4 392 |
||||
|
#define n_GS4 415 |
||||
|
#define n_A4 440 |
||||
|
#define n_AS4 466 |
||||
|
#define n_B4 494 |
||||
|
#define n_C5 523 |
||||
|
#define n_CS5 554 |
||||
|
#define n_D5 587 |
||||
|
#define n_DS5 622 |
||||
|
#define n_E5 659 |
||||
|
#define n_F5 698 |
||||
|
#define n_FS5 740 |
||||
|
#define n_G5 784 |
||||
|
#define n_GS5 831 |
||||
|
#define n_A5 880 |
||||
|
#define n_AS5 932 |
||||
|
#define n_B5 988 |
||||
|
#define n_C6 1047 |
||||
|
#define n_CS6 1109 |
||||
|
#define n_D6 1175 |
||||
|
#define n_DS6 1245 |
||||
|
#define n_E6 1319 |
||||
|
#define n_F6 1397 |
||||
|
#define n_FS6 1480 |
||||
|
#define n_G6 1568 |
||||
|
#define n_GS6 1661 |
||||
|
#define n_A6 1760 |
||||
|
#define n_AS6 1865 |
||||
|
#define n_B6 1976 |
||||
|
#define n_C7 2093 |
||||
|
#define n_CS7 2217 |
||||
|
#define n_D7 2349 |
||||
|
#define n_DS7 2489 |
||||
|
#define n_E7 2637 |
||||
|
#define n_F7 2794 |
||||
|
#define n_FS7 2960 |
||||
|
#define n_G7 3136 |
||||
|
#define n_GS7 3322 |
||||
|
#define n_A7 3520 |
||||
|
#define n_AS7 3729 |
||||
|
#define n_B7 3951 |
||||
|
#define n_C8 4186 |
||||
|
#define n_CS8 4435 |
||||
|
#define n_D8 4699 |
||||
|
#define n_DS8 4978 |
||||
|
#define n_E8 5274 |
||||
|
#define n_F8 5587 |
||||
|
#define n_FS8 5920 |
||||
|
#define n_G8 6272 |
||||
|
#define n_GS8 6645 |
||||
|
#define n_A8 7040 |
||||
|
#define n_AS8 7459 |
||||
|
#define n_B8 7902 |
||||
|
|
||||
|
namespace Anycubic { |
||||
|
|
||||
|
void PlayTune(uint8_t beeperPin, const uint16_t *tune, uint8_t speed); |
||||
|
|
||||
|
// Only uncomment the tunes you are using to save memory
|
||||
|
// This will help you write tunes!
|
||||
|
// https://www.apronus.com/music/flashpiano.htm
|
||||
|
|
||||
|
const uint16_t SOS[] = { |
||||
|
250, |
||||
|
n_G6,l_T3, n_P,l_T3, n_G6,l_T3, n_P,l_T3, n_G6,l_T3, n_P,l_T1, |
||||
|
n_G6,l_T1, n_P,l_T3, n_G6,l_T1, n_P,l_T3, n_G6,l_T1, n_P,l_T1, |
||||
|
n_G6,l_T3, n_P,l_T3, n_G6,l_T3, n_P,l_T3, n_G6,l_T3, n_P,l_T1, |
||||
|
n_END |
||||
|
}; |
||||
|
|
||||
|
const uint16_t BeepBeep[] = { |
||||
|
500, |
||||
|
n_C7,l_T8, n_P,l_T16, n_C7,l_T8, n_P,l_T8, |
||||
|
n_END |
||||
|
}; |
||||
|
|
||||
|
const uint16_t BeepBeepBeeep[] = { |
||||
|
1000, |
||||
|
n_G7,l_T4, n_P,l_T16, n_G7,l_T4, n_P,l_T8, n_G7,l_T2, |
||||
|
n_END |
||||
|
}; |
||||
|
|
||||
|
const uint16_t Anycubic_PowerOn[] = { |
||||
|
1000, |
||||
|
n_F7,l_T8, n_P,l_T8, n_C7,l_T8, n_P,l_T8, n_D7,l_T8, n_P,l_T8, |
||||
|
n_E7,l_T8, n_P,l_T8, n_D7,l_T4, n_P,l_T4, n_G7,l_T4, n_P,l_T4, |
||||
|
n_A7,l_T2, n_P,l_T1, |
||||
|
n_END |
||||
|
}; |
||||
|
|
||||
|
const uint16_t GB_PowerOn[] = { |
||||
|
500, |
||||
|
n_C6,l_T4, n_P,l_T16, n_C7,l_T2, n_P,l_T8, |
||||
|
n_END |
||||
|
}; |
||||
|
|
||||
|
const uint16_t Heater_Timedout[] = { |
||||
|
1000, |
||||
|
n_C6,l_T1, |
||||
|
n_END |
||||
|
}; |
||||
|
|
||||
|
const uint16_t FilamentOut[] = { |
||||
|
1000, |
||||
|
n_AS7,l_T4, n_P,l_T16, n_FS7,l_T2, |
||||
|
n_END |
||||
|
}; |
||||
|
|
||||
|
} |
@ -0,0 +1,896 @@ |
|||||
|
/**
|
||||
|
* Marlin 3D Printer Firmware |
||||
|
* Copyright (c) 2020 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/>.
|
||||
|
* |
||||
|
*/ |
||||
|
|
||||
|
/**
|
||||
|
* lcd/extui/lib/chiron_tft.cpp |
||||
|
* |
||||
|
* Extensible_UI implementation for Anycubic Chiron |
||||
|
* Written By Nick Wells, 2020 [https://github.com/SwiftNick]
|
||||
|
* (not affiliated with Anycubic, Ltd.) |
||||
|
*/ |
||||
|
|
||||
|
#include "../../../../inc/MarlinConfigPre.h" |
||||
|
|
||||
|
#if ENABLED(ANYCUBIC_LCD_CHIRON) |
||||
|
|
||||
|
#include "chiron_tft.h" |
||||
|
#include "Tunes.h" |
||||
|
#include "FileNavigator.h" |
||||
|
|
||||
|
#include "../../../../gcode/queue.h" |
||||
|
#include "../../../../sd/cardreader.h" |
||||
|
#include "../../../../libs/numtostr.h" |
||||
|
#include "../../../../MarlinCore.h" |
||||
|
namespace Anycubic { |
||||
|
|
||||
|
printer_state_t ChironTFT::printer_state; |
||||
|
paused_state_t ChironTFT::pause_state; |
||||
|
heater_state_t ChironTFT::hotend_state; |
||||
|
heater_state_t ChironTFT::hotbed_state; |
||||
|
xy_uint8_t ChironTFT::selectedmeshpoint; |
||||
|
char ChironTFT::selectedfile[MAX_PATH_LEN]; |
||||
|
char ChironTFT::panel_command[MAX_CMND_LEN]; |
||||
|
uint8_t ChironTFT::command_len; |
||||
|
float ChironTFT::live_Zoffset; |
||||
|
file_menu_t ChironTFT::file_menu; |
||||
|
|
||||
|
ChironTFT::ChironTFT(){} |
||||
|
|
||||
|
void ChironTFT::Startup() { |
||||
|
selectedfile[0] = '\0'; |
||||
|
panel_command[0] = '\0'; |
||||
|
command_len = 0; |
||||
|
printer_state = AC_printer_idle; |
||||
|
pause_state = AC_paused_idle; |
||||
|
hotend_state = AC_heater_off; |
||||
|
hotbed_state = AC_heater_off; |
||||
|
live_Zoffset = 0.0; |
||||
|
file_menu = AC_menu_file; |
||||
|
|
||||
|
// Setup pins for powerloss detection
|
||||
|
// Two IO pins are connected on the Trigorilla Board
|
||||
|
// On a power interruption the OUTAGECON_PIN goes low.
|
||||
|
|
||||
|
#if ENABLED(POWER_LOSS_RECOVERY) |
||||
|
OUT_WRITE(OUTAGECON_PIN, HIGH); |
||||
|
#endif |
||||
|
|
||||
|
// Filament runout is handled by Marlin settings in Configuration.h
|
||||
|
// set FIL_RUNOUT_STATE HIGH // Pin state indicating that filament is NOT present.
|
||||
|
// enable FIL_RUNOUT_PULLUP
|
||||
|
|
||||
|
TFTSer.begin(115200); |
||||
|
|
||||
|
// Signal Board has reset
|
||||
|
SendtoTFTLN(AC_msg_main_board_has_reset); |
||||
|
|
||||
|
safe_delay(200); |
||||
|
|
||||
|
// Enable levelling and Disable end stops during print
|
||||
|
// as Z home places nozzle above the bed so we need to allow it past the end stops
|
||||
|
injectCommands_P(AC_cmnd_enable_levelling); //M211 S0\n"));
|
||||
|
|
||||
|
// Startup tunes are defined in Tunes.h
|
||||
|
//PlayTune(BEEPER_PIN, Anycubic_PowerOn, 1);
|
||||
|
PlayTune(BEEPER_PIN, GB_PowerOn, 1); |
||||
|
#if ACDEBUGLEVEL |
||||
|
SERIAL_ECHOLNPAIR("AC Debug Level ", ACDEBUGLEVEL); |
||||
|
#endif |
||||
|
SendtoTFTLN(AC_msg_ready); |
||||
|
} |
||||
|
|
||||
|
void ChironTFT::IdleLoop() { |
||||
|
if (ReadTFTCommand()) { |
||||
|
ProcessPanelRequest(); |
||||
|
command_len = 0; |
||||
|
} |
||||
|
CheckHeaters(); |
||||
|
} |
||||
|
|
||||
|
void ChironTFT::PrinterKilled(PGM_P error,PGM_P component) { |
||||
|
SendtoTFTLN(AC_msg_kill_lcd); |
||||
|
#if ACDEBUG(AC_MARLIN) |
||||
|
SERIAL_ECHOLNPAIR("PrinterKilled()\nerror: ", error , "\ncomponent: ", component); |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
void ChironTFT::MediaEvent(media_event_t event) { |
||||
|
#if ACDEBUG(AC_MARLIN) |
||||
|
SERIAL_ECHOLNPAIR("ProcessMediaStatus() ", event); |
||||
|
#endif |
||||
|
switch (event) { |
||||
|
case AC_media_inserted: |
||||
|
SendtoTFTLN(AC_msg_sd_card_inserted); |
||||
|
break; |
||||
|
|
||||
|
case AC_media_removed: |
||||
|
SendtoTFTLN(AC_msg_sd_card_removed); |
||||
|
break; |
||||
|
|
||||
|
case AC_media_error: |
||||
|
SendtoTFTLN(AC_msg_no_sd_card); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void ChironTFT::TimerEvent(timer_event_t event) { |
||||
|
#if ACDEBUG(AC_MARLIN) |
||||
|
SERIAL_ECHOLNPAIR("TimerEvent() ", event); |
||||
|
SERIAL_ECHOLNPAIR("Printer State: ", printer_state); |
||||
|
#endif |
||||
|
|
||||
|
switch (event) { |
||||
|
case AC_timer_started: { |
||||
|
live_Zoffset = 0.0; // reset print offset
|
||||
|
setSoftEndstopState(false); // disable endstops to print
|
||||
|
printer_state = AC_printer_printing; |
||||
|
SendtoTFTLN(AC_msg_print_from_sd_card); |
||||
|
} break; |
||||
|
|
||||
|
case AC_timer_paused: { |
||||
|
printer_state = AC_printer_paused; |
||||
|
pause_state = AC_paused_idle; |
||||
|
SendtoTFTLN(AC_msg_paused); |
||||
|
} break; |
||||
|
|
||||
|
case AC_timer_stopped: { |
||||
|
if (printer_state != AC_printer_idle) { |
||||
|
printer_state = AC_printer_stopping; |
||||
|
SendtoTFTLN(AC_msg_print_complete); |
||||
|
} |
||||
|
setSoftEndstopState(true); // enable endstops
|
||||
|
} break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void ChironTFT::FilamentRunout() { |
||||
|
#if ACDEBUG(AC_MARLIN) |
||||
|
SERIAL_ECHOLNPAIR("FilamentRunout() printer_state ", printer_state); |
||||
|
#endif |
||||
|
// 1 Signal filament out
|
||||
|
SendtoTFTLN(isPrintingFromMedia() ? AC_msg_filament_out_alert : AC_msg_filament_out_block); |
||||
|
//printer_state = AC_printer_filament_out;
|
||||
|
PlayTune(BEEPER_PIN, FilamentOut, 1); |
||||
|
} |
||||
|
|
||||
|
void ChironTFT::ConfirmationRequest(const char * const msg) { |
||||
|
// M108 continue
|
||||
|
#if ACDEBUG(AC_MARLIN) |
||||
|
SERIAL_ECHOLNPAIR("ConfirmationRequest() ", msg, " printer_state:", printer_state); |
||||
|
#endif |
||||
|
switch (printer_state) { |
||||
|
case AC_printer_pausing: { |
||||
|
if ( (strcmp_P(msg, MARLIN_msg_print_paused) == 0 ) || (strcmp_P(msg, MARLIN_msg_nozzle_parked) == 0 ) ) { |
||||
|
SendtoTFTLN(AC_msg_paused); // enable continue button
|
||||
|
printer_state = AC_printer_paused; |
||||
|
} |
||||
|
} break; |
||||
|
|
||||
|
case AC_printer_resuming_from_power_outage: |
||||
|
case AC_printer_printing: |
||||
|
case AC_printer_paused: { |
||||
|
// Heater timout, send acknowledgement
|
||||
|
if (strcmp_P(msg, MARLIN_msg_heater_timeout) == 0 ) { |
||||
|
pause_state = AC_paused_heater_timed_out; |
||||
|
SendtoTFTLN(AC_msg_paused); // enable continue button
|
||||
|
PlayTune(BEEPER_PIN,Heater_Timedout,1); |
||||
|
} |
||||
|
// Reheat finished, send acknowledgement
|
||||
|
else if (strcmp_P(msg, MARLIN_msg_reheat_done) == 0 ) { |
||||
|
pause_state = AC_paused_idle; |
||||
|
SendtoTFTLN(AC_msg_paused); // enable continue button
|
||||
|
} |
||||
|
// Filament Purging, send acknowledgement enter run mode
|
||||
|
else if (strcmp_P(msg, MARLIN_msg_filament_purging) == 0 ) { |
||||
|
pause_state = AC_paused_purging_filament; |
||||
|
SendtoTFTLN(AC_msg_paused); // enable continue button
|
||||
|
} |
||||
|
} break; |
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void ChironTFT::StatusChange(const char * const msg) { |
||||
|
#if ACDEBUG(AC_MARLIN) |
||||
|
SERIAL_ECHOLNPAIR("StatusChange() ", msg); |
||||
|
SERIAL_ECHOLNPAIR("printer_state:", printer_state); |
||||
|
#endif |
||||
|
bool msg_matched = false; |
||||
|
// The only way to get printer status is to parse messages
|
||||
|
// Use the state to minimise the work we do here.
|
||||
|
switch (printer_state) { |
||||
|
case AC_printer_probing: { |
||||
|
// If probing completes ok save the mesh and park
|
||||
|
if (strcmp_P(msg, MARLIN_msg_ready) == 0 ) { |
||||
|
injectCommands_P(PSTR("M500\nG27")); |
||||
|
SendtoTFTLN(AC_msg_probing_complete); |
||||
|
printer_state = AC_printer_idle; |
||||
|
msg_matched = true; |
||||
|
} |
||||
|
// If probing fails dont save the mesh raise the probe above the bad point
|
||||
|
if (strcmp_P(msg, MARLIN_msg_probing_failed) == 0 ) { |
||||
|
PlayTune(BEEPER_PIN, BeepBeepBeeep, 1); |
||||
|
injectCommands_P(PSTR("G1 Z50 F500")); |
||||
|
SendtoTFTLN(AC_msg_probing_complete); |
||||
|
printer_state = AC_printer_idle; |
||||
|
msg_matched = true; |
||||
|
} |
||||
|
} break; |
||||
|
|
||||
|
case AC_printer_printing: { |
||||
|
if (strcmp_P(msg, MARLIN_msg_reheating) == 0 ) { |
||||
|
SendtoTFTLN(AC_msg_paused); // enable continue button
|
||||
|
msg_matched = true; |
||||
|
} |
||||
|
} break; |
||||
|
|
||||
|
case AC_printer_pausing: { |
||||
|
if (strcmp_P(msg, MARLIN_msg_print_paused) == 0 ) { |
||||
|
SendtoTFTLN(AC_msg_paused); |
||||
|
printer_state = AC_printer_paused; |
||||
|
pause_state = AC_paused_idle; |
||||
|
msg_matched = true; |
||||
|
} |
||||
|
} break; |
||||
|
|
||||
|
case AC_printer_stopping: { |
||||
|
if (strcmp_P(msg, MARLIN_msg_print_aborted) == 0 ) { |
||||
|
SendtoTFTLN(AC_msg_stop); |
||||
|
printer_state = AC_printer_idle; |
||||
|
msg_matched = true; |
||||
|
} |
||||
|
} break; |
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
// If not matched earlier see if this was a heater message
|
||||
|
if (!msg_matched) { |
||||
|
if (strcmp_P(msg, MARLIN_msg_extruder_heating) == 0) { |
||||
|
SendtoTFTLN(AC_msg_nozzle_heating); |
||||
|
hotend_state = AC_heater_temp_set; |
||||
|
} |
||||
|
else if (strcmp_P(msg, MARLIN_msg_bed_heating) == 0) { |
||||
|
SendtoTFTLN(AC_msg_bed_heating); |
||||
|
hotbed_state = AC_heater_temp_set; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void ChironTFT::PowerLossRecovery() { |
||||
|
printer_state = AC_printer_resuming_from_power_outage; // Play tune to notify user we can recover.
|
||||
|
PlayTune(BEEPER_PIN, SOS, 1); |
||||
|
SERIAL_ECHOLNPGM("Resuming from power outage..."); |
||||
|
SERIAL_ECHOLNPGM("Select SD file then press resume"); |
||||
|
} |
||||
|
|
||||
|
void ChironTFT::SendtoTFT(PGM_P str) { // A helper to print PROGMEN string to the panel
|
||||
|
#if ACDEBUG(AC_SOME) |
||||
|
serialprintPGM(str); |
||||
|
#endif |
||||
|
while (const char c = pgm_read_byte(str++)) TFTSer.print(c); |
||||
|
} |
||||
|
|
||||
|
void ChironTFT::SendtoTFTLN(PGM_P str = nullptr) { |
||||
|
if (str != nullptr) { |
||||
|
#if ACDEBUG(AC_SOME) |
||||
|
SERIAL_ECHO("> "); |
||||
|
#endif |
||||
|
SendtoTFT(str); |
||||
|
#if ACDEBUG(AC_SOME) |
||||
|
SERIAL_EOL(); |
||||
|
#endif |
||||
|
} |
||||
|
TFTSer.println(""); |
||||
|
} |
||||
|
|
||||
|
bool ChironTFT::ReadTFTCommand() { |
||||
|
bool command_ready = false; |
||||
|
while( (TFTSer.available() > 0) && (command_len < MAX_CMND_LEN) ) { |
||||
|
panel_command[command_len] = TFTSer.read(); |
||||
|
if(panel_command[command_len] == '\n') { |
||||
|
command_ready = true; |
||||
|
break; |
||||
|
} |
||||
|
command_len++; |
||||
|
} |
||||
|
|
||||
|
if(command_ready) { |
||||
|
panel_command[command_len] = 0x00; |
||||
|
#if ACDEBUG(AC_ALL) |
||||
|
SERIAL_ECHOLNPAIR("< ", panel_command); |
||||
|
#endif |
||||
|
#if ACDEBUG(AC_SOME) |
||||
|
// Ignore status request commands
|
||||
|
uint8_t req = atoi(&panel_command[1]); |
||||
|
if (req > 7 && req != 20) { |
||||
|
SERIAL_ECHOLNPAIR("> ", panel_command); |
||||
|
SERIAL_ECHOLNPAIR("printer_state:", printer_state); |
||||
|
} |
||||
|
#endif |
||||
|
} |
||||
|
return command_ready; |
||||
|
} |
||||
|
|
||||
|
int8_t ChironTFT::Findcmndpos(const char * buff, char q) { |
||||
|
bool found = false; |
||||
|
int8_t pos = 0; |
||||
|
do { |
||||
|
if (buff[pos] == q) { |
||||
|
found = true; |
||||
|
break; |
||||
|
} |
||||
|
pos ++; |
||||
|
} while(pos < MAX_CMND_LEN); |
||||
|
if (found) return pos; |
||||
|
return -1; |
||||
|
} |
||||
|
|
||||
|
void ChironTFT::CheckHeaters() { |
||||
|
uint8_t faultDuration = 0; float temp = 0; |
||||
|
|
||||
|
// if the hotend temp is abnormal, confirm state before signalling panel
|
||||
|
temp = getActualTemp_celsius(E0); |
||||
|
if ( (temp <= HEATER_0_MINTEMP) || (temp >= HEATER_0_MAXTEMP) ) { |
||||
|
do { |
||||
|
faultDuration ++; |
||||
|
if (faultDuration >= AC_HEATER_FAULT_VALIDATION_TIME) { |
||||
|
SendtoTFTLN(AC_msg_nozzle_temp_abnormal); |
||||
|
SERIAL_ECHOLNPAIR("Extruder temp abnormal! : ", temp); |
||||
|
break; |
||||
|
} |
||||
|
delay_ms(500); |
||||
|
temp = getActualTemp_celsius(E0); |
||||
|
} while ((temp <= HEATER_0_MINTEMP) || (temp >= HEATER_0_MAXTEMP) ); |
||||
|
} |
||||
|
|
||||
|
// if the hotbed temp is abnormal, confirm state before signalling panel
|
||||
|
faultDuration = 0; |
||||
|
temp = getActualTemp_celsius(BED); |
||||
|
if ( (temp <= BED_MINTEMP) || (temp >= BED_MAXTEMP) ) { |
||||
|
do { |
||||
|
faultDuration ++; |
||||
|
if (faultDuration >= AC_HEATER_FAULT_VALIDATION_TIME) { |
||||
|
SendtoTFTLN(AC_msg_nozzle_temp_abnormal); |
||||
|
SERIAL_ECHOLNPAIR_P("Bed temp abnormal! : ", temp); |
||||
|
break; |
||||
|
} |
||||
|
delay_ms(500); |
||||
|
temp = getActualTemp_celsius(E0); |
||||
|
} while ((temp <= BED_MINTEMP) || (temp >= BED_MAXTEMP) ); |
||||
|
} |
||||
|
|
||||
|
// Update panel with hotend heater status
|
||||
|
if (hotend_state != AC_heater_temp_reached) { |
||||
|
if ( WITHIN( getActualTemp_celsius(E0) - getTargetTemp_celsius(E0), -1, 1 ) ) { |
||||
|
SendtoTFTLN(AC_msg_nozzle_heating_done); |
||||
|
hotend_state = AC_heater_temp_reached; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Update panel with bed heater status
|
||||
|
if (hotbed_state != AC_heater_temp_reached) { |
||||
|
if ( WITHIN( getActualTemp_celsius(BED) - getTargetTemp_celsius(BED), -0.5, 0.5 ) ) { |
||||
|
SendtoTFTLN(AC_msg_bed_heating_done); |
||||
|
hotbed_state = AC_heater_temp_reached; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void ChironTFT::SendFileList(int8_t startindex) { |
||||
|
// respond to panel request for 4 files starting at index
|
||||
|
#if ACDEBUG(AC_INFO) |
||||
|
SERIAL_ECHOLNPAIR("## SendFileList ## ", startindex); |
||||
|
#endif |
||||
|
SendtoTFTLN(PSTR("FN ")); |
||||
|
filenavigator.getFiles(startindex); |
||||
|
SendtoTFTLN(PSTR("END")); |
||||
|
} |
||||
|
|
||||
|
void ChironTFT::SelectFile() { |
||||
|
strncpy(selectedfile,panel_command+4,command_len-4); |
||||
|
selectedfile[command_len-5] = '\0'; |
||||
|
#if ACDEBUG(AC_FILE) |
||||
|
SERIAL_ECHOLNPAIR_F(" Selected File: ",selectedfile); |
||||
|
#endif |
||||
|
switch (selectedfile[0]) { |
||||
|
case '/': // Valid file selected
|
||||
|
SendtoTFTLN(AC_msg_sd_file_open_success); |
||||
|
break; |
||||
|
|
||||
|
case '<': // .. (go up folder level)
|
||||
|
filenavigator.upDIR(); |
||||
|
SendtoTFTLN(AC_msg_sd_file_open_failed); |
||||
|
SendFileList( 0 ); |
||||
|
break; |
||||
|
default: // enter sub folder
|
||||
|
filenavigator.changeDIR(selectedfile); |
||||
|
SendtoTFTLN(AC_msg_sd_file_open_failed); |
||||
|
SendFileList( 0 ); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void ChironTFT::InjectCommandandWait(PGM_P cmd) { |
||||
|
//injectCommands_P(cmnd); queue.enqueue_now_P(cmd);
|
||||
|
//SERIAL_ECHOLN(PSTR("Inject>"));
|
||||
|
} |
||||
|
|
||||
|
void ChironTFT::ProcessPanelRequest() { |
||||
|
// Break these up into logical blocks // as its easier to navigate than one huge switch case!
|
||||
|
int8_t req = atoi(&panel_command[1]); |
||||
|
|
||||
|
// Information requests A0 - A8 and A33
|
||||
|
if (req <= 8 || req == 33) PanelInfo(req); |
||||
|
|
||||
|
// Simple Actions A9 - A28
|
||||
|
else if ( req <= 28) PanelAction(req); |
||||
|
|
||||
|
// Process Initiation
|
||||
|
else if (req <= 34) PanelProcess(req); |
||||
|
|
||||
|
else SendtoTFTLN(); |
||||
|
} |
||||
|
|
||||
|
void ChironTFT::PanelInfo(uint8_t req) { |
||||
|
// information requests A0-A8 and A33
|
||||
|
switch (req) { |
||||
|
case 0: // A0 Get HOTEND Temp
|
||||
|
SendtoTFT(PSTR("A0V ")); |
||||
|
TFTSer.println(getActualTemp_celsius(E0)); |
||||
|
break; |
||||
|
|
||||
|
case 1: // A1 Get HOTEND Target Temp
|
||||
|
SendtoTFT(PSTR("A1V ")); |
||||
|
TFTSer.println(getTargetTemp_celsius(E0)); |
||||
|
break; |
||||
|
|
||||
|
case 2: // A2 Get BED Temp
|
||||
|
SendtoTFT(PSTR("A2V ")); |
||||
|
TFTSer.println(getActualTemp_celsius(BED)); |
||||
|
break; |
||||
|
|
||||
|
case 3: // A3 Get BED Target Temp
|
||||
|
SendtoTFT(PSTR("A3V ")); |
||||
|
TFTSer.println(getTargetTemp_celsius(BED)); |
||||
|
break; |
||||
|
|
||||
|
case 4: // A4 Get FAN Speed
|
||||
|
SendtoTFT(PSTR("A4V ")); |
||||
|
TFTSer.println(getActualFan_percent(FAN0)); |
||||
|
break; |
||||
|
|
||||
|
case 5: // A5 Get Current Coordinates
|
||||
|
SendtoTFT(PSTR("A5V X: ")); |
||||
|
TFTSer.print(getAxisPosition_mm(X)); |
||||
|
SendtoTFT(PSTR(" Y: ")); |
||||
|
TFTSer.print(getAxisPosition_mm(Y)); |
||||
|
SendtoTFT(PSTR(" Z: ")); |
||||
|
TFTSer.println(getAxisPosition_mm(Z)); |
||||
|
break; |
||||
|
|
||||
|
case 6: // A6 Get printing progress
|
||||
|
if (isPrintingFromMedia()) { |
||||
|
SendtoTFT(PSTR("A6V ")); |
||||
|
TFTSer.println(ui8tostr2(getProgress_percent())); |
||||
|
|
||||
|
} |
||||
|
else |
||||
|
SendtoTFTLN(PSTR("A6V ---")); |
||||
|
break; |
||||
|
|
||||
|
case 7: { // A7 Get Printing Time
|
||||
|
uint32_t time = getProgress_seconds_elapsed() / 60; |
||||
|
SendtoTFT(PSTR("A7V ")); |
||||
|
TFTSer.print(ui8tostr2(time / 60)); |
||||
|
SendtoTFT(PSTR(" H ")); |
||||
|
TFTSer.print(ui8tostr2(time % 60)); |
||||
|
SendtoTFT(PSTR(" M")); |
||||
|
#if ACDEBUG(AC_ALL) |
||||
|
SERIAL_ECHOLNPAIR("Print time ", ui8tostr2(time / 60), ":", ui8tostr2(time % 60)); |
||||
|
#endif |
||||
|
} break; |
||||
|
|
||||
|
case 8: // A8 Get SD Card list A8 S0
|
||||
|
if (!isMediaInserted()) safe_delay(500); |
||||
|
if (!isMediaInserted()) // Make sure the card is removed
|
||||
|
SendtoTFTLN(AC_msg_no_sd_card); |
||||
|
else if (panel_command[3] == 'S') |
||||
|
SendFileList( atoi( &panel_command[4] ) ); |
||||
|
break; |
||||
|
|
||||
|
case 33: // A33 Get firmware info
|
||||
|
SendtoTFT(PSTR("J33 ")); |
||||
|
SendtoTFTLN(PSTR(SHORT_BUILD_VERSION)); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void ChironTFT::PanelAction(uint8_t req) { |
||||
|
switch (req) { |
||||
|
case 9: // A9 Pause SD print
|
||||
|
if (isPrintingFromMedia()) { |
||||
|
SendtoTFTLN(AC_msg_pause); |
||||
|
pausePrint(); |
||||
|
printer_state = AC_printer_pausing; |
||||
|
} |
||||
|
else |
||||
|
SendtoTFTLN(AC_msg_stop); |
||||
|
break; |
||||
|
|
||||
|
case 10: // A10 Resume SD Print
|
||||
|
if (pause_state == AC_paused_idle || printer_state == AC_printer_resuming_from_power_outage) |
||||
|
resumePrint(); |
||||
|
else |
||||
|
setUserConfirmed(); |
||||
|
break; |
||||
|
|
||||
|
case 11: // A11 Stop SD print
|
||||
|
if (isPrintingFromMedia()) { |
||||
|
printer_state = AC_printer_stopping; |
||||
|
stopPrint(); |
||||
|
} |
||||
|
else { |
||||
|
if (printer_state == AC_printer_resuming_from_power_outage) |
||||
|
injectCommands_P(PSTR("M1000 C\n")); // Cancel recovery
|
||||
|
SendtoTFTLN(AC_msg_stop); |
||||
|
printer_state = AC_printer_idle; |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case 12: // A12 Kill printer
|
||||
|
kill(); // from marlincore.h
|
||||
|
break; |
||||
|
|
||||
|
case 13: // A13 Select file
|
||||
|
SelectFile(); |
||||
|
break; |
||||
|
|
||||
|
case 14: { // A14 Start Printing
|
||||
|
// Allows printer to restart the job if we dont want to recover
|
||||
|
if (printer_state == AC_printer_resuming_from_power_outage) { |
||||
|
injectCommands_P(PSTR("M1000 C\n")); // Cancel recovery
|
||||
|
printer_state = AC_printer_idle; |
||||
|
} |
||||
|
#if ACDebugLevel >= 1 |
||||
|
SERIAL_ECHOLNPAIR_F("Print: ", selectedfile); |
||||
|
#endif |
||||
|
// the card library needs a path starting // but the File api doesn't...
|
||||
|
char file[MAX_PATH_LEN]; |
||||
|
file[0] = '/'; |
||||
|
strcpy(file + 1, selectedfile); |
||||
|
printFile(file); |
||||
|
SendtoTFTLN(AC_msg_print_from_sd_card); |
||||
|
} break; |
||||
|
|
||||
|
case 15: // A15 Resuming from outage
|
||||
|
if (printer_state == AC_printer_resuming_from_power_outage) |
||||
|
// Need to home here to restore the Z position
|
||||
|
injectCommands_P(AC_cmnd_power_loss_recovery); |
||||
|
|
||||
|
injectCommands_P(PSTR("M1000\n")); // home and start recovery
|
||||
|
break; |
||||
|
|
||||
|
case 16: { // A16 Set HotEnd temp A17 S170
|
||||
|
const float set_Htemp = atof(&panel_command[5]); |
||||
|
hotend_state = set_Htemp ? AC_heater_temp_set : AC_heater_off; |
||||
|
switch ((char)panel_command[4]) { |
||||
|
// Set Temp
|
||||
|
case 'S': case 'C': setTargetTemp_celsius(set_Htemp, E0); |
||||
|
} |
||||
|
} break; |
||||
|
|
||||
|
case 17: { // A17 Set bed temp
|
||||
|
const float set_Btemp = atof(&panel_command[5]); |
||||
|
hotbed_state = set_Btemp ? AC_heater_temp_set : AC_heater_off; |
||||
|
if (panel_command[4] == 'S') |
||||
|
setTargetTemp_celsius(set_Btemp, BED); |
||||
|
} break; |
||||
|
|
||||
|
case 18: // A18 Set Fan Speed
|
||||
|
if (panel_command[4] == 'S') |
||||
|
setTargetFan_percent(atof(&panel_command[5]), FAN0); |
||||
|
break; |
||||
|
|
||||
|
case 19: // A19 Motors off
|
||||
|
if (!isPrinting()) { |
||||
|
disable_all_steppers(); // from marlincore.h
|
||||
|
SendtoTFTLN(AC_msg_ready); |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case 20: // A20 Read/write print speed
|
||||
|
if (panel_command[4] == 'S') |
||||
|
setFeedrate_percent(atoi(&panel_command[5])); |
||||
|
else { |
||||
|
SendtoTFT(PSTR("A20V ")); |
||||
|
TFTSer.println(getFeedrate_percent()); |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case 21: // A21 Home Axis A21 X
|
||||
|
if (!isPrinting()) { |
||||
|
switch ((char)panel_command[4]) { |
||||
|
case 'X': injectCommands_P(PSTR("G28 X\n")); break; |
||||
|
case 'Y': injectCommands_P(PSTR("G28 Y\n")); break; |
||||
|
case 'Z': injectCommands_P(PSTR("G28 Z\n")); break; |
||||
|
case 'C': injectCommands_P(PSTR("G28\n")); break; |
||||
|
} |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case 22: // A22 Move Axis A22 Y +10F3000
|
||||
|
// Ignore request if printing
|
||||
|
if (!isPrinting()) { |
||||
|
// setAxisPosition_mm() uses pre defined manual feedrates so ignore the feedrate from the panel
|
||||
|
setSoftEndstopState(true); // enable endstops
|
||||
|
float newposition = atof(&panel_command[6]); |
||||
|
|
||||
|
#if ACDEBUG(AC_ACTION) |
||||
|
SERIAL_ECHOLNPAIR("Nudge ", panel_command[4], " axis ", newposition); |
||||
|
#endif |
||||
|
|
||||
|
switch (panel_command[4]) { |
||||
|
case 'X': setAxisPosition_mm(getAxisPosition_mm(X) + newposition, X); break; |
||||
|
case 'Y': setAxisPosition_mm(getAxisPosition_mm(Y) + newposition, Y); break; |
||||
|
case 'Z': setAxisPosition_mm(getAxisPosition_mm(Z) + newposition, Z); break; |
||||
|
case 'E': // The only time we get this command is from the filament load/unload menu
|
||||
|
// the standard movement is too slow so we will use the load unlod GCode to speed it up a bit
|
||||
|
if (canMove(E0) && !commandsInQueue()) |
||||
|
injectCommands_P(newposition > 0 ? AC_cmnd_manual_load_filament : AC_cmnd_manual_unload_filament); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case 23: // A23 Preheat PLA
|
||||
|
// Ignore request if printing
|
||||
|
if (!isPrinting()) { |
||||
|
// Temps defined in configuration.h
|
||||
|
setTargetTemp_celsius(PREHEAT_1_TEMP_BED, BED); |
||||
|
setTargetTemp_celsius(PREHEAT_1_TEMP_HOTEND, E0); |
||||
|
SendtoTFTLN(); |
||||
|
hotbed_state = AC_heater_temp_set; |
||||
|
hotend_state = AC_heater_temp_set; |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case 24: // A24 Preheat ABS
|
||||
|
// Ignore request if printing
|
||||
|
if (!isPrinting()) { |
||||
|
setTargetTemp_celsius(PREHEAT_2_TEMP_BED, BED); |
||||
|
setTargetTemp_celsius(PREHEAT_2_TEMP_HOTEND, E0); |
||||
|
SendtoTFTLN(); |
||||
|
hotbed_state = AC_heater_temp_set; |
||||
|
hotend_state = AC_heater_temp_set; |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case 25: // A25 Cool Down
|
||||
|
// Ignore request if printing
|
||||
|
if (!isPrinting()) { |
||||
|
setTargetTemp_celsius(0, E0); |
||||
|
setTargetTemp_celsius(0, BED); |
||||
|
SendtoTFTLN(AC_msg_ready); |
||||
|
hotbed_state = AC_heater_off; |
||||
|
hotend_state = AC_heater_off; |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case 26: // A26 Refresh SD
|
||||
|
// M22 M21 maybe needed here to reset sd card
|
||||
|
filenavigator.reset(); |
||||
|
break; |
||||
|
|
||||
|
case 27: // A27 Servo Angles adjust
|
||||
|
break; |
||||
|
|
||||
|
case 28: // A28 Filament set A28 O/C
|
||||
|
// Ignore request if printing
|
||||
|
if (isPrinting()) break; |
||||
|
SendtoTFTLN(); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void ChironTFT::PanelProcess(uint8_t req) { |
||||
|
switch (req) { |
||||
|
case 29: { // A29 Read Mesh Point A29 X1 Y1
|
||||
|
xy_uint8_t pos; |
||||
|
float pos_z; |
||||
|
pos.x = atoi(&panel_command[5]); |
||||
|
pos.y = atoi(&panel_command[8]); |
||||
|
pos_z = getMeshPoint(pos); |
||||
|
|
||||
|
SendtoTFT(PSTR("A29V ")); |
||||
|
TFTSer.println(pos_z * 100); |
||||
|
if (!isPrinting()) { |
||||
|
setSoftEndstopState(true); // disable endstops
|
||||
|
// If the same meshpoint is selected twice in a row, move the head to that ready for adjustment
|
||||
|
if ((selectedmeshpoint.x == pos.x) && (selectedmeshpoint.y == pos.y)) { |
||||
|
if (!isPositionKnown()) |
||||
|
injectCommands_P(PSTR("G28\n")); // home
|
||||
|
|
||||
|
if (isPositionKnown()) { |
||||
|
#if ACDEBUG(AC_INFO) |
||||
|
SERIAL_ECHOLNPAIR("Moving to mesh point at x: ", pos.x, " y: ", pos.y, " z: ", pos_z); |
||||
|
#endif |
||||
|
// Go up before moving
|
||||
|
setAxisPosition_mm(3.0,Z); |
||||
|
|
||||
|
setAxisPosition_mm(17 + (93 * pos.x), X); |
||||
|
setAxisPosition_mm(20 + (93 * pos.y), Y); |
||||
|
setAxisPosition_mm(0.0, Z); |
||||
|
#if ACDEBUG(AC_INFO) |
||||
|
SERIAL_ECHOLNPAIR("Current Z: ", getAxisPosition_mm(Z)); |
||||
|
#endif |
||||
|
} |
||||
|
} |
||||
|
selectedmeshpoint.x = pos.x; |
||||
|
selectedmeshpoint.y = pos.y; |
||||
|
} |
||||
|
} break; |
||||
|
|
||||
|
case 30: { // A30 Auto leveling
|
||||
|
if (panel_command[3] == 'S') { // Start probing
|
||||
|
// Ignore request if printing
|
||||
|
if (isPrinting()) |
||||
|
SendtoTFTLN(AC_msg_probing_not_allowed); // forbid auto leveling
|
||||
|
else { |
||||
|
injectCommands_P(isMachineHomed() ? PSTR("G29") : PSTR("G28\nG29")); |
||||
|
printer_state = AC_printer_probing; |
||||
|
SendtoTFTLN(AC_msg_start_probing); |
||||
|
} |
||||
|
} |
||||
|
else SendtoTFTLN(AC_msg_start_probing); |
||||
|
} break; |
||||
|
|
||||
|
case 31: { // A31 Adjust all Probe Points
|
||||
|
switch (panel_command[3]) { |
||||
|
case 'C': // Restore and apply original offsets
|
||||
|
if (!isPrinting()) { |
||||
|
injectCommands_P(PSTR("M501\nM420 S1\n")); |
||||
|
selectedmeshpoint.x = 99; |
||||
|
selectedmeshpoint.y = 99; |
||||
|
} |
||||
|
break; |
||||
|
case 'D': // Save Z Offset tables and restore levelling state
|
||||
|
if (!isPrinting()) { |
||||
|
setAxisPosition_mm(1.0,Z); |
||||
|
injectCommands_P(PSTR("M500\n")); |
||||
|
selectedmeshpoint.x = 99; |
||||
|
selectedmeshpoint.y = 99; |
||||
|
} |
||||
|
break; |
||||
|
case 'G': // Get current offset
|
||||
|
SendtoTFT(PSTR("A31V ")); |
||||
|
// When printing use the live z Offset position
|
||||
|
// we will use babystepping to move the print head
|
||||
|
if (isPrinting()) |
||||
|
TFTSer.println(live_Zoffset); |
||||
|
else { |
||||
|
TFTSer.println(getZOffset_mm()); |
||||
|
selectedmeshpoint.x = 99; |
||||
|
selectedmeshpoint.y = 99; |
||||
|
} |
||||
|
break; |
||||
|
case 'S': { // Set offset (adjusts all points by value)
|
||||
|
float Zshift = atof(&panel_command[4]); |
||||
|
setSoftEndstopState(false); // disable endstops
|
||||
|
// Allow temporary Z position nudging during print
|
||||
|
// From the levelling panel use the all points UI to adjust the print pos.
|
||||
|
if (isPrinting()) { |
||||
|
#if ACDEBUG(AC_INFO) |
||||
|
SERIAL_ECHOLNPAIR("Change Zoffset from:", live_Zoffset, " to ", live_Zoffset + Zshift); |
||||
|
#endif |
||||
|
if (isAxisPositionKnown(Z)) { |
||||
|
#if ACDEBUG(AC_INFO) |
||||
|
const float currZpos = getAxisPosition_mm(Z); |
||||
|
SERIAL_ECHOLNPAIR("Nudge Z pos from ", currZpos, " to ", currZpos + constrain(Zshift, -0.05, 0.05)); |
||||
|
#endif |
||||
|
// Use babystepping to adjust the head position
|
||||
|
int16_t steps = mmToWholeSteps(constrain(Zshift,-0.05,0.05), Z); |
||||
|
#if ACDEBUG(AC_INFO) |
||||
|
SERIAL_ECHOLNPAIR("Steps to move Z: ", steps); |
||||
|
#endif |
||||
|
babystepAxis_steps(steps, Z); |
||||
|
live_Zoffset += Zshift; |
||||
|
} |
||||
|
SendtoTFT(PSTR("A31V ")); |
||||
|
TFTSer.println(live_Zoffset); |
||||
|
} |
||||
|
else { |
||||
|
GRID_LOOP(x, y) { |
||||
|
const xy_uint8_t pos { x, y }; |
||||
|
const float currval = getMeshPoint(pos); |
||||
|
setMeshPoint(pos, constrain(currval + Zshift, AC_LOWEST_MESHPOINT_VAL, 2)); |
||||
|
} |
||||
|
const float currZOffset = getZOffset_mm(); |
||||
|
#if ACDEBUG(AC_INFO) |
||||
|
SERIAL_ECHOLNPAIR("Change probe offset from ", currZOffset, " to ", currZOffset + Zshift); |
||||
|
#endif |
||||
|
|
||||
|
setZOffset_mm(currZOffset + Zshift); |
||||
|
SendtoTFT(PSTR("A31V ")); |
||||
|
TFTSer.println(getZOffset_mm()); |
||||
|
|
||||
|
if (isAxisPositionKnown(Z)) { |
||||
|
// Move Z axis
|
||||
|
const float currZpos = getAxisPosition_mm(Z); |
||||
|
#if ACDEBUG(AC_INFO) |
||||
|
SERIAL_ECHOLNPAIR("Move Z pos from ", currZpos, " to ", currZpos + constrain(Zshift, -0.05, 0.05)); |
||||
|
#endif |
||||
|
setAxisPosition_mm(currZpos+constrain(Zshift,-0.05,0.05),Z); |
||||
|
} |
||||
|
} |
||||
|
} break; |
||||
|
} // end switch
|
||||
|
} break; |
||||
|
|
||||
|
case 32: { // A32 clean leveling beep flag
|
||||
|
// Ignore request if printing
|
||||
|
//if (isPrinting()) break;
|
||||
|
//injectCommands_P(PSTR("M500\nM420 S1\nG1 Z10 F240\nG1 X0 Y0 F6000"));
|
||||
|
//TFTSer.println("");
|
||||
|
} break; |
||||
|
|
||||
|
// A33 firmware info request seet PanelInfo()
|
||||
|
|
||||
|
case 34: { // A34 Adjust single mesh point A34 C/S X1 Y1 V123
|
||||
|
if (panel_command[3] == 'C') { // Restore original offsets
|
||||
|
injectCommands_P(PSTR("M501\nM420 S1")); |
||||
|
selectedmeshpoint.x = 99; |
||||
|
selectedmeshpoint.y = 99; |
||||
|
//printer_state = AC_printer_idle;
|
||||
|
} |
||||
|
else { |
||||
|
xy_uint8_t pos; |
||||
|
pos.x = atoi(&panel_command[5]); |
||||
|
pos.y = atoi(&panel_command[8]); |
||||
|
|
||||
|
float currmesh = getMeshPoint(pos); |
||||
|
float newval = atof(&panel_command[11])/100; |
||||
|
#if ACDEBUG(AC_INFO) |
||||
|
SERIAL_ECHOLNPAIR("Change mesh point x:", pos.x, " y:", pos.y); |
||||
|
SERIAL_ECHOLNPAIR("from ", currmesh, " to ", newval); |
||||
|
#endif |
||||
|
// Update Meshpoint
|
||||
|
setMeshPoint(pos,newval); |
||||
|
if ( (printer_state == AC_printer_idle) || (printer_state == AC_printer_probing) ) {//!isPrinting()) {
|
||||
|
// if we are at the current mesh point indicated on the panel Move Z pos +/- 0.05mm ( The panel changes the mesh value by +/- 0.05mm on each button press)
|
||||
|
if ((selectedmeshpoint.x == pos.x) && (selectedmeshpoint.y == pos.y)) { |
||||
|
setSoftEndstopState(false); |
||||
|
float currZpos = getAxisPosition_mm(Z); |
||||
|
#if ACDEBUG(AC_INFO) |
||||
|
SERIAL_ECHOLNPAIR("Move Z pos from ", currZpos, " to ", currZpos + constrain(newval - currmesh, -0.05, 0.05)); |
||||
|
#endif |
||||
|
setAxisPosition_mm(currZpos + constrain(newval - currmesh, -0.05, 0.05), Z); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} break; |
||||
|
} |
||||
|
} |
||||
|
} // namespace
|
||||
|
|
||||
|
#endif // ANYCUBIC_LCD_CHIRON
|
@ -0,0 +1,77 @@ |
|||||
|
/**
|
||||
|
* Marlin 3D Printer Firmware |
||||
|
* Copyright (c) 2020 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/>.
|
||||
|
* |
||||
|
*/ |
||||
|
#pragma once |
||||
|
|
||||
|
/**
|
||||
|
* lcd/extui/lib/chiron_tft.h |
||||
|
* |
||||
|
* Extensible_UI implementation for Anycubic Chiron |
||||
|
* Written By Nick Wells, 2020 [https://github.com/SwiftNick]
|
||||
|
* (not affiliated with Anycubic, Ltd.) |
||||
|
*/ |
||||
|
|
||||
|
#include "chiron_tft_defs.h" |
||||
|
#include "../../../../inc/MarlinConfigPre.h" |
||||
|
#include "../../ui_api.h" |
||||
|
namespace Anycubic { |
||||
|
|
||||
|
class ChironTFT { |
||||
|
static printer_state_t printer_state; |
||||
|
static paused_state_t pause_state; |
||||
|
static heater_state_t hotend_state; |
||||
|
static heater_state_t hotbed_state; |
||||
|
static xy_uint8_t selectedmeshpoint; |
||||
|
static char panel_command[MAX_CMND_LEN]; |
||||
|
static uint8_t command_len; |
||||
|
static char selectedfile[MAX_PATH_LEN]; |
||||
|
static float live_Zoffset; |
||||
|
static file_menu_t file_menu; |
||||
|
public: |
||||
|
ChironTFT(); |
||||
|
void Startup(); |
||||
|
void IdleLoop(); |
||||
|
void PrinterKilled(PGM_P,PGM_P); |
||||
|
void MediaEvent(media_event_t); |
||||
|
void TimerEvent(timer_event_t); |
||||
|
void FilamentRunout(); |
||||
|
void ConfirmationRequest(const char * const ); |
||||
|
void StatusChange(const char * const ); |
||||
|
void PowerLossRecovery(); |
||||
|
|
||||
|
private: |
||||
|
void SendtoTFT(PGM_P); |
||||
|
void SendtoTFTLN(PGM_P); |
||||
|
bool ReadTFTCommand(); |
||||
|
int8_t Findcmndpos(const char *, char); |
||||
|
void CheckHeaters(); |
||||
|
void SendFileList(int8_t); |
||||
|
void SelectFile(); |
||||
|
void InjectCommandandWait(PGM_P); |
||||
|
void ProcessPanelRequest(); |
||||
|
void PanelInfo(uint8_t); |
||||
|
void PanelAction(uint8_t); |
||||
|
void PanelProcess(uint8_t); |
||||
|
}; |
||||
|
|
||||
|
extern ChironTFT Chiron; |
||||
|
|
||||
|
} |
@ -0,0 +1,151 @@ |
|||||
|
/**
|
||||
|
* Marlin 3D Printer Firmware |
||||
|
* Copyright (c) 2020 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/>.
|
||||
|
* |
||||
|
*/ |
||||
|
|
||||
|
/**
|
||||
|
* lcd/extui/lib/chiron_defs.h |
||||
|
* |
||||
|
* Extensible_UI implementation for Anycubic Chiron |
||||
|
* Written By Nick Wells, 2020 [https://github.com/SwiftNick]
|
||||
|
* (not affiliated with Anycubic, Ltd.) |
||||
|
*/ |
||||
|
|
||||
|
#pragma once |
||||
|
#include "../../../../inc/MarlinConfigPre.h" |
||||
|
//#define ACDEBUGLEVEL 255
|
||||
|
|
||||
|
#if ACDEBUGLEVEL |
||||
|
// Bit-masks for selective debug:
|
||||
|
enum ACDebugMask : uint8_t { |
||||
|
AC_INFO = 1, |
||||
|
AC_ACTION = 2, |
||||
|
AC_FILE = 4, |
||||
|
AC_PANEL = 8, |
||||
|
AC_MARLIN = 16, |
||||
|
AC_SOME = 32, |
||||
|
AC_ALL = 64 |
||||
|
}; |
||||
|
#define ACDEBUG(mask) ( ((mask) & ACDEBUGLEVEL) == mask ) // Debug flag macro
|
||||
|
#else |
||||
|
#define ACDEBUG(mask) false |
||||
|
#endif |
||||
|
|
||||
|
#define TFTSer LCD_SERIAL // Serial interface for TFT panel now uses marlinserial
|
||||
|
#define MAX_FOLDER_DEPTH 4 // Limit folder depth TFT has a limit for the file path
|
||||
|
#define MAX_CMND_LEN 16 * MAX_FOLDER_DEPTH // Maximum Length for a Panel command
|
||||
|
#define MAX_PATH_LEN 16 * MAX_FOLDER_DEPTH // Maximum number of characters in a SD file path
|
||||
|
|
||||
|
#define AC_HEATER_FAULT_VALIDATION_TIME 5 // number of 1/2 second loops before signalling a heater fault
|
||||
|
#define AC_LOWEST_MESHPOINT_VAL -7.00 // The lowest value you can set for a single mesh point offset
|
||||
|
|
||||
|
// TFT panel commands
|
||||
|
#define AC_msg_sd_card_inserted PSTR("J00") |
||||
|
#define AC_msg_sd_card_removed PSTR("J01") |
||||
|
#define AC_msg_no_sd_card PSTR("J02") |
||||
|
#define AC_msg_usb_connected PSTR("J03") |
||||
|
#define AC_msg_print_from_sd_card PSTR("J04") |
||||
|
#define AC_msg_pause PSTR("J05") |
||||
|
#define AC_msg_nozzle_heating PSTR("J06") |
||||
|
#define AC_msg_nozzle_heating_done PSTR("J07") |
||||
|
#define AC_msg_bed_heating PSTR("J08") |
||||
|
#define AC_msg_bed_heating_done PSTR("J09") |
||||
|
#define AC_msg_nozzle_temp_abnormal PSTR("J10") |
||||
|
#define AC_msg_kill_lcd PSTR("J11") |
||||
|
#define AC_msg_ready PSTR("J12") |
||||
|
#define AC_msg_low_nozzle_temp PSTR("J13") |
||||
|
#define AC_msg_print_complete PSTR("J14") |
||||
|
#define AC_msg_filament_out_alert PSTR("J15") |
||||
|
#define AC_msg_stop PSTR("J16") |
||||
|
#define AC_msg_main_board_has_reset PSTR("J17") |
||||
|
#define AC_msg_paused PSTR("J18") |
||||
|
#define AC_msg_j19_unknown PSTR("J19") |
||||
|
#define AC_msg_sd_file_open_success PSTR("J20") |
||||
|
#define AC_msg_sd_file_open_failed PSTR("J21") |
||||
|
#define AC_msg_level_monitor_finished PSTR("J22") |
||||
|
#define AC_msg_filament_out_block PSTR("J23") |
||||
|
#define AC_msg_probing_not_allowed PSTR("J24") |
||||
|
#define AC_msg_probing_complete PSTR("J25") |
||||
|
#define AC_msg_start_probing PSTR("J26") |
||||
|
#define AC_msg_version PSTR("J27") |
||||
|
|
||||
|
#define MARLIN_msg_start_probing PSTR("Probing Point 1/25") |
||||
|
#define MARLIN_msg_probing_failed PSTR("Probing Failed") |
||||
|
#define MARLIN_msg_ready PSTR("3D Printer Ready.") |
||||
|
#define MARLIN_msg_print_paused PSTR("Print Paused") |
||||
|
#define MARLIN_msg_print_aborted PSTR("Print Aborted") |
||||
|
#define MARLIN_msg_extruder_heating PSTR("E Heating...") |
||||
|
#define MARLIN_msg_bed_heating PSTR("Bed Heating...") |
||||
|
|
||||
|
#define MARLIN_msg_nozzle_parked PSTR("Nozzle Parked") |
||||
|
#define MARLIN_msg_heater_timeout PSTR("Heater Timeout") |
||||
|
#define MARLIN_msg_reheating PSTR("Reheating...") |
||||
|
#define MARLIN_msg_reheat_done PSTR("Reheat finished.") |
||||
|
#define MARLIN_msg_filament_purging PSTR("Filament Purging...") |
||||
|
#define MARLIN_msg_special_pause PSTR("PB") |
||||
|
#define AC_cmnd_auto_unload_filament PSTR("M701") // Use Marlin unload routine
|
||||
|
#define AC_cmnd_auto_load_filament PSTR("M702 M0 PB") // Use Marlin load routing then pause for user to clean nozzle
|
||||
|
|
||||
|
#define AC_cmnd_manual_load_filament PSTR("M83\nG1 E50 F700\nM82") // replace the manual panel commands with something a little faster
|
||||
|
#define AC_cmnd_manual_unload_filament PSTR("M83\nG1 E-50 F1200\nM82") |
||||
|
#define AC_cmnd_enable_levelling PSTR("M420 S1 V1") |
||||
|
#define AC_cmnd_power_loss_recovery PSTR("G28 X Y R5\nG28 Z") // Lift, home X and Y then home Z when in 'safe' position
|
||||
|
|
||||
|
namespace Anycubic { |
||||
|
enum heater_state_t : uint8_t { |
||||
|
AC_heater_off, |
||||
|
AC_heater_temp_set, |
||||
|
AC_heater_temp_reached |
||||
|
}; |
||||
|
|
||||
|
enum paused_state_t : uint8_t { |
||||
|
AC_paused_heater_timed_out, |
||||
|
AC_paused_purging_filament, |
||||
|
AC_paused_idle |
||||
|
}; |
||||
|
|
||||
|
enum printer_state_t : uint8_t { |
||||
|
AC_printer_idle, |
||||
|
AC_printer_probing, |
||||
|
AC_printer_printing, |
||||
|
AC_printer_pausing, |
||||
|
AC_printer_paused, |
||||
|
AC_printer_stopping, |
||||
|
AC_printer_resuming_from_power_outage |
||||
|
}; |
||||
|
|
||||
|
enum timer_event_t : uint8_t { |
||||
|
AC_timer_started, |
||||
|
AC_timer_paused, |
||||
|
AC_timer_stopped |
||||
|
}; |
||||
|
|
||||
|
enum media_event_t : uint8_t { |
||||
|
AC_media_inserted, |
||||
|
AC_media_removed, |
||||
|
AC_media_error |
||||
|
}; |
||||
|
enum file_menu_t : uint8_t { |
||||
|
AC_menu_file, |
||||
|
AC_menu_command, |
||||
|
AC_menu_change_to_file, |
||||
|
AC_menu_change_to_command |
||||
|
}; |
||||
|
} |
Loading…
Reference in new issue