2016-07-19 8 views
0

Я пишу мост qt для доступа к серийным термопринтерам через веб-приложения. У меня возникли параметры выпуска настройки последовательного порта, вот мой код:Странное поведение QT QSerialPort в Windows 7 не изменяет настройки последовательного COM-порта

bool Bridge::printToSerial(QByteArray arr, QString serialPortName, quint16 baud) { 

/* 
QProcess proc; 
QStringList args = QStringList() << QString("mode COM1 BAUD=%1 PARITY=%2 DATA=%3").arg(9600).arg("n").arg(8); 
proc.start("cmd.exe", args); 
proc.waitForStarted(); 
proc.close(); 
*/ 

QSerialPort* m_port = new QSerialPort(this); 
m_port->setPortName(serialPortName); // \\.\COM1 
if(!m_port->open(QSerialPort::ReadWrite)) { 
    qDebug() << "Error serial open"; 
} else { 
    if (arr.isEmpty()) { 
     qDebug() << QObject::tr("Either no data was currently available on the standard input for reading, or an error occurred for port %1, error: %2").arg(serialPortName).arg(m_port->errorString()) << endl; 
     delete m_port; 
     return 1; 
    } 

    m_port->setBaudRate(baud); 
    m_port->setDataBits(QSerialPort::Data8); 
    m_port->setParity(QSerialPort::NoParity); 
    m_port->setStopBits(QSerialPort::OneStop); 

    //m_port->setBreakEnabled(true); 

    qint64 bytesWritten = m_port->write(arr); 
    if (bytesWritten == -1) { 
     qDebug() << QObject::tr("Failed to write the data to port %1, error: %2").arg(serialPortName).arg(m_port->errorString()) << endl; 
     delete m_port; 
     return 1; 
    } else if (bytesWritten != arr.size()) { 
     qDebug() << QObject::tr("Failed to write all the data to port %1, error: %2").arg(serialPortName).arg(m_port->errorString()) << endl; 
     delete m_port; 
     return 1; 
    } else if (!m_port->waitForBytesWritten(500)) { 
     qDebug() << QObject::tr("Operation timed out or an error occurred for port %1, error: %2").arg(serialPortName).arg(m_port->errorString()) << endl; 
     delete m_port; 
     return 1; 
    } 
    m_port->close(); 
    delete m_port; 
    qDebug() << QObject::tr("Data successfully sent to port %1").arg(serialPortName) << endl; 
    return false; 
} 
delete m_port; 
return true; 
} 

проблема заключается в том, что отпечатки данных, но не заканчивается, что заставило меня вещь, что биты данных не установлен в 8 бит ,

Я выполнил команду: режим COM1, и он показывает, что порт не настроен должным образом (скорость передачи, бит, четность все не так). Кстати, диспетчер устройств показывает настройки по умолчанию порта и другой результат, чем линия cmd: «mode COM1»

Чтобы заставить его работать, я либо должен выполнить строку cmd: mode COM1 BAUD = 9600 PARITY = n DATA = 8 до запуска программы. или вызовите m_port-> setBreakEnabled (true); после открытия порта. Этот вызов зависает от программы, и мне приходится перекомпилировать exe без работы. Когда система перезагружается, режим командной строки показывает старые результаты (скорость передачи 1200, бит данных 7 и т. Д.)

Любая подсказка, почему у меня такое поведение? Кажется, что QSerialPort не может эффективно изменить все необходимые мне настройки.

ответ

1

Почему вы открываете и закрываете порт каждый раз, когда вы отправляете данные? Кроме того, только потому, что write или waitForBytesWritten вернули что-то, что указывает на то, что данные были «записаны», это означает, что данные были сброшены с буферов драйвера устройства верхнего уровня. USB-запросы на то, чтобы на самом деле нажимать все эти данные на аппаратное обеспечение, по-прежнему находятся на рассмотрении, у FIFO устройства все еще могут быть данные и т. Д.

Однако, когда вы закрываете устройство, вы, чтобы очистить свои буферы. Запись является асинхронной и потоковой, чтобы поддерживать производительность, закрытие устройства - это синхронный, мгновенный тип действия.

Держите устройство открытым. Вам нужно только открыть его, когда вы узнаете, каким образом зависит от платформы, устройства, уходящего или добавляемого нового устройства.

+0

Так что в основном я должен отслеживать открытые порты и, если их открыть, записывать данные, иначе: открыть, записать данные и пометить порт как открытый. Есть ли способ узнать, открыт ли порт? – othmoz

+0

@othmoz Это зависит от вас. Сохраните список портов, которые вы используете. Те, которые вы не используете, явно не открыты вам, те, которые вы используете, остаются открытыми. Это все. –

0

@ Kuba Ober был прав. Я закончил тем, что изменил функцию, чтобы выглядеть так: открытые порты отслеживания: (я не знаю, должен ли я иметь указатель QSerialPort для каждого порта или как он ниже, использовать его для переопределения параметров портов каждый раз, когда я пишу данные, хотя это работает).

bool Bridge::printToSerial(QByteArray arr, QString serialPortName, quint16 baud) { 

if (arr.isEmpty()) { 
    qDebug() << QObject::tr("Either no data was currently available on the standard input for reading, or an error occurred for port %1, error: %2").arg(serialPortName).arg(m_port->errorString()) << endl; 
    return false; 
} 

bool portOpen = m_opened.contains(serialPortName); 

if(!portOpen) { 
    if(m_port == NULL) { 
     m_port = new QSerialPort(this); 
    } 
    m_port->setPortName(serialPortName); 
    if(!m_port->open(QSerialPort::WriteOnly)) { 
     qDebug() << "Error serial open"; 
     return false; 
    } 
    portOpen = true; 
    m_opened[serialPortName] = true; 
} else { 
    m_port->setPortName(serialPortName); // \\.\COM1 
} 

m_port->setBaudRate(baud); 
m_port->setDataBits(QSerialPort::Data8); 
m_port->setParity(QSerialPort::NoParity); 
m_port->setStopBits(QSerialPort::OneStop); 

qint64 bytesWritten = m_port->write(arr); 
if (bytesWritten == -1) { 
    qDebug() << QObject::tr("Failed to write the data to port %1, error: %2").arg(serialPortName).arg(m_port->errorString()) << endl; 
    delete m_port; 
    return 1; 
} else if (bytesWritten != arr.size()) { 
    qDebug() << QObject::tr("Failed to write all the data to port %1, error: %2").arg(serialPortName).arg(m_port->errorString()) << endl; 
    delete m_port; 
    return 1; 
} else if (!m_port->waitForBytesWritten(5000)) { 
    qDebug() << QObject::tr("Operation timed out or an error occurred for port %1, error: %2").arg(serialPortName).arg(m_port->errorString()) << endl; 
    delete m_port; 
    return 1; 
} 
qDebug() << QObject::tr("Data successfully sent to port %1").arg(serialPortName) << endl; 
return true; 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^