#include "mainwindow.h" #include "ui_mainwindow.h" #include #include #include #define SEARCH_STR_STIMULUS "StimulusCode " MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); PCIP_1 = 0; PCIP_2 = 0; PCIP_3 = 0; PCIP_4 = 0; FeatherIP_1 = 0; FeatherIP_2 = 0; FeatherIP_3 = 0; FeatherIP_4 = 0; //default PCIP_full = QHostAddress("127.0.0.1"); PCPort = 5001; FeatherIP_full = QHostAddress("192.168.4.1"); FeatherPort = 8888; udpSocket_PC = new QUdpSocket(this); udpSocket_Feather = new QUdpSocket(this); //no binding to socket needed. Just send data! stylesheet_tac_marked = "QLabel {background-color: rgb(0,170,0);}"; stylesheet_tac_unmarked = "QLabel {background-color: white;}"; logBCIData = true; tac1ON = false; tac2ON = false; tac3ON = false; tac4ON = false; tac5ON = false; tac6ON = false; lastBufferStr = "0"; setupSignalsAndSlots(); } MainWindow::~MainWindow() { delete ui; } void MainWindow::setupSignalsAndSlots() { connect(ui->push_Apply, SIGNAL(clicked()), this, SLOT(applyButton())); connect(udpSocket_PC, SIGNAL(readyRead()), this, SLOT(readPCSocketData())); connect(ui->check_LogBCI, SIGNAL(toggled(bool)), this, SLOT(setLogBCIData(bool))); connect(ui->push_ClearLog, SIGNAL(clicked()), this, SLOT(clearLog())); connect(ui->push_Tac1, SIGNAL(clicked(bool)), this, SLOT(pushTac1(bool))); connect(ui->push_Tac2, SIGNAL(clicked(bool)), this, SLOT(pushTac2(bool))); connect(ui->push_Tac3, SIGNAL(clicked(bool)), this, SLOT(pushTac3(bool))); connect(ui->push_Tac4, SIGNAL(clicked(bool)), this, SLOT(pushTac4(bool))); connect(ui->push_Tac5, SIGNAL(clicked(bool)), this, SLOT(pushTac5(bool))); connect(ui->push_Tac6, SIGNAL(clicked(bool)), this, SLOT(pushTac6(bool))); connect(ui->push_allLOW, SIGNAL(clicked()), this, SLOT(allLOW())); connect(ui->push_allHIGH, SIGNAL(clicked()), this, SLOT(allHIGH())); } void MainWindow::log(QString logtext) { QString output = "[" + getCurrentTime() + "] " + logtext; ui->plain_Log->appendPlainText(output); } QString MainWindow::getCurrentTime() { QString currenttime = QTime::currentTime().toString("HH:mm:ss"); return currenttime; } void MainWindow::applyButton() { if(ui->check_ClearLog->isChecked()) { ui->plain_Log->clear(); } bindPC(); setupFeather(); } void MainWindow::bindPC() { if(udpSocket_PC->state() == QAbstractSocket::BoundState) { udpSocket_PC->abort(); } QString tmp_PCIP_full = buildPCIP(); if(tmp_PCIP_full == "0") { log("Please try another IP address"); } else { PCIP_full = QHostAddress(tmp_PCIP_full); PCPort = ui->line_PCPort->text().toUShort(nullptr,10); if(checkPort(PCPort)) { log("Receive socket BCI-Stream set to:"); log("-- PC-IP: " + PCIP_full.toString()); log("-- PC-Port: " + QString::number(PCPort)); if(udpSocket_PC->bind(PCIP_full, PCPort)) { log("UDP PC socket: successfully bound."); } else { log("!! UDP PC socket: binding error !!"); } } else { PCPort = 00000; ui->line_PCPort->setText("00000"); log("!! PC Port not valid !!"); QMessageBox::critical(this, "PC Port not valid", "PC Port is not valid. Please make sure that the port is a number between 0 and 65535."); } } } void MainWindow::setupFeather() { QString tmp_FeatherIP_full = buildFeatherIP(); if(tmp_FeatherIP_full == "0") { log("Please try another IP address"); } else { FeatherIP_full = QHostAddress(tmp_FeatherIP_full); FeatherPort = ui->line_FeatherPort->text().toUShort(nullptr,10); if(checkPort(FeatherPort)) { log("Receive socket Adafruit Feather set to:"); log("-- Feather-IP: " + FeatherIP_full.toString()); log("-- Feather-Port: " + QString::number(FeatherPort)); } else { FeatherPort = 00000; ui->line_FeatherPort->setText("00000"); log("!! Port not valid !!"); QMessageBox::critical(this, "Feather Port not valid", "Feather Port is not valid. Please make sure that the port is a number between 0 and 65535."); } } } bool MainWindow::checkPort(const quint16 port) { bool valid = false; if(port) { valid = true; } return valid; } QString MainWindow::buildPCIP() { int PCIP1 = ui->line_PCIP1->text().toInt(); int PCIP2 = ui->line_PCIP2->text().toInt(); int PCIP3 = ui->line_PCIP3->text().toInt(); int PCIP4 = ui->line_PCIP4->text().toInt(); if( ((PCIP1 < 0) || (PCIP1 > 255)) || ((PCIP2 < 0) || (PCIP2 > 255)) || ((PCIP3 < 0) || (PCIP3 > 255)) || ((PCIP4 < 0) || (PCIP4 > 255)) ) { QMessageBox::critical(this, "PC IP address not valid", "PC IP address is not valid. Please make sure that the IP components only consist of numbers between 0 and 255."); log("!! Error while setting PC IP !!"); return "0"; } else { QString IP = QString::number(PCIP1) + "." + QString::number(PCIP2) + "." + QString::number(PCIP3) + "." + QString::number(PCIP4); return IP; } } QString MainWindow::buildFeatherIP() { int FeatherIP1 = ui->line_FeatherIP1->text().toInt(); int FeatherIP2 = ui->line_FeatherIP2->text().toInt(); int FeatherIP3 = ui->line_FeatherIP3->text().toInt(); int FeatherIP4 = ui->line_FeatherIP4->text().toInt(); if( ((FeatherIP1 < 0) || (FeatherIP1 > 255)) || ((FeatherIP2 < 0) || (FeatherIP2 > 255)) || ((FeatherIP3 < 0) || (FeatherIP3 > 255)) || ((FeatherIP4 < 0) || (FeatherIP4 > 255)) ) { QMessageBox::critical(this, "Feather IP address not valid", "Feather IP address is not valid. Please make sure that the IP components only consist of numbers between 0 and 255."); log("!! Error while setting Feather IP !!"); return "0"; } else { QString IP = QString::number(FeatherIP1) + "." + QString::number(FeatherIP2) + "." + QString::number(FeatherIP3) + "." + QString::number(FeatherIP4); return IP; } } void MainWindow::readPCSocketData() { QString bufferStr; while (udpSocket_PC->hasPendingDatagrams()) { QByteArray buffer; buffer.resize(static_cast(udpSocket_PC->pendingDatagramSize())); udpSocket_PC->readDatagram(buffer.data(), buffer.size()); bufferStr = QString::fromStdString(buffer.toStdString()); if(bufferStr.contains(SEARCH_STR_STIMULUS,Qt::CaseSensitive)) { bufferStr.replace(SEARCH_STR_STIMULUS, ""); if(!bufferStr.contains("0")) { ui->lineLastSymbol->setText(bufferStr); } if(logBCIData) { log(bufferStr); } if(ui->check_Tactile->isChecked()) { markDirectionTactile(bufferStr); } if(bufferStr != lastBufferStr){ QByteArray data = bufferStr.toUtf8(); udpSocket_Feather->writeDatagram(data, FeatherIP_full, FeatherPort); lastBufferStr = bufferStr; } } } } void MainWindow::markDirectionTactile(const QString direction) { unsigned int i_direction = direction.toUInt(nullptr,10); //qDebug() << i_direction; switch (i_direction) { case 0: //nothing ui->label_Tac1->setStyleSheet(stylesheet_tac_unmarked); ui->label_Tac2->setStyleSheet(stylesheet_tac_unmarked); ui->label_Tac3->setStyleSheet(stylesheet_tac_unmarked); ui->label_Tac4->setStyleSheet(stylesheet_tac_unmarked); ui->label_Tac5->setStyleSheet(stylesheet_tac_unmarked); ui->label_Tac6->setStyleSheet(stylesheet_tac_unmarked); break; case 1: //Tac1 ui->label_Tac1->setStyleSheet(stylesheet_tac_marked); ui->label_Tac2->setStyleSheet(stylesheet_tac_unmarked); ui->label_Tac3->setStyleSheet(stylesheet_tac_unmarked); ui->label_Tac4->setStyleSheet(stylesheet_tac_unmarked); ui->label_Tac5->setStyleSheet(stylesheet_tac_unmarked); ui->label_Tac6->setStyleSheet(stylesheet_tac_unmarked); break; case 2: //Tac2 ui->label_Tac1->setStyleSheet(stylesheet_tac_unmarked); ui->label_Tac2->setStyleSheet(stylesheet_tac_marked); ui->label_Tac3->setStyleSheet(stylesheet_tac_unmarked); ui->label_Tac4->setStyleSheet(stylesheet_tac_unmarked); ui->label_Tac5->setStyleSheet(stylesheet_tac_unmarked); ui->label_Tac6->setStyleSheet(stylesheet_tac_unmarked); break; case 3: //Tac3 ui->label_Tac1->setStyleSheet(stylesheet_tac_unmarked); ui->label_Tac2->setStyleSheet(stylesheet_tac_unmarked); ui->label_Tac3->setStyleSheet(stylesheet_tac_marked); ui->label_Tac4->setStyleSheet(stylesheet_tac_unmarked); ui->label_Tac5->setStyleSheet(stylesheet_tac_unmarked); ui->label_Tac6->setStyleSheet(stylesheet_tac_unmarked); break; case 4: //Tac4 ui->label_Tac1->setStyleSheet(stylesheet_tac_unmarked); ui->label_Tac2->setStyleSheet(stylesheet_tac_unmarked); ui->label_Tac3->setStyleSheet(stylesheet_tac_unmarked); ui->label_Tac4->setStyleSheet(stylesheet_tac_marked); ui->label_Tac5->setStyleSheet(stylesheet_tac_unmarked); ui->label_Tac6->setStyleSheet(stylesheet_tac_unmarked); break; case 5: //Tac5 ui->label_Tac1->setStyleSheet(stylesheet_tac_unmarked); ui->label_Tac2->setStyleSheet(stylesheet_tac_unmarked); ui->label_Tac3->setStyleSheet(stylesheet_tac_unmarked); ui->label_Tac4->setStyleSheet(stylesheet_tac_unmarked); ui->label_Tac5->setStyleSheet(stylesheet_tac_marked); ui->label_Tac6->setStyleSheet(stylesheet_tac_unmarked); break; case 6: //Tac6 ui->label_Tac1->setStyleSheet(stylesheet_tac_unmarked); ui->label_Tac2->setStyleSheet(stylesheet_tac_unmarked); ui->label_Tac3->setStyleSheet(stylesheet_tac_unmarked); ui->label_Tac4->setStyleSheet(stylesheet_tac_unmarked); ui->label_Tac5->setStyleSheet(stylesheet_tac_unmarked); ui->label_Tac6->setStyleSheet(stylesheet_tac_marked); break; } } void MainWindow::setLogBCIData(const bool log) { logBCIData = log; } void MainWindow::clearLog() { ui->plain_Log->clear(); } void MainWindow::pushTac1(const bool state) { tac1ON = state; pushDirection(); } void MainWindow::pushTac2(const bool state) { tac2ON = state; pushDirection(); } void MainWindow::pushTac3(const bool state) { tac3ON = state; pushDirection(); } void MainWindow::pushTac4(const bool state) { tac4ON = state; pushDirection(); } void MainWindow::pushTac5(const bool state) { tac5ON = state; pushDirection(); } void MainWindow::pushTac6(const bool state) { tac6ON = state; pushDirection(); } void MainWindow::pushDirection() { //first switch off all udpSocket_Feather->writeDatagram(QByteArray::number(0), FeatherIP_full, FeatherPort); if(tac1ON) udpSocket_Feather->writeDatagram(QByteArray::number(1), FeatherIP_full, FeatherPort); if(tac2ON) udpSocket_Feather->writeDatagram(QByteArray::number(2), FeatherIP_full, FeatherPort); if(tac3ON) udpSocket_Feather->writeDatagram(QByteArray::number(3), FeatherIP_full, FeatherPort); if(tac4ON) udpSocket_Feather->writeDatagram(QByteArray::number(4), FeatherIP_full, FeatherPort); if(tac5ON) udpSocket_Feather->writeDatagram(QByteArray::number(5), FeatherIP_full, FeatherPort); if(tac6ON) udpSocket_Feather->writeDatagram(QByteArray::number(6), FeatherIP_full, FeatherPort); } void MainWindow::allLOW() { udpSocket_Feather->writeDatagram(QByteArray::number(0), FeatherIP_full, FeatherPort); ui->push_Tac1->setChecked(false); ui->push_Tac2->setChecked(false); ui->push_Tac3->setChecked(false); ui->push_Tac4->setChecked(false); ui->push_Tac5->setChecked(false); ui->push_Tac6->setChecked(false); } void MainWindow::allHIGH() { udpSocket_Feather->writeDatagram(QByteArray::number(1), FeatherIP_full, FeatherPort); udpSocket_Feather->writeDatagram(QByteArray::number(2), FeatherIP_full, FeatherPort); udpSocket_Feather->writeDatagram(QByteArray::number(3), FeatherIP_full, FeatherPort); udpSocket_Feather->writeDatagram(QByteArray::number(4), FeatherIP_full, FeatherPort); udpSocket_Feather->writeDatagram(QByteArray::number(5), FeatherIP_full, FeatherPort); udpSocket_Feather->writeDatagram(QByteArray::number(6), FeatherIP_full, FeatherPort); ui->push_Tac1->setChecked(true); ui->push_Tac2->setChecked(true); ui->push_Tac3->setChecked(true); ui->push_Tac4->setChecked(true); ui->push_Tac5->setChecked(true); ui->push_Tac6->setChecked(true); }