Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Qt и кроссплатформенное программирование С/С++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.10.2012, 17:52   #1
Vanta11a
Lawful Evil
Участник клуба
 
Аватар для Vanta11a
 
Регистрация: 13.05.2008
Сообщений: 1,208
По умолчанию QExtSerialPort, работа с битом RTS

Исходные данные:
COM - порт, реализующий RS-485, с аппаратным контролем потока. Qt в связке с библиотекой QExtSerialPort.
Чтение данных, приходящих из порта, идет на ура.
Функция записи в порт не пишет ничего, причем именно для RS-485. Если порт будет реализовывать RS-232 или RS-422, все шикарно работает.

Исходник функции отправки (по заданию вызывается по завершению приема сообщения):
Код:
    QString command, checksumm;
    BBPPort->setRts(false);
    BBPPort->setDtr(false);
    command.append("command");
    checksumm = calcCheckSumm(command.section('*',0,0));
    command.append(checksumm);
    command.append('\r' + '\n');
    QByteArray data;
    data = command.toAscii();
    int bytes;
    bytes = BBPPort->write(data);
    ui->lE_BytesWrought->setText(QString("%1").arg(bytes));
    BBPPort->setRts(true);
    BBPPort->setDtr(true);
Что я делаю не так?
Алгоритм - бесплатен. Поиск багов - бесплатен. Реализация алгоритма - за отдельную плату.
На форуме помогают советами и объясняют, а не пишут на халяву программы, лабы, курсачи и т.д. (c)
Vanta11a вне форума Ответить с цитированием
Старый 16.10.2012, 19:29   #2
raxp
Старожил
 
Регистрация: 29.09.2009
Сообщений: 9,713
По умолчанию

Цитата:
COM - порт, реализующий RS-485, с аппаратным контролем потока
COM-порт может реализовать RS-485 только вкупе с конвертором RS-232/RS-485, в вашем случае видимо неавтоматическим, с управлением направлением приема-передачи:



И вообще:
Код:
bytes = BBPPort->write(data);
    ui->lE_BytesWrought->setText(QString("%1").arg(bytes));
    BBPPort->setRts(true);
    BBPPort->setDtr(true);
сначала устанавливают RTS, а уже потом передают, а у вас наоборот.

1- проконтролируйте саму передачу на TX (пин 3) - RS-232
2- проконтролируйте установку RTS и единичного уровня на 2-3 ноге драйвера ADM485/ST-485, т.е. убедитесь, что в вашем конверторе реализуется не обратная логика по RTS в ноль, а прямая
3- проконтролируйте передачу на A-B RS-485-го интерфейса ...осциллом или внешним терминалом
Разработки и научно-технические публикации :: Видеоблог :: Твиттер
Radar systems engineer & Software developer of industrial automation
raxp вне форума Ответить с цитированием
Старый 17.10.2012, 05:27   #3
Vanta11a
Lawful Evil
Участник клуба
 
Аватар для Vanta11a
 
Регистрация: 13.05.2008
Сообщений: 1,208
По умолчанию

От замены true на false ничего не меняется, проверял. Если поставить софтварный контроль за передачей - в порт идет какая-то ересь вместо нужных данных.

Есть софт, работающий с данным портом, причем успешно. Для передачи используются те же функции, что и в QExtSerialPort, а именно:
Код:
00810             EscapeCommFunction(Win_Handle, SETRTS);
00813             EscapeCommFunction(Win_Handle, CLRRTS);
Причем сначала в работающей программе идет CLRRTS, запись данных, а после этого - SETRTS.

Функция write, возвращает в качестве количества записанных данных - 0. Возможен вариант, что бит просто не успевает установиться?
Случай, что передача от меня накладывается на другую - исключаем, т.к. даже когда я в канале один, данные все равно не передаются.
Алгоритм - бесплатен. Поиск багов - бесплатен. Реализация алгоритма - за отдельную плату.
На форуме помогают советами и объясняют, а не пишут на халяву программы, лабы, курсачи и т.д. (c)
Vanta11a вне форума Ответить с цитированием
Старый 17.10.2012, 07:57   #4
raxp
Старожил
 
Регистрация: 29.09.2009
Сообщений: 9,713
По умолчанию

Цитата:
От замены true на false ничего не меняется, проверял
а должно бы.

1- используйте WinAPI функции напрямую, раз обертка не срабатывает
2- проверяйте сниффером Portmon, что идет в порт со стандартного ПО и вашего, так вы отследите на каком этапе вы делаете ошибку

Цитата:
Причем сначала в работающей программе идет CLRRTS, запись данных, а после этого - SETRTS
установка в ноль - это прием, в единицу - это передача. В вашем случае: вы сначала ставите в ноль, что-то пытаетесь передать, а потом устанавливаете в режим передачи, когда передачи уже нет. Смысл дошел?
Разработки и научно-технические публикации :: Видеоблог :: Твиттер
Radar systems engineer & Software developer of industrial automation
raxp вне форума Ответить с цитированием
Старый 17.10.2012, 09:41   #5
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,331
По умолчанию

А что должно изменится? Если мне не изменяет память, RTS это Request To Send, то биш требоивание к девайсу чтоб слал данные (ну, или разрешение). Для того, чтоб знать надо ли нам слать или нет надо смотреть на CTS (Clear To Send)
waleri вне форума Ответить с цитированием
Старый 17.10.2012, 11:24   #6
Vanta11a
Lawful Evil
Участник клуба
 
Аватар для Vanta11a
 
Регистрация: 13.05.2008
Сообщений: 1,208
По умолчанию

Итак. Работающий код выглядит следующим образом:
Код:
EscapeCommFunction(hCom,CLRRTS);
SEND_RS(); // Генерация сообщения в переменной chbuf
WriteFile ( hCom, chbuf,  strlen(chbuf), &temp, &overlappedwr );
Sleep(15);
EscapeCommFunction(hCom,SETRTS);
Мой код:
Код:
BBPPort->setRts(false); // Отработает как EscapeCommFunction(hCom,CLRRTS)
command.append("command"); // Формирование команды в QString
QByteArray data;
data.append(command);
BBPPort->write((data.data()),data.length());
BBPPort->setRts(true); // Отработает как EscapeCommFunction(hCom,SETRTS)
Функция write принадлежит QIODevice, и в свою очередь вызывает функцию writeData. writeData перегружена в QExtSerialPort и в общем приближении имеет вид
Код:
WriteFile(Win_Handle, (void*)data, (DWORD)maxSize, & bytesWritten, newOverlapWrite)
Причем данная функция прекрасно работает для RS422 и RS232.

В чем глобальная ошибка? Может быть я передаю в функцию не то, что надо?
Алгоритм - бесплатен. Поиск багов - бесплатен. Реализация алгоритма - за отдельную плату.
На форуме помогают советами и объясняют, а не пишут на халяву программы, лабы, курсачи и т.д. (c)

Последний раз редактировалось Vanta11a; 17.10.2012 в 11:27.
Vanta11a вне форума Ответить с цитированием
Старый 17.10.2012, 11:31   #7
raxp
Старожил
 
Регистрация: 29.09.2009
Сообщений: 9,713
По умолчанию

Цитата:
Итак. Работающий код выглядит следующим образом:
...
имхо, сие справедливо лишь для конкретного преобразователя с обратной логикой управления по RTS/DTR.

В моем конверторе логика управления прямая. Впрочем, что не мешает задавать нужное направление через WinAPI:


Цитата:
В чем глобальная ошибка?
в том, что вы проигнорировали возможность пошагово отследить, что делает ваш код с помощью сниффера и сравнить с рабочим кодом, а тупо долбите обертку в QT.

Цитата:
Может быть я передаю в функцию не то, что надо?
это загадка, для нас, ибо:
1- вы не указали схему подключенного оборудования
2- вы не указали, чем отслеживаете, осциллографом, сниффером, вторым терминалом на шине RS-485, может вы смотрите через Modbus-терминал ...а так, передачу вы не проверили, по крайней мере нам ничего об этом неизвестно.

Цитата:
WriteFile(Win_Handle, (void*)data, (DWORD)maxSize, & bytesWritten, newOverlapWrite)

Причем данная функция прекрасно работает для RS422 и RS232.
RS-422 - однонаправленный интерфейс, RS-232 не требует переключения и управления. Либо возьмите автоматический конвертор RS-232/RS-485 и избавьтесь от головной боли раз и навсегда. Да, дороже
Разработки и научно-технические публикации :: Видеоблог :: Твиттер
Radar systems engineer & Software developer of industrial automation

Последний раз редактировалось raxp; 17.10.2012 в 11:44.
raxp вне форума Ответить с цитированием
Старый 17.10.2012, 11:40   #8
Vanta11a
Lawful Evil
Участник клуба
 
Аватар для Vanta11a
 
Регистрация: 13.05.2008
Сообщений: 1,208
По умолчанию

Цитата:
имхо, сие справедливо лишь для конкретного преобразователя с обратной логикой управления по RTS/DTR.
Самое печальное - что нельзя этот преобразователь поменять.

И portmon не получится использовать, т.к. Win7 x64, которую тоже поменять нельзя.

На данный момент нашел(?) альтернативу, но взлетит или нет - вопрос.

Итак, на данный момент имеется:
ПК с железным портом RS485 (менять нельзя). Каким вывертом реализован RS485 на ПК - неизвестно.
Блок, которым надо управлять - тоже с железным RS485.
Конвертер ADAM RS485/RS232, подключенный в шину между блоком и ПК, отдающий данные на HyperTerminal.

Из проблем: ПК менять нельзя. Блок менять нельзя. Ставить конвертер между блоком и ПК - нельзя. Остается только долбить код.
Прием работает изумительно, отправка - никак. Я бы понял, если бы не работало все, а так...
Алгоритм - бесплатен. Поиск багов - бесплатен. Реализация алгоритма - за отдельную плату.
На форуме помогают советами и объясняют, а не пишут на халяву программы, лабы, курсачи и т.д. (c)

Последний раз редактировалось Vanta11a; 17.10.2012 в 12:09.
Vanta11a вне форума Ответить с цитированием
Старый 17.10.2012, 12:11   #9
raxp
Старожил
 
Регистрация: 29.09.2009
Сообщений: 9,713
По умолчанию

Цитата:
И portmon не получится использовать
не Portmon-ом единым... К тому же, всегда можно воспользоваться VMWare или VirtualBox, поставить нужную ОС и экспериментировать с портами по самое не могу.

Цитата:
Самое печальное - что нельзя этот преобразователь поменять
такие вещи решаются на этапе ТЗ. Тут уж зависит от "степени жлобства" руководства.
Разработки и научно-технические публикации :: Видеоблог :: Твиттер
Radar systems engineer & Software developer of industrial automation
raxp вне форума Ответить с цитированием
Старый 17.10.2012, 12:19   #10
Vanta11a
Lawful Evil
Участник клуба
 
Аватар для Vanta11a
 
Регистрация: 13.05.2008
Сообщений: 1,208
По умолчанию

Итак. Главный тезис руководства: в железе ничего не менять. То есть работать с тем, что есть. В понятие "железо" включается как используемый ПК, так и версия ОС.

Есть программа, которая с грехом пополам, но работает. И по образу и подобию которой надо делать новую.
Различия с моей имеют вид одной строки. В работающем варианте:
Код:
WriteFile ( hCom, chbuf,  strlen(chbuf), &temp, &overlappedwr );
, в моем:
Код:
WriteFile(Win_Handle, (void*)data, (DWORD)maxSize, & bytesWritten, newOverlapWrite)
Похоже единственный способ решить проблему без написания своего велосипеда - вытащить в public Win_Handle, указывающий на порт, и работать с ним напрямую через WinAPI.
Алгоритм - бесплатен. Поиск багов - бесплатен. Реализация алгоритма - за отдельную плату.
На форуме помогают советами и объясняют, а не пишут на халяву программы, лабы, курсачи и т.д. (c)
Vanta11a вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
как сделать RTS? Vadim_U Свободное общение 18 27.07.2010 00:05
Задача. Работа с псевдослучайными последовательностями (ПСП). Работа с цветом. 0101 Помощь студентам 3 17.12.2009 23:57
Работа с webbrowser - Фреймы, работа с конкретным феймом в фрейме NewDelphi Фриланс 2 08.10.2009 11:00
Многопользовательская RTS+RPG SaintlyHawk Фриланс 1 13.02.2009 22:13