#include "win01_com.h" #include "stepList.h" // define all working chain steps here #include "datei.h" //#include "globVars.h" // %%%%%%%%%%%%%%%%%%%% TabComPort Console::Console(QWidget *parent) : QPlainTextEdit(parent) { document()->setMaximumBlockCount(100); QPalette p = palette(); p.setColor(QPalette::Base, Qt::black); //geht nicht weil untergrund schon farbig p.setColor(QPalette::Text, Qt::blue); setPalette(p); } void Console::putData(const QByteArray &data) { insertPlainText(data); insertPlainText("\n"); QScrollBar *bar = verticalScrollBar(); bar->setValue(bar->maximum()); } void Console::putText(QString text) { insertPlainText(text); insertPlainText("\n"); QScrollBar *bar = verticalScrollBar(); bar->setValue(bar->maximum()); } void T_winComPort::subPortInfo() { // Port Info Anzeige Feld, 2. Zeile links QStringList myStringList; QStringList comboPortList; const auto infos = QSerialPortInfo::availablePorts(); for (const QSerialPortInfo &info : infos) { myStringList.append(QObject::tr(" \n Port: ") + info.portName() ); myStringList.append(QObject::tr("Location: ") + info.systemLocation()); // + "\n"); myStringList.append(QObject::tr("Description: ") + info.description() ); myStringList.append(QObject::tr("Manufacturer: ") + info.manufacturer()); myStringList.append(QObject::tr("Serial number: ") + info.serialNumber()); myStringList.append (QObject::tr("Vendor Id: ") + QString::number(info.vendorIdentifier(), 16)); myStringList.append(QObject::tr("Product Id: ") +QString::number(info.productIdentifier(), 16)); //myStringList.append(QObject::tr("Busy: ") + (info.isBusy() ? QObject::tr("Yes") : QObject::tr("No"))); comboPortList.append(info.portName()); // wenn Comport im System vorhanden dann in die Liste eintragen } QListWidget *myListWidget = new QListWidget; myListWidget->insertItems(0, myStringList); myListWidget->setMaximumWidth(250); myTabComLayout->addWidget(myListWidget,1,0); // ComboBox Comport Nr: CB_portSel = new QComboBox(); CB_portSel->addItems(comboPortList); // string Liste mit addItems (s am Schluss) ! CB_portSel->setMinimumHeight(30); CB_portSel->setMaximumWidth(150); QFont myCBfont; //myCBfont.setBold(true); myCBfont.setPixelSize(15); CB_portSel->setFont(myCBfont); CB_portSel->setCurrentIndex(2); // default 3. Comport in der Liste = ttymxc2 in PTU5 myTabComLayout->addWidget(CB_portSel, 4,0); } void T_winComPort::callOpenSerial() { // Taste Connect wurde gedrückt, eine Klasse/einen Slot aus einer übergeordneten Klasse: // openSerialPort(); // kann man nicht aufrufen. deshalb: speichere ComPort, Baudrate und Startbefehl global. // Von dort wird mit einem zyklischen Timer ausgelesen int br, ci; QString bs, cn; //br=CB_baudSel->currentIndex(); //bs=CB_baudSel->currentText(); br=5; bs="115200"; cn=CB_portSel->currentText(); ci=CB_portSel->currentIndex(); // aktuell: br=5 bs=115200 cn=0 (=Com5) //epi_setSerial(5,"115200","COM5",1); // epi_setSerial(br, bs, cn, 1); // new: save values for next time QByteArray myBA, tmpBA; myBA.clear(); tmpBA.clear(); myBA.append('s'); // start sign, not used myBA.append(FILESEPERATOR); tmpBA.setNum(br,10); myBA.append(tmpBA); myBA.append(FILESEPERATOR); myBA.append(bs.toLatin1()); myBA.append(FILESEPERATOR); myBA.append(cn.toLatin1()); myBA.append(FILESEPERATOR); tmpBA.clear(); tmpBA.setNum(ci,10); myBA.append(tmpBA); myBA.append(FILESEPERATOR); datei_clearFile(FILENAME_COMPORT); datei_writeToFile(FILENAME_COMPORT, myBA); qDebug() << "winComPort opening serial with: " << br << " " << bs << " " << cn; HWaccess->dc_openSerial(br, bs, cn, 1);// same function with hwapi // void dc_openSerial(int BaudNr, QString BaudStr, QString ComName, uint8_t connect) // BaudNr: 0:1200 1:9600 2:19200 3:38400 4:57600 5:115200 // BaudStr: for exapmle "19200" // ComName: for example "COM48" // connect: 0, 1 emit connectButtonPressed(); } void T_winComPort::callCloseSerial() { HWaccess->dc_closeSerial(); // epi_closeSerial(); // same function without hwapi emit closeButtonPressed(); } void T_winComPort::callAutoSend() { if (AutSendButton->isChecked()) { HWaccess->dc_autoRequest(1); emit autoSendButtonIsOn(); } else { HWaccess->dc_autoRequest(0); emit autoSendButtonIsOff(); } } void T_winComPort::callRefresh(void) { subPortInfo(); } void T_winComPort::callConnectToggle() { if (connectButton->isChecked()) { //qDebug() << "down"; callOpenSerial(); } else { //qDebug() << "released"; callCloseSerial(); } } void T_winComPort::getDcTestRS232() { //qDebug() << "request test response..."; HWaccess->dc_requTestResponse(); } void T_winComPort::newBaud(void) { qDebug() << "new baud selected..."; } void T_winComPort::setButtons4autoStart() { connectButton->setEnabled(true); connectButton->setDown(true); connectButton->setChecked(true); AutSendButton->setEnabled(true); AutSendButton->setDown(true); AutSendButton->setChecked(true); } T_winComPort::T_winComPort(hwinf *HWaccess, QWidget *parent) : QWidget(parent) { this->HWaccess = HWaccess; myTabComLayout = new QGridLayout; //QGridLayout *myGridLayout = new QGridLayout(); // Überschrift linke Spalte QLabel *portListLabel2 = new QLabel(tr("in System available Ports:")); myTabComLayout->addWidget(portListLabel2, 0,0); // Überschrift rechte Spalte QLabel *lab_headlineR = new QLabel(tr("Serial traffic:")); myTabComLayout->addWidget(lab_headlineR, 0, 1); subPortInfo(); // sende-empfangs-Rohdaten-Fenster, 2. Zeile rechts myDiagWindow = new Console(); myDiagWindow->setReadOnly(true); myDiagWindow->setEnabled(true); //myDiagWindow->setLocalEchoEnabled(p.localEchoEnabled); //myDiagWindow->setMinimumWidth(300); //myDiagWindow->putData("ongoing serial traffic: "); myTabComLayout->addWidget(myDiagWindow, 1,1); // links: // refresh button: refreshButton = new QPushButton(tr("&refresh")); refreshButton->setCheckable(false); // true = toggle button refreshButton->setAutoDefault(false); // beim start aus //refreshButton->setMaximumWidth(90); myTabComLayout->addWidget(refreshButton, 2,0); //connect(refreshButton, &QAbstractButton::clicked, this, &T_fenster01::callRefresh); connect(refreshButton, SIGNAL(clicked()), this, SLOT(callRefresh())); QLabel *Label3 = new QLabel(tr("Port:")); myTabComLayout->addWidget(Label3, 3,0); QLabel *Label4 = new QLabel(tr("Baud:")); myTabComLayout->addWidget(Label4, 5,0); // ComboBox Baudrate: QFont my2CBfont; //my2CBfont.setBold(true); my2CBfont.setPixelSize(15); /* CB_baudSel = new QComboBox(); CB_baudSel->addItem(tr("1200")); CB_baudSel->addItem(tr("9600")); CB_baudSel->addItem(tr("19200")); CB_baudSel->addItem(tr("38400")); CB_baudSel->addItem(tr("57600")); CB_baudSel->addItem(tr("115200")); CB_baudSel->setMinimumHeight(30); CB_baudSel->setMaximumWidth(150); CB_baudSel->setFont(my2CBfont); CB_baudSel->setCurrentIndex(5); // default 115k baud //CB_baudSel->setCurrentIndex(1); // default 9600 baud myTabComLayout->addWidget(CB_baudSel, 6,0); //connect(CB_baudSel, SIGNAL(currentIndexChanged(int)), this, SLOT(newBaud())); connect(CB_baudSel, SIGNAL(currentIndexChanged(int)), this, SLOT(newBaud())); */ // Statuszeile COM Port (serial Port) LabelComState = new QLabel(tr("not connected")); myTabComLayout->addWidget(LabelComState, 7,0); // Connect button: connectButton = new QPushButton(tr("&Connect")); connectButton->setCheckable(true); // true = toggle button connectButton->setAutoDefault(true); // beim start ein connectButton->setMaximumWidth(90); connectButton->setMinimumHeight(50); myTabComLayout->addWidget(connectButton, 8,0); //connect(connectButton, &QAbstractButton::clicked, this, &T_fenster01::callConnectToggle); connect(connectButton, SIGNAL(clicked()), this, SLOT(callConnectToggle())); // rechts: // test serial line: TestButton = new QPushButton(tr("test Connection")); TestButton->setMaximumWidth(150); myTabComLayout->addWidget(TestButton,2,1); TestButton->setCheckable(false); // true = toggle button TestButton->setAutoDefault(false); // beim start aus // connect(TestButton, &QAbstractButton::clicked, this, &T_fenster01::getDcTestRS232); connect(TestButton, SIGNAL(clicked()), this, SLOT(getDcTestRS232())); // I Statuszeile Handshakes (serial Control) flow.cpp // geht überhaupt was raus? kommt überhaupt was zurück? //LabelHandshakes = new QLabel(tr("control line")); LabelHandshakes = new QLabel("HS"); // not used myTabComLayout->addWidget(LabelHandshakes, 3,1); // II Statuszeile Auswertung der SlaveResponse (serial Frame, CRC usw) (prot.cpp) LabelRecieveFrame = new QLabel(tr("slave receive")); myTabComLayout->addWidget(LabelRecieveFrame, 4,1); // III Anzeige der Slave-Results (Datif) LabelResults = new QLabel(tr("results line")); myTabComLayout->addWidget(LabelResults, 5,1); // IV Statuszeile Sende- und Empfangsdaten brauchbar? (Datif) LabelDataState = new QLabel(tr("datif line")); myTabComLayout->addWidget(LabelDataState, 6,1); // V LabelDatif = new QLabel(tr("datif line")); myTabComLayout->addWidget(LabelDatif, 7,1); // Autosend: AutSendButton = new QPushButton(tr("&Automatic reading")); // &A --> also keycode Alt-A possible //AutSendButton->setMaximumWidth(90); myTabComLayout->addWidget(AutSendButton,8,1); AutSendButton->setCheckable(true); // true = toggle button AutSendButton->setAutoDefault(true); // beim start aus AutSendButton->setMinimumHeight(50); // connect(AutSendButton, &QAbstractButton::clicked, this, &T_fenster01::callAutoSend); connect(AutSendButton, SIGNAL(clicked()), this, SLOT(callAutoSend())); setLayout(myTabComLayout); myNextStep=0; myStep=0; callConnectToggle(); callAutoSend(); myTO = new QTimer(); myTO->setSingleShot(true); myTO->start(2000); } // not needed: T_winComPort::~T_winComPort() { close(); } void T_winComPort::Nav_back(void) { myNextStep=WCS_WIN01BAK; } void T_winComPort::Nav_home(void) { myNextStep=WCS_WIN01MID; } void T_winComPort::Nav_next(void) { myNextStep=WCS_WIN01FWD; } bool T_winComPort::work_ini(uint16_t *nextScreen, uint8_t *useNavi) { // one state of the vending/operating FSM // called ONE time after selecting this state (initialization) // useNavi=0: no change // bit0,1: enable/disable button "next" // bit2,3: enable/disable button "home" // bit4,5: enable/disable button "back" *nextScreen=0; // needed 0=no change // *useNavi=SWITCH_BACK_OFF | SWITCH_HOME_OFF | SWITCH_NEXT_ON; *useNavi=SWITCH_BACK_OFF | SWITCH_HOME_OFF | SWITCH_NEXT_OFF; // bei CArun alle aus return false; } bool T_winComPort::working(uint16_t *nextScreen, uint8_t *useNavi) { // one state of the vending/operating FSM // called cyclic until this state changes intentionally to another state // display informations for human operator, react on operators inputs or wait for payment media // useNavi=0: no change // bit0,1: enable/disable button "next" // bit2,3: enable/disable button "home" // bit4,5: enable/disable button "back" QString bs, cn; int br, ci; this->updateGui(); *nextScreen=0; // 0=no change *useNavi=0; if (myStep==0) { // load and use last settings: -------------------- QByteArray myBA; myBA=datei_readFromFile(FILENAME_COMPORT); if (myBA.length()>0) { bs=csv_getEntryAsString(myBA,0); // read the 's' war 2!?? br=csv_getEntryAsInt(myBA,1); // z.B. 5 (5.Eintrag in der Baud-Liste) bs=csv_getEntryAsString(myBA,2); // z.B 115200 cn=csv_getEntryAsString(myBA,3); // z.B. COM9 ci=csv_getEntryAsInt(myBA,4); // Eintragsnummer in COM-Fenster HWaccess->dc_openSerial(br,bs,cn,1); CB_portSel->setCurrentIndex(ci); // den Port aus der Datei hier vorgeben connectButton->setChecked(true); // connect Taste "druecken" } else { // open with default settings qDebug()<<"CArunGui: open serial with default values"; bs="115200"; br=5; //cn="COM14"; // Windows cn="ttymxc2"; // PTU5 ci=2; HWaccess->dc_openSerial(br,bs,cn,1); } myTO->start(100); // restart myStep++; } else if (myStep==1) { if (!myTO->isActive()) { if (HWaccess->dc_isPortOpen()) { myStep++; } else { myStep=6; // 13.12.23: start Autoconnect cycle qDebug()<<"CArunGui: port is still closed, restarting.."; } myTO->start(100); } } else if (myStep==2) { if (!myTO->isActive()) { HWaccess->dc_requTestResponse(); myStep++; myTO->start(100); } } else if (myStep==3) { if (!myTO->isActive()) { if (HWaccess->dc_readAnswTestResponse()) myStep++; // response was correct else { myStep=6; // 13.12.23: start Autoconnect cycle qDebug()<<"CArunGui: got no answer from DC, retry.."; } myTO->start(100); } } else if (myStep==4) { HWaccess->dc_autoRequest(1); AutSendButton->setChecked(true); // taste "druecken" myStep++; myTO->start(2000); } else if (myStep==5) { if (!myTO->isActive()) { if (HWaccess->sys_areDCdataValid()) { qDebug()<<"CArunGui: DC is connected"; myStep=7; // OK, connection is up and running } else { qDebug()<<"CArunGui: auto request is not running, retry..."; myStep++; myTO->start(100); } } } else if (myStep==6) { // restart autoconnect cycle myTO->start(100); // restart myStep=0; } else if (myStep==7) { // stay here, DC connection is up and running } else { } if (myNextStep) { *nextScreen=myNextStep; myNextStep=0; } return false; } void T_winComPort::updateGui(void) { QByteArray myBA; QString ms; ms=HWaccess->dc_getTxt4RsDiagWin(); if (ms.length()>1) // sonst ständig scrolling { myDiagWindow->putText(ms); HWaccess->dc_clrTxt4RsDiagWin(); } ms=HWaccess->dc_get2ndTxt4RsDiagWin(); if (ms.length()>1) // sonst ständig scrolling { myDiagWindow->putText(ms); HWaccess->dc_clr2ndTxt4RsDiagWin(); } // state of the COM Port (open, closed) ms=HWaccess->dc_getSerialState(); if (ms.length()>1) // sonst ständig scrolling { LabelComState->setText(ms); } // -------------------------------------------------------------------------- // I Statuszeile Handshakes (serial Control) ms=HWaccess->dc_getTxt4HsStateLine(); if (!connectButton->isChecked()) ms=""; if (ms.length()>1) // sonst ständig scrolling { LabelHandshakes->setText(ms); HWaccess->dc_clrTxt4HsStateLine(); // clear to avoid multiple displaying } // II Master receive state (empfangenes Telgramm OK? crc? length? ) // Statuszeile Auswertung der SlaveResponse (serial Frame, CRC usw) (prot.cpp) ms=HWaccess->dc_getTxt4masterStateLine(); if (!connectButton->isChecked()) ms="---"; if (ms.length()>1) // sonst ständig scrolling { LabelRecieveFrame->setText(ms); HWaccess->dc_clrTxt4masterStateLine(); } // III Slave receive (from Master) OK? if then show results, if not then show errors // entweder Empfangsfehler anzeigen (crc? length?) oder result OUT-OK, OUT_ERR, IN_OK, IN_ERR // Hintergrund: wenn der Slave Fehler im Master-Telegramm gefunden hat, dann kann er es auch // nicht verwenden und nichts ausgeben oder einlesen ms=HWaccess->dc_getTxt4resultStateLine(); if (!connectButton->isChecked()) ms="---"; if (ms.length()>1) // sonst ständig scrolling { LabelResults->setText(ms); HWaccess->dc_clrTxt4resultStateLine(); } // IV Statuszeile Empfangsdaten ms=HWaccess->dc_getdataStateLine(); if (!connectButton->isChecked()) ms="---"; if (ms.length()>1) // sonst ständig scrolling { LabelDataState->setText(ms); HWaccess->dc_clrTxt4dataStateLine(); // clear to avoid multiple displaying } // 5. Zeile: Datif Ergebnis, Daten brauchbar? ms=HWaccess->dc_getdatifLine(); if (!connectButton->isChecked()) ms="---"; if (ms.length()>1) // sonst ständig scrolling { LabelDatif->setText(ms); HWaccess->dc_clrTxt4datifLine(); } // ----------------------------------------------------------------------------- }