LINUX.ORG.RU

не приходит сигнал readyRead

 ,


0

1

Совершенно невероятная проблема, я работал с QSerialPort не один год, а сейчас даже если порт открывается, сигнал коннектится, то readyRead не срабатывает. Чудовищно простой код, запускается консольная программка, запускается a.exec, должно же приходить. Если открыть порт при помощи minicom то всё прекрасно работает, т.е. в плане железа всё окей. Более того, на оффтопике с Qt 5.4+ тоже всё хорошо уже с этой самой программой.

Подозреваю баг в самом Qt, однако посмотрите пожалуйста код, вдруг что-то новое упустил, может теперь требуется иначе. Нужна работа с портом по сигналам readyRead.

Смешно, но мой коллега тоже сейчас бьется уже несколько дней с проблемой, с этой же самой. В другом софте пашет, в винде Qt 5.4+ пашет, а на Linux нет.

Код: http://paste.org.ru/?jms2g2

#include <QCoreApplication>
#include <QDebug>
#include <scan.h>

int main(int argc, char *argv[])
{
	QCoreApplication a(argc, argv);

	int delay = 100;
	QString rs485_pn = "/dev/ttyUSB0";
	if(argc >= 2)
	{
		for(int i = 1; i < argc; i++)
		{
			QString arg(argv[i]);
			qDebug() << "arg=" << arg;
			if(arg.contains("/dev/")) rs485_pn = arg;
			if(arg.contains("COM")) rs485_pn = arg;
		}
	}

	QList<short> devs;
	devs.append(0x2001);
	devs.append(0x2002);
	for(int i = 0; i < 5; i++)
	{
		devs.append(0x3001 + i);
		devs.append(0x4001 + i);
	}
	for(int i = 0; i < 5; i++)
	{
		devs.append(0x1001 + i);
		devs.append(0x1011 + i);
	}
	for(int i = 0; i < 3; i++)
	{
		devs.append(0x6001 + i);
	}
	foreach(short dev, devs) qDebug("dev %04X", dev);

	qDebug() << "-----";
	qDebug() << "scan port=" << rs485_pn;
	qDebug() << "delay=" << delay << "ms";
	qDebug() << "-----";
	scan sc(devs, rs485_pn, delay);
	return a.exec();
}

Сигналы не ходят _без_ eventloop, до строки return a.exec(); нету у тебя eventloop. Или крути руками или можно сделать примерно так:

QCatchTest.h

#pragma once

#include <QCoreApplication>
#include <QTimer>
#include <QObject>
class QCatchTest : public QCoreApplication
{
	Q_OBJECT
	int m_argc;
	char** m_argv;
public:
	QCatchTest(int &argc, char *argv[]) : QCoreApplication(argc, argv) {
		m_argc = argc;
		m_argv = argv;
	}

public Q_SLOTS:
	void startCatch();
};

QCatchTest.cpp

#define CATCH_CONFIG_RUNNER // own main
#include "catch.hpp"

#include "QCatchTest.h"

void QCatchTest::startCatch()
{
// а вот тут он уже есть. 
	int result = Catch::Session().run( m_argc, m_argv);
	qApp->exit(result);
}

int main( int argc, char *argv[])
{
	QCatchTest app(argc, argv);
	QTimer timer;
	timer.setSingleShot(true);
	QObject::connect(&timer, SIGNAL(timeout()), &app, SLOT(startCatch()));
	timer.start(100);
        // тут eventloop ещё не запущен.
	return app.exec();
}

dhampire ★★★
()
Последнее исправление: dhampire (всего исправлений: 1)
Ответ на: комментарий от dhampire

Спасибо, это наводит на мысль, хотя я сильно удивлен. А так?

	scan sc(devs, rs485_pn, delay);

	QTimer timer;
	timer.setSingleShot(true);
	QObject::connect(&timer, SIGNAL(timeout()), &sc, SLOT(slot_start()));
	timer.start(100);
	return a.exec();
void scan::slot_start()
{
	qDebug() << "START!";
	slot_scan();
}
Действительно START! пишется, но ответы не приходят. С трудом верю что QSerialPort багнутый...

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от I-Love-Microsoft

QObject::connect(&timer, SIGNAL(timeout()), &sc, SLOT(slot_start()));

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

//З.Ы. Сказанное не относится к самой обсуждаемой проблеме, просто не могу не промолчать. :(

pathfinder ★★★★
()

1. Нужно проверить, есть ли какие-то ошибки, т.е. подконнектиться к error().

2. Какой Linux используется? Случаем не Ubuntu 14.04? Какое ядро?

kuzulis ★★
()
Ответ на: комментарий от I-Love-Microsoft

Попробуй настроить также flowcontrol.

port.setFlowControl(QSerialPort::NoFlowControl) - например.

И последовать 1 совету товарища kuzulis и проверить нет ли ошибок от порта.

dhampire ★★★
()
Ответ на: комментарий от dhampire

В итоге, как я и ожидал, после того как app.exec() получит управление после всех конструкторов, то все сигналы всё же будут обслужены. Так что такой «ловец начала eventloop-а» не требуется.

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от kuzulis

ДА! Это убунтопроблемушки! Я обновился

sudo apt-get install linux-generic-lts-vivid
и на 3.19.0-31-generic всё стало работать! И да, у меня реально Ubuntu 14.04.3 LTS, как-то не подумал на ядро, ведь с таким же ядром но чуть ранее - всё пахало!

Благодарю всех за ответы!

Чувствовал себя беспомощным дебилом пока пытался оживить примитивнейший код на базе QSerialPort, у которого не было очевидных причин не работать... =(((

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Это не ошибка, просто своп значений скорости работы, устройства работают одни на одной скорости, другие на второй.

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от pathfinder

Так и считаю :) Ибо connect, если он не сработал, то в рантайме в консоль вывалится ошибка, так что ;) Так как программа лишь тестовая, то я особо не усердствовал.

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

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от I-Love-Microsoft

connect, если он не сработал, то в рантайме в консоль вывалится ошибка

Можно ещё пользоваться новым синтаксисом из Qt5, чтобы быть уверенным уже во время компиляции.
И один раз попробовав connect с лямбдами уже не получается остановиться.

Suigintou ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.