Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: QSerialDevice - Библиотека для работы с COM-портами
Форум на CrossPlatform.RU > Административный > Crossplatform.ru - все о нем > Обсуждение исходников с сайта
Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9
Litkevich Yuriy
Цитата(igor_bogomolov @ 19.9.2012, 12:11) *
RS422 обеспечивает соединение точка-точка (в полном дуплексе). RS485 точка-многоточие (полудуплексная передача), RS485-4w точка-многоточие (в полном дуплексе).
RS422 != 2 канала RS485.
это лишь реализация и на логическом уровне. Возьми к примеру BitBus, синхронный режим, там как раз RS-422, по одному каналу гонятся данные, по другому синхросигнал.
mmsd
Добрый день. Необходимо отправлять данные в COM порт допустим каждую секунду. И соответсвенно получать ответную информацию. С приемом проблем не возникло благодаря http://robocraft.ru/blog/544.html. Интересует вопрос организации непрерывной отправки команд. Использовать потоки?
kuzulis
Цитата(mmsd @ 14.1.2013, 13:51) *
Интересует вопрос организации непрерывной отправки команд. Использовать потоки?


Нет, QTimer. Также вместо QSerialDevice лучше использовать QtSerialPort

RazrFalcon
А багтрекер есть?

У меня на мак не удается получить инфу об устройстве, только portName. Все остальные поля доступные в QtSerialPortInfo пустые. На win и linux норм.
Мак 10.8.
QtSerialPort из гита, вчерашний.
Устройство - FTDI.
kuzulis
Цитата(RazrFalcon @ 22.2.2013, 15:09) *
А багтрекер есть?


Да, есть. См. Отслеживание ошибок
RazrFalcon
Это видел. Думал есть отдельный.

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

В догонку.
Можно ли как то отловить что устройство отключили/выдернули?
kuzulis
Цитата(RazrFalcon @ 23.2.2013, 16:59) *
Это видел. Думал есть отдельный.

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

Блин, только что проверил на 10.6.8 в виртуалке с чипом PL2303 - все работает.
Можешь пройтись отладчиком сам и поглядеть что там да как?

Например, открой пример enumerator и слинкуй его статически с библиотекой:

1. Подправь enumerator.pro

удали:
greaterThan(QT_MAJOR_VERSION, 4) {
    QT       += widgets serialport
} else {
    include($$QTSERIALPORT_PROJECT_ROOT/src/serialport/qt4support/serialport.prf)
}

и всесто этого добавь:
include(../../../qtserialport/src/serialport/serialport-lib.pri)


2. При компиляции будет ругаться что не найдены

#include <QtSerialPort/QSerialPortInfo>

и т.п., просто замени на:
#include "qserialportinfo.h"

и т.п.

3. Добавь в баг-трекере типы используемых USB/Serial конвертеров с которыми не работает.


Цитата(RazrFalcon @ 23.2.2013, 16:59) *
В догонку.
Можно ли как то отловить что устройство отключили/выдернули?

Просто так - Нет.

Можно только если оно до этого порт был открыт и в этот момент выделнули,
тогда выстрелит сигнал ResourceError.
RazrFalcon
Ок. Сегодня попробую.

Цитата
Можно только если оно до этого порт был открыт и в этот момент выделнули, тогда выстрелит сигнал ResourceError.

Да, устройство открыто. Сигнала такого не нашел. Он в QSerialPort?
RazrFalcon
Не совсем понял что дебагить то...
Надел пару скринов на всякий случай:
kuzulis
Цитата(RazrFalcon @ 24.2.2013, 16:53) *
Да, устройство открыто. Сигнала такого не нашел. Он в QSerialPort?


Есть такой код ошибки ResourceError. Вот он и должен выстрелить.
Хотя в MacOSX это не проверялось, т.к. ни у кого нет MacOSX :)

Цитата(RazrFalcon @ 24.2.2013, 16:53) *
Не совсем понял что дебагить то


Ну, пройтись по этим всем строчкам и посмотреть, находит ли оно вообще что-то,
каунтеры все по нулям?

Важно от тебя получить это:
1. Вообще, имена портов находит или тоже пустые все?
2. Если находит, то запусти в MacOSX утилиту типа IORegistryExplorer или как-то так
называться должна (естественно, твой шнурок должен быть втыкнут).
Эта йтилита "стандартная" находится в папке Applications или Utils в директории с XCode.
Так вот, эта утилита должна показать все зарегистрированные устройства, в том числе и твой FTDI
шнурок. Ты там просмотри ветки в USB на предмет наличия твоего девайса, плюс на предмет наличия там VID/PID
и т.п. И если найдешь - то приложи скрины всех этих веток от твоего девайса до его корневого USB хаба.

UPD:

И кстати, этот макрос:

#if defined(MAC_OS_X_VERSION_10_4) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4)
#  include <IOKit/serial/ioss.h>
#endif


корректно в 10.8 обрабатывается? ioss.h Реально подключается?
RazrFalcon
В qserialportinfo_mac.cpp начиная с:
87: while ((service = ::IOIteratorNext(iter))) {
Все что внутри прошелся дебагом. Все значения всегда были 0 и не менялись (все что я писал в багрепорте).
То есть не конвевртация в Qt типы фейлиться, он и не забирает ничего.

Имена портов есть. Инфо - нету.

IORegistryExplorer не нашел нигде. Вот такое есть:


Макрос работает. По крайней мере ошибок не было.
Разве что примеры не собираются. Либу не находят. Приходится в сам app/Content/Mac (или Framework) переносить.

По поводу перехвата отключения устройства:
connect(port, SIGNAL(error(QSerialPort::SerialPortError)),
            this, SLOT(onError(QSerialPort::SerialPortError)));

сигналы вообще никакие не приходят.
kuzulis
Цитата(RazrFalcon @ 24.2.2013, 21:54) *
IORegistryExplorer не нашел нигде.


Тут должно быть:

Developer->Applications->Utilities->IORegistryExplorer

По крайней мере в 10.6.8. оно есть, но для этого должен XCode стоять.
Хотя вроде где-то слышал, что в новом XCode эппловцы потихоньку стали удалять эти утилиты..

UPD:

Цитата
сигналы вообще никакие не приходят.


Не, не правда, в старой версии должен был приходить UnknownError.
Теперь я исправил поведение и должно быть ResourceError,
см. патч тут:

https://codereview.qt-project.org/#change,48847

Повторю еще раз: Для этого порт должнен был быть открыт, иначе ничего не поймаешь.
Также, когда ловишь ResourceError - то должен закрыть порт, иначе может быть вечный event-loop
и все повиснет.
RazrFalcon
Да. Делаю коннект. Открываю порт. Выдергиваю устройство. Слот не вызывается в принципе.

Про закрытие ясно. Сделаю.


Утилиту завтра поищу.
kuzulis
Цитата(RazrFalcon @ 25.2.2013, 3:34) *
Да. Делаю коннект. Открываю порт. Выдергиваю устройство. Слот не вызывается в принципе.


Блин, да не может быть. Неужели для Мака настолько разное поведение от версии к версии и от типа чипа?

Тогда продебаж, как я поветовал выше, но только пример Terminal.

1. Добавь в qserialport_unix.cpp код:

QSerialPort::SerialPortError QSerialPortPrivate::decodeSystemError() const
{
    ...
    int r = errno;
    switch (r) {
    ...
    }
}


и пересобери.

2. Воткни шнурок
3. Запусти пример Terminal его в дебаге
4. Добавь брекпойнты на:

- int r = errno; (то что ты исправил)
- readFromPort()
- ExceptionNotifier::event() (на ret = QSocketNotifier::event(e); )
- ReadNotifier::event() (на ret = QSocketNotifier::event(e); )

5. Открой твой FTDI порт и потом выдерни его.


Приведи результаты:

- сработает ли ReadNotifier при выдергивании?
- сработает ли ExceptionNotifier при выдергивании?
- какой код вернет errno после readFromPort() в decodeSystemError() ?
(естественно этот код возможен только после срабатывания ReadNotifier).
RazrFalcon
Цитата
- сработает ли ReadNotifier при выдергивании?
сработал, true

Цитата
- readFromPort()
сработал, bytesRead = -1

Цитата
- сработает ли ExceptionNotifier при выдергивании?
сработал
UnknownError.
Цитата
- какой код вернет errno после readFromPort() в decodeSystemError() ?
тоже -1

все происходит дважды, и оба раза одно и тоже



Цитата
Developer->Applications->Utilities->IORegistrExplorer
у меня в Applications только Qt.
XCode и остальное установлено.
kuzulis
Цитата(RazrFalcon @ 26.2.2013, 23:12) *
UnknownError.


Но а какой errno то? Нужен именно код errno!!!

Цитата
у меня в Applications только Qt.
XCode и остальное установлено.


Без этой утилиты невозмоно пофиксить этот баг, т.к. непонятно
в каких ветках макового словаря (или как там его) лежит требуемая инфа.

Ну значит яблоководы удалили эту утилиту из новых XCode.
Попробуй найти где нить эту утилиту, если тебе еще нужно чтобы пофиксили баг. :)

ЗЫ:
У тебя какая версия XCode?
RazrFalcon
errno вроде бы 6, сегодня еще раз проверю. У меня только удаленка к этому компу есть.

XCode скорее всего самый новый. Комп не мой...
kuzulis
Цитата(RazrFalcon @ 27.2.2013, 17:46) *
errno вроде бы 6, сегодня еще раз проверю. У меня только удаленка к этому компу есть.


Если код #6 - то это уже пофикшено с сигналом ResourceError, обновись.

Цитата(RazrFalcon @ 27.2.2013, 17:46) *
XCode скорее всего самый новый. Комп не мой...


А вот с этим будет проблема, т.к. нужен IORegistryExplorer.
RazrFalcon
Потестил на новой версии:

ReadNotifier - true

readFromPort:
bytesRead = -1
maxSize = 512

decode...:
r = 0

и так дважды с одинаковыми результатами



kuzulis
Цитата(RazrFalcon @ 27.2.2013, 22:35) *
Потестил на новой версии:

ReadNotifier - true

readFromPort:
bytesRead = -1
maxSize = 512

decode...:
r = 0

и так дважды с одинаковыми результатами


Вот блин засада :blink: , п#*дец какой-то с этим маком, ты уверен что errno == 0 ? :blink:

А можешь поставить брек-пойнт непосредственно внутри readFromPort() на
bytesRead = ::read(descriptor, data, maxSize); // << тут брекпойнт поставь
qDebug() << "errno: " << errno; // << это добавь в код

?

UPD: За скрин спасибо, буду смотреть.
---
Посмотрел на скрин и вижу, что немного не то ты показал.

Надо так: выбери в верхнем-левом углу (в комбобоксе) утилиты вместо IOUSB -> IOService,
также и в нижнем комбобоксе тоже начиналось с IOService.

И приведи все результаты по всем веткам , например, нужны такие ветки
как у меня от "USB-Serial Controller@9f300000" и вниз до "IOSerialBSDClient"

http://www.imageup.ru/img201/1229412/pl2303.jpg.html
RazrFalcon
Наскринил по максимуму:


kuzulis
О, спасибки за скрины.

Но все-таки есть непонятный момент: у тебя на скринах сразу после read()
errno равен 6, но после readFromPort() он равен 0?

Так ли это или 0 - это просто ты ошибся? Можешь еще раз проверить errno после readFromPort()
в методе decodeSystemError() ?
RazrFalcon
kuzulis
О! Спасибо! Теперь понятно насчет ошибки с кодом 0.

Теперь что касается определения VID/PID и т.п..

Попробуй пожалуйста сделать по очереди некоторые
изменения в qserialportinfo_mac.cpp в методе availablePorts()
в ф-ю

    ::CFDictionaryAddValue(matching,
                           CFSTR(kIOSerialBSDTypeKey),
                           CFSTR(kIOSerialBSDAllTypes));


вместо kIOSerialBSDAllTypes попробуй по очереди заменить на

kIOSerialBSDModemType

, пересобрать, запустить и проверить, появятся ли VID/PID,
а потом заменить на

kIOSerialBSDRS232Type

и снова проверить. Отпишись плз. о резульатах.
RazrFalcon
c kIOSerialBSDModemType определило только блютзу и все, остальные 2-а устройства вообще пропали, в enumerator

c kIOSerialBSDRS232Type нашло 2-а из 3-х, все определилось
kuzulis
Цитата(RazrFalcon @ 28.2.2013, 23:40) *
c kIOSerialBSDModemType определило только блютзу и все, остальные 2-а устройства вообще пропали, в enumerator

c kIOSerialBSDRS232Type нашло 2-а из 3-х, все определилось


1. Так, стоп, а какое третье у-во? Как я понял, есть блютус, FTDI, а третье какое?

2. Текущий вариант kIOSerialBSDAllTypes тоже определяет два у-ва, только за исключением FTDI?


RazrFalcon
Вот, я кидал до этого. Это с kIOSerialBSDAllTypes
kuzulis
Цитата(RazrFalcon @ 1.3.2013, 13:47) *
Вот, я кидал до этого. Это с kIOSerialBSDAllTypes


А можешь дать удаленный доступ к Mac компу, например через TeamViever?

Естественно, коды доступа мне в личку..
RazrFalcon
Я и сам через TeamViever цепляюсь. Комп не мой. А заказчика, скажем так. По этому вряд ли. Увы.
kuzulis
Цитата(RazrFalcon @ 1.3.2013, 16:14) *
Я и сам через TeamViever цепляюсь. Комп не мой. А заказчика, скажем так. По этому вряд ли. Увы.


Ок. Тогда можешь проверить фикс для бага с errno,
тут: https://codereview.qt-project.org/#change,49405

?

Теперь decodeSystemError() сбрасывает код ошибки?
RazrFalcon
Выдергивание устройства детектится.
kuzulis
Цитата(RazrFalcon @ 2.3.2013, 1:23) *
Выдергивание устройства детектится.


Ок, тогда я этот патч представляю для ревью.

Теперь другой вопрос по другим твоим девайсам типа блютуса и т.п.

Я на скринах вижу, что для FTDI детектится описание, VID/PID и т.п.,
а вот для блютуса везде пусто..

Так вот вопрос: а утилита IORegistryExplorer видит какие нить VID/PID и т.п.?

RazrFalcon
Гляну. Но по-моему это какие-то виртуальные устройства мака. Я к ним даже подключиться не могу.

Сегодня проверю инфу у блютуза.
RazrFalcon
Его вообще нет в том списке...
Все что нашел:
RazrFalcon
А как работает смена скорости? Нужно ли переподключатся или можно на лету менять.

А то, опять же на маке, прибор не отвечает на нужной скорости.

Выглядит это приблизительно так:
1) Конектимся к устройству.
2) Ставим скорость 56700
3) Работаем, работаем
4) Меняем скорость и посылаем прибору команду на новой скорости.
5) Ответа нет

А если сразу ставим нужную скорость, а не 56700, и сразу посылаем эту саму команду - то все норм.
То есть смена скорости работает только после рестарта проги.
kuzulis
Цитата(RazrFalcon @ 4.3.2013, 0:36) *
А как работает смена скорости? Нужно ли переподключатся или можно на лету менять.

А то, опять же на маке, прибор не отвечает на нужной скорости.

Выглядит это приблизительно так:
1) Конектимся к устройству.
2) Ставим скорость 56700
3) Работаем, работаем
4) Меняем скорость и посылаем прибору команду на новой скорости.
5) Ответа нет

А если сразу ставим нужную скорость, а не 56700, и сразу посылаем эту саму команду - то все норм.
То есть смена скорости работает только после рестарта проги.


Должно на лету работать.
А как твое у-во определяет то, что ему пришла команда уже на другой скорости?

Дай минимальный проект который проблему воспроизводит.

ЗЫ:
Также запости баг, о котором ты говорил ранее про невозможность установки в Маке, типа там где ты что-то вручную копируешь,
или как то так.


---

UPD: И кстати, а можешь в коде заменить
    ::CFDictionaryAddValue(matching,
                           CFSTR(kIOSerialBSDTypeKey),
                           CFSTR(kIOSerialBSDAllTypes));

на
    ::CFDictionarySetValue(matching,
                           CFSTR(kIOSerialBSDTypeKey),
                           CFSTR(kIOSerialBSDAllTypes));


И попробовать снова?
RazrFalcon
Ну значит баг. Так как не меняет... Прибору можно вручную задать скорость. На самом приборе.

Хотел запостить баг сборки/линковвки. Теперь вообще не собирается. Версия из git. Текущая.

http://pastebin.com/7CKn3zeb
kuzulis
Цитата(RazrFalcon)
Ну значит баг. Так как не меняет... Прибору можно вручную задать скорость. На самом приборе.


Блин, ну ты пример приведи минимально компилябельный где оно реально не меняет скорость.

Цитата(RazrFalcon)
Хотел запостить баг сборки/линковвки. Теперь вообще не собирается. Версия из git. Текущая.

http://pastebin.com/7CKn3zeb


Да не может быть.
Скорее всего у тебя линкуется старая либа, где нет QSerialPort::setPortName(QString const&),
т.к. setPort(..) заменили на setPortName(..).

--

Оопс, сорри реально есть такой касяк... О_о - хз как оно с setPortName вышло..
По ходу что-то профукалось после переезда из Playground в /qt5.1.


И не забудь проверить с CFDictionarySetValue() - заработает енумератор или нет.
RazrFalcon
Так какой пример?

    port->setPort(text);
    if (port->open(QIODevice::ReadWrite)) {
        port->setBaudRate(QSerialPort::Baud57600);
        port->setDataBits(QSerialPort::Data8);
        port->setParity(QSerialPort::NoParity);
        port->setFlowControl(QSerialPort::NoFlowControl);
        qDebug() << "connected to:" << port->portName() << port->baudRate();
        connect(port, SIGNAL(error(QSerialPort::SerialPortError)),
                this, SLOT(onError(QSerialPort::SerialPortError)));
        return true;
    }

...
port->write("blah-blah"); // работаем с устройством
// приходит ответ на readyRead

// потом в какой-то момент
        port->setBaudRate(QSerialPort::Baud9600);
// снова
port->write("blah-blah");
// ответов уже нет




2) я ж написал. Собирал из гита. Никаких левых либ.
UPD: ясно
kuzulis
Цитата(RazrFalcon @ 4.3.2013, 13:56) *
Так какой пример?


1. Эмм. а ты проверяешь на реткоды для port->setBaudRate()?
Может оно фейлится.

2. И еще надо учесть, чтобы в момент setBaudRate() не было никакого I/O,
т.к. оно асинхронное и может что-то передавать/принимать в этот момент,
поэтому ХЗ как оно там себя поведет.

Цитата
2) я ж написал. Собирал из гита. Никаких левых либ.
UPD: ясно

Блин, это проблема у тебя при сборке! Ты сначала удали предыдущую установленную версию с Мака,
т.к. он берет заголовок от старой версии. :)
RazrFalcon
1) возвращает true. Пробовал спрашивать baud текущий после смены + пауза - пишет верный. Но прибор не отвечает на команду. Хотя write возвращает нужное количество байт.
2) та вроде нету...
3) либа не установлена, буду думать. UPD: gitorious лежит...
4) Еще такой вопрос по waitForReadyRead(). Как я понимаю: оно блочит текущую функцию на заданное время, и если ответ есть, то пропускает дальше и сразу после нее можно вызывать readAll? А ели закончилось время, то возвращает false?
kuzulis
Цитата(RazrFalcon)
1) возвращает true. Пробовал спрашивать baud текущий после смены + пауза - пишет верный. Но прибор не отвечает на команду. Хотя write возвращает нужное количество байт.

Ну, тут ХЗ, надо разбираться с прибором.
Проверь в линухе или на винде как оно будет работать...

Цитата(RazrFalcon)
3) либа не установлена, буду думать. UPD: gitorious лежит...

Я тоже решил это проверить и такую же ошибку поймал как у тебя при сборке.
Но оказалось, что оно берет qserialport.h из директории с установленной Qt куда я ранее
устанавливал старую версию QtSerialPort и забыл про это.
Но после удаления всех старых заголовков и либ из Qt - все заработало.

Цитата(RazrFalcon)
4) Еще такой вопрос по waitForReadyRead(). Как я понимаю: оно блочит текущую функцию на заданное время, и если ответ есть, то пропускает дальше и сразу после нее можно вызывать readAll? А ели закончилось время, то возвращает false?


Да, оно блочит и если данные приходят (хотя бы один байт) - то оно читает их во внутренний буфер и возвращает true.
Поэтому дальнейший вызов readAll() вернет содержимое этого внутреннего буфера. Если данных так и нету за таймаут -
то вернет false.
RazrFalcon
Ясно.

Так waitForReadyRead() сработает после первого же байта и readAll() вернет 1-н байт? Или полную команду, все байты?
kuzulis
Цитата(RazrFalcon @ 4.3.2013, 15:44) *
Ясно.

Так waitForReadyRead() сработает после первого же байта и readAll() вернет 1-н байт? Или полную команду, все байты?


Минимум один байт.

Но вообще, читается пачками по 512 байт.
И если на данный момент успело придти 10 байт - то прочтет 10,
если только один - то один.

Т.е. зависит от драйвера, ОС и т.п.
RazrFalcon
Ага, ну то есть так же, если бы я делал readAll в слоте readyRead. Это хорошо.

Остальное вечером проверю, когда будет доступ.
kuzulis
Цитата(RazrFalcon @ 4.3.2013, 15:51) *
Ага, ну то есть так же, если бы я делал readAll в слоте readyRead. Это хорошо.


Да, именно так.

Цитата(RazrFalcon @ 4.3.2013, 15:51) *
Остальное вечером проверю, когда будет доступ.


Ок, жду твоих тестов
RazrFalcon
Установка CFDictionarySetValue ничего не поменяла.
Инфа не появилась.

Скорости меняются. Был баг в ответе прибора. Отбой.
kuzulis
Принято.

Насчет енумерации будем думу думать, я там вчера в трекере ввел
Laszlo в курс дела - может что и придумаем. Но пока - увы, жди. :)
RazrFalcon
Да я себе с R232 собрал и норм.
RazrFalcon
Запостил баг со сборкой.

https://bugreports.qt-project.org/browse/QTPLAYGROUND-20
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.