Russian Qt Forum

Qt => Дополнительные компоненты => Тема начата: VAP от Август 03, 2009, 18:50



Название: не могу "отловить" константу 0x00 из COM порта
Отправлено: VAP от Август 03, 2009, 18:50
Добрый день! Возникла проблема следующего характера: при чтении данных из последовательного порта нужно "отловить" константу 0х00, а она почему-то читается как простой 0. Все остальные читаются правильно (в HEX формате). Может у кого-то возникала подобная проблема?


Название: Re: не могу "отловить" константу 0x00 из COM порта
Отправлено: lit-uriy от Август 03, 2009, 19:26
покажи как читаешь


Название: Re: не могу "отловить" константу 0x00 из COM порта
Отправлено: kuzulis от Август 03, 2009, 19:45
и в чем проблема то? как 0 преобразовать в 0х00 ? )


Название: Re: не могу "отловить" константу 0x00 из COM порта
Отправлено: VAP от Август 03, 2009, 20:07
Читаю так: (собственно "маркеры" 0x1F 0x1B читаются без проблем)
                     ..........................
                     for (qint64 i = 0; i < len; i++) {
                           qint64 n = port->read((char*)&buf_r, 1024);
                           if (n != -1)
                               buf_r[n] = '\0';
                                           
                           dataPtr = (unsigned char*)&buf_r;               
                           Code c(*dataPtr);
                           v = qVariantFromValue(c);                                                 
                           Code code = v.value<Code>();
                           switch (code) {
                           case 0x1F:
                              mode = 1;
                              stk.push(mode);
                           break;
                           case 0x1B:
                              mode = 2;
                              stk.push(mode);
                           break;
                           default: 
                              int marker = stk.top();
                              decode(marker, code); 
                           }
                      }
Смысл преобразования 0 в 0x00? На передающей стороне передается именно 0х00!


Название: Re: не могу "отловить" константу 0x00 из COM порта
Отправлено: denka от Август 03, 2009, 20:19
Уважаемый объясните мне далекому разницу между 0 и 0x00 если честно я вижу разницу тока в системе счисления.


Название: Re: не могу "отловить" константу 0x00 из COM порта
Отправлено: VAP от Август 03, 2009, 20:34
Разницы нет, я согласен, но вопрос был поставлен как "отловить" эту константу.
Если добавлю в код вариант 0х00 или 0, - не определяет. (0 - вижу в консоли отладки).


Название: Re: не могу "отловить" константу 0x00 из COM порта
Отправлено: denka от Август 03, 2009, 20:44
Хотелось бы увидеть код при котором case не реагирует на 0, а так же производиться вывод консоль(то есть вывод чего именно?).

Еще что такое Code

И к чему эти преобразования?

Код:
Code c(*dataPtr);
v = qVariantFromValue(c);                                                 
Code code = v.value<Code>();


Название: Re: не могу "отловить" константу 0x00 из COM порта
Отправлено: spectre71 от Август 03, 2009, 20:57
Наверное имеется ввиду что данные приходит ввиде строк "0x1F", "0x1B", "0x00", правильно?


Название: Re: не могу "отловить" константу 0x00 из COM порта
Отправлено: kuzulis от Август 03, 2009, 21:08
Цитировать
Читаю так: (собственно "маркеры" 0x1F 0x1B читаются без проблем)
                     ..........................
                     for (qint64 i = 0; i < len; i++) {
                           qint64 n = port->read((char*)&buf_r, 1024);
                           if (n != -1)
                               buf_r[n] = '\0';
                                          
                           dataPtr = (unsigned char*)&buf_r;                
                           Code c(*dataPtr);
                           v = qVariantFromValue(c);                                                
                           Code code = v.value<Code>();
                           switch (code) {
                           case 0x1F:
                              mode = 1;
                              stk.push(mode);
                           break;
                           case 0x1B:
                              mode = 2;
                              stk.push(mode);
                           break;
                           default:  
                              int marker = stk.top();
                              decode(marker, code);  
                           }
                      }
ужоснах :)

что за библиотеку используете?

и что за:
Код:
                           if (n != -1) 
                               buf_r[n] = '\0';
о_О  Зачем это? ??

и вообще...




Название: Re: не могу "отловить" константу 0x00 из COM порта
Отправлено: VAP от Август 04, 2009, 18:25
 Использую библиотеку qextserialport 1.1
 Представленная часть кода работоспособна

for (qint64 i = 0; i < len; i++) {
       qint64 n = port->read((char*)&buf_r, 1024); // вычитать из буфера содержимое
       if (n <= len)               
           dataPtr = (unsigned char*)&buf_r;               
           Code c(*dataPtr);     //отдельный класс Code для считывания 5 бит                 
            v = qVariantFromValue(c);                     
            Code code = v.value<Code>();
            switch (code) {
            case 0x00:   //вот здесь не определяет константу!
                  mode = 0;
                  stk.push(mode);
            break;
            case 0x1B:
                   mode = 1;
                   stk.push(mode);  // запись в стек
            break;
            case 0x1F:
                   mode = 2;
                   stk.push(mode);
            break;
            default: 
                   int marker = stk.top(); // чтение из стека
                   decode(marker, code); 
            }
            QTextStream out(stdout);  // Печать на консоль
            out << code;
}

При передаче данных, например: 0x00 0x01 0x03 0x27 0x04 0x31 0x22 0x24
Принимаю вот такую последовательность(на консоль): 00000100003000027000040000310000220000240000 (0x00 «разбивается» и нули добавляются в конец).  Почему так происходит именно с 0x00 не разобрался.


Название: Re: не могу "отловить" константу 0x00 из COM порта
Отправлено: VAP от Август 04, 2009, 18:34
Почему не отображается на форуме оператор присваимания для buf_r - большая загадка???


Название: Re: не могу "отловить" константу 0x00 из COM порта
Отправлено: verzer от Август 04, 2009, 19:23
Почему не отображается на форуме оператор присваимания для buf_r - большая загадка???
потому что [i] - это bb-тег курсива
нужно оформлять код соответсвующими тегами ([code] ..код.. [/code], либо [code=cpp]..C++/Qt код..[/code]), тогда и проблем не будет


Название: Re: не могу "отловить" константу 0x00 из COM порта
Отправлено: spectre71 от Август 04, 2009, 20:12
Телепаты все в отпуске!
Ты так ничего и не объяснил!
1) В каком виде приходят данные??
2) Что это за Code??
3) Что это такое
Code code = v.value<Code>();
switch (code) {
.......
}
что за Code и как с ним вообще может работать switch



Название: Re: не могу "отловить" константу 0x00 из COM порта
Отправлено: VAP от Август 04, 2009, 20:34
Код
C++ (Qt)
class Code  
{
public:
   Code() {}
   Code(const Code &code) { data = code; }
   Code(unsigned char ch) { data = ch; }
 
   operator unsigned char() const { return data & 0x1f; }
 
protected:
   unsigned char data;
};
 
Q_DECLARE_METATYPE(Code);
 
QDataStream &operator << (QDataStream &out, const Code &code);
QDataStream &operator >> (QDataStream &in, Code &code);


Название: Re: не могу "отловить" константу 0x00 из COM порта
Отправлено: kuzulis от Август 05, 2009, 08:04
и я шото не могу вникнуть в суть проблемы:  :)

1. зачем вообще использовать этот Code ???
2. Зачем читать вот так:
Код:
for (qint64 i = 0; i < len; i++) {
       qint64 n = port->read((char*)&buf_r, 1024); // вычитать из буфера содержимое
       if (n <= len) 
.....             
????
3. Зачем вообще все эти преобразования???

ЗЫ: я так и не понял что хотят, т.к. от всех этих преобразований теряю мыслю :)


Название: Re: не могу "отловить" константу 0x00 из COM порта
Отправлено: ритт от Август 05, 2009, 08:12
2. как этот код вообще работает? говоришь, что Code обрабатывает по пять бит, а читаешь килобайтовыми кусками...
или я что-то не доглядел?


Название: Re: не могу "отловить" константу 0x00 из COM порта
Отправлено: kuzulis от Август 05, 2009, 10:31
2 VAP ,

ты хоть сам понимаешь что хочешь? (что делаешь) ? :)


Название: Re: не могу "отловить" константу 0x00 из COM порта
Отправлено: VAP от Август 05, 2009, 20:24
 Привожу результаты моих исследований:
 
Код
C++ (Qt)
qint len = port->bytesAvailable();
//возвращает количество байт, которые доступны для чтения.
1. Из порта считываю количество байт, равное количеству приходящих символов(байтов). Символы 5 битовые в hex-формате. Все эти данные должны считываться через буфер. Размышления на счет размера буфера. Его размер, в моем случае  критичен, если будет меньше количества доступных для чтения байт (len). Большее количество символов, чем 1024 отправлено не будет. Еще можно поставить ограничение условием:
     
Код
C++ (Qt)
if (len > sizeof(buf_r))
                              len = sizeof(buf_r);
 

2. Если считывать побайтно, т.е.
 
Код
C++ (Qt)
qint64 n = port->read((char*)&buf_r, 1);
if (n <= len)                
     dataPtr = (unsigned char*)&buf_r;                
     Code c(*dataPtr);
     v = qVariantFromValue(c);                                                
     Code code = v.value<Code>();
     switch (code) {
     case 0x1B: // не определяет
         mode = 1;
         stk.push(mode);
     break;
     case 0x1F: // не определяет
         mode = 2;
         stk.push(mode);
     break;
     default:  
     marker = stk.top();
     decode(marker, code);
 
     QTextStream out(stdout);
     out << code;
     [\code]              
Служебные маркеры в этом случае не определяются. В варианте 1 и варианте 2 на консоль данные выводятся в десятичном формате, но в первом определяются по case маркеры, а во втором нет. Ну и общее, для обоих вариантов, почему удаляет нули в начале комбинации и добавляет их потом в конец всей комбинации.
0x1F     0x03   0x1B    0x16
000031 00003 000027 000022    будет  принято как  31000030000270000220000.
 
0x00     0x03   0x1B    0x16
00000   00003 000027 000022    принят так              0000030000270000220000.
 
хотя доверяя "выводу на консоль" в общем-то, все правильно: нули впереди просто удаляются за ненадобностью в десятичном представлении, а добавляясь в конец комбинации, сам нуль ничего не значит(хотя зачем тогда добавляет?).


Название: Re: не могу "отловить" константу 0x00 из COM порта
Отправлено: f-r-o-s-t от Август 05, 2009, 21:07
Код
C++ (Qt)
qint len = port->bytesAvailable();
//возвращает количество байт, которые доступны для чтения.
не знаю типа что слева от присваивания, но это не суть =)

Код
C++ (Qt)
 
     dataPtr = (unsigned char*)&buf_r;                
     Code c(*dataPtr);
     v = qVariantFromValue(c);                                                
     Code code = v.value<Code>();
 
Может все таки расскажешь смысл этих магических преобразований ?

нули впереди просто удаляются за ненадобностью в десятичном представлении, а добавляясь в конец комбинации, сам нуль ничего не значит(хотя зачем тогда добавляет?).
Ничего не удаляется и сзади не приписывается, это порядок байт меняется.


Название: Re: не могу "отловить" константу 0x00 из COM порта
Отправлено: kuzulis от Август 05, 2009, 22:00
Цитировать
Символы 5 битовые в hex-формате.
1. режим порта 5 Data Bits ?
2. если символ в hex формате , например "0x00", "0x01" и т.п. то это уже по 4 символа! :)
3. Если делаешь case 0x1B - то это значит что ЗНАЧЕНИЕ = 27 DEC! и т.п.
4. Если ты принимаешь байт = 0x1B - он определится по любому

Цитировать
Служебные маркеры в этом случае не определяются. В варианте 1 и варианте 2 на консоль данные выводятся в десятичном формате, но в первом определяются по case маркеры, а во втором нет. Ну и общее, для обоих вариантов, почему удаляет нули в начале комбинации и добавляет их потом в конец всей комбинации.
0x1F     0x03   0x1B    0x16
000031 00003 000027 000022    будет  принято как  31000030000270000220000.
 
0x00     0x03   0x1B    0x16
00000   00003 000027 000022    принят так              0000030000270000220000

если тебе передают байты с значениями  1F     0x03   0x1B    0x16 - то ты их так и примешь с этими же значениями и в этом же порядке!

ВЫВОД: значит ты что-то неправильно делаешь!

так что тебе конкретно передается? данные в виде:

[00][00][1F][00][00][03][00][00][1B][00][00][16] ?????

Скачай для начала сниффер COM портов и проверь в нем что тебе приходит! А потом уже разбирайся!
ЗЫ: и не путай тут нас :)


Название: Re: не могу "отловить" константу 0x00 из COM порта
Отправлено: VAP от Август 05, 2009, 22:09
передают байты со значениями  от 0x00 до 0x1F (32 комбинации). Что-то не правильно делаю, без сомнения.
Спасибо за подсказки и что такое сниффер COM портов?


Название: Re: не могу "отловить" константу 0x00 из COM порта
Отправлено: kuzulis от Август 06, 2009, 07:37
Цитировать
Спасибо за подсказки и что такое сниффер COM портов?
это такие программулины, которые позволяют:
1. Либо вручную набирать пакет данных и писать его в порт
2. Либо читать пакеты данных из порта
3. Либо, если у тебя есть неизвестный девайс и он работает с неизвестным приложением (имеется ввиду с неизвестным протоколом обмена) - то сниффер может трассировать (т.е. внедряться и показывать листинг обмена данными между неизвестным девайсом и неизвестным приложением) :)

В твоем случае нужен п.2. т.е ты береш сниффер, настраиваеш его на прием данных от девайса и смотриш что по настоящему приходит тебе от девайса.. А потом добиваешься такого же приема данных, используя не сниффер - а твое приложение.. т.е. подгоняешь под сниффер :) , ищеш ошибки и т.п.