Mundarija:

Python va Arduino -da MIDI baraban to'plami: 5 qadam (rasmlar bilan)
Python va Arduino -da MIDI baraban to'plami: 5 qadam (rasmlar bilan)

Video: Python va Arduino -da MIDI baraban to'plami: 5 qadam (rasmlar bilan)

Video: Python va Arduino -da MIDI baraban to'plami: 5 qadam (rasmlar bilan)
Video: Сенсорная кнопка | Control Surface | Arduino | Midi 2024, Noyabr
Anonim
Image
Image
Python va Arduino -da MIDI baraban to'plami
Python va Arduino -da MIDI baraban to'plami
Python va Arduino -da MIDI baraban to'plami
Python va Arduino -da MIDI baraban to'plami

Men bolaligimdan baraban to'plamini sotib olishni xohlardim. O'sha paytda, barcha musiqiy asboblar raqamli dasturlarga ega emas edi, chunki bizda bugungi kun ko'p, shuning uchun narxlar kutilganidek yuqori edi. Yaqinda men eBay -dan eng arzon baraban to'plamini sotib olishga qaror qildim: uni yirtib tashlash va o'z apparat va dasturiy ta'minotimni qurilmaga ulash.

Sotib olish hech kimni xafa qilmadi: 9 ta turli xil ovoz yostig'i bo'lgan ko'chma baraban to'plami, tepki baraban va salom-shapka uchun ikkita oyoqli pedal va micro-USB rozetkasi. Haqiqatan ham, demotivatsiya qiluvchi narsa bu chiqish tovushlari (bu to'plamdan haqiqiy foydalanish tashqi karnayni ulash va undan zavqlanish). Shunday qilib, men uni USB, Arduino -ga asoslangan MIDI baraban to'plami va Python -ga asoslangan foydalanuvchi interfeysi orqali o'zim dasturlashtiriladigan dasturga aylantirishga qaror qildim.

Qurilmaning xususiyatlari:

  • Past narx
  • Har qanday raqamli kirishdan baraban to'plamini yaratish - hatto tugmalar to'plami
  • Faqat USB interfeysi orqali aloqani qo'llab -quvvatlash va quvvat manbai - USB -ni UART konvertori va Arduino qurilmasiga birlashtirish
  • Minimal qismlar to'g'ri ishlashi uchun
  • Python-ga asoslangan foydalanish oson interfeysi
  • O'rnatiladigan tezlik, eslatma va Arduino pinlari bilan to'liq MIDI qo'llab -quvvatlashi
  • Qurilmaning xotirasida saqlanadigan maxsus baraban konfiguratsiyalarini saqlash va yuklash

Keling, loyihaga o'tamiz …

1 -qadam: Operatsion nazariyasi

Amaliyot nazariyasi
Amaliyot nazariyasi
Amaliyot nazariyasi
Amaliyot nazariyasi
Amaliyot nazariyasi
Amaliyot nazariyasi

Blok diagrammasi

Birinchidan, loyiha tuzilishiga e'tibor qaratsak va uni alohida bloklarga ajratamiz:

Baraban to'plami

Loyihaning asosiy qismi. U 9 ta alohida baraban yostig'idan iborat bo'lib, ularda har bir tugma o'z mantiqiy holatini o'zgartiradigan tugmalar majmuasidir. Strukturasi tufayli baraban to'plamini har qanday tugmachadan yasash imkoniyati mavjud. Har bir baraban yostig'i asosiy elektron kartadagi tortishish qarshiligiga ulanadi, shuning uchun baraban yostig'i bir necha marta urilganda, kontaktlarning zanglashiga ma'lum bir kalit ulanadi va baraban paneli chizig'ida mantiqiy LOW mavjud. Hech qanday bosim o'tkazilmaganda, baraban yostig'i tugmachasi ochiladi va elektr tarmog'iga tortish qarshiligi tufayli baraban paneli chizig'ida mantiqiy HIGH mavjud. Loyihaning maqsadi to'liq raqamli MIDI qurilmasini yaratish bo'lgani uchun, asosiy PCBdagi barcha analog qismlarni e'tiborsiz qoldirish mumkin. Shuni ta'kidlash kerakki, baraban to'plamida tepish barabanlari va tepaliklar uchun ikkita pedal bor, ular tortishish rezistorlariga bog'langan va baraban tagliklari bilan bir xil ishlash mantig'iga ega (biz bu haqda biroz keyinroq gaplashamiz).).

Arduino Pro-Micro

Baraban to'plamining miyasi. Uning maqsadi - baraban yostig'idan signal chiqayotganini aniqlash va barcha kerakli parametrlarga mos MIDI chiqishini ta'minlash: Eslatma, signal tezligi va davomiyligi. Baraban yostiqchalarining raqamli tabiati tufayli ularni arduino raqamli kirishiga bog'lash mumkin (jami 10 ta pin). Barcha kerakli sozlamalar va MIDI ma'lumotlarini saqlash uchun biz uning xotirasidan foydalanamiz-EEPROM, shuning uchun har safar biz qurilmani yoqganimizda, MIDI ma'lumoti EEPROM-dan yuklanadi, bu uni qayta dasturlash va qayta sozlash imkonini beradi. Bundan tashqari, Arduino Pro-Micro juda kichik to'plamda mavjud va uni baraban to'plamining ichki qutisiga osongina ajratish mumkin.

FTDI USB dan seriyali konvertor

Kompyuter ilovasi yordamida bizning qurilmamiz xususiyatlarini dasturlash va aniqlash uchun USB interfeysini ketma-ket konvertatsiya qilish kerak, chunki Arduino Pro-Micro-da USB yo'q. Qurilmalar orasidagi aloqa UART -ga asoslanganligi sababli, FTDI qurilmasi, uning qo'shimcha xususiyatlaridan qat'i nazar, foydalanish qulayligi tufayli ushbu loyihada ishlatiladi.

Kompyuter uchun dastur - Python

Foydalanuvchi interfeysi va tez quriladigan loyihalar haqida gap ketganda, Python-bu ajoyib echim. UI dasturining maqsadi - baraban to'plamimiz uchun MIDI xususiyatlarini qayta aniqlash, ma'lumotlarni saqlash, dastur qurilmasi va kodni qayta -qayta kompilyatsiya qilmasdan tizimlar o'rtasida aloqa o'rnatish. Baraban to'plami bilan aloqa qilish uchun biz ketma -ket interfeysdan foydalanayotganimiz sababli, Internetda har qanday ketma -ket aloqani qo'llab -quvvatlaydigan juda ko'p bepul modullar mavjud. UART interfeysi RXD, TXD va DTR kabi uchta pimdan iborat. DTR Arduino modulini asl holatiga qaytarish uchun ishlatiladi, shuning uchun biz MIDI dasturini ishga tushirish yoki foydalanuvchi interfeysini dasturiy qurilmaga ulashdan manfaatdor bo'lsak, USB kabelini yoki boshqa biror narsani qayta ulashning hojati yo'q.

2 -qadam: qismlar va asboblar

Qismlar

  • Baraban to'plami
  • 2 x Sustain Pedals (Odatda, DK paketiga kiritilgan).
  • FTDI - USB dan seriyali konvertor
  • Arduino Pro Micro
  • Micro-USB kabeli

Asboblar

  • Lehimlash temir/stantsiya
  • Lehimlash kalay
  • Yupqa diametrli bitta yadroli sim
  • Cımbızlar
  • To'sar
  • Plier
  • Pichoq
  • Tornavida
  • 3D printer (ixtiyoriy - moslashtirilgan pedalli platformalar uchun)

Dasturiy ta'minot

  • Arduino IDE
  • Python 3 yoki undan yuqori
  • JetBrains Pycharm
  • Sochsiz MIDI interfeysi
  • loopMIDI

3 -qadam: Lehimlash va yig'ish

Lehimlash va yig'ish
Lehimlash va yig'ish
Lehimlash va yig'ish
Lehimlash va yig'ish
Lehimlash va yig'ish
Lehimlash va yig'ish

Birlashtirilishi kerak bo'lgan uchta modul borligi sababli, lehimlash va yig'ish jarayoni qisqa va oddiy:

  • Arduino Pro-Micro-ni FTDI qurilmasi bilan ulang, ulanishlar har bir qurilmada belgilangan kirish-chiqish moslamalariga mos kelishiga ishonch hosil qiling:

    • VBUS-VBUS
    • GND-GND
    • DTR-DTR
    • RXD-TXD
    • TXD-RXD
  • Barabanning plastmassa korpusidagi barcha vintlarni echib oling, siz diqqatni taxtadan simi va uning tortuvchi rezistorlariga qaratishingiz mumkin.
  • Biz ilgari qurgan Arduino-FTDI moduli uchun lehimli ingichka simlar:

    • Raqamli kirish: D [2:11]
    • VBUS
    • D+
    • D-
    • GND
  • Modulni batareya qutisiga joylashtiring, shunda simlar prokladkalarning tortish rezistorlari bilan bir tomonda suzadi.
  • Oxirgi rasmda ko'rsatilgandek, barcha raqamli kirishni baraban paneli terminallariga lehimlang.
  • Mikro USB-avtobusni (VBUS, D+, D-, GND) FTDI qurilmasiga ulang, bu simlarni kuzatishda xatolar yo'qligiga ishonch hosil qiling.
  • Arduino-FTDI modulini akkumulyator qutisiga issiq elim bilan mahkamlang
  • Qurilmani mos keladigan vintlar bilan mahkamlang

Biz buni qildik, qurilma yig'ildi. Kodni davom ettiramiz …

4 -qadam: A: Arduino dasturlash

Dasturlash A: Arduino
Dasturlash A: Arduino

Bosqichma-bosqich eskizimizni tasvirlab beramiz:

Birinchidan, to'g'ri ishlashi uchun ikkita kerakli kutubxonani kiritish kerak. EEPROM allaqachon Arduino IDE-da oldindan o'rnatilgan, ammo baraban uchun debyutor moduli alohida o'rnatilishi kerak

#qo'shing #qo'shing

Bu kalitlar asosan disk raskadrovka ketma -ketligida ishlatiladi. Agar siz Arduino terminallarining baraban yostig'iga ulanishini tekshirmoqchi bo'lsangiz va barcha raqamli kirishni aniqlasangiz, bu kalitlarni aniqlash kerak

/ * Tuzuvchi kalitlari: disk raskadrovka qilish yoki ishga tushirish uchun kerakli rejimga izoh bermang * ///#LOAD_DEFAULT_VALUES ni aniqlang // EEPROM o'rniga doimiy qiymatlarni yuklang //#PRINT_PADS_PIN_NUMBERS raqamini aniqlang // ketma -ket port orqali ulangan padga ulangan pin raqamini chop eting.

Ruxsat etilgan maydonlar barcha standart qiymatlarni, shu jumladan baraban paneli ro'yxatini ko'rsatadi. Qurilmani birinchi marta ishga tushirish uchun Hi-Hat va Kick pedallarining aniq ulanishini bilish kerak

/ * Baraban turini sanash */

DRUM_POSITION {KICK = 0, SNARE, HIHAT, RIDE, CYMBAL1, CYMBAL2, TOM_HIGH, TOM_MID, TOM_LO, HIHAT_PEDAL};

/ * Standart qiymatlar */

const uint8_t DRUM_NOTES [10] = {36, 40, 42, 51, 49, 55, 47, 45, 43, 48}; const uint8_t DRUM_VELOCITIES [10] = {110, 100, 100, 110, 110, 110, 110, 110, 110, 110}; const uint8_t DRUM_PINS [10] = {8, 6, 4, 3, 11, 9, 5, 10, 2, 7};

/ * Barabanni o'chirish muddati */

const uint8_t KICK_DB_DURATION = 30;

EEPROM kompyuter dasturidan keladigan barcha ma'lumotlarni saqlash/yuklash uchun ishlatiladi. Yuqorida tavsiflangan manzillar har bir baraban paneli uchun MIDI ma'lumotlarining aniq manzilini ko'rsatadi

/* EEPROM manzillar xaritasi

Izohlar: | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 |

Pim: | 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 | Tezliklar | 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22, 0x23 | */ const uint8_t NOTES_ADDR = 0x00; const uint8_t VELOCITIES_ADDR = 0x14; const uint8_t PINS_ADDR = 0x0A;

Global o'zgaruvchilar har bir pad holatini aniqlash va shunga mos ravishda MIDI aloqasini amalga oshirish uchun ishlatiladi

/ * Global o'zgaruvchilar */

uint8_t drumNotes [10], drumVelocities [10], drumPins [10]; // MIDI o'zgaruvchilari

uint8_t uartBuffer [64]; // MIDI Data Debouncer zarbasini yig'ish va saqlash uchun UART buferi (DRUM_PINS [KICK], KICK_DB_DURATION); // Kikkali baraban uchuvchi bool uchun oldiruvchi ob'ekt oldingiState [9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; // Davul paneli oldingi mantiq o'zgaruvchan bool currentState [9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; // Baraban padining hozirgi mantiqiy holatlari

EEPROM funktsiyalari

/* Sozlamalarni EEPROMda saqlang*/

bo'sh do'konEEPROM () {

memcpy (drumNotes, uartBuffer, 10); memcpy (drumPins, uartBuffer + 10, 10); memcpy (drumVelocities, uartBuffer + 20, 10); uchun (uint8_t i = 0; i <10; i ++) EEPROM.write (NOTES_ADDR+i, drumNotes ); uchun (uint8_t i = 0; i <10; i ++) EEPROM.write (PINS_ADDR+i, drumPins ); uchun (uint8_t i = 0; i <10; i ++) EEPROM.write (VELOCITIES_ADDR+i, drumVelocities ); }

/* EEPROM -dan sozlamalarni yuklash*/

void loadEEPROM () {for (uint8_t i = 0; i <10; i ++) drumNotes = EEPROM.read (NOTES_ADDR+i); uchun (uint8_t i = 0; i <10; i ++) drumPins = EEPROM.read (PINS_ADDR+i); uchun (uint8_t i = 0; i <10; i ++) drumVelocities = EEPROM.read (VELOCITIES_ADDR+i); }

O'zgaruvchilarni ishga tushirish va dasturlash rejimi, pedallar holatida va Arduino boot bir vaqtning o'zida yoqiladi

void enterProgrammingMode () {

bool confirmBreak = noto'g'ri; uint8_t lineCnt = 0; uint8_t charCnt = 0; char readChar = 0; while (! confirmBreak) {if (Serial.available ()) {uartBuffer [charCnt] = Serial.read (); agar (charCnt> = 29) confirmBreak = true; boshqa charCnt ++; }} Serial.println ("OK"); storeEEPROM (); }

void initValues () {

#ifdef LOAD_DEFAULT_VALUES memcpy (drumNotes, DRUM_NOTES, 10); memcpy (drumVelocities, DRUM_VELOCITIES, 10); memcpy (drumPins, DRUM_PINS, 10); #else loadEEPROM (); #endif}

MIDI Aloqa ishlovchilari, 1ms yozuvni ushlab turish vaqtini kechiktiradi

/ * MIDI eslatma funktsiyasini ijro etish */

void midiOut (DRUM_POSITION drumIn ro'yxati) {

if (drumIn == HIHAT) {// Agar HI-HAT urilgan bo'lsa, (! digitalRead (drumPins [HIHAT_PEDAL])) {noteOn (0x90, drumNotes [HIHAT_PEDAL], drumVelocities) [HIHAT_PEDAL]); kechikish (1); noteOn (0x90, drumNotes [HIHAT_PEDAL], 0); } else {noteOn (0x90, drumNotes [HIHAT], drumVelocities [HIHAT]); kechikish (1); noteOn (0x90, drumNotes [HIHAT], 0); }} else {// Doimiy baraban MIDI uzatish notasi (0x90, drumNotes [drumIn], drumVelocities [drumIn]); kechikish (1); noteOn (0x90, drumNotes [drumIn], 0); }}

void noteOn (int cmd, int pitch, int tezlik) {Serial.write (cmd); Serial.write (pitch); Serial.write (tezlik); }

setup () va loop () funktsiyalari cheksiz qurilma operatsion tsikliga ega:

bo'sh o'rnatish () {

Serial.begin (115200);

uchun (uint8_t i = 0; i <10; i ++) {pinMode (i+2, INPUT); } #ifdef PRINT_PADS_PIN_NUMBERS while (true) {// (uint8_t i = 0; i <10; i ++) {cheksiz disk raskadrovka aylanishi {if (! digitalRead (i+2)) {Serial.print ("Pin No: D"); Serial.print (i + '0'); // Raqamni ASCII belgisiga aylantirish}}} #else initValues (); / * Dasturlash rejimi: Agar yuklash paytida ikkita pedal bosilsa - rejim yoqiladi */ if (! DigitalRead (drumPins [KICK]) &&! DigitalRead (drumPins [HIHAT_PEDAL])) enterProgrammingMode (); #endif}

void loop () {for (uint8_t i = 1; i <9; i = i + 1) {currentState = digitalRead (drumPins ); if (! currentState && previousState ) midiOut (i); // Shtatlarni taqqoslang va oldingi holatni aniqlang oldingiState = currentState ; } kick.update (); // Kick baraban maxsus ajratish algoritmidan foydalanadi if (kick.edge ()) if (kick.falling ()) midiOut (KICK); }

5 -qadam: B dasturlash: Python va foydalanuvchi interfeysi

Dasturlash B: Python va foydalanuvchi interfeysi
Dasturlash B: Python va foydalanuvchi interfeysi
Dasturlash B: Python va foydalanuvchi interfeysi
Dasturlash B: Python va foydalanuvchi interfeysi
Dasturlash B: Python va foydalanuvchi interfeysi
Dasturlash B: Python va foydalanuvchi interfeysi

Python foydalanuvchi interfeysi birinchi qarashda tushunish uchun biroz murakkab, shuning uchun biz uning asoslarini, qanday ishlatilishini, har bir tugma qanday funktsiyaga ega ekanligini va Arduino qurilmasini to'g'ri dasturlashni tushuntirishga harakat qilardik.

Foydalanuvchi interfeysi - dastur

UI - bu baraban to'plami dasturchimiz uchun grafik tasvir bo'lib, Arduino qurilmasini istalgan vaqtda ishlatishni osonlashtiradi va qulay qiladi. UI bir nechta grafik modullardan iborat bo'lib, ular tavsiya etilgan ishlashga bog'liq. ularni birma -bir ko'rib chiqaylik:

  1. Baraban to'plami tasviri: Python interfeysi qaysi baraban turi tanlanganligini aniqlash uchun X-Y tasvir koordinatalarini ishlatadi. Agar to'g'ri baraban maydoni tanlansa, ikkilamchi IO xabari ko'rsatiladi, unda maydonlar, tezlik va maxsus baraban paneli uchun Arduino terminali ko'rsatiladi. Ushbu parametrlar foydalanuvchi tomonidan tasdiqlangan va tasdiqlanganidan so'ng, bu qiymatlar to'g'ridan -to'g'ri Arduino qurilmasiga uzatilishi mumkin.
  2. Tashqi nazoratchi tasviri: VST/Musiqa yaratish muhitiga ega MIDI baraban to'plamidan foydalanish uchun Serial-MIDI tarjimonini ishga tushirish kerak. Men Hairless -dan foydalandim, uni bepul olish mumkin va uni to'g'ridan -to'g'ri foydalanuvchi interfeysidan ishga tushirish mumkin, faqat uning tasvirini bosing.
  3. MAQOMOTI portlar ro'yxati: Arduino bilan bog'lanish uchun unga biriktirilgan COM portini ko'rsatish kerak. Ro'yxat Yangilash tugmachasini bosib yangilanmoqda.
  4. Konfiguratsiyani yuklash/saqlash: Kodda belgilangan MIDI qiymatlari mavjud bo'lib, ularni foydalanuvchi interfeysi bilan o'zaro aloqada o'zgartirish mumkin. Konfiguratsiya config.txt faylida foydalanuvchi tomonidan saqlanishi yoki yuklanishi mumkin bo'lgan maxsus formatda belgilanadi.
  5. Dastur qurilmasi tugmasi: Arduino EEPROM-da barcha o'zgartirilgan MIDI qiymatlarini saqlash uchun ikkita oyoq pedalini (Kick baraban va Hi-hat pedalini) bosish kerak, keyin ma'lumotlarni uzatish tugashini kutish kerak. Agar aloqa bilan bog'liq muammolar bo'lsa, tegishli pop-up ko'rsatiladi. Agar uzatish muvaffaqiyatli bo'lsa, UI muvaffaqiyatli xabarini ko'rsatadi.
  6. Chiqish tugmasi: Foydalanuvchining ruxsati bilan dasturdan chiqish kifoya.

Python kodining diqqatga sazovor joylari

Kodda juda ko'p narsa sodir bo'ladi, shuning uchun biz butun kodni emas, balki yozma funktsiyalarni kengaytiramiz.

Birinchidan, UI -dan foydalanish uchun kodni ishlashi uchun bir nechta modullarni yuklab olish kerak bo'ladi:

osimport threading import tkinter tk tkinter dan tkter import xabarlar qutisi * PIL import ImageTk dan tkinter import * dan xabarlar qutisi, np import ketma -ket import glob sifatida

Ba'zi modullar standart Python paketiga kiritilgan. PIP vositasi yordamida bir nechta modullarni o'rnatish kerak:

Yostiqchani o'rnatish

pip install numpy pip o'rnatish ScreenInfo

PyCharm orqali dasturni ishga tushirish tavsiya etiladi. Kelgusi nashrlarda men loyiha uchun bajariladigan faylni eksport qilishni rejalashtirmoqdaman.

Kod haqida qisqacha tushuntirish

Agar biz uning satrlariga funktsiyalar va sinflar nuqtai nazaridan qarasak, kodni tushunish ancha oson bo'ladi:

1. Asosiy funksiya - bu erda kod boshlanadi

agar _name_ == '_main_': drumkit_gui ()

2. Baraban to'plami konstantalari, koordinatalari va standart MIDI ma'lumotlari

sinf barabanlari: DRUM_TYPES = ["Kick", "Hihat", "Snare", "Crash 1", "Crash 2", "Tom High", "Tom Mid", "Tom Low", "Ride", "Hihat Pedal") "," Nazoratchi "]

COORDINATES_X = [323, 117, 205, 173, 565, 271, 386, 488, 487, 135, 79]

COORDINATES_Y = [268, 115, 192, 40, 29, 107, 104, 190, 71, 408, 208] DIMS_WIDTH = [60, 145, 130, 120, 120, 70, 70, 130, 120, 70, 145] DIMS_LENGTH = [60, 60, 80, 35, 35, 40, 40, 70, 35, 100, 50]

DRUM_ENUM = ["Kick", "Tuzoq", "Hihat", "Ride", "Crash 1", "Crash 2", "Tom High", "Tom Mid", "Tom Low", "Hihat pedal")]

DRUM_NOTES = [36, 40, 42, 51, 49, 55, 47, 45, 43, 48] DRUM_VELOCITIES = [110, 100, 100, 110, 110, 110, 110, 110, 110, 110] DRUM_PINS = [8, 6, 4, 3, 11, 9, 5, 10, 2, 7]

3. UI funktsiyalari - foydalanuvchi interfeysi va grafik ob'ektlarni qayta ishlash

def set_active (ui)

def ikkilamchi_ui (tambur turi)

sinf SelectionUi (tk. Frame)

sinf ilovasi (tk. Frame)

def drumkit_gui ()

def event_ui_clicked (voqea)

def getorigin (o'z -o'zidan, voqea)

4. Seriyali aloqa

def get_serial_ports ()

def communication_with_arduino (port)

5. Fayllar bilan ishlash: txt faylidan sozlamalarni saqlash/yuklash

def save_config ()

def load_config ()

6. Python Threading imkoniyatlari yordamida koddan hairless.exe tashqi dasturini ishga tushirish

ExternalExecutableThread klassi (threading. Thread)

def run_hairless_executable ()

Kodni ishga tushirish uchun loyiha papkasiga biriktirilishi kerak bo'lgan fayllar ro'yxati mavjud:

  • config.txt: Sozlamalar fayli
  • hairlessess.exe: sochsiz MIDI konvertori
  • drumkit.png: Bizning foydalanuvchi interfeysimizdagi barcha bosiladigan baraban yostiqchalarini aniqlaydigan rasm (bu qadamni rasmlar to'plamidan yuklab olish kerak)
  • drumgui.py: Loyiha kodi

Bu biz ishlashimiz uchun hamma narsani ta'kidlashimiz kerak. Loyihaga fayllarni qo'shish juda muhim: baraban tasviri, bajarilmaydigan hairless.exe va config.txt fayli.

Va.. Mana, biz shunday qildik!:)

Umid qilamanki, siz buni foydali deb topasiz.

O'qiganingiz uchun tashakkur!:)

Tavsiya: