Russian Qt Forum

Qt => Дополнительные компоненты => Тема начата: Larry от Ноябрь 16, 2017, 16:14



Название: [РЕШЕНО]QModbusRtuSerialMaster ошибка "Resource error"
Отправлено: Larry от Ноябрь 16, 2017, 16:14
Добрый день, форумчане.
При работе с QModbusRtuSerialMaster иногда возникает ошибка "Resource error", например при переходе между вкладками программы или смене активного окна при нажатия ALT+TAB...можно нажать несколько раз переключение, но ошибка рано или поздно происходит и без переподключения к порту не обойтись...Чем может быть вызвана эта ошибка? В какую сторону копать? Второй день что ни делаю, ничего не помагает...
Спасибо.


Название: Re: QModbusRtuSerialMaster ошибка "Resource error"
Отправлено: Larry от Ноябрь 16, 2017, 18:11
склоняюсь к тому что это из-за того, что все в одном потоке идет. Пока не работал с потоками и теперь не понятно как все это перенести безболезненно в отдельный поток...


Название: Re: QModbusRtuSerialMaster ошибка "Resource error"
Отправлено: kuzulis от Ноябрь 16, 2017, 18:55
ОС + версия ядра? Что за девайс? Какая версия Qt?


Название: Re: QModbusRtuSerialMaster ошибка "Resource error"
Отправлено: Larry от Ноябрь 16, 2017, 19:33
Windows 10 x64, Qt 5.9.0.
Устройство соединяется по RS485 (оно только разрабатывается).


Название: Re: QModbusRtuSerialMaster ошибка "Resource error"
Отправлено: Larry от Ноябрь 16, 2017, 21:35
что интересно, то есть программа, которую развиваю параллельно (эмулирует устройсво), то там связь по UART и все сделано через QSerialPort и таких проблем не наблюдалось...Может просто отказаться от QModbusRtuSerialMaster?! Но не хотелось бы этого делать, если есть уже готовый инструмент...


Название: Re: QModbusRtuSerialMaster ошибка "Resource error"
Отправлено: kuzulis от Ноябрь 17, 2017, 08:21
Цитировать
Qt 5.9.0.

возьми 5.9.2 попробуй, т.к. там были какие-то исправления для modbus (погугли на баг-трекере).

Цитировать
Устройство соединяется по RS485 (оно только разрабатывается).

я не про это, я про адаптер serial спрашиваю.. это usb/485, pci/485, что за девайс? MOXA? Если да, то какая.


Название: Re: QModbusRtuSerialMaster ошибка "Resource error"
Отправлено: Larry от Ноябрь 17, 2017, 08:25
Адаптер usb/485. Сейчас попробую скачать Qt5.9.2. Была проблема с закрытием порта в Qt5.8.0 - постоянно висело состояние ClosingState, может и здесь действительно что-то поменяли.


Название: Re: QModbusRtuSerialMaster ошибка "Resource error"
Отправлено: Larry от Ноябрь 17, 2017, 08:57
Жаль, но в Qt 5.9.2 тоже самое...Наверное все-таки придется попробовать засунуть QModbusRtuSerialMaster в отдельный поток...


Название: Re: QModbusRtuSerialMaster ошибка "Resource error"
Отправлено: kuzulis от Ноябрь 17, 2017, 09:28
Цитировать
Адаптер usb/485

Дровишки обновлял?


Название: Re: QModbusRtuSerialMaster ошибка "Resource error"
Отправлено: Larry от Ноябрь 17, 2017, 09:38
Обновлял...такое же поведение и на других компах, с другими адаптерами (разные чипы установлены)...


Название: Re: QModbusRtuSerialMaster ошибка "Resource error"
Отправлено: Larry от Ноябрь 17, 2017, 10:00
Очередной раз удалил дрова и перезакачал с сайта производителя (на всякий случай). Эффект тот же...


Название: Re: QModbusRtuSerialMaster ошибка "Resource error"
Отправлено: Larry от Ноябрь 17, 2017, 11:34
Набросал проект с созданием объекта QModbusRtuSerialMaster в отдельном потоке:
Код:
void MainWindow::serialPortCtrl()
{
    if(ui->pushButton->isChecked())
    {
        QThread* thread_device = new QThread;
        CModbus* newdevice     = new CModbus;
        
        newdevice->moveToThread(thread_device);
        newdevice->m_device.moveToThread(thread_device);
        
        connect(thread_device, SIGNAL(started()), newdevice, SLOT(connectModbusDevice()));
        connect(newdevice, &CModbus::disconnectDeviceFinish, thread_device, &QThread::quit);
        connect(newdevice, &CModbus::disconnectDeviceFinish, this, &MainWindow::disconnectDevice);
        connect(thread_device, &QThread::finished, newdevice, &CModbus::deleteLater);
        connect(newdevice, &CModbus::connectDeviceOk, this, &MainWindow::connectStateOk);
        connect(newdevice, &CModbus::errorDevice, this, &MainWindow::errorDevice);
        connect(this, &MainWindow::signalDisconnectDevice, newdevice, &CModbus::disconnectModbusDevice);
        connect(ui->pushButtonSend, &QPushButton::clicked, newdevice, &CModbus::modbusRequest);
        
        thread_device->start();
    }
    else
    {
        emit signalDisconnectDevice();
    }
}

И получаю при нажатии на кнопку отправления запроса
Код:
QObject::startTimer: Timers cannot be started from another thread

Код:
void CModbus::modbusRequest()
{
    QModbusDataUnit unit(QModbusDataUnit::InputRegisters, 64, 10);
    
    QModbusReply* reply;
    
    reply = m_device.sendReadRequest(unit, 0x01);
    
    if(reply)
    {
        if(!reply->isFinished())
        {
            connect(reply, &QModbusReply::finished, this, &CModbus::modbusReadReady);
        }
        else
        {
            delete reply;
        }
    }
    else
        emit errorDevice(m_device.errorString());
}

Таймеров не использую...


Название: Re: QModbusRtuSerialMaster ошибка "Resource error"
Отправлено: Larry от Ноябрь 19, 2017, 20:37
Переделал без использования QModbusRtuSerialMaster, чисто на QSerialPort без использования потоков, то все работает без зависаний...


Название: Re: [РЕШЕНО]QModbusRtuSerialMaster ошибка "Resource error"
Отправлено: kuzulis от Ноябрь 21, 2017, 08:57
Пиши им баг-репорт тогда, т.к. странно это (и спроси у них, а можно ли вообще использовать их modbus в другом потоке,
да и баг-репорт напиши все-же, как ты в поток переносил и прочее, настоятельно советую, т.к. мантейнеры qtserialbus адекватные).

QSP интерпретирует ResourceError в случаях когда:

1. Обнаруживаются ошибки ввода/вывода типа: ERROR_OPERATION_ABORTED, ERROR_DEVICE_REMOVED, ERROR_BAD_COMMAND, ERROR_INVALID_HANDLE.
2. Когда после успешного открытия и попытке вызвать ReadFile,WriteFile и прочее,  возвращается ошибка ERROR_ACCESS_DENIED.

Хорошо бы тебе проверить, какой нативный код ошибки генерится (надо в сорцы QSP тыкнуть qDebug() внутрь
QSerialPortPrivate::getSystemError(int systemErrorCode) и пересобрать и переустановить QSP). Я сам проверить, естественно, не смогу.