Rotola con stile con questo dado elettronico D20 fai-da-te

Rotola con stile con questo dado elettronico D20 fai-da-te

Vuoi qualcosa di unico per il tuo prossimo gioco di ruolo da tavolo? Che ne dici di un D20 elettronico con grafica personalizzata per colpi critici e miss? Oggi ti mostrerò come costruirne uno tuo con un Arduino e alcune semplici parti.





Non preoccuparti se non hai mai usato un Arduino prima, abbiamo un guida introduttiva .





Piano di costruzione

Questo è un progetto semplice. Un Arduino guiderà un display OLED e un pulsante farà rotolare il dado. La grafica personalizzata verrà mostrata per i tiri per i colpi critici o per i tiri mancati critici. Puoi facilmente modificare il codice in D8, D10 o D12.





Quello di cui hai bisogno

  • 1 x Arduino
  • 1x0.96' Display OLED I2C
  • 1 x pulsante
  • 1x10k? Resistore
  • 1 x tagliere
  • Cavi di collegamento assortiti
  • Codice completo qui, se non vuoi seguire fino in fondo le istruzioni scritte.

Queste sono le parti fondamentali di cui hai bisogno per costruire il tuo D20. Potresti voler installarlo in una custodia (discussa di seguito) e saldare il circuito in uno stato più permanente. Ecco le parti aggiuntive necessarie per farlo:

Questi display OLED sono molto belli. Di solito possono essere acquistati in bianco, blu, giallo o una miscela dei tre. Ne ho acquistato uno in blu, per abbinare il mio caso. Assicurati di ottenere un I2C modello invece di SPI .



Quasi tutti gli Arduino saranno adatti. Ho scelto un Nano, in quanto sono abbastanza piccoli da stare nella custodia. Consulta la nostra guida all'acquisto per ulteriori informazioni sui modelli Arduino.

Il circuito

Ecco il circuito che ti serve:





Collegare VCC e GND sul display OLED ad Arduino +5V e terreno . Collegare analogico 4 sull'Arduino al pin etichettato SDA . Collegare analogico 5 al SCL spillo. Questi pin contengono i circuiti necessari per pilotare il display utilizzando il bus I2C. I pin esatti variano in base al modello, ma su Nano e Uno vengono utilizzati A4 e A5. Controlla il Documentazione della libreria di cavi per il tuo modello se non stai utilizzando Uno o Nano.

Collegare la batteria a terra e il VINO spillo. Questo sta per tensione in ingresso e accetta una varietà di diverse tensioni CC, ma controlla prima il tuo modello specifico e a volte può variare leggermente.





Collega il pulsante a pin digitale 2 . Notate come i 10k? la resistenza è collegata a massa. Questo è molto importante! Questo è noto come resistore di pull down e impedisce ad Arduino di rilevare dati spuri o interferenze quando si preme un pulsante. Serve anche a proteggere il tabellone. Se questo resistore non fosse utilizzato, +5V andrebbe direttamente a terra. Questo è noto come a morto corto ed è un modo semplice per uccidere un Arduino.

Se stai saldando questo circuito, proteggi le tue connessioni con una guaina termorestringente:

Assicurati di non scaldarlo troppo e fallo solo quando sei sicuro che il circuito funzioni. Potresti anche voler intrecciare i cavi in ​​coppie. Questo li mantiene puliti e li aiuta a proteggerli dallo stress eccessivo:

Pulsante di prova

Ora che hai costruito il circuito, carica questo codice di prova (assicurati di selezionare la scheda e la porta corrette dal Strumenti > Tavola e Strumenti > Porta menù):

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

Una volta caricato, tieni collegato Arduino tramite USB e apri il monitor seriale ( In alto a destra > Monitor seriale ). Dovresti vedere le parole Funziona appaiono ogni volta che si preme il pulsante.

Se non succede nulla, vai a ricontrollare il tuo circuito.

Configurazione OLED

È necessario installare due librerie per pilotare il display. Scarica il Adafruit_SSD1306 e Adafruit-GFX [Non più disponibile] da Github e salvarli nella cartella della libreria. Se non sei sicuro di dove siano le cartelle della tua libreria, vai a leggere il mio tutorial sui giochi retrò, in cui configuro questo stesso display in modo più dettagliato.

Riavvia il tuo IDE Arduino e carica uno schizzo di prova dal File > Esempi menù. Selezionare Adafruit SSD1306 poi ssd1306_128x64_i2c . Carica questo codice (ci vorrà un po' di tempo) e dovresti vedere molte forme e motivi sul display:

Se non succede nulla, ricontrolla le tue connessioni. Se, dopo il controllo, continua a non funzionare, sarà necessario modificare il codice di esempio.

come spostare Google Drive su un'altra unità

Cambia questa riga (all'inizio del impostare funzione):

display.begin(SSD1306_SWITCHCAPVCC, 0x3D);

A questa:

display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

Questo dice alla libreria dettagli specifici sul display che stai usando. Ora dovresti essere pronto per continuare con la build.

Il caso

Se lo stai costruendo su una breadboard o non desideri imballarlo, puoi saltare questo passaggio.

Ho progettato e stampato in 3D questa scatola. Scarica i file Thingiverse . Non preoccuparti se non hai una stampante 3D: servizi online Hub 3D e Shapeways fornire servizi di stampa online.

Potresti facilmente realizzare questa scatola in legno o acquistando una plastica scatola del progetto .

Il coperchio è un semplice design a pressione e contiene alcuni ritagli per l'hardware:

Il codice

Ora che tutto è pronto, è il momento del codice. Ecco come funzionerà in Pseudocodice :

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

Affinché questo funzioni correttamente, deve essere generato un numero casuale: questo è il lancio del dado. Arduino ha un generatore di numeri casuali chiamato a caso , ma non dovrebbe usarlo. Sebbene sia abbastanza buono per le attività casuali di base, non è abbastanza casuale per un dado elettronico. I motivi sono alquanto complicati, ma puoi leggere di più se sei interessato a boallen.com .

Scarica il VeroCasuale biblioteca di sirleech su Github. Aggiungilo alla cartella della tua libreria e riavvia l'IDE.

Ora crea un nuovo file e imposta il tuo codice iniziale (o prendi semplicemente il codice finito da 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() {

}

Questo codice configura l'OLED e include tutte le librerie necessarie per comunicare con esso, insieme alla nuova libreria di numeri casuali. Ora aggiungi questo al ciclo principale:

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

Questo è abbastanza semplice al momento, ma è un D20 funzionante. Ogni volta che si preme il pulsante, sullo schermo viene visualizzato un numero casuale compreso tra uno e 20:

Funziona bene, ma è un po' noioso. Rendiamolo migliore. Crea due nuovi metodi, disegnareDie e cancellaDie :

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

Questi disegneranno un dado al centro dello schermo. Potresti voler rendere questo più complicato, magari disegnando un D20, o un D12 e così via, ma è più semplice disegnare un dado a sei facce di base. Ecco l'utilizzo di base:

drawDie();

Quindi, modifica il tuo ciclo principale per disegnare il numero casuale, solo più grande e nel mezzo. Modifica la dimensione del testo e il cursore in questo modo:

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

Sembra molto meglio ora:

L'unico problema è con i numeri maggiori di nove:

La soluzione per questo è semplice. Qualsiasi numero inferiore a 10 avrà il cursore impostato su una posizione diversa rispetto a quei numeri 10 o maggiori. Sostituisci questa riga:

cosa fare quando hai dimenticato la password dell'iPhone
display.setCursor(57, 21);

Con questo:

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

Ecco come appare ora:

Tutto ciò che resta ora è per le immagini quando ottieni un colpo critico o manchi. Ci sono alcuni passaggi coinvolti, ma è un processo abbastanza semplice.

Trova un'immagine adatta che desideri utilizzare (più semplice è, meglio è in quanto il display è solo a colore singolo). Ecco le immagini che ho usato:

Credito immagine: publicdomainvectors.org

Qualsiasi immagine che desideri utilizzare dovrà essere convertita in un array HEX. Questa è una rappresentazione dell'immagine sotto forma di codice. Ci sono molti strumenti disponibili per farlo e alcuni sono scritti specificamente per i display OLED. Il modo più semplice è usare il PicturetoC_Hex strumento in linea. Ecco le impostazioni necessarie:

Nintendo Switch non è in grado di connettersi al dispositivo di rete

Carica la tua immagine e imposta il formato del codice su HEX: 0x . Set Usato per a Nero/Bianco per tutte le funzioni di disegno dell'immagine . Lascia tutte le altre opzioni come predefinite. Se necessario, puoi ridimensionare l'immagine qui. premere Ottieni la stringa C e dovresti vedere apparire i dati dell'immagine:

Avrai bisogno di questi dati generati in un minuto. Crea due funzioni chiamate disegnareEsplosione e disegnareTeschio (o un nome adatto alla tua versione). Ecco il codice:

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 desideri utilizzare le immagini che ho usato, vai avanti e copia il codice. Se vuoi usare le tue immagini che hai generato in precedenza, copia il codice byte nel file imSku e imExp array come richiesto.

Ecco come appaiono queste immagini sul display:

La parte più importante di quel codice è questa riga:

static const unsigned char PROGMEM imSku[]

Questo dice ad Arduino di memorizzare le tue immagini nella EEPROM ( cos'è l'EEPROM? ) invece della sua RAM ( guida rapida alla RAM ). La ragione di ciò è semplice; l'Arduino ha una RAM limitata e l'utilizzo di tutto per memorizzare le immagini potrebbe non lasciare alcun residuo per l'esecuzione del codice

Modifica il tuo principale Se dichiarazione per mostrare questi nuovi grafici quando viene tirato un uno o un 20. Nota le righe di codice per mostrare anche il numero arrotolato accanto alle immagini:

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
}

Ed ecco come sono i nuovi rulli:

Questo è tutto per il lato del codice (vai a prendere il codice da GitHub se hai saltato tutto questo). Potresti facilmente modificarlo per essere un D12, D8 e così via.

Assemblea finale

Ora che tutto il resto è finito, è ora di inscatolare tutto. Avvitare il display, assicurandosi di non serrare eccessivamente i bulloni. Questa è forse la parte più difficile. Ho rotto un display così facendo, quindi potresti voler usare delle rondelle di plastica. Ho ritagliato dei quadratini Plasticard :

I piccoli dadi e bulloni possono essere difficili da collegare. Consiglio: Utilizzare un pezzetto di Blu-Tack all'estremità di un cacciavite per posizionare inizialmente i dadi:

Avvitare il pulsante, collegare la batteria e chiudere il coperchio. Fare attenzione a non intrappolare i fili o a non avvolgerli troppo strettamente, causando un cortocircuito. A seconda della lunghezza dei cavi finali, potrebbe essere necessario proteggere i collegamenti esposti con un po' di isolamento (una scatola seriale funziona bene):

Ecco come appare all'interno:

Ed ecco il prodotto finito:

Ora dovresti essere l'orgoglioso proprietario di un D20 elettronico!

Che modifiche hai fatto? Hai cambiato le immagini? Faccelo sapere nei commenti, ci piacerebbe vedere cosa hai fatto!

Condividere Condividere Tweet E-mail Una guida per principianti all'animazione del discorso

L'animazione del discorso può essere una sfida. Se sei pronto per iniziare ad aggiungere dialoghi al tuo progetto, analizzeremo il processo per te.

Leggi Avanti
Argomenti correlati
  • Fai da te
  • Arduino
  • Gioco da tavolo
  • Elettronica
Circa l'autore Joe Coburn(136 articoli pubblicati)

Joe si è laureato in Informatica presso l'Università di Lincoln, nel Regno Unito. È uno sviluppatore di software professionista e, quando non pilota droni o scrive musica, lo si trova spesso a scattare foto o produrre video.

Altro da Joe Coburn

Iscriviti alla nostra Newsletter

Iscriviti alla nostra newsletter per suggerimenti tecnici, recensioni, ebook gratuiti e offerte esclusive!

Clicca qui per iscriverti