Diy

Roll в стиле с этим DIY электронным D20 Die

Roll в стиле с этим DIY электронным D20 Die

Хотите что-то немного уникальное для своей следующей настольной ролевой игры? Как насчет электронного D20 с пользовательской графикой для критических попаданий и промахов? Сегодня я покажу вам, как создать свой собственный Arduino и несколько простых деталей.

Не беспокойтесь, если вы никогда ранее не использовали Arduino, у нас есть руководство по

План строительства

Это простой проект. Arduino будет управлять OLED-дисплеем, а кнопка прокручивает матрицу. Пользовательская графика будет отображаться для критических попаданий или бросков. Вы можете легко изменить код на D8, D10 или D12.

Что вам нужно

arduino_d20_what_you_need

  • 1 х Arduino
  • 1 x 0,96 ″ I2C OLED дисплей
  • 1 х кнопка
  • 1 х 10к? резистор
  • 1 х макет
  • Ассорти подключить провода
  • Полный код здесь , если вы не хотите следовать всем письменным инструкциям.

Это основные части, которые вам нужны, чтобы создать свой собственный D20. Вы можете установить его в корпус (см. Ниже) и припаять схему в более постоянное состояние. Вот дополнительные детали, которые вам понадобятся для этого:

Эти OLED-дисплеи очень крутые. Обычно их можно приобрести в белом, синем, желтом цвете или в смеси из трех. Я купил один в синем, чтобы соответствовать моему случаю. Убедитесь, что вы получаете модель I2C вместо SPI .

Подойдет практически любой Arduino. Я выбрал Nano, так как они достаточно малы, чтобы поместиться в корпусе. Ознакомьтесь с нашим руководством по покупке купить для получения дополнительной информации о моделях Arduino.

Схема

Вот схема, которая вам нужна:

схема Arduino D20

Подключите VCC и GND на OLED-дисплее к Arduino + 5V и заземлению . Подключите аналог 4 на Arduino к выводу с маркировкой SDA . Подключите аналог 5 к выводу SCL . Эти контакты содержат схему, необходимую для управления дисплеем по шине I2C. Точные контакты будут различаться в зависимости от модели, но A4 и A5 используются на Nano и Uno. Проверьте документацию библиотеки Wire для вашей модели, если вы не используете Uno или Nano.

Подключите аккумулятор к земле и контакт VIN . Это обозначает напряжение на входе и принимает различные напряжения постоянного тока, но сначала проверьте вашу конкретную модель, и она иногда может немного отличаться.

Подключите кнопку к цифровому контакту 2 . Обратите внимание, как 10k? резистор подключен к земле. Это очень важно! Это известно как понижающий резистор, и он предотвращает Arduino обнаружение паразитных данных или помех при нажатии кнопки. Он также служит для защиты доски. Если бы этот резистор не использовался, + 5 В пошел бы прямо в землю. Это известно как мертвый шорт и это простой способ убить Ардуино.

Если вы паяете эту цепь, защитите свои соединения с помощью термоусадочной трубки:

Arduino D20 термоусадочная

Убедитесь, что вы не нагреваете его слишком сильно, и делайте это только после того, как убедитесь, что схема работает. Вы можете также захотеть скрутить свои кабели в пары. Это сохраняет их аккуратными и помогает защитить их от чрезмерного стресса:

Arduino D20 витой кабель

Тест кнопки

Теперь, когда вы построили схему, загрузите этот тестовый код (убедитесь, что вы выбрали правильную плату и порт из меню « Инструменты»> « Плата и инструменты»> «Порты» ):

const int buttonPin = 2; // the number of the button pin void setup() { pinMode(buttonPin, INPUT); // setup button Serial.begin(9600); // setup serial } void loop(){ if(digitalRead(buttonPin) == HIGH) { Serial.print("It Works"); delay(250); } } 

После загрузки оставьте Arduino подключенным через USB и откройте последовательный монитор ( вверху справа> Serial Monitor ). Вы должны видеть, что слова It Works появляются каждый раз, когда вы нажимаете кнопку.

Если ничего не происходит, пойди и перепроверь свою схему.

Установка OLED

тест Arduino Oled

Вам нужно установить две библиотеки для управления дисплеем. Загрузите библиотеки Adafruit_SSD1306 и Adafruit-GFX [больше не доступны] с Github и сохраните их в своей папке библиотеки. Если вы не уверены, где находятся папки вашей библиотеки, прочитайте мое учебное пособие по ретро-играм , где я настраиваю этот же дисплей более подробно.

Перезапустите свою среду разработки Arduino и загрузите эскиз теста из меню « Файл»> «Примеры» . Выберите Adafruit SSD1306, а затем ssd1306_128x64_i2c . Загрузите этот код (это займет некоторое время), и вы должны увидеть множество форм и рисунков на дисплее:

тест Arduino Oled

Если ничего не происходит, дважды проверьте ваши соединения. Если после проверки он все равно не будет работать, вам нужно будет изменить пример кода.

Измените эту строку (в начале функции настройки ):

 display.begin(SSD1306_SWITCHCAPVCC, 0x3D); 

К этому:

 display.begin(SSD1306_SWITCHCAPVCC, 0x3C); 

Это сообщает библиотеке конкретные сведения об используемом вами дисплее. Теперь вы должны быть готовы продолжить сборку.

Дело

Если вы строите это на макете или не хотите его упаковывать, вы можете пропустить этот шаг.

чехол Arduino D20

Я разработал и напечатал 3D эту коробку. Получить файлы на Thingiverse . Не беспокойтесь, если у вас нет 3D-принтера — онлайн-сервисы 3D Hubs и Shapeways предоставляют услуги онлайн-печати.

Вы можете легко сделать эту коробку из дерева, или купив пластиковую коробку для проекта .

Крышка представляет собой простую конструкцию с плотной посадкой и содержит несколько вырезов для крепежа:

чехол Arduino D20

Код

Теперь, когда все готово, пришло время для кода. Вот как это будет работать в псевдокоде :

 if button is pressed generate random number if random number is 20 show graphic else if random number is 1 show graphic else show number 

Чтобы это работало должным образом, необходимо сгенерировать случайное число — это бросок кубика. Arduino имеет генератор случайных чисел, называемый random , но не должен его использовать. Хотя он достаточно хорош для базовых случайных задач, он не достаточно случайен для электронного кристалла. Причины несколько сложны, но вы можете прочитать больше, если вы заинтересованы в boallen.com .

Загрузите библиотеку TrueRandom от sirleech на Github. Добавьте это в свою библиотеку и перезапустите IDE.

Теперь создайте новый файл и настройте свой исходный код (или просто получите готовый код из GitHub ):

 #include <SPI.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include <TrueRandom.h> Adafruit_SSD1306 display(4); void setup() { display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // setup the OLED pinMode(buttonPin, INPUT); // setup button } void loop() { } 

Этот код настраивает OLED и включает в себя все библиотеки, которые вам необходимы для связи с ним, а также новую библиотеку случайных чисел. Теперь добавьте это в основной цикл:

 if(digitalRead(buttonPin) == HIGH) { delay(15); if(digitalRead(buttonPin) == HIGH) { display.fillScreen(BLACK); // erase the whole display display.setTextColor(WHITE); display.setTextSize(2); display.setCursor(0, 0); display.println(TrueRandom.random(1, 21)); // print random number display.display(); // write to display delay(100); } } 

Это довольно просто на минуту, но это рабочий D20. При каждом нажатии кнопки на экране отображается случайное число от одного до 20:

Arduino D20 первый код

Это хорошо работает, но немного скучно. Давайте сделаем это лучше. Создайте два новых метода, drawDie и eraseDie :

 void drawDie() { display.drawRect(32, 0, 64, 64, WHITE); } 

Они нарисуют кубик в середине экрана. Возможно, вы захотите сделать это более сложным, возможно, нарисовав D20 или D12 и так далее, но проще нарисовать базовый шестигранный кубик. Вот основное использование:

 drawDie(); 

Затем измените ваш основной цикл, чтобы нарисовать случайное число, только больше и посередине. Измените размер текста и курсор на это:

 display.setTextColor(WHITE); display.setCursor(57, 21); 

Теперь это выглядит намного лучше:

Arduino D20 одиночный символ

Единственная проблема с числами больше девяти:

Arduino D20 двойной характер

Исправить это просто. Для любых чисел меньше 10 курсор будет установлен в положение, отличное от этих цифр 10 или больше. Заменить эту строку:

 display.setCursor(57, 21); 

С этим:

 int roll = TrueRandom.random(1, 21); // store the random number if (roll < 10) { // single character number display.setCursor(57, 21); } else { // dual character number display.setCursor(47, 21); } 

Вот как это выглядит сейчас:

Arduino D20 фиксированный двойной символ

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

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

Arduino D20 работа
Изображение предоставлено: publicdomainvectors.org

Любое изображение, которое вы хотите использовать, необходимо преобразовать в HEX-массив. Это представление изображения в виде кода. Для этого доступно множество инструментов, и некоторые из них написаны специально для OLED дисплеев. Самый простой способ — использовать онлайн-инструмент PicturetoC_Hex . Вот необходимые настройки:

Arduino изображения в гекс

Загрузите свое изображение и установите формат кода HEX: 0x . Установите Используется для на Черный / Белый для всех функций рисования изображения . Оставьте все остальные параметры по умолчанию. Вы можете изменить размер изображения здесь, если вам нужно. Нажмите Get C String, и вы должны увидеть данные изображения:

Arduino D20 данные изображения

Вам понадобятся эти сгенерированные данные через минуту. Создайте две функции с именами drawExplosion и drawSkull (или подходящее имя для вашей версии). Вот код:

 void drawExplosion() { // store image in EEPROM static const unsigned char PROGMEM imExp[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x78,0x7f,0xff,0xc0,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xf0,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xfb,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x7f,0xff,0xff,0xff,0xff,0xff,0x00,0x01,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x03,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x03,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x03,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x03,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x07,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x07,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x07,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x07,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x0f,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x1f,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x1f,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x0f,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x03,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x03,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x03,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x01,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x0f,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x07,0xff,0xff,0xf9,0xff,0xd8,0x00,0x00,0x00,0x3f,0xff,0xf0,0x0f,0x00,0x00,0x00,0x00,0x1f,0x1f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0xff,0x00,0x00,0x00,0x00,0x00,0x0f,0xff,0xff,0xff,0x00,0x00,0x00,0x07,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x0f,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x1f,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x1f,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x01,0xbf,0xff,0xff,0xff,0x30,0x00,0x00,0x00,0x13,0xf7,0xb8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; display.drawBitmap(0, 0, imExp, 64, 62, 1); // draw mushroom cloud } void drawSkull() { // store image in EEPROM static const unsigned char PROGMEM imSku[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0x78,0x00,0x07,0xf0,0x00,0x00,0x00,0x00,0xfc,0x00,0x07,0xf8,0x00,0x00,0x00,0x00,0xfe,0x00,0x07,0xf8,0x00,0x00,0x00,0x01,0xfe,0x00,0x07,0xfc,0x00,0x00,0x00,0x01,0xfe,0x00,0x07,0xfe,0x00,0x3f,0xc0,0x03,0xfe,0x00,0x01,0xff,0x81,0xff,0xfc,0x07,0xec,0x00,0x00,0x3f,0xc7,0xff,0xff,0x1f,0xc0,0x00,0x00,0x0f,0xcf,0xff,0xff,0xdf,0x00,0x00,0x00,0x07,0xbf,0xff,0xff,0xee,0x00,0x00,0x00,0x01,0x7f,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x01,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x03,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x07,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x0f,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x0f,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x1f,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x1f,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x1f,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x1f,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x1f,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x1f,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x1e,0x3f,0xff,0x3f,0xc7,0x80,0x00,0x00,0x1e,0x0c,0x0f,0x00,0x07,0x80,0x00,0x00,0x1e,0x00,0x0f,0x00,0x0f,0x80,0x00,0x00,0x1e,0x00,0x19,0x80,0x0f,0x00,0x00,0x00,0x0f,0x00,0x19,0x80,0x0f,0x00,0x00,0x00,0x0d,0x00,0x30,0xc0,0x1f,0x00,0x00,0x00,0x05,0x80,0x70,0xc0,0x1e,0x00,0x00,0x00,0x05,0xf0,0xe0,0xe0,0x36,0x00,0x00,0x00,0x01,0xff,0xe0,0x7f,0xf0,0x00,0x00,0x00,0x03,0xff,0xc4,0x7f,0xf0,0x00,0x00,0x00,0x03,0xff,0xcc,0x7f,0xf0,0x00,0x00,0x00,0x03,0xff,0xcc,0x7f,0xf0,0x00,0x00,0x00,0x03,0xff,0x9e,0x7f,0xf0,0x00,0x00,0x00,0x00,0xff,0xfe,0x7f,0xc0,0x00,0x00,0x00,0x00,0x01,0xff,0xf8,0x1c,0x00,0x00,0x00,0x03,0xe0,0x3f,0x01,0xbf,0x00,0x00,0x00,0x07,0xa6,0x40,0x09,0x9f,0x80,0x00,0x00,0x1f,0x27,0x5a,0x39,0x9f,0xf8,0x00,0x01,0xff,0x27,0xdb,0x39,0x0f,0xfc,0x00,0x03,0xfe,0x31,0x7f,0x39,0x07,0xfc,0x00,0x03,0xfc,0x10,0x1a,0x02,0x03,0xf8,0x00,0x03,0xf8,0x10,0x00,0x02,0x01,0xf0,0x00,0x01,0xf8,0x10,0x00,0x02,0x01,0xe0,0x00,0x00,0x78,0x10,0x00,0x02,0x00,0xe0,0x00,0x00,0x70,0x30,0x00,0x02,0x00,0x00,0x00,0x00,0x30,0x20,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x64,0x00,0x1b,0x00,0x00,0x00,0x00,0x00,0x73,0x55,0x63,0x00,0x00,0x00,0x00,0x00,0xf9,0x55,0x4f,0x00,0x00,0x00,0x00,0x00,0x7f,0x14,0x1f,0x00,0x00,0x00,0x00,0x00,0x1f,0xe0,0xfe,0x00,0x00,0x00,0x00,0x00,0x0f,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x07,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x03,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; display.drawBitmap(0, 0, imSku, 60, 64, 1); // draw skull cloud } 

Если вы хотите использовать изображения, которые я использовал, тогда скопируйте код. Если вы хотите использовать свои собственные изображения, сгенерированные ранее, скопируйте байтовый код в массивы imSku и imExp по мере необходимости.

Вот как эти изображения выглядят на дисплее:

Arduino Oled изображения

Наиболее важной частью этого кода является эта строка:

 static const unsigned char PROGMEM imSku[] 

Это говорит Arduino хранить ваши изображения в EEPROM ( что такое EEPROM? ) вместо его ОЗУ ( краткое руководство по ОЗУ ). Причина этого проста; Arduino имеет ограниченную оперативную память, и использование всего этого для хранения изображений может не оставить ничего для выполнения вашего кода

Измените ваш основной оператор if, чтобы показывать эти новые графики, когда выпадает единица или 20. Обратите внимание на строки кода, чтобы показать число, свернутое вместе с изображениями:

 if(roll == 20) { drawExplosion(); display.setCursor(80, 21); display.println("20"); } else if(roll == 1) { display.setCursor(24, 21); display.println("1"); drawSkull(); } else if (roll < 10) { // single character number display.setCursor(57, 21); display.println(roll); // write the roll drawDie(); // draw the outline } else { // dual character number display.setCursor(47, 21); display.println(roll); // write the roll drawDie(); // draw the outline } 

А вот как выглядят эти новые роллы:

Arduino D20 критических изображений

Это все, что касается кода (иди, возьми код из GitHub, если ты пропустил все это). Вы можете легко изменить это на D12, D8 и так далее.

Финальная сборка

Теперь, когда все остальное закончено, пришло время собрать все вместе. Прикрутите дисплей, следя за тем, чтобы не перетянуть болты. Это, пожалуй, самая сложная часть. Я взломал дисплей, поэтому вы можете использовать некоторые пластиковые шайбы. Я вырезал несколько квадратов из Plasticard :

Arduino D20 Проставки

Маленькие гайки и болты могут быть сложны для подключения. Совет: Используйте маленький кусок Blu-Tack на конце отвертки, чтобы изначально посадить гайки:

Arduino D20 Орех

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

Arduino D20 Внутри картона

Вот как это выглядит внутри:

Arduino D20 внутри

И вот готовый продукт:

Arduino D20 Skull

Теперь вы должны быть счастливым обладателем электронного D20!

Какие модификации вы сделали? Вы меняли изображения? Дайте нам знать в комментариях, мы будем рады видеть, что вы сделали!

Похожие посты
Diy

Вещи, которые вы должны иметь в виду, прежде чем брать ноутбук или смартфон в службу технической поддержки

Diy

Как использовать Arduino для съемки красивой скоростной фотографии

DiyLinux

Пять великолепных расширений Raspberry Pi, которые делают его еще более полезным

Diy

Первые шаги с Arduino: пристальный взгляд на печатную плату и структуру программы