Russian Qt Forum

Qt => Общие вопросы => Тема начата: i_rik_mik от Октябрь 09, 2014, 10:33



Название: QSerialPort не работает
Отправлено: i_rik_mik от Октябрь 09, 2014, 10:33
Доброго времен суток.
Передаю файл через ком порт
вначале идет заголовок с командой  размером и имя файла
устанавливаю апартное управление
код с настройками и openSerialPort тиснул из примера "terminal".
Код:
qint64 len = serial->write((char*)buffer, inBytes);
len всегда == inBytes тиво все пучком.
но почти всегда байтов не хватает до размера файла и чем больше файл тем больше байт не хватает
а бывает что все нормально, но это как правило на небольшом файле(не хватает из середины файла )
после отправки всего файла ставлю
Код:
 serial->flush();
кстати если после write поставить flush в цикле передачи
то все упадет с критической ошибкой  Resource temporarily unavaible

увеличение размера буффера приема
Код:
serial->setReadBufferSize(LEN_BUF+LEN_BUF);
ни к чему не приводит
работа проверял пока ток под Linux,

Мое мнение надо писать все самому, но мне надо кросплатформенность (много писанины)
QSerialPort -был выход ради него сменил 4 на 5 короче разочарование


Название: Re: QSerialPort не работает
Отправлено: kuzulis от Октябрь 09, 2014, 11:36
Бла бла бла. Версия QtSerialPort, ОС?

Код св студию.

Цитировать
Мое мнение надо писать все самому, но мне надо кросплатформенность (много писанины)
QSerialPort -был выход ради него сменил 4 на 5 короче разочарование

Нет проблем - пишите сами.
По секрету: он работает и на Qt4. Ваше разочарование в нежелании гуглить и читать документацию.

UPD: Если у вас есть что-то по-делу, то давайте разбираться, если нет - то проходите мимо.


Название: Re: QSerialPort не работает
Отправлено: i_rik_mik от Октябрь 09, 2014, 13:04
буду рад помощи

код для отправки файла
Код:
void Chat::on_but_send_file_clicked()
{
    unsigned char buffer[LEN_BUF];
    QString file = QFileDialog::getOpenFileName(this, tr("Выбирете файл"), QDir::homePath() );

    if (file.isEmpty())
        return;
    QFile srcFile(file);

    buffer[0] = 127;
    partition_int(&buffer[1], int(srcFile.size()));
    file = lastDir(srcFile.fileName());


    QTextCodec *koiCodec = QTextCodec::codecForName("KOI8-R");
    QByteArray data = koiCodec->fromUnicode(file);

    memcpy(&buffer[5], data.data(), data.size());
    int len = 5 + data.size();
    buffer[len] = '\n';
    len++;

    if (!srcFile.open(QFile::ReadOnly))
    {
         QMessageBox::critical(this, tr("Error"), tr("Не могу открыть файл ") + file);
         return ;
    }
    serial->write((char *)buffer, len);
    serial->flush();

    //sleep(1);
    memset(buffer, 0, LEN_BUF);

    mLen = 0;
    while (!srcFile.atEnd())
    {
        qint64 inBytes = srcFile.read((char*) buffer, LEN_BUF);

        if(inBytes > 0)
        {
            qint64 len = serial->write((char*)buffer, inBytes);
            serial->flush();
            if(len != inBytes)
            {
               mLen += len;
               sleep(1);
               if (inBytes-len != serial->write((char*)&buffer[len], inBytes-len))
               {
                   QMessageBox::critical(this, tr("Error"), tr("Не могу отправить данные"));
                   serial->flush();                 
                   srcFile.close();
                   return;
               }

            }
            else
                mLen += inBytes;
            //serial->flush();
        }
        else if(inBytes < 0)
        {
            QMessageBox::critical(this, tr("Error"), tr("Не могу прочитать данные"));
            serial->flush();           
            srcFile.close();
            return;
        }
    }
    srcFile.close();
    sleep(1);
    serial->flush();
   
    //выводим ожидание
    mes->setWindowTitle(tr("Ожидание подтверждения"));
    mes->setText(tr("Передано ") + QString::number(mLen) + tr(" байт"));
    mes->show();
}

код для приема
Код:
void Chat::accumulete_data(const QByteArray &ba)
{
    last = last + ba;   

    char ch = 127;
    int k = last.indexOf(ch);
    if(k != -1)
    {
        if(last.at(k+1) == '\n')
        {
            mes->close();
            mes->hide();
            last.clear();
            serial->clear();
            return;
        }
        mFlagFile = 1;
        show_chat(last.left(k));
        last.remove(0,k+1);
    }

    k = last.indexOf('\n');
    if(k != -1)
    {
        if(mFlagFile == 1)
        { //устанавливаем прием файла
            capture_int((unsigned int*)&mSize, (unsigned char*)last.data());
            last.remove(0,4);
            k = last.indexOf('\n');
            QByteArray temp = last.left(k);
            last.remove(0,k+1);
            recv_file(temp);
        }
        else
        {
            show_chat(last.left(k+1));
            last.remove(0, k+1);
        }
    }
}

void Chat::recv_file(const QByteArray &ba)
{
    QTextCodec *koiCodec = QTextCodec::codecForName("KOI8-R");
    QString str = koiCodec->toUnicode(ba);
    QString file = QDir::homePath() + QDir::separator() + str;
    progress->setLabelText(tr("Прием файла ") + str);
    progress->setMaximum(mSize);   
    int k = 0;
setname_label:
    dstFile.setFileName(file);
    if(dstFile.exists())
    {
        file = file + QString::number(k);
        k++;
        goto setname_label;
    }
    dstFile.open(QFile::WriteOnly);
    mFlagFile = 2;
    mLen = 0;
    if(!last.isEmpty())
    {
        mLen = last.count();
        dstFile.write(last.data(), last.count());       
        last.clear();
    }
    progress->setValue(mLen);
    progress->show();
}
void Chat::readData()
{
    QByteArray ba = serial->readAll();
    if(mFlagFile == 2)
    {
        //складываем все в файл
        int k = mLen + ba.count();
        if(k >= mSize)
        {
            k = mSize - mLen;
        }
        else
        {
            k = ba.count();
        }
        dstFile.write(ba, k);
        mLen += k;
        progress->setValue(mLen);

        if(mLen == mSize)
        {
            mFlagFile = 0;
            progress->close();
            dstFile.close();
            //посылаем подтверждение
            ba.resize(2);
            ba.append((char )127);
            ba.append('\n');
            //serial->clear();
            serial->write(ba);
            serial->flush();
        }
    }
    else
        accumulete_data(ba);
}

connect(serial, SIGNAL(readyRead()), this, SLOT(readData()));



Название: Re: QSerialPort не работает
Отправлено: i_rik_mik от Октябрь 09, 2014, 13:08
OC Linux Mint 15 (i686) kernel 3.8.0-19
Qt 5.3.2


Название: Re: QSerialPort не работает
Отправлено: kuzulis от Октябрь 09, 2014, 14:13
1. Переделайте все в "асинхронном" виде (не используйте sleep и прочие вещи).
2. Не используйте flush (это сомнительная затея)
3. Не используйте flow control (никто не проверял это на практике).
4. Не трогайте readBufferSize свойство (оно должно быть нулевым)

Цитировать
кстати если после write поставить flush в цикле передачи
то все упадет с критической ошибкой  Resource temporarily unavaible

Serial port реализован на каком чипе?


Название: Re: QSerialPort не работает
Отправлено: i_rik_mik от Октябрь 10, 2014, 10:56
sleep - это от отчаяния ))
flush - нормально работет если использовать чистый С (имеется ввиду функция flush(int fd) ) я думал что это тоже самое но нет
flow control - все работает проверял тыс раз
все передается в асинхронном режиме
И самое интересное под Windows Xp sp3 мой код работает.

Что касается чипа - 1 Ком порт от материнской платы что там за чип не заню
2 от Most Chip PCI (на 2 порта)