Форум программистов, компьютерный форум CyberForum.ru

C++: COM, OLE, ActiveX

Войти
Регистрация
Восстановить пароль
 
Krounis
2 / 2 / 0
Регистрация: 10.11.2016
Сообщений: 42
#1

Блок управления и rs 232 - C++ COM

10.11.2016, 12:20. Просмотров 694. Ответов 13
Метки нет (Все метки)

Доброго времени суток, форумчане. Сразу перейду к делу, есть блок управления двумя фотоприемниками и затворами, нужно программно обеспечить проведение эксперимента с использованием этих устройств, есть код на c# нужно переписать на c++, либо написать подобный, чем я и занялся.

Вступление:
Удаленный компьютер (PC) всегда мастер (master) на линии, устройство (УС) всегда раб (slave).

Обмен данными происходит в пакетном режиме.
Начало пакета это байт 0x55.

Первый байт – байт статуса пакета, распределение битов в этом байте:
биты 0 – 4 это адрес устройства (0x00..0x01F; 0..31),
биты 5 и 6 длина данных (бит 0x20 и бит 0x40):
0b00 – один байт
0b01 – двухбайтовое число (целое)
0b10 – резервный параметр
0b11 – четырехбайтовое число (плавающее)
бит 7 (0x80) определяет тип операции
1- чтение из прибора,
0 - запись в прибор
Второй и Третий байт – 16 разрядный адрес данных в приборе.
Второй байт - старший байт адреса,
Третий байт – младший байт адреса.
Байты 4, 5, 6, 7 – байты данных.
Для байтовых операций данные – это байт 7.
Для двухбайтовых операций – байты 6-7.
Байт 8 это последний байт – контрольная сумма.
Контрольная сумма это сумма байтов с первого по 8. Для вычисления контрольной суммы байты складываются как беззнаковые 8 битные числа (unsigned char).

Если тип операции – запись, то устройство (SLAVE) игнорирует байты данных.
Если тип операции чтение, то устройство (SLAVE) отправляет тот же пакет, только данные другие.
Поскольку PC всегда мастер, то обмен данными происходит только по команде со стороны PC.
Прибор в ответ отправляет такой же пакет.

Суть проблемы:
1) Serial port не отвечает на пакеты, или отвечает на предыдущие спустя несколько пакетов.
Пример:
Чтобы ввести устройство в режим "измерение" (идет считывание с фотоприемников, моргают затворы) нужно записать задержки в мс (в пределах 1 секунды) на 3 стадии работы:
stad1 - задержка на стадию 1 (время когда оба затвора открыты) это 2 байта (unsigned int) по адресу 0xDF

stad2 - задержка на стадию 2 (затвор 2 - закрыт; затвор 1 - открыт) это 2 байта (unsigned int) по адресу 0xE1

stad3 - задержка на стадию 3 (оба затвора закрыты) это 2 байта (unsigned int) по адресу 0xE3
Как я это реализовал:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
    //Delay 1 (байт для записи первой задержки)
    zad1.resize(9);
    zad1[0] = 0x55;
    zad1[1] = 0x21;
    zad1[2] = 0;
    zad1[3] = 0xDF;
    zad1[4] = 0;
    zad1[5] = 0;
    if (zad1in > 256) //условие если длительность задержки больше 256 (режим двух двухбайтовых числа)
    {
    zad1[6] = 1;
    zad1[7] = (zad1in - 256);
    }
    else //если длительность задержки меньше 256 (режим одного двухбайтового числа)
    {
    zad1[6] = 0;
    zad1[7] = zad1in;
    }
    zad1[8] = zad1[1];
    for (int i=2; i<8; i++)
        zad1[8]=zad1[8]+zad1[i];
 
 
    //Delay 2 (байт для записи второй задержки)
    zad2.resize(9);
    zad2[0] = 0x55;
    zad2[1] = 0x21;
    zad2[2] = 0;
    zad2[3] = 0xE1;
    zad2[4] = 0;
    zad2[5] = 0;
    if (zad2in > 256) //условие если длительность задержки больше 256 (режим двух двухбайтовых числа)
    {
    zad2[6] = 1;
    zad2[7] = (zad2in - 256);
    }
    else //если длительность задержки меньше 256 (режим одного двухбайтового числа)
    {
    zad2[6] = 0;
    zad2[7] = zad2in;
    }
    zad2[8] = zad2[1];
    for (int i=2; i<8; i++)
        zad2[8]=zad2[8]+zad2[i];
 
 
    //Delay 3 (байт для записи третьей задержки)
    zad3.resize(9);
    zad3[0] = 0x55;
    zad3[1] = 0x21;
    zad3[2] = 0;
    zad3[3] = 0xE3;
    zad3[4] = 0;
    zad3[5] = 0;
    if (zad3in > 256) //условие если длительность задержки больше 256 (режим двух двухбайтовых числа)
    {
    zad3[6] = 1;
    zad3[7] = (zad3in - 256);
    }
    else //если длительность задержки меньше 256 (режим одного двухбайтового числа)
    {
    zad3[6] = 0;
    zad3[7] = zad3in;
    }
    zad3[8] = zad3[1];
    for (int i=2; i<8; i++)
        zad3[8]=zad3[8]+zad3[i];
 
    //Запись
    com1->write(zad1);
    com1->write(zad2);
    com1->write(zad3);
В ответ устройство после каждый записи com1->write(...) должно отправлять такой же байт, но устройство отправляет ответ только на команду com1->write(zad1); (отслеживал в режиме HEX программой Advanced Serial Port Monitor)

Как исправить? (пробовал считывать командой com1->read(result, 9); толку нету, так же пробовал использовать функцию com1->waitForBytesWritten(100); после каждой записи, ситуация не поменялась)

Могу скинуть исходники на c# (там все работает как надо) и свои исходники если необходимо

Буду благодарен за любую помощь.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.11.2016, 12:20     Блок управления и rs 232
Посмотрите здесь:

Передача команд SCPI по RS-232 - C++ COM
Привет всем есть такая задачка нужно написать программу на (MFC)c++ для управления измерительными приборами через RS-232, в частности...

Блок управления микропрограммной структурой - Микропроцессоры
Добрый вечер всем,не знаю правильную ли выбрал тему,но нужна помощь. Нам дали задание,а я делал только жесткую связь и микропрограммную не...

Беспроводной блок управления нагрузками 220В - КИП, датчики
Приветствую. Ищу информацию о следующем девайсе. Требуется дистанционно (например, брелком) в радиусе примерно 30 метров...

Для чего нужен блок управления в блоке питания? - Блоки питания
для чего нужен блок управления в блоке питания. помогите пожалуйста!

Блок управления ст.машиной Bosh WOL2050 - мерцают все индикаторы - Стиральные машины
Мерцают все индикаторы) ...есть донор, старый блок с битыми дорожками, перепаял часть деталей, в части питания .... не помогло( ... Фото...

rs 232 - Delphi
нужна программа которая будет автоматически определять порт к которому подключенн, отсылалать по rs 232 и принимать байты

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
vxg
Модератор
3146 / 1948 / 214
Регистрация: 13.01.2012
Сообщений: 7,439
10.11.2016, 14:32     Блок управления и rs 232 #2
Krounis, что скрывает строчка com1->write(zad1) и как вы собственно принимаете данные?
Krounis
2 / 2 / 0
Регистрация: 10.11.2016
Сообщений: 42
10.11.2016, 15:04  [ТС]     Блок управления и rs 232 #3
vxg, com1->write(zad1) это запись в компорт байта первой задержки, принимать данные не обязательно, этими командами я даю понять устройству, что сейчас будет проходить запись/считывание данных с фотоприемников, при том что два затвора будут открываться и закрываться в определенные моменты. А вообще прием данных далее буду осуществлять:
C++ (Qt)
1
2
char Result[9];
com1->read(Result, 9);
Устройство должно мне ответить таким же пакетом, это будет означать что задержка записалась

P.S.
C++ (Qt)
1
2
3
4
5
6
7
8
9
//SerialPort
    com1 = new QSerialPort;
        com1->setPortName("COM1");
        com1->open(QIODevice::ReadWrite);
        com1->setFlowControl(QSerialPort::NoFlowControl);
        com1->setBaudRate(QSerialPort::Baud115200);
        com1->setStopBits(QSerialPort::OneStop);
        com1->setDataBits(QSerialPort::Data8);
        com1->setDataTerminalReady(false);
vxg
Модератор
3146 / 1948 / 214
Регистрация: 13.01.2012
Сообщений: 7,439
10.11.2016, 15:38     Блок управления и rs 232 #4
Krounis, попробуйте понизить скорость обмена. какие таймауты ставит QSerialPort не смотрели?
Krounis
2 / 2 / 0
Регистрация: 10.11.2016
Сообщений: 42
10.11.2016, 16:10  [ТС]     Блок управления и rs 232 #5
vxg, а как их посмотреть/поменять?
vxg
Модератор
3146 / 1948 / 214
Регистрация: 13.01.2012
Сообщений: 7,439
10.11.2016, 18:48     Блок управления и rs 232 #6
Krounis, если бы речь шла о winapi я бы сказал а в qt не знаю в свойствах объекта смотреть надо очевидно
Krounis
2 / 2 / 0
Регистрация: 10.11.2016
Сообщений: 42
10.11.2016, 19:29  [ТС]     Блок управления и rs 232 #7
vxg, хорошо, спасибо попробую, как я понимаю таймауты надо уменьшить?
vxg
Модератор
3146 / 1948 / 214
Регистрация: 13.01.2012
Сообщений: 7,439
11.11.2016, 06:22     Блок управления и rs 232 #8
Krounis, я думаю что они наоборот могут быть очень малыми
Krounis
2 / 2 / 0
Регистрация: 10.11.2016
Сообщений: 42
12.11.2016, 08:48  [ТС]     Блок управления и rs 232 #9
vxg, не нашел как настроить тайм-ауты((
vxg
Модератор
3146 / 1948 / 214
Регистрация: 13.01.2012
Сообщений: 7,439
12.11.2016, 17:58     Блок управления и rs 232 #10
Krounis, попробуйте для пробы кинуть запрос через winapi
Krounis
2 / 2 / 0
Регистрация: 10.11.2016
Сообщений: 42
13.11.2016, 18:51  [ТС]     Блок управления и rs 232 #11
vxg, а это как?)
vxg
Модератор
3146 / 1948 / 214
Регистрация: 13.01.2012
Сообщений: 7,439
14.11.2016, 11:18     Блок управления и rs 232 #12
Krounis, примерно так
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
        HANDLE h;
        DCB dcb;
        COMMTIMEOUTS cto; 
 
        h = INVALID_HANDLE_VALUE;
 
        memset(&dcb, 0, sizeof(dcb));
        memset(&cto, 0, sizeof(cto));
    
        dcb.DCBlength = sizeof(dcb);
    
        dcb.BaudRate = CBR_9600;
        dcb.fBinary = true;
        dcb.fParity = false;
        dcb.fOutxCtsFlow = false;
        dcb.fOutxDsrFlow = false;
        dcb.fDtrControl = DTR_CONTROL_DISABLE;
        dcb.fDsrSensitivity = false;
        dcb.fTXContinueOnXoff = false;
        dcb.fOutX = false;
        dcb.fInX = false;
        dcb.fErrorChar = false;
        dcb.fNull = false;
        dcb.fRtsControl = RTS_CONTROL_DISABLE;
        dcb.fAbortOnError = false;
        dcb.ByteSize = 8;
        dcb.Parity = 0;
        dcb.StopBits = 0;
        dcb.XonChar = '\x11';
        dcb.XoffChar = '\x13';
        dcb.ErrorChar = '\x00';
        dcb.EofChar = '\x00';
        dcb.EvtChar = '\x00';
 
        cto.ReadIntervalTimeout = 0;
        cto.ReadTotalTimeoutMultiplier = 0;
        cto.ReadTotalTimeoutConstant = 1000;
        cto.WriteTotalTimeoutMultiplier = 0;
        cto.WriteTotalTimeoutConstant = 1000;
 
        h = CreateFile
        (
            "COM1", //lpFileName
            GENERIC_READ | GENERIC_WRITE, //dwDesiredAccess
            0, //dwShareMode
            0, //lpSecurityAttributes
            OPEN_EXISTING, //dwCreationDistribution
            FILE_ATTRIBUTE_NORMAL, //dwFlagsAndAttributes
            0 //hTemplateFile
        );
        PurgeComm
        (
            h,
            PURGE_RXABORT | PURGE_TXABORT | PURGE_RXCLEAR | PURGE_TXCLEAR
        );
        SetCommState(h, &dcb);
        SetCommTimeouts(h, &cto);
        GetCommState(h, &dcb);
        GetCommTimeouts(h, &cto);
...
        //------------------------------------------------------------------------------
        bool com_port::write(unsigned char *out, unsigned long sizeof_out)
        {
            unsigned long sizeof_out_real;
            return
            WriteFile(h, out, sizeof_out, &sizeof_out_real, 0) &&
            sizeof_out_real == sizeof_out;
        }
        //------------------------------------------------------------------------------
        bool com_port::read(unsigned char *in, unsigned long * const sizeof_in)
        {
            unsigned long sizeof_in_max = *sizeof_in;
            return
            ReadFile(h, in, sizeof_in_max, sizeof_in, 0);
        }
седьмой
34 / 33 / 0
Регистрация: 11.07.2012
Сообщений: 820
18.11.2016, 13:16     Блок управления и rs 232 #13
Цитата Сообщение от vxg Посмотреть сообщение
Krounis, примерно так
я так понимаю, это код настройки регистров сом порта, в каком то типовом варианте?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.11.2016, 13:48     Блок управления и rs 232
Еще ссылки по теме:

RS-232 (COM - порт) и С++ - C++
Подскажите, пожалуйста, как через прерывания написать программу для управления через COM-порт. Например, по линии Tx с компьютера передаем...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
vxg
Модератор
3146 / 1948 / 214
Регистрация: 13.01.2012
Сообщений: 7,439
18.11.2016, 13:48     Блок управления и rs 232 #14
седьмой, да
Yandex
Объявления
18.11.2016, 13:48     Блок управления и rs 232
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru