Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: QSerialDevice - Библиотека для работы с COM-портами
Форум на CrossPlatform.RU > Административный > Crossplatform.ru - все о нем > Обсуждение исходников с сайта
Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9
RazrFalcon
Либу под виндой в статику собрать нельзя? На лине и маке норм, на выне:
moc_qserialport.cpp:195: ошибка: definition of static data member 'QSerialPort::staticMetaObjectExtraData' of dllimport'd class
kuzulis
Цитата(RazrFalcon @ 8.3.2013, 0:05) *
Либу под виндой в статику собрать нельзя? На лине и маке норм, на выне:
moc_qserialport.cpp:195: ошибка: definition of static data member 'QSerialPort::staticMetaObjectExtraData' of dllimport'd class

Можно, надо в qserialportglobal.h закоментировать Q_DECL_EXPORT или Q_DECL_IMPORT
RazrFalcon
Это нужно только на винде, или желательно на всех ос?
RazrFalcon
Еще по поводу info.
pid/vid на маке с R232 не ставит нули в начале
типа

на вин и лине 0001, а на маке 1

На Win XP с 4.8.4 не приходит ResourceError после отключения.
Разве что через сек 30 срабатывает ReadError.
RazrFalcon
И еще вопрос.
Есть переходник на microchip. Не открывается порт. По дебагу вылетает тут:
// qserialport_win.cpp
// line 235
if (descriptor == INVALID_HANDLE_VALUE) {
        q_ptr->setError(decodeSystemError()); // сюда выбивает
        return false;
}

из дебага:
descriptor 4294967295 HANDLE
desiredAccess 3221225472

UPD: в linux все норм, разве что устройство определяется как ttyACM0, а не ttyUSB0.
В винде драйвер стоит и сторонними прогами получается достучатся до порта.
kuzulis
Цитата
Это нужно только на винде, или желательно на всех ос?

По-моему только на винде.

Цитата
Еще по поводу info.
pid/vid на маке с R232 не ставит нули в начале
типа

на вин и лине 0001, а на маке 1

Да, есть такая фигня. Запости баг, чтобы не забыть.

Цитата
На Win XP с 4.8.4 не приходит ResourceError после отключения.
Разве что через сек 30 срабатывает ReadError.

А что за шнурок?

Можешь в дебагере в qserialport_win.cpp стать на все
processCompletionRoutine() во всех нотификаторах
CommOverlappedEventNotifier, ReadOverlappedCompletionNotifier и WriteOverlappedCompletionNotifier?

Цитата
Есть переходник на microchip. Не открывается порт. По дебагу вылетает тут:
...
из дебага:
descriptor 4294967295 HANDLE
desiredAccess 3221225472
...

Ну это ХЗ, вроде как не может открыть девайс, т.к. 4294967295 это INVALID_HANDLE_VALUE.
Возможно ему не нравится FILE_FLAG_OVERLAPPED в CreateFile, может еще что...
Проверить можешь только ты сам. :)






RazrFalcon
Цитата
А что за шнурок?

Все тот же, что и 5-ь страниц назад. Не пашет пока только на винде.

Цитата
Ну это ХЗ, вроде как не может открыть девайс

Ну это я и так понял. Буду думать. Главное на лине и маке пашет нормально. А на винде ни в какую.

Есть какие-то флаги, функции которые можно попробовать? Я то понимаю что придется самому фиксить, но как - хз.

С pid/vid забагрепортил.
kuzulis
Цитата(RazrFalcon)
Все тот же, что и 5-ь страниц назад. Не пашет пока только на винде.

Попробуй все-таки после открытия порта встать на те брекпойнты что я сказал и
выдернуть шнурок. Сработает ли CommOverlappedEventNotifier?

И если сработает, то какое значение будет у triggeredEventMask?


Цитата(RazrFalcon)
Есть какие-то флаги, функции которые можно попробовать? Я то понимаю что придется самому фиксить, но как - хз.


Попробуй сначала просто поглядеть что возвратит после CreateFile функция GetLastError() которая внутри decodeSystemError().
Далее, уже будем смотреть что делать в зависимости от этого системного кода ошибки.

Цитата(RazrFalcon)
С pid/vid забагрепортил.

Спасибо.
RazrFalcon
Отключение проверю позже.

Пока что вышел на ошибку. И она до смешного популярна в гугле и именно с микрочипом.
SetCommState возвращает ошибку номер 31...
kuzulis
Цитата(RazrFalcon @ 11.3.2013, 16:11) *
Пока что вышел на ошибку. И она до смешного популярна в гугле и именно с микрочипом.
SetCommState возвращает ошибку номер 31...


Эмм... Так это не в CreateFile проблема?

RazrFalcon
Угу. Видел. Проверю.

По поводу устройства. Еще более интересно. Дали мне сорцы оригинальной проги, на дельфи, которая работает отлично.

Вот как она открывает (перевел на c++), отличия от QtSerialPort:
::SetupComm(descriptor, 1024, 1024);
::PurgeComm(descriptor, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
// +
currentCommTimeouts.ReadTotalTimeoutConstant = 0;
currentCommTimeouts.ReadTotalTimeoutMultiplier = 0;
currentCommTimeouts.WriteTotalTimeoutMultiplier = 0;
currentCommTimeouts.WriteTotalTimeoutConstant = 0;

SetCommState не используется вообще.
В итоге сделав как в ней и закоментировав SetCommState, так как на нем ошибка. Теперь не могу дождаться ответа. Дебаг повисатет на:
QWinEventNotifier *n = new CommOverlappedEventNotifier(this, originalEventMask, q_ptr);

То есть прога тупо зависает, ждет как я понимаю ответа, но он не приходит.

Полный код функции на дельфи:
Раскрывающийся текст
function TfrmMain.OpenCOMDevice( port:string ) : boolean;
var
  ii: Integer;
  IsAvail:boolean;
begin
  if IsCOMConnected then
    CloseCOMDevice;

  LOG_INFO('OpenCOMDevice()', 'Подключение к порту: ' + PChar('\\.\\' + port));

  Result := False;

  try
    hComm:=CreateFile(PChar('\\.\\' + port),//cbDevPorts.Items[cbDevPorts.ItemIndex]),
                      GENERIC_READ or GENERIC_WRITE,
                      0,
                      Nil,
                      OPEN_EXISTING,
                      0,
                      0);

    if hComm = INVALID_HANDLE_VALUE then
    begin
      LOG_ERR('OpenCOMDevice()', 'hComm = INVALID_HANDLE_VALUE ('+SysErrorMessage(GetLastError)+')');
      Exit;
    end;

    ResBool := SetupComm(hComm, 1024, 1024);
    if ResBool = false then
    begin
      LOG_WARN('OpenCOMDevice()', 'SetupComm(hComm, 2048, 2048) = false');
    end;

    if not PurgeComm(hComm, PURGE_TXABORT or PURGE_RXABORT or PURGE_TXCLEAR or PURGE_RXCLEAR) then
    begin
      LOG_WARN('OpenCOMDevice()', 'PurgeComm(hComm, PURGE_TXABORT or PURGE_RXABORT or PURGE_TXCLEAR or PURGE_RXCLEAR) = false');
    end;

    CommTimeouts.ReadIntervalTimeout:=MAXDWORD;
    CommTimeouts.ReadTotalTimeoutMultiplier:=0;
    CommTimeouts.ReadTotalTimeoutConstant:=0;
    CommTimeouts.WriteTotalTimeoutMultiplier:=0;
    CommTimeouts.WriteTotalTimeoutConstant:=0;

    ResBool := SetCommTimeouts(hComm,CommTimeouts);
    if ResBool = false then
    begin
      LOG_ERR('OpenCOMDevice()', 'SetCommTimeouts(hComm,CommTimeouts) = false');
      raise Exception.Create('[SetCommTimeouts(..)] Ошибка при утановке таймингов порта!');
    end;

    OnDeviceConnect;

    Result := True;
  except
    SysErrorMessage(GetLastError);
    CloseHandle(hComm);
    hComm := INVALID_HANDLE_VALUE;
    Result:=False;
  end;
end;


PS: сомневаюсь что патч с vid/pid не заработает. rightJustified не может не работать ;)
Алексей1153
CommTimeouts.ReadIntervalTimeout:=MAXDWORD;

ну ну :)

ждать будешь дооооолго. Примерно 50 суток
RazrFalcon
В QtSerialPort так же =/
Да и код не мой.
Алексей1153
RazrFalcon, этот таймаут - максимально позволяемое время между принимаемыми байтами. Раньше придёт - хорошо, а пока не приходит, функция держит управление. По таймауту (с учётом множителя и общего таймаута на чтение) возвращается ошибка - не удалось чтение

Как в других системах, не знаю, а в винде, чтобы таких затыканий не происходило, для синхронного режима вызывают функцию ClearCommError, откуда можно узнать, сколько сейчас уже принято байтов в буфере системы. Эти байты всегда считаются без задержек и управление тут же вернётся
RazrFalcon
По поводу детекта отключения на винде.

CommOverlappedEventNotifier
error = false

Всё. read и write не вызываются.


Что-то конкретное проверить может?

Алексей1153, это понятно. Только толку? Я не автор либы. Почему повисает понятно. По таймауту. Но повисать не должна, вот в чем затык.
kuzulis
Цитата(RazrFalcon)
По поводу детекта отключения на винде.

CommOverlappedEventNotifier
error = false

Всё. read и write не вызываются.


Что-то конкретное проверить может?

Да, какое значение у triggeredEventMask и у originalEventMask в CommOverlappedEventNotifier::processCompletionRoutine()?

Цитата
CommTimeouts.ReadIntervalTimeout:=MAXDWORD;

ну ну :)

ждать будешь дооооолго. Примерно 50 суток

Нет, как раз наоборот. Почитай MSDN. ;)

Цитата(RazrFalcon)
Полный код функции на дельфи:


Нет. Открывают аналогично, таймауты такие-же.

Отличия в том, что дельфовый вариант не использует OVERLAPPED режим порта,
а также не устанавливает DCB структуру..

Хм.. т.е. скорость порта невозможно установить?

Цитата(RazrFalcon)
В итоге сделав как в ней и закоментировав SetCommState, так как на нем ошибка. Теперь не могу дождаться ответа. Дебаг повисатет на:

И будет зависать, т.к. открыто без FILE_FLAG_OVERLAPPED.
Фишка еще в том, что этот флаг обязательно нужен для QtSerialPort -
без него оно вообще не будет работать. :)


Цитата(RazrFalcon)
Пока что вышел на ошибку. И она до смешного популярна в гугле и именно с микрочипом.
SetCommState возвращает ошибку номер 31...


Да уж, обхохочешься:
Цитата
ERROR_GEN_FAILURE

31 (0x1F)

A device attached to the system is not functioning.


Цитата(RazrFalcon)
PS: сомневаюсь что патч с vid/pid не заработает. rightJustified не может не работать ;)

Уже отказались от этого патча. Забудь. По другому там надо делать. :)

Алексей1153
kuzulis, ага, подзабылось ) Но это не отменяет практику чистить ошибку
RazrFalcon
triggeredEventMask = 1
originalEventMask = 129

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

да и на маке и лине, udev как я понимаю, справляется нормально


про патч - ок, себе добавил. у меня и так тоже самое было, только уже в самой проге
kuzulis
Цитата(RazrFalcon)
triggeredEventMask = 1
originalEventMask = 129


Ох. Вот это вот и хреновенько. Т.е. тут уже не определишь что устройство выткнуто.

Хорошо, тогда вот что: в коде после того как ты выдернул шнурок, т.к. triggeredEventMask = 1 (EV_RXCHAR),
то должен запуститься startAsyncRead(), а после него - completeAsyncRead().

Так вот, проверь, есть ли какие-нить ошибки после ReadFile() в startAsyncRead() или еще где нить?
Т.к. если никаких ошибок нет - то невозможно отловить выдергивание.

А если все-таки ошибки есть и GetLastError их возвращает, то приведи номер ошибки
и скажи после какой операции она возникла.

Все дело в драйвере шнурка, возможно поможет установка последнего драйвера от FTDI
(мы же про FTDI говорим в данном случае?)


Цитата(RazrFalcon)
ну по этому и по другому
просто прога на дельфях то пашет, пусть и 31-н ошибка...


Ну так на дельфях и не используется много чего. Это не проблема QtSerialPort -
это проблема драйвера устройства. Если он гогно - то тут ничего не сделаешь.
Только обновить драйвер.

Цитата(RazrFalcon)
да и на маке и лине, udev как я понимаю, справляется нормально


Ну, ты сравнил теплое с мягким. :)
RazrFalcon
startAsyncRead

1) первое условие не выполнилось, на чтение буфера
2) второе тоже (то есть указатель забрало нормально)
3) файл не прочло
4) QSerialPort::PermissionError
5) Поменяло на ReadError
6) вернуло false


Как временная заглушка, на винде и на ReadError проверяю. Но это как то не очень, вроде бы.
kuzulis
Цитата(RazrFalcon @ 12.3.2013, 13:46) *
startAsyncRead

1) первое условие не выполнилось, на чтение буфера
2) второе тоже (то есть указатель забрало нормально)
3) файл не прочло
4) QSerialPort::PermissionError
5) Поменяло на ReadError
6) вернуло false


Как временная заглушка, на винде и на ReadError проверяю. Но это как то не очень, вроде бы.


Странно.
Нашел на работе девайс с FTDI чипом, установил драйвера v 2.08.28 с сайта: http://www.ftdichip.com/Drivers/VCP.htm

И все работает, при выдергивании triggeredEventMask = 0!

ОС: Win8x32
RazrFalcon
XP...
На семерке не проверял.
kuzulis
Цитата(RazrFalcon @ 12.3.2013, 18:42) *
XP...
На семерке не проверял.


Это неважно, т.к. драйвер один на х32 архитектуру -ftser2k.sys (а на х64 тоже его имя ftser2k.sys, но он в другой папочке лежит)
kuzulis
RazrFalcon,

Кстати да, все-же имеется баг с излучением сигнала ResourceError в Windows.
Предыдущее решение рабоатет частично.

Он (баг) должен воспроизводится, если из открытого ранее у-ва мы что-то прочитали,
а потом через некоторое время выдернули шнурок.

Но если мы просто открыли девайс и выдернули - то вроде бага нет.

Можешь у себя проверить?


UPD: И еще, зря ты на свой QTPLAYGROUND-21 баг та честно утвердительно ответил. :)

Потому что просто возвращать uint16 немного некорректно, т.к. некоторые девайсы (которые НЕ USB, и НЕ PCI)
не имеют вообще никакого VID/PID. Поэтому возвращать 0 в таких случаях некорректно,
потому что нулевые VID/PID реально могут существовать для USB и в некоторых случаях это не ошибка!

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

Даже хочет лишить меня (создателя библиотеки) права голоса, говорит, что я приношу только вред проекту.
И обсирает всех в некомпетентности.

Вот такие вот дела. :(
kuzulis
RazrFalcon,

Ты у нас единственный человек у которого есть возможность доступа к MacOSX.

Не мог бы ты проверить патч для бага с отображением описания для Bluetooth у-ва?

https://bugreports.qt-project.org/browse/QTPLAYGROUND-25

Вот примерный мануал как проверять:

http://www.prog.org.ru/index.php?topic=953...73695#msg173695


ЗЫ: Или кто-нибудь, проверьте плиз.
Алексей1153
вот понадобился данный класс, стал разбираться.

квест прошёл, но мозг взорвал ))

вот здесь http://qt-project.org/wiki/QtSerialPort_Russian

для Qt4 вместо
CONFIG += serialport


должно быть
LIBS += -lqtserialport

-------------------

тут выше упоминается, что
Цитата(Litkevich Yuriy @ 6.7.2010, 0:40) *
Цитата(kuzulis @ 6.7.2010, 0:49) *
Хто хочет - сделает сам если что.
вот поэтому я и не использую твою библиотеку, также как и QxtSerialPort


а какие ещё классы есть ?
Алексей1153
сел читать из реального порта - и не читаются данные. Порт открывается, а сигнал readyRead() не вызывается, да и принудительный вызов readAll() возвращает 0. Хотя данные в порт с прибора точно идут - я темриналом проверял

это что может быть такое ?

CMainWindow::CMainWindow(QWidget *parent) :
    QDialog(parent,Qt::Window),
    ui(new Ui::CMainWindow)
{
    ui->setupUi(this);
...
...
    m_sp=new QSerialPort("//./com5",0);
    m_sp->setBaudRate(QSerialPort::Baud115200);
    m_sp->setDataBits(QSerialPort::Data8);
    m_sp->setParity(QSerialPort::NoParity);
    m_sp->setStopBits(QSerialPort::OneStop);
//    m_sp->setFlowControl(QSerialPort::NoFlowControl);
    if(m_sp->open(m_sp->ReadWrite))
    {
        QSerialPort::SerialPortError e=m_sp->error();
        qDebug()<<"port opened";
        qDebug()<<"error="<<e;
    }

    connect(m_sp,SIGNAL(readyRead()),this,SLOT(readyRead()));
}

void CMainWindow::readyRead()
{
    //сюда не попадаем вообще
    QByteArray d=m_sp->readAll();
    qDebug()<<d;
}


верси Qt 4.8.2 - может, в этом проблема ?
Алексей1153
какие там другие классы для работы с ком-портом упоминались ? Желательно без наворотов - мне всё равно нужно будет простая вычитка в отдельном потоке
Алексей1153
перешёл на Qt 5 , там QSerialPort уже встроен, прописываем

QT += serialport
kuzulis
1)

Цитата
должно быть

LIBS += -lqtserialport


не не не .. ни в коем случае.

для Qt4 надо:

Цитата
CONFIG += serialport


скорее всего ты просто не установил QtSerialPort в свою Qt4. В Wiki исчерпывающая инфа.

2)

Цитата
сел читать из реального порта - и не читаются данные. Порт открывается, а сигнал readyRead() не вызывается, да и принудительный вызов readAll() возвращает 0. Хотя данные в порт с прибора точно идут - я темриналом проверял

это что может быть такое ?


Это не напрягает?
m_sp=new QSerialPort("//./com5",0);


Может так правильнее тогда:
m_sp=new QSerialPort("\\\\.\\COM5",0);

если вздумал использовать "\\.\" ?? :) Но это можно опустить, достаточно писать просто COM5, там внутри оно само подставит что надо и куда надо.


ПЫСЫ: Может сначала нужно почитать документацию и посмотреть примеры? Или мы "нахрапом" берем? :)
Алексей1153
kuzulis,
1) "не не не" - а вот и да , я же пробовал

2) установил, иначе бы не слинковалось и не открылся бы порт вообще. А он открылся

3) "//./com5" - не напрягает, библиотека (да и винда) понимает и так, и так. Опять же - я пробовал и так, и так

4) целый день смотрел примеры, читал и искал, консультировался по скайпу с народом - удивляются, что там ещё могло быть такое )

В общем, под Qt4 не завелось. Обновил библиотеку на Qt5 - всё теперь работает (код не менял даже)

Вот такие загадки :)
Iron Bug
Цитата(kuzulis @ 29.4.2014, 20:40) *
Это не напрягает?
m_sp=new QSerialPort("//./com5",0);


Может так правильнее тогда:
m_sp=new QSerialPort("\\\\.\\COM5",0);

если вздумал использовать "\\.\" ?? :)

простите, что вмешиваюсь. а что должно тут напрягать? это единственное правильное отображение слэшей в путях, которое понимают все системы (по крайней мере, в С++). обратный слэш - чисто вендозная шняга, поэтому его использование в кроссплатформенном программировании должно быть исключено.
Гость
Класс называется QSerialDevice, тогда логично использовать с помощью него для символьных устройсв. Но когда используешь open, класса AbstractSerial, реузльтат false. Это из-за того что символьные устройства не используют настройки типа baud и т.д... Это решаемо...
Вопрос в другом, если все же поправить исходники что бы символьное устройство можно было открыть, то что делать с сигналами readyRead() они постоянно валят.... есть данных или нет. Или что нужно учесть в символьном стройстве для этого?
человек
Класс называется QSerialDevice, тогда логично использовать с помощью него для символьных устройсв. Но когда используешь open, класса AbstractSerial, реузльтат false. Это из-за того что символьные устройства не используют настройки типа baud и т.д... Это решаемо...
Вопрос в другом, если все же поправить исходники что бы символьное устройство можно было открыть, то что делать с сигналами readyRead() они постоянно валят.... есть данных или нет. Или что нужно учесть в символьном стройстве для этого?
kuzulis
Iron Bug,
Цитата
простите, что вмешиваюсь. а что должно тут напрягать? это единственное правильное отображение слэшей в путях, которое понимают все системы (по крайней мере, в С++). обратный слэш - чисто вендозная шняга, поэтому его использование в кроссплатформенном программировании должно быть исключено.


Эмм.. да, пути к у-вам типа "//./" допустимы и в Windows. НО! Внутри виндовых API они преобразуются в "\\\\.\\"
(по крайней мере об этом упоминается маленькими буковками в MSDN).

НО, в WinCE при задании ком-портов необходимо писать COM1: ... COMn:.

Поэтому ну никак нельзя принять "//./" как кросс-платформенное решение. :)

Кстати, в Qt 5.4.1 баг с путями (для QtSerialPort) типа "//./" пофикшен.

человек,
Цитата
Класс называется QSerialDevice, тогда логично использовать с помощью него для символьных устройсв. Но когда используешь open, класса AbstractSerial, реузльтат false. Это из-за того что символьные устройства не используют настройки типа baud и т.д... Это решаемо...
Вопрос в другом, если все же поправить исходники что бы символьное устройство можно было открыть, то что делать с сигналами readyRead() они постоянно валят.... есть данных или нет. Или что нужно учесть в символьном стройстве для этого?


Не использовать QSerialDevice, а использовать QtSerialPort.
человек
Цитата(kuzulis @ 4.12.2014, 18:51) *
Не использовать QSerialDevice, а использовать QtSerialPort.

у меня есть ограницения по использованию Qt 4.6. QtSerialPort использует 4.8 или 5 версию
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.