├── QTMarlin.pro ├── README ├── main.cpp ├── mainwindow.cpp ├── mainwindow.h ├── tab_eeprom.cpp ├── tab_eeprom.h ├── tab_pid.cpp ├── tab_pid.h ├── tab_raw.cpp ├── tab_raw.h ├── tab_veltest.cpp └── tab_veltest.h /QTMarlin.pro: -------------------------------------------------------------------------------- 1 | ###################################################################### 2 | # Automatically generated by qmake (2.01a) Sat Nov 12 13:08:01 2011 3 | ###################################################################### 4 | 5 | QWT_DIR=/home/bkubicek/software/qwt-6.0.1/ 6 | QEXTSERIAL_DIR=/home/bkubicek/git/qextserialport 7 | QSERIALDEVICE_DIR=/home/bkubicek/software/qserialdevice-qserialdevice/ 8 | 9 | 10 | TEMPLATE = app 11 | TARGET = 12 | DEPENDPATH += . 13 | INCLUDEPATH += . 14 | INCLUDEPATH += $$QEXTSERIAL_DIR/src/ 15 | INCLUDEPATH += $$QWT_DIR/src 16 | INCLUDEPATH += $$QSERIALDEVICE_DIR/src/qserialdeviceenumerator 17 | INCLUDEPATH += $$QSERIALDEVICE_DIR/src/qserialdevice 18 | 19 | QMAKE_LIBDIR += $$QWT_DIR/lib/ / 20 | QMAKE_LIBDOR += $$QEXTSERIAL_DIR/src/build/ 21 | QMAKE_LIBDIR += $$QSERIALDEVICE_DIR/src/build/release 22 | 23 | # Input 24 | HEADERS += mainwindow.h tab_pid.h tab_raw.h tab_eeprom.h tab_veltest.h 25 | SOURCES += main.cpp mainwindow.cpp tab_pid.cpp tab_raw.cpp tab_eeprom.cpp tab_veltest.cpp 26 | #LIBS += -lqextserialport -lqserialdevice -lqwt 27 | LIBS += -lqwt 28 | LIBS += libqextserialport.a 29 | LIBS += -lqserialdevice 30 | 31 | 32 | 33 | win32 { 34 | LIBS += -lsetupapi -luuid -ladvapi32 35 | } 36 | unix:!macx { 37 | LIBS += -ludev 38 | } 39 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This will soon be a QT tool for the marlin firmware. 2 | 3 | indended features: 4 | Temp monitoring+PID adjustments, 5 | find accurate accelerations/velocities 6 | eeprom values managing 7 | configuration.h and pins.h creation. 8 | 9 | requires: qt 4, qwt v5, qserialdevice 10 | currently tested in linux 11 | to build, you have to adopt the qtmarlin.pro to have the correct dependency paths. 12 | then qmake-qt4 or just qmake in case there is no qt3 installed. 13 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "mainwindow.h" 3 | 4 | 5 | int main(int argv, char **args) 6 | { 7 | QApplication app(argv, args); 8 | 9 | MainWindow window; 10 | window.show(); 11 | 12 | return app.exec(); 13 | } -------------------------------------------------------------------------------- /mainwindow.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "mainwindow.h" 3 | 4 | 5 | 6 | #include 7 | #include 8 | 9 | 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | using namespace std; 19 | 20 | 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #include "tab_pid.h" 44 | #include "tab_raw.h" 45 | #include "tab_eeprom.h" 46 | #include "tab_veltest.h" 47 | 48 | #ifdef USE_QSERIALDEVICE 49 | #include 50 | #endif 51 | 52 | MainWindow::MainWindow(QWidget *parent): QWidget(parent) 53 | { 54 | initSerial(); 55 | 56 | //port = new AbstractSerial(); 57 | serialBinBuffer.resize(0); 58 | wait_reply=false; 59 | QVBoxLayout *layout = new QVBoxLayout; 60 | 61 | QHBoxLayout *comLayout= new QHBoxLayout; 62 | portSelector=new QComboBox(this); 63 | baudSelector=new QComboBox(this); 64 | 65 | baudSelector->addItem("115200"); 66 | baudSelector->addItem("57600"); 67 | baudSelector->addItem("230400"); 68 | baudSelector->addItem("250000"); 69 | btConnect= new QPushButton("Connect");; 70 | btDisconnect=new QPushButton("Disconnect",this); 71 | btRescan= new QPushButton("Rescan",this); 72 | comLayout->addWidget(portSelector); 73 | comLayout->addWidget(baudSelector); 74 | comLayout->addWidget(btConnect); 75 | comLayout->addWidget(btDisconnect); 76 | comLayout->addWidget(btRescan); 77 | layout->addLayout(comLayout); 78 | tab=new QTabWidget(); 79 | layout->addWidget(tab); 80 | 81 | tabPID=new TabPID(tab); 82 | tabRaw=new TabRaw(tab); 83 | tabEEPROM=new TabEEPROM(tab); 84 | tabVeltest=new TabVeltest(this,0); 85 | 86 | tab->addTab(tabRaw,"Raw"); 87 | tab->addTab(tabPID,"PID"); 88 | tab->addTab(tabEEPROM,"EEPROM"); 89 | tab->addTab(tabVeltest,"VelTest"); 90 | 91 | status=new QStatusBar(this); 92 | 93 | 94 | layout->addWidget(status); 95 | //layout->addWidget(slider); 96 | setLayout(layout); 97 | clickedRefresh(); 98 | 99 | connect(btConnect, SIGNAL(clicked(bool)), this, SLOT(clickedConnect())); 100 | connect(btDisconnect, SIGNAL(clicked(bool)), this, SLOT(clickedDisconnect())); 101 | connect(btRescan, SIGNAL(clicked(bool)), this, SLOT(clickedRefresh())); 102 | 103 | //connect(comport, SIGNAL(readyRead()), this, SLOT(slotRead())); 104 | connect(tabRaw->sendText,SIGNAL(returnPressed()),this, SLOT(manualSend())); 105 | 106 | 107 | connect(tabPID,SIGNAL(pidChanged()),this, SLOT(sendPID())); 108 | connect(tabPID->pids[0],SIGNAL(returnPressed()),this, SLOT(sendPID())); 109 | connect(tabPID->pids[1],SIGNAL(returnPressed()),this, SLOT(sendPID())); 110 | connect(tabPID->pids[2],SIGNAL(returnPressed()),this, SLOT(sendPID())); 111 | connect(tabPID->pids[3],SIGNAL(returnPressed()),this, SLOT(sendPID())); 112 | connect(tabPID->btLoad,SIGNAL(clicked()),this, SLOT(getPID())); 113 | 114 | connect(tabPID->temp[hotend1],SIGNAL(returnPressed()),this, SLOT(setHotend1Temp())); 115 | 116 | connect(this,SIGNAL(newSerialData()),this,SLOT(processReply())); 117 | timer = new QTimer(this); 118 | connect(timer,SIGNAL(timeout()),tabVeltest,SLOT(checkDone())); 119 | pidloaded=false; 120 | 121 | 122 | connect(tabEEPROM->pbRead,SIGNAL(clicked(bool)),this, SLOT(EEPROM_loadClicked())); 123 | connect(tabEEPROM->pbWrite,SIGNAL(clicked(bool)),this, SLOT(EEPROM_writeClicked())); 124 | connect(tabEEPROM->pbReset,SIGNAL(clicked(bool)),this, SLOT(EEPROM_resetClicked())); 125 | connect(tabEEPROM->pbFactorReset,SIGNAL(clicked(bool)),this, SLOT(EEPROM_factorResetClicked())); 126 | } 127 | 128 | MainWindow::~MainWindow() 129 | { 130 | closeSerial(); 131 | } 132 | 133 | void MainWindow::initSerial() 134 | { 135 | #ifdef USE_QEXTSERIALPORT 136 | comport=0; 137 | #endif 138 | 139 | #ifdef USE_QSERIALDEVICE 140 | comport = new AbstractSerial(); 141 | connect(comport, SIGNAL(readyRead()), this, SLOT(slotRead())); 142 | #endif 143 | } 144 | 145 | void MainWindow::closeSerial() 146 | { 147 | 148 | #ifdef USE_QEXTSERIALPORT 149 | comport->close(); 150 | delete comport; 151 | comport=0; 152 | #endif 153 | 154 | #ifdef USE_QSERIALDEVICE 155 | comport->close(); 156 | #endif 157 | } 158 | 159 | void MainWindow::openSerial() 160 | { 161 | #ifdef USE_QEXTSERIALPORT 162 | if(comport) 163 | closeSerial(); 164 | 165 | comport = new QextSerialPort(portSelector->currentText(), QextSerialPort::EventDriven); 166 | connect(comport, SIGNAL(readyRead()), this, SLOT(slotRead())); 167 | 168 | QString baud=baudSelector->currentText(); 169 | if(baud=="57600") 170 | comport->setBaudRate(BAUD57600); 171 | else if(baud=="115200") 172 | comport->setBaudRate(BAUD115200); 173 | else 174 | cerr<<"Unsuppored baudrate"<open(QIODevice::ReadWrite) != true) 177 | { 178 | cout<<"failed opening comport:"<currentText().toStdString()<setDeviceName(portSelector->currentText()); 185 | if (comport->open(AbstractSerial::ReadWrite | AbstractSerial::Unbuffered)) 186 | { 187 | qDebug()<<"opened ok"<currentText()<currentText(); 197 | if(baud=="115200") 198 | { 199 | if (!comport->setBaudRate(AbstractSerial::BaudRate115200)) 200 | { 201 | qDebug() << "Set baud rate " << AbstractSerial::BaudRate115200 << " error."; 202 | return ; 203 | }; 204 | } 205 | if(baud=="230400") 206 | { 207 | if (!comport->setBaudRate(AbstractSerial::BaudRate230400)) 208 | { 209 | qDebug() << "Set baud rate " << AbstractSerial::BaudRate230400 << " error."; 210 | return ; 211 | }; 212 | } 213 | if(baud=="250000") 214 | { 215 | if (!comport->setBaudRate(AbstractSerial::BaudRate250000)) 216 | { 217 | qDebug() << "Set baud rate " << AbstractSerial::BaudRate250000 << " error."; 218 | return ; 219 | }; 220 | } 221 | if(baud=="57600") 222 | { 223 | if (!comport->setBaudRate(AbstractSerial::BaudRate57600)) 224 | { 225 | qDebug() << "Set baud rate " << AbstractSerial::BaudRate57600<< " error."; 226 | return ; 227 | }; 228 | } 229 | #endif 230 | } 231 | 232 | 233 | 234 | void MainWindow::clickedConnect() 235 | { 236 | openSerial(); 237 | 238 | tabPID->startTime(); 239 | 240 | connect(timer, SIGNAL(timeout()), this, SLOT(measure())); 241 | timer->start(1000); 242 | //getPID(); 243 | serialBuffer=""; 244 | } 245 | 246 | void MainWindow::clickedDisconnect() 247 | { 248 | //comport->close(); 249 | //disconnect(comport, SIGNAL(readyRead()), this, SLOT(slotRead())); 250 | closeSerial(); 251 | } 252 | 253 | void MainWindow::clickedRefresh() 254 | { 255 | QStringList portnames; 256 | #ifdef USE_QEXTSERIALPORT 257 | QList ports = QextSerialEnumerator::getPorts(); 258 | stringstream ss; 259 | for (int i = 0; i < ports.size(); i++) 260 | portnames<<(ports.at(i).physName); 261 | #endif 262 | 263 | #ifdef USE_QSERIALDEVICE 264 | 265 | #ifdef DONTUSE_QSERIALDEVICEENUMERATE 266 | QDir mydir("/dev"); 267 | QStringList list = mydir.entryList(QDir::AllEntries|QDir::System); 268 | foreach (QString s, list) 269 | { 270 | if(s.startsWith("tty")) 271 | portnames<devicesAvailable(); 278 | 279 | foreach (QString s, list) 280 | { 281 | m_sde->setDeviceName(s); 282 | portnames<shortName(); 283 | } 284 | 285 | #endif 286 | #endif 287 | 288 | //always: 289 | portSelector->clear(); 290 | foreach (QString s, portnames) 291 | portSelector->addItem(s); 292 | } 293 | 294 | void MainWindow::getdata(const QString &line,const QString &after, const QString &key,float &target) 295 | { 296 | int n=line.indexOf(after); 297 | if(n==-1) return; 298 | QString t=line.mid(n,line.size()); 299 | int m=t.indexOf(key)+key.size(); 300 | if(m==-1) 301 | return; 302 | float f; 303 | QString end=t.mid(m, t.size()).split(" ")[0]; 304 | f=end.toFloat(); 305 | target=f; 306 | 307 | //qDebug()<setText(end); 322 | tabEEPROM->EEPROM_recalculate(); 323 | //qDebug()<readAll(); 328 | serialBinBuffer.append(ba); 329 | int lastnewlinepos=serialBinBuffer.lastIndexOf('\n'); 330 | // qDebug()<<"newline@"<displayText(readlines); 339 | 340 | foreach(QString s, lines) //s = linecontent 341 | { 342 | //qDebug()<<"read line:"<pids[0]->setText(ll[1]); 362 | tabEEPROM->lEPIDp->setText(ll[1]); 363 | } 364 | if(ll[0]=="i") 365 | { 366 | tabPID->pids[1]->setText(ll[1]); 367 | tabEEPROM->lEPIDi->setText(ll[1]); 368 | } 369 | if(ll[0]=="d") 370 | { 371 | tabPID->pids[2]->setText(ll[1]); 372 | tabEEPROM->lEPIDd->setText(ll[1]); 373 | } 374 | if(ll[0]=="c") 375 | { 376 | tabPID->pids[3]->setText(ll[1]); 377 | } 378 | 379 | } 380 | } 381 | tabPID->addData(variables["T"],variables["B"],0,variables["@"]); 382 | 383 | } 384 | else if(s.startsWith("echo:")) 385 | { 386 | 387 | 388 | getdata(s,"M92","X",tabEEPROM->lEstepsperunit[0]); 389 | getdata(s,"M92","Y",tabEEPROM->lEstepsperunit[1]); 390 | getdata(s,"M92","Z",tabEEPROM->lEstepsperunit[2]); 391 | getdata(s,"M92","E",tabEEPROM->lEstepsperunit[3]); 392 | 393 | getdata(s,"M203","X",tabEEPROM->lEvmax[0]); 394 | getdata(s,"M203","Y",tabEEPROM->lEvmax[1]); 395 | getdata(s,"M203","Z",tabEEPROM->lEvmax[2]); 396 | getdata(s,"M203","E",tabEEPROM->lEvmax[3]); 397 | 398 | getdata(s,"M201","X",tabEEPROM->lEamax[0]); 399 | getdata(s,"M201","Y",tabEEPROM->lEamax[1]); 400 | getdata(s,"M201","Z",tabEEPROM->lEamax[2]); 401 | getdata(s,"M201","E",tabEEPROM->lEamax[3]); 402 | 403 | getdata(s,"M204","S",tabEEPROM->lEacceleration); 404 | getdata(s,"M204","T",tabEEPROM->lEaccelerationRetract); 405 | 406 | getdata(s,"M205","S",tabEEPROM->lEvmin); 407 | getdata(s,"M205","T",tabEEPROM->lEvmin_travel); 408 | getdata(s,"M205","B",tabEEPROM->lEtmin_segment); 409 | getdata(s,"M205","X",tabEEPROM->lEvxyjerk); 410 | getdata(s,"M205","Z",tabEEPROM->lEvzjerk); 411 | 412 | getdata(s,"M301","P",tabEEPROM->lEPIDp); 413 | getdata(s,"M301","I",tabEEPROM->lEPIDi); 414 | getdata(s,"M301","D",tabEEPROM->lEPIDd); 415 | 416 | //qDebug()<sendText->text()+"\n"); 434 | } 435 | 436 | 437 | void MainWindow::send(QString text) 438 | { 439 | tabRaw->displayTextHtml(QString("
Sending:%0
").arg(text)); 440 | if(!comport->isOpen()) 441 | return; 442 | QString text2=text.append("\n"); 443 | QByteArray ba=text2.toAscii(); //data to send 444 | qint64 bw = 0; //bytes really writed 445 | 446 | bw = comport->write(ba); 447 | 448 | } 449 | 450 | void MainWindow::sendGcode(const QString &text) 451 | { 452 | //qDebug()<<"gcode cue list:"<monitor->isChecked()) 522 | sendGcode("M105"); 523 | 524 | } 525 | 526 | void MainWindow::setHotend1Temp() 527 | { 528 | sendGcode(QString("M104 S%1").arg(tabPID->temp[hotend1]->text())); 529 | } 530 | 531 | void MainWindow::sendPID() 532 | { 533 | sendGcode(QString("M301 P%1 I%2 D%3 C%4").arg(tabPID->pids[0]->text()).arg(tabPID->pids[1]->text()).arg(tabPID->pids[2]->text()).arg(tabPID->pids[3]->text())); 534 | } 535 | 536 | void MainWindow::getPID() 537 | { 538 | sendGcode(QString("M301")); 539 | } 540 | 541 | 542 | void MainWindow::EEPROM_loadClicked() 543 | { 544 | //qDebug()<<"Load Clicked"; 545 | sendGcode(QString("M503")); 546 | } 547 | 548 | 549 | 550 | void MainWindow::EEPROM_resetClicked() 551 | { 552 | sendGcode("M501"); 553 | EEPROM_loadClicked(); 554 | } 555 | 556 | 557 | void MainWindow::EEPROM_factorResetClicked() 558 | { 559 | sendGcode("M502"); 560 | EEPROM_loadClicked(); 561 | } 562 | 563 | void MainWindow::EEPROM_storeClicked() 564 | { 565 | 566 | } 567 | 568 | void MainWindow::EEPROM_writeClicked() 569 | { 570 | /* 571 | * : M92 X79.87 Y79.87 Z533.00 E953.00 572 | echo:Maximum feedrates (mm/s): 573 | echo: M203 X200.00 Y200.00 Z19.00 E932.00 574 | echo:Maximum Acceleration (mm/s2): 575 | echo: M201 X10300 Y10500 Z500 E4700 576 | echo:Acceleration: S=acceleration, T=retract acceleration 577 | echo: M204 S4700.00 T7000.00 578 | echo:Advanced variables: S=Min feedrate (mm/s), T=Min travel feedrate (mm/s), B=minimum segment time (ms), X=maximum xY jerk (mm/s), Z=maximum Z jerk (mm/s) 579 | echo: M205 S0.00 T174.00 B20000 X36.00 Z600.00 580 | echo:PID settings: 581 | echo: M301 P24.00 I1.02 D141.00 582 | */ 583 | sendGcode(QString("M92 X%1 Y%2 Z%3 E%4").arg(tabEEPROM->lEstepsperunit[0]->text()).arg(tabEEPROM->lEstepsperunit[1]->text()).arg(tabEEPROM->lEstepsperunit[2]->text()).arg(tabEEPROM->lEstepsperunit[3]->text()) ); 584 | sendGcode(QString("M203 X%1 Y%2 Z%3 E%4").arg(tabEEPROM->lEvmax[0]->text()).arg(tabEEPROM->lEvmax[1]->text()).arg(tabEEPROM->lEvmax[2]->text()).arg(tabEEPROM->lEvmax[3]->text()) ); 585 | sendGcode(QString("M201 X%1 Y%2 Z%3 E%4").arg(tabEEPROM->lEamax[0]->text()).arg(tabEEPROM->lEamax[1]->text()).arg(tabEEPROM->lEamax[2]->text()).arg(tabEEPROM->lEamax[3]->text()) ); 586 | sendGcode(QString("M204 S%1 T%2").arg(tabEEPROM->lEacceleration->text()).arg(tabEEPROM->lEaccelerationRetract->text())); 587 | sendGcode(QString("M301 P%1 I%2 D%3").arg(tabEEPROM->lEPIDp->text()).arg(tabEEPROM->lEPIDi->text()).arg(tabEEPROM->lEPIDd->text())); 588 | } 589 | -------------------------------------------------------------------------------- /mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef __MAINWINDOWH 2 | #define __MAINWINDOWH 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | 10 | 11 | 12 | 13 | 14 | class MyThread; 15 | class QwtPlotCurve; 16 | class QwtPlot; 17 | class QStatusBar; 18 | class QCheckBox; 19 | class QTreeWidget; 20 | class QTreeWidgetItem; 21 | class QTabWidget; 22 | class QComboBox; 23 | class QPushButton; 24 | class QLineEdit; 25 | 26 | class TabPID; 27 | class TabRaw; 28 | class TabEEPROM; 29 | class TabVeltest; 30 | //class QextSerialPort; 31 | class SerialDeviceEnumerator; 32 | class AbstractSerial; 33 | class QTimer; 34 | 35 | #include 36 | 37 | //user choices: 38 | //#define USE_QEXTSERIALPORT //if comment QSerialDevice will be used 39 | //#define DONTUSE_QSERIALDEVICEENUMERATE //OSX fix for QSerialDevice 40 | 41 | #ifndef USE_QEXTSERIALPORT 42 | #define USE_QSERIALDEVICE 43 | #endif 44 | 45 | 46 | 47 | 48 | #ifdef USE_QEXTSERIALPORT 49 | #include "qextserialport.h" 50 | #include 51 | #endif 52 | 53 | #ifdef USE_QSERIALDEVICE 54 | #include 55 | #endif 56 | 57 | class MainWindow : public QWidget 58 | { 59 | Q_OBJECT 60 | 61 | public: 62 | MainWindow(QWidget *parent = 0); 63 | ~MainWindow(); 64 | 65 | 66 | void send(QString text); 67 | void sendGcode(const QString &text); //wait for "ok" 68 | 69 | QStringList sendcodes; 70 | QMap variables; 71 | 72 | bool wait_reply; 73 | bool endstopfound; 74 | 75 | 76 | public slots: 77 | void clickedConnect(); 78 | void clickedDisconnect(); 79 | void clickedRefresh(); 80 | void slotRead(); 81 | void manualSend(); 82 | void measure(); 83 | void setHotend1Temp(); 84 | 85 | void sendPID(); 86 | void getPID(); 87 | //void quit(); 88 | 89 | void processReply(); 90 | 91 | 92 | void EEPROM_loadClicked(); 93 | void EEPROM_writeClicked(); 94 | void EEPROM_storeClicked(); 95 | void EEPROM_resetClicked(); 96 | void EEPROM_factorResetClicked(); 97 | 98 | signals: 99 | void newSerialData(); 100 | 101 | private: 102 | QStatusBar *status; 103 | QTabWidget *tab; 104 | TabPID *tabPID; 105 | TabRaw *tabRaw; 106 | TabEEPROM *tabEEPROM; 107 | TabVeltest *tabVeltest; 108 | 109 | QComboBox *portSelector; 110 | QComboBox *baudSelector; 111 | QPushButton *btConnect; 112 | QPushButton *btDisconnect; 113 | QPushButton *btRescan; 114 | 115 | #ifdef USE_QEXTSERIALPORT 116 | QextSerialPort *comport; 117 | #endif 118 | 119 | #ifdef USE_QSERIALDEVICE 120 | AbstractSerial *comport; 121 | #endif 122 | QString serialBuffer; //so only full lines are handed to the next stuff. 123 | QTimer *timer; 124 | 125 | private: //functions 126 | void initSerial(); 127 | void openSerial(); 128 | void closeSerial(); 129 | 130 | void getdata(const QString &line,const QString &after, const QString &key,float &target); 131 | void getdata(const QString &line,const QString &after, const QString &key,QLineEdit *target); 132 | 133 | QByteArray serialBinBuffer; 134 | QString readSinceLastSend; 135 | bool pidloaded; 136 | }; 137 | 138 | #endif -------------------------------------------------------------------------------- /tab_eeprom.cpp: -------------------------------------------------------------------------------- 1 | #include "tab_eeprom.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | TabEEPROM::TabEEPROM(QWidget* parent): QWidget(parent) 19 | { 20 | QVBoxLayout *layout = new QVBoxLayout; 21 | //test=new QPushButton("test",this); 22 | QGridLayout *g1=new QGridLayout(this); 23 | QGridLayout *g2=new QGridLayout(this); 24 | QGridLayout *g3=new QGridLayout(this); 25 | QGridLayout *g4=new QGridLayout(this); 26 | QWidget *w1=new QWidget(this); 27 | QWidget *w2=new QWidget(this); 28 | QWidget *w3=new QWidget(this); 29 | QWidget *w4=new QWidget(this); 30 | w1->setLayout(g1); 31 | w2->setLayout(g2); 32 | w3->setLayout(g3); 33 | w4->setLayout(g4); 34 | uint8_t curline; 35 | 36 | curline=0; 37 | 38 | g1->addWidget(new QLabel(""),curline,0); 39 | g1->addWidget(new QLabel("X"),curline,1); 40 | g1->addWidget(new QLabel("Y"),curline,2); 41 | g1->addWidget(new QLabel("Z"),curline,3); 42 | g1->addWidget(new QLabel("E"),curline,4); 43 | 44 | curline=1; 45 | g1->addWidget(new QLabel("steps per mm"),curline,0); 46 | g1->addWidget(lEstepsperunit[0]=new QLineEdit("0"),curline,1);connect(lEstepsperunit[0], SIGNAL(editingFinished()),this,SLOT(changed())); 47 | g1->addWidget(lEstepsperunit[1]=new QLineEdit("0"),curline,2);connect(lEstepsperunit[1], SIGNAL(editingFinished()),this,SLOT(changed())); 48 | g1->addWidget(lEstepsperunit[2]=new QLineEdit("0"),curline,3);connect(lEstepsperunit[2], SIGNAL(editingFinished()),this,SLOT(changed())); 49 | g1->addWidget(lEstepsperunit[3]=new QLineEdit("0"),curline,4);connect(lEstepsperunit[3], SIGNAL(editingFinished()),this,SLOT(changed())); 50 | 51 | curline=2; 52 | g1->addWidget(new QLabel("v max [mm/sec]"),curline,0); 53 | g1->addWidget(lEvmax[0]=new QLineEdit("0"),curline,1);connect(lEvmax[0], SIGNAL(editingFinished()),this,SLOT(changed())); 54 | g1->addWidget(lEvmax[1]=new QLineEdit("0"),curline,2);connect(lEvmax[1], SIGNAL(editingFinished()),this,SLOT(changed())); 55 | g1->addWidget(lEvmax[2]=new QLineEdit("0"),curline,3);connect(lEvmax[2], SIGNAL(editingFinished()),this,SLOT(changed())); 56 | g1->addWidget(lEvmax[3]=new QLineEdit("0"),curline,4);connect(lEvmax[3], SIGNAL(editingFinished()),this,SLOT(changed())); 57 | 58 | curline=3; 59 | g1->addWidget(new QLabel("a max [mm/sec^2]"),curline,0); 60 | g1->addWidget(lEamax[0]=new QLineEdit("0"),curline,1);connect(lEamax[0], SIGNAL(editingFinished()),this,SLOT(changed())); 61 | g1->addWidget(lEamax[1]=new QLineEdit("0"),curline,2);connect(lEamax[1], SIGNAL(editingFinished()),this,SLOT(changed())); 62 | g1->addWidget(lEamax[2]=new QLineEdit("0"),curline,3);connect(lEamax[2], SIGNAL(editingFinished()),this,SLOT(changed())); 63 | g1->addWidget(lEamax[3]=new QLineEdit("0"),curline,4);connect(lEamax[3], SIGNAL(editingFinished()),this,SLOT(changed())); 64 | 65 | 66 | curline=0; 67 | 68 | g2->addWidget(new QLabel(""),curline,0); 69 | g2->addWidget(new QLabel(""),curline,1); 70 | 71 | curline++; 72 | g2->addWidget(new QLabel("acceleration [mm/sec^2]"),curline,0); 73 | g2->addWidget(lEacceleration=new QLineEdit("0"),curline,1);connect(lEacceleration, SIGNAL(editingFinished()),this,SLOT(changed())); 74 | g2->addWidget(new QLabel("retract acceleration [mm/sec^2]"),curline,2); 75 | g2->addWidget(lEaccelerationRetract=new QLineEdit("0"),curline,3); connect(lEaccelerationRetract, SIGNAL(editingFinished()),this,SLOT(changed())); 76 | 77 | curline++; 78 | g2->addWidget(new QLabel("Jerk velocity xy [mm/sec]"),curline,0); 79 | g2->addWidget(lEvxyjerk=new QLineEdit("0"),curline,1);connect(lEvxyjerk, SIGNAL(editingFinished()),this,SLOT(changed())); 80 | g2->addWidget(new QLabel("Jerk velocity z [mm/sec]"),curline,2); 81 | g2->addWidget(lEvzjerk=new QLineEdit("0"),curline,3);connect(lEvzjerk, SIGNAL(editingFinished()),this,SLOT(changed())); 82 | 83 | curline++; 84 | g2->addWidget(new QLabel("Minimum velocity [mm/sec]"),curline,0); 85 | g2->addWidget(lEvmin=new QLineEdit("0"),curline,1);connect(lEvmin, SIGNAL(editingFinished()),this,SLOT(changed())); 86 | g2->addWidget(new QLabel("Minimum travel velocity [mm/sec]"),curline,2); 87 | g2->addWidget(lEvmin_travel=new QLineEdit("0"),curline,3);connect(lEvmin_travel, SIGNAL(editingFinished()),this,SLOT(changed())); 88 | 89 | curline++; 90 | g2->addWidget(new QLabel("Minimum segment time [usec]"),curline,0); 91 | g2->addWidget(lEtmin_segment=new QLineEdit("0"),curline,1);connect(lEtmin_segment, SIGNAL(editingFinished()),this,SLOT(changed())); 92 | 93 | curline++; 94 | g2->addWidget(new QLabel("PID"),curline,0); 95 | g2->addWidget(lEPIDp=new QLineEdit("0"),curline,1);connect(lEPIDp, SIGNAL(editingFinished()),this,SLOT(changed())); 96 | g2->addWidget(lEPIDi=new QLineEdit("0"),curline,2);connect(lEPIDi, SIGNAL(editingFinished()),this,SLOT(changed())); 97 | g2->addWidget(lEPIDd=new QLineEdit("0"),curline,3);connect(lEPIDd, SIGNAL(editingFinished()),this,SLOT(changed())); 98 | 99 | 100 | g3->addWidget(pbRead=new QPushButton("Read Mem"),curline,0); 101 | g3->addWidget(pbWrite=new QPushButton("Write Mem"),curline,1); 102 | g3->addWidget(pbStore=new QPushButton("Store EEPROM"),curline,2); 103 | g3->addWidget(pbReset=new QPushButton("Read EEPROM "),curline,3); 104 | g3->addWidget(pbFactorReset=new QPushButton("Read Factory "),curline,4); 105 | pbStore->setStyleSheet("background-color: rgb(255, 0, 0); color: rgb(255, 255, 255)"); 106 | pbReset->setStyleSheet("background-color: rgb(255, 0, 0); color: rgb(255, 255, 255)"); 107 | pbFactorReset->setStyleSheet("background-color: rgb(255, 0, 0); color: rgb(255, 255, 255)"); 108 | 109 | curline=0; 110 | g4->addWidget(new QLabel("Vmax xy:"),curline,0); 111 | g4->addWidget(new QLabel("Acc. Distance:"),curline,1); 112 | g4->addWidget(lbAccDis=new QLabel("0"),curline,2); 113 | g4->addWidget(new QLabel("Acceleration time:"),curline,3); 114 | g4->addWidget(lbAccTime=new QLabel("0"),curline,4); 115 | 116 | curline=1; 117 | g4->addWidget(new QLabel("100 mm/s:"),curline,0); 118 | g4->addWidget(new QLabel("Acc. Distance:"),curline,1); 119 | g4->addWidget(lbAccDis100=new QLabel("0"),curline,2); 120 | g4->addWidget(new QLabel("Acceleration time:"),curline,3); 121 | g4->addWidget(lbAccTime100=new QLabel("0"),curline,4); 122 | layout->addWidget(w1); 123 | layout->addWidget(w2); 124 | layout->addWidget(w4); 125 | layout->addWidget(w3); 126 | setLayout(layout); 127 | 128 | } 129 | 130 | 131 | void TabEEPROM::EEPROM_recalculate() 132 | { 133 | float amax=lEacceleration->text().toFloat(); 134 | float vx=lEvmax[0]->text().toFloat(); 135 | float vy=lEvmax[1]->text().toFloat(); 136 | float vz=lEvmax[2]->text().toFloat(); 137 | float vxyjerk=lEvxyjerk->text().toFloat(); 138 | float vmin=vx; 139 | if(vyvmax) vmax=vy; 143 | //if(vz>vmax) vmax=vz; 144 | 145 | float t=(vmax-vxyjerk)/amax; 146 | float adis=amax/2.*t*t; 147 | lbAccDis->setText(QString("%1 mm").arg(adis)); 148 | lbAccTime->setText(QString("%1 ms").arg(t*1000)); 149 | 150 | t=(100-vxyjerk)/amax; 151 | adis=amax/2.*t*t; 152 | lbAccDis100->setText(QString("%1 mm").arg(adis)); 153 | lbAccTime100->setText(QString("%1 ms").arg(t*1000)); 154 | } 155 | 156 | void TabEEPROM::changed() 157 | { 158 | EEPROM_recalculate(); 159 | } 160 | 161 | -------------------------------------------------------------------------------- /tab_eeprom.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | class MyThread; 7 | class QwtPlotCurve; 8 | class QwtPlot; 9 | class QStatusBar; 10 | class QCheckBox; 11 | class QTreeWidget; 12 | class QTreeWidgetItem; 13 | class QTabWidget; 14 | class QPushButton; 15 | class QLineEdit; 16 | class QLabel; 17 | 18 | class TabEEPROM : public QWidget 19 | { 20 | Q_OBJECT 21 | 22 | public: 23 | TabEEPROM(QWidget *parent = 0); 24 | 25 | 26 | // float stepsperunit[4]; 27 | // float vmax[4]; 28 | // float amax[4]; 29 | // float acceleration, accelerationRetract; 30 | // float vxyjerk,vzjerk; 31 | // float vmin,vmin_travel; 32 | // float tmin_segment; 33 | 34 | QLineEdit *lEstepsperunit[4]; 35 | QLineEdit *lEvmax[4]; 36 | QLineEdit *lEamax[4]; 37 | QLineEdit *lEacceleration; 38 | QLineEdit *lEaccelerationRetract; 39 | QLineEdit *lEvxyjerk; 40 | QLineEdit *lEvzjerk; 41 | QLineEdit *lEvmin; 42 | QLineEdit *lEvmin_travel; 43 | QLineEdit *lEtmin_segment; 44 | QLineEdit *lEPIDp,*lEPIDd,*lEPIDi; 45 | 46 | QPushButton *pbRead,*pbWrite,*pbStore,*pbReset,*pbFactorReset; 47 | 48 | QLabel *lbAccDis,*lbAccTime; 49 | QLabel *lbAccDis100,*lbAccTime100; 50 | QLabel *lbStepRate; 51 | void EEPROM_recalculate(); 52 | public slots: 53 | //void setWasRead(); 54 | //void quit(); 55 | void changed(); 56 | 57 | 58 | private: 59 | QPushButton *test; 60 | }; 61 | 62 | -------------------------------------------------------------------------------- /tab_pid.cpp: -------------------------------------------------------------------------------- 1 | #include "tab_pid.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | TabPID::TabPID(QWidget* parent): QWidget(parent) 23 | { 24 | QVBoxLayout *layout = new QVBoxLayout; 25 | 26 | 27 | tempPlot = new QwtPlot( this); 28 | //myPlot->setAxisTitle(QwtPlot::xBottom,""); 29 | tempPlot->setAxisTitle(QwtPlot::yLeft,"Celsius"); 30 | heaterPlot= new QwtPlot(this); 31 | heaterPlot->setAxisTitle(QwtPlot::yLeft,"Heating Power"); 32 | QwtPlotGrid *myGrid=new QwtPlotGrid(); 33 | myGrid->attach(tempPlot); 34 | QwtPlotGrid *myhGrid=new QwtPlotGrid(); 35 | myhGrid->attach(heaterPlot); 36 | tempPlot->insertLegend(new QwtLegend()); 37 | heaterPlot->insertLegend(new QwtLegend()); 38 | tempPlot->setMaximumHeight(150); 39 | heaterPlot->setMaximumHeight(150); 40 | double x[2]={0,0}; 41 | double y[2]={0,0}; 42 | 43 | curve[hotend1] = new QwtPlotCurve("Hotend 1"); 44 | curve[bed] = new QwtPlotCurve("Bed"); 45 | curve[hotend2] = new QwtPlotCurve("Hotend 2"); 46 | curve[heater] = new QwtPlotCurve("Heater"); 47 | for(int i=0;i<4;i++) 48 | { 49 | curve[i]->setSamples(x,y,2); 50 | curve[i]->setPen(QPen(QColor::fromHsv((255*i)/10,255,255),2)); 51 | 52 | } 53 | curve[0]->attach(tempPlot); 54 | curve[1]->attach(tempPlot); 55 | curve[2]->attach(tempPlot); 56 | curve[3]->attach(heaterPlot); 57 | tempPlot->replot(); 58 | heaterPlot->replot(); 59 | 60 | 61 | 62 | 63 | layout->addWidget(tempPlot); 64 | layout->addWidget(heaterPlot); 65 | QHBoxLayout *h1layout = new QHBoxLayout; 66 | 67 | QGroupBox *gb1=new QGroupBox("Temperature:"); 68 | QGroupBox *gb2=new QGroupBox("PID values:"); 69 | QGroupBox *gb3=new QGroupBox("Ziegler-Nichols:"); 70 | 71 | QGridLayout *gb1g=new QGridLayout; 72 | gb1g->addWidget(new QLabel("Hotend 1:"),0,0); 73 | gb1g->addWidget(temp[0]=new QLineEdit("0"),0,1); 74 | gb1g->addWidget(new QLabel("Bed:"),1,0); 75 | gb1g->addWidget(temp[1]=new QLineEdit("0"),1,1); 76 | gb1g->addWidget(new QLabel("Hotend 2:"),2,0); 77 | gb1g->addWidget(temp[2]=new QLineEdit("0"),2,1); 78 | gb1->setLayout(gb1g); 79 | temp[0]->setMaxLength(3); 80 | temp[1]->setMaxLength(3); 81 | temp[2]->setMaxLength(3); 82 | 83 | QGridLayout *gb2g=new QGridLayout; 84 | gb2g->addWidget(new QLabel("Proportional:"),0,0); 85 | gb2g->addWidget(pids[0]=new QLineEdit("0"),0,1); 86 | gb2g->addWidget(new QLabel("Integral:"),1,0); 87 | gb2g->addWidget(pids[1]=new QLineEdit("0"),1,1); 88 | gb2g->addWidget(new QLabel("Differential:"),2,0); 89 | gb2g->addWidget(pids[2]=new QLineEdit("0"),2,1); 90 | gb2g->addWidget(new QLabel("Extruder speed prop:"),3,0); 91 | gb2g->addWidget(pids[3]=new QLineEdit("0"),3,1); 92 | gb2g->addWidget(btLoad=new QPushButton("Load"),4,0); 93 | gb2->setLayout(gb2g); 94 | // pids[0]->setMaxLength(3); 95 | // pids[1]->setMaxLength(3); 96 | // pids[2]->setMaxLength(3); 97 | // pids[3]->setMaxLength(3); 98 | 99 | QGridLayout *gb3g=new QGridLayout; 100 | 101 | gb3g->addWidget(new QLabel("Critical prop. Gain:"),0,0); 102 | gb3g->addWidget(eCriticalGain=new QLineEdit("0"),0,1); 103 | gb3g->addWidget(btPeriod=new QPushButton("Period [sec]@critical:"),1,0); 104 | gb3g->addWidget(ePeriod=new QLineEdit("0"),1,1); 105 | gb3g->addWidget(cbZieglerDif=new QCheckBox("PI+D?"),2,0); 106 | //gb3g->addWidget(pids[2]=new QLineEdit("0"),2,1); 107 | gb3g->addWidget(btSet=new QPushButton("Set",this),3,0); 108 | //gb3g->addWidget(pids[3]=new QLineEdit("0"),3,1); 109 | gb3->setLayout(gb3g); 110 | 111 | h1layout->addWidget(gb1); 112 | h1layout->addWidget(gb2); 113 | h1layout->addWidget(gb3); 114 | layout->addLayout(h1layout); 115 | 116 | QHBoxLayout *h2layout = new QHBoxLayout; 117 | monitor=new QCheckBox("monitor temp",this); 118 | h2layout->addWidget(monitor); 119 | differential=new QCheckBox("Offset Temperature",this); 120 | h2layout->addWidget(differential); 121 | btClear=new QPushButton("Clear"); 122 | h2layout->addWidget(btClear); 123 | h2layout->addWidget(new QLabel("Period [sec]:")); 124 | h2layout->addWidget(lPeriod=new QLabel("0")); 125 | 126 | h2layout->addWidget(new QLabel("Amplitude [C]:")); 127 | h2layout->addWidget(lAmp=new QLabel("0")); 128 | h2layout->addWidget(new QLabel("last Amplitude [C]:")); 129 | h2layout->addWidget(lAmpPrevious=new QLabel("0")); 130 | 131 | h2layout->addWidget(new QLabel("ratio:")); 132 | h2layout->addWidget(lAmpRatio=new QLabel("0")); 133 | 134 | layout->addLayout(h2layout); 135 | setLayout(layout); 136 | 137 | 138 | connect(btClear,SIGNAL(clicked(bool)),this,SLOT(clearClicked())); 139 | connect(btPeriod,SIGNAL(clicked(bool)),this,SLOT(periodClicked())); 140 | connect(btSet,SIGNAL(clicked(bool)),this,SLOT(setClicked())); 141 | //connect(btLoad,SIGNAL(clicked(bool)),this,SLOT(loadClicked())); 142 | 143 | 144 | } 145 | 146 | 147 | void TabPID::addData(float t1, float b, float t2, float h) 148 | { 149 | QTime now=QTime::currentTime(); 150 | float dt=starttime.msecsTo(now); 151 | 152 | value_hotend1.push_back(t1); 153 | time.push_back(dt); 154 | value_bed.push_back(b); 155 | value_hotend2.push_back(t2); 156 | value_heater.push_back(h/255.); 157 | 158 | target_hotend1.push_back(temp[hotend1]->text().toDouble()); 159 | target_hotend2.push_back(temp[hotend2]->text().toDouble()); 160 | target_bed.push_back(temp[bed]->text().toDouble()); 161 | 162 | if(differential->checkState()) 163 | { 164 | QVector d[3]; 165 | 166 | d[0].resize(value_hotend1.size()); 167 | d[1].resize(value_hotend1.size()); 168 | d[2].resize(value_hotend1.size()); 169 | for(int i=0;isetSamples(time,d[0]); 176 | curve[hotend2]->setSamples(time,d[2]); 177 | curve[bed]->setSamples(time,d[1]); 178 | } 179 | else 180 | { 181 | curve[hotend1]->setSamples(time,value_hotend1); 182 | curve[hotend2]->setSamples(time,value_hotend2); 183 | curve[bed]->setSamples(time,value_bed); 184 | } 185 | curve[heater]->setSamples(time,value_heater); 186 | tempPlot->replot(); 187 | heaterPlot->replot(); 188 | calculatePeriodicity(); 189 | } 190 | 191 | void TabPID::calculatePeriodicity() 192 | { 193 | if(value_hotend1.size()<5) 194 | return; 195 | float t=value_hotend1.last(); 196 | int period=0; 197 | int previouslast=value_hotend1.size()-1; 198 | bool firsteventfound=false; 199 | for(int i=value_hotend1.size()-2;i>0;i--) 200 | { 201 | if( ((value_hotend1[i]>=t)&&(value_hotend1[i-1]t)) ) 202 | { 203 | if(previouslast-i>5) 204 | { 205 | if(firsteventfound) 206 | { 207 | 208 | period=value_hotend1.size()-i; 209 | lPeriod->setText(QString("%1").arg(period)); 210 | break; 211 | } 212 | else 213 | { 214 | firsteventfound=true; 215 | previouslast=i; 216 | } 217 | 218 | } 219 | else //in proximity 220 | { 221 | previouslast=i; 222 | 223 | } 224 | } 225 | } 226 | 227 | float minnow=100000,maxnow=0; 228 | float minlast=100000,maxlast=0; 229 | for(int i=value_hotend1.size()-2;i>value_hotend1.size()-period;i--) 230 | { 231 | double &f=value_hotend1[i]; 232 | if(fmaxnow) maxnow=f; 234 | } 235 | lAmp->setText(QString("%1").arg(maxnow-minnow)); 236 | 237 | if(value_hotend1.size()-2*period) 238 | { 239 | //float minnow=100000,maxnow=0; 240 | //float minlast=100000,maxlast=0; 241 | for(int i=value_hotend1.size()-period;i>value_hotend1.size()-2*period;i--) 242 | { 243 | double &f=value_hotend1[i]; 244 | if(fmaxlast) maxlast=f; 246 | } 247 | lAmpPrevious->setText(QString("%1").arg(maxlast-minlast)); 248 | } 249 | lAmpRatio->setText(QString("%1").arg(lAmp->text().toFloat()/lAmpPrevious->text().toFloat())); 250 | } 251 | 252 | void TabPID::startTime() 253 | { 254 | starttime= QTime::currentTime(); 255 | } 256 | 257 | 258 | void TabPID::clearClicked() 259 | { 260 | time.resize(0); 261 | value_hotend1.resize(0); 262 | value_bed.resize(0); 263 | value_hotend2.resize(0); 264 | value_heater.resize(0); 265 | 266 | target_hotend1.resize(0); 267 | target_hotend2.resize(0); 268 | target_bed.resize(0); 269 | startTime(); 270 | 271 | } 272 | 273 | void TabPID::periodClicked() 274 | { 275 | ePeriod->setText(lPeriod->text()); 276 | } 277 | 278 | void TabPID::setClicked() 279 | { 280 | float ku=eCriticalGain->text().toFloat(); 281 | float t=ePeriod->text().toFloat(); 282 | float kp=0,ki=0,kd=0; 283 | if(cbZieglerDif->isChecked()) 284 | { //PID 285 | kp=0.6*ku; 286 | ki=2.*kp/t; 287 | kd=kp*t/8.; 288 | } 289 | else //PI only 290 | { 291 | kp=ku/2.2; 292 | ki=1.2*kp/t; 293 | kd=0; 294 | } 295 | pids[0]->setText(QString("%1").arg(kp)); 296 | pids[1]->setText(QString("%1").arg(ki)); 297 | pids[2]->setText(QString("%1").arg(kd)); 298 | emit pidChanged(); 299 | } 300 | -------------------------------------------------------------------------------- /tab_pid.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class MyThread; 10 | class QwtPlotCurve; 11 | class QwtPlot; 12 | class QStatusBar; 13 | class QCheckBox; 14 | class QTreeWidget; 15 | class QTreeWidgetItem; 16 | class QTabWidget; 17 | class QPushButton; 18 | class QLineEdit; 19 | class QLabel; 20 | 21 | enum Curves {hotend1=0,bed=1,hotend2=2,heater=3}; 22 | 23 | class TabPID : public QWidget 24 | { 25 | Q_OBJECT 26 | 27 | public: 28 | TabPID(QWidget *parent = 0); 29 | void addData(float t1,float b,float t2,float h); 30 | void startTime(); 31 | void calculatePeriodicity(); 32 | 33 | 34 | QwtPlotCurve *curve[4] ; 35 | QwtPlot *tempPlot,*heaterPlot; 36 | 37 | QPushButton *clear; 38 | QLineEdit *temp[3]; 39 | QLineEdit *pids[4]; 40 | 41 | QVector time; 42 | QVector value_hotend1,value_hotend2,value_bed,value_heater; 43 | QVector target_hotend1,target_hotend2,target_bed; 44 | QTime starttime; 45 | QCheckBox *differential,*monitor; 46 | QPushButton *btClear, *btPeriod, *btSet,*btLoad; 47 | QLabel *lPeriod,*lAmp,*lAmpPrevious,*lAmpRatio; 48 | QLineEdit *ePeriod,*eCriticalGain; 49 | QCheckBox *cbZieglerDif; 50 | 51 | public slots: 52 | //void setWasRead(); 53 | //void quit(); 54 | void clearClicked(); 55 | void periodClicked(); 56 | void setClicked(); 57 | signals: 58 | void pidChanged(); 59 | private: 60 | QPushButton *test; 61 | }; 62 | 63 | -------------------------------------------------------------------------------- /tab_raw.cpp: -------------------------------------------------------------------------------- 1 | #include "tab_raw.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | 23 | TabRaw::TabRaw(QWidget* parent): QWidget(parent) 24 | { 25 | QVBoxLayout *layout = new QVBoxLayout; 26 | edit=new QTextEdit("",this); 27 | edit->setReadOnly(true); 28 | 29 | layout->addWidget(edit); 30 | //layout->addWidget(slider); 31 | 32 | QHBoxLayout *hlayout = new QHBoxLayout; 33 | hlayout->addWidget(new QLabel("Send:",this)); 34 | sendText= new QLineEdit("",this); 35 | hlayout->addWidget(sendText); 36 | 37 | btClear=new QPushButton("clear",this); 38 | hlayout->addWidget(btClear); 39 | layout->addLayout(hlayout); 40 | setLayout(layout); 41 | 42 | } 43 | 44 | void TabRaw::displayText(const QString& text) 45 | { 46 | edit->moveCursor(QTextCursor::End); 47 | edit->insertPlainText(text); 48 | if(!edit->underMouse()) 49 | edit->ensureCursorVisible(); 50 | } 51 | 52 | void TabRaw::displayTextHtml(const QString& text) 53 | { 54 | edit->moveCursor(QTextCursor::End); 55 | edit->insertHtml(text); 56 | if(!edit->underMouse()) 57 | edit->ensureCursorVisible(); 58 | } 59 | -------------------------------------------------------------------------------- /tab_raw.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | class MyThread; 7 | class QwtPlotCurve; 8 | class QwtPlot; 9 | class QStatusBar; 10 | class QCheckBox; 11 | class QTreeWidget; 12 | class QTreeWidgetItem; 13 | class QTabWidget; 14 | class QPushButton; 15 | 16 | 17 | class QTextEdit; 18 | class QLineEdit; 19 | 20 | class TabRaw : public QWidget 21 | { 22 | Q_OBJECT 23 | 24 | public: 25 | TabRaw(QWidget *parent = 0); 26 | void displayText(const QString &text); 27 | void displayTextHtml(const QString& text); 28 | 29 | QTextEdit *edit; 30 | QLineEdit *sendText; 31 | QPushButton *btClear; 32 | 33 | 34 | 35 | public slots: 36 | //void setWasRead(); 37 | //void quit(); 38 | 39 | 40 | private: 41 | QPushButton *test; 42 | }; 43 | 44 | -------------------------------------------------------------------------------- /tab_veltest.cpp: -------------------------------------------------------------------------------- 1 | #include "tab_veltest.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | TabVeltest::TabVeltest(MainWindow* _mw,QWidget *parent): QWidget(parent) 24 | { 25 | mw=_mw; 26 | testing=false; 27 | QVBoxLayout *layout = new QVBoxLayout; 28 | 29 | QHBoxLayout *h1box=new QHBoxLayout(this); 30 | 31 | QGridLayout *g1=new QGridLayout(this); 32 | g1->addWidget(new QLabel(""),0,0); 33 | g1->addWidget(new QLabel("Vmin"),0,1); 34 | g1->addWidget(new QLabel("Vmax"),0,2); 35 | g1->addWidget(new QLabel("Amax"),0,3); 36 | 37 | 38 | g1->addWidget(doTest[0]=new QPushButton("X"), 1,0); 39 | g1->addWidget(vmin[0]=new QLineEdit("100"), 1,1); 40 | g1->addWidget(vmax[0]=new QLineEdit("500"), 1,2); 41 | g1->addWidget(amax[0]=new QLineEdit("10000"), 1,3); 42 | 43 | g1->addWidget(doTest[1]=new QPushButton("Y"), 2,0); 44 | g1->addWidget(vmin[1]=new QLineEdit("100"), 2,1); 45 | g1->addWidget(vmax[1]=new QLineEdit("500"), 2,2); 46 | g1->addWidget(amax[1]=new QLineEdit("10000"), 2,3); 47 | 48 | g1->addWidget(doTest[2]=new QPushButton("Z"), 3,0); 49 | g1->addWidget(vmin[2]=new QLineEdit("5"), 3,1); 50 | g1->addWidget(vmax[2]=new QLineEdit("30"), 3,2); 51 | g1->addWidget(amax[2]=new QLineEdit("10000"), 3,3); 52 | 53 | g1->addWidget(new QLabel("Teststeps"), 4,0); 54 | g1->addWidget(vsteps=new QLineEdit("5"),4,2); 55 | g1->addWidget(asteps=new QLineEdit("5"),4,3); 56 | g1->addWidget(new QLabel(""),5,0); 57 | g1->setColumnStretch(5,1); 58 | g1->setColumnStretch(0,0); 59 | 60 | connect(doTest[0],SIGNAL(clicked(bool)), this,SLOT(testX())); 61 | connect(doTest[1],SIGNAL(clicked(bool)), this,SLOT(testY())); 62 | connect(doTest[2],SIGNAL(clicked(bool)), this,SLOT(testZ())); 63 | 64 | h1box->addLayout(g1); 65 | 66 | 67 | plot= new QwtPlot( this); 68 | 69 | //myPlot->setAxisTitle(QwtPlot::xBottom,""); 70 | plot->setAxisTitle(QwtPlot::yLeft,"a mm/sec^2"); 71 | plot->setAxisTitle(QwtPlot::xBottom,"v mm/sec"); 72 | 73 | QwtPlotGrid *myGrid=new QwtPlotGrid(); 74 | myGrid->attach(plot); 75 | plot->insertLegend(new QwtLegend()); 76 | //double x[2]={0,0}; 77 | //double y[2]={0,0}; 78 | 79 | curveGood= new QwtPlotCurve("Good"); 80 | curveFail = new QwtPlotCurve("Fail"); 81 | 82 | //curveGood->setSamples(x,y,2); 83 | curveGood->setPen(QPen(Qt::blue,2)); 84 | //curveFail->setSamples(x,y,2); 85 | curveFail->setPen(QPen(Qt::red,2)); 86 | curveGood->setStyle(QwtPlotCurve::Dots); 87 | curveFail->setStyle(QwtPlotCurve::Dots); 88 | 89 | 90 | curveGood->attach(plot); 91 | curveFail->attach(plot); 92 | 93 | QwtSymbol *s=new QwtSymbol(QwtSymbol::Rect); 94 | s->setSize(10,10); 95 | s->setColor(Qt::blue); 96 | curveGood->setSymbol(s); 97 | 98 | QwtSymbol *s2=new QwtSymbol(QwtSymbol::Rect); 99 | s2->setSize(10,10); 100 | s2->setColor(Qt::red); 101 | curveFail->setSymbol(s2); 102 | plot->replot(); 103 | 104 | 105 | h1box->addWidget(plot); 106 | layout->addLayout(h1box); 107 | 108 | //setLayout(layout); 109 | 110 | } 111 | 112 | void TabVeltest::testX() 113 | { 114 | starttest(0); 115 | } 116 | 117 | void TabVeltest::testY() 118 | { 119 | starttest(1); 120 | } 121 | 122 | void TabVeltest::testZ() 123 | { 124 | starttest(2); 125 | } 126 | 127 | void TabVeltest::starttest(uint8_t axis) 128 | { 129 | if(axis==2) 130 | return; 131 | 132 | float v,a; 133 | int nrV=vsteps->text().toInt(); 134 | int nrA=asteps->text().toInt()+1; 135 | for(int i=0;i<=nrV;i++) 136 | { 137 | v=vmin[axis]->text().toFloat()+(vmax[axis]->text().toFloat()-vmin[axis]->text().toFloat())*i/float(nrV); 138 | for(int j=1;j<=nrA;j++) 139 | { 140 | a=amax[axis]->text().toFloat()*j/float(nrA); 141 | bool result=testSetting(axis,v,a,30,10); 142 | 143 | } 144 | 145 | } 146 | 147 | 148 | 149 | } 150 | 151 | void TabVeltest::startTestCase(TestCase& tc) 152 | { 153 | float t=tc.v/tc.a; 154 | 155 | //float x=tc.a*t*t/2.*2; //10mm + full acceleration distance. 156 | float x=200; 157 | 158 | qDebug()<<"Test:"<endstopfound=false; 160 | mw->sendGcode(QString("M205 S0 T0")); 161 | mw->sendGcode(QString("M205 S0 T0 %0%1 Z%2").arg(AxisChars[tc.axis]).arg(tc.xyjerk).arg(tc.zjerk)); 162 | mw->sendGcode(QString("M202 %00%1 Y%2 ").arg(AxisChars[tc.axis]).arg(tc.a).arg(tc.a)); 163 | mw->sendGcode(QString("M204 S%0 T%1 ").arg(tc.a).arg(tc.a)); 164 | mw->sendGcode(QString("M203 %00%1 Y%2 ").arg(AxisChars[tc.axis]).arg(tc.v).arg(tc.v)); 165 | mw->sendGcode(QString("G28 %000 ").arg(AxisChars[tc.axis])); 166 | 167 | 168 | mw->sendGcode(QString("G1 %00%1 F%2").arg(AxisChars[tc.axis]).arg(x).arg(tc.v*60)); 169 | mw->sendGcode(QString("M400")); 170 | mw->sendGcode(QString("G1 %001 F%1").arg(AxisChars[tc.axis]).arg(tc.v*0.5*60)); 171 | mw->sendGcode(QString("M400")); 172 | testing=true; 173 | } 174 | 175 | #include 176 | bool TabVeltest::testSetting(uint8_t axis, float v, float a, float xyjerk, float zjerk) 177 | { 178 | struct TestCase tc; 179 | tc.axis=axis; 180 | tc.v=v; 181 | tc.a=a; 182 | tc.xyjerk=xyjerk; 183 | tc.zjerk=zjerk; 184 | float t=tc.v/tc.a; 185 | if(tc.a*t*t/2.*2>200) return false; 186 | bufferedCases.push_back(tc); 187 | qDebug()<<"Adding testcase; "<<(testing?" already testing":"not testing until now")<<" a="<sendGcode(QString("G1 Z10 F400")); 192 | startTestCase(bufferedCases[0]); 193 | testing=true; 194 | } 195 | 196 | 197 | 198 | } 199 | 200 | 201 | 202 | void TabVeltest::checkDone() 203 | { 204 | if(!testing) 205 | return; 206 | //qDebug()<<"checking"<sendcodes.size()!=0) //if mainwindow is still sending, not finished 208 | return; 209 | qDebug()<<"no more sending"; 210 | if(bufferedCases.size()==0) //if cue is empty, we are finished 211 | { 212 | testing=false; 213 | return; 214 | } 215 | //qDebug()<<"still stuff do do."<endstopfound); 219 | if(!badresult) 220 | { 221 | sucess_x.push_back(bufferedCases[0].v); 222 | sucess_y.push_back(bufferedCases[0].a); 223 | curveGood->setSamples(sucess_x,sucess_y); 224 | } 225 | else 226 | { 227 | fail_x.push_back(bufferedCases[0].v); 228 | fail_y.push_back(bufferedCases[0].a); 229 | curveFail->setSamples(fail_x,fail_y); 230 | } 231 | plot->replot(); 232 | 233 | 234 | 235 | float lasta,lastv; 236 | lasta=bufferedCases[0].a; 237 | lastv=bufferedCases[0].v; 238 | bufferedCases.removeFirst(); 239 | qDebug()<<"still buffered"<=lasta && bufferedCases[0].v>=lastv) 247 | { 248 | bufferedCases.removeFirst(); 249 | if(bufferedCases.size()==0) 250 | { 251 | qDebug()<<"Testing done"< 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class MyThread; 10 | class QwtPlotCurve; 11 | class QwtPlot; 12 | class QStatusBar; 13 | class QCheckBox; 14 | class QTreeWidget; 15 | class QTreeWidgetItem; 16 | class QTabWidget; 17 | class QPushButton; 18 | class QLineEdit; 19 | class QLabel; 20 | 21 | #include "mainwindow.h" 22 | 23 | const char AxisChars[]={'X','Y','Z','E'}; 24 | struct TestCase 25 | { 26 | uint8_t axis; 27 | float v,a,xyjerk,zjerk; 28 | }; 29 | 30 | class TabVeltest : public QWidget 31 | { 32 | Q_OBJECT 33 | 34 | public: 35 | TabVeltest(MainWindow* _mw,QWidget *parent); 36 | 37 | void calculatePeriodicity(); 38 | void starttest(uint8_t axis); 39 | bool testSetting(uint8_t axis, float v, float a, float xyjerk, float zjerk); 40 | void startTestCase(TestCase &tc); 41 | 42 | 43 | QwtPlotCurve *curveGood,*curveFail ; 44 | QwtPlot *plot; 45 | 46 | 47 | QLineEdit *vmax[4],*vmin[4],*vsteps; 48 | QLineEdit *amax[4],*asteps; 49 | QPushButton *doTest[3]; 50 | 51 | QVector sucess_x,sucess_y; 52 | QVector fail_x,fail_y; 53 | 54 | MainWindow *mw; 55 | QList bufferedCases; 56 | 57 | 58 | public slots: 59 | void testX(); 60 | void testY(); 61 | void testZ(); 62 | void checkDone(); 63 | 64 | signals: 65 | 66 | private: 67 | bool testing; 68 | }; 69 | 70 | --------------------------------------------------------------------------------