Tecnico guardiancar Ответов: 3

Как я могу кодировать, только используя протокол?


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

Протокол ABNT NBR-14522 основан на стандартах IEC-62056 и ANSI-C12.2.
У меня есть протокол здесь.

В протоколе есть много октетов(octetos), которые состоят из 8 битов, которые запрашивает протокол (их очень много).
В настоящее время я принимаю любые идеи о том, как я собираюсь запросить команду, чтобы оборудование могло ответить мне нужной строкой.

Заранее благодарю вас, Джон.

Что я уже пробовал:

Понятия не имею. Я пробовал проводить исследования в интернете и на этом сайте.

3 Ответов

Рейтинг:
25

Jochen Arndt

У вас должен быть драйвер устройства для связи. Это должно обеспечить функции для настройки интерфейса и чтения и записи данных (обычно с указателем для данных и параметром размера).

Цитата:
В протоколе есть много октетов(octetos), которые состоят из 8 байтов, которые запрашивает протокол.
Я думаю, что вы неправильно поняли это, и у вас есть только байты (8 бит).

Если это так, просто объявите буфер достаточного размера (максимальное количество байтов на сообщение) и заполните его данными в соответствии с протоколом (я не знаю, применимо ли нижеприведенное к вашему протоколу, но быстрое веб-исследование предполагает это):
unsigned char buf[MAX_MSG_SIZE];
buf[0] = 0x2f; // start
// set n data bytes here
// this might be for example a command send to the device
//memcpy(buf+1, data, n);
buf[n+1] = 0x21; // end
buf[n+2] = 0x0d; // CR
buf[n+3] = 0x0a; // LF
buf[n+4] = 0; // Optional when using string functions
// Driver specific send function
send_meter(buf, n+4);
//send_meter(buf, strlen(buf));
Вышеизложенное предполагает, что также двоичные данные могут быть частью сообщения. Если нет, то вы также можете использовать char буфер и использование strlen() чтобы получить длину сообщения (при создании NULL завершенный буфер).

Аналогично для функции приема. Со строковыми данными, которые обычно возвращаются, когда была получена завершенная строка CR-LF. Чем просто получить доступ к той части, которая содержит полезную нагрузку данных.

КСТАТИ:
Можно ли сделать документ доступным в сети?
Если нет, Пожалуйста, удалите ссылку из вашего вопроса.


Tecnico guardiancar

На самом деле я не знаю, потому что я просто погуглил NBR15422 и нашел его. Но на всякий случай я его уберу.

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

Октет 001: двузначный номер, который указывает, что я прошу метр отправить мне(20/21/22/51)

Октет 002: серийный номер считывателя MSB
Октет 003: Серийный Номер Считывателя
Октет 004: серийный номер считывателя LSB
Октет 005: 00 для всей массовой памяти
Октет 006: какие каналы выбрать (00=каналы 1,2,3;01=каналы 4,5,6...до 32)
Октет 007: если 00, то октет 005 истинен.
Октет 008 - 010: ноль,
если 01 считанное количество часов в массе памяти
Октет 005 должен быть прочитан как количество часов регистрации, которое должно быть предоставлено
Октеты 008 и 009 должны быть нулевыми
Октет 010 определяет маску считываемых величин,
если 02 читать количество дней регистрации в запоминающем устройстве
Октеты 008 и 009 должны быть прочитаны как количество дней регистрации, которое должно быть предоставлено
Октет 010 определяет маску считываемых величин,
если 03 чтение реестра с момента последнего чтения массы памяти.
Октет 010 определяет маску считываемых величин
Октет 008: NN1 количество гражданских дней в памяти Mass MSB.
Октет 009: nn1 количество гражданских дней в памяти Mass LSB.
Октет 010: Маска запрашиваемых каналов.
Бит 0: запрошенные количества Первого канала этой группы.
Бит 1: запрошенные количества второго канала этой группы.
Бит 2: запрошенные количества третьего канала этой группы.
Октет 011 - 064: NULL
Октет 065: CRC LSB
Октет 066: CRC MSB
(Количества указаны в Вт, кВт, квар,...)
------------------

И я не знаю, как кодировать, следуя этим стандартам. (обратите внимание, что код проходит через
последовательный порт RS-232, а также оптический инфракрасный измеритель.)

И у меня тоже есть это:

<enq> ::= 05 шестнадцатеричный код
<ack> ::= 06 шестнадцатеричный код
<nak> :: = 15 шестнадцатеричный
<wait> ::= 10 шестнадцатеричный
<byte> ::= 00 to FF шестнадцатеричный
<code.> ::= от 01 до 99 BCD, кроме 05, 06, 10 и 15.
<crc> ::= CRC16 (X16 + X15 + X2 + 1)
<com> :: = 63 <байт>
<res> :: = 255 <байт>
&ЛТ;флаг&ГТ; ::= &л;enq по теме> или <АСК&ГТ; или <НАК&ГТ; или <ждать&ГТ;
в <команда&ГТ; ::= &л;код&ГТ;&ЛТ;ком&ГТ;&ЛТ;КПР&ГТ;
&ЛТ;ответить&ГТ; ::= &л;код&ГТ;&ЛТ;РЭС&ГТ;&ЛТ;КПР&ГТ;

Jochen Arndt

Октет - это байт.
Поскольку вышеизложенное содержит "00", у вас есть двоичные данные.
Затем установите байты, как уже было объяснено.

Октет 002: серийный номер считывателя MSB
Октет 003: Серийный Номер Считывателя
Октет 004: серийный номер считывателя LSB

Это означает, что у вас есть 3-байтовый (24-битный) серийный номер. Если это хранится в 32-битном беззнаковом sn (или sn-это просто постоянное значение):
// Offset должно быть на единицу меньше, потому что индексы C начинаются с 0
buf[0] = 0x20; // командный байт
параметр buf[1] = (беззнаковый тип char)((СН &ГТ;&ГТ; 16) &усилителя; как 0xFF); // МСБ
buf[2] = (unsigned char)((sn >> 8) & 0xff); // средний байт
buf[3] = (unsigned char)(sn && 0xff); // LSB

buf[offset] = 0x06; // ACK

Ему все равно, какой тип аппаратного интерфейса используется. Вам просто нужно подготовить / прочитать данные и использовать функции, предоставляемые драйвером / SDK.

fernando barbosa

МОГ БЫ МНЕ ПОМОЧЬ У МЕНЯ ЕСТЬ ПОХОЖИЙ ПРОЕКТ

Рейтинг:
1

Patrice T

Октет-это байт:
Октет (вычислительная техника) - Википедия[^]

Цитата:
<enq> :: = 05 шестнадцатеричный
<ack> ::= 06 шестнадцатеричный код
<nak> :: = 15 шестнадцатеричный
<wait> ::= 10 шестнадцатеричный

Это стандартные коды ASCII, эта нотация используется, потому что они не могут быть напечатаны.
Таблица Ascii - коды символов ASCII и html, восьмеричное, шестнадцатеричное и десятичное преобразование диаграмм[^]


Рейтинг:
1

KarstenK

Вы должны работать с буферами размером 8 байт. Вы можете назвать его "октет".

byte octet[8];// or char
strncpy( octet, "it works", 8); 

Обратите внимание, что в a обычный строка последний элемент является завершающим нулем, так что у вас есть 7 символов "полезной нагрузки". Также можно использовать 8-й байт, когда код работает без Терминатора.