Rul i stil med denne DIY elektroniske D20 Die

Rul i stil med denne DIY elektroniske D20 Die

Vil du have noget lidt unikt til dit næste rollespil på bordpladen? Hvad med en elektronisk D20 med brugerdefineret grafik til kritiske hits og savner? I dag viser jeg dig, hvordan du bygger din egen med en Arduino og et par enkle dele.





Bare rolig, hvis du aldrig har brugt en Arduino før, vi har en startguide .





Byg plan

Dette er et simpelt projekt. En Arduino kører et OLED -display, og en knap ruller matricen. Brugerdefineret grafik vises for kritisk hit eller kritiske miss -ruller. Du kan nemt ændre koden til at være en D8, D10 eller D12.





Hvad du har brug for

  • 1 x Arduino
  • 1 x 0,96 ' I2C OLED display
  • 1 x trykknap
  • 1 x 10k? Modstand
  • 1 x brødbræt
  • Assorterede tilslutningstråde
  • Fuld kode her, hvis du ikke vil følge hele vejen igennem de skriftlige instruktioner.

Det er de centrale dele, du skal bruge til at bygge din egen D20. Du vil måske installere det i en sag (diskuteret nedenfor) og lodde kredsløbet i en mere permanent tilstand. Her er de ekstra dele, du skal gøre for at gøre det:

  • 4 x M2 x 10 mm (0,4 tommer) bolte
  • 4 x M2 møtrikker
  • 4 x 7 mm (0,28 tommer) skiver
  • 9V batteri snap (eller passende alternativ)
  • Assorteret varmekrympeslange

Disse OLED -skærme er meget seje. De kan normalt købes i hvid, blå, gul eller en blanding af de tre. Jeg har købt en i blå, så den matcher min sag. Sørg for at få en I2C model i stedet for SPI .



Næsten enhver Arduino vil være egnet. Jeg har valgt en Nano, da de er små nok til at passe ind i etuiet. Se vores købsguide for mere information om Arduino -modeller.

Kredsløbet

Her er det kredsløb, du har brug for:





Forbinde VCC og GND på OLED -displayet til Arduino +5V og jord . Forbinde analog 4 på Arduino til stiften mærket SDA . Forbinde analog 5 til SCL pin. Disse ben indeholder det kredsløb, der er nødvendigt for at drive displayet ved hjælp af I2C -bussen. De nøjagtige stifter varierer efter model, men A4 og A5 bruges på Nano og Uno. Tjek Wire biblioteks dokumentation til din model, hvis du ikke bruger en Uno eller Nano.

Tilslut batteriet til jorden og VIN pin. Dette står for spænding i og accepterer en række forskellige DC -spændinger - men tjek din specifikke model først, og den kan nogle gange variere lidt.





Tilslut knappen til digital pin 2 . Læg mærke til hvordan 10k? modstand er forbundet til jorden. Dette er meget vigtigt! Dette er kendt som en pull down -modstand, og det forhindrer Arduino i at registrere falske data eller interferens ved et tryk på en knap. Det tjener også til at beskytte tavlen. Hvis denne modstand ikke blev brugt, ville +5V gå direkte i jorden. Dette er kendt som en død kort og er en nem måde at dræbe en Arduino på.

Hvis du lodder dette kredsløb, skal du beskytte dine forbindelser med varmekrympeslange:

Sørg for, at du ikke opvarmer det for meget, og gør det først, når du er sikker på, at kredsløbet fungerer. Du vil måske også sno dine kabler i par. Dette holder dem pæne og hjælper med at beskytte dem mod unødig stress:

Knap test

Nu hvor du har bygget kredsløbet, skal du uploade denne testkode (sørg for at vælge det korrekte kort og port fra Værktøjer> Board og Værktøjer> Port menuer):

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

Når den er uploadet, skal du holde Arduino tilsluttet via USB og åbne den serielle skærm ( Øverst til højre> Seriel skærm ). Du skulle se ordene Det virker vises hver gang du trykker på knappen.

Hvis der ikke sker noget, skal du gå og kontrollere dit kredsløb.

OLED -opsætning

Du skal installere to biblioteker for at køre skærmen. Download Adafruit_SSD1306 og Adafruit-GFX [No Longer Available] biblioteker fra Github, og gem dem i din biblioteksmappe. Hvis du ikke er sikker på, hvor biblioteksmapperne er, skal du læse min retro -spilstudie, hvor jeg konfigurerer den samme skærm mere detaljeret.

Genstart din Arduino IDE, og upload en testskitse fra Fil> Eksempler menu. Vælg Adafruit SSD1306 og så ssd1306_128x64_i2c . Upload denne kode (det vil tage et stykke tid), og du skal se masser af former og mønstre på displayet:

Hvis der ikke sker noget, skal du kontrollere dine forbindelser. Hvis det efter kontrol stadig ikke virker, skal du ændre prøvekoden.

dual boot windows 10 og linux

Skift denne linje (i starten af Opsætning fungere):

display.begin(SSD1306_SWITCHCAPVCC, 0x3D);

Til dette:

display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

Dette fortæller bibliotekets specifikke detaljer om det display, du bruger. Du skal nu være klar til at fortsætte med opbygningen.

Sagen

Hvis du bygger dette på et brødbræt, eller ikke ønsker at bokse det op, kan du springe dette trin over.

Jeg har designet og 3D -printet denne æske. Få filerne på Thingiverse . Bare rolig, hvis du ikke har en 3D -printer - onlinetjenester 3D -hubs og Shapeways tilbyde online udskrivningstjenester.

Du kan nemt lave denne æske af træ eller ved at købe en plastik projektboks .

Låget er et enkelt push -fit design og indeholder et par udskæringer til hardwaren:

Koden

Nu hvor alt er klar, er det tid til koden. Sådan fungerer det i Pseudokode :

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

For at dette kan fungere korrekt, skal der genereres et tilfældigt tal - dette er terningen. Arduino har en tilfældig talgenerator kaldet tilfældig , men skal ikke bruge det. Selvom det er godt nok til grundlæggende tilfældige opgaver, er det bare ikke tilfældigt nok til en elektronisk dør. Årsagerne til det er noget komplicerede, men du kan læse mere, hvis du er interesseret i boallen.com .

Download TrueRandom bibliotek ved sirleech på Github. Føj dette til din biblioteksmappe, og genstart IDE.

Opret nu en ny fil og konfigurer din oprindelige kode (eller tag den færdige kode fra 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() {

}

Denne kode konfigurerer OLED og inkluderer alle de biblioteker, du har brug for for at kommunikere med den, sammen med dit nye bibliotek med tilfældige tal. Tilføj nu dette til hovedsløjfen:

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

Dette er ganske grundlæggende i øjeblikket, men det er en fungerende D20. Når der trykkes på knappen, vises et tilfældigt tal mellem en og 20 på skærmen:

Dette fungerer godt, men det er lidt kedeligt. Lad os gøre det bedre. Opret to nye metoder, drawDie og sletteDie :

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

Disse vil tegne en matrice i midten af ​​skærmen. Du vil måske gøre dette mere kompliceret, måske ved at tegne en D20 eller en D12 og så videre, men det er lettere at tegne en grundlæggende seks-sidet matrice. Her er den grundlæggende brug:

drawDie();

Rediger derefter din hovedsløjfe for at tegne det tilfældige tal, kun større og i midten. Skift tekststørrelse og markør til dette:

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

Det ser meget bedre ud nu:

Det eneste problem er med tal større end ni:

Rettelsen til dette er enkel. Alle tal mindre end 10 har markøren indstillet til en anden position end tallene 10 eller større. Erstat denne linje:

siger jeg er tilsluttet, men intet internet
display.setCursor(57, 21);

Med dette:

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

Sådan ser det ud nu:

Det eneste, der er tilbage nu, er til billederne, når du ruller et kritisk hit eller savner. Der er et par trin involveret, men det er en enkel nok proces.

Find et passende billede, du vil bruge (jo enklere jo bedre, da displayet kun er i én farve). Her er de billeder, jeg brugte:

Billedkredit: publicdomainvectors.org

Ethvert billede, du ønsker at bruge, skal konverteres til et HEX -array. Dette er en repræsentation af billedet i kodeform. Der er mange værktøjer til rådighed til at gøre dette, og nogle er skrevet specielt til OLED -skærme. Den nemmeste måde er at bruge Billede til C_Hex online værktøj. Her er de nødvendige indstillinger:

hvorfor er diskplads på 100

Upload dit billede, og indstil kodeformatet til HEX: 0x . Sæt Anvendes til til Sort/hvid til alle tegnebilledfunktioner . Lad alle de andre muligheder stå som standard. Du kan ændre størrelsen på billedet her, hvis du har brug for det. Trykke Få C -streng og du skal se billeddataene vises:

Du får brug for disse genererede data på et minut. Opret to funktioner kaldet drawExplosion og drawSkull (eller et passende navn til din version). Her er koden:

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
}

Hvis du ønsker at bruge de billeder, jeg har brugt, så fortsæt og kopier koden. Hvis du vil bruge dine egne billeder, du har genereret tidligere, skal du kopiere byte -koden til imSku og imExp arrays efter behov.

Sådan ser disse billeder ud på displayet:

Den vigtigste del af denne kode er denne linje:

static const unsigned char PROGMEM imSku[]

Dette fortæller Arduino at gemme dine billeder i EEPROM ( hvad er EEPROM? ) i stedet for dets RAM ( hurtig guide til RAM ). Grunden til dette er enkel; Arduino har begrænset RAM, og hvis du bruger det hele til at gemme billeder, er der muligvis ingen rester tilbage, før din kode kan udføres

Rediger din main hvis erklæring for at vise denne nye grafik, når en eller 20 rulles. Bemærk kodelinjerne for også at vise nummeret rullet sammen med billederne:

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
}

Og sådan ser de nye ruller ud:

Det er alt for kodesiden (tag fat i koden fra GitHub, hvis du har sprunget alt det over). Du kan let ændre dette til at være en D12, D8 og så videre.

Endelig forsamling

Nu hvor alt andet er færdigt, er det tid til at bokse alt op. Bolt displayet på, og sørg for ikke at stramme boltene for meget. Dette er muligvis den sværeste del. Jeg knækkede et display ved at gøre det, så du vil måske bruge nogle plastskiver. Jeg skar nogle firkanter ud af Plasticard :

De små møtrikker og bolte kan være vanskelige at forbinde. Tip: Brug et lille stykke Blu-Tack på enden af ​​en skruetrækker til først at sætte møtrikkerne på plads:

Skru knappen på, tilslut batteriet og luk låget. Vær omhyggelig med ikke at fange nogen ledninger eller bundte dem for stramt, muligvis forårsage kortslutning. Afhængigt af længden af ​​dine bagledninger, skal du muligvis beskytte udsatte forbindelser med en vis isolering (en seriel boks fungerer godt):

Sådan ser det ud indeni:

Og her er det færdige produkt:

Du skulle nu være den stolte ejer af en elektronisk D20!

Hvilke ændringer foretog du? Har du ændret billederne? Fortæl os det i kommentarerne, vi vil meget gerne se, hvad du gjorde!

Del Del Tweet E -mail En begyndervejledning til animering af tale

Animering af tale kan være en udfordring. Hvis du er klar til at begynde at tilføje dialog til dit projekt, nedbryder vi processen for dig.

Læs Næste
Relaterede emner
  • gør det selv
  • Arduino
  • Brætspil
  • Elektronik
Om forfatteren Joe Coburn(136 artikler udgivet)

Joe er uddannet i datalogi fra University of Lincoln, UK. Han er en professionel softwareudvikler, og når han ikke flyver med droner eller skriver musik, kan han ofte findes tage fotos eller producere videoer.

Mere fra Joe Coburn

Abonner på vores nyhedsbrev

Tilmeld dig vores nyhedsbrev for at få tekniske tips, anmeldelser, gratis e -bøger og eksklusive tilbud!

Klik her for at abonnere