Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Чтение информации из Com (перевод кода С на С++), использованием goto - C++&Qt  
:(
    Опции темы
krounis
  Дата 13.5.2017, 21:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 13.5.2017

Репутация: нет
Всего: нет



Нужно перевести с Си
Код

char YesStop=0;
char SSS[80];
unsigned Ready;
int W;
Ready=1;
byte Cur_Count;
BOOL Read_ADC_Expos(int *Data_ADC_1,int *Data_ADC_2 )
{
int W;
byte Ready;
loop:
if (YesStop) return TRUE;

Write_Data[0]=0x81; // читаем тек счетчик и сравниваем c Cur_Count
Write_Data[1]=0;
Write_Data[2]=0xd6;
Write_Data[3]=0;
Write_Data[4]=0;
Write_Data[5]=0;
Write_Data[6]=1;

if (!Send_Pack(Write_Data,Read_Data)) return FALSE;
Ready = Read_Data[6];
if (Ready!=Cur_Count)  //  можно считывать данные  
{
Cur_Count=Ready;
Write_Data[0]=0xe1; // читаем
Write_Data[1]=0;
Write_Data[2]=0xdb;
Write_Data[3]=0;
Write_Data[4]=0;
Write_Data[5]=0;
Write_Data[6]=0;
if (!Send_Pack(Write_Data,Read_Data)) return FALSE;
W=Read_Data[5];
W&=0x0f;
W<<=8; 
W+=Read_Data[6];
*Data_ADC_2 = (int)(((double)W - BSig)/(ASig-BSig)*4000);
W=Read_Data[3];
W&=0x0f;
W<<=8; 
W+=Read_Data[4];
*Data_ADC_1 = (int)(((double)W - BRef)/(ARef-BRef)*4000); 
sprintf(SSS," ADC_1 = %d ADC_2 = %d ",*Data_ADC_1,*Data_ADC_2);
WriteLog(SSS);
return TRUE;
}
else // Ready = Cur_Count
{
if (YesStop) return TRUE; 
goto loop;
}
}
BOOL White_End_Pause(byte *Cur_Count)
{
int W;
byte Ready;
loop:
if (YesStop) return TRUE;
Write_Data[0]=0x81; // читаем тек счетчик и сравниваем c Cur_Count
Write_Data[1]=0;
Write_Data[2]=0xd6;
Write_Data[3]=0;
Write_Data[4]=0;
Write_Data[5]=0;
Write_Data[6]=1;
if (!Send_Pack(Write_Data,Read_Data)) return FALSE;
Ready = Read_Data[6];
if (Ready==*Cur_Count) 
{
//----------------------------------------------- надо ли что то делать 
goto loop;    //  можно считывать данные  
}
else // Ready! = Cur_Count
{

*Cur_Count=Ready;
    
    return TRUE; 
}
}

Нужно перевести код который выше на код С++ (начало положено, но код работает с ошибками, что подтверждается логами см. вложения)
Код

void TabWindow::on_expButton_clicked() //функция эксперимента
{
    //открытие и установка параметром Com порта
    com1->open(QIODevice::ReadWrite);
    com1->setFlowControl(QSerialPort::NoFlowControl);
    com1->setBaudRate(QSerialPort::Baud115200);
    com1->setStopBits(QSerialPort::OneStop);
    com1->setDataBits(QSerialPort::Data8);
    com1->setDataTerminalReady(false);
    com1->clear();

    //Experiment writepack 2
    expWrite2.resize(9);
    expWrite2[0] = 0x55;
    expWrite2[1] = 0x81;
    expWrite2[2] = 0;
    expWrite2[3] = 0xc2;
    expWrite2[4] = 0;
    expWrite2[5] = 0;
    expWrite2[6] = 0;
    expWrite2[7] = 0;
    expWrite2[8] = expWrite2[1];
    for (int i=2; i<8; i++)
        expWrite2[8]=expWrite2[8]+expWrite2[i];

    //Experiment readpack 1
    expRead1.resize(9);
    expRead1[0] = 0x55;
    expRead1[1] = 0x81;
    expRead1[2] = 0;
    expRead1[3] = 0xD6;
    expRead1[4] = 0;
    expRead1[5] = 0;
    expRead1[6] = 0;
    expRead1[7] = 1;
    expRead1[8] = expRead1[1];
    for (int i=2; i<8; i++)
        expRead1[8]=expRead1[8]+expRead1[i];

    //Experiment readpack 2
    expRead2.resize(9);
    expRead2[0] = 0x55;
    expRead2[1] = 0xE1;
    expRead2[2] = 0;
    expRead2[3] = 0xDB;
    expRead2[4] = 0;
    expRead2[5] = 0;
    expRead2[6] = 0;
    expRead2[7] = 0;
    expRead2[8] = expRead2[1];
    for (int i=2; i<8; i++)
        expRead2[8]=expRead2[8]+expRead2[i];

    ARef = 4000;
    BRef = 0;
    ASig = 4000;
    BSig = 0;
    QFile adcFile("ADC data.csv");

    expResult.resize(9);
    expResultP.resize(9);
    
    //запись байтов по адресу 0xC2 для начала стадии считывания данных
    com1->write(expWrite1);
    com1->waitForBytesWritten(50);
    com1->waitForReadyRead(50);
    expResult = com1->readAll();

    //с данной строки логи отправляемые и получаемые в ответ 
    //программой на С++ не совпадают с логами на Си 
    //Ошибка в том что с данной строки цикл должен повторятся и привязываться к тому что условие выполнения цикла 
    //это то что в ответном байте от блока по адресу 0хd6 8 бит с каждым шагом цикла увеличивается на 1цу в 16 системе 
    int count=0;
    expSignal[0]=count;
    while ((int)expSignal[0]<14)
    {
    com1->write(expWrite2);
    com1->waitForBytesWritten(50);
    com1->waitForReadyRead(50);
    expResult = com1->readAll();
    //expSignal[0]=count+1;

    //отправление байта для проверки можно ли проводить считывание по адресу 0хd6
    flag1:
    com1->write(expRead1);
    com1->waitForBytesWritten(100);
    com1->waitForReadyRead(100);
    expResultP = com1->readAll();
    expSignal[0] = expResultP[7];
    if ((int)expSignal[0]!=(int)expSignal[0]+1) goto flag1;
    else goto flag2;

    //если прошлый байт изменился в 8 бите на 1, считываем данные
    flag2:
    com1->write(expRead2);
    com1->waitForBytesWritten(100);
    com1->waitForReadyRead(100);
    expResult = com1->readAll();

    //операции преобразования полученных данных
        expRes1 = 0;
        expRes1 = expResult[4];
        expRes1 = expRes1 & 0xf;
        expRes1 = expRes1 << 8;
        expRes1 = expRes1 + expResult[5];
        expRes1 = (((double)expRes1 - BRef) / (ARef - BRef) * 4000);
        expRes2 = 0;
        expRes2 = expResult[6];
        expRes2 = expRes2 & 0xf;
        expRes2 = expRes2 << 8;
        expRes2 = expRes2 + expResult[7];
        expRes2 = (((double)expRes2 - BSig) / (ASig - BSig) * 4000);

        ADC1.resize(count+1);
        ADC2.resize(count+1);
        ADC1[count]=expRes1;
        ADC2[count]=expRes2;
        count++;
}
         com1->clear();
         com1->close();
}

Полное описание проблемы:
Всем доброго времени суток! 
Перейду сразу к делу, есть два фотоприемника (ФП), которые считывают данные при засветки их лазером. Оба ФП подключены к блоку управления, тот в свою очередь подключается к ПК по Com порту. Задача импульсно в течении определенного времени считывать данные с ФП и передавать через Com порт и записывать в массив данных.

Сам процесс считывания уже реализован, но по всей видимости неверно. Есть так же уже реализованное ПО для той же самой задачи но на Cи, нужно переписать функцию для С++ либо написать свою. 
Я попробовал написать свою и столкнулся с проблемой использования так называемых "меток" и оператора goto. Зачем, собственно, использовать те самые метки. Отвечаю - обмен данными через ком порт идет следующим образом: с ПК отсылается байт из 9 битов, в ответ приходит такой же байт но с измененными (если это нужно) данными. А оператор goto нужен для того чтобы постоянно отправлять байты, до тех пор пока блок не откликнется прислав в ответном байте измененный бит (8 бит), это даст нам понять что он готов передать данные, потом отправляем ему пустой байт по определенному адресу (0xdb) и в ответ прилетает такой же байт, но с нужными данными, затем работа устройства повторяется указанное пользователем время и количество замера данных.

Основная проблема в том, что я, как новичек, не совсем понимаю как работать с goto, а обычный цикл здесь не воспринимается устройством (мы зависим от его быстродействия), ну и в уже работающей программе на Си как раз используются эти "метки".

Прошу помощи в выявлении ошибок в коде, на основании логов (во вложенных файлах - логи обмена данными по RS232 во время проведения эксперимента) Write и Read логов записанных в порт и считанных с него соответственно.
А так же прилагаю код правильной и рабочей реализации этой задачи на Си и неправильно работающий код на С++.

полный код на си
полный неправильный код на с++
Логи записи данных в ком порт обеими программами
Логи считывания данных из ком порта обеими программами
Протокол обмена данными





Это сообщение отредактировал(а) krounis - 13.5.2017, 21:19
PM MAIL   Вверх
xvr
Дата 15.5.2017, 15:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



Во первых - вы поместили свой вопрос не в том разделе. COM в этом разделе - это Component Object Model, и не имет ничего общего с COM портом.
Во вторых - программа на С ужастна. Никаких goto там не надо, а нужны обычные циклы (причем бесконечные). Похоже, что ее переписывали с Фортрана  smile 
В третьих - GUI программы так не пишут - ваше чтение прибора начнется сразу после нажатия кнопки в GUI, при этом сама GUI зависнет и будет висеть до окончания процесса. Вам нужен отдельный поток для чтения (Thread)

PM MAIL   Вверх
tzirechnoy
Дата 15.5.2017, 21:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1173
Регистрация: 30.1.2009

Репутация: нет
Всего: 16



1) Ваш код не компилируется. По очевидным причинам -- поскольку бОльшая часть его не приведена. Не думаю, что кому-нибудь из местных старожылов будет интересно телепатировать, что там было написано, потому помощи по коду Вы вряд ли дождётесь.

(Прямым текстом: выделите минимальный компилирующийся пример, который показывает вашу проблему).

2) А зачем вам вообще переводить с т.н. "С" на т.н. "C++"? Заметная часть кода на C будет вполне работать на C++, остальное потребует минимальных косметических правок, на которые укажэт компилятор.
Если для развлечения -- то... Ну, будем считать что поразвлекаться так у вас не получилось. А если там какая-то другая цэль -- то скажыте, можэт вы вообще не в ту сторону копаете.

3) По поводу goto -- его использование в оригинальном коде обусловлено только тем, что автор того кода не очень умел программировать. Ну, чуть лучшэ, чем Вы сейчас, но тожэ не очень. Это строго единственная причина. Более того, перевести приведённый код на цыкл while() можно дажэ без известной методологии по разбиению программы на блоки с одним входом и одним выходом и обрамления этого в конечный автомат -- а на одной только интуицыи. Там и так это goto стоит в концэ блока, можно ввести его условия в while()

3.5) Но это в общем вообще не проблема -- поскольку у вас не с goto как таковым проблема, а с тем, что Вы не очень понимаете, что делает оригинальная программа и что -- Ваша. Постарайтесь понять. Отладчик, профили и отладочная печать (не только данных, но и всего остального состояния программы, которое меняется) -- и работайте. Основная работа программиста в общем-то.

4) Никаких байтов из 9 битов у Вас, к счастью, нет. Не пугайте так -- тем более, что писишные чипы и драйвера этого и не поддержывают обычно.

5) И да, логи в .docx -- это конечно ужасно. Не делайте так большэ. То, что в jpeg было бы ещё хужэ -- это не оправдание. И, конечно, журналируйте отправку и приём в один файл -- ну там, с пометкой какой-нибудь, вот это всё. А то пытаться это сопоставить -- тожэ та ещё развлекуха.

PS И да, тут говорят про threads, вопросы залипания итэрфейса... Не парьтесь пока, не до того Вам.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: COM/DCOM/ActiveX/ATL/CORBA | Следующая тема »


 




[ Время генерации скрипта: 0.1379 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.