Rullige end stiilselt selle isetehtud elektroonilise D20 matriitsiga

Rullige end stiilselt selle isetehtud elektroonilise D20 matriitsiga

Kas soovite oma järgmise lauamängude rollimängu jaoks midagi pisut unikaalset? Kuidas oleks elektroonilise D20 -ga, millel on kohandatud graafika kriitiliste tabamuste ja puudumiste jaoks? Täna näitan teile, kuidas Arduino ja mõne lihtsa osa abil oma ehitada.





Ärge muretsege, kui te pole kunagi varem Arduinot kasutanud, meil on alustamise juhend .





Ehita plaan

See on lihtne projekt. Arduino juhib OLED -ekraani ja nupp veeretab matši. Kohandatud graafika kuvatakse kriitiliste tabamuste või kriitiliste missirullide korral. Saate hõlpsasti muuta koodi D8, D10 või D12.





Mida sa vajad

  • 1 x Arduino
  • 1 x 0,96 tolli I2C OLED display
  • 1 x nupp
  • 1 x 10k? Takisti
  • 1 x leivalaud
  • Ühendatud juhtmete ühendamine
  • Siin on täielik kood, kui te ei soovi kirjalikke juhiseid täielikult järgida.

Need on peamised osad, mida vajate oma D20 ehitamiseks. Võib -olla soovite selle paigaldada korpusesse (mida arutatakse allpool) ja vooluahel jootma püsivamasse olekusse. Siin on täiendavad osad, mida selleks vaja on:

Need OLED -ekraanid on väga lahedad. Tavaliselt saab neid osta valge, sinise, kollase või nende kolme seguga. Olen ostnud ühe sinise värvi, mis sobib minu juhtumiga. Veenduge, et saate I2C mudel asemel SPI .



Peaaegu iga Arduino sobib. Olen valinud Nano, kuna need on korpuse jaoks piisavalt väikesed. Arduino mudelite kohta lisateabe saamiseks vaadake meie ostujuhendit.

Ringkond

Siin on vajalik ahel:





Ühenda VCC ja GND OLED -ekraanil Arduinole +5V ja maapind . Ühenda analoog 4 Arduino peal märgistatud tihvtini SDA . Ühenda analoog 5 juurde SCL tihvt. Need tihvtid sisaldavad vooluringi, mis on vajalik ekraani juhtimiseks I2C siiniga. Täpsed tihvtid on mudeliti erinevad, kuid Nano ja Uno puhul kasutatakse A4 ja A5. Kontrolli Juhtmeraamatukogu dokumentatsioon oma mudeli jaoks, kui te ei kasuta Unot ega Nano.

Ühendage aku maandusega ja VEIN tihvt. See tähistab pinget ja aktsepteerib erinevaid alalisvoolu pingeid, kuid kontrollige kõigepealt oma konkreetset mudelit ja see võib mõnikord veidi erineda.





Ühendage nupp digitaalne tihvt 2 . Pange tähele, kuidas 10k? takisti on maandusega ühendatud. See on väga oluline! Seda nimetatakse tõmbetakistiks ja see takistab Arduino nupuvajutusel valeandmete või häirete tuvastamist. See kaitseb ka tahvlit. Kui seda takistit ei kasutataks, läheks +5V otse maasse. Seda tuntakse kui a surnult lühike ja see on lihtne viis Arduino tapmiseks.

Kui joote seda vooluringi, kaitske oma ühendusi termokahanevate torudega:

Veenduge, et te ei kuumutaks seda liiga palju, ja tehke seda ainult siis, kui olete veendunud, et vooluring töötab. Samuti võite soovida oma kaablid paaridesse keerata. See hoiab neid puhtana ja aitab kaitsta liigse stressi eest:

Nuppude test

Nüüd, kui olete vooluringi üles ehitanud, laadige see testkood üles (valige kindlasti õige plaat ja port Tööriistad> Tahvel ja Tööriistad> Port menüüd):

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

Pärast üleslaadimist hoidke Arduino USB kaudu ühendatud ja avage jadamonitor ( Üleval paremal> Seeriamonitor ). Peaksite sõnu nägema See töötab ilmub iga kord, kui nuppu vajutate.

Kui midagi ei juhtu, minge ja kontrollige oma vooluringi uuesti.

OLED Setup

Ekraani juhtimiseks peate installima kaks raamatukogu. Laadige alla Adafruit_SSD1306 ja Adafruit-GFX [enam saadaval] raamatukogud Githubist ja salvestage need oma raamatukogu kausta. Kui te pole kindel, kus teeki kaustad asuvad, lugege minu retromängude õpetust, kus konfigureerin sama ekraani üksikasjalikumalt.

Taaskäivitage Arduino IDE ja laadige üles testvisand Fail> Näited menüü. Valige Adafruit SSD 1306 ja siis ssd1306_128x64_i2c . Laadige see kood üles (see võtab natuke aega) ja peaksite ekraanil nägema palju kujundeid ja mustreid:

Kui midagi ei juhtu, kontrollige oma ühendusi uuesti. Kui see pärast kontrollimist ikkagi ei tööta, peate proovikoodi muutma.

kuidas saada Internet sülearvutisse kõikjal

Muutke seda rida (. Alguses seadistamine funktsioon):

display.begin(SSD1306_SWITCHCAPVCC, 0x3D);

Selleks:

display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

See ütleb raamatukogule kasutatava ekraani kohta üksikasjalikud andmed. Nüüd peaksite olema valmis ehitusega jätkama.

Juhul

Kui ehitate selle leivaplaadile või ei soovi seda kasti panna, võite selle sammu vahele jätta.

Kavandasin ja 3D printisin selle kasti. Lülitage failid sisse Thingiverse . Ärge muretsege, kui teil pole 3D -printerit - veebiteenused 3D -jaoturid ja Kujundid pakkuda veebipõhiseid printimisteenuseid.

Selle kasti saate hõlpsalt puidust valmistada või plastikust osta projekti kast .

Kaas on lihtne push fit disain ja sisaldab riistvara jaoks mõningaid väljalõikeid:

Kood

Nüüd, kui kõik on valmis, on aeg koodi sisestamiseks. Siit saate teada, kuidas see töötab Pseudokood :

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

Selleks, et see korralikult töötaks, tuleb genereerida juhuslik arv - see on koopia rull. Arduinol on juhuslike numbrite generaator juhuslik , kuid ei tohiks seda kasutada. Ehkki see on põhiliste juhuslike ülesannete jaoks piisavalt hea, pole see lihtsalt elektroonilise die jaoks piisavalt juhuslik. Põhjused on mõnevõrra keerulised, kuid võite huvi korral rohkem lugeda boallen.com .

Laadige alla TrueRandom raamatukogu poolt sirleech Githubis. Lisage see oma raamatukogu kausta ja taaskäivitage IDE.

Nüüd looge uus fail ja seadistage oma esialgne kood (või lihtsalt hankige valmis kood GitHubist):

#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() {

}

See kood konfigureerib OLED -i ja sisaldab kõiki raamatukogusid, mida peate sellega suhtlema, koos teie uue juhuslike numbrite koguga. Nüüd lisage see põhisilmusse:

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

See on hetkel üsna lihtne, kuid see on töötav D20. Iga kord, kui nuppu vajutatakse, kuvatakse ekraanil juhuslik number ühe ja 20 vahel:

See töötab hästi, kuid see on natuke igav. Teeme selle paremaks. Looge kaks uut meetodit, drawDie ja eraseDie :

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

Need joonistavad ekraani keskele matriitsi. Võib-olla soovite selle keerulisemaks muuta, näiteks joonistades D20 või D12 ja nii edasi, kuid lihtsam on joonistada põhiline kuuepoolne tikk. Siin on põhikasutus:

drawDie();

Seejärel muutke oma põhiahelat, et joonistada juhuslik arv, ainult suurem ja keskel. Muutke teksti suurus ja kursor selliseks:

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

See näeb nüüd palju parem välja:

Ainus probleem on arvud, mis on suuremad kui üheksa:

Selle parandus on lihtne. Kui arv on väiksem kui 10, on kursor seatud erinevasse kohta kui need numbrid 10 või suuremad. Asenda see rida:

kuidas sisestada riba Wordi
display.setCursor(57, 21);

Sellega:

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

See näeb nüüd välja selline:

Nüüd jääb üle ainult piltide jaoks kriitilise tabamuse või löögi tegemisel. See hõlmab mõningaid samme, kuid see on piisavalt lihtne.

Leidke sobiv pilt, mida soovite kasutada (mida lihtsam, seda parem, kuna ekraan on ainult ühevärviline). Siin on pildid, mida kasutasin:

Pildikrediit: publicdomainvectors.org

Kõik pildid, mida soovite kasutada, tuleb teisendada HEX -massiiviks. See on kujutise kujutis koodivormis. Selleks on saadaval palju tööriistu ja mõned on kirjutatud spetsiaalselt OLED -ekraanide jaoks. Lihtsaim viis on kasutada Pilt toC_Hex veebitööriist. Siin on vajalikud seaded:

kettakasutus 100, kuid mitte protsesse

Laadige oma pilt üles ja määrake koodivorminguks HEX: 0x . Määra Kasutatud et Must/valge kõigi joonistuspiltide jaoks . Jäta kõik muud valikud vaikeseadeteks. Vajadusel saate siin pildi suurust muuta. Vajutage Hankige C -string ja peaksite nägema pildiandmeid:

Neid genereeritud andmeid vajate minuti pärast. Looge kaks funktsiooni nimega drawExplosion ja joonistaKolju (või teie versioonile sobiv nimi). Siin on kood:

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
}

Kui soovite kasutada minu kasutatud pilte, siis jätkake ja kopeerige kood. Kui soovite kasutada oma varem loodud pilte, kopeerige baitkood kausta imSku ja imExp massiivid vastavalt vajadusele.

Need pildid näevad ekraanil välja järgmised:

Selle koodi kõige olulisem osa on see rida:

static const unsigned char PROGMEM imSku[]

See käsib Arduino'l salvestada teie pildid EEPROM -i ( mis on EEPROM? ) RAM -i asemel ( RAM -i kiirjuhend ). Selle põhjus on lihtne; Arduino mälu on piiratud ja selle kogu kasutamine piltide salvestamiseks ei pruugi teie koodi täitmiseks järele jääda

Muutke oma peamist kui avaldus, et näidata neid uusi graafikaid ühe või 20 valtsimisel. Pange tähele koodiridu, et kuvada ka piltide kõrval rullitud number:

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
}

Ja need rullid näevad välja järgmised:

See on koodipoole jaoks kõik (hankige kood GitHubist, kui jätsite selle kõik vahele). Saate selle hõlpsasti muuta D12, D8 jne.

Lõplik assamblee

Nüüd, kui kõik muu on valmis, on aeg kõik kokku pakkida. Keerake ekraan sisse, veendudes, et poldid ei pinguta üle. See on ilmselt kõige keerulisem osa. Ma lõhkusin seda tehes, nii et võite kasutada mõnda plastikust seibi. Lõikasin välja mõned ruudud Plastkaart :

Väikeste mutrite ja poltide ühendamine võib olla keeruline. Näpunäide: Kasutage kruvikeeraja otsas väikest tükki Blu-Tacki, et pähklid esmalt kinni panna:

Keerake nupp sisse, ühendage aku ja sulgege kaas. Olge ettevaatlik, et mitte juhtmeid kinni hoida ega liiga tihedalt kokku panna, mis võib põhjustada lühise. Sõltuvalt teie järeljuhtmete pikkusest peate võib -olla kaitsma avatud ühendusi mõne isolatsiooniga (jadakarp töötab hästi):

See näeb välja seestpoolt:

Ja siin on valmistoode:

Nüüd peaksite olema elektroonilise D20 uhke omanik!

Milliseid muudatusi tegite? Kas muutsite pilte? Andke meile kommentaarides teada, tahaksime näha, mida tegite!

Jaga Jaga Piiksuma E -post Algaja juhend kõne animeerimiseks

Kõne animeerimine võib olla väljakutse. Kui olete valmis oma projektile dialoogi lisama, jagame teie jaoks protsessi.

Loe edasi
Seotud teemad
  • Isetegija
  • Arduino
  • Lauamäng
  • Elektroonika
Autori kohta Joe Coburn(136 artiklit avaldatud)

Joe on lõpetanud arvutiteaduse Ühendkuningriigi Lincolni ülikoolis. Ta on professionaalne tarkvaraarendaja ja kui ta ei lennuta droonidega ega kirjuta muusikat, võib teda sageli leida pildistamas või videoid tootmas.

Rohkem Joe Coburnilt

Telli meie uudiskiri

Liituge meie uudiskirjaga, et saada tehnilisi näpunäiteid, ülevaateid, tasuta e -raamatuid ja eksklusiivseid pakkumisi!

Tellimiseks klõpsake siin