Вход

Просмотр полной версии : Как получить переменную int64 со сканера штрих-кода ?



ВладОвен
26.04.2022, 11:15
Всем привет.
Необходимо получать от сканера штрих-кодов значения. Но непонятно как передавать по Mod-Bus большие величины.
Объясню по подробнее:
1. Оператор сканирует штрих-код.
2. Т.к. сканнер не имеет своего протокола обмена высокого уровня, то он просто асинхронно выбрасывает распознанный штрих в символах 0..9 (!) и после эмулирует нажатие клавиши Enter (h0D).
3. Штрих-код ловится спец.устройством собственной разработки - "Bridge Scanner-PLC" - и хранится во временной памяти. Этот bridge может принимать асинхронно данные от 8 сканеров штрих-кодов.
4. Штрих-код преобразуется из последовательности символов 0..9 в последовательность цифр 0..9.
5. ПЛК сканирует регистры внутри Bridge через шину mod-bus. Тут возникает проблема - регистры в mod-bus двух-байтные. А Bridge хочет выдать гигантское число - 4811620472025 (штрих-код в формате EAN13).
6. Для совместимости с mod-bus сейчас реализовано так, что Bridge разделяет свое гигантское число на 4 регистра mod-bus со значениями: 0004, 8116, 2047 и 2025 соответственно (штрих-код из п.5).

Вопрос знатокам:
Как потом собрать это число в ПЛК в одно единое int64 ?
Правильно ли всё это? Может есть пути попроще?
Есть ли уже готовые решения?

A.Simonov
26.04.2022, 11:20
Всем привет.
Необходимо получать от сканера штрих-кодов значения. Но непонятно как передавать по Mod-Bus большие величины.
Объясню по подробнее:
1. Оператор сканирует штрих-код.
2. Т.к. сканнер не имеет своего протокола обмена высокого уровня, то он просто асинхронно выбрасывает распознанный штрих в символах 0..9 (!) и после эмулирует нажатие клавиши Enter (h0D).
3. Штрих-код ловится спец.устройством собственной разработки - "Bridge Scanner-PLC" - и хранится во временной памяти. Этот bridge может принимать асинхронно данные от 8 сканеров штрих-кодов.
4. Штрих-код преобразуется из последовательности символов 0..9 в последовательность цифр 0..9.
5. ПЛК сканирует регистры внутри Bridge через шину mod-bus. Тут возникает проблема - регистры в mod-bus двух-байтные. А Bridge хочет выдать гигантское число - 4811620472025 (штрих-код в формате EAN13).
6. Для совместимости с mod-bus сейчас реализовано так, что Bridge разделяет свое гигантское число на 4 регистра mod-bus: 0004, 8116, 2047 и 2025 соответственно (штрих-код из п.5).

Вопрос знатокам:
Как потом собрать это число в ПЛК в одно единое int64 ?
Правильно ли всё это? Может есть пути попроще?
Есть ли уже готовые решения?

Добрый день.

А почему именно в число собрать хотите?
Соберите в строку STRING.

ВладОвен
26.04.2022, 11:31
А почему именно в число собрать хотите?
Соберите в строку STRING.

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

Перевод из символов и цифры реализован хорошо. Он работает нормально.
Но это не решает проблему передачи большого числа / длинной строки через протокол mod-bus.

Или строку как-то можно разбивать / передавать / собирать через mod-bus ?

A.Simonov
26.04.2022, 11:40
Я думал об этом.
Мне кажется с числами проще: можно диапазоны задавать, со строкой было бы, наверное, потруднее.

Перевод из символов и цифры реализован хорошо. Он работает нормально.
Но это не решает проблему передачи большого числа / длинной строки через протокол mod-bus.

Или строку как-то можно разбивать / передавать / собирать через mod-bus ?

Ну вы ни какую конкретику не приводите, поэтому сложно говорить.
Но сам протокол MODBUS передает просто байты, он не вкурсе строка это или число.
В этом смысле, за один обмен пакетами — нет ни каких проблем передать набор байт любой длины, который укладывается в размер фрейма (256 байт, вместе с заголовками).
А что вы будете делать с байтами, например, собирать их в числа или строки — уже не зона ответственности протокола.

ВладОвен
26.04.2022, 12:38
Вырисовывается такой вариант:
Объявить переменную типа ulint. Это целое беззнаковое число на 8 байт в памяти. В такую переменную запросто должен влезть штрихкод EAN13 (13 цифр).
А в ПЛК собирать эту переменную из 4-х двухбайтовых регистров mod-bus можно так:

uliKod := ( iReg4 * 10000 0000 0000 ) + ( iReg3 * 10000 0000 ) + ( iReg2 * 10000 ) + ( iReg1 * 1 ) ;

И тогда будет штрих-код 4811620472025, собранный из регистров: 0004 8116 2047 2025.

Вопрос к знатокам: это преобразование правильно делать тупо в программе PLC_PRG ? Или же можно как-то это оформить во время объявления переменной и система будет автоматически делать преобразование? (просто не хочется усложнять/загромождать основной код PCL_PRG).

melky
26.04.2022, 13:02
Не все ПЛК работают с Long или LReal насколько помню.

Если уж вы разрезали число для передачи по Modbus, то и склеить обратно можно, главное чтобы клеяльщик умел работать с 8-ми байтными переменными... 100, 150, 154 точно не умеют, как и 63/73

ВладОвен
26.04.2022, 14:06
Не все ПЛК работают с Long или LReal насколько помню.

Точно! Мой ПЛК не работает с ulint!
Посмотрите, как идет умножение (42 * 100000000) и (43 * 100000000)

60487

Значит нужно работать со string.

Cs-Cs
26.04.2022, 15:44
ИМХО лучше STRING: потому что там же последняя цифра - контрольная, и её можно проверять по алгоритму, проверяя корректность самого кода.
А, если есть какие-то спецзадачи (у меня по штрих-коду в CS CRM документы и товары ищутся), то надо отдельно смотреть на первые 1-3 цифры. Например, если в штрих-коде первая цифра "2" - то это или весовой штрих-код или внутренний (не международный).

Евгений Кислов
26.04.2022, 16:08
Точно! Мой ПЛК не работает с ulint!
Посмотрите, как идет умножение (42 * 100000000) и (43 * 100000000)

60487

Значит нужно работать со string.

По скрину четкое ощущение, что у вас uliY объявлен как UDINT, а не ULINT.
Не готов поверить, что у RealLab нет поддержки 64-битных целых.

ВладОвен
26.04.2022, 16:16
Да. А может подскажете как собрать такую переменную?

Я пробовал передавать первые две цифры штрих-кода в регистре. Соотносил их с переменными в среде CodeSys. Потом функция TO_STRING делала эти переменные символьными, но не символами ASCII с нужными кодами.
Т.е. Первые две цифры штрих-кода 4 и 8. Они передаются через mod-bus как h04 и h08. Падают в переменную word - h408. Это десятичное число 1032. После TO_STRING я вижу строковую переменную - '1032'.
А хочу видеть '48'.

Что я делаю не так?

ВладОвен
26.04.2022, 16:19
Не готов поверить, что у RealLab нет поддержки 64-битных целых.

Я проверил. Поддержки нету. Работает только до UDINT (до 32 бит). Это скрины с их "камня".

Объявлено было правильно. Я перепроверил. Было именно ULINT.

60490

(Впрочем, может дело решается подключением какой-либо библиотеки... ХЗ...)

[Дополнено: НА САМОМ ДЕЛЕ ПОДДЕРЖКА 64бит ЕСТЬ! Листайте тему дальше вниз.]

Евгений Кислов
26.04.2022, 16:58
Я проверил. Поддержки нету. Работает только до UDINT (до 32 бит). Это скрины с их "камня".

Объявлено было правильно. Я перепроверил. Было именно ULINT.

60490

(Впрочем, может дело решается подключением какой-либо библиотеки... ХЗ...)

Дело все же не в RealLab, в специфике компилятора CODESYS.

Надо так:



uliY := uiX * ULINT#100000000;


60491

Пояснение: uiX - UINT, 100000000 без принудительной типизации (https://youtu.be/_77HrDXNVBE) - это UDINT (потому что укладывается в его диапазон).
Компилятор выделяет под результат умножения UDINT (это неочевидно), происходит переполнение и уже "переполненное" значение копируется в ULINT.

ВладОвен
26.04.2022, 17:15
Да, вы правы. Я уже это понял.

ВладОвен
26.04.2022, 18:52
В общем - теперь заработало.
С последними подсказками от Евгения, получилось передавать штрих-код в виде числа (не строки). Посмотрим далее на возникающие проблемы.

Но вот вопрос к знатокам остался.
Это преобразование (сборку гигантского числа из 4-х регистров mod-bus) можно как-то прописать при объявлении переменных, а не в основном коде PLC_PRG?

uliKod := ( uiReg4 * ULINT#10000 0000 0000 ) + ( uiReg3 * ULINT# 10000 0000 ) + ( uiReg2 * ULINT#10000 ) + ( uiReg1 * ULINT#1 ) ;


Тут вопрос стратегический: при написании логики, математики, алгоритмов мы должны весь код закладывать в PLC_PRG или же как-то разбивать по частям / дробить / создавать множество подобных клонов PLC_PRG ?


60492

kondor3000
27.04.2022, 09:15
Тут вопрос стратегический: при написании логики, математики, алгоритмов мы должны весь код закладывать в PLC_PRG или же как-то разбивать по частям / дробить / создавать множество подобных клонов PLC_PRG ?



Для этого существуют ФБ (функц. блоки), функции и программы, вы можете дробить основную программу на блоки ( программы, функции) и вызывать их из PLC_PRG.
В данном случае лучше было создать ФБ.