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

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: QSerialPort не работает  (Прочитано 5286 раз)
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 короче разочарование
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #1 : Октябрь 09, 2014, 11:36 »

Бла бла бла. Версия QtSerialPort, ОС?

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

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

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

UPD: Если у вас есть что-то по-делу, то давайте разбираться, если нет - то проходите мимо.
« Последнее редактирование: Октябрь 09, 2014, 11:39 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
i_rik_mik
Гость
« Ответ #2 : Октябрь 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()));

Записан
i_rik_mik
Гость
« Ответ #3 : Октябрь 09, 2014, 13:08 »

OC Linux Mint 15 (i686) kernel 3.8.0-19
Qt 5.3.2
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #4 : Октябрь 09, 2014, 14:13 »

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

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

Serial port реализован на каком чипе?
« Последнее редактирование: Октябрь 09, 2014, 14:17 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
i_rik_mik
Гость
« Ответ #5 : Октябрь 10, 2014, 10:56 »

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

Что касается чипа - 1 Ком порт от материнской платы что там за чип не заню
2 от Most Chip PCI (на 2 порта)
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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