Russian Qt Forum
Май 01, 2024, 19:47 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало Форум WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  
  Просмотр сообщений
Страниц: [1]
1  Qt / Вопросы новичков / Re: QSerial приём данных : Ноябрь 08, 2020, 23:45
Всё!!!!!!!! Кажется дошло !!!!!
Спасибо что вытерпели меня Смеющийся Пошёл дерзать - о результате отпишусь
2  Qt / Вопросы новичков / Re: QSerial приём данных : Ноябрь 08, 2020, 21:18

не должна функция делать и запись и чтение, разделяй и переписывай код
и никаких sleep и waitForReadyRead - не нужно


Поскольку это мой дебют в QT - можно по подробнее: в чем проблема если даю запрос потом пауза и чтение (про GUI не надо рассказывать)

Нет. Догадываюсь, в чём у вас проблема. waitForReadyRead вам нужен тут только для того, чтобы хоть как то отдать время центральному процессору. Тут надо либо по-другому строить архитектуру (чтобы нормально использовать сигналы-слоты) либо в цикле (при ожидании) периодически вызывать QCoreApplication::processEvents.
Ну и, при полном приёме данных (после заполнения буфера полезными данными), лучше взвести какой-нибудь флаг. Либо выпустить сигнал. Хотя тут "на вкус и цвет все фломастеры разные" Улыбающийся
Может я заблуждаюсь - поправьте, когда данные приходят в COM порт они складываются сначала в буфер винды и выполнение этого процесса никоим образом не касается выполнения QTшного кода, а когда дело у QT доходит до забора данных с буфера COM порта - QT фактически забирает эти данные с памяти (с буфера винды) а не непосредственно с COM порта.

Как бы тема для новичков, но некоторые ответы просто "убивают" Плачущий

3  Qt / Вопросы новичков / Re: QSerial приём данных : Ноябрь 08, 2020, 17:10
Заголовочный файл нужен ?

mainwindow.cpp
Код:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "sendcom.h"

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

   QString PORT="COM4";
   sendCom.setPORT(PORT);// Устанавливаем номер порта
   if(!sendCom.InitPort())qDebug<<"Что то не получилось с "<<PORT;

   
   qDebug()<<"Получилось подключится к "<<PORT;


}
sendcom.cpp
Код:
#include "sendcom.h"
#include <QDebug>


SendCom::SendCom(QObject *parent) : QObject(parent)//,

{

//qDebug("Potok SendCom telo");
//qDebug()<<"Telo Thread:"<<QString::number((int)QThread::currentThreadId());
}

bool SendCom::InitPort()
{
    if(!InitSerial())return false;

    if(!SendAndRead())
    {
        serial->close();
        return false;
    }
    qDebug()<<PORT<<" Read:"<<QString(m_arrCom.toHex().toUpper());

        serial->close();
        return true;
}

bool SendCom::InitSerial()
{
    qDebug()<<"Init START "<<PORT;
    serial=new QSerialPort(this);
    serial->setPortName(PORT);
    serial->setBaudRate(QSerialPort::Baud38400);
    serial->setDataBits(QSerialPort::Data8);
    serial->setParity(QSerialPort::NoParity);
    serial->setStopBits(QSerialPort::OneStop);
    serial->setFlowControl(QSerialPort::NoFlowControl);

    if(!serial->open(QSerialPort::ReadWrite))
    {
        qDebug()<<"ERROR !!! Не могу открыть порт "<<PORT;
    return false;
    }


    connect(serial, SIGNAL(readyRead()), this, SLOT(read()));
    connect(serial, SIGNAL(error(QSerialPort::SerialPortError)),
                this, SLOT(errorSerial(QSerialPort::SerialPortError)));
    return true;
}

bool SendCom::SendAndRead()
{
   serial->clear();
   w_arrCom.clear();//Очищаем массив перед подготовкой пакета

w_arrCom = QByteArray::fromHex("010404020001913A");


quint8 lenRead=........;//Вычисление длины ответа от устройства


for (quint8 i=0;i<2;i++)//Две попытки отправки запроса и получения ответа
{
    qDebug()<<"Попытка №"<<QString::number(i+1);
  serial->write(w_arrCom);// Запись в последовательный порт

    this->thread()->msleep(qCeil(150));// Засыпаем, ожидая, пока микроконтроллер обработает данные и ответит.
  m_arrCom.clear();//Очищаем буфер перед приёмом данных

serial->waitForReadyRead(300);//Без этой команды данные не приходят в буфер от слова СОВСЕМ)))

      if (m_arrCom.size()==lenRead) break;
      else{
          qDebug<<"Ответ не подходит по длине Bytes read: "<<QString::number(m_arrCom.size())
                  <<" lenRead:"<<QString::number(lenRead);

}
      serial->clear();
}
if (m_arrCom.size()!=lenRead) return false;

return true;
}

void SendCom::read()
{

//qDebug()<< "Доступно: "<<serial->bytesAvailable();
        m_arrCom += serial->readAll();
}

void SendCom::errorSerial(QSerialPort::SerialPortError err)
{
    qDebug()<<"SendCom Error: "+serial->errorString();//QString::number(err);
}

void SendCom::setPORT(QString m_PORT)
{
    if (PORT == m_PORT)
        return;

    PORT = m_PORT;
}
4  Qt / Вопросы новичков / Re: QSerial приём данных : Ноябрь 08, 2020, 15:09
Цитировать
Трудно гадать без исходников, но по симптомам - отсутствует цикл обработки событий.
Код в первом посте
http://www.prog.org.ru/index.php?topic=32856.msg243311#msg243311
 изменение времени задержки проблему появления ошибки таймаута не решают.
Код обработки ошибок:
Код:
    connect(serial, SIGNAL(error(QSerialPort::SerialPortError)),
                this, SLOT(errorSerial(QSerialPort::SerialPortError)));

void SendCom::errorSerial(QSerialPort::SerialPortError err)
{
    qDebug()<<"SendCom Error: "+serial->errorString();//QString::number(err);
}
5  Qt / Вопросы новичков / Re: QSerial приём данных : Ноябрь 08, 2020, 13:24
Спасибо всем кто отписался.... Свистков у меня 2 - мой на FTDI, и клиентский на PL2303 - поведение одинаковое. Самый стабильный приём получился при приёме данных по сигналу readReady(). Один из моментов которые я не могу понять это почему этот сигнал появляется только после пользования waitForReadyRead(), но больше всего БЕСИТ !!!!!!!!!!! появление ошибки таймаут после пользования waitForReadyRead(), причём независимо от длительности задержки. Версия QT 5.15.1. Программа проверялась и на 10ке и на 7ке. Железо на 10ке значительно сильнее, но при этом по сигналу readReady() на 10ке всегда принимается исключительно по 1му байту, в то время как на 7ке при приёме пакета 7 байт за один раз залетало и 4 байта(размер буфера и задавал и не задавал) - этот момент также непонятен....
Может комуто мои изыскания будут полезны..........
P.S. Весь гемморой начался после того как рабочая программа с использованием QModbusRtuSerialMaster на I5 не захотела работать на более слабом железе и пришлось связь по MODBUS реализовывать через QSerialPort
6  Qt / Вопросы новичков / Re: QSerial приём данных : Ноябрь 06, 2020, 22:34
Считывал данные не юзая сигнал readyRead()?
Или вообще не юзая QSerialport?

Перенёс проект на Win10 - поведение точь точь как и на семёрке....... Версия QT везде 5.15. Как то странно чтобы такие "детские" баги до сих пор имели место..........
Может ктото из гуру всё таки подскажет куда копать ?
7  Qt / Вопросы новичков / Re: QSerial приём данных : Ноябрь 06, 2020, 20:52
Не на семёрке такое, случайно?
Так точно - на семёрке)). Есть ещё комп с 10й и с QT, могу попробовать и там.
8  Qt / Вопросы новичков / QSerial приём данных : Ноябрь 06, 2020, 19:32
Если не затруднит когото кто досконально знает работу QSerial объясните пожалуйста как правильно принимать данные. Пересмотрел, перегуглил, перепробовал разные варианты, но так и не понял как это правильно делать Шокированный. Можно ли принимать данные не используя сигнала
Код:
readyRead()
- у меня не получилось. В замешательстве. Сигнал
Код:
readyRead()
у меня испускается только после выполнения
Код:
serial->waitForReadyRead(100);
Число принимаемых данных небольшое 10-50 байт. Данные принимаются после отправки запроса (с этим проблем нет). Самое неприятное (что собственно и подвигло к написанию данного поста) это возникновение ошибки "TimeoutError" после выполнения команды waitForReadyRead. Значение задержки на появление ошибки не влияет. Данные принимаются полностью и с ошибкой "TimeoutError" следующим кодом:
Код:
    connect(serial, SIGNAL(readyRead()), this, SLOT(read()));
.
//Подготовка запроса для COM порта
.
.
    lenRead=.....//Расчёт длины пакета от микроконтроллера
    serial->write(m_arrCom);// Запись запроса в последовательный порт
    this->thread()->msleep(100);// Засыпаем, ожидая, пока микроконтроллер обработает данные и ответит.
  m_arrCom.clear();//Очищаем буфер перед приёмом данных
  serial->waitForReadyRead(300);
      if (m_arrCom.size()!=lenRead)
          outLog("Ответ не подходит по длине Bytes read: "+QString::number(m_arrCom.size())
                  +" tim:"+QString::number(tim_read.elapsed())+" lenRead:"+QString::number(lenRead));

void SendCom::read()
{
        m_arrCom += serial->readAll();
}
9  Qt / Вопросы новичков / Re: QT 5.15 не хочет принять код стандартного примера : Сентябрь 02, 2020, 12:40
Смотрел я документацию... Если бы всё понял и был бы не новичком, не задавал бы глупых вопросов уважаемым и занятым людям.........
Строка на которую указали - это уже были истерические )) попытки исправить ситуацию  Смеющийся(просто вставил две строки из похожего кода чтобы убедится что проблема не в компиляторе). Эта строка и предыдущая к данному коду не относятся....
10  Qt / Вопросы новичков / QT 5.15 не хочет принять код стандартного примера : Сентябрь 02, 2020, 11:23
С помощью примера из просторов сети хочу разобраться с TCP соединением двух машин. Пример клиента скомпилился нормально, а пример сервера уже при написании ругается....
Код:
void MyServer::slotNewConnection()
{
    QTcpSocket* pClientSocket = m_ptcpServer->nextPendingConnection();
    connect(pClientSocket, SIGNAL(disconnected()),
            pClientSocket, SLOT(deleteLater())
           );
    connect(pClientSocket, SIGNAL(readyRead()),
            this,          SLOT(slotReadClient())
           );

    sendToClient(pClientSocket, "Server Response: Connected!");
}
void MyServer::slotReadClient()
{
    QTcpSocket* pClientSocket = (QTcpSocket*)sender();
    QTcpSocket *tcpSocket = (QTcpSocket*)sender();
    QDataStream clientReadStream(&tcpSocket);
    QDataStream in(pClientSocket);
    in.setVersion(QDataStream::Qt_5_7);
    for (;;) {
        if (!m_nNextBlockSize) {
            if (pClientSocket->bytesAvailable() < sizeof(quint16)) {
                break;
            }
            in >> m_nNextBlockSize;
        }

        if (pClientSocket->bytesAvailable() < m_nNextBlockSize) {
            break;
        }
        QTime   time;
        QString str;
        in >> time >> str;

        QString strMessage =
            time.toString() + " " + "Client has sended - " + str;
        m_ptxt->append(strMessage);

        m_nNextBlockSize = 0;

        sendToClient(pClientSocket,
                     "Server Response: Received \"" + str + "\""
                    );
    }
}
uploads
Страниц: [1]

Страница сгенерирована за 0.054 секунд. Запросов: 24.