Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: QtSerialport. Проблема с приемом данных.
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt Ввод/Вывод, Сеть. Межпроцессное взаимодействие
Voronar
Здравствуйте. Взял в помощь эту библиотеку, чтобы общаться с Arduino.
Моя проблема заключается в следующем:

Написал прогу по приему данных с Arduino, но прием и отображение данных происходит не сразу. Сначала приходится через Arduino IDE помониторить порт(послать какой-то сигнал готовности), а после этого уже приходят желанные данные по сигналу readyRead() в соответствующий слот моей программы. Я так понимаю, что в моей программе не хватает какого-то метода, который говорит порту: "Я готов принимать от тебя данные, давай!". Не подскажите как называется этот метод?

Спасибо за внимание.
kuzulis
См. ответ на prog.org.ru
ALeXUI
kuzulis, Здравствуйте, я давно задавал вопрос, на другом форуме, к сожалению времени вернуться к нему не было а сейчас появилось, чтобы не плодить темы, спрошу здесь:

Имеется следующая проблема, при первом включении программы, программа сразу же зависает, при открывании ком порта. Если запустить HyperTerminal и считать данные с ком, и снова запустить программу, все прекрасно работает. В режиме дебага, данные корректо идут и считываются, даже первый раз.
Скорее всего зависание происходит на строчке где вызывается метод readall, он вызывается соответсвенно по сигналу readyread().
Уже месяц не могу понять в чем проблема? Может кто-то сталкивался с чем-то похожим?

Я обновился до последней версии, теперь программа не зависает. Но и данные сразу тоже не идут. Сначало все равно приходится открывать hyperterminal.


Класс отвечающей за соединение и первоначальный прием.

CSerialPort::CSerialPort(QWidget *parent)
{
    serial = new QSerialPort();    
}


QList<QString> CSerialPort::GiveAvaliableCom()
{
    QList<QString> List_Settings;
    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        List_Settings.append(info.portName());
    }
    return List_Settings;
}

void CSerialPort::Slot_CSerialProt_OpenComPort(QString name)
{
    //устанавливаем настройки Com
    serial->setPortName(name);
    serial->setBaudRate(QSerialPort::Baud115200);
    serial->setDataBits(QSerialPort::Data8);
    serial->setParity(QSerialPort::NoParity);
    serial->setStopBits(QSerialPort::OneStop);
    serial->setFlowControl(QSerialPort::NoFlowControl);
    
if (serial->open(QIODevice::ReadWrite))
    {
        qDebug() << "Open is normal";
        emit Signal_CSerialPort_OpenIsNormal();
    }
    else
    {
        QMessageBox::critical(this, tr("Невозможно открыть порт"),
                              tr("Возможно порт занят"),
                              QMessageBox::Ok);
    }
}
void CSerialPort::Slot_CSerialProt_CloseComPOrt()
{
    serial->close();
    qDebug()<< "Close is normal";
}

void CSerialPort::Slot_ReadData_From_Com()
{

    QByteArray data;
    QApplication::processEvents();
    if (serial->error())  qDebug()<<"Eror"<<serial->errorString()<<"   "<<serial->error();
    data = serial->readAll();


    if (statusPRIorSON==0)
    {

        if (status==0)
        {
            emit Signal_CSerialPort_SendDataToIFRNS(data);
        }
        if (status==1)
        {
           ;
        }
        if (status==2)
        {
            emit Signal_CSerialPort_SendDataToXModem(data);
        }

    }
    else if(statusPRIorSON==1)
    {

        if (status==0)
        {
            emit Signal_CSerialPort_SendDataToPRI(data);
        }
        if (status==1)
        {
           ;
        }

    }
    else if(statusPRIorSON==2)
    {
        if (status==0)
        {
            emit Signal_CSerialPort_SendDataToIFRNS_struct1(data);
        }
        if (status==1)
        {
           ;
        }
    }

}

void CSerialPort::Slot_Write_to_Com(QByteArray data1)
{
    serial->write(data1);
}







в главном классе виджета коннект


connect(ComPort->serial,SIGNAL(readyRead()),ComPort,SLOT(Slot_ReadData_From_Com()));



if (serial->error())  qDebug()<<"Eror"<<serial->errorString()<<"   "<<serial->error();




Здесь выводится

Eror "Unknown error" 5
Eror "Unknown error" 5
Eror "Unknown error" 6
Eror "Unknown error" 6
Eror "Unknown error" 5
Eror "Unknown error" 5
ALeXUI
Спасибо уже помогли! Если у кого-то возникнут похожие проблемы, нужно сначало открывать ком-порт, а потом задавть его настройки!
kuzulis
Это само собой разумеется! :)

В следующий раз просто надо читать документацию, смотреть примеры, и "включить мозг" в конце концов!
Voronar
Спасибо ALeXUI.

kuzulis, если бы он не был включен, я бы сюда не добрался с этим вопросом. :) Вполне себе нормальный вопрос начинающего. :)
ALeXUI
kuzulis,
Цитата
В следующий раз просто надо читать документацию

Я бы с таким удовольствием её почитал, да где взять?
http://qt-project.org/wiki/QtSerialPort_Russian здесь про документацию все зачеркнуто....
Цитата
"включить мозг" в конце концов!

Так по логике сначала необходимо настроить соединение, а потом открывать его, из-за этого вся и путаница.

И ещё такой вопрос, сегодня столкнулся со следующей проблемой, первый раз пришлось работать с переходником usb com, как раз после того как обновился=)
После пересброса питания на плате, (но не всегда), такое ощущение, что не идет сигнал readyread(), и происходит это не всегда... Хотя при работе на компьютере с нормальным ком портом, такого замечено не было, поэтому не думаюь что косяк в программе.
Litkevich Yuriy
Цитата(ALeXUI @ 2.4.2013, 2:43) *
Так по логике сначала необходимо настроить соединение, а потом открывать его, из-за этого вся и путаница.
И из-за текущей последовательности все наступали и будут наступать на грабли.
kuzulis
Цитата(ALeXUI)
Я бы с таким удовольствием её почитал, да где взять?
http://qt-project.org/wiki/QtSerialPort_Russian здесь про документацию все зачеркнуто....

Скоро должна быть в открытом доступе на qt-project.org после того как ее допилят до того состояния чтобы не стыдно было :)

А пока что можно сгенерить самому, вот линк: http://www.prog.org.ru/index.php?topic=953...73488#msg173488


Цитата(ALeXUI)
Так по логике сначала необходимо настроить соединение, а потом открывать его, из-за этого вся и путаница.

Крайне неверное утверждение.
1. Ты не можешь что-то сконфигурировать не открыв это, т.е. не получив дескриптор у-ва. Это - раз.
2. Ты можешь переконфигурировать у-во в процессе его работы не закрывая его. Это - два.

Цитата(ALeXUI)
И ещё такой вопрос, сегодня столкнулся со следующей проблемой, первый раз пришлось работать с переходником usb com, как раз после того как обновился=)
После пересброса питания на плате, (но не всегда), такое ощущение, что не идет сигнал readyread(), и происходит это не всегда... Хотя при работе на компьютере с нормальным ком портом, такого замечено не было, поэтому не думаюь что косяк в программе.

Ну, я не телепат.
Дай полный HowTo как воспроизвести проблему и т.п.
Запости баг в багзиллу в конце концов с детальным описанием проблемы.

Вот тогда и есть смысл это обсуждать...


Цитата(Litkevich Yuriy @ 2.4.2013, 6:37) *
Цитата(ALeXUI @ 2.4.2013, 2:43) *
Так по логике сначала необходимо настроить соединение, а потом открывать его, из-за этого вся и путаница.
И из-за текущей последовательности все наступали и будут наступать на грабли.


Ну, это единственно верная последовательность. :)
Litkevich Yuriy
Цитата(kuzulis @ 2.4.2013, 12:11) *
единственно верная последовательность
вообще-то спорно.
Для меня, например, естественной является как раз та, что пишушие сюда и пытаются использовать.

И, я думаю, сюда писать по этому поводу буду ещё долго (таких как я много) :)
Иван
Цитата(kuzulis @ 2.4.2013, 10:11) *
Цитата
Я бы с таким удовольствием её почитал, да где взять?
http://qt-project.org/wiki/QtSerialPort_Russian здесь про документацию все зачеркнуто....

Скоро должна быть в открытом доступе на qt-project.org после того как ее допилят до того состояния чтобы не стыдно было :)

А пока что можно сгенерить самому, вот линк: http://www.prog.org.ru/index.php?topic=953...73488#msg173488


Цитата
Так по логике сначала необходимо настроить соединение, а потом открывать его, из-за этого вся и путаница.

Крайне неверное утверждение.
1. Ты не можешь что-то сконфигурировать не открыв это, т.е. не получив дескриптор у-ва. Это - раз.
2. Ты можешь переконфигурировать у-во в процессе его работы не закрывая его. Это - два.

Цитата
И ещё такой вопрос, сегодня столкнулся со следующей проблемой, первый раз пришлось работать с переходником usb com, как раз после того как обновился=)
После пересброса питания на плате, (но не всегда), такое ощущение, что не идет сигнал readyread(), и происходит это не всегда... Хотя при работе на компьютере с нормальным ком портом, такого замечено не было, поэтому не думаюь что косяк в программе.

Ну, я не телепат.
Дай полный HowTo как воспроизвести проблему и т.п.
Запости баг в багзиллу в конце концов с детальным описанием проблемы.

Вот тогда и есть смысл это обсуждать...


Цитата( @ 2.4.2013, 6:37) *
Цитата(ALeXUI @ 2.4.2013, 2:43) *
Так по логике сначала необходимо настроить соединение, а потом открывать его, из-за этого вся и путаница.
И из-за текущей последовательности все наступали и будут наступать на грабли.


Ну, это единственно верная последовательность. :)

Цитата(kuzulis @ 2.4.2013, 10:11) *
Крайне неверное утверждение.
1. Ты не можешь что-то сконфигурировать не открыв это, т.е. не получив дескриптор у-ва. Это - раз.
2. Ты можешь переконфигурировать у-во в процессе его работы не закрывая его. Это - два.

Вот как раз по второй причине хочется сделать сначала задать конфигурацию, а потом открывать устройство. И потом в QextSerialPort нужно сначала создать объект порта (получить дескриптор устройства), затем сконфигурировать его и только потом открывать. Так что по крайней мере я не вижу в действиях ALeXUI ничего конфликтующего с нормальной логикой или опытом использования QextSerialPort.
Алексей1153
сам порт (который в системе), конечно же, требует, чтобы сначала открыли его, потом настроили. Но оболочка вполне может позволить сначала задать настройки, а потом , когда порт открывают, эти настройки туда лепить.

так что, недоработочка в интерфейсе оболочки ИМХО :)
kuzulis
Парни, ну не серьезно все это. Я перестану вообще отвечать и реагировать на такого рода вопросы и хотелки.

Цитата
Вот как раз по второй причине хочется сделать сначала задать конфигурацию, а потом открывать устройство.

Неверно. Ты можешь для такого поведения сделать свою обертку над классом.

Цитата
И потом в QextSerialPort нужно сначала создать объект порта (получить дескриптор устройства), затем сконфигурировать его и только потом открывать.

Неверно. Каша в голове.

Цитата
Так что по крайней мере я не вижу в действиях ALeXUI ничего конфликтующего с нормальной логикой или опытом использования QextSerialPort.

Неверно. Я не разбираюсь в сортах г-на и логика/опыт с QextSerialPort меня не волнует.


Цитата
сам порт (который в системе), конечно же, требует, чтобы сначала открыли его, потом настроили. Но оболочка вполне может позволить сначала задать настройки, а потом , когда порт открывают, эти настройки туда лепить.


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

Цитата
так что, недоработочка в интерфейсе оболочки ИМХО

Так что, недоработочка в интерфейсе мозга ИМХО




А также нежелание читать документацию, смотреть примеры, поискать решение в гугле и т.п.
Проще ляпнуть перл в форум - авось кто-нибудь решит вашу проблему за Вас.

UPD:
Также см. QFile, QAbstractSocket, QProcess и прочие классы от QIODevice. Они не согласны с вашей логикой.
Я нехочу спорить об этом.

Если есть желание что-то изменить - представьте свое решение в Gerrit. Если его одобрят (но я не одобрю :) )
то оно появится в QtSerialPort.




Алексей1153
какие по весне все нервные :D
ud4fd
Здравствуйте kuzulis,

Подскажите ка в библиотеке QtSerialPort использовать сигнал PinoutSignals для контроля за состоянием линий CTS, RI, DCD ... желательно с реальным примером.
ud4fd
Здравствуйте kuzulis,

при попытке использовать сигналы от состояния линий порта
 connect(serial, SIGNAL(DataSetReadySignal()), this, SLOT(myDSR()) );

в дебаг получаю следующее
Цитата
Object::connect: No such signal QSerialPort::DataSetReadySignal()
Object::connect: (receiver name: 'MainWindow')


Тестировал под Linux в QT4.8 и QT5

Как правильно работать с сигналами от линий порта?
kuzulis
А гдеты нашел эти сигналы? Таких сигналов нету, есть только эти:

Цитата
Q_SIGNALS:
void baudRateChanged(qint32 baudRate, QSerialPort::Directions dir);
void dataBitsChanged(QSerialPort::DataBits dataBits);
void parityChanged(QSerialPort::Parity parity);
void stopBitsChanged(QSerialPort::StopBits stopBits);
void flowControlChanged(QSerialPort::FlowControl flow);
void dataErrorPolicyChanged(QSerialPort::DataErrorPolicy policy);
void dataTerminalReadyChanged(bool set);
void requestToSendChanged(bool set);
void error(QSerialPort::SerialPortError serialPortError);
void settingsRestoredOnCloseChanged(bool restore);


Во вторых, отслеживание изменения сигналов DSR, CTS, RNG и пр. не поддерживается
потому что невозможно это кросс-платформено реализовать для всех платформ
(например в MAC OSX) без использования поллинга.
ud4fd
Цитата(kuzulis @ 28.4.2013, 14:35) *
А гдеты нашел эти сигналы? Таких сигналов нету, есть только эти:


А это нафига есть в файле qserialport_unix.cpp

QSerialPort::PinoutSignals QSerialPortPrivate::pinoutSignals() const
{
    int arg = 0;
    QSerialPort::PinoutSignals ret = QSerialPort::NoSignal;

    if (::ioctl(descriptor, TIOCMGET, &arg) == -1) {
        q_ptr->setError(decodeSystemError());
        return ret;
    }

#ifdef TIOCM_LE
    if (arg & TIOCM_LE)
        ret |= QSerialPort::DataSetReadySignal;
#endif
#ifdef TIOCM_DTR
    if (arg & TIOCM_DTR)
        ret |= QSerialPort::DataTerminalReadySignal;
#endif
#ifdef TIOCM_RTS
    if (arg & TIOCM_RTS)
        ret |= QSerialPort::RequestToSendSignal;
#endif
#ifdef TIOCM_ST
    if (arg & TIOCM_ST)
        ret |= QSerialPort::SecondaryTransmittedDataSignal;
#endif
#ifdef TIOCM_SR
    if (arg & TIOCM_SR)
        ret |= QSerialPort::SecondaryReceivedDataSignal;
#endif
#ifdef TIOCM_CTS
    if (arg & TIOCM_CTS)
        ret |= QSerialPort::ClearToSendSignal;
#endif
#ifdef TIOCM_CAR
    if (arg & TIOCM_CAR)
        ret |= QSerialPort::DataCarrierDetectSignal;
#elif defined TIOCM_CD
    if (arg & TIOCM_CD)
        ret |= QSerialPort::DataCarrierDetectSignal;
#endif
#ifdef TIOCM_RNG
    if (arg & TIOCM_RNG)
        ret |= QSerialPort::RingIndicatorSignal;
#elif defined TIOCM_RI
    if (arg & TIOCM_RI)
        ret |= QSerialPort::RingIndicatorSignal;
#endif
#ifdef TIOCM_DSR
    if (arg & TIOCM_DSR)
        ret |= QSerialPort::DataSetReadySignal;
#endif

    return ret;
}
kuzulis
Цитата
А это нафига есть в файле qserialport_unix.cpp


А ты не можешь отличить Qt-шные сигналы от сигнальных линий порта (pinout signals)?

Нонсенс, я и не знал, что можно делать QObject::connect к перечисляемому типу, вот это новость так новость! :huh:

Ужос!
ud4fd
Цитата(kuzulis @ 28.4.2013, 22:07) *
А ты не можешь отличить Qt-шные сигналы от сигнальных линий порта (pinout signals)?

вот здесь
Цитата(ud4fd @ 27.4.2013, 1:00) *
Здравствуйте kuzulis,

Подскажите ка в библиотеке QtSerialPort использовать сигнал PinoutSignals для контроля за состоянием линий CTS, RI, DCD ... желательно с реальным примером.


Я и спрашивол есть ли возможность обрабатывать сигналя от PinoutSignals или нет. Так как в документации ни чего толком не нашел.
kuzulis
А я тебе ответил, что можешь только поллингом их состояние узнать (по таймеру или еще как нить):

...
PinoutSignals signals = port->pinoutSignals();
...
bool dsrState = QSerialPort::DataSetReadySignal & signals;
if (dsrState) {
    // do something
}
...


Нативный мониторинг не поддерживается, т.к. невозможно в MAC OSX это реализовать.
Поэтому забили болт на реализацию этой возможности - т.к. она могла бы работать только на Windows и Linux.
marsel
Здравствуйте kuzulis.

Подскажите пожалуйста возможно ли в QSerialPort из под Windows получить дескриптор (handle) com порта, который возвращает CreateFile.

Просто необходимо изменить время ожидания у микросхемы FTDI(Виртуальный com порт). У неё есть библиотека, с помощью которой можно изменить это время ожидания. Но необходим дескриптор (handle) com порта.

http://www.ftdichip.com/Support/Knowledgeb...atencytimer.htm

#include "ftd2xx.h"

FT_HANDLE ftHandle;
UCHAR LatencyTimer;//***Время ожидания

FT_SetLatencyTimer(ftHandle, LatencyTimer);

Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.