Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: QSerialDevice - Библиотека для работы с COM-портами
Форум на CrossPlatform.RU > Административный > Crossplatform.ru - все о нем > Обсуждение исходников с сайта
Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9
kuzulis
Я вчера проверял, открывал "/dev/ttyS0" и "/dev/ttyUSB0" (у меня только эти порты имеются). И все они открывались.
...
AbstractSerial port1;
AbstractSerial port2;

port1.setDeviceName("/dev/ttyS0");
port2.setDeviceName("/dev/ttyUSB0");

if (!port1.open(AbstractSerial::ReadWrite))
    qDebug("Port1 not open");
if (!port2.open(AbstractSerial::ReadWrite))
    qDebug("Port2 not open");

port1.close();
port2.close();
...
...


Не знаю в чем проблема... Попробуйте перед сборкой библиотеки раскомментировать в nativeserialengine_unix.cpp
строку вида:
//#define NATIVESERIALENGINE_UNIX_DEBUG


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

ЗЫ: Какую версию используете?
Гость
Цитата(kuzulis @ 15.11.2010, 12:34) *
Я вчера проверял, открывал "/dev/ttyS0" и "/dev/ttyUSB0" (у меня только эти порты имеются). И все они открывались.
ЗЫ: Какую версию используете?


до этого использовал 0,2,0. сейчас пробую подключить библиотеку версии 0,3,0 из git, но после пересборки своего проекта получаю:
Цитата
./Lib/libqserialdevice.a(abstractserial.o):(.data.rel.ro._ZTV21AbstractSerialPrivate[vtable for AbstractSerialPrivate]+0x14): undefined reference to `QIODevicePrivate::peek(char*, long long)'
./Lib/libqserialdevice.a(abstractserial.o):(.data.rel.ro._ZTV21AbstractSerialPrivate[vtable for AbstractSerialPrivate]+0x18): undefined reference to `QIODevicePrivate::peek(long long)'
collect2: выполнение ld завершилось с кодом возврата 1
kuzulis
Это не 0.3.0, это уже новьё, поэтому может еще не собираться. :)
Должно собраться с >= Qt 4.7.0

Кстати, какая версия Qt4?

Чтобы собралось всё, скачайте пока что "стабильный" релиз 0.3.0. тут : http://gitorious.org/qserialdevice/qserial...e-tarball/0.3.0
Гость
Цитата(kuzulis @ 15.11.2010, 16:18) *
Кстати, какая версия Qt4?


Qt4.6.3

Большое спасибо за помощь, все работает!
megomark
Сперва хочу поблагодарить за клевую библиотеку.

Но сегодня решил использовать более новую версию библиотеки - 0.3.0 как было сказано здесь:
Цитата(kuzulis @ 15.11.2010, 15:18) *
Чтобы собралось всё, скачайте пока что "стабильный" релиз 0.3.0. тут : http://gitorious.org/qserialdevice/qserial...e-tarball/0.3.0


Я скачал, релиз 0.3.0 по указанному адресу, но заметил появившейся баг- Если подряд несколько раз открыть и закрыть устройство то программа неожиданно завершает работу. Это только у меня так или же и у других тоже ?
kuzulis
Цитата(megomark @ 16.11.2010, 16:23) *
Сперва хочу поблагодарить за клевую библиотеку.

Но сегодня решил использовать более новую версию библиотеки - 0.3.0 как было сказано здесь:
Цитата(kuzulis @ 15.11.2010, 15:18) *
Чтобы собралось всё, скачайте пока что "стабильный" релиз 0.3.0. тут : http://gitorious.org/qserialdevice/qserial...e-tarball/0.3.0


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


1. Какая ОС?
2. Приведи минимальный тестовый пример который воспроизводит касяк.

Если речь идет о падении тех примеров, которые идут в архиве - то оно и должно там падать, т.к. они реализованы кривоватенько, чисто чтобы показать использование. :rolleyes:
Litkevich Yuriy
Цитата(kuzulis @ 16.11.2010, 20:57) *
т.к. они реализованы кривоватенько, чисто чтобы показать использование.
дак ты их реализуй правильно, раз уж это пример
megomark
Спасибо kuzulis за быстрый ответ. Это был мой баг. Раньше устройство не закрывалось. Если я вызвал метод close(); то после не мог заново открыть устройство. Я тогда решил проблему так. Удалял объкт AbstractSerial и создавал его заново. Но в новой версии библиотеки теперь этого делать не надо. Видимо был исправлен баг.
Большое спасибо.
Виталий
Цитата(kuzulis @ 16.11.2010, 16:57) *
Цитата(megomark @ 16.11.2010, 16:23) *
Сперва хочу поблагодарить за клевую библиотеку.

Но сегодня решил использовать более новую версию библиотеки - 0.3.0 как было сказано здесь:
Цитата(kuzulis @ 15.11.2010, 15:18) *
Чтобы собралось всё, скачайте пока что "стабильный" релиз 0.3.0. тут : http://gitorious.org/qserialdevice/qserial...e-tarball/0.3.0


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


1. Какая ОС?
2. Приведи минимальный тестовый пример который воспроизводит касяк.

Если речь идет о падении тех примеров, которые идут в архиве - то оно и должно там падать, т.к. они реализованы кривоватенько, чисто чтобы показать использование. :rolleyes:

Виталий
Испробовал QSerialDevice с железками, неплохо сделано, однако есть пара предложений:
1. Дать возможность назначать любой BaudRate, у меня например есть железка которая нестандартный использует.
2. Дать возможность назначать структуру DCB напрямую, не все параметры нашел как менять, а железки некоторые капризные попадаются.
kuzulis
Цитата
1. Дать возможность назначать любой BaudRate, у меня например есть железка которая нестандартный использует.

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

Хотя, а кто мешает переконфигурировать железку на стандартную скорость? ;)

Цитата
2. Дать возможность назначать структуру DCB напрямую, не все параметры нашел как менять, а железки некоторые капризные попадаются.

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




Виталий
Цитата(kuzulis @ 18.11.2010, 12:29) *
Цитата
1. Дать возможность назначать любой BaudRate, у меня например есть железка которая нестандартный использует.

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

Хотя, а кто мешает переконфигурировать железку на стандартную скорость? ;)

Цитата
2. Дать возможность назначать структуру DCB напрямую, не все параметры нашел как менять, а железки некоторые капризные попадаются.

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


Не все железки можно переконфигурировать, ту с которой мне работать приходится спаял какой то "гений", он же видимо придумал и протокол, таких конечно мало, если есть в одном месте, значит есть и где то еще. Я добавил в исходники нужный мне BaudRate, работает, но заметил одну странность, не могу пока понять из за чего, но может из за правки исходников, завтра проверю.
Litkevich Yuriy
Цитата(Гость_Виталий_* @ 18.11.2010, 13:57) *
Дать возможность назначать структуру DCB напрямую
как ты её в Линухе собираешься использовать?

Виталий не цитируй целыми сообщениями.
Смотри Справку по кнопкам и тэгам форума
Виталий
Цитата(Litkevich Yuriy @ 18.11.2010, 14:24) *
как ты её в Линухе собираешься использовать?

Ну да, вообщем то....а так удобно было бы )

kuzulis
Скачал исходники отсюда, версия 0.2.0
И вот заметил странность, ставлю AbstractSerial::BaudRate115200, а под отладчиком вижу что в setBaudRate он уже AbstractSerial::BaudRate128000 и так для любого BaudRate начиная с 9600, все передаются на одну ступень выше. Думал, что это из за того что добавлял нестандартный BaudRate, но заменил оригинальными исходниками, все пересобрал и тоже самое...может я чего то не понимаю....
kuzulis
Цитата
Скачал исходники отсюда, версия 0.2.0
И вот заметил странность, ставлю AbstractSerial::BaudRate115200, а под отладчиком вижу что в setBaudRate он уже AbstractSerial::BaudRate128000 и


Ну, эт мистика прям какая то. :)
Я 0.2.0 не поддерживаю. Текущая "типо стабильная" это 0.3.0.. Текущая "типо нестабильная" это 0.4.0, которая master ветка.
Гость
Использую порты в схеме мастер-слейв. Windows XP Pro SP3, MinGW 4.5.1, Qt 4.7.0
Возникла проблема: во время отправки данных мастером возникает замораживание GUI на несколько секунд. Поскольку я после определенного периода ожидания отправляю запросы вновь и вновь, то окна оказываются постоянно замороженными. Нашел на этом форуме решение проблемы:

Цитата
Цитата
Третий вопрос:
Произвожу отправку данных в порт функцией qint64 AbstractSerial::write(const char *data, qint64 maxSize)
Каким образом можно задать таймаут на выполнение данной функции, так как в случае ошибки передачи данных поисходит зависание программы,
например, при разрыве кабеля


Ух... тут это наверное возникает изза "режиме с управлением потоком" . Если это так, то я не сталкивался с этими особенностями и даж не представлю куда копать...
Хотя, попробуйте в методе:

void NativeSerialEnginePrivate::prepareOtherOptions()
{
this->cc.dcb.fBinary = true;
this->cc.dcb.fInX = this->cc.dcb.fOutX = this->cc.dcb.fAbortOnError = this->cc.dcb.fNull = false;
}

для this->cc.dcb.fAbortOnError = true; (вместо false)!!!


Думаю, это можно было бы сделать раз и навсегда, чтобы подобных проблем не возникало.

Это я победил, но осталась другая проблема. Использую VSPE - Virtual Serial Port Emulator - программа виртуальных COM-портов.
Создаю пару портов (Pair) в этой программе.
Запускаю программу-мастер (отправляет запросы слейву) - все нормально - порт открылся, запросы идут, GUI в порядке (использую один поток).
Запускаю программу Terminal.exe - она открывает второй порт пары и отображает полученные запросы (эмулирует слейва, но пока не отвечает) - тоже все нормально.
Отправляю любой набор байт в ответ - программа-мастер зависает на 5 секунд. Как быть? Другие программы подобным недугом не страдают.
Хочу сделать акцент на то, что такая штука возникает с VSPE, а прога очень удобная. Проверял с com0com - все нормально. Теряюсь в догадках. Help!
Гость
Еще одно дополнение: использую для чтения данных сигнал readyRead(), в слоте вызываю readAll() и посылаю дальше в программу QByteArray. Может это как-то разъяснит проблему.
Гость
Добавил setTotalReadConstantTimeout(1); после открытия порта - проблема вроде бы решилась. Правильно ли я сделал? Можно ли внести это в конструктор класса, как настройку по умолчанию
kuzulis
Цитата
Думаю, это можно было бы сделать раз и навсегда, чтобы подобных проблем не возникало.

Это я победил,

т.е. эта проблема у вас решена? а то я не стал делать this->cc.dcb.fAbortOnError = true; , т.к. тот человек мне так и не ответил, получилось у него или нет.

Цитата
Возникла проблема: во время отправки данных мастером возникает замораживание GUI на несколько секунд. Поскольку я после определенного периода ожидания отправляю запросы вновь и вновь, то окна оказываются постоянно замороженными.

Так и должно в принципе быть. Вы скорее всего используете режим Unbuffered? Если да - то при чтении данных в этом режиме функция чтения работает в блокирующем режиме, т.е. ждет данных. Поэтому желательно использовать I/O в отдельном потоке или попробовать небуферизированный режим работы или делать processEvent (или как то так).

Цитата
Отправляю любой набор байт в ответ - программа-мастер зависает на 5 секунд. Как быть? Другие программы подобным недугом не страдают.
Хочу сделать акцент на то, что такая штука возникает с VSPE, а прога очень удобная. Проверял с com0com - все нормально. Теряюсь в догадках.

Попробую разобраться что за беда.

Цитата
Еще одно дополнение: использую для чтения данных сигнал readyRead(), в слоте вызываю readAll() и посылаю дальше в программу QByteArray. Может это как-то разъяснит проблему.

В смысле?

Цитата
Добавил setTotalReadConstantTimeout(1); после открытия порта - проблема вроде бы решилась. Правильно ли я сделал? Можно ли внести это в конструктор класса, как настройку по умолчанию

Нет, нельзя. т.к. по умолчанию подразумевается работа в буферизованном режиме, и все таймауты равны 0. Только при работе в режиме Unbuffered они имеют значение (только 0 нельзя в этом режиме ставить). Да и вообще, я специально реализовал эти методы для более гибкой настройки порта и для того, чтобы вручную можно было их подобрать так, чтобы оптимальнее чтение происходило.

Почитайте ка документацию лучше, там я всё это расписал.







Гость
Цитата
т.е. эта проблема у вас решена?

Да, т.е. по всей видимости это правильный способ.

Цитата
Вы скорее всего используете режим Unbuffered?

По-моему, нет - использую метод open(AbstractSerial::ReadWrite) - как там по умолчанию не знаю. Посмотрю.

Цитата
Почитайте ка документацию лучше, там я всё это расписал.


Читал, но вскользь. Спасибо за ответ и за библиотеку :)
kuzulis
Цитата
По-моему, нет - использую метод open(AbstractSerial::ReadWrite) - как там по умолчанию не знаю. Посмотрю.

Если просто ReadWrite - то вообще никаких тормозов не должно быть.

Цитата
Читал, но вскользь. Спасибо за ответ и за библиотеку :)

Да незачто :)
panbaraban
Цитата(kuzulis @ 13.11.2010, 21:49) *
Конечно можно!

Просто есть такой касяк/фича в *.nix , которая заключается в том, что при некорректном завершении программы (например при нажатии ctrl^c) библиотека не удаляет lock-файлы. И поэтому при следующем запуске оно не может открыть порт. Но если теперь еще раз запустить приложение - то порты корректно откроются... :)

Для меня это пока не существенный касяк, поэтому пока не исправляю его.

Просто необходимо перед закрытием приложения делать close() всем открытым портам и тогда всё будет хорошо.


И снова в тред врываюсь я. Есть у меня переходник USB->RS232. Запускаю прогу, открываю порт. При открытом порте выдергиваю переходник, затем делаю close и удаляю порт.
Далее снова создаю порт и пытаюсь подключиться. Получаю кукиш. Могу подключиться только после перезапуска проги (или если удалить из /var/lock, но не пробовал ещё). Так что косяк иногда существенный, приходится прогу перезапускать, чего нехотелось бы. Поправимо ли это? Или же лучше вручную удалять локи, если таковые имеются, дабы не нарушить работу других устройств итд?
З.Ы. В системе только один подобный переходник(один юсб) , другие физически подключить некуда.
kuzulis
Цитата
Могу подключиться только после перезапуска проги (или если удалить из /var/lock, но не пробовал ещё). Так что косяк иногда существенный, приходится прогу перезапускать, чего нехотелось бы. Поправимо ли это?

В принципе всё поправимо. Пройдитесь дебаггером в момент закрытияи и посмотрите где оно косячит.

В принципе я догадываюсь в чем дело:
--------------------------------------
Суть в том, что за lock/unlock отвечает класс TTYLocker. В него передается имя порта для того, чтобы класс создавал соответствующие ему лок файлы в виде major/minor и имени (т.е. "/LCK.%1.%2" и /LCK..%1), т.е. создается сразу два лок-файла.

Для определения major/minor номера устройства используется POSIX функция stat(...) которая принимает два параметра :
один - имя устройства
второй - буфер куда будет записан major/minor.

Так вот, когда мы открыли порт open(), после этого вызывается метод TTYLocker::lock() , который создает два лок файла в которые записывает некоторые параметры.

Теперь мы закрываем порт close(), после этого вызывается метод TTYLocker::unlock(), который удаляет два лок-файла.

Но всё дело в том, что для получения имен лок-файлов, класс TTYLocker использует только имя самого порта!
Т.е. за это отвечают методы:

QString TTYLocker::getLockFileInNumericForm() const
QString TTYLocker::getLockFileInNamedForm() const


Теперь, если мы вызвали метод close(), и при этом, порт присутствует в системе, то метод
QString TTYLocker::getLockFileInNumericForm() const

вернет корректное имя лок-файла и удалит его.

НО в случае, когда мы выдернули шнурок, то порт из системы пропал, следовательно метод
QString TTYLocker::getLockFileInNumericForm() const

вернет пустое имя лок-файла, т.к. самого устройства в системе уже нет, и определить его major/minor не представляется возможным.

В данной ситуации TTYLocker удалит только один лок-файл (из двух), связанный только с именем порта, а лок-файл, связанный с major/minor останется в системе.

Теперь, мы вставляем снова шнурок и пытаемся открыть порт.. НО, класс TTYLocker видит, что уже есть лок-файл с major/minor этого порта и PID (идентификатор процесса использующего порт) равен PID-у нашего приложения, а также этот PID активен!
Поэтому TTYLocker "делает вывод" что порт уже занят!

Поэтому если мы перезапустим приложение, то TTYLocker увидит этот же лок-файл, но в нём PID уже не будет равен PID-у нашего приложения.
Поэтому TTYLocker "делает вывод" что порт свободен!
--------------------------------------

Вот вкратце чисто гипотетическое предположение что происходит.
Я пока не решил еще, правильный ли алгоритм у TTYLocker или нет. Но, хочу заметить, что я "передирал" реализацию TTYLocker из других опен сурц проектов, поэтому не думаю, что она некорректна (хотя ХЗ).

Т.е. временное решение - это в коде TTYLocker закомментировать вообще всё что связано с лок-файлом по major/minor, т.е. в итоге нужно чтобы будет создавался один лок-файл связанный только с именем устройства.
Я пока не буду трогать код, но вы для себя можете это сделать. :)
Aleksei
Добрый день
Вопрос к многоуважаемому автору.
Есть ли веские доводы при вызове AbstractSerial::close() не делать автоматом AbstractSerial::flush() ?
kuzulis
В смысле? Я ничо не понял.
BRE
Камрад спрашивает: происходит ли flush при закрытии порта? И почему? :)
panbaraban
А ещё такой вопрос. Одинаково ли работают релиз и дебаг сборки? У меня почему то не открывается порт если я компилю в релиз сборке, точнее открывается, но очень редко. :scratch_one-s_head:
Upd: Оказывается у меня руки кривые. Не знаю как удалить сообщение(
Alexk
Руки, понимаю, лечатся долго, я новичок, но никак не получается юзать либу:

Qt 4.7.0, WinXP sp3

Взял исходники из ветки master, отредактировал BuildLibrary.pro, qserialdevice.pro, qserialdeviceenumerator.pro на предмет CONFIG +=dll (+=staticlib закомментировал),
далее - qmake BuildLibrary.pro, mingw32-make (под виндой).
Переписал .dll и .a в Qt\2010.05\qt\lib, положил рядом с exe.

При запуске вылетает сразу с ошибкой 139 - проблема с точкой входа в dll.

Собирал и непосредственно qserialdevice.pro, удаляя makefile - то же самое.

В проекте INCLUDEPATH += C:\Qt\2010.05\sport\src\qserialdevice, LIBS += -lqserialdevice (c d тоже пробовал)

Ну никак! Помогите, плиз!



kuzulis
Как надо:
1. Редактировать нужно только в src.pro
Цитата
...
#CONFIG += staticlib
CONFIG += dll
...

2. Открываем BuildExamples.pro и собираем всё: и библиотеку и примеры.
3. Если хотим запустить /examples/enumerator, то копируем скомпиленную qserialdevice*.dll к екзешке enumerator*.exe
4. Запускаем QtCommandPromt , переходим к enumerator*.exe и запускаем его.

ЗЫ: эти манипуляции справедливы только в Windows.
Alexk
Библиотека и примеры компилируются, и сразу запускается AnyMaster, если с нуля, ничего не правя и записав qserialdevice-qserialdevice в например C:\Qt\2010.05, открыть QtCreator`ом BuildExamples.pro и нажать, так сказать, большую зеленую кнопку.

.a помещает в Qt\2010.05\BuildExamples-build-desktop\src\build\debug - это так и должно быть, или должно в Qt\2010.05\qserialdevice-qserialdevice\src ?

Пример так работает.

Если поправить CONFIG в src.pro, либа собирается, но примеры уже не компилит -

mingw32-make: Leaving directory `C:/Qt/2010.05/BuildExamples-build-desktop'

obj/anymaster.o: In function `AnyMaster':

C:\Qt\2010.05\BuildExamples-build-desktop\examples\anymaster/../../../qserialdevice-qserialdevice/examples/anymaster/anymaster.cpp:30: undefined reference to `operator<<(QDebug, AbstractSerial::BaudRate)'

и т.д. Вероятно, это нормально.

.dll помещает опять в Qt\2010.05\BuildExamples-build-desktop\src\build\debug.

С полученной .dll моя прога работать не хочет, опять 139 ошибка (там только создание экземпляра класса, больше совсем ничего, и #include <abstractserial.h>, как в примере, и dll лежит рядом с ехе), а примеры проверить не могу.


Охотно проверю любую версию)
kuzulis
Цитата
C:\Qt\2010.05\BuildExamples-build-desktop\examples\anymaster/../../../qserialdevice-qserialdevice/examples/anymaster/anymaster.cpp:30: undefined reference to `operator<<(QDebug, AbstractSerial::BaudRate)'

Возьмите сегодняшний master. Я там это исправил.

Цитата
так сказать, большую зеленую кнопку.

не надо нажимать кнопок. запускать надо через Qt Command Promt или заранее прописав в PATH пути к либам Qt и MinGW.

Цитата
.a помещает в Qt\2010.05\BuildExamples-build-desktop\src\build\debug - это так и должно быть, или должно в Qt\2010.05\qserialdevice-qserialdevice\src ?

Должно быть, всегда библиотеку помещает в \BuildExamples-build-desktop\src\build\debug(release).

Цитата
С полученной .dll моя прога работать не хочет, опять 139 ошибка (там только создание экземпляра класса, больше совсем ничего, и #include <abstractserial.h>, как в примере, и dll лежит рядом с ехе), а примеры проверить не могу.

Разбираться что у Вас не работает в Вашем приложении я не буду. Для Вас специально созданы примеры /examples , они работают так как задумано. Сделайте у себя по аналогии. В чем проблема?

Цитата
.dll помещает опять в Qt\2010.05\BuildExamples-build-desktop\src\build\debug.

А куда ей помещать?
Если хотите использовать shared (*.dll) библиотеку - то напишите сами себе *.pro файл так как Вам нужно чтобы оно помещало туда куда Вам надо.


В общем, почитайте assistent и что нить про разделяемые библиотеки.




Alexk
Спасибо большое!

Все компилируется и работает. Н-да, только в треде намусорил, виноват.
Sasha07
Доброго времени суток, форумчане!
Возникла проблема (видимо с руками) при чтении/записи с использованием QSerialDevice.
ОС ubuntu 10.10, usb-->rs переходник. На том конце управляемый коммутатор. Библиотеку стянул сегодня, собралась без проблем.
Вот только как отдать железке данные, понятные ей и забрать понятные мне не пойму...
Вывод QDebug :
Раскрывающийся текст
[/expand]
[expand]= New parameters =
Device name : "/dev/ttyUSB0"
Baud rate : "57600 baud"
Data bits : "8 bit"
Parity : "None"
Stop bits : "1"
Flow : "Disable"
Char timeout, msec : 0
open mode : OpenMode( "ReadOnly|WriteOnly" )
port error : "Unknown error"
port lineStatus : 6
log : 0x9939128
read : ""
log : 0x9939128
read : ""
log : 0x9939128
read : ""
log : 0x9939128
read : ""
log : 0x9939128
read : ""
log : 0x9939128
read : ""


Код:

Раскрывающийся текст
AbstractSerial *port = new AbstractSerial;
QByteArray a,b,inputBuffer;

QString *logText = new QString;


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
ui->setupUi(this);

port->setDeviceName("/dev/ttyUSB0");
connect( port, SIGNAL(readyRead()), this, SLOT(ReadData()));
connect( port, SIGNAL(signalStatus(QString,QDateTime)), this, SLOT(State(QString,QDateTime)));

if (port->open(AbstractSerial::ReadWrite))
     ui->label->setText("open!");

port->reset();
port->setBaudRate(AbstractSerial::BaudRate57600);
port->setFlowControl(AbstractSerial::FlowControlOff);
port->setDataBits(AbstractSerial::DataBits8);
port->setParity(AbstractSerial::ParityNone);
port->setStopBits(AbstractSerial::StopBits1);

qDebug() << "= New parameters =";
qDebug() << "Device name            : " << port->deviceName();
qDebug() << "Baud rate              : " << port->baudRate();
qDebug() << "Data bits              : " << port->dataBits();
qDebug() << "Parity                 : " << port->parity();
qDebug() << "Stop bits              : " << port->stopBits();
qDebug() << "Flow                   : " << port->flowControl();
qDebug() << "Char timeout, msec     : " << port->charIntervalTimeout();
qDebug() << "open mode              : " << port->openMode();
qDebug() << "port error             : " << port->errorString();
qDebug() << "port lineStatus        : " << port->lineStatus();

}

void MainWindow::ReadData()
{
   if (!port->waitForReadyRead(500))
        qDebug() << "Response timeout.";
  qint64 ba_count= port->bytesAvailable();
   QByteArray ba = port->read(ba_count);

   inputBuffer.append(ba);
       if (inputBuffer.contains("\n"))                                 // Если пришёл конец строки
       {
           QString ba_str(inputBuffer);
           inputBuffer.clear();
         logText->append(QString("<b>></b> %1").arg(ba_str));       // Записываем посылаемые данные в лог
       }

    QString ba1_str(ba);
    qDebug () << "log    : "  << logText;
    qDebug () << "read   : "  << ba1_str;
}

void MainWindow::State(QString stateMsg,QDateTime dt)
{

  qDebug() << "State: " << stateMsg << ", in time: " << dt.time().toString();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{


port->write(ui->lineEdit->text().toAscii() +'/r');
ui->lineEdit->clear();
// qDebug() << "port error             : " << port->errorString();
// qDebug() << "port line state        : " << port->lineStatus();

}

void MainWindow::on_pushButton_2_clicked()
{
  port->flush();
}



Сильно не пинайте - это моя первая программа на qt.
kuzulis
1. Зачем в слоте ReadData вы делаете port->waitForReadyRead(500) ?
2. Чтобы посмотреть что читается - понавставляйте qDebug-ов после QByteArray ba = port->read(ba_count);
3. А насчет того как отдавать/забирать данные железке - это вам виднее, читайте документацию, смотрите примеры.

Sasha07
1. Зачем в слоте ReadData вы делаете port->waitForReadyRead(500) ?
2. Чтобы посмотреть что читается - понавставляйте qDebug-ов после QByteArray ba = port->read(ba_count);
3. А насчет того как отдавать/забирать данные железке - это вам виднее, читайте документацию, смотрите примеры.

1. Не заработало корректно - начал лепить и перебирать что попало.
2. Изначально лепил qDebug, в ответ или то что ввожу (т.е. ответа от железки нет) или иероглифы.
3. Видимо у меня проблемы с кодировкой записи в порт, + кривые руки, поэтому и писал:
Цитата
Сильно не пинайте - это моя первая программа на qt.


Если кто - то сталкивался с такой проблемой дайте кусок кода в котором идет преобразование qstring -> to qbytearray при записи и наоборот при чтении. qstring-toASCII, UTF-8 и т.д. не спасает.
Заранее благодарен.

kuzulis, спасибо за библиотеку!
Litkevich Yuriy
Цитата(Sasha07 @ 7.1.2011, 21:46) *
Видимо у меня проблемы с кодировкой записи в порт
устройство в символьном (ASCII) режиме работает?
Sasha07
Цитата
устройство в символьном (ASCII) режиме работает?


Думаю да, гипертерминал и putty с ним нормально работают, в настройках putty по дефолту стоит unicode.
Sasha07
Цитата
устройство в символьном (ASCII) режиме работает?


Нашел serial port monitor 4, он разрешает писать следующие типы данных в порт : string, hex, oct, demical, bin. Так вот, при записи string строка пишется и читается корректно, но /r , /n, /r/n , CR - не отправляет железке команду перевода каретки, тип oct, ввожу 15 return отрабатывает. также с bin, и hex, demical.

Dump view : 45 6e 74 65 72 20 69 6e 74 6f 20 73 74 70 20 6d Enter into stp m - то что возвращается из порта.
Как отправить/ получить символ возврата каретки и символ новой строки (/n) используя данную библиотеку?
Заранее благодарен.





Litkevich Yuriy
управляющие символы ASCII используют обратный слэш:
\r
\n
\rn

Цитата(Sasha07 @ 9.1.2011, 3:03) *
Нашел serial port monitor 4
Это устройство так называется?
Sasha07
[quote]управляющие символы ASCII используют обратный слэш:
\r
\n
\rn
[quote]
Да как только не извращался уже - все равно их железка читает как обычные символы.

serial port monitor 4 - программа под винду для диагностики и дампа данных c com port.
Непосредственно с нее и работал с коммутатором, чтобы понять чего ему надо.
Строки коммутатор воспринимает, а вот управляющие символы в String отправить не получается, коммутатор воспринимает их как строку и все.
kuzulis
Цитата
Строки коммутатор воспринимает, а вот управляющие символы в String отправить не получается, коммутатор воспринимает их как строку и все.

Ну так смекнуть нужно и формировать данные в виде QByteArray и слать их устройству.
...
QString s("моя команда или хз что там")
QByteArray data;
data.append(s);
data.append('\r');
port.write(data);
...


Это же элементарно, Ватсон (с)
Алексей1153
Цитата(Litkevich Yuriy @ 9.1.2011, 7:41) *
\rn

вообще-то так:
\r\n
Sasha07
Цитата
Это же элементарно, Ватсон (с)

:rolleyes: , благодарю - работает.
Еще раз спасибо за библиотеку!
Litkevich Yuriy
Цитата(Алексей1153 @ 9.1.2011, 15:33) *
вообще-то так:
\r\n
да, ты прав
good835
Добрый день!
Работаю с некоторой железкой, которая работает в режиме С Управлением потоком. Обновил библиотеку из репозитария, появилось несколько вопросов:
1. Теперь после открытия порта IsOpenCorrectrly = MyDevice->open(AbstractSerial::ReadWrite) железка говорит, что RTS установлен, раньше такого не было
2. После успешного открытия порта и установки параметров пытаюсь установить RTS
порт сконфигурирован как (MyDevice->setFlowControl(AbstractSerial::FlowControlOff);
MyDevice->setRts(true) возвращает false?
Если же порт был сконфигурирован без управления потоком (MyDevice->setFlowControl(AbstractSerial::FlowControlOff), то RTS - успешно устанавливается
и ПРОГРАММА УСПЕШНО работает, так, как будто управление потоком установлено.
Спасибо.



Цитата(good835 @ 11.1.2011, 19:22) *
Добрый день!
Работаю с некоторой железкой, которая работает в режиме С Управлением потоком. Обновил библиотеку из репозитария, появилось несколько вопросов:
1. Теперь после открытия порта IsOpenCorrectrly = MyDevice->open(AbstractSerial::ReadWrite) железка говорит, что RTS установлен, раньше такого не было
2. После успешного открытия порта и установки параметров пытаюсь установить RTS
порт сконфигурирован как (MyDevice->setFlowControl(AbstractSerial::FlowControlOff);
MyDevice->setRts(true) возвращает false?
Если же порт был сконфигурирован без управления потоком (MyDevice->setFlowControl(AbstractSerial::FlowControlOff), то RTS - успешно устанавливается
Спасибо.

kuzulis
Вообще-то я не тестировал связь с управлением потоком. (Тестировал только без, т.к. влом было паять нуль-модемный кабель с подключением всех 9-ти пинов).
Так что проверить не смогу, имею только GND, RX, TX :)

Что за ОС?

Цитата
1. Теперь после открытия порта IsOpenCorrectrly = MyDevice->open(AbstractSerial::ReadWrite) железка говорит, что RTS установлен, раньше такого не было

Насчет установки RTS и DTR - то да, при открытии порта они устанавливаются (по крайней мере в винде)!
Просто в Винде (а я подозреваю, что вы в ней кодите) ранее метод lineStatus() не мог определять состояния линий DTR и RTS.
Эта фича (определение статуса этих линий) появилась буквально неделю назад. Если я правильно понял.

Я думаю (на днях) добавить в метод открытия порта еще возможность указания желаемого состояния линий DTR, RTS порта.
То, что происходит сейчас - хз что, я копипастил эти методы из QextSerialPort особо не проверяя их.

В общем, нужно разобраться. Попробуйте поиграться при открытии с флагами из DCB (для винды):
Цитата
...
fDtrControl
...
fRtsControl
...


и напишите что вышло и с какими комбинациями для разных режимов контроля потока.

Цитата
2. После успешного открытия порта и установки параметров пытаюсь установить RTS
порт сконфигурирован как (MyDevice->setFlowControl(AbstractSerial::FlowControlOff);
MyDevice->setRts(true) возвращает false?
Если же порт был сконфигурирован без управления потоком (MyDevice->setFlowControl(AbstractSerial::FlowControlOff), то RTS - успешно устанавливается
и ПРОГРАММА УСПЕШНО работает, так, как будто управление потоком установлено.


По идее, если установлен аппаратный контроль управления потоком - то setRts и не должен работать, т.к. всю работу делает драйвер, хотя ХЗ.
В общем, нужно упорно разбираться еще. :)

ЗЫ: Я тут пишу тестовое GUI приложение (с кнопочками, терминалом и т.п.) в котором можно будет опробовать все краеугольные моменты, думаю, завтра к вечеру (по мск.) выложу в Git. Вот тогда и начну вникать, а пока что, пробуйте сами понять в чем проблема.

good835
Продолжаю разобираться с работой порта в режиме упаравления потоком

fRtsControl - пробовал в двух вариантах RTS_CONTROL_ENABLE (это то что нужно моему приложению) и RTS_CONTROL_HANDSHAKE
в обоих вариантах - RTS устанавливается либо при открытии порта (по моему читается предыдущая конфигурация порта DCB, так как порт еще не конфигурился)
либо при конфигурировании setFlowControl(AbstractSerial::FlowControlOff)
при этом
1. функция setRTS(true) - возвращает false - но возможно это и правильно, так как RTS уже активен
2. функция lineStatus() - говорит что RTS - не установлен ??? вот это не понятно

если открыть порт без управления потоком, то связка setRTS(true) + lineStatus() - отрабатывает нормально
good835
небольшое дополнение
возможно вызов lineStatus() - должен быть с некоторый таймаутом после открытия и конфигурирования порта
если смотреть после открытия - то RTS - не установлен
если через паузу (не таймером просто некоторые задачки еще выполняются перед записью) - то RTS установлен
silver47
Доброго времени суток.
У меня такая проблема появилась. Заметил, что читаю из порта максимум 4096 байт. Чтение происходит таким образом:
QByteArray data(port->readAll());

Где я ошибся? Спасибо.
Litkevich Yuriy
дак наверное буфер порта имеет только 4к, смотри в настройках драйвера устройства
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.