Сучасна диджитал-освіта для дітей — безоплатне заняття в GoITeens ×
Mazda CX 5
×

Сканер штрих-кодів і Java

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

Нещодавно в рамках проекту, який пишеться на Java на базі SpringBoot, виникла задача підключити сканер штрих-кодів.
Причому операційною системою, на якій виконуватиметься Java-application, є Embedded Linux.

Кожен такий сканер (ми використали виробництва Honeywell) за замовчуванням має режим «клавіатури» — USB-Keyboard simulation. Тобто коли сканер розпізнає штрих-код, то він його посилає на комп’ютер так, наче до комп’ютера підключена клавіатура і хтось ввів з неї символи розпізнаного штрих коду.

Проблема такого режиму в тому як фільтрувати контекст вводу? Адже може бути відкрите діалогове вікно, в якому не потрібно, щоб раптом прилітали символи від сканера. До того ж в Linux введення з клавіатури реєструються як події ядра Linux, з відповідним нетривіальним форматом, куди входить і тайм-стамп події, тобто кожне натискання клавіші супроводжується купою додаткової інформації. І нефільтрований Input stream такої інформації при її перегляді є набором якихось байтів, причому їх просто дофіга і оті ASCII-символи власне розпізнаного штрих-коду навіть не проглядаються.

Один з наших програмістів взявся реалізувати розбір цих event-ів від Linux, в результаті написав два окремих Java-класи з використанням BufferedInputStream. Об’єкт одного класу крутиться в своєму потоці і розбирає структуру Linux-event’у кожного сканкоду клавіші (з якимись таблицями перекодування сканкодів у ASCII), а об’єкт другого класу теж крутиться у іншому треді, слідкує за першим, щоб сформувати рядок символів коли в першому треді спорожнів input-buffer і він перейшов в стан блокування. Тоді цей другий тред вмикав прапорець, що рядок сформовано — можна забирати.

Кожен Java-клас містив десь з сотню рядків.

Програміст мучився з пошуком рішення, з тими Linux-event’ами десь тиждень.

Той код хоч і працював, але був доволі незрозумілий, з якимись часовими інтервалами в тих тредах, неочевидним обміном даними між ними. І, головне, він не гарантував коректність послідовності символів якщо кнопку сканера натиснути швидко підряд два рази.

Мене це трохи напружувало, до того ж потім той програміст звільнився.

Тоді я взяв документацію на сканер і виявилось, що сканер може працювати як в KEYBOARD-режимі, так і в режимі USB-Serial simulation, тобто як звичайний послідовний пристрій введення (в Linux він з’являється як TTY-файл). Кожен подібний сканер може бути переведений в цей режим, треба просто ним відсканувати спеціальний командний штрих-код, який присутній в документації. Причому непотрібно параметризувати якусь швидкість передачі, оці всі parity, stop-bits, etc. Потрібно лише просто прочитати з вхідного буфера ГОТОВИЙ рядок ASCII.

Після переведення сканера в цей режим кількість рядків коду на Java скоротилася до ЧОТИРЬОХ. З усіма обв’язками — десь до двадцяти для реалізації шаблону Observable, щоб натискання кнопки на сканері ВІДРАЗУ викликало потрібний код в Observer.

На написання і шліфування коду пішла десь одна година.

Виявилось, що рішення задачі отримання в Java-програмі готових ASCII-рядків зі сканеру штрих-кодів — тривіальне.

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному0
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Дякую за цікаву та інформативну статтю.

виникла задача підключити сканер штрих-кодів

Маю запитання, чи пробували ви використовувати готові рішення у вигляді бібліотек?

Як виявилось, в моєму випадку ніякі бібліотеки взагалі виявились непотрібні, бо Java вже сама в собі містить все потрібне. Допис був про те, що інколи шлях до розв’язання задачі буває коротший на порядок і елегантніший на декілька порядків (і це не перебільшення), варто просто глянути в документацію.

Коментар порушує правила спільноти і видалений модераторами.

Теперь повторите тоже самое РРО и обогощайтесь

Що таке РРО?
обогощайтесь — це якою мовою?

1. РРО (регистратор расчетных операций) — это устройство или программно-технический комплекс, в котором реализованы фискальные функции, предназначенные для регистрации расчетных операций при продаже товаров (оказании услуг), операций купли/продажи иностранной валюты.

2. Албанский

І нефільтрований Input stream такої інформації при її перегляді є набором якихось байтів, причому їх просто дофіга і оті ASCII-символи власне розпізнаного штрих-коду навіть не проглядаються.

о боже, как страшно жыть то! надо же почитать документацию, как работают input events! хнык хнык
хорошо в яве — ничего читать не надо

хорошо в яве — ничего читать не надо

(но это не точно)

Не тільки «хньІк-хньІк», а й «нах-нах».

Жду продолжения, автодиагностика, автонастройка, причем моделей от разных производителей. После, обзор готовых фреймворков. )

прочитал, прямо какая то боль жависта, сто строчек уже непонятно

для меня кодовая база меньше 1Гб это маленькая

Неочевидний момент: миша має ту саму «проблему», і може попадати не в ті вікна і так далі. Що як не дивно, не призводить до написання якихось прибамбасів окрім випадків кіберспорту. Просто те що миша ввела невірно, розглядається як можлива помилка юзера. Якою вона по суті і є.

Так само зі сканерами — їхня фізична робота ну дуууже схожа на роботу звичайної оптичної миші. Тобто, коли контроллер відчуває рух, сканер вмикає випромінювальний діод на повну потужність і лише тоді намагається щось читати. До тих пір проводить пасивне сканування, НІЧОГО не віддаючи в порт.

Тому все, що насправді потрібно — використовувати стаціонарний тримач для тих сканерів, який скоріше за все йде в комплекті. Як нема — тупо взяти чорний килимок для миші чи тупо чорний папір роздрукувати та покласти на нього. І все, користуєте БУДЬ ЯКИЙ сканер як клавіатуру. Навіть самі давні моделі, що до PS/2 порту підключаються.

Мораль: не використовуйте програміста не за призначенням.

Вангую: писати те рішення ви посадили джуна, принаймні до того він ніколи не працював в Java безпосередньо з потоковими пристроями (а на Java це адський гемор, через те що Java працює в рамках JVM). Більш того, на проекті забанений вихід в зовнішній інтернет, тому він просто не знав як і що робити з досвіду інших кодерів, та змушений був розбиратися з документацією.
Чому він звільнився — здогадайтеся самі.

В нашій задачі зчитування штрих-коду має відбуватися по натисканні на кнопку (курок) самого сканера. Завжди тільки так. Тому ловити рух непотрібно зовсім.
А програміст, який взявся те робити, на Java взагалі не писав до того. Він Embedded С-шник. Але питання навіть не в тому на чому він писав, а в тому, що «клавіатурний» режим роботи сканера не підходить під цю конкретну задачу. Бо сканер має посилати рядок символів взагалі без якоїсь семантичної прив’язки до екранного інтерфейсу користувача, наче того користувача за екраном нема і самого екрану з контекстом вводу з клавіатури теж.

Так кажеш ніби клавіатура того не робить. Щось ви перемудрили.

Та ні, все норм. Навіть гуд. Якби не було гуд, я б не писав цей постік.

Причому непотрібно параметризувати якусь швидкість передачі, оці всі parity, stop-bits, etc. Потрібно лише просто прочитати з вхідного буфера ГОТОВИЙ рядок ASCII.

Маленькие дети тоже верят, что под ёлку им подарки Санта приносит и заполняет некие входные буфера. Просто счастливое совпадение дефолтовых параметров до тех пор пока не появится новая винда, новое устройство в системе или и чтение будет идти не с того устройства.

Ніт.
Непотрібно — означає саме те, що написано.

Із документації:

No extra configuration (e.g., baud rate) is necessary.

Открываю документацию, а там написано что это Communication Device Class (CDC) Abstract Control Model (ACM), что никакого отношения к serial port не имеет. И даже в линуксе они видятся как /dev/ttyACM, не как serial. Поэтому:

оці всі parity, stop-bits, etc

просто неприменимы к данному типу устройств.

называется — открой для себя дивный мир AT команд

Нащо мені АТ-команди, якщо і без них все працює?

Підписатись на коментарі