Rulați în stil cu această matriță electronică DIY D20

Rulați în stil cu această matriță electronică DIY D20

Doriți ceva puțin unic pentru următorul dvs. joc de rol de masă? Ce zici de un D20 electronic cu grafică personalizată pentru lovituri și ratări critice? Astăzi vă voi arăta cum să vă construiți propriul cu un Arduino și câteva piese simple.





Nu vă faceți griji dacă nu ați folosit niciodată un Arduino înainte, avem un Ghidul începătorului .





Construiți planul

Acesta este un proiect simplu. Un Arduino va conduce un afișaj OLED și un buton va rula matrița. Graficele personalizate vor fi afișate pentru lovituri critice sau lansări critice. Puteți modifica cu ușurință codul pentru a fi D8, D10 sau D12.





De ce ai nevoie

  • 1 x Arduino
  • 1 x 0,96 ' Afișaj I2C OLED
  • 1 x buton
  • 1 x 10k? Rezistor
  • 1 x panou de pâine
  • Cabluri asortate
  • Cod complet aici, dacă nu doriți să urmați până la capăt instrucțiunile scrise.

Acestea sunt piesele de bază de care aveți nevoie pentru a vă construi propriul D20. Poate doriți să îl instalați într-o carcasă (discutat mai jos) și să lipiți circuitul într-o stare mai permanentă. Iată părțile suplimentare de care va trebui să faceți acest lucru:

Aceste afișaje OLED sunt foarte cool. De obicei, acestea pot fi achiziționate în alb, albastru, galben sau într-un amestec al celor trei. Am achiziționat unul în albastru, pentru a se potrivi cu cazul meu. Asigurați-vă că obțineți un I2C model în loc de SPI .



Aproape orice Arduino va fi potrivit. Am ales un Nano, deoarece sunt suficient de mici pentru a se încadra în carcasă. Consultați ghidul nostru de cumpărare pentru mai multe informații despre modelele Arduino.

Circuitul

Iată circuitul de care aveți nevoie:





Conectați VCC și GND pe afișajul OLED către Arduino + 5V și sol . Conectați analogic 4 pe Arduino la pinul etichetat SDA . Conectați analogic 5 la SCL pin. Acești pini conțin circuitele necesare pentru a conduce afișajul folosind magistrala I2C. Pinii exacți vor varia în funcție de model, dar A4 și A5 sunt utilizate pe Nano și Uno. Verifică Documentația bibliotecii de sârmă pentru modelul dvs. dacă nu utilizați un Uno sau Nano.

Conectați bateria la masă și la VIN pin. Aceasta înseamnă tensiune de intrare și acceptă o varietate de tensiuni DC diferite - dar verificați mai întâi modelul specific și uneori poate varia ușor.





Conectați butonul la pin digital 2 . Observați cum 10k? rezistorul este conectat la masă. Este foarte important! Acest lucru este cunoscut sub numele de rezistență pull down și împiedică Arduino să detecteze date false sau interferențe la apăsarea unui buton. De asemenea, servește pentru a proteja placa. Dacă acest rezistor nu ar fi folosit, + 5V ar merge direct în sol. Acest lucru este cunoscut sub numele de pe scurt și este o modalitate ușoară de a ucide un Arduino.

Dacă lipiți acest circuit, protejați-vă conexiunile cu tuburi termocontractabile:

Asigurați-vă că nu îl încălziți prea mult și faceți acest lucru numai după ce sunteți sigur că circuitul funcționează. Poate doriți să vă răsuciți cablurile în perechi. Acest lucru îi menține îngrijit și îi ajută să îi protejeze de stresul nejustificat:

Test buton

Acum că ați construit circuitul, încărcați acest cod de test (asigurați-vă că selectați placa și portul corecte din Instrumente> Tablă și Instrumente> Port meniuri):

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

Odată încărcat, păstrați Arduino conectat prin USB și deschideți monitorul serial ( În dreapta sus> Monitor serial ). Ar trebui să vezi cuvintele Functioneaza apare de fiecare dată când apăsați butonul.

Dacă nu se întâmplă nimic, du-te și verifică din nou circuitul tău.

Configurare OLED

Trebuie să instalați două biblioteci pentru a conduce afișajul. Descărcați fișierul Adafruit_SSD1306 și bibliotecile Adafruit-GFX [Nu mai sunt disponibile] de la Github și salvați-le în dosarul bibliotecii. Dacă nu sunteți sigur unde sunteți folderele bibliotecii, citiți tutorialul meu retro pentru jocuri, unde configurez același afișaj mai detaliat.

Reporniți ID-ul Arduino și încărcați o schiță de test din Fișier> Exemple meniul. Selectați Adafruit SSD1306 și apoi ssd1306_128x64_i2c . Încărcați acest cod (va dura ceva timp) și ar trebui să vedeți o mulțime de forme și modele pe ecran:

Dacă nu se întâmplă nimic, verificați conexiunile. Dacă, după verificare, tot nu va funcționa, va trebui să modificați codul eșantion.

cum să ștergeți un hard disk Windows 10

Schimbați această linie (la începutul înființat funcţie):

display.begin(SSD1306_SWITCHCAPVCC, 0x3D);

La acest:

display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

Aceasta spune bibliotecii detalii specifice despre afișajul pe care îl utilizați. Acum ar trebui să fiți pregătit să continuați cu construirea.

Cazul

Dacă construiți acest lucru pe o placă de calcul sau nu doriți să îl adăugați la cutie, atunci puteți sări peste acest pas.

Am proiectat și am imprimat 3D această cutie. Puneți fișierele pe Thingiverse . Nu vă faceți griji dacă nu aveți o imprimantă 3D - servicii online Huburi 3D și Shapeways furnizează servicii de tipărire online.

Ați putea face cu ușurință această cutie din lemn sau cumpărând un plastic caseta proiectului .

Capacul este un design simplu push push și conține câteva decupaje pentru hardware:

Codul

Acum că totul este gata, este timpul pentru cod. Iată cum va funcționa Pseudo cod :

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

Pentru ca acest lucru să funcționeze corect, trebuie generat un număr aleatoriu - aceasta este sulul matriței. Arduino are un generator de numere aleatorii numit Aleatoriu , dar nu ar trebui să-l folosească. Deși este suficient de bun pentru sarcini aleatorii de bază, nu este suficient de aleatoriu pentru o matriță electronică. Motivele pentru care sunt oarecum complicate, dar puteți citi mai multe dacă vă interesează boallen.com .

Descărcați fișierul TrueRandom bibliotecă de sirleech pe Github. Adăugați acest lucru în dosarul bibliotecii și reporniți IDE-ul.

Acum creați un fișier nou și configurați codul inițial (sau pur și simplu preluați codul terminat de la 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() {

}

Acest cod configurează OLED și include toate bibliotecile de care aveți nevoie pentru a comunica cu acesta, împreună cu noua dvs. bibliotecă cu numere aleatorii. Acum adăugați acest lucru la bucla 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);
}
}

Acest lucru este destul de simplu la un moment dat, dar este un D20 funcțional. De fiecare dată când butonul este apăsat, pe ecran este afișat un număr aleatoriu între unu și 20:

Acest lucru funcționează bine, dar este un pic plictisitor. Să o facem mai bună. Creați două metode noi, drawDie și eraseDie :

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

Acestea vor extrage o matriță în mijlocul ecranului. Poate doriți să faceți acest lucru mai complicat, poate desenând un D20 sau un D12 și așa mai departe, dar este mai simplu să desenați o matriță de bază cu șase fețe. Iată utilizarea de bază:

drawDie();

Apoi, modificați bucla principală pentru a desena numărul aleatoriu, doar mai mare și la mijloc. Schimbați dimensiunea textului și cursorul astfel:

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

Acum arată mult mai bine:

Singura problemă este cu numerele mai mari de nouă:

Remedierea pentru acest lucru este simplă. Orice numere mai mici de 10 vor avea cursorul setat la o poziție diferită de acele numere 10 sau mai mari. Înlocuiți această linie:

cum să nu mai utilizați rețelele sociale
display.setCursor(57, 21);

Cu asta:

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

Iată cum arată acum:

Tot ce a mai rămas acum este pentru imagini atunci când lansați o lovitură sau o ratare critică. Există câțiva pași implicați, dar este un proces suficient de simplu.

Găsiți o imagine adecvată pe care doriți să o utilizați (cu cât este mai simplă, cu atât mai bine, cu cât afișajul are o singură culoare). Iată imaginile pe care le-am folosit:

Credit de imagine: publicdomainvectors.org

Orice imagine pe care doriți să o utilizați va trebui convertită într-o matrice HEX. Aceasta este o reprezentare a imaginii sub formă de cod. Există multe instrumente disponibile pentru a face acest lucru, iar unele sunt scrise special pentru afișajele OLED. Cel mai simplu mod este să utilizați fișierul PicturetoC_Hex instrument online. Iată setările necesare:

cum să înregistrați audio de pe site

Încărcați imaginea și setați formatul codului la HEX: 0x . A stabilit Folosit pentru la Alb / negru pentru toate funcțiile de desenare a imaginii . Lăsați toate celelalte opțiuni ca valori implicite. Puteți redimensiona imaginea aici, dacă aveți nevoie. presa Obțineți șirul C și ar trebui să vedeți datele despre imagine să apară:

Veți avea nevoie de aceste date generate într-un minut. Creați două funcții numite drawExplosion și drawSkull (sau un nume potrivit pentru versiunea dvs.). Iată codul:

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
}

Dacă doriți să utilizați imaginile pe care le-am folosit, continuați și copiați codul. Dacă doriți să utilizați propriile imagini pe care le-ați generat anterior, copiați codul de octet în imSku și imExp matrici după cum este necesar.

Iată cum arată aceste imagini pe ecran:

Cea mai importantă parte a codului este următoarea linie:

static const unsigned char PROGMEM imSku[]

Acest lucru îi spune Arduino să vă stocheze imaginile în EEPROM ( ce este EEPROM? ) în loc de memoria RAM ( ghid rapid pentru RAM ). Motivul pentru aceasta este simplu; Arduino are o memorie RAM limitată și utilizarea acesteia pentru a stoca imagini poate să nu lase rămase pentru executarea codului dvs.

Modifică-ți principalul dacă declarație pentru a afișa aceste noi grafice atunci când unul sau 20 este rulat. Rețineți liniile de cod pentru a afișa și numărul rulat alături de imagini:

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
}

Iată cum arată acele role noi:

Asta este tot pentru partea codului (du-te să ia codul de la GitHub dacă ai omis toate acestea). Puteți modifica cu ușurință acest lucru pentru a fi un D12, D8 și așa mai departe.

Asamblarea finala

Acum, că toate celelalte sunt terminate, este timpul să le aranjăm pe toate. Înșurubați afișajul, asigurându-vă că nu strângeți excesiv șuruburile. Aceasta este probabil cea mai dificilă parte. Am spart un afișaj făcând acest lucru, deci este posibil să doriți să utilizați niște șaibe de plastic. Am tăiat niște pătrate din Plasticard :

Piulițele mici și șuruburile pot fi dificil de conectat. Bacsis: Folosiți o bucată mică de Blu-Tack la capătul unei șurubelnițe pentru a așeza inițial piulițele:

Înșurubați butonul, conectați bateria și închideți capacul. Aveți grijă să nu prindeți fire sau să le legați prea strâns, provocând posibil un scurtcircuit. În funcție de lungimea cablurilor dvs. finale, poate fi necesar să protejați conexiunile expuse cu o anumită izolație (o cutie de serie funcționează bine):

Iată cum arată în interior:

Și iată produsul finit:

Ar trebui să fii acum mândru proprietar al unui D20 electronic!

Ce modificări ai făcut? Ai schimbat imaginile? Spuneți-ne în comentarii, ne-ar plăcea să vedem ce ați făcut!

Acțiune Acțiune Tweet E-mail Un ghid pentru începători pentru vorbirea animată

Animarea vorbirii poate fi o provocare. Dacă sunteți gata să începeți să adăugați dialog la proiectul dvs., vom descompune procesul pentru dvs.

Citiți în continuare
Subiecte asemănătoare
  • DIY
  • Arduino
  • Joc de societate
  • Electronică
Despre autor Joe Coburn(136 articole publicate)

Joe este absolvent de Informatică de la Universitatea Lincoln, Marea Britanie. Este un dezvoltator de software profesionist și, atunci când nu zboară cu drone sau nu scrie muzică, poate fi găsit adesea făcând fotografii sau producând videoclipuri.

Mai multe de la Joe Coburn

Aboneaza-te la newsletter-ul nostru

Alăturați-vă newsletter-ului pentru sfaturi tehnice, recenzii, cărți electronice gratuite și oferte exclusive!

Faceți clic aici pentru a vă abona
Categorie Diy