Role com estilo com este molde eletrônico D20 DIY

Role com estilo com este molde eletrônico D20 DIY

Quer algo um pouco único para o seu próximo RPG de mesa? Que tal um D20 eletrônico com gráficos personalizados para acertos e erros críticos? Hoje vou mostrar como construir o seu próprio com um Arduino e algumas peças simples.





Não se preocupe se você nunca usou um Arduino antes, temos um Guia de Introdução .





Plano de construção

Este é um projeto simples. Um Arduino acionará um display OLED e um botão rolará o dado. Os gráficos personalizados serão exibidos para acertos críticos ou erros críticos. Você pode modificar facilmente o código para ser um D8, D10 ou D12.





O que você precisa

  • 1 x Arduino
  • 1 x 0,96 ' Tela I2C OLED
  • 1 x botão de pressão
  • 1 x 10k? Resistor
  • 1 x tábua de pão
  • Fios de conexão variados
  • Código completo aqui, se você não quiser seguir todas as instruções escritas.

Essas são as peças principais de que você precisa para construir seu próprio D20. Você pode querer instalá-lo em um gabinete (discutido abaixo) e soldar o circuito em um estado mais permanente. Aqui estão as partes adicionais de que você precisará para fazer isso:

  • 4 parafusos M2 x 10 mm (0,4 polegadas)
  • 4 x porcas M2
  • Arruelas 4 x 7 mm (0,28 polegada)
  • Encaixe de bateria de 9 V (ou alternativa adequada)
  • Tubos termorretráteis sortidos

Esses monitores OLED são muito legais. Eles geralmente podem ser comprados em branco, azul, amarelo ou uma mistura dos três. Comprei um em azul, para combinar com o meu caso. Certifique-se de obter um I2C modelo em vez de SPI .



Quase qualquer Arduino será adequado. Eu escolhi um Nano, pois eles são pequenos o suficiente para caber no case. Confira nosso guia de compra para obter mais informações sobre os modelos do Arduino.

O circuito

Aqui está o circuito de que você precisa:





Conectar VCC e GND no display OLED para o Arduino + 5V e chão . Conectar analógico 4 no Arduino para o pino rotulado SDA . Conectar analógico 5 ao SCL alfinete. Esses pinos contêm os circuitos necessários para acionar o monitor usando o barramento I2C. Os pinos exatos variam de acordo com o modelo, mas A4 e A5 são usados ​​no Nano e no Uno. Verifica a Documentação da biblioteca de fios para o seu modelo, se você não estiver usando um Uno ou Nano.

Conecte a bateria ao aterramento e o VINHO alfinete. Significa entrada de tensão e aceita uma variedade de tensões CC diferentes - mas verifique primeiro o seu modelo específico e às vezes pode variar um pouco.





Conecte o botão a pino digital 2 . Observe como o 10k? resistor está conectado ao aterramento. Isto é muito importante! Isso é conhecido como resistor pull down e evita que o Arduino detecte dados espúrios ou interferência ao pressionar um botão. Também serve para proteger o conselho. Se este resistor não fosse usado, + 5V iria direto para o terra. Isso é conhecido como muito curto e é uma maneira fácil de matar um Arduino.

Se você estiver soldando este circuito, proteja suas conexões com tubulação termorretrátil:

Certifique-se de não aquecê-lo muito e só faça isso quando tiver certeza de que o circuito está funcionando. Você também pode torcer seus cabos em pares. Isso os mantém organizados e ajuda a protegê-los do estresse indevido:

Teste de Botão

Agora que você construiu o circuito, carregue este código de teste (certifique-se de selecionar a placa e a porta corretas do Ferramentas> Tabuleiro e Ferramentas> Porta menus):

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);
}
}

Depois de carregado, mantenha o Arduino conectado via USB e abra o monitor serial ( Superior direito> Monitor serial ) Você deveria ver as palavras Funciona aparecem toda vez que você pressiona o botão.

Se nada acontecer, vá e verifique seu circuito.

Configuração de OLED

Você precisa instalar duas bibliotecas para acionar o monitor. Faça o download do Adafruit_SSD1306 e bibliotecas Adafruit-GFX [não mais disponíveis] do Github e salve-as na pasta da biblioteca. Se você não tem certeza de onde estão as pastas da biblioteca, leia meu tutorial de jogos retrô, onde configuro essa mesma tela com mais detalhes.

Reinicie seu IDE Arduino e carregue um esboço de teste do Arquivo> Exemplos cardápio. Selecione Adafruit SSD1306 e então ssd1306_128x64_i2c . Faça upload deste código (isso vai demorar um pouco), e você verá muitas formas e padrões na tela:

Se nada acontecer, verifique suas conexões. Se, após a verificação, ainda não funcionar, você precisará modificar o código de amostra.

como limpar um disco rígido do Windows 10

Altere esta linha (no início do configurar função):

display.begin(SSD1306_SWITCHCAPVCC, 0x3D);

Para isso:

display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

Isso informa à biblioteca detalhes específicos sobre o monitor que você está usando. Agora você deve estar pronto para continuar com a construção.

O caso

Se você estiver construindo isso em uma placa de ensaio ou não deseja encaixá-lo, pule esta etapa.

Eu projetei e imprimi esta caixa em 3D. Coloque os arquivos em Thingiverse . Não se preocupe se você não tiver uma impressora 3D - serviços online Hubs 3D e Shapeways fornecer serviços de impressão online.

Você pode facilmente fazer esta caixa de madeira ou comprando um plástico caixa de projeto .

A tampa tem um design de encaixe simples e contém alguns recortes para o hardware:

O código

Agora que tudo está pronto, é hora do código. É assim que vai funcionar em Pseudo-código :

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

Para que isso funcione corretamente, um número aleatório precisa ser gerado - este é o lançamento do dado. Arduino tem um gerador de números aleatórios chamado aleatória , mas não deve usá-lo. Embora seja bom o suficiente para tarefas aleatórias básicas, simplesmente não é aleatório o suficiente para um dado eletrônico. Os motivos são um tanto complicados, mas você pode ler mais se estiver interessado em boallen.com .

Faça o download do TrueRandom biblioteca por Sirleech no Github. Adicione isso à sua pasta de biblioteca e reinicie o IDE.

Agora crie um novo arquivo e configure seu código inicial (ou apenas pegue o código finalizado do GitHub):

#include
#include
#include
#include
#include
Adafruit_SSD1306 display(4);
void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // setup the OLED
pinMode(buttonPin, INPUT); // setup button
}
void loop() {

}

Este código configura o OLED e inclui todas as bibliotecas de que você precisa para se comunicar com ele, junto com sua nova biblioteca de números aleatórios. Agora adicione isso ao loop principal:

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);
}
}

Isso é bastante básico no momento, mas é um D20 funcional. Sempre que o botão é pressionado, um número aleatório entre um e 20 é mostrado na tela:

Isso funciona bem, mas é um pouco chato. Vamos melhorar. Crie dois novos métodos, drawDie e eraseDie :

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

Isso desenhará um dado no meio da tela. Você pode querer tornar isso mais complicado, talvez desenhando um D20, ou um D12 e assim por diante, mas é mais simples desenhar um dado básico de seis lados. Aqui está o uso básico:

drawDie();

Em seguida, modifique seu loop principal para desenhar o número aleatório, apenas maior e no meio. Altere o tamanho do texto e o cursor para este:

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

Parece muito melhor agora:

O único problema é com números maiores que nove:

A solução para isso é simples. Quaisquer números menores que 10 terão o cursor colocado em uma posição diferente dos números 10 ou maiores. Substitua esta linha:

como aumentar a RAM no macbook pro
display.setCursor(57, 21);

Com isso:

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);
}

Esta é a aparência agora:

Tudo o que resta agora são as imagens quando você rola um acerto crítico ou falha. Existem algumas etapas envolvidas, mas é um processo bastante simples.

Encontre uma imagem adequada que deseja usar (quanto mais simples, melhor, pois a exibição é de uma única cor). Aqui estão as imagens que usei:

Crédito da imagem: publicdomainvectors.org

Qualquer imagem que você deseja usar precisará ser convertida em uma matriz HEX. Esta é uma representação da imagem em formato de código. Existem muitas ferramentas disponíveis para fazer isso, e algumas são desenvolvidas especificamente para monitores OLED. A maneira mais fácil é usar o PicturetoC_Hex ferramenta online. Aqui estão as configurações necessárias:

como rasgar um blu-ray

Faça upload da sua imagem e defina o formato do código para HEX: 0x . Definir Usado para para Preto / Branco para todas as funções de desenho de imagem . Deixe todas as outras opções como padrão. Você pode redimensionar a imagem aqui se precisar. pressione Obter Cadeia de caracteres C e você deverá ver os dados da imagem aparecerem:

Você precisará desses dados gerados em um minuto. Crie duas funções chamadas drawExplosion e drawSkull (ou um nome adequado para sua versão). Aqui está o código:

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
}

Se você deseja usar as imagens que usei, vá em frente e copie o código. Se você quiser usar suas próprias imagens geradas anteriormente, copie o código de byte para o imSku e imExp matrizes conforme necessário.

Esta é a aparência dessas imagens na tela:

A parte mais importante desse código é esta linha:

static const unsigned char PROGMEM imSku[]

Isso diz ao Arduino para armazenar suas imagens na EEPROM ( o que é EEPROM? ) em vez de sua RAM ( guia rápido para RAM ) A razão para isso é simples; o Arduino tem RAM limitada e usá-la para armazenar imagens não pode deixar nada para o seu código executar

Modifique o seu principal E se declaração para mostrar esses novos gráficos quando um ou 20 é lançado. Observe as linhas de código para mostrar o número rolado ao lado das imagens também:

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
}

E aqui está a aparência desses novos rolos:

Isso é tudo para o lado do código (pegue o código do GitHub se você pulou tudo isso). Você pode facilmente modificá-lo para um D12, D8 e assim por diante.

Assembléia final

Agora que todo o resto está concluído, é hora de encaixotar tudo. Aparafuse a tela, certificando-se de não apertar demais os parafusos. Esta é possivelmente a parte mais difícil. Eu rachei uma tela ao fazer isso, então você pode querer usar algumas arruelas de plástico. Eu cortei alguns quadrados de Plasticard :

As porcas e parafusos pequenos podem ser difíceis de conectar. Gorjeta: Use um pequeno pedaço de Blu-Tack na ponta de uma chave de fenda para inicialmente encaixar as porcas:

Aparafuse o botão, conecte a bateria e feche a tampa. Tenha cuidado para não prender os fios ou enrolá-los com muita força, possivelmente causando um curto. Dependendo do comprimento dos cabos de fuga, pode ser necessário proteger as conexões expostas com algum isolamento (uma caixa serial funciona bem):

Aqui está o que parece por dentro:

E aqui está o produto acabado:

Agora você deve ser o orgulhoso proprietário de um D20 eletrônico!

Que modificações você fez? Você mudou as imagens? Deixe-nos saber nos comentários, adoraríamos ver o que você fez!

Compartilhado Compartilhado Tweet O email Um guia para iniciantes em animação de discurso

Animar a fala pode ser um desafio. Se você estiver pronto para começar a adicionar diálogo ao seu projeto, vamos dividir o processo para você.

Leia a seguir
Tópicos relacionados
  • faça você mesmo
  • Arduino
  • Jogo de tabuleiro
  • Eletrônicos
Sobre o autor Joe Coburn(136 artigos publicados)

Joe é graduado em Ciência da Computação pela University of Lincoln, no Reino Unido. Ele é um desenvolvedor de software profissional e, quando não está pilotando drones ou escrevendo música, pode ser encontrado tirando fotos ou produzindo vídeos.

Mais de Joe Coburn

Assine a nossa newsletter

Junte-se ao nosso boletim informativo para dicas de tecnologia, análises, e-books grátis e ofertas exclusivas!

Clique aqui para se inscrever