Как организовать работу N com-портов одновременно?
Здравствуйте! Работаю с com-port, и хочу сделать отправку и прием для нескольких портов.
В случае работы с одним портом предельно понятно, на каком-то уровне. Работаю с ним так:
#include "mainwindow.h" #include "ui_mainwindow.h" //---------------------------------------------------------------------------------------------------------------------------------------------------- MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), m_ui(new Ui::MainWindow), m_timerWaitAnswer(new QTimer) { m_ui->setupUi(this); //Получение списка портов и запись их в выпадающий список foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) m_ui->serialPortComboBox->addItem(info.portName()); // Отправка в сом-порт по нажатию на кнопку connect(m_ui->sendComPortPushButton, SIGNAL(clicked(bool)), this, SLOT(writeComPort())); // Подключаем чтение с порта по таймеру connect(m_timerWaitAnswer, SIGNAL(timeout()), this, SLOT(readComPort())); connect(m_ui->serialPortComboBox, SIGNAL(activated(QString)), this, SLOT(reopenComPort(QString))); m_comPort = new QSerialPort; } //---------------------------------------------------------------------------------------------------------------------------------------------------- MainWindow::~MainWindow() { if(m_comPort->isOpen()) m_comPort->close(); delete m_ui; } //---------------------------------------------------------------------------------------------------------------------------------------------------- void MainWindow::openComPort(QString comName, QSerialPort::BaudRate baud, QSerialPort::DataBits dataBits, QSerialPort::Parity parity, QSerialPort::StopBits stopBits, QSerialPort::FlowControl flowControl) { m_comPort->setPortName(comName); // Настройка параметров com-порта m_comPort->setBaudRate(baud); m_comPort->setDataBits(dataBits); m_comPort->setParity(parity); m_comPort->setStopBits(stopBits); m_comPort->setFlowControl(flowControl); // Открываем com-порт. В случае неудачи, выводим ошибку в лог if (!m_comPort->open(QIODevice::ReadWrite)) qDebug() << "failed"; else qDebug() << "connected"; } //---------------------------------------------------------------------------------------------------------------------------------------------------- void MainWindow::readComPort() { m_waitAnswer = false; QString data; // Чтение данных и вывод m_bufferRead.append(m_comPort->readAll()); qDebug() << m_comPort->readAll(); m_ui->textEdit->setText(m_bufferRead.data()); m_bufferRead.clear(); m_timerWaitAnswer->stop(); } //---------------------------------------------------------------------------------------------------------------------------------------------------- void MainWindow::writeComPort() { QByteArray toSend; QString value = m_ui->sendComPortLineEdit->text(); if(value.isEmpty()) return; toSend.append(value); // Отправка в сом-порт m_comPort->write(toSend); m_ui->textEdit->setText(toSend); // Запуск таймера ожидания ответа m_timerWaitAnswer->start(m_ui->timeSpinBox->text().toInt()); m_waitAnswer = true; } //---------------------------------------------------------------------------------------------------------------------------------------------------- void MainWindow::reopenComPort(QString namePort) { m_comPort->close(); // Открываем новый com-порт openComPort(namePort, QSerialPort::Baud9600, QSerialPort::Data8, QSerialPort::EvenParity, QSerialPort::OneStop, QSerialPort::NoFlowControl); } Заголовочный файл: <code lang="cpp"> #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QSerialPort> #include <QSerialPortInfo> #include <QTimer> #include <QDebug> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: // Конструктор explicit MainWindow(QWidget *parent = 0); // Деструктор ~MainWindow(); public slots: // Читает из com-порта void readComPort(); // Записывает данные в com-порт void writeComPort(); // Переоткрывает com-порт void reopenComPort(QString namePort); private: // Форма окна Ui::MainWindow *m_ui; // Флаг ожидания ответа bool m_waitAnswer; // Открываемый com-порт QSerialPort *m_comPort; // Приемный буфер QByteArray m_bufferRead; // Таймер QTimer *m_timerWaitAnswer; // Открывает com-порт void openComPort(QString comName, QSerialPort::BaudRate baud, QSerialPort::DataBits dataBits, QSerialPort::Parity parity, QSerialPort::StopBits stopBits, QSerialPort::FlowControl flowControl); }; #endif // MAINWINDOW_H </code> Так выглядит взаимодействие с одним портом: <img src="https://habrastorage.org/webt/65/eb/f8/65ebf8a872479371143502.jpeg" alt="image"/> В случае, когда работаем не с одним, а с двумя и более портами, как нужно организовать работу, чтобы все работало корректно? Вопрос как в подходе, так как есть свои идеи, так и в некой реализации. Создавать несколько экземпляров com-портов - не гибко, если вдруг их количество увеличится.. Информация в интернетах, разумеется, есть, но не помогает прийти к какому-то решению для меня. Пробовал решить проблему следующим образом (пока без чтения и прочего): <code lang="cpp"> #include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); QList<QSerialPortInfo> ports = QSerialPortInfo::availablePorts(); connect(ui->sendButton, SIGNAL(clicked()), this, SLOT(sendToAllPorts())); connectToAllPorts(); connect(this, SIGNAL(messageSentSuccessfully(QString)), this, SLOT(msgSentSuccessfully(QString))); } //------------------------------------------------------------------------------ MainWindow::~MainWindow() { delete ui; } //------------------------------------------------------------------------------ void MainWindow::msgSentSuccessfully(QString message) { qDebug() << "Сообщение успешно отправлено: " << message; } //------------------------------------------------------------------------------ void MainWindow::msgFailedToSend(QString message) { qDebug() << "Сообщение не удалось отправить: " << message; } //------------------------------------------------------------------------------ void MainWindow::sendMessage(QString message) { // Отправка сообщения на все порты qDebug() << "Отправка сообщения: " << message; // Проверка успешной отправки сообщения bool messageSent = true; // Предположим, что сообщение успешно отправлено if (messageSent) { emit messageSentSuccessfully(message); } else { emit messageFailedToSend(message); } } //------------------------------------------------------------------------------ void MainWindow::sendToAllPorts() { QList<QSerialPortInfo> ports = QSerialPortInfo::availablePorts(); message = "Hello, World!"; foreach (const QSerialPortInfo &portInfo, ports) { QSerialPort port; port.setPort(portInfo); if (port.open(QIODevice::WriteOnly)) { qDebug() << "Sending message" << message << "to port" << portInfo.portName(); qint64 bytesWritten = port.write(message); if (bytesWritten == -1) { qDebug() << "Failed to write to port" << portInfo.portName(); } else { qDebug() << "Message sent to port" << portInfo.portName(); } port.close(); } else { qDebug() << "Failed to open port" << portInfo.portName(); } } } //------------------------------------------------------------------------------ void MainWindow::connectToAllPorts() { QVector<QSerialPort*> ports; //availablePorts; foreach (const QSerialPortInfo &portInfo, QSerialPortInfo::availablePorts()) { QSerialPort *port = new QSerialPort(portInfo); // Настройка параметров com-порта m_comPort->setBaudRate(QSerialPort::Baud9600); m_comPort->setDataBits(QSerialPort::Data8); m_comPort->setParity(QSerialPort::EvenParity); m_comPort->setStopBits(QSerialPort::OneStop); m_comPort->setFlowControl(QSerialPort::NoFlowControl); if (port->open(QIODevice::ReadWrite)) { ports.append(port); qDebug() << "Port " << portInfo.portName() << " opened successfully"; } else { qDebug() << "Failed to open port " << portInfo.portName(); } } qDebug() << ports; } </code> Заголовочный файл: <code lang="cpp"> #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QSerialPortInfo> #include <QSerialPort> #include <QDebug> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); public slots: void sendMessage(QString message); void msgSentSuccessfully(QString message); void msgFailedToSend(QString message); void ReadData(); signals: void messageSentSuccessfully(const QString &message); void messageFailedToSend(const QString &message); private slots: void sendToAllPorts(); private: Ui::MainWindow *ui; QList<QSerialPortInfo> ports; QByteArray message; QSerialPort *m_comPort; void connectToAllPorts(); }; #endif // MAINWINDOW_H </code> При включении считываются доступные порты, записываются в QVector, через qDebug отображаю их и делаю автоматическое, на данный момент, подключение ко всем портам. Как впоследствии обращаться к ним для работы для отправки и приема? |
#include "mainwindow.h" #include "ui_mainwindow.h" //---------------------------------------------------------------------------------------------------------------------------------------------------- MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), m_ui(new Ui::MainWindow), m_timerWaitAnswer(new QTimer) { m_ui->setupUi(this); //Получение списка портов и запись их в выпадающий список foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) m_ui->serialPortComboBox->addItem(info.portName()); // Отправка в сом-порт по нажатию на кнопку connect(m_ui->sendComPortPushButton, SIGNAL(clicked(bool)), this, SLOT(writeComPort())); // Подключаем чтение с порта по таймеру connect(m_timerWaitAnswer, SIGNAL(timeout()), this, SLOT(readComPort())); connect(m_ui->serialPortComboBox, SIGNAL(activated(QString)), this, SLOT(reopenComPort(QString))); m_comPort = new QSerialPort; } //---------------------------------------------------------------------------------------------------------------------------------------------------- MainWindow::~MainWindow() { if(m_comPort->isOpen()) m_comPort->close(); delete m_ui; } //---------------------------------------------------------------------------------------------------------------------------------------------------- void MainWindow::openComPort(QString comName, QSerialPort::BaudRate baud, QSerialPort::DataBits dataBits, QSerialPort::Parity parity, QSerialPort::StopBits stopBits, QSerialPort::FlowControl flowControl) { m_comPort->setPortName(comName); // Настройка параметров com-порта m_comPort->setBaudRate(baud); m_comPort->setDataBits(dataBits); m_comPort->setParity(parity); m_comPort->setStopBits(stopBits); m_comPort->setFlowControl(flowControl); // Открываем com-порт. В случае неудачи, выводим ошибку в лог if (!m_comPort->open(QIODevice::ReadWrite)) qDebug() << "failed"; else qDebug() << "connected"; } //---------------------------------------------------------------------------------------------------------------------------------------------------- void MainWindow::readComPort() { m_waitAnswer = false; QString data; // Чтение данных и вывод m_bufferRead.append(m_comPort->readAll()); qDebug() << m_comPort->readAll(); m_ui->textEdit->setText(m_bufferRead.data()); m_bufferRead.clear(); m_timerWaitAnswer->stop(); } //---------------------------------------------------------------------------------------------------------------------------------------------------- void MainWindow::writeComPort() { QByteArray toSend; QString value = m_ui->sendComPortLineEdit->text(); if(value.isEmpty()) return; toSend.append(value); // Отправка в сом-порт m_comPort->write(toSend); m_ui->textEdit->setText(toSend); // Запуск таймера ожидания ответа m_timerWaitAnswer->start(m_ui->timeSpinBox->text().toInt()); m_waitAnswer = true; } //---------------------------------------------------------------------------------------------------------------------------------------------------- void MainWindow::reopenComPort(QString namePort) { m_comPort->close(); // Открываем новый com-порт openComPort(namePort, QSerialPort::Baud9600, QSerialPort::Data8, QSerialPort::EvenParity, QSerialPort::OneStop, QSerialPort::NoFlowControl); } Заголовочный файл: <code lang="cpp"> #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QSerialPort> #include <QSerialPortInfo> #include <QTimer> #include <QDebug> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: // Конструктор explicit MainWindow(QWidget *parent = 0); // Деструктор ~MainWindow(); public slots: // Читает из com-порта void readComPort(); // Записывает данные в com-порт void writeComPort(); // Переоткрывает com-порт void reopenComPort(QString namePort); private: // Форма окна Ui::MainWindow *m_ui; // Флаг ожидания ответа bool m_waitAnswer; // Открываемый com-порт QSerialPort *m_comPort; // Приемный буфер QByteArray m_bufferRead; // Таймер QTimer *m_timerWaitAnswer; // Открывает com-порт void openComPort(QString comName, QSerialPort::BaudRate baud, QSerialPort::DataBits dataBits, QSerialPort::Parity parity, QSerialPort::StopBits stopBits, QSerialPort::FlowControl flowControl); }; #endif // MAINWINDOW_H </code> Так выглядит взаимодействие с одним портом: <img src="https://habrastorage.org/webt/65/eb/f8/65ebf8a872479371143502.jpeg" alt="image"/> В случае, когда работаем не с одним, а с двумя и более портами, как нужно организовать работу, чтобы все работало корректно? Вопрос как в подходе, так как есть свои идеи, так и в некой реализации. Создавать несколько экземпляров com-портов - не гибко, если вдруг их количество увеличится.. Информация в интернетах, разумеется, есть, но не помогает прийти к какому-то решению для меня. Пробовал решить проблему следующим образом (пока без чтения и прочего): <code lang="cpp"> #include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); QList<QSerialPortInfo> ports = QSerialPortInfo::availablePorts(); connect(ui->sendButton, SIGNAL(clicked()), this, SLOT(sendToAllPorts())); connectToAllPorts(); connect(this, SIGNAL(messageSentSuccessfully(QString)), this, SLOT(msgSentSuccessfully(QString))); } //------------------------------------------------------------------------------ MainWindow::~MainWindow() { delete ui; } //------------------------------------------------------------------------------ void MainWindow::msgSentSuccessfully(QString message) { qDebug() << "Сообщение успешно отправлено: " << message; } //------------------------------------------------------------------------------ void MainWindow::msgFailedToSend(QString message) { qDebug() << "Сообщение не удалось отправить: " << message; } //------------------------------------------------------------------------------ void MainWindow::sendMessage(QString message) { // Отправка сообщения на все порты qDebug() << "Отправка сообщения: " << message; // Проверка успешной отправки сообщения bool messageSent = true; // Предположим, что сообщение успешно отправлено if (messageSent) { emit messageSentSuccessfully(message); } else { emit messageFailedToSend(message); } } //------------------------------------------------------------------------------ void MainWindow::sendToAllPorts() { QList<QSerialPortInfo> ports = QSerialPortInfo::availablePorts(); message = "Hello, World!"; foreach (const QSerialPortInfo &portInfo, ports) { QSerialPort port; port.setPort(portInfo); if (port.open(QIODevice::WriteOnly)) { qDebug() << "Sending message" << message << "to port" << portInfo.portName(); qint64 bytesWritten = port.write(message); if (bytesWritten == -1) { qDebug() << "Failed to write to port" << portInfo.portName(); } else { qDebug() << "Message sent to port" << portInfo.portName(); } port.close(); } else { qDebug() << "Failed to open port" << portInfo.portName(); } } } //------------------------------------------------------------------------------ void MainWindow::connectToAllPorts() { QVector<QSerialPort*> ports; //availablePorts; foreach (const QSerialPortInfo &portInfo, QSerialPortInfo::availablePorts()) { QSerialPort *port = new QSerialPort(portInfo); // Настройка параметров com-порта m_comPort->setBaudRate(QSerialPort::Baud9600); m_comPort->setDataBits(QSerialPort::Data8); m_comPort->setParity(QSerialPort::EvenParity); m_comPort->setStopBits(QSerialPort::OneStop); m_comPort->setFlowControl(QSerialPort::NoFlowControl); if (port->open(QIODevice::ReadWrite)) { ports.append(port); qDebug() << "Port " << portInfo.portName() << " opened successfully"; } else { qDebug() << "Failed to open port " << portInfo.portName(); } } qDebug() << ports; } </code> Заголовочный файл: <code lang="cpp"> #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QSerialPortInfo> #include <QSerialPort> #include <QDebug> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); public slots: void sendMessage(QString message); void msgSentSuccessfully(QString message); void msgFailedToSend(QString message); void ReadData(); signals: void messageSentSuccessfully(const QString &message); void messageFailedToSend(const QString &message); private slots: void sendToAllPorts(); private: Ui::MainWindow *ui; QList<QSerialPortInfo> ports; QByteArray message; QSerialPort *m_comPort; void connectToAllPorts(); }; #endif // MAINWINDOW_H </code> При включении считываются доступные порты, записываются в QVector, через qDebug отображаю их и делаю автоматическое, на данный момент, подключение ко всем портам. Как впоследствии обращаться к ним для работы для отправки и приема?
Дополнительно:
Ответы:
// Форма окна Ui::MainWindow *m_ui; // Флаг ожидания ответа bool m_waitAnswer; // Открываемый com-порт QSerialPort *m_comPort; // Приемный буфер QByteArray m_bufferRead; // Таймер QTimer *m_timerWaitAnswer; |
// Форма окна Ui::MainWindow *m_ui; // Флаг ожидания ответа bool m_waitAnswer; // Открываемый com-порт QSerialPort *m_comPort; // Приемный буфер QByteArray m_bufferRead; // Таймер QTimer *m_timerWaitAnswer;
Эти свойства у вас отвечают за контекст одного конкретного порта.
1. Нужно описать элемент-структуру по этим свойствам - тем самым опишите контекст порта.
2. Сделать массив из этих элементов - массив контекстов портов.
3. В каждом методе работы с портом обеспечить передачу входного параметра, чтобы указывать, какой i-ый элемент структуры использовать (какой контекст порта - конкретный порт), чтобы что-то делать с параметрами конкретного порта.
- Сделал следующим образом, поправьте, если ошибаюсь?
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); connectToAllPorts(); } //------------------------------------------------------------------------------ MainWindow::~MainWindow() { delete ui; } //------------------------------------------------------------------------------ void MainWindow::connectToAllPorts() { QList<QSerialPortInfo> availablePorts = QSerialPortInfo::availablePorts(); for (const QSerialPortInfo &portInfo : availablePorts) { QSerialPort *port = new QSerialPort(portInfo); // Подбираем параметры, скорость и т.д. port->setBaudRate(QSerialPort::Baud9600); port->setDataBits(QSerialPort::Data8); port->setParity(QSerialPort::EvenParity); port->setStopBits(QSerialPort::OneStop); port->setFlowControl(QSerialPort::NoFlowControl); // Открываем порт qDebug() << "Серийный номер: " << portInfo.serialNumber(); if (port->open(QIODevice::ReadWrite)) { ports.append(port); qDebug() << "Порт " << portInfo.portName() << "успешно открыт"; } else { qDebug() << "Ошибка при открытии порта " << portInfo.portName(); delete port; // Освобождаем память, если порт не удалось открыть } } } //------------------------------------------------------------------------------ void MainWindow::on_sendButton_clicked() // также пробую отправить в ком-порт { // Отправка сообщения через порт QByteArray data = "message"; ports[1]->write(data); // Проверка, отправлены ли данные if (ports[1]->waitForBytesWritten(1000)) qDebug() << "Данные успешно отправлены"; else qDebug() << "Ошибка отправки данных"; }#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); connectToAllPorts(); } //------------------------------------------------------------------------------ MainWindow::~MainWindow() { delete ui; } //------------------------------------------------------------------------------ void MainWindow::connectToAllPorts() { QList<QSerialPortInfo> availablePorts = QSerialPortInfo::availablePorts(); for (const QSerialPortInfo &portInfo : availablePorts) { QSerialPort *port = new QSerialPort(portInfo); // Подбираем параметры, скорость и т.д. port->setBaudRate(QSerialPort::Baud9600); port->setDataBits(QSerialPort::Data8); port->setParity(QSerialPort::EvenParity); port->setStopBits(QSerialPort::OneStop); port->setFlowControl(QSerialPort::NoFlowControl); // Открываем порт qDebug() << "Серийный номер: " << portInfo.serialNumber(); if (port->open(QIODevice::ReadWrite)) { ports.append(port); qDebug() << "Порт " << portInfo.portName() << "успешно открыт"; } else { qDebug() << "Ошибка при открытии порта " << portInfo.portName(); delete port; // Освобождаем память, если порт не удалось открыть } } } //------------------------------------------------------------------------------ void MainWindow::on_sendButton_clicked() // также пробую отправить в ком-порт { // Отправка сообщения через порт QByteArray data = "message"; ports[1]->write(data); // Проверка, отправлены ли данные if (ports[1]->waitForBytesWritten(1000)) qDebug() << "Данные успешно отправлены"; else qDebug() << "Ошибка отправки данных"; }
Заголовочный файл:
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QSerialPortInfo> #include <QSerialPort> #include <QDebug> #include <QVector> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void on_sendButton_clicked(); private: Ui::MainWindow *ui; QVector<QSerialPort*> ports; QByteArray message; QSerialPort *m_comPort; void connectToAllPorts(); }; #endif // MAINWINDOW_H#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QSerialPortInfo> #include <QSerialPort> #include <QDebug> #include <QVector> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void on_sendButton_clicked(); private: Ui::MainWindow *ui; QVector<QSerialPort*> ports; QByteArray message; QSerialPort *m_comPort; void connectToAllPorts(); }; #endif // MAINWINDOW_H
- А какой результат работы проверочного скрипта?
void MainWindow::on_sendButton_clicked() // также пробую отправить в ком-порт { // Отправка сообщения через порт QByteArray data = "message"; ports[1]->write(data); // Проверка, отправлены ли данные if (ports[1]->waitForBytesWritten(1000)) qDebug() << "Данные успешно отправлены"; else qDebug() << "Ошибка отправки данных"; }
void MainWindow::on_sendButton_clicked() // также пробую отправить в ком-порт { // Отправка сообщения через порт QByteArray data = "message"; ports[1]->write(data); // Проверка, отправлены ли данные if (ports[1]->waitForBytesWritten(1000)) qDebug() << "Данные успешно отправлены"; else qDebug() << "Ошибка отправки данных"; }
Попробуйте следом отправить другое сообщение на другой порт. Если на портах пришли разные сообщения, то вектор портов вы правильно построили. Потом, проверьте отправку сообщений, превышающие размер буфера порта. Если после этого успешно отправятся сообщения на разные порты, то все ок.
- alexalexes, результата в этом коде не было.
Сейчас создал виртуальные порты, ввиду отсутствия временно реальных. Сделал 'pair' для com2-com3 и com4-com5. Отправляю, вижу, что принимает верно. Сейчас хочу создать потоки, т.к. на отправку некоторых сообщений у меня разное время вызова таймера, по которому и планирую работать далее с портами.
Также логику для открытия порта изменил. Подключаться без разбора ко всем - это плохо)
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); connectToAllPorts(); connect(ports[0], SIGNAL(readyRead()), this, SLOT(readPort())); connect(ports[1], SIGNAL(readyRead()), this, SLOT(readPort())); connect(ports[2], SIGNAL(readyRead()), this, SLOT(readPort())); connect(ports[3], SIGNAL(readyRead()), this, SLOT(readPort())); connect(ports[4], SIGNAL(readyRead()), this, SLOT(readPort())); } //------------------------------------------------------------------------------ MainWindow::~MainWindow() { delete ui; } //------------------------------------------------------------------------------ void MainWindow::connectToAllPorts() { QList<QSerialPortInfo> availablePorts = QSerialPortInfo::availablePorts(); // ищем доступные порты for (const QSerialPortInfo &portInfo : availablePorts) { QSerialPort *port = new QSerialPort(portInfo); // Устанавливаем параметры, скорость и т.д. port->setPortName(portInfo.portName()); port->setBaudRate(QSerialPort::Baud9600); port->setDataBits(QSerialPort::Data8); port->setParity(QSerialPort::EvenParity); port->setStopBits(QSerialPort::OneStop); port->setFlowControl(QSerialPort::NoFlowControl); // Открываем порт qDebug() << "Серийный номер: " << portInfo.serialNumber(); if (port->open(QIODevice::ReadWrite)) { ports.append(port); qDebug() << "Порт" << portInfo.portName() << "успешно открыт для чтения и записи"; } else { qDebug() << "Ошибка при открытии порта" << portInfo.portName(); delete port; // Освобождаем память, если порт не удалось открыть } } } //------------------------------------------------------------------------------ void MainWindow::on_sendButton_clicked() // также пробую отправить в ком-порт { // Отправка сообщения через порт QString textStr = "message"; QByteArray data = QByteArray(ui->sendLineEdit->text().toStdString().c_str());//QByteArray(textStr.toStdString().c_str()); //QByteArray data = "message"; ports[1]->write(data); ports[2]->write(data); ports[3]->write(data); ports[4]->write(data); } //------------------------------------------------------------------------------ void MainWindow::readPort() { if(ports[0]->bytesAvailable() > 0) { QByteArray receivedData = ports[0]->readAll(); qDebug() << "nsize: " << receivedData.size(); qDebug() << "Received data ports[0]: " << receivedData; } if(ports[1]->bytesAvailable() > 0) { QByteArray receivedData = ports[1]->readAll(); qDebug() << "nsize: " << receivedData.size(); qDebug() << "Received data ports[1]: " << receivedData; } if(ports[2]->bytesAvailable() > 0) { QByteArray receivedData = ports[2]->readAll(); qDebug() << "nsize: " << receivedData.size(); qDebug() << "Received data ports[2]: " << receivedData; } if(ports[3]->bytesAvailable() > 0) { QByteArray receivedData = ports[3]->readAll(); qDebug() << "nsize: " << receivedData.size(); qDebug() << "Received data ports[3]: " << receivedData; } if(ports[4]->bytesAvailable() > 0) { QByteArray receivedData = ports[4]->readAll(); qDebug() << "nsize: " << receivedData.size(); qDebug() << "Received data ports[4]: " << receivedData; } }#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); connectToAllPorts(); connect(ports[0], SIGNAL(readyRead()), this, SLOT(readPort())); connect(ports[1], SIGNAL(readyRead()), this, SLOT(readPort())); connect(ports[2], SIGNAL(readyRead()), this, SLOT(readPort())); connect(ports[3], SIGNAL(readyRead()), this, SLOT(readPort())); connect(ports[4], SIGNAL(readyRead()), this, SLOT(readPort())); } //------------------------------------------------------------------------------ MainWindow::~MainWindow() { delete ui; } //------------------------------------------------------------------------------ void MainWindow::connectToAllPorts() { QList<QSerialPortInfo> availablePorts = QSerialPortInfo::availablePorts(); // ищем доступные порты for (const QSerialPortInfo &portInfo : availablePorts) { QSerialPort *port = new QSerialPort(portInfo); // Устанавливаем параметры, скорость и т.д. port->setPortName(portInfo.portName()); port->setBaudRate(QSerialPort::Baud9600); port->setDataBits(QSerialPort::Data8); port->setParity(QSerialPort::EvenParity); port->setStopBits(QSerialPort::OneStop); port->setFlowControl(QSerialPort::NoFlowControl); // Открываем порт qDebug() << "Серийный номер: " << portInfo.serialNumber(); if (port->open(QIODevice::ReadWrite)) { ports.append(port); qDebug() << "Порт" << portInfo.portName() << "успешно открыт для чтения и записи"; } else { qDebug() << "Ошибка при открытии порта" << portInfo.portName(); delete port; // Освобождаем память, если порт не удалось открыть } } } //------------------------------------------------------------------------------ void MainWindow::on_sendButton_clicked() // также пробую отправить в ком-порт { // Отправка сообщения через порт QString textStr = "message"; QByteArray data = QByteArray(ui->sendLineEdit->text().toStdString().c_str());//QByteArray(textStr.toStdString().c_str()); //QByteArray data = "message"; ports[1]->write(data); ports[2]->write(data); ports[3]->write(data); ports[4]->write(data); } //------------------------------------------------------------------------------ void MainWindow::readPort() { if(ports[0]->bytesAvailable() > 0) { QByteArray receivedData = ports[0]->readAll(); qDebug() << "nsize: " << receivedData.size(); qDebug() << "Received data ports[0]: " << receivedData; } if(ports[1]->bytesAvailable() > 0) { QByteArray receivedData = ports[1]->readAll(); qDebug() << "nsize: " << receivedData.size(); qDebug() << "Received data ports[1]: " << receivedData; } if(ports[2]->bytesAvailable() > 0) { QByteArray receivedData = ports[2]->readAll(); qDebug() << "nsize: " << receivedData.size(); qDebug() << "Received data ports[2]: " << receivedData; } if(ports[3]->bytesAvailable() > 0) { QByteArray receivedData = ports[3]->readAll(); qDebug() << "nsize: " << receivedData.size(); qDebug() << "Received data ports[3]: " << receivedData; } if(ports[4]->bytesAvailable() > 0) { QByteArray receivedData = ports[4]->readAll(); qDebug() << "nsize: " << receivedData.size(); qDebug() << "Received data ports[4]: " << receivedData; } }
#ifndef MAINWINDOW_H #define MAINWINDOW_H #define CHANNEL_1 "..." #define CHANNEL_2 "..." ... #define CHANNEL_16 "..." #include <QMainWindow> #include <QThread> #include <QSerialPortInfo> #include <QSerialPort> #include <QDebug> #include <QVector> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void on_sendButton_clicked(); void on_pushButton_6_clicked(); void readPort(); private: Ui::MainWindow *ui; QVector<QSerialPort*> ports; QByteArray message; QSerialPort *m_comPort; void connectToAllPorts(); }; #endif // MAINWINDOW_H#ifndef MAINWINDOW_H #define MAINWINDOW_H #define CHANNEL_1 "..." #define CHANNEL_2 "..." ... #define CHANNEL_16 "..." #include <QMainWindow> #include <QThread> #include <QSerialPortInfo> #include <QSerialPort> #include <QDebug> #include <QVector> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void on_sendButton_clicked(); void on_pushButton_6_clicked(); void readPort(); private: Ui::MainWindow *ui; QVector<QSerialPort*> ports; QByteArray message; QSerialPort *m_comPort; void connectToAllPorts(); }; #endif // MAINWINDOW_H
- alexalexes,
Попробуйте следом отправить другое сообщение на другой порт. Если на портах пришли разные сообщения, то вектор портов вы правильно построили.
Проверил, создал еще один слот на другую кнопку, отправляются разные сообщения. В проверке буфера смысла видеть перестал, переполниться с моими командами не сможет никак, поэтому и проверять тоже не стал!
Теперь в потоки..
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Для организации работы с несколькими COM-портами одновременно вам потребуется использовать специальные библиотеки или API, предоставляемые операционной системой. Ниже приведен пример работы с N COM-портами одновременно на языке PHP с использованием WinAPI для Windows.
```php
// Подключаем библиотеку php_com_dotnet com_load_typelib('MSCommLib.MSComm'); // Создаем объект COM-порта $comPort1 = new COM('MSCommLib.MSComm'); $comPort2 = new COM('MSCommLib.MSComm'); // Добавляем настройки для первого COM-порта $comPort1->CommPort = 1; $comPort1->Settings = '9600,N,8,1'; $comPort1->InputLen = 0; $comPort1->PortOpen = true; // Добавляем настройки для второго COM-порта $comPort2->CommPort = 2; $comPort2->Settings = '9600,N,8,1'; $comPort2->InputLen = 0; $comPort2->PortOpen = true; // Теперь можно работать с обоими COM-портами одновременно
```
В данном примере мы использовали библиотеку `MSCommLib.MSComm` для работы с COM-портами. Создали два объекта COM-порта, установили им настройки (номер порта, скорость передачи данных и другие параметры) и открыли порты для передачи данных.
Помните, что для работы с COM-портами необходимо иметь права администратора на компьютере, а также установленные драйвера для работы с портами. Также обратите внимание на то, что в разных операционных системах могут использоваться различные библиотеки или API для работы с COM-портами.
Надеюсь, данное решение поможет вам организовать работу с N COM-портами одновременно. Если у вас возникнут дополнительные вопросы, не стесняйтесь задавать их.