File indexing completed on 2024-05-12 04:41:09
0001 /* AtCore KDE Libary for 3D Printers 0002 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0003 SPDX-FileCopyrightText: 2016, 2018 Tomaz Canabrava <tcanabrava@kde.org> 0004 SPDX-FileCopyrightText: 2016-2019 Chris Rizzitello <rizzitello@kde.org> 0005 SPDX-FileCopyrightText: 2016-2019 Patrick José Pereira <patrickjp@kde.org> 0006 SPDX-FileCopyrightText: 2016, 2019 Lays Rodrigues <lays.rodrigues@kde.org> 0007 SPDX-FileCopyrightText: 2018 Leandro Santiago <leandrosansilva@gmail.com> 0008 */ 0009 0010 #pragma once 0011 #include <QObject> 0012 #include <QSerialPort> 0013 #include <QSerialPortInfo> 0014 #include <memory> 0015 0016 #include "atcore_export.h" 0017 #include "beddeform.h" 0018 #include "ifirmware.h" 0019 #include "temperature.h" 0020 0021 class SerialLayer; 0022 class IFirmware; 0023 class QTime; 0024 0025 /** 0026 * @brief The AtCore class 0027 * aims to provides a high level interface for serial based gcode devices<br /> 0028 * 0029 * #### General Workflow 0030 * - Connect to a serial port with newConnection() 0031 * - Send commands to the device (pushCommand(), print(), ...) 0032 * - AtCore::close() when you are all done. 0033 0034 * #### How AtCore Finds Plugins. 0035 * AtCore will check each directory below for plugins. 0036 * 1. QApplication::applicationDirPath/plugins (runtime) 0037 * 2. QApplication::applicationDirPath/AtCore (runtime) 0038 * 3. QApplication::applicationDirPath/../PlugIns/AtCore (runtime) 0039 * 4. Fullpath of KDE_PLUGIN_DIR (buildtime) 0040 * 5. Qt Plugin path/AtCore (runtime) 0041 * 6. ECM set KDE PLUGIN DIR (buildtime) 0042 * 7. Build Dir/plugins (buildtime) 0043 */ 0044 class ATCORE_EXPORT AtCore : public QObject 0045 { 0046 Q_OBJECT 0047 Q_PROPERTY(QString version READ version CONSTANT) 0048 Q_PROPERTY(QStringList availableFirmwarePlugins READ availableFirmwarePlugins NOTIFY availableFirmwarePluginsChanged) 0049 Q_PROPERTY(int extruderCount READ extruderCount WRITE setExtruderCount NOTIFY extruderCountChanged) 0050 Q_PROPERTY(int temperatureTimerInterval READ temperatureTimerInterval WRITE setTemperatureTimerInterval NOTIFY temperatureTimerIntervalChanged); 0051 Q_PROPERTY(int serialTimerInterval READ serialTimerInterval WRITE setSerialTimerInterval NOTIFY serialTimerIntervalChanged) 0052 Q_PROPERTY(QStringList serialPorts READ serialPorts NOTIFY portsChanged) 0053 Q_PROPERTY(float percentagePrinted READ percentagePrinted NOTIFY printProgressChanged) 0054 Q_PROPERTY(QStringList portSpeeds READ portSpeeds CONSTANT) 0055 Q_PROPERTY(QString connectedPort READ connectedPort CONSTANT) 0056 Q_PROPERTY(AtCore::STATES state READ state WRITE setState NOTIFY stateChanged) 0057 Q_PROPERTY(bool sdMount READ isSdMounted WRITE setSdMounted NOTIFY sdMountChanged) 0058 Q_PROPERTY(QStringList sdFileList READ sdFileList NOTIFY sdCardFileListChanged) 0059 Q_PROPERTY(bool autoTemperatureReport READ autoTemperatureReport WRITE setAutoTemperatureReport NOTIFY autoTemperatureReportChanged) 0060 Q_PROPERTY(Temperature *temperature READ temperature CONSTANT) 0061 0062 friend class AtCoreTests; 0063 // Add friends as Sd Card support is extended to more plugins. 0064 friend class RepetierPlugin; 0065 friend class MarlinPlugin; 0066 // friend class SmoothiePlugin; 0067 // friend class TeacupPlugin; 0068 // friend class AprinterPlugin; 0069 // friend class SprinterPlugin; 0070 0071 public: 0072 /** 0073 * @brief STATES enum Possible states the printer can be in 0074 */ 0075 enum STATES { 0076 DISCONNECTED, //!< Not Connected to a printer, initial state 0077 CONNECTING, //!< Attempting to connect, Fw not probed 0078 IDLE, //!< Connected to printer and ready for commands 0079 BUSY, //!< Printer is Printing or working 0080 PAUSE, //!< Printer is paused 0081 ERRORSTATE, //!< Printer Returned Error 0082 STOP, //!< Stop Printing and Clean Queue 0083 STARTPRINT, //!< Just Starting a print job 0084 FINISHEDPRINT, //!< Just Finished print job 0085 }; 0086 Q_ENUM(STATES) 0087 /** 0088 * @brief The AXES enum - Printer Axes. 0089 */ 0090 enum AXES { 0091 X = 1 << 0, //!< X Axis: X Motor 0092 Y = 1 << 1, //!< Y Axis Y Motor 0093 Z = 1 << 2, //!< Z Axis Z Motor 0094 E = 1 << 3, //!< E Axis: Extruder Motor 0 0095 }; 0096 Q_ENUM(AXES) 0097 /** 0098 * @brief The UNITS enum - Possible Mesurment Units 0099 */ 0100 enum UNITS { 0101 METRIC, //!< Metric Units (Meters) 0102 IMPERIAL //!< Imperial Units (Feet) 0103 }; 0104 Q_ENUM(UNITS) 0105 /** 0106 * @brief AtCore create a new instance of AtCore 0107 * @param parent: parent of the object 0108 */ 0109 explicit AtCore(QObject *parent = nullptr); 0110 ~AtCore(); 0111 0112 /** 0113 * @brief version 0114 * @return Version number 0115 */ 0116 QString version() const; 0117 0118 /** 0119 * @brief Returns a List of detected serial ports 0120 * @return List of detected ports 0121 * @sa newConnection(), serial(), closeConnection() 0122 */ 0123 QStringList serialPorts() const; 0124 0125 /** 0126 * @brief connectedPort 0127 * @return the port atcore is connected to or empty string if none 0128 */ 0129 QString connectedPort() const; 0130 0131 /** 0132 * @brief Connect to a device. 0133 * @param port: the port to initialize 0134 * @param baud: the baud of the port 0135 * @param fwName: Firmware name of plugin to use (will try to autodetect if fwName is unknown) 0136 * @param disableROC: atcore will attempt to disable reset on connect for this device. 0137 * @return True is connection was successful 0138 * @sa serialPorts(), serial(), closeConnection() 0139 */ 0140 Q_INVOKABLE bool newConnection(const QString &port, int baud, const QString &fwName, bool disableROC = false); 0141 0142 /** 0143 * @brief Returns a list of valid baud speeds 0144 */ 0145 QStringList portSpeeds() const; 0146 0147 /** 0148 * @brief Close the current serial connection 0149 * @sa newConnection(), serial(), serialPorts(), close() 0150 */ 0151 Q_INVOKABLE void closeConnection(); 0152 0153 /** 0154 * @brief Main access to the loaded firmware plugin 0155 * @return IFirmware * to currently loaded plugin 0156 * @sa availableFirmwarePlugins(), loadFirmwarePlugin() 0157 */ 0158 Q_INVOKABLE IFirmware *firmwarePlugin() const; 0159 0160 /** 0161 * @brief List of available firmware plugins 0162 * @sa loadFirmwarePlugin(), firmwarePlugin() 0163 */ 0164 QStringList availableFirmwarePlugins() const; 0165 0166 /** 0167 * @brief Get Printer state 0168 * @return State of the printer 0169 * @sa setState(), stateChanged(), AtCore::STATES 0170 */ 0171 AtCore::STATES state(); 0172 0173 /** 0174 * @brief extruderCount 0175 * @return The number of detected Extruders Default is 1 0176 * @sa setExtruderCount(int newCount), extruderCountChanged(int newCount) 0177 */ 0178 int extruderCount() const; 0179 0180 /** 0181 * @brief Return printed percentage 0182 * @sa printProgressChanged() 0183 */ 0184 float percentagePrinted() const; 0185 0186 /** 0187 * @brief The Bed Deform data as told by the Firmware. 0188 */ 0189 std::shared_ptr<BedDeform> bedDeform(); 0190 0191 /** 0192 * @brief The temperature of the current hotend as told by the Firmware. 0193 */ 0194 Temperature *temperature(); 0195 0196 /** 0197 * @brief Return the amount of miliseconds the serialTimer is set to. 0 = Disabled 0198 */ 0199 int serialTimerInterval() const; 0200 0201 /** 0202 * @brief Return the amount of miliseconds the temperatureTimer is set to. 0 = Disabled 0203 */ 0204 int temperatureTimerInterval() const; 0205 0206 /** 0207 * @brief Attempt to Mount an sd card 0208 * @param slot: Sd card Slot on machine (0 is default) 0209 */ 0210 Q_INVOKABLE void mountSd(uint slot = 0); 0211 0212 /** 0213 * @brief Attempt to Unmount an sd card 0214 * @param slot: Sd card Slot on machine (0 is default) 0215 */ 0216 Q_INVOKABLE void umountSd(uint slot = 0); 0217 0218 /** 0219 * @brief sdFileList 0220 * @return List of files on the sd card. 0221 */ 0222 QStringList sdFileList(); 0223 0224 /** 0225 * @brief Check if an sd card is mounted on the printer 0226 * @return True if card mounted 0227 */ 0228 bool isSdMounted() const; 0229 0230 /** 0231 * @brief Check if using automatic Temperature reporting to monitor temperatures 0232 * @return True if using automatic temperature reporting 0233 */ 0234 bool autoTemperatureReport() const; 0235 0236 signals: 0237 0238 /** 0239 * @brief Message emit from atcore these should be displayed to the user for debug. 0240 * 0241 * Possable Messages Are: 0242 * - Waiting for firmware detect. 0243 * - No Plugin found for (detected FW) 0244 * - Failed to open device in Read / Write mode. 0245 * - Device Errors. 0246 * @param msg: the message. 0247 */ 0248 void atcoreMessage(const QString &msg); 0249 0250 /** 0251 * @brief New number of extruders 0252 * @sa extruderCount(), setExtruderCount(int newCount) 0253 */ 0254 void extruderCountChanged(const int newCount); 0255 0256 /** 0257 * @brief Print job's precentage changed. 0258 * @param newProgress : Message 0259 * @sa percentagePrinted() 0260 */ 0261 void printProgressChanged(const float newProgress); 0262 0263 /** 0264 * @brief New message was received from the printer 0265 * @param message: Message that was received 0266 */ 0267 void receivedMessage(const QByteArray &message); 0268 0269 /** 0270 * @brief New interval for serial timer 0271 * @sa setSerialTimerInterval() 0272 */ 0273 void serialTimerIntervalChanged(const int newTime); 0274 0275 /** 0276 * @brief New interval for temperature timer 0277 * @sa setTemperatureTimerInterval() 0278 */ 0279 void temperatureTimerIntervalChanged(const int newTime); 0280 0281 /** 0282 * @brief use of automatic temperature reporting has changed 0283 * @param autoReport: True if using automatic Reporting mode. 0284 */ 0285 void autoTemperatureReportChanged(bool autoReport); 0286 0287 /** 0288 * @brief New interval for automatic temperature report 0289 * @sa setautoTemperatureReport() 0290 */ 0291 void autoCheckTemperatureIntervalChanged(const int newTime); 0292 0293 /** 0294 * @brief The Printer's State Changed 0295 * @param newState : the new state of the printer 0296 * @sa setState(), state(), AtCore::STATES 0297 */ 0298 void stateChanged(AtCore::STATES newState); 0299 0300 /** 0301 * @brief Available serialports Changed 0302 */ 0303 void portsChanged(const QStringList &portList); 0304 0305 /** 0306 * @brief Sd Card Mount Changed 0307 */ 0308 void sdMountChanged(bool newState); 0309 0310 /** 0311 * @brief The files on the sd card have changed. 0312 */ 0313 void sdCardFileListChanged(const QStringList &fileList); 0314 0315 /** 0316 * @brief pushedCommand via serialLayer connect this to your log to see send commands 0317 * @param comm: the command sent. 0318 */ 0319 void pushedCommand(const QByteArray &comm); 0320 0321 /** 0322 * @brief availableFirmwarePluginsChanged notify about the new plugins available 0323 */ 0324 void availableFirmwarePluginsChanged(); 0325 0326 public slots: 0327 0328 /** 0329 * @brief Set the printers state 0330 * @param state : printer state. 0331 * @sa state(), stateChanged(), AtCore::STATES 0332 */ 0333 void setState(AtCore::STATES state); 0334 0335 /** 0336 * @brief updateFWPlugins Check for new Firmware plugins. 0337 */ 0338 Q_INVOKABLE void updateFWPlugins(); 0339 0340 /** 0341 * @brief Push a command into the command queue 0342 * 0343 * @param comm : Command 0344 */ 0345 Q_INVOKABLE void pushCommand(const QString &comm); 0346 0347 /** 0348 * @brief Public Interface for printing a file 0349 * @param fileName: the gcode file to print. 0350 * @param sdPrint: set true to print fileName from Sd card 0351 */ 0352 Q_INVOKABLE void print(const QString &fileName, bool sdPrint = false); 0353 0354 /** 0355 * @brief Stop the Printer by empting the queue and aborting the print job (if running) 0356 * @sa emergencyStop(), pause(), resume() 0357 */ 0358 Q_INVOKABLE void stop(); 0359 0360 /** 0361 * @brief stop the printer via the emergency stop Command (M112) 0362 * @sa stop(), pause(), resume() 0363 */ 0364 Q_INVOKABLE void emergencyStop(); 0365 0366 /** 0367 * @brief pause an in process print job 0368 * 0369 * Sends M114 on pause to store the location where the head stoped. 0370 * This is known to cause problems on fake printers 0371 * @param pauseActions: Gcode to run after pausing commands are ',' separated 0372 * @sa resume(), stop(), emergencyStop() 0373 */ 0374 void pause(const QString &pauseActions); 0375 0376 /** 0377 * @brief resume a paused print job. 0378 * After returning to location pause was triggered. 0379 * @sa pause(), stop(), emergencyStop() 0380 */ 0381 Q_INVOKABLE void resume(); 0382 0383 /** 0384 * @brief Send home \p axis command 0385 * @param axis: the axis(es) to home (use X Y Z or any combo of) 0386 * @sa home(), move() 0387 */ 0388 Q_INVOKABLE void home(uchar axis); 0389 0390 /** 0391 * @brief Send home all command 0392 * @sa home(uchar axis), move() 0393 */ 0394 Q_INVOKABLE void home(); 0395 0396 /** 0397 * @brief Set extruder temperature 0398 * @param temp : new temperature 0399 * @param extruder : extruder number 0400 * @param andWait: True for heat and ignore commands until temperature is reached 0401 */ 0402 Q_INVOKABLE void setExtruderTemp(uint temp = 0, uint extruder = 0, bool andWait = false); 0403 0404 /** 0405 * @brief move an axis of the printer 0406 * @param axis the axis to move AXES (X Y Z E ) 0407 * @param arg the distance to move the axis or the place to move to depending on printer mode 0408 * @sa home(), home(uchar axis), move(QLatin1Char axis, int arg) 0409 */ 0410 Q_INVOKABLE void move(AtCore::AXES axis, double arg); 0411 0412 /** 0413 * @brief move an axis of the printer 0414 * @param axis the axis to move AXES (X Y Z E ) 0415 * @param arg the distance to move the axis or the place to move to depending on printer mode 0416 * @sa home(), home(uchar axis), move(AtCore::AXES, int arg) 0417 */ 0418 Q_INVOKABLE void move(QLatin1Char axis, double arg); 0419 0420 /** 0421 * @brief Set the bed temperature 0422 * @param temp : new temperature 0423 * @param andWait: True for heat and ignore commands until temperature is reached 0424 * @sa setExtruderTemp() 0425 */ 0426 Q_INVOKABLE void setBedTemp(uint temp = 0, bool andWait = false); 0427 0428 /** 0429 * @brief setFanSpeed set the fan speed 0430 * @param fanNumber: fan number 0431 * @param speed: new speed of the fan 0-100 0432 */ 0433 Q_INVOKABLE void setFanSpeed(uint speed = 0, uint fanNumber = 0); 0434 0435 /** 0436 * @brief Set printer to absolute position mode 0437 * @sa setRelativePosition() 0438 */ 0439 Q_INVOKABLE void setAbsolutePosition(); 0440 0441 /** 0442 * @brief Set printer to relative position mode 0443 * @sa setAbsolutePosition() 0444 */ 0445 Q_INVOKABLE void setRelativePosition(); 0446 0447 /** 0448 * @brief Disable motors after a delay 0449 * @param delay: Seconds until motors are disabled. 0= No delay 0450 */ 0451 Q_INVOKABLE void disableMotors(uint delay = 0); 0452 0453 /** 0454 * @brief set the Printers speed 0455 * @param speed: speed in % (default is 100); 0456 */ 0457 Q_INVOKABLE void setPrinterSpeed(uint speed = 100); 0458 0459 /** 0460 * @brief set extruder Flow rate 0461 * @param rate: flow rate in % (default is 100) 0462 */ 0463 Q_INVOKABLE void setFlowRate(uint rate = 100); 0464 0465 /** 0466 * @brief close any open items. 0467 * You should call this on close events to force any stuck jobs to close 0468 * @sa closeConnection() 0469 */ 0470 Q_INVOKABLE void close(); 0471 0472 /** 0473 * @brief showMessage push a message to the printers LCD 0474 * @param message: message to show on the LCD 0475 */ 0476 Q_INVOKABLE void showMessage(const QString &message); 0477 0478 /** 0479 * @brief setUnits sets the measurement units do be used 0480 * @param units : the measurement units to use(METRIC / IMPERIAL) 0481 * @sa AtCore::UNITS 0482 */ 0483 Q_INVOKABLE void setUnits(AtCore::UNITS units); 0484 0485 /** 0486 * @brief Set the time between checks for new serialPorts (0 is default) 0487 * @param newTime: Milliseconds between checks. values <= 0 will Disable Checks. 0488 */ 0489 void setSerialTimerInterval(int newTime); 0490 0491 /** 0492 * @brief Set the time between checks for new Temperature (5000 is default on new connections) 0493 * @param newTime: Milliseconds between checks. values <= 0 will Disable Checks. 0494 */ 0495 void setTemperatureTimerInterval(int newTime); 0496 0497 /** @brief Set if atcore should Enable auto temperature reporting. Temperature timer will also be stopped. 0498 * @param autoReport: True to enable automatic reporting of temperatures. 0499 * @sa setAutoCheckTemperature 0500 */ 0501 void setAutoTemperatureReport(bool autoReport); 0502 0503 /** 0504 * @brief Tell the machine to start reporting its temperature automaticly 0505 * @param newTime: Time in seconds between reports (0: disabled) 0506 */ 0507 Q_INVOKABLE void setAutoCheckTemperatureInterval(int newTime); 0508 0509 /** 0510 * @brief delete file from sd card 0511 */ 0512 Q_INVOKABLE void sdDelete(const QString &fileName); 0513 0514 /** 0515 * @brief Queue the Printer for status of sd card print 0516 */ 0517 void sdCardPrintStatus(); 0518 0519 private slots: 0520 /** 0521 * @brief processQueue send commands from the queue. 0522 */ 0523 void processQueue(); 0524 0525 /** 0526 * @brief Send M105 to the printer if one is not in the Queue 0527 */ 0528 void checkTemperature(); 0529 0530 /** 0531 * @brief Connect to SerialLayer::receivedCommand 0532 * @param message: new message. 0533 */ 0534 void newMessage(const QByteArray &message); 0535 0536 /** 0537 * @brief Connect to SerialLayer::pushedCommand 0538 * @param command: newCommand. 0539 */ 0540 void newCommand(const QByteArray &command); 0541 0542 /** 0543 * @brief Search for firmware string in message. 0544 * A Helper function for Firmware detection 0545 * @param message 0546 */ 0547 void findFirmware(const QByteArray &message); 0548 0549 /** 0550 * @brief Search for new serial ports 0551 */ 0552 void locateSerialPort(); 0553 0554 /** 0555 * @brief Attempts to disableResetOnConnect for the selected port. 0556 * @param port: the port. 0557 */ 0558 void disableResetOnConnect(const QString &port); 0559 0560 /** 0561 * @brief Send request to the printer for the sd card file list. 0562 */ 0563 void getSDFileList(); 0564 0565 /** 0566 * @brief Handle serial Errors. 0567 */ 0568 void handleSerialError(QSerialPort::SerialPortError error); 0569 0570 private: 0571 /** 0572 * @brief Load A firmware plugin 0573 * @param fwName : name of the firmware 0574 * @sa firmwarePlugin(), availableFirmwarePlugins() 0575 */ 0576 Q_INVOKABLE void loadFirmwarePlugin(const QString &fwName); 0577 0578 /** 0579 * @brief True if a firmware plugin is loaded 0580 */ 0581 bool firmwarePluginLoaded() const; 0582 0583 /** 0584 * @brief True if a serial port is initialized 0585 */ 0586 bool serialInitialized() const; 0587 0588 /** 0589 * @brief send firmware request to the printer 0590 */ 0591 void requestFirmware(); 0592 0593 /** 0594 * @brief returns AtCorePrivate::sdCardReadingFileList 0595 * @return True if printer is returning sd card file list 0596 */ 0597 bool isReadingSdCardList() const; 0598 0599 /** 0600 * @brief stops print just for sd prints used internally 0601 * @sa stop(), emergencyStop() 0602 */ 0603 void stopSdPrint(); 0604 0605 /** 0606 * @brief New connections need to wait for the machine to be ready if it needs reboot 0607 * @param message: message from the firmware 0608 * @param fwName: fwName to load 0609 */ 0610 void waitForPrinterReboot(const QByteArray &message, const QString &fwName); 0611 0612 /** 0613 * @brief Hold private data of AtCore. 0614 */ 0615 struct AtCorePrivate; 0616 std::unique_ptr<AtCorePrivate> d; 0617 0618 protected: 0619 /** 0620 * @brief Set the number of extruders on the machine. 0621 * @param newCount 0622 * @sa extruderCount(), extruderCountChanged(int newCount) 0623 */ 0624 void setExtruderCount(int newCount); 0625 /** 0626 * @brief Append a file to AtCorePrivate::sdCardFileList. 0627 * @param fileName: new FileName 0628 */ 0629 void appendSdCardFileList(const QString &fileName); 0630 0631 /** 0632 * @brief Clear AtCorePrivate::sdCardFileList. 0633 */ 0634 void clearSdCardFileList(); 0635 0636 /** 0637 * @brief Set if the sd card is mounted by the printer 0638 * @param mounted: True is mounted 0639 */ 0640 void setSdMounted(const bool mounted); 0641 0642 /** 0643 * @brief set AtCorePrivate::sdCardReadingFileList 0644 * @param readingList set true if reading file list 0645 */ 0646 void setReadingSdCardList(bool readingList); 0647 };