├── screenshot.png ├── common.pri ├── EzGraver.pro ├── EzGraverUi ├── clicklabel.cpp ├── main.cpp ├── EzGraverUi.pro ├── clicklabel.h ├── mainwindow.h ├── imagelabel.cpp ├── imagelabel.h ├── mainwindow.cpp └── mainwindow.ui ├── EzGraverCore ├── specifications.h ├── ezgravercore_global.h ├── ezgraver_v1.cpp ├── ezgraver_v2.cpp ├── EzGraverCore.pro ├── ezgraver_v1.h ├── ezgraver_v2.h ├── factory.h ├── factory.cpp ├── ezgraver_v3.h ├── ezgraver_v3.cpp ├── ezgraver.cpp └── ezgraver.h ├── .gitignore ├── .drone.sec ├── EzGraverCli ├── EzGraverCli.pro └── main.cpp ├── LICENSE ├── appveyor.yml ├── .drone.yml ├── .travis.yml └── README.md /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/camrein/EzGraver/HEAD/screenshot.png -------------------------------------------------------------------------------- /common.pri: -------------------------------------------------------------------------------- 1 | DEFINES += EZ_VERSION=\\\"$$(EZ_VERSION)\\\" 2 | 3 | CONFIG += c++11 4 | -------------------------------------------------------------------------------- /EzGraver.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = subdirs 2 | 3 | CONFIG += ordered 4 | 5 | SUBDIRS += \ 6 | EzGraverCore \ 7 | EzGraverCli \ 8 | EzGraverUi 9 | -------------------------------------------------------------------------------- /EzGraverUi/clicklabel.cpp: -------------------------------------------------------------------------------- 1 | #include "clicklabel.h" 2 | 3 | #include 4 | 5 | ClickLabel::ClickLabel(QWidget* parent) : QLabel{parent} {} 6 | ClickLabel::~ClickLabel() {} 7 | 8 | void ClickLabel::mouseReleaseEvent(QMouseEvent*) { 9 | emit clicked(); 10 | } 11 | -------------------------------------------------------------------------------- /EzGraverCore/specifications.h: -------------------------------------------------------------------------------- 1 | #ifndef SETTINGS_H 2 | #define SETTINGS_H 3 | 4 | namespace Ez { 5 | namespace Specifications { 6 | 7 | /*! The image width */ 8 | int const ImageWidth{512}; 9 | 10 | /*! The image height */ 11 | int const ImageHeight{512}; 12 | 13 | } 14 | } 15 | 16 | #endif // SETTINGS_H 17 | -------------------------------------------------------------------------------- /EzGraverUi/main.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include 3 | #include 4 | 5 | int main(int argc, char *argv[]) { 6 | QApplication a(argc, argv); 7 | MainWindow w; 8 | w.show(); 9 | w.setWindowTitle(QString{"EzGraver %1"}.arg(EZ_VERSION)); 10 | 11 | return a.exec(); 12 | } 13 | -------------------------------------------------------------------------------- /EzGraverCore/ezgravercore_global.h: -------------------------------------------------------------------------------- 1 | #ifndef EZGRAVERCORE_GLOBAL_H 2 | #define EZGRAVERCORE_GLOBAL_H 3 | 4 | #include 5 | 6 | #if defined(EZGRAVERCORE_LIBRARY) 7 | # define EZGRAVERCORESHARED_EXPORT Q_DECL_EXPORT 8 | #else 9 | # define EZGRAVERCORESHARED_EXPORT Q_DECL_IMPORT 10 | #endif 11 | 12 | #endif // EZGRAVERCORE_GLOBAL_H 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # C++ objects and libs 2 | 3 | *.slo 4 | *.lo 5 | *.o 6 | *.a 7 | *.la 8 | *.lai 9 | *.so 10 | *.dll 11 | *.dylib 12 | 13 | # Qt-es 14 | 15 | /.qmake.cache 16 | /.qmake.stash 17 | *.pro.user 18 | *.pro.user.* 19 | *.qbs.user 20 | *.qbs.user.* 21 | *.moc 22 | moc_*.cpp 23 | qrc_*.cpp 24 | ui_*.h 25 | Makefile* 26 | *build-* 27 | 28 | # QtCreator 29 | 30 | *.autosave 31 | 32 | # QtCtreator Qml 33 | *.qmlproject.user 34 | *.qmlproject.user.* 35 | 36 | # QtCtreator CMake 37 | CMakeLists.txt.user 38 | 39 | -------------------------------------------------------------------------------- /.drone.sec: -------------------------------------------------------------------------------- 1 | eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.s7gMtvokhwFYScYC2yya0NXW1A2TbKNFrB1NlWwRNyqXrkPVtkYJUWNjAZ1K5ol69-FLvNH_ESEBYRFnAC8-pnh7t9Kmq-EzitK-abNFMqY-7VeoqCMufA8gsJCI27srFjZh9UuLvWsZmOggPoU7OrX12aKyMIbUS0f6a3K4hJN-fi2R8YlYV9UuY_fFbWDQ4ZDkhzS1OMZvwS59o8455C-C_YgL2ufKqwo06FqMLtOt7uVRNxYgTWguGVn8XKr6CAFF-JA7KObCRSE2pGZAjt_Ep-eZgq9HSB6169cFkOrVzxKLH-LOa8oTOVyGBWHsg23NR6pNXIEwSof4d6IBUg.w_2a5xX8z_ngnnvg.pHfpgNx6gb9baILVpU9f6C1J-Ajd1GHmdA3ZJf3t9JkPObS5vwkMxRdPgz2wFqz1W247j9wfNmVei9hvZTVI4rATOsTWem212Rt3NDyKzIs.xpe_AhaTO8mZq4oa7fC8Dg -------------------------------------------------------------------------------- /EzGraverCore/ezgraver_v1.cpp: -------------------------------------------------------------------------------- 1 | #include "ezgraver_v1.h" 2 | 3 | #include 4 | 5 | namespace Ez { 6 | 7 | void EzGraverV1::up() { 8 | qDebug() << "moving up"; 9 | _transmit(0xF5); 10 | } 11 | 12 | void EzGraverV1::down() { 13 | qDebug() << "moving down"; 14 | _transmit(0xF6); 15 | } 16 | 17 | void EzGraverV1::left() { 18 | qDebug() << "moving left"; 19 | _transmit(0xF7); 20 | } 21 | 22 | void EzGraverV1::right() { 23 | qDebug() << "moving right"; 24 | _transmit(0xF8); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /EzGraverCore/ezgraver_v2.cpp: -------------------------------------------------------------------------------- 1 | #include "ezgraver_v2.h" 2 | 3 | #include 4 | 5 | namespace Ez { 6 | 7 | void EzGraverV2::up() { 8 | qDebug() << "moving up"; 9 | _transmit("\xf5\x01"); 10 | } 11 | 12 | void EzGraverV2::down() { 13 | qDebug() << "moving down"; 14 | _transmit("\xf5\x02"); 15 | } 16 | 17 | void EzGraverV2::left() { 18 | qDebug() << "moving left"; 19 | _transmit("\xf5\x03"); 20 | } 21 | 22 | void EzGraverV2::right() { 23 | qDebug() << "moving right"; 24 | _transmit("\xf5\x04"); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /EzGraverCli/EzGraverCli.pro: -------------------------------------------------------------------------------- 1 | include(../common.pri) 2 | 3 | QT += core 4 | QT += serialport 5 | 6 | TARGET = EzGraverCli 7 | CONFIG += console 8 | CONFIG -= app_bundle 9 | 10 | TEMPLATE = app 11 | 12 | SOURCES += main.cpp 13 | 14 | win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../EzGraverCore/release/ -lEzGraverCore 15 | else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../EzGraverCore/debug/ -lEzGraverCore 16 | else:unix: LIBS += -L$$OUT_PWD/../EzGraverCore/ -lEzGraverCore 17 | 18 | INCLUDEPATH += $$PWD/../EzGraverCore 19 | DEPENDPATH += $$PWD/../EzGraverCore 20 | -------------------------------------------------------------------------------- /EzGraverCore/EzGraverCore.pro: -------------------------------------------------------------------------------- 1 | include(../common.pri) 2 | 3 | QT += core 4 | QT += serialport 5 | 6 | TARGET = EzGraverCore 7 | TEMPLATE = lib 8 | 9 | DEFINES += EZGRAVERCORE_LIBRARY 10 | 11 | SOURCES += ezgraver.cpp \ 12 | ezgraver_v1.cpp \ 13 | ezgraver_v2.cpp \ 14 | factory.cpp \ 15 | ezgraver_v3.cpp 16 | 17 | HEADERS += ezgraver.h\ 18 | ezgravercore_global.h \ 19 | ezgraver_v1.h \ 20 | ezgraver_v2.h \ 21 | specifications.h \ 22 | factory.h \ 23 | ezgraver_v3.h 24 | 25 | unix { 26 | target.path = /usr/lib 27 | INSTALLS += target 28 | } 29 | -------------------------------------------------------------------------------- /EzGraverCore/ezgraver_v1.h: -------------------------------------------------------------------------------- 1 | #ifndef EZGRAVERV1_H 2 | #define EZGRAVERV1_H 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include "ezgraver.h" 9 | 10 | namespace Ez { 11 | 12 | struct EzGraverV1 : EzGraver { 13 | using EzGraver::EzGraver; 14 | 15 | /*! Moves the engraver up. */ 16 | void up() override; 17 | 18 | /*! Moves the engraver down. */ 19 | void down() override; 20 | 21 | /*! Moves the engraver left. */ 22 | void left() override; 23 | 24 | /*! Moves the engraver right. */ 25 | void right() override; 26 | }; 27 | 28 | } 29 | 30 | #endif // EZGRAVERV1_H 31 | -------------------------------------------------------------------------------- /EzGraverCore/ezgraver_v2.h: -------------------------------------------------------------------------------- 1 | #ifndef EZGRAVERV2_H 2 | #define EZGRAVERV2_H 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include "ezgraver.h" 9 | 10 | namespace Ez { 11 | 12 | struct EzGraverV2 : EzGraver { 13 | using EzGraver::EzGraver; 14 | 15 | /*! Moves the engraver up. */ 16 | void up() override; 17 | 18 | /*! Moves the engraver down. */ 19 | void down() override; 20 | 21 | /*! Moves the engraver left. */ 22 | void left() override; 23 | 24 | /*! Moves the engraver right. */ 25 | void right() override; 26 | }; 27 | 28 | } 29 | 30 | #endif // EZGRAVERV2_H 31 | -------------------------------------------------------------------------------- /EzGraverUi/EzGraverUi.pro: -------------------------------------------------------------------------------- 1 | include(../common.pri) 2 | 3 | QT += core 4 | QT += gui 5 | QT += serialport 6 | 7 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 8 | 9 | TARGET = EzGraverUi 10 | TEMPLATE = app 11 | 12 | 13 | SOURCES += main.cpp\ 14 | mainwindow.cpp \ 15 | clicklabel.cpp \ 16 | imagelabel.cpp 17 | 18 | HEADERS += mainwindow.h \ 19 | clicklabel.h \ 20 | imagelabel.h 21 | 22 | FORMS += mainwindow.ui 23 | 24 | win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../EzGraverCore/release/ -lEzGraverCore 25 | else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../EzGraverCore/debug/ -lEzGraverCore 26 | else:unix: LIBS += -L$$OUT_PWD/../EzGraverCore/ -lEzGraverCore 27 | 28 | INCLUDEPATH += $$PWD/../EzGraverCore 29 | DEPENDPATH += $$PWD/../EzGraverCore 30 | -------------------------------------------------------------------------------- /EzGraverUi/clicklabel.h: -------------------------------------------------------------------------------- 1 | #ifndef CLICKLABEL_H 2 | #define CLICKLABEL_H 3 | 4 | #include 5 | 6 | /*! 7 | * A label extended with the possibility to retrieve click events. 8 | */ 9 | class ClickLabel : public QLabel { 10 | Q_OBJECT 11 | 12 | public: 13 | /*! 14 | * Creates a new instance with the given \a parent. 15 | * 16 | * \param parent The parent of the label. 17 | */ 18 | explicit ClickLabel(QWidget* parent=NULL); 19 | 20 | /*! 21 | * Frees all required resources upon deconstruction. 22 | */ 23 | virtual ~ClickLabel(); 24 | 25 | signals: 26 | /*! 27 | * Signal emitted as soon as a click has been registered on the label. 28 | */ 29 | void clicked(); 30 | 31 | protected: 32 | /*! 33 | * Retrieves the event of releasing a mouse button on the de 34 | * 35 | * \param event 36 | */ 37 | void mouseReleaseEvent(QMouseEvent* event); 38 | }; 39 | 40 | #endif // CLICKLABEL_H 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016-2017 Christoph Amrein 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /EzGraverCore/factory.h: -------------------------------------------------------------------------------- 1 | #ifndef EZGRAVER_FACTORY_H 2 | #define EZGRAVER_FACTORY_H 3 | 4 | #include "ezgravercore_global.h" 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include "ezgraver.h" 13 | 14 | namespace Ez { 15 | 16 | /*! 17 | * Creates an instance and connects to the given \a portName. 18 | * 19 | * \param portName The port the connection should be established to. 20 | * \param protocol The protocol version to use. 21 | * \return An instance of the EzGraver as a shared pointer. 22 | * \throws std::runtime_error Thrown if no connection to the specified port could be established. 23 | * \throws std::invalid_argument Thrown if the provided protocol code is unknown. 24 | */ 25 | EZGRAVERCORESHARED_EXPORT std::shared_ptr create(QString const& portName, int protocol = 1); 26 | 27 | /*! 28 | * Gets the available protocols. 29 | * 30 | * \return The available protocols. 31 | */ 32 | EZGRAVERCORESHARED_EXPORT QList protocols(); 33 | 34 | /*! 35 | * Gets a list of all available ports. 36 | * 37 | * \return A list with all ports. 38 | */ 39 | EZGRAVERCORESHARED_EXPORT QStringList availablePorts(); 40 | 41 | } 42 | 43 | 44 | #endif // EZGRAVER_FACTORY_H 45 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | environment: 2 | matrix: 3 | - arch: x64 4 | QT_DIR: C:\Qt\5.7\msvc2015_64 5 | - arch: x86 6 | QT_DIR: C:\Qt\5.7\msvc2015 7 | 8 | install: 9 | - set PATH=%PATH%;%QT_DIR%\bin 10 | # TODO descide Decide whether vcredist_$(arch).exe should be packaged with the application or published separately. 11 | # - set VCINSTALLDIR=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC 12 | 13 | before_build: 14 | - set EZ_VERSION=%APPVEYOR_REPO_TAG_NAME% 15 | - cd EzGraverCli & qmake -config release -tp vc -spec win32-msvc2015 EzGraverCli.pro & cd .. 16 | - cd EzGraverCore & qmake -config release -tp vc -spec win32-msvc2015 EzGraverCore.pro & cd .. 17 | - cd EzGraverUi & qmake -config release -tp vc -spec win32-msvc2015 EzGraverUi.pro & cd .. 18 | - qmake -config release -tp vc -spec win32-msvc2015 EzGraver.pro 19 | 20 | configuration: 21 | - Release 22 | 23 | after_build: 24 | - mkdir deploy 25 | - copy EzGraverCli\release\EzGraverCli.exe deploy\EzGraverCli.exe 26 | - copy EzGraverCore\release\EzGraverCore.dll deploy\EzGraverCore.dll 27 | - copy EzGraverUi\release\EzGraverUi.exe deploy\EzGraverUi.exe 28 | - windeployqt --release --no-translations --no-angle --no-opengl-sw deploy/EzGraverCli.exe 29 | - windeployqt --release --no-translations --no-angle --no-opengl-sw deploy/EzGraverCore.dll 30 | - windeployqt --release --no-translations --no-angle --no-opengl-sw deploy/EzGraverUi.exe 31 | - 7z a EzGraver_win_%arch%.zip .\deploy\* 32 | 33 | artifacts: 34 | - path: EzGraver_win_$(arch).zip 35 | 36 | deploy: 37 | provider: GitHub 38 | auth_token: 39 | secure: kQ5w9sYhOflgqli0RP05IzEMc946SuYcK7nyhsOivYd5MoC6QLgg9tknjt8ALkTn 40 | artifact: EzGraver_win_$(arch).zip 41 | draft: false 42 | prerelease: false 43 | on: 44 | appveyor_repo_tag: true 45 | -------------------------------------------------------------------------------- /.drone.yml: -------------------------------------------------------------------------------- 1 | build: 2 | image: teaci/msys$$arch 3 | shell: mingw$$arch 4 | pull: true 5 | commands: 6 | # Compilation 7 | - export EZ_VERSION=$CI_TAG 8 | - if [ $$arch = 32 ]; then target=i686; fi 9 | - if [ $$arch = 64 ]; then target=x86_64; fi 10 | - pacman -S --needed --noconfirm --noprogressbar mingw-w64-${target}-pkg-config mingw-w64-${target}-qt5 zip 11 | - qmake -v 12 | - qmake -config release EzGraver.pro 13 | - make 14 | # Dependency collection 15 | # windeployqt searches for icu*.dll instead of libicu*.dll 16 | - mkdir dependencies 17 | - cp /mingw$$arch/bin/libicudt*.dll dependencies/ 18 | - cp /mingw$$arch/bin/libicuin*.dll dependencies/ 19 | - cp /mingw$$arch/bin/libicuuc*.dll dependencies/ 20 | - for file in dependencies/lib* ; do mv "$file" "${file/lib/}" ; done 21 | - PATH=$PATH:$PWD/dependencies 22 | # Deployment 23 | - mkdir deploy 24 | - cp EzGraverCli/release/EzGraverCli.exe deploy/ 25 | - cp EzGraverCore/release/EzGraverCore.dll deploy/ 26 | - cp EzGraverUi/release/EzGraverUi.exe deploy/ 27 | - windeployqt --release --no-translations --no-angle --no-opengl-sw deploy/EzGraverCli.exe 28 | - windeployqt --release --no-translations --no-angle --no-opengl-sw deploy/EzGraverCore.dll 29 | - windeployqt --release --no-translations --no-angle --no-opengl-sw deploy/EzGraverUi.exe 30 | # Add missing libraries. MSYS libs have to be added as well. 31 | # Generate final zip 32 | - if [ $$arch = 32 ]; then zip -r EzGraver_win_x86.zip deploy/; fi 33 | - if [ $$arch = 64 ]; then zip -r EzGraver_win_x64.zip deploy/; fi 34 | 35 | #publish: 36 | # github_release: 37 | # api_key: $$GITHUB_RELEASES_TOKEN 38 | # files: 39 | # - EzGraver_win_x86.zip 40 | # - EzGraver_win_x64.zip 41 | # when: 42 | # event: tag 43 | 44 | matrix: 45 | arch: 46 | - 64 47 | - 32 48 | -------------------------------------------------------------------------------- /EzGraverCore/factory.cpp: -------------------------------------------------------------------------------- 1 | #include "factory.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | #include "ezgraver.h" 11 | #include "ezgraver_v1.h" 12 | #include "ezgraver_v2.h" 13 | #include "ezgraver_v3.h" 14 | 15 | namespace Ez { 16 | 17 | std::shared_ptr create(QString const& portName, int protocol) { 18 | qDebug() << "instantiating EzGraver on port" << portName << "with protocol version" << protocol; 19 | 20 | std::shared_ptr serial{new QSerialPort(portName)}; 21 | serial->setBaudRate(QSerialPort::Baud57600, QSerialPort::AllDirections); 22 | serial->setParity(QSerialPort::Parity::NoParity); 23 | serial->setDataBits(QSerialPort::DataBits::Data8); 24 | serial->setStopBits(QSerialPort::StopBits::OneStop); 25 | 26 | if(!serial->open(QIODevice::ReadWrite)) { 27 | qDebug() << "failed to establish a connection on port" << portName; 28 | qDebug() << serial->errorString(); 29 | throw std::runtime_error{QString{"failed to connect to port %1 (%2)"}.arg(portName, serial->errorString()).toStdString()}; 30 | } 31 | 32 | switch(protocol) { 33 | case 1: 34 | return std::make_shared(serial); 35 | case 2: 36 | return std::make_shared(serial); 37 | case 3: 38 | return std::make_shared(serial); 39 | default: 40 | throw std::invalid_argument{QString{"unsupported protocol '%1' selected"}.arg(protocol).toStdString()}; 41 | } 42 | } 43 | 44 | QList protocols() { 45 | return QList{1, 2, 3}; 46 | } 47 | 48 | QStringList availablePorts() { 49 | auto toPortName = [](QSerialPortInfo const& port) { return port.portName(); }; 50 | auto ports = QSerialPortInfo::availablePorts(); 51 | QStringList result{}; 52 | 53 | std::transform(ports.cbegin(), ports.cend(), std::back_inserter(result), toPortName); 54 | return result; 55 | } 56 | 57 | } 58 | 59 | -------------------------------------------------------------------------------- /EzGraverCore/ezgraver_v3.h: -------------------------------------------------------------------------------- 1 | #ifndef EZGRAVERV3_H 2 | #define EZGRAVERV3_H 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include "ezgraver.h" 9 | 10 | namespace Ez { 11 | 12 | struct EzGraverV3 : EzGraver { 13 | using EzGraver::EzGraver; 14 | 15 | /*! 16 | * Starts the engraving process with the given \a burnTime. 17 | * 18 | * \param burnTime The burn time to use in milliseconds. 19 | */ 20 | void start(unsigned char const& burnTime) override; 21 | 22 | /*! 23 | * Pauses the engraving process at the given location. The process 24 | * can be continued by invoking start. 25 | */ 26 | void pause() override; 27 | 28 | /*! Resets the engraver. */ 29 | void reset() override; 30 | 31 | /*! Moves the engraver to the home position. */ 32 | void home() override; 33 | 34 | /*! Moves the engraver to the center. */ 35 | void center() override; 36 | 37 | /*! Draws a preview of the currently loaded image. */ 38 | void preview() override; 39 | 40 | /*! Moves the engraver up. */ 41 | void up() override; 42 | 43 | /*! Moves the engraver down. */ 44 | void down() override; 45 | 46 | /*! Moves the engraver left. */ 47 | void left() override; 48 | 49 | /*! Moves the engraver right. */ 50 | void right() override; 51 | 52 | /*! 53 | * Erases the EEPROM of the engraver. This is necessary before uploading 54 | * any new image to it. 55 | * Erasing the EEPROM takes a while. Sending image data to early causes 56 | * that some of the leading pixels are lost. Waiting for about 5 seconds 57 | * seems to be sufficient. 58 | * 59 | * \return The recommended time in ms to wait until uploading the image. 60 | */ 61 | int erase() override; 62 | 63 | /*! 64 | * Uploads the given \a image to the EEPROM. It is mandatory to use \a erase() 65 | * it prior uploading an image. The image will automatically be scaled, inverted, 66 | * mirrored and converted to a monochrome bitmap. 67 | * 68 | * \param image The image to upload to the EEPROM for engraving. 69 | * \return The number of bytes being sent to the device. 70 | */ 71 | int uploadImage(QImage const& image) override; 72 | 73 | private: 74 | void _setBurnTime(unsigned char const& burnTime); 75 | }; 76 | 77 | } 78 | 79 | #endif // EZGRAVERV3_H 80 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | sudo: required 3 | dist: trusty 4 | 5 | os: 6 | - linux 7 | - osx 8 | 9 | before_install: 10 | - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi 11 | - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install qt55 ; fi 12 | - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew link --force qt55 ; fi 13 | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo add-apt-repository --yes ppa:beineri/opt-qt551-trusty ; fi 14 | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get update -qq ; fi 15 | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install -qq qt55base qt55serialport ; fi 16 | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install -qq libudev-dev ; fi 17 | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then source /opt/qt55/bin/qt55-env.sh ; fi 18 | 19 | script: 20 | - export EZ_VERSION=$TRAVIS_TAG 21 | - echo "Building $EZ_VERSION" 22 | - qmake -v 23 | - qmake -config release EzGraver.pro 24 | - make 25 | - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then mkdir EzGraverUi/EzGraverUi.app/Contents/Frameworks/ ; fi 26 | - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then cp EzGraverCore/libEzGraverCore.1.dylib EzGraverUi/EzGraverUi.app/Contents/Frameworks/libEzGraverCore.1.dylib ; fi 27 | - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then macdeployqt EzGraverUi/EzGraverUi.app -dmg ; fi 28 | - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then otool -L EzGraverUi/EzGraverUi.app/Contents/MacOS/EzGraverUi ; fi 29 | - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then mv EzGraverUi/EzGraverUi.dmg EzGraverUi/EzGraver_osx.dmg; fi 30 | 31 | deploy: 32 | provider: releases 33 | api_key: 34 | secure: jIWIt+ocrCrp564ezeKQ9SAu1xo/22/6crqyhFRM7YqOZHFloJdqf1xTSS3IVrkxNmFJ6uyGX1ZJfCnrxilyXPdXi35qE3WoNYPtHypWaLo4szD/F8orsWvoG/QvAeEQwXDQ4010d0ao4RQSj07mxAPjrn88h8WrIfJ0N19et8O7qXGMGnCB0lMaaqlpN9uycEg3ZYJY0uxhljk9dMESFz/0t68KUNMVttAgoEvxXhTnWUrNheigIxD0fpssDdXRNUbg9r2RS/yZyOLR5yybi2xKfKx3WxsDtJQTNTVVfFtcwiwCozsbM3vwRZzZtmc22KxLediZyvSNZUJ7RUfSZnd88HHwKWAQHj04UaeBLgoj0lxRKorWEcWfBQPpFy1nT9c0nQGGpq6+LZHehd+ZAqmf17y5o1HxEYRszMsgHLNEgqZomEkgUG8cWkoylz7QRm0+Ia0wvoQz7C0Neg57VLUPi1OmlxPo4GQuskoUGptA5OFnDiLwtkPEWuLeLroxFiZtsSWqJicqWPUgg14bGNMG3/VVD3vf7M80MCIHCuHtyP+s78DiZlkxil0KH2f2ORhqkNocJOrjtFpuXriHfbKYwD4O2EAQTHB1mMLviL05oaJLvPaODYX/+ua5BAmPdIyC5Mil3M0+WBqFxf4Do1KhwQCId78AOUMGGqeLc74= 35 | file: EzGraverUi/EzGraver_osx.dmg 36 | skip_cleanup: true 37 | on: 38 | repo: camrein/EzGraver 39 | condition: $TRAVIS_OS_NAME = osx 40 | tags: true 41 | -------------------------------------------------------------------------------- /EzGraverUi/mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | #include "ezgraver.h" 13 | 14 | namespace Ui { 15 | class MainWindow; 16 | } 17 | 18 | class MainWindow : public QMainWindow { 19 | Q_OBJECT 20 | Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged) 21 | 22 | public: 23 | explicit MainWindow(QWidget* parent = NULL); 24 | ~MainWindow(); 25 | 26 | bool connected() const; 27 | signals: 28 | void connectedChanged(bool connected); 29 | 30 | private slots: 31 | void on_connect_clicked(); 32 | void on_home_clicked(); 33 | void on_up_clicked(); 34 | void on_left_clicked(); 35 | void on_center_clicked(); 36 | void on_right_clicked(); 37 | void on_down_clicked(); 38 | void on_upload_clicked(); 39 | void on_preview_clicked(); 40 | void on_start_clicked(); 41 | void on_pause_clicked(); 42 | void on_reset_clicked(); 43 | void on_disconnect_clicked(); 44 | void on_image_clicked(); 45 | 46 | void updatePorts(); 47 | void bytesWritten(qint64 bytes); 48 | void updateProgress(qint64 bytes); 49 | void updateEngraveProgress(); 50 | 51 | protected: 52 | void dragEnterEvent(QDragEnterEvent* event); 53 | void dropEvent(QDropEvent* event); 54 | 55 | private: 56 | /*! The delay between each port list update. */ 57 | static int const PortUpdateDelay{1000}; 58 | /*! The delay between each progress update while erasing the EEPROM. */ 59 | static int const EraseProgressDelay{500}; 60 | 61 | Ui::MainWindow* _ui; 62 | QTimer _portTimer{}; 63 | QImage _image{}; 64 | QSettings _settings{"EzGraver", "EzGraver"}; 65 | 66 | std::shared_ptr _ezGraver{}; 67 | std::function _bytesWrittenProcessor{[](qint64){}}; 68 | bool _connected{false}; 69 | 70 | void _initBindings(); 71 | void _initUploadBindings(); 72 | void _initConnectionBindings(); 73 | void _initSetupBindings(); 74 | void _initTransformationBindings(); 75 | void _initLayerBindings(); 76 | 77 | void _initConversionFlags(); 78 | void _initProtocols(); 79 | 80 | void _setConnected(bool connected); 81 | void _printVerbose(QString const& verbose); 82 | void _loadImage(QString const& fileName); 83 | void _eraseProgressed(QTimer* eraseProgressTimer, QImage const& image, int const& waitTimeMs); 84 | void _uploadImage(QImage const& image); 85 | }; 86 | 87 | #endif // MAINWINDOW_H 88 | -------------------------------------------------------------------------------- /EzGraverCore/ezgraver_v3.cpp: -------------------------------------------------------------------------------- 1 | #include "ezgraver_v3.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "specifications.h" 8 | 9 | namespace Ez { 10 | 11 | void EzGraverV3::start(unsigned char const& burnTime) { 12 | _setBurnTime(burnTime); 13 | qDebug() << "starting engrave process"; 14 | _transmit(QByteArray::fromRawData("\xFF\x01\x01\x00", 4)); 15 | } 16 | 17 | void EzGraverV3::_setBurnTime(unsigned char const& burnTime) { 18 | if(burnTime < 0x01 || burnTime > 0xF0) { 19 | throw new std::out_of_range("burntime out of range"); 20 | } 21 | qDebug() << "setting burn time to:" << static_cast(burnTime); 22 | 23 | QByteArray payload{"\xFF\x05?\x00", 4}; 24 | payload[2] = burnTime; 25 | _transmit(payload); 26 | } 27 | 28 | void EzGraverV3::pause() { 29 | qDebug() << "pausing engrave process"; 30 | _transmit(QByteArray::fromRawData("\xFF\x01\x02\x00", 4)); 31 | } 32 | 33 | void EzGraverV3::reset() { 34 | qDebug() << "resetting"; 35 | _transmit(QByteArray::fromRawData("\xFF\x04\x01\x00", 4)); 36 | } 37 | 38 | void EzGraverV3::home() { 39 | qDebug() << "moving to home"; 40 | _transmit(0xF3); 41 | } 42 | 43 | void EzGraverV3::center() { 44 | qDebug() << "moving to center"; 45 | _transmit(QByteArray::fromRawData("\xFF\x02\x01\x00", 4)); 46 | } 47 | 48 | void EzGraverV3::preview() { 49 | qDebug() << "drawing image preview"; 50 | _transmit(QByteArray::fromRawData("\xFF\x02\x02\x00", 4)); 51 | } 52 | 53 | void EzGraverV3::up() { 54 | qDebug() << "moving up"; 55 | _transmit(QByteArray::fromRawData("\xFF\x03\x01\x00", 4)); 56 | } 57 | 58 | void EzGraverV3::down() { 59 | qDebug() << "moving down"; 60 | _transmit(QByteArray::fromRawData("\xFF\x03\x02\x00", 4)); 61 | } 62 | 63 | void EzGraverV3::left() { 64 | qDebug() << "moving left"; 65 | _transmit(QByteArray::fromRawData("\xFF\x03\x03\x00", 4)); 66 | } 67 | 68 | void EzGraverV3::right() { 69 | qDebug() << "moving right"; 70 | _transmit(QByteArray::fromRawData("\xFF\x03\x04\x00", 4)); 71 | } 72 | 73 | int EzGraverV3::erase() { 74 | qDebug() << "erasing EEPROM"; 75 | _transmit(QByteArray::fromRawData("\xFF\x06\x01\x00", 4)); 76 | return 50; 77 | } 78 | 79 | int EzGraverV3::uploadImage(QImage const& originalImage) { 80 | qDebug() << "converting image to bitmap"; 81 | QImage image{originalImage 82 | .scaled(Ez::Specifications::ImageWidth, Ez::Specifications::ImageHeight) 83 | .mirrored() 84 | .convertToFormat(QImage::Format_Mono)}; 85 | QByteArray bytes{}; 86 | QBuffer buffer{&bytes}; 87 | image.save(&buffer, "BMP"); 88 | 89 | // protocol v3 neither needs the BMP header nor the invertion of the pixels. 90 | return EzGraver::uploadImage(bytes.mid(62)); 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /EzGraverCore/ezgraver.cpp: -------------------------------------------------------------------------------- 1 | #include "ezgraver.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include "specifications.h" 14 | 15 | namespace Ez { 16 | 17 | EzGraver::EzGraver(std::shared_ptr serial) : _serial{serial} {} 18 | 19 | void EzGraver::start(unsigned char const& burnTime) { 20 | _setBurnTime(burnTime); 21 | qDebug() << "starting engrave process"; 22 | _transmit(0xF1); 23 | } 24 | 25 | void EzGraver::_setBurnTime(unsigned char const& burnTime) { 26 | if(burnTime < 0x01 || burnTime > 0xF0) { 27 | throw new std::out_of_range("burntime out of range"); 28 | } 29 | qDebug() << "setting burn time to:" << static_cast(burnTime); 30 | _transmit(burnTime); 31 | } 32 | 33 | void EzGraver::pause() { 34 | qDebug() << "pausing engrave process"; 35 | _transmit(0xF2); 36 | } 37 | 38 | void EzGraver::reset() { 39 | qDebug() << "resetting"; 40 | _transmit(0xF9); 41 | } 42 | 43 | void EzGraver::home() { 44 | qDebug() << "moving to home"; 45 | _transmit(0xF3); 46 | } 47 | 48 | void EzGraver::center() { 49 | qDebug() << "moving to center"; 50 | _transmit(0xFB); 51 | } 52 | 53 | void EzGraver::preview() { 54 | qDebug() << "drawing image preview"; 55 | _transmit(0xF4); 56 | } 57 | 58 | int EzGraver::erase() { 59 | qDebug() << "erasing EEPROM"; 60 | _transmit(QByteArray{8, '\xFE'}); 61 | return 6000; 62 | } 63 | 64 | int EzGraver::uploadImage(QImage const& originalImage) { 65 | qDebug() << "converting image to bitmap"; 66 | QImage image{originalImage 67 | .scaled(Ez::Specifications::ImageWidth, Ez::Specifications::ImageHeight) 68 | .mirrored() 69 | .convertToFormat(QImage::Format_Mono)}; 70 | image.invertPixels(); 71 | 72 | QByteArray bytes{}; 73 | QBuffer buffer{&bytes}; 74 | image.save(&buffer, "BMP"); 75 | return uploadImage(bytes); 76 | } 77 | 78 | int EzGraver::uploadImage(QByteArray const& image) { 79 | qDebug() << "uploading image"; 80 | // Data is chunked in order to get at least some progress updates 81 | _transmit(image, 8192); 82 | return image.size(); 83 | } 84 | 85 | void EzGraver::awaitTransmission(int msecs) { 86 | _serial->waitForBytesWritten(msecs); 87 | } 88 | 89 | std::shared_ptr EzGraver::serialPort() { 90 | return _serial; 91 | } 92 | 93 | void EzGraver::_transmit(unsigned char const& data) { 94 | _transmit(QByteArray{1, static_cast(data)}); 95 | } 96 | 97 | void EzGraver::_transmit(QByteArray const& data) { 98 | qDebug() << "transmitting" << data.size() << "bytes:" << data.toHex(); 99 | _serial->write(data); 100 | _serial->flush(); 101 | } 102 | 103 | void EzGraver::_transmit(QByteArray const& data, int chunkSize) { 104 | qDebug() << "transmitting" << data.size() << "bytes in chunks of size" << chunkSize; 105 | for(int i{0}; i < data.size(); i += chunkSize) { 106 | _serial->write(data.mid(i, chunkSize)); 107 | _serial->flush(); 108 | } 109 | } 110 | 111 | EzGraver::~EzGraver() { 112 | qDebug() << "EzGraver is being destroyed, closing serial port"; 113 | _serial->close(); 114 | } 115 | 116 | } 117 | 118 | -------------------------------------------------------------------------------- /EzGraverCli/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "ezgraver.h" 11 | #include "factory.h" 12 | #include "specifications.h" 13 | 14 | std::ostream& operator<<(std::ostream& lhv, QString const& rhv) { 15 | return lhv << rhv.toStdString(); 16 | } 17 | 18 | void showHelp() { 19 | std::cout << "Usage: EzGraverCli