Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: QSerialDevice - Библиотека для работы с COM-портами
Форум на CrossPlatform.RU > Административный > Crossplatform.ru - все о нем > Обсуждение исходников с сайта
Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9
niklep
Прошу прощения, косяк был мой (стоило ожидать=)). просто я не в том месте делал привязку:
connect(temp_com->port, SIGNAL(readyRead()), this, SLOT(slotReadCom()));
kuzulis
Цитата(niklep @ 22.5.2011, 19:59) *
Прошу прощения, косяк был мой (стоило ожидать=)). просто я не в том месте делал привязку:
connect(temp_com->port, SIGNAL(readyRead()), this, SLOT(slotReadCom()));

Понятно. :)

Значит можешь не отвечать на мои сообщения на gitorious.org .
devnir
Здравствуйте, перечитал практически всю тему. Собственно читать то начал из-за своей проблемы:
работаю с AbstractSerial, собственно из под Linux - все хорошо и прекрасно. а вот в маст дае (Win) начинают "теряться" байты данных.
Ну собственно сам код:
Port = new AbstractSerial(this);
#if defined (Q_OS_UNIX)
    portNameStr = "/dev/ttyUSB0";
#elif defined (Q_OS_WIN)
    portNameStr = "COM1";
#endif


инициализация и открытие:
    Port->setDeviceName(Pname);
    if (Port->open(AbstractSerial::ReadWrite | AbstractSerial::Unbuffered)){

        if (!Port->setBaudRate(AbstractSerial::BaudRate115200)) {
        };
        if (!Port->setDataBits(AbstractSerial::DataBits8)) {
        };
        if (!Port->setParity(AbstractSerial::ParityNone)) {
        };
        if (!Port->setStopBits(AbstractSerial::StopBits1)) {
        };
        if (!Port->setFlowControl(AbstractSerial::FlowControlOff)) {
        };

#if defined (Q_OS_UNIX)
        if (Port->openMode() & AbstractSerial::Unbuffered)
            Port->setCharIntervalTimeout(10000);//5 msec
#elif defined (Q_OS_WIN)
        if (Port->openMode() & AbstractSerial::Unbuffered)
            Port->setTotalReadConstantTimeout(100);
#endif

#ifdef __Debug__
        dbg("Port Opened, timeout: %d\n", Port->charIntervalTimeout());
#endif
        connect(Port, SIGNAL(readyRead()), this, SLOT(slotReadPort()));
        return true;
    }
    else
    {
#ifdef __Debug__
        dbg("Port not OPENED!!! \n");
#endif
        return false;
    }



slotReadPort()
{
    QByteArray tmpBuff;
    quint64 len = Port->bytesAvailable();
    tmpBuff = Port->read(len);
    for(int i =0; i< tmpBuff.length(); i++)
    {
        dbg("0x%02X ", tmpBuff.at(i)&0xff);
        pRead(tmpBuff.at(i)&0xff);
    }
}


использую для пересылки файла через порт. Алгоритм простой как двери. отправил сообщение - получил подтверждение что со стороны приемника часть файла получена (0xAA)- отправил следующую часть(F_LEN = 4096 + 4 байта) с небольшой задержкой:
pRead(char c)
{
                if (c==0xAA) {
                    serial_timer.start(TR_WAIT);
                }
}


slotTimeout()
{
            if (offset >= file_data.size())
                return;

            this->Port->write(file_data.constData()+offset, F_LEN);
                offset+=F_LEN;
}


Собственно где я что упустил ? Есть идеи? Писал и отлаживал в Linux, вот понадобилось собрать под винду. собрал - а работает не корректно. примерно на пересылке 2-3 го блока все зависает :( из за того что не получена квитанция о пересылке предыдущего куска.
kuzulis
Попробуй пройтись сниффером типа free-serial-port-monitor на предмет того, а шлет ли клиент вообще 0хAA ?!
А также выложи минимальные компилябельные проекты "клиента<->сервера" в которых воспроизводится данная проблема.
devnir
Да мне кажется там просто переполнение идет буферов порта у винды. - рвется пакет который отправляется - ну а приемник собственно проверяет ЦРЦ свертку - которая не сходится - нет АА.

Проверил примерно так:
файл для передачи: нарезал на 4096 байт + 4байта ЦРЦ32. получил 4100 байт массива который передал кусками (с задержкой в 1 сек.) по 205 байт.
Покурил - сделал кофе - вернулся, пол файла передало. но ошибок нет.
Теперь вот думаю примерно какой кусок и с какой задержкой посылать - что бы не переполнить какуют там ФиФошку. Еще угнетает то что QT в виртуалке да еще и статической сборки. Проэкт линкуется минут 15 :(

Насчет снифера - то я уже мониторил. Собственно и дошел до того что ошибка именно в переполнении буферов винды(сервер) - так как порт начинал работать криво - терял байты. хотя с другой стороны(клиент) мониторя - я точно уверен в отправке сообщения, так как там такой же снифер стоял.
kuzulis
Цитата
файл для передачи: нарезал на 4096 байт + 4байта ЦРЦ32. получил 4100 байт массива который передал кусками (с задержкой в 1 сек.) по 205 байт.
Покурил - сделал кофе - вернулся, пол файла передало. но ошибок нет.

Попробуй тогда открывать порт в буферизованном режиме, т.е не использовать флаг Unbuffered (тут можно передавать неограниченное кол-во байт) и убрать вообще код где используются таймауты и т.п.
т.е смотри примеры в /test/guiapp(guiapp2)

ЗЫ:
А так - да, если читаешь из порта (открытого с флагом Unbuffered , как у тебя сейчас) то нужно использовать метод waitForReadyRead() , и т.п извращаться,
т.к. лимит по умолчанию в драйвере винды на 4096 байт (если не ошибаюсь) и нужно постоянно читать данные для того чтобы буфер драйера не переполнился.

В общем, используй буферизованный режим и будет всё ок.
Алексей1153
Извиняюсь, что вклиниваюсь, но, по-моему, я совсем только что по таким граблям прошёл ) Дело было с драйвером фирмы FTDI, преобразователь USB<->COM

на небольших скоростях всё было хорошо, но когда прибор стал валить в USB порт очень толстый поток данных, драйвер стал подглючитваь и зависать. В конце концов всё решилось так: в отдельном потоке раз в 1 мс (при помощи мультимедийного таймера) вытаскиваю все данные в буфер (размер я могу, конечно же, задать произвольный. Это - рассчитать, сколько нужно). Если буфер переполняется, то новые данные откидываю - иначе у драйвера крышу сносит. В основном потоке по обычному виндовому таймеру выделяю осмысленные куски данных и вычищаю их из буфера. Естественно, операции работы с буфером - через критическую секцию.

Уже 4 дня после этих исправлений полёт нормальный, тьфу, тьфу, тьфу
good835
Добрый день!
После изменений в классе SerialDeviceEnumerator (SerialDeviceEnumerator reimplemented as a singleton.) программа стала подвисать при создании объекта класса (пример quiapp)
    if (!this->enumerator)
        this->enumerator = SerialDeviceEnumerator::instance();

грузит процессор сервис Service Control Manager (SCM) (\Windows\System32\Services.exe) - под 100% - идет поиск устройств?
после того как сервис отработает появляется окно программы. До изменений такой проблемы не было, с чем это может быть связано?
ОС: WindowsXP, QT 4.7.1. mingw
kuzulis
2 good835

Да не должно грузить, т.к. в принципе ничего не изменилось (кроме того что теперь SerialDeviceEnumerator является одиночкой).

Я только что проверил : у меня приложение /gui/test, собранное в релизе,
не подвисает (ну, загружает, процентов на 30% - но не на 100 как у вас.).

В принципе, это нормально, любые иные приложения тоже при старте грузят процессор.

ЗЫ: Хотя, может быть, это связано с тем, что вы в конструкторе выполняете метод: isBusy() ?
И если ДА - то может из-за него проблемы, т.к. если порт открыт и метод пытается его опять открыть - то этот процесс тормозит N-ное кол-во времени.
good835
2 kuzulis

Разобрался я, почему грузит процессор. Как и предполагалось проблема была в методе SerialInfoMap SerialDeviceEnumeratorPrivate::updateInfo() const
   
static const ::GUID guidArray[] =
{
    /* Windows Ports Class GUID */
    { 0x4D36E978, 0xE325, 0x11CE, { 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 } },
    /* Virtual Ports Class GUIG (i.e. com0com, nmea and etc) */
    { 0xDF799E12, 0x3C56, 0x421B, { 0xB2, 0x98, 0xB6, 0xD3, 0x64, 0x2B, 0xC8, 0x78 } },
    /* Windows Modems Class GUID */
    { 0x4D36E96D, 0xE325, 0x11CE, { 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 } }
};
   int guidCount = sizeof(guidArray);
   for (int i = 0; i < guidCount; ++i) {

       ::HDEVINFO DeviceInfoSet = ::SetupDiGetClassDevs(&guidArray[i],
                                                        0,
                                                        0,
                                                        DIGCF_PRESENT);
  ....

Собственно говоря ошибка была в определении длины цикла guidCount, что и приводило к некорректной работе при поиске инфо об устройстве. Должно быть так:
   int guidCount = sizeof(guidArray)/sizeof(::GUID);
kuzulis
Спасибо! Исправил.
Алексей1153
а так красивше :)

int guidCount = sizeof(guidArray)/sizeof(*guidArray);
universeroot
Сегодня написал с применением этой библиотеки:

http://robocraft.ru/blog/544.html
kuzulis
Цитата(universeroot @ 13.6.2011, 21:06) *
Сегодня написал с применением этой библиотеки:

http://robocraft.ru/blog/544.html


О, зачетненько! :clapping:

Только если библиотека линкуется статически (а по умолчанию она статически линкуется), то нет нужды её куда-то копировать (а также копировать заголовки).
Также можно было её подключать "напрямую" к проекту чтобы не заморачиваться с копированием (см. примеры в /test/guiapp).
:)
grio
Объясните пожалуйста, как правильно инсталлировать
библиотеку QSerialDevice и прикрутить ее к проекту в Линуксе.
kuzulis
Цитата(grio @ 1.7.2011, 14:40) *
Объясните пожалуйста, как правильно инсталлировать
библиотеку QSerialDevice и прикрутить ее к проекту в Линуксе.

А по умолчанию не нужно её никуда инсталлировать.
Она является статической и линкуется с приложением,
т.е. её код встраивается в код приложения.

Можете использовать её классы напрямую, как в примере /test/quiapp
grio
Цитата(kuzulis @ 1.7.2011, 16:47) *
Цитата(grio @ 1.7.2011, 14:40) *
Объясните пожалуйста, как правильно инсталлировать
библиотеку QSerialDevice и прикрутить ее к проекту в Линуксе.

А по умолчанию не нужно её никуда инсталлировать.
Она является статической и линкуется с приложением,
т.е. её код встраивается в код приложения.

Можете использовать её классы напрямую, как в примере /test/quiapp


В моем случае, оказалось, что просто не хватало пакета libudev-dev.
Продолжаю эксперименты, спасибо.
shurilnik
kuzulis, Здравствуйте. Решил попробовать использовать вашу библиотеку на embedded девайсе mini2440 под linux. Столкнулся с проблемой что serialdeviceenumenator начинает грузить проц на 100% после того как в системе появляется или исчезает (если было включено до запуска конструктора класса) ttyUSB устройство. Звук непрерывно воспроизводимый прерывается 2-3 раза в секунду, независимо уже после этого появилось еще устройство или исчезло. Т.е. какой-то метод класса в периодом условно в миллисекунд 300 что-то делает что серьезно грузит процессор, а в остальное время приоритет операции пониже, но все равно грузит. Подскажите пожалуйста куда копать.
Если подключится straceом к процессу то после подключения устройства начинают с большой скорость проскакивать вот такие операции:
readlink("/sys/devices/virtual/tty/tty42/subsystem", "../../../../class/tty"..., 1024) = 21
lstat64("/dev/.udev/db/tty:tty42", {st_mode=S_IFLNK|0777, st_size=15, ...}) = 0
readlink("/dev/.udev/db/tty:tty42", "tty42 char/4:42"..., 1024) = 15
readlink("/sys/devices/virtual/tty/tty43", 0xbed2c680, 1024) = -1 EINVAL (Invalid argument)
stat64("/sys/devices/virtual/tty/tty43/uevent", {st_mode=S_IFREG|0644, st_size=4096, ...}) = 0
open("/sys/devices/virtual/tty/tty43/uevent", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 21
fstat64(21, {st_mode=S_IFREG|0644, st_size=4096, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x4001f000
read(21, "MAJOR=4\nMINOR=43\nDEVNAME=tty43\n", 4096) = 31
read(21, "", 4096) = 0
close(21) = 0
munmap(0x4001f000, 4096) = 0
readlink("/sys/devices/virtual/tty/tty43/subsystem", "../../../../class/tty"..., 1024) = 21
lstat64("/dev/.udev/db/tty:tty43", {st_mode=S_IFLNK|0777, st_size=15, ...}) = 0
readlink("/dev/.udev/db/tty:tty43", "tty43 char/4:43"..., 1024) = 15
readlink("/sys/devices/virtual/tty/tty44", 0xbed2c680, 1024)usb 1-1.2: USB disconnect, address 3
ftdi_sio ttyUSB0: FTDI USB Serial Device converter now disconnected from ttyUSB0
ftdi_sio 1-1.2:1.0: device disconnected
= -1 EINVAL (Invalid argument)
stat64("/sys/devices/virtual/tty/tty44/uevent", {st_mode=S_IFREG|0644, st_size=4096, ...}) = 0
open("/sys/devices/virtual/tty/tty44/uevent", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 21
fstat64(21, {st_mode=S_IFREG|0644, st_size=4096, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x4001f000
read(21, "MAJOR=4\nMINOR=44\nDEVNAME=tty44\n", 4096) = 31
read(21, "", 4096) = 0
close(21) = 0
munmap(0x4001f000, 4096) = 0
readlink("/sys/devices/virtual/tty/tty44/subsystem", "../../../../class/tty"..., 1024) = 21
lstat64("/dev/.udev/db/tty:tty44", {st_mode=S_IFLNK|0777, st_size=15, ...}) = 0
readlink("/dev/.udev/db/tty:tty44", "tty44 char/4:44"..., 1024) = 15
readlink("/sys/devices/virtual/tty/tty45", 0xbed2c680, 1024) = -1 EINVAL (Invalid argument)
stat64("/sys/devices/virtual/tty/tty45/uevent", {st_mode=S_IFREG|0644, st_size=4096, ...}) = 0
open("/sys/devices/virtual/tty/tty45/uevent", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 21
fstat64(21, {st_mode=S_IFREG|0644, st_size=4096, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x4001f000
read(21, "MAJOR=4\nMINOR=45\nDEVNAME=tty45\n", 4096) = 31
read(21, "", 4096) = 0
close(21) = 0
munmap(0x4001f000, 4096) = 0

причем номер и тип tty постоянно меняется...
Или может это нормальное поведение ?
Заранее спасибо.
kuzulis
2 shurilnik,

я даже и не знаю что посоветовать.

Что первое приходит на ум, так это - попробуйте скачать master ветку:

https://gitorious.org/qserialdevice/qserial...ce/trees/master

Цитата
Столкнулся с проблемой что serialdeviceenumenator начинает грузить проц на 100% после того как в системе появляется или исчезает (если было включено до запуска конструктора класса) ttyUSB устройство.

Это если используется только класс SerialDeviceEnumenator (и не используется AbstractSerial) такое поведение? Или как?

Иначе:
Такое может быть если Вы, используя класс AbstractSerial, открыли порт и выдернули его.
В этом случае QSocketNotifier будет вечно гнать евенты (почему-то такое поведение у функции select()).
т.е. может быть, начинает срабатывать вечно exceptionNotifier или readNotifier (см. nativeserialnotifier_unix.cpp).
Если это так - то я в курсе этой проблемы, но пока не могу найти решения,
т.к. правильным решением является принудительное закрытие дескриптора выдернутого порта при возникновении такой ситуации.
Но вот как отличить Exception/Read событие вызванную какой-либо другой причиной от Exception/Read события вызванной выдергиванием порта - я не знаю.

PS: Если используете AbstractSerial и вам не нужны уведомления о сигналах RTS/DTR/CTS и пр. то можете в
nativeserialnotifier_unix.cpp закомментировать всё что запускает поток run(), т.к. он тоже может быть причиной.
shurilnik
У меня как раз мастер ветка, недельной давности правда.
Да порт сразу открывается при появлении устройства. Но проблема появляется не только при выдергивании а и при вставлении. Т.е. пока устройств нету - все тихо. Появляется устройство и начинается. На самом деле я пробовал и без открытия порта - тоже самое происходит. Я serialenumerator и использую для отслеживания что устройство выдернули, (даже с открытым портом) и соответствующий ему Abstractserial класс удаляется с закрытием порта и удалением дескриптора.
По поводу, RTS/DTR/CTS попробую поправить как вы сказали. Отпишусь потом.
Кстати ttylocker пришлось править как вы раньше советовали, иначе после выдергивания порт при повторном подключении не давало открыть порт.... Закоментировал обработки pid локфайла.
kuzulis
Цитата
На самом деле я пробовал и без открытия порта - тоже самое происходит. Я serialenumerator и использую для отслеживания что устройство выдернули, (даже с открытым портом) и соответствующий ему Abstractserial класс удаляется с закрытием порта и удалением дескриптора.

Ну, если вы говорите, что ошибка в serialenumerator - значит нужно его ковырять.
Я не скажу навскидку что там происходит... Может udev шалит, а мож еще что.

PS: А на обычном PC с Linux пробовали?
sh2ka
Есть некоторая проблема при использовании QSerialDevice.

Вот, исходные данные:
  • графическое приложение Qt (QWidget)
  • объект открытого порта (QSerialDevice)
  • фоновый таймер, отправляющий в порт запросы с интервалом ~1 секунду
  • есть слейв устройство, которое отправляет ответы на запросы (ГАРАНТИРОВАННО)


шаги по воспроизведению:
  • хватаю окно мышью за заголовок и держу
  • или открываю модальное окно


ПРОБЛЕМА: прекращается обмен с устройством.

Проверил, работает ли в этой ситуации таймер запросов - оказалось, что работает, т.е. запросы идут (проверял с помощью разных терминалок) - на стороне слейва данные приходят и отправляется ответ, но он не приходит мастеру.

Думаю, что здесь что-то связано с использованием API-функции WaitForSingleObject, т.е. она не возвращает управление до тех пор, пока не отпустишь окно или не закроешь модальное окно.

Однако, это всего лишь мое предположение. Хотелось бы узнать, что на самом деле: я что-то не так делаю или это баг?
kuzulis
Да, подтверждаю. Есть такое дело.

По ходу блокируется метод: QWinEventNotifier::event(QEvent *e).
т.е. не блокируется - а перестает срабатывать при появлении события.

Цитата
Думаю, что здесь что-то связано с использованием API-функции WaitForSingleObject, т.е. она не возвращает управление до тех пор, пока не отпустишь окно или не закроешь модальное окно.

Хз в какой функции проблема - но точно она в QWinEventNotifier.
В этом случае я ничего не могу сделать. ИМХО.

Создавайте экземпляр класса порта тогда в другом потоке, может поможет.
Litkevich Yuriy
Цитата(sh2ka @ 17.8.2011, 15:53) *
хватаю окно мышью за заголовок и держу
В виндовозе главный поток сразу блокируется, поэтому коммуникационную часть нужно делать в отдельном окне
kuzulis
Цитата(Litkevich Yuriy @ 18.8.2011, 9:14) *
В виндовозе главный поток сразу блокируется, поэтому коммуникационную часть нужно делать в отдельном окне

Эмм... но если б он блокировался - то не срабатывал бы таймер и не излучался бы от него сигнал, по которому порт отправляет данные.
Но в данном случае порт их периодично (раз в 1 сек) отправляет, но вот обратно не принимает ответ!

Почему тогда срабатывает таймер и обрабатываются евенты, если гл. поток должен блокироваться!?
Litkevich Yuriy
у меня и таймер не срабатывает, отпущу мыша, и попёрла вся пачка накопившаяся в очереди.
kuzulis
Цитата(Litkevich Yuriy @ 18.8.2011, 13:33) *
у меня и таймер не срабатывает, отпущу мыша, и попёрла вся пачка накопившаяся в очереди.

Хм, странно. У меня таймер срабатывает (WinXP SP2). :blink:
sh2ka
Цитата(Litkevich Yuriy @ 18.8.2011, 14:33) *
у меня и таймер не срабатывает, отпущу мыша, и попёрла вся пачка накопившаяся в очереди.


Странно, у меня таймер подвисает на долю секунды пока рамочка вокруг окна отрисовывается (содержимое окна при перетаскивании не отрисовывается), а потом все нормально.

Аналогично с полями ввода (скорее всего там таймер и используется для моргания курсора).
Одно понять не могу: это баг виндовс или Qt? Может какие-то особые настройки нужны системе для генерации события от порта (прерывания-то должны возникать хоть как при получении данных в порт)?

Я программировал на чистом WinAPI одно время и сам делал модальные циклы - это обычный рекурсивный вызов бесконечного цикла обработки событий, который закрывается при закрытии модального окна. Исходя из этого непонятно, почему блокируется генерация событий от порта. С отдельным потоком не всегда удобно, когда нужно сделать быстро и без проблем примитивную програмку с модальными окнами.
kuzulis
Цитата(sh2ka @ 19.8.2011, 7:56) *
Одно понять не могу: это баг виндовс или Qt?

ИМХО - баг Qt, связанный с обработкой событий (или типа того, не охота копать глубоко).

Вот, я прикрепил небольшой тестовый примерчик где по таймеру раз в 1 сек в порт отправляется запрос на чтение регистров (Modbus) и принимается ответ. Так тут такое же поведение.
silver47
Добрый день. Обновился до ветки master от 17 сентября. На windows 7 не закрывает порт с модемом, который подключен по USB. Так и висит с открытым портом, до тех пор пока шнурок из модема не выдернешь. В чем может быть проблема?

спасибо.

P.S. под USB модемом подразумеваю zyxel OMNI 56K UNO, а не всякие GPRS/3G.
kuzulis
Цитата(silver47 @ 4.11.2011, 15:41) *
Добрый день. Обновился до ветки master от 17 сентября. На windows 7 не закрывает порт с модемом, который подключен по USB. Так и висит с открытым портом, до тех пор пока шнурок из модема не выдернешь. В чем может быть проблема?

спасибо.

P.S. под USB модемом подразумеваю zyxel OMNI 56K UNO, а не всякие GPRS/3G.

Не знаю, проверьте сами дебаггером.
silver47
Дебаггер встал на файле abstractserial.cpp На строке номер 800
d->serialEngine->close();
Если копать глубже, то в файле nativeserialengine_win.cpp на строке 176
::CancelIo(this->descriptor);


Прилагаю скриншот.

P.S. если выдернуть девайс в этот момент, то сразу же переходим к строке 178
if (0 == ::CloseHandle(this->descriptor)) {
kuzulis
Можно попробовать перед закрытием делать setFlowControl(FlowControlOff) или,
если не получится, закомментировать CancelIo().
silver47
Цитата
Можно попробовать перед закрытием делать setFlowControl(FlowControlOff)

Порт открывается с FlowControlOff, тем не менее, поставил вызов прямо перед закрытием порта - результат нулевой.

Закомментировал вызов ::CancelIO(this->descriptor); гм... тоже без результата. Может чего не так делаю, но деббагер упорно переходит на строку с комментом. Уже вычистил проект и пересобрал, все равно.

UPDATE:Прошу прощения, спросонья подумал что сегодня уже 8е число, и что это уже пересобранная библиотека, а оказалась что исходники поменял, а саму библиотеку QSerialDevice не перекомпилил. Все работает.

Спасибо.
sarge
Добрый день, сори за идиотские вопросы, но с qt столкнулся впервые и пытаюсь разобраться с работой с ком портом.

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

мне надо как то по другому установить Qt чтобы все работало?
kuzulis
[/telepaty mode = ON]
См тут ответ.
Или тут на форуме или на prog.org.ru
[/telepaty mode]

sarge
Цитата(kuzulis @ 7.11.2011, 18:08) *
[/telepaty mode = ON]
См тут ответ.
Или тут на форуме или на prog.org.ru
[/telepaty mode]


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

спасибо большое, пока что все работает
shurilnik
kuzulis, Приветствую!

Наконец опять занялся своим устройством, сижу пытаюсь разобраться почему SerialDeviceEnumerator грузит проц... Пока что выяснил вот что:
в функции void SerialDeviceEnumeratorPrivate::setEnabled(bool enable)
создается коннект:
q->connect(this->notifier, SIGNAL(activated(int)), q, SLOT(_q_processWatcher()));

И в общем-то все нормально пока не воткнешь usb устройство. После вставки (или доставания, если сабжевый класс был инициализирован при воткнутом устройстве) начинаются бесконечные ивенты от этого QSocketNotifier (который udev_socket). И он постоянно дергает _q_processWatcher() и получается загрузка проца по плешку.
Пробовал на десктопе у себя - тоже самое. только грузится одно ядро (ну есесно прога а один поток работает).
Насколько я понимаю QSocketNotifier должен выдавать сигнал только когда udev увидел что действительно устройство появилось/исчезло? А оно почему-то выдает постоянно.

PS: Это все происходит вообще без участия AbstractSerial. Т.е. порт я даже не откываю.
Может есть идеи отчего так происходит ?

О, а может сокет не читается, поэтому сигнал все время заново посылается ?
kuzulis
Цитата
После вставки (или доставания, если сабжевый класс был инициализирован при воткнутом устройстве) начинаются бесконечные ивенты от этого QSocketNotifier (который udev_socket).


Да, есть такое дело. Если открыть порт и выдернуть шнурок то будут евенты сыпаться и будет загрузка.
Тут эта тема поднималась уже.
Решения нет и не будет в принципе, т.к. эта ветка библиотеки заморожена и больше не поддерживается.

Вместо этой ветки используй 2.0. : https://gitorious.org/qserialdevice/qserial...ive-tarball/2.0
которую (тьфу-тьфу чтобы не сглазить), нокиевцы обещали добавить в Qt как аддон.

Здесь вместо SerialDeviceEnumerator использовать можно SerialPortInfo с проверкой портов по таймеру.



shurilnik
Цитата(kuzulis @ 7.12.2011, 20:05) *
Цитата
После вставки (или доставания, если сабжевый класс был инициализирован при воткнутом устройстве) начинаются бесконечные ивенты от этого QSocketNotifier (который udev_socket).


Да, есть такое дело. Если открыть порт и выдернуть шнурок то будут евенты сыпаться и будет загрузка.
Тут эта тема поднималась уже.

Решения нет и не будет в принципе, т.к. эта ветка библиотеки заморожена и больше не поддерживается.

Это я читал, но как я выше написал порт вообще не открывается. Т.е. проблема даже при неоткрытом порте, я инициализирую только класс SerialDeviceEnumerator, AbstractSerial я не трогаю... Он же сам не открывает порт при появлении устройства....
Смысл как я понял в том что на udev_motitor вешается QSocketNotifier который выдает событие что данные можно читать, а обработчик из этого сокета ничего не читает а запускает сразу udev_enumerator и уже из него читает.
добавление struct udev_device *udev_device =::udev_monitor_receive_device(this->udev_monitor);
в обработчик решает проблему, но эта функция блокирующая и есть свои нюансы.
Я до конца механизм еще не понял (мало знаний, начинающий я...), но попробую как-нибудь всетаки красиво это решить.

Цитата(kuzulis @ 7.12.2011, 20:05) *
Вместо этой ветки используй 2.0. : https://gitorious.org/qserialdevice/qserial...ive-tarball/2.0
которую (тьфу-тьфу чтобы не сглазить), нокиевцы обещали добавить в Qt как аддон.

Здесь вместо SerialDeviceEnumerator использовать можно SerialPortInfo с проверкой портов по таймеру.

Эта ветка считается более стабильной ?
Спасибо, посмотрю, хотя если б ту доделать то в общем-то все красиво получалось... а по таймеру не всегда удобно в embedded системе ресурсы дороги...
kuzulis
Цитата
Я до конца механизм еще не понял (мало знаний, начинающий я...), но попробую как-нибудь всетаки красиво это решить.

Ok. Если у тебя получится, то сделай на гиториусе мерж-реквест и я волью твое решение в master ветку.

Цитата
Эта ветка считается более стабильной ?

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

Если что - то его (енумератор) всегда можно самому сделать отдельным классом,
(для себя), если уж он так необходим.
И возложить на него урезанные функции - только определять имя появившегося устройства
и "скармливать" это имя в SerialPortInfo для получения подробной информации об устройстве.

И переименовать к примеру тогда этот класс из SerialDeviceEnumerator в SerialPortWatcher.
blinvip
Здравствуйте!

Пытаюсь написать программу для передачи AT-команд модему через COM-порт, используя библиотеку qserialdevice 2.0.

Подскажите, пожалуйста какими функциями можно реализовать подобную передачу команд (наподобие Hyperterminal).
На команду, переданную через тестовое приложение guiapp модем не реагирует.

Доступна ли документация на библиотеку?

Спасибо.
kuzulis
Цитата
Подскажите, пожалуйста какими функциями можно реализовать подобную передачу команд (наподобие Hyperterminal).

см. QIODevice::write()

Цитата
На команду, переданную через тестовое приложение guiapp модем не реагирует.

Да неужели? А не забыл ли кое кто добавить в конце команды что-то типа "\r\n" ?

Цитата
Доступна ли документация на библиотеку?

Да. Пока в виде комментариев в исходном коде.
В принципе см. методы в serialport.h , а комментарии в serialport.cpp
KocMak
Привет.

Использую Prolific USB-to-Serial Comm Port и библиотеку qserialdevice для передачи пакетов на свою железку.
Проблема в том, что после создания виртуального порта, пока я любым терминалом не открою/закрою нужный COM, данные не передаются, хотя порт открывается нормально. Потом всё работает как надо, могу отправлять и принимать данные.

Подскажите, в чём может быть проблема?
kuzulis
Цитата
Подскажите, в чём может быть проблема?

А конфигурировать порт кто будет после открытия?
Больше информации давай: какая ос, версия библиотеки, как открываешь и настраивашь порт,
код в студию.

Тут телепатов нет.
KocMak
Цитата(kuzulis @ 11.12.2011, 21:13) *
Цитата
Подскажите, в чём может быть проблема?

А конфигурировать порт кто будет после открытия?
Больше информации давай: какая ос, версия библиотеки, как открываешь и настраивашь порт,
код в студию.

Тут телепатов нет.


OC - Win XP и Win7, библиотека 0.4.0, код настройки порта:
void MainWindow::portInit()
{
    if(initSerial(("COM"+ui->comSelect->text()), ui->speedSelect->currentText().toInt()) == false)
    {
        QMessageBox::information(this,"Error", "Error Open COM"+ui->comSelect->text());
    }
}
bool MainWindow::initSerial(QString dev, int baudRate)
{
    serial = new AbstractSerial(this);
    serial->setDeviceName(dev);
    serial->setBaudRate(baudRate);
    serial->setDataBits(AbstractSerial::DataBits8);
    serial->setParity(AbstractSerial::ParityNone);
    serial->setStopBits(AbstractSerial::StopBits1);
    serial->setFlowControl(AbstractSerial::FlowControlOff);

    connect(this->serial, SIGNAL(readyRead()), this, SLOT(ReadData()));

    if(serial->open(AbstractSerial::ReadWrite))return true;
    else return false;
}
kuzulis
2 Гость_KocMak_*,

слушайте, парни, вы достали с такими вопросами уже.

Кто будет документацию читать?
Я не буду отвечать на ваш вопрос. Из принципа. Разбирайтесь сами где у вас накосячено.

ЗЫ:
Накипело.

ЗЫЗЫ:
Цитата
библиотека 0.4.0

Оно устарело. Используй ветку master или ветку 2.0.
KocMak
Цитата(kuzulis @ 12.12.2011, 9:44) *
Кто будет документацию читать?
Я не буду отвечать на ваш вопрос. Из принципа. Разбирайтесь сами где у вас накосячено.


Спасибо и на этом, буду разбираться.
blinvip
Спасибо, разобрался. действительно забыл вставить \r.
shurilnik
kuzulis, Подскажи это нормально что при использовании qserialdevice 2.0, для работы с usb serial если открыть порт и выдернуть usb устройство, то в основном процессе почему-то перестают выполняться все ивенты таймеров... они срабатывают только при любом ручном GUI ивенте. Можно ли как-то корректно отлавливать отключение usb устройства и закрывать открытый порт ? Или мы возвращаемся к схожей нерешенной ситуации что была в прошлой версии ?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.