Russian Qt Forum

Qt => Общие вопросы => Тема начата: Vamireh от Август 21, 2013, 20:57



Название: [РЕШЕНО] QSerialPort и RS-485 короткий вопрос.
Отправлено: Vamireh от Август 21, 2013, 20:57
Необходимо управлять одной штукой через RS-485, есть (будет) USB->RS485 преобразователь, по ходу без контроля направления передачи. Как понимаю, перед отправкой нужно выставлять флаг rts, а после отправки его восстанавливать. То есть, если использовать QSerialPort, нужно сделать:
Код:
setRequestToSend(true);
write(.....);
setRequestToSend(false);

Прав ли я?


Название: Re: QSerialPort и RS-485 короткий вопрос.
Отправлено: Bepec от Август 21, 2013, 21:21
Неправы. RS-485 преобразователь  сам всё разрулит. так что вам надо тупо посылать и принимать байтики.

update: использовал преобразователи RS-485/RS-232 от фирм MOXA, Advantech и какой то русской фирмы. Любой из них сам всё разрулит. Единственно что нужно - при первом подключении правильно настроить адаптер. Ну там буфера поотключать, если он кадры большие резать будет и прочая лабуда. Но если всё работает из коробки - ничего делать не надо, наслаждайтесь! :)


Название: Re: QSerialPort и RS-485 короткий вопрос.
Отправлено: Vamireh от Август 22, 2013, 07:02
хорошо, буду наслаждаться. меня смутило то, что на дорогих моделях пишут "автоматическое определение направления передачи", а на USB свистках этой фразы не нашел
собственно, к moxa uport 1150 склоняюсь


Название: Re: QSerialPort и RS-485 короткий вопрос.
Отправлено: Bepec от Август 22, 2013, 07:36
С ней тоже работал. Никаких затруднений - открыл порт и шли.


Название: Re: QSerialPort и RS-485 короткий вопрос.
Отправлено: kuzulis от Август 22, 2013, 10:52
В принципе, если попадется "обрезаный" конвертер, который сам ничего не разруливает, то при реализации в QtSerialPort есть небольшой нюанс, связанный с асинхронной природой I/O в Qt.

Т.е. если сделаешь так:

Код
C++ (Qt)
setRequestToSend(true);
write(.....);
setRequestToSend(false);
 

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

Т.е. после write() не факт, что все данные отправятся, и когда ты сделаешь setRequestToSend(false), то тебя может ждать сюрприз. :)

Я бы попробовал определить завершение передачи при помощи сигнала bytesWtitten(qint64) и подсчитывать (аккумулировать) кол-во реально отправленных байт.
Потому что они могут передаваться по кусочкам, т.е. не все сразу, и => bytesWtitten() будет тебе сигналить после передачи каждого кусочка.

Т.е. я бы сделал как-то так:

Код
C++ (Qt)
 
...
...
 
const qint64 bytesToWrite = 1234;
 
...
...
 
connect(port, SIGNAL(bytesWtitten(qint64)), this, SLOT(onEndOfTransfer(qint64))));
 
...
...
 
MyClass::onEndOfTransfer(qint64 bytesTransferred)
{
   static qint64 accumulator = 0;
 
   accumulator += bytesTransferred;
 
   if (accumulator < bytesToWrite) {
       // ничего не делаешь, т.к. не все данные еще передались.
   } else {
       setRequestToSend(false); // <- тут отключаешь у конвертера режим передачи
   }
}
 
...
...
 
MyClass::onWrite()
{
   ...
   QByteArray data(bytesToWrite, 0); // <- тут заполняешь свой массив чем тебе нужно
 
   setRequestToSend(true); // <- тут переключаешь конвертер а передачу
   ...
   write(data); // <- тут передаешь
}
 
...
...
 
 

Естественно, тут просто показана идея без всяких проверок и т.п.

В принципе, я ее бы еще расширил и дополнительно коннектился бы к сигналу requestToSendChanged(bool) для запуска write().

Как-то так..