ARDUINO Игровой банковский терминал

BarrtyG

✩✩✩✩✩✩✩
24 Апр 2025
5
1
Привет, я Артем.
После освобождения от магистратуры решил опубликовать свой текущий проект, давно хотел это сделать - банковский терминал для настолок.
Скажу сразу, я искал и видел подобные проекты, может они и хороши, но не идеальны, планируется другой подход. О Монополии знаю, именно она и является источником вдохновения.
Итак поехали...

ЗАДАЧА
Образец из монополии.jpg
Рис. 0 - Терминал из Монополии
Разработать устройство банковского терминала для настольных игр с целью частичной замены игровых валют.
Оно должно работать с банковскими или аналогичными картами по беспроводному интерфейсу.
Необходимо отработать 4 сценария:
  • Обмен между банком и игроком, как на кассе;
  • Обмен между игроком и банком, как в банкомате;
  • Обмен между игроками, подобно СПБ;
  • Изменение состава игроков.

О ПРОЕКТЕ
Проект разрабатывается давно, поэтому графического материала накопилось достаточно. А время на него появилось только сейчас (
Фото и схемы
а) VPL_ep7Aw5t6GE_PBlTXMzPySoStCEeCpjjXCYYaXN9bYj9hk3RAXbcJSR-gNxwOLN2HqK0IbmElIfscdD_vwPr-.jpg1784296466914.png б) fWuANeL-r0nlKDBhJQp83uxX3eMM8Hdlfun0PBdTapGmxsXWyfGPt80wX6b6-li5HlWv3G5ESQAAMYT9hpfcmRei.jpg
Рис. 1 - Фото устройства: а) старая схема от 07.04.26; б) текущая сборка от 17.07.26
Все фотоматериалы, схемы, концепты и найденные гайды по проекту прилагаю, не стесняйтесь спрашивать.
Единственное, что я не могу предоставить: модели корпусов - это мой отдельный проект, которым я собираюсь отбить покупку 3д принтера.
Актуальные на данный момент схемы на картинках далее, исходник в файле Скетч v4.2.fzz... не отправляется.
а) Скетч v4.2_схема.png б) Скетч v4.2_МП.png
Рис. 2 - Версия 4.2: а) Схема; б) Макетная плата
Программная часть
Снимок экрана 2026-07-17 181829.png
Рис. 3 - Наша среда разработки - Visual Studio Code, на базе расширения PlatformIO IDE
Лично мы программируем платы в VSC на базе расширения PlatformIO IDE.
Обмен кодом проекта в этом репозитории: https://github.com/Kotendro/arduino_kassa, его ведет мой брат.
Код не в одном файле, планируется легко расширяемая классовая система.

Концепты
Их много, все просто не влезут, поэтому часть оставлю тут, остальное в файле ИБТ - Концепт.pdf. Их целью является описание интерфейсов и взаимодействий пользователя с устройством.
а) 1784296810525.png б) 1784296835299.png
в) 1784296734729.png
Рис. 4 - Концепты: а) Часть карты действий пользователя; б) Ввод с клавиатуры 4х4; в) Вывод на IPS 1602

ПРОБЛЕМЫ АППАРАТНЫЕ
На повестке дня от 17.07.26 есть некоторые вопросы:
Клавиатура 4х4
а) 1784297186472.png б) 1784297263664.png
Рис. 5 - Подключение клавиатуры: а) было; б) стало
После отказа от подключения клавиатуры по трем проводам с отслеживанием клавиш по сопротивлению из-за их пересечений и перехода на подключение через микросхему PCF8574 с добавлением батареек доступ к компоненту пропал. Очень надеюсь, что это я не так его подключил, скоро отработаю отдельно от всего.
Модуль RFID MFRC522
Оказалось, что данный модуль работает далеко не со всеми картами, он может как реагировать так и игнорировать разные карты от одного банка или с одной платежной системой.
Тут нужен совет по подбору аналогичного модуля.

ПРОБЛЕМЫ ПРОГРАММНЫЕ
Вывод на экран

На данный момент мы не совсем понимаем, как запрограммировать эту часть, как именно его можно обновлять, возможно ли сделать анимацию перевода средств, подобную устройствам из Монополии?
Разделение уровни на действия
Подобная разработка с подобной появилась для нас впервые. Хоть сейчас концепты составлены, а уровни запрограммированы, им все равно требуется некоторая полировка - составление документации, расширение действий, критические точки зрения и т.п.

ИНЫЕ ПРОБЛЕМЫ
Сейчас терминал испытывается во временном универсальном корпусе. Очевидно, что ему понадобится новая модель корпуса для 3д печати.
В теории возможно применение нормальных печатных плат, но так далеко я еще не заходил.

РАЗРАБОТЧИКИ
Сейчас разработкой занимаются 2 человека:
  • Я, Артем - задаю видение проекта, рисую концепты и схемы, закупаю компоненты и собираю их, программирую и проверяю детали. Осенью 2026 ухожу в армию.
  • Мой брат, Илья - занимается программированием.
ОБРАЩЕНИЕ К СООБЩЕСТВУ
Все файлы из текста сжаты в папку Игровой банковский терминал.zip под этим сообщением.
Я никогда не взаимодействовал с форумами, возможны ошибки и недопонимания. В целом, воспринимаю, это место как публичный дневник разработки.
Для удобства связи можно организовать другое место, например Discord, но посмотрим.
Проблемы обозначены выше, вы можете собрать устройство самостоятельно и воспроизвести их, просто дать обратную связь и советы.
Считаю, что потенциал устройства огромен. Оно применимо к части игр, а если еще и разные валюты прикрутить... то хоть в ДнД с ним можно идти.
Быстрого результата не гарантирую, жизнь слишком загружена.
 

Вложения

Изменено:
  • Лойс +1
Реакции: wizard suleiman

BarrtyG

✩✩✩✩✩✩✩
24 Апр 2025
5
1
Проблема с клавиатурой решена - ошибка была в неверном адресе I2C, в моем случае она имеет значение 0x38 вместо 0x20, как было в гайдах.
Детектор адреса поместил в папку archive.
 

wizard suleiman

✩✩✩✩✩✩✩
13 Окт 2023
75
5
понятия не имею как ваш код посмотреть...

C++:
#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN 10  // Пин для выбора модуля MFRC522
#define RST_PIN 9   // Пин сброса модуля MFRC522
#define POT_PIN A0  // Пин для потенциометра

MFRC522 mfrc522(SS_PIN, RST_PIN); // Создаем объект MFRC522

// Массив для хранения ID меток
String cardIDs[3];
float balances[3]; // Балансы для каждой метки
bool lastActionPerformed[3]; // Массив для отслеживания, было ли действие выполнено для каждой метки

void setup() {
    Serial.begin(9600); // Инициализация последовательного порта
    SPI.begin(); // Инициализация SPI
    mfrc522.PCD_Init(); // Инициализация MFRC522
    Serial.println("Поднесите RFID метку к считывателю...");
   
    // Инициализация балансов и состояния действий
    for (int i = 0; i < 3; i++) {
        balances[i] = 500000.0; // Начальный баланс 500000
        lastActionPerformed[i] = false; // Изначально действие не выполнено
    }
}

void loop() {
    // Проверка наличия метки
    if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
        String currentCardID = "";
        for (byte i = 0; i < mfrc522.uid.size; i++) {
            currentCardID += String(mfrc522.uid.uidByte[i], HEX);
        }
        currentCardID.toUpperCase(); // Приводим к верхнему регистру
        Serial.print("Считан ID метки: ");
        Serial.println(currentCardID);
       
        // Проверка, есть ли метка в массиве
        int cardIndex = -1;
        for (int i = 0; i < 3; i++) {
            if (cardIDs[i] == currentCardID) {
                cardIndex = i;
                break;
            }
        }

        // Если метка не найдена, запоминаем ее
        if (cardIndex == -1) {
            for (int i = 0; i < 3; i++) {
                if (cardIDs[i] == "") {
                    cardIDs[i] = currentCardID;
                    Serial.print("Запомнена метка с ID: ");
                    Serial.println(currentCardID);
                    break;
                }
            }
        } else {
            // Если метка найдена, выводим баланс
            Serial.print("Баланс метки ");
            Serial.print(currentCardID);
            Serial.print(": ");
            Serial.println(balances[cardIndex]);

            // Считываем значение с потенциометра
            int potValue = analogRead(POT_PIN);
            Serial.print("Значение потенциометра: ");
            Serial.println(potValue);

            // Увеличиваем или уменьшаем баланс в зависимости от значения потенциометра
            if (potValue >= 0 && potValue <= 400) { // Если значение от 0 до 400, уменьшаем баланс
                if (!lastActionPerformed[cardIndex]) { // Проверяем, было ли действие выполнено
                    balances[cardIndex] -= 50000; // Уменьшаем баланс
                    Serial.print("Баланс метки ");
                    Serial.print(currentCardID);
                    Serial.print(" после уменьшения: ");
                    Serial.println(balances[cardIndex]);
                    lastActionPerformed[cardIndex] = true; // Отмечаем, что действие выполнено
                }
            } else if (potValue >= 600 && potValue <= 1023) { // Если значение от 600 до 1023, увеличиваем баланс
                if (!lastActionPerformed[cardIndex]) { // Проверяем, было ли действие выполнено
                    balances[cardIndex] += 50000; // Увеличиваем баланс
                    Serial.print("Баланс метки ");
                    Serial.print(currentCardID);
                    Serial.print(" после увеличения: ");
                    Serial.println(balances[cardIndex]);
                    lastActionPerformed[cardIndex] = true; // Отмечаем, что действие выполнено
                }
            }
        }
       
        mfrc522.PICC_HaltA(); // Остановка работы с меткой
    }

    // Сброс состояния действия, если метка не считывается
    for (int i = 0; i < 3; i++) {
        if (cardIDs[i] != "" && !mfrc522.PICC_IsNewCardPresent()) {
            lastActionPerformed[i] = false; // Сбрасываем состояние, если метка не считывается
        }
    }
}
вот может пригодится взять за основу... успехов!)))
 
  • Лойс +1
Реакции: BarrtyG

BarrtyG

✩✩✩✩✩✩✩
24 Апр 2025
5
1
@wizard suleiman, ого, манипулирование балансом через потенциометр? Оригинально.
Спасибо конечно, близко, может пригодиться для изучения.

Код на ГитХабе по ссылке: https://github.com/Kotendro/arduino_kassa, его можно целиком в zip выгрузить.
Метод запуска описан в тексте выше.
Главный файл main.cpp, после моего фикса клавиатуры, сейчас полурабочий.

Там не все так просто как в Arduino IDE - файлов и библиотек куча из-за множества компонентов и машины состояний.
Надо кое-кого попинать для решения вопроса с документацией.
 

wizard suleiman

✩✩✩✩✩✩✩
13 Окт 2023
75
5
@BarrtyG, я почти не умею пользоваться платформио, в свое время выбрал путь мазохизма, и загружаю через ардуино идэ, благодаря этому не совершаю кучу ошибок, и не перепрошиваю кучу раз, а думаю над кодом, и долгая загрузка кода стимулирует)))

потенциометр можно потом заменить на переменную, и сделать автоматизацию, при присвоении такого то значения сделать то то, и вновь изменить переменную, и вроде не запутаешься в своей же программе)))

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

справедливости ради, код использует не экономно память... и в будущем это станет проблемой, но это проблемы потомков)))
 
Изменено:
  • Лойс +1
Реакции: BarrtyG

BarrtyG

✩✩✩✩✩✩✩
24 Апр 2025
5
1
Разработка временно приостановлена до 07.07.26 - всем составом уехали в отпуск в КНДР и КНР.
 
Изменено: