2 / 2 / 1
Регистрация: 10.11.2016
Сообщений: 94
1

Блок управления и rs 232

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

Author24 — интернет-сервис помощи студентам
Доброго времени суток, форумчане. Сразу перейду к делу, есть блок управления двумя фотоприемниками и затворами, нужно программно обеспечить проведение эксперимента с использованием этих устройств, есть код на 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# (там все работает как надо) и свои исходники если необходимо

Буду благодарен за любую помощь.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
10.11.2016, 12:20
Ответы с готовыми решениями:

Алгоритм или протокол управления эл.двигателем по RS-232
Всем привет! Подскажите плз как бы правильнее реализовать управление эл.двиг. подключенного к МК...

rusEfi - блок управления двигателем
Я допроектировал свой ЭБУ до состояния, что могу ездить вокруг дома. Ищу смелых добровольцев, кто...

Блок управления шаговым двигателем.
Доброго времени суток. Возникла у меня необходимость сделать непростое устройство с шаговым...

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

13
Модератор
3401 / 2172 / 353
Регистрация: 13.01.2012
Сообщений: 8,421
10.11.2016, 14:32 2
Krounis, что скрывает строчка com1->write(zad1) и как вы собственно принимаете данные?
0
2 / 2 / 1
Регистрация: 10.11.2016
Сообщений: 94
10.11.2016, 15:04  [ТС] 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);
0
Модератор
3401 / 2172 / 353
Регистрация: 13.01.2012
Сообщений: 8,421
10.11.2016, 15:38 4
Krounis, попробуйте понизить скорость обмена. какие таймауты ставит QSerialPort не смотрели?
0
2 / 2 / 1
Регистрация: 10.11.2016
Сообщений: 94
10.11.2016, 16:10  [ТС] 5
vxg, а как их посмотреть/поменять?
0
Модератор
3401 / 2172 / 353
Регистрация: 13.01.2012
Сообщений: 8,421
10.11.2016, 18:48 6
Krounis, если бы речь шла о winapi я бы сказал а в qt не знаю в свойствах объекта смотреть надо очевидно
0
2 / 2 / 1
Регистрация: 10.11.2016
Сообщений: 94
10.11.2016, 19:29  [ТС] 7
vxg, хорошо, спасибо попробую, как я понимаю таймауты надо уменьшить?
0
Модератор
3401 / 2172 / 353
Регистрация: 13.01.2012
Сообщений: 8,421
11.11.2016, 06:22 8
Krounis, я думаю что они наоборот могут быть очень малыми
0
2 / 2 / 1
Регистрация: 10.11.2016
Сообщений: 94
12.11.2016, 08:48  [ТС] 9
vxg, не нашел как настроить тайм-ауты((
0
Модератор
3401 / 2172 / 353
Регистрация: 13.01.2012
Сообщений: 8,421
12.11.2016, 17:58 10
Krounis, попробуйте для пробы кинуть запрос через winapi
0
2 / 2 / 1
Регистрация: 10.11.2016
Сообщений: 94
13.11.2016, 18:51  [ТС] 11
vxg, а это как?)
0
Модератор
3401 / 2172 / 353
Регистрация: 13.01.2012
Сообщений: 8,421
14.11.2016, 11:18 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);
        }
0
45 / 44 / 1
Регистрация: 11.07.2012
Сообщений: 1,024
18.11.2016, 13:16 13
Цитата Сообщение от vxg Посмотреть сообщение
Krounis, примерно так
я так понимаю, это код настройки регистров сом порта, в каком то типовом варианте?
0
Модератор
3401 / 2172 / 353
Регистрация: 13.01.2012
Сообщений: 8,421
18.11.2016, 13:48 14
седьмой, да
0
18.11.2016, 13:48
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
18.11.2016, 13:48
Помогаю со студенческими работами здесь

Блок управления ШД с тремя обмотками
Задача: сделать блок управления для ШД, который можно подцепить к МК. двигатель не один, их два....

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

Блок управления подкачивающего насоса котла
Доброго времени суток! Уважаемые форумчане обращаюсь к Вам, за помощью. Требуется составить...

Блок управления автоматическим открыванием ворот
Надумал создать свой блок управления открыванием ворот. Пока схемку только накидал, собираюсь плату...


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Опции темы

Новые блоги и статьи
Как проводить научные вычисления на Python
InfoMaster 15.01.2025
Python стал одним из наиболее востребованных языков программирования в области научных вычислений благодаря своей простоте, гибкости и обширной экосистеме специализированных библиотек. Научные. . .
Создание игры типа Minecraft на PyGame/Python: пошаговое руководство
InfoMaster 15.01.2025
В данном руководстве мы рассмотрим процесс создания игры в стиле Minecraft с использованием библиотеки PyGame на языке программирования Python. Этот проект идеально подходит как для начинающих. . .
Как создать свою первую игру в стиле Doom на Unreal Engine
InfoMaster 15.01.2025
Разработка шутера от первого лица в стиле классического Doom представляет собой увлекательное путешествие в мир игрового программирования, где сочетаются творческий подход и технические навыки. . . .
Параллельное программировани­е: основные технологии и принципы
InfoMaster 15.01.2025
Введение в параллельное программирование Параллельное программирование представляет собой фундаментальный подход к разработке программного обеспечения, который позволяет одновременно выполнять. . .
Как написать микросервис на C# с Kafka, MediatR, Redis и GitLab CI/CD
InfoMaster 15.01.2025
В современной разработке программного обеспечения микросервисная архитектура стала стандартом де-факто для создания масштабируемых и гибких приложений. Этот подход позволяет разделить сложную систему. . .
Что такое CQRS и как это реализовать на C# с MediatR
InfoMaster 15.01.2025
Концепция CQRS и её роль в современной разработке В современном мире разработки программного обеспечения архитектурные паттерны играют ключевую роль в создании масштабируемых и поддерживаемых. . .
Как настроить CI/CD с Azure DevOps
InfoMaster 15.01.2025
CI/ CD, или непрерывная интеграция и непрерывное развертывание, представляет собой современный подход к разработке программного обеспечения, который позволяет автоматизировать и оптимизировать процесс. . .
Как настроить CI/CD с помощью Jenkins
InfoMaster 15.01.2025
Введение в CI/ CD и Jenkins В современной разработке программного обеспечения непрерывная интеграция (CI) и непрерывная доставка (CD) стали неотъемлемыми элементами процесса создания качественных. . .
Как написать микросервис на Go/Golang с Kafka, REST и GitHub CI/CD
InfoMaster 14.01.2025
Определение микросервиса, преимущества использования Go/ Golang Микросервис – это архитектурный подход к разработке программного обеспечения, при котором приложение состоит из небольших, независимо. . .
Как написать микросервис с нуля на C# с RabbitMQ, CQRS, Swagger и CI/CD
InfoMaster 14.01.2025
В современном мире разработки программного обеспечения микросервисная архитектура стала стандартом де-факто для создания масштабируемых и гибких приложений. Этот архитектурный подход предполагает. . .
Как создать интернет-магазин на PHP и JavaScript
InfoMaster 14.01.2025
В современном мире электронная коммерция стала неотъемлемой частью бизнеса. Создание собственного интернет-магазина открывает широкие возможности для предпринимателей, позволяя достичь большей. . .
Как написать Тетрис на Ассемблере
InfoMaster 14.01.2025
Тетрис – одна из самых узнаваемых и популярных компьютерных игр, созданная в 1984 году советским программистом Алексеем Пажитновым. За прошедшие десятилетия она завоевала симпатии миллионы людей по. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru