Isi kandungan:

Walabot FX - Kawalan Kesan Gitar: 28 Langkah (dengan Gambar)
Walabot FX - Kawalan Kesan Gitar: 28 Langkah (dengan Gambar)

Video: Walabot FX - Kawalan Kesan Gitar: 28 Langkah (dengan Gambar)

Video: Walabot FX - Kawalan Kesan Gitar: 28 Langkah (dengan Gambar)
Video: Walabot FX- Guitar Effect Control. Full Demo 2024, Julai
Anonim
Walabot FX - Kawalan Kesan Gitar
Walabot FX - Kawalan Kesan Gitar

Kawal kesan gitar kegemaran anda dengan hanya menggunakan gitar yang hebat!

Langkah 1: Perkara yang Anda Perlu

Komponen Perkakasan

Walabot - Walabot

Raspberry Pi - Raspberry Pi 3 Model B

Sunfounder LCD1602

Pemacu Servo SunFounder PCA9685 16 Saluran 12 Bit PWM untuk Arduino dan Raspberry Pi

Servo (generik) Tiada pautan

Klip Bateri 9V

Pemegang bateri 4xAA

Bateri AA

Wayar pelompat (generik)

DPDT Latching Action Foot Switch

Korg SDD3000-PDL

OS Perisian, Aplikasi dan Perkhidmatan Dalam Talian

Autodesk Fusion360 -

Blynk -

Alat dll

Pencetak 3D

Besi pematerian

Langkah 2: Abstrak

Getting Started
Getting Started

Bagaimana rasanya mengawal ekspresi muzik dengan menggunakan kedudukan gitar anda di ruang 3D? Baiklah, mari buat protoaip sesuatu dan cari tahu!

Langkah 3: Idea Asas

Saya mahu dapat mengawal parameter kesan 3 dalam masa nyata, saya mahu melakukan ini menggunakan cara saya meletakkan gitar saya. Jadi satu perkara yang jelas, saya memerlukan beberapa perkara.

  • Sensor yang dapat melihat ruang 3D
  • Servo untuk menghidupkan tombol
  • Paparan LCD
  • Pemacu Servo I2C
  • Pi Raspberry
  • Untuk belajar Python

Langkah 4: Walabot

Ingin melihat melalui dinding? Rasa objek dalam ruang 3D? Rasa jika anda bernafas dari seberang bilik? Nah, anda bernasib baik!

Walabot adalah cara baru untuk merasakan ruang di sekitar anda menggunakan radar kuasa rendah.

Ini akan menjadi kunci untuk projek ini, saya dapat mengambil kodinat objek karteasan (X-Y-Z) dalam ruang 3D, dan memetakannya ke posisi servo mengubah bagaimana bunyi gitar berbunyi, dalam masa nyata, tanpa menyentuh pedal.

Menang.

Maklumat lebih lanjut mengenai Walabot boleh didapati di sini

Langkah 5: Bermula

Perkara pertama yang pertama, anda memerlukan komputer untuk menggerakkan Walabot, untuk projek ini saya menggunakan Raspberry Pi 3 (di sini disebut di RPi) kerana WiFi dalam talian dan oomph tambahan umum

Saya membeli kad SD 16GB dengan NOOBS yang telah diprapasang untuk memastikan semuanya baik dan sederhana, dan memilih untuk memasang Raspian sebagai OS Linux pilihan saya

(jika anda tidak mengetahui cara memasang Raspian, sila luangkan sedikit masa untuk membaca ini)

OK, setelah Raspian dijalankan di RPi anda, terdapat beberapa langkah konfigurasi yang perlu diambil untuk menyiapkan projek kami

Langkah 6: Menyiapkan Raspberry Pi - 1

Pertama, pastikan anda menjalankan versi Kernel terkini dan periksa kemas kini dengan membuka shell perintah dan menaip

sudo apt-get kemas kini

sudo apt-get dist-upgrade

(sudo ditambahkan untuk memastikan anda mempunyai hak privasi pentadbiran, misalnya. barang akan berfungsi)

Ini mungkin memerlukan sedikit masa untuk diselesaikan, jadi pergi dan minum secawan teh yang enak.

Langkah 7: Menyiapkan Raspberry Pi - 2

Anda perlu memasang Walabot SDK untuk RPi. Dari penyemak imbas web RPi anda pergi ke https://www.walabot.com/gettingstarted dan muat turun Pakej Pemasang Raspberry Pi.

Dari shell arahan:

muat turun cd

sudo dpkg -I walabotSDK_RasbPi.deb

Langkah 8: Menyiapkan Raspberry Pi - 3

Kita perlu mula mengkonfigurasi RPi untuk menggunakan bas i2c. Dari shell arahan:

sudo apt-get install python-smbus

sudo apt-get pasang alat-alat i2c

setelah ini selesai, anda harus menambahkan yang berikut ke fail modul

Dari shell arahan:

sudo nano / etc / modul

tambahkan 2 rentetan ini pada baris berasingan:

i2c-dev

i2c-bcm2708

Langkah 9: Menyiapkan Raspberry Pi - 4

Walabot menarik sedikit arus, dan kami juga akan menggunakan GPIO untuk mengawal barang jadi kami perlu menyiapkannya

Dari shell arahan:

sudo nano /boot/config.txt

tambahkan baris berikut di akhir fail:

safe_mode_gpio = 4

max_usb_current = 1

RPi adalah alat yang sangat baik untuk pembuat, tetapi terhad pada masa ini yang dapat dihantar ke Walabot. Oleh itu mengapa kita menambah arus maksimum 1Amp dan bukannya 500mA yang lebih standard

Langkah 10: Python

Mengapa Python? baik, kerana sangat mudah dikod, cepat untuk berjalan dan terdapat banyak contoh python yang baik! Saya tidak pernah menggunakannya sebelum ini dan tidak lama lagi beroperasi. Sekarang RPi dikonfigurasi untuk apa yang kita inginkan, langkah selanjutnya adalah mengkonfigurasi Python agar dapat mengakses API Walabot, antara muka Servo LCD

Langkah 11: Untuk Walabot

Dari shell arahan

Sudo pip memasang “/usr/share/walabot/python/WalabotAPI-1.0.21.zip”

Langkah 12: Untuk Antaramuka Servo

Dari shell arahan

sudo apt-get install git build-essential python-dev

cd ~

klon git

cd Adafruit_Python_PCA9685

sudo python setup.py pasang

Mengapa kita perlu menggunakan servo driver? Nah, untuk RPi beberapa sebab.

1. Arus yang diambil oleh servo boleh menjadi sangat tinggi, dan jumlahnya semakin besar semakin banyak servo yang anda miliki (tentu saja). Sekiranya anda menggunakan servo directky dari RPi, anda menghadapi risiko meletupkan bekalan kuasa

2. Jangka masa PWM (Pulse Width Modulation) yang mengawal kedudukan servos sangat penting. Oleh kerana RPi tidak menggunakan OS masa nyata (mungkin ada gangguan dan semacamnya) waktunya tidak tepat dan boleh membuat servo berkedut gugup. Pemacu khusus membolehkan kawalan yang tepat, tetapi juga membolehkan sehingga 16 servo ditambahkan, jadi ini bagus untuk pengembangan.

Langkah 13: Untuk LCD

Blynk
Blynk

buka penyemak imbas web RPi anda

www.sunfounder.com/learn/category/sensor-k…

muat turun

github.com/daveyclk/SunFounder_SensorKit_…

Dari shell arahan:

sudo mkdir / usr / share / sunfounder

Dengan menggunakan penjelajah grafik, salin folder python dari fail zip ke dalam folder sunfounder baru anda

LCD digunakan untuk meminta pengguna mengenai apa sebenarnya yang sedang berlaku. Menunjukkan proses konfigurasi hingga ke nilai x, y dan z yang dipetakan ke setiap servo

Langkah 14: Blynk

Blynk
Blynk
Blynk
Blynk

Blynk adalah perkhidmatan IoT yang cemerlang yang membolehkan anda membuat aplikasi tersuai untuk mengawal barang anda. Nampaknya penyelesaian terbaik untuk memberi saya kawalan jauh dari walabot untuk benar-benar mendail dalam tetapan …

Satu masalah. Blynk pada masa ini tidak disokong pada platform Python, bugger. Tetapi jangan takut! saya dapat mencari kerja kecil yang membolehkan kawalan jauh dan input parameter jauh! ia adalah sedikit hacky

langkah pertama adalah memuat turun aplikasi Blynk dari kedai aplikasi kegemaran anda

Kedua, daftar untuk akaun

Setelah selesai, buka aplikasi dan mulakan projek baru, memilih Raspberry Pi 3 sebagai perkakasan.

Aplikasi ini akan memberi anda token akses (anda memerlukannya untuk memasukkan kod anda)

Sebaik sahaja anda melakukannya. anda perlu menyediakan aplikasi seperti yang ditunjukkan dalam gambar. Ini adalah bagaimana ia akan bersambung dengan walabot.

Langkah 15: Mengkonfigurasi Aplikasi Blynk

Mengkonfigurasi Aplikasi Blynk
Mengkonfigurasi Aplikasi Blynk
Mengkonfigurasi Aplikasi Blynk
Mengkonfigurasi Aplikasi Blynk
Mengkonfigurasi Aplikasi Blynk
Mengkonfigurasi Aplikasi Blynk

Langkah 16: Anda Boleh Menggunakan Kod QR Ini Dengan Aplikasi Blynk untuk Klon Projek Saya untuk Menjimatkan Masa Anda

Anda Boleh Menggunakan Kod QR Ini Dengan Aplikasi Blynk untuk Klon Projek Saya untuk Menjimatkan Masa Anda
Anda Boleh Menggunakan Kod QR Ini Dengan Aplikasi Blynk untuk Klon Projek Saya untuk Menjimatkan Masa Anda

OK Sekarang aplikasinya sudah siap, kita dapat mengkonfigurasi Python dan RPi untuk bercakap dengannya melalui internet. Sihir

Langkah 17: Menjalankan Blynk Dengan Raspberry Pi dan Menggunakan HTTP Blynk untuk Python

Pertama, anda perlu memasang pembungkus HTTPS Blynk untuk Python

Dari shell arahan:

sudo git clone

sudo pip pasang blynkapi

Kedua, anda perlu memasang Perkhidmatan Blynk pada RPi

Dari shell arahan:

git klon

cd blynk-perpustakaan / linux

buat bersih semua

untuk menjalankan perkhidmatan blynk

sudo./blynk --token = YourAuthToken

Untuk memastikan Perkhidmatan Blynk beroperasi semasa anda perlu mengubah suai /etc/rc.local

dengan melakukan

sudo nano /etc/rc.local

tambahkan ini pada akhir

./blynk-library/linux/blynk --token = token saya &

(saya telah memasukkan fail fail /etc/rc.local saya di bahagian kod untuk rujukan)

Untuk menguji ia berfungsi dengan menaip

sudo /etc/rc.local start

Perkhidmatan Blynk kini seharusnya berjalan

Langkah 18: Menjalankan Skrip secara automatik

Sekarang ini semua sudah disiapkan dan dikonfigurasi, dan kita sudah menyediakan kod python. kita boleh mengatur agar berjalan secara automatik sehingga kita boleh membuang papan kekunci dan monitor

Terdapat beberapa perkara yang perlu dilakukan

Buat fail skrip baru untuk menjalankan Program Python

sudo nano guitareffect.sh

tambah baris ini

#! / bin / sh

python /home/pi/GuitarEffectCLI.py

pastikan menyimpannya

Seterusnya kita perlu memberi kebenaran skrip untuk dijalankan dengan menaip

Sudo chmod + x /home/pi/guitareffect.sh

Dan akhirnya, kita perlu menambahkan skrip ini ke fail /etc/rc.local yang kita mainkan sebelumnya.

Sudo nano /etc/rc.local

Tambah

/home/pi/guitareffect.sh &

pastikan untuk memasukkan "&" ini membolehkan Skrip Python berjalan di latar belakang

Betul! Itu semua konfigurasi dan perisian yang disusun, seterusnya tiba masanya untuk memasang perkakasan

Langkah 19: Perkakasan

Image
Image
Walabot guitar effects control proto1
Walabot guitar effects control proto1

Prototaip Breadboard Pertama

Langkah 20: Reka Bentuk Kandang

Reka Bentuk Kandang
Reka Bentuk Kandang
Reka Bentuk Kandang
Reka Bentuk Kandang

Kandang ini dirancang dan dibuat dalam Fusion360 yang mengagumkan

Langkah 21: Tembakan Guts

Tembakan Guts
Tembakan Guts
Tembakan Guts
Tembakan Guts
Tembakan Guts
Tembakan Guts

Langkah 22: Tembakan Perhimpunan Akhir

Tembakan Perhimpunan Akhir
Tembakan Perhimpunan Akhir
Tembakan Perhimpunan Akhir
Tembakan Perhimpunan Akhir
Tembakan Perhimpunan Akhir
Tembakan Perhimpunan Akhir

Langkah 23: Untuk Memperbaiki Walabot ke Dudukan

Untuk Memperbaiki Walabot ke Dudukan
Untuk Memperbaiki Walabot ke Dudukan

Gunakan cakera logam pelekat sendiri yang disertakan dengan walabot untuk memperbaikinya di tempat

Langkah 24: Fail STL Perkakasan untuk Percetakan 3D

Langkah 25: Skema untuk Memasang Masalah

Langkah 26: Kod

Gunakan skrip Python yang dilampirkan untuk projek anda

dari _future_ import print_functiondari platform import sys dari sistem import os dari blynkapi import Blynk import WalabotAPI import masa import RPi. GPIO sebagai GPIO

#menetapkan GPIO menggunakan Penomboran Papan

GPIO.setmode (GPIO. BOARD) GPIO.setup (18, GPIO. IN, pull_up_down = GPIO. PUD_UP)

#blynk token autentikasi

auth_token = "your_auth_token_di sini"

# Import modul PCA9685 untuk kawalan servo.

import Adafruit_PCA9685

#import modul LCD dari lokasi

dari imp import load_source LCD1602 = load_source ('LCD1602', '/usr/share/sunfounder/Python/LCD1602.py')

# Mulakan PCA9685 menggunakan alamat lalai (0x40).

pwm = Adafruit_PCA9685. PCA9685 ()

# objek blynk

lalai = Blynk (auth_token, pin = "V9") start_button = Blynk (auth_token, pin = "V3") Rmax = Blynk (auth_token, pin = "V0") Rmin = Blynk (auth_token, pin = "V1") Rres = Blynk (auth_token, pin = "V2")

ThetaMax = Blynk (auth_token, pin = "V4")

ThetaRes = Blynk (auth_token, pin = "V5")

PhiMax = Blynk (auth_token, pin = "V6")

PhiRes = Blynk (auth_token, pin = "V7")

Ambang = Blynk (auth_token, pin = "V8")

ServoMin = Blynk (auth_token, pin = "V10")

ServoMax = Blynk (auth_token, pin = "V11")

def LCDsetup ():

LCD1602.init (0x27, 1) # init (alamat hamba, lampu latar)

def numMap (x, in_min, in_max, out_min, out_max): "" "digunakan untuk memetakan bacaan walabot ke posisi servo" "" return int ((x- in_min) * (out_max - out_min) / (in_max - in_min) + keluar_min)

# gunakan ini untuk membundarkan data mentah ke nilai yang ditetapkan

def myRound (x, base = 2): return int (base * bulat (float (x) / base))

# mengekstrak nombor dari rentetan blynk yang dikembalikan

nombor defEkstrak (val): val = str (val) return int (filter (str.isdigit, val))

# Tetapkan frekuensi hingga 60hz, bagus untuk servos.

pwm.set_pwm_freq (60)

# Konfigurasi lalai panjang denyut servo minimum dan maksimum

SERVO_MIN = 175 # Panjang nadi minimum daripada 4096 SERVO_MAX = 575 # Panjang nadi maksimum daripada 4096

# nilai lalai walabot

R_MAX = 60 R_MIN = 20 R_RES = 5

THETA_MAX = 20

THETA_RES = 5

PHI_MAX = 20

PHI_RES = 5

THRESHOLD = 1

# pemboleh ubah untuk pertukaran blynk

pada = "[u'1 ']"

kelas Walabot:

def _init _ (diri):

self.wlbt = WalabotAPI self.wlbt. Init () self.wlbt. SetSettingsFolder () self.isConnected = Salah diri.isTargets = Salah

def blynkConfig (diri):

load_defaults = defaults.get_val () if str (load_defaults) == on: SERVO_MAX = ServoMax.get_val () SERVO_MAX = numberExtract (SERVO_MAX) cetak ("Servo Max =", SERVO_MAX)

SERVO_MIN = ServoMin.get_val ()

SERVO_MIN = numberExtract (SERVO_MIN) cetak ("Servo MIN =", SERVO_MIN) R_MAX = Rmax.get_val () R_MAX = numberExtract (R_MAX) cetak ("R max =", R_MAX)

R_MIN = Rmin.get_val ()

Cetakan R_MIN = numberExtract (R_MIN) ("R Min =", R_MIN)

R_RES = Rres.get_val ()

Cetakan R_RES = numberExtract (R_RES) ("R Res =", R_RES)

THETA_MAX = ThetaMax.get_val ()

THETA_MAX = numberExtract (THETA_MAX) cetak ("Theta Max =", THETA_MAX) THETA_RES = ThetaRes.get_val () THETA_RES = numberExtract (THETA_RES) cetakan ("Theta Res =", THETA_RES)

PHI_MAX = PhiMax.get_val ()

PHI_MAX = numberExtract (PHI_MAX) cetak ("Phi Max =", PHI_MAX) PHI_RES = PhiRes.get_val () PHI_RES = numberExtract (PHI_RES) cetak ("Phi Res =", PHI_RES)

THRESHOLD = Ambang.get_val ()

Cetakan THRESHOLD = numberExtract (THRESHOLD) ("Ambang =", THRESHOLD)

lain: # jika tiada dari aplikasi blynk, muatkan lalai SERVO_MIN = 175 # Panjang nadi minimum daripada 4096 SERVO_MAX = 575 # Panjang nadi maksimum daripada 4096

# nilai lalai walabot

R_MAX = 60 R_MIN = 20 R_RES = 5

THETA_MAX = 20

THETA_RES = 5

PHI_MAX = 20

PHI_RES = 5

THRESHOLD = 1

def connect (self): cuba: self.wlbt. ConnectAny () self.isConnected = True self.wlbt. SetProfile (self.wlbt. PROF_SENSOR) # self.wlbt. SetDynamicImageFilter (self.wlbt. FILTER_TYPE_MTI) self.wlbt. (self.wlbt. FILTER_TYPE_NONE) # self.wlbt. SetDynamicImageFilter (self.wlbt. FILTER_TYPE_DERIVATIVE) diri.wlbt. SetArenaTheta (-THETA_MAX, THETA_MAX, THETA_RES) self.wlb. SetArenaR (R_MIN, R_MAX, R_RES) self.wlbt. SetThreshold (THRESHOLD) kecuali self.wlbt. WalabotError as err: if err.code! = 19: # 'WALABOT_INSTRUMENT_NOT_FOUND' naikkan kesalahan

permulaan def (diri):

diri.wlbt. Mulakan ()

def calibrate (diri):

self.wlbt. StartCalibration ()

def get_targets (diri):

self.wlbt. Trigger () kembali self.wlbt. GetSensorTargets ()

henti def (diri):

diri.wlbt. Berhenti ()

def memutuskan sambungan (diri):

self.wlbt. Disconnect ()

def utama ():

flag = True check = "" LCDsetup () manakala flag: LCD1602.write (0, 0, 'Guitar') LCD1602.write (0, 1, 'Effect Control') time.sleep (2) LCD1602.write (0, 0, 'Tekan Start to') LCD1602.write (0, 1, 'start') time.sleep (2) if (str (check) == on): flag = False else: check = start_button.get_val () # periksa butang mula blynk tekan jika (GPIO.input (18) == 0): #check footswitch flag = Palsu

LCD1602.write (0, 0, "OK! Mari kita lakukan")

LCD1602.write (0, 1, '') wlbt = Walabot () wlbt.blynkConfig () wlbt.connect () LCD1602.clear () if not wlbt.isConnected: LCD1602.write (0, 0, 'Not Connected') lain: LCD1602.write (0, 0, 'Connected') time.sleep (2) wlbt.start () wlbt.calibrate () LCD1602.write (0, 0, 'Calibrating…..') time.sleep (3) LCD1602.write (0, 0, 'Memulakan Walabot')

appcheck = start_button.app_status () flag = Benar # ulang bendera untuk prog utama

sambil bendera: # digunakan untuk memberi kesan dalam keadaan bersedia (berkesan)

if (appcheck == True): if (str (check)! = on): if (GPIO.input (18)! = 0): #check footswitch flag = Salah lain: check = start_button.get_val () #check for butang mula tekan appcheck = start_button.app_status ()

lain:

if (GPIO.input (18)! = 0): #semak bendera alas kaki = Salah

xval = 0

yval = 0 zval = 0 purata = 2 penundaan Masa = 0

target = wlbt.get_targets ()

jika len (sasaran)> 0:

untuk j dalam julat (purata):

target = wlbt.get_targets ()

jika len (target)> 0: print (len (target)) target = target [0]

cetak (str (targets.xPosCm))

xval + = int (targets.xPosCm) yval + = int (targets.yPosCm) zval + = int (targets.zPosCm) time.sleep (delayTime) other: print ("no target") xval = xval / rata-rata

xval = numMap (xval, -60, 60, SERVO_MIN, SERVO_MAX)

xval = myRound (xval) jika xval SERVO_MAX: xval = SERVO_MAX LCD1602.write (0, 0, 'x =' + str (xval) + '') pwm.set_pwm (0, 0, xval)

yval = yval / purata

yval = numMap (yval, -60, 60, SERVO_MIN, SERVO_MAX)

yval = myRound (yval) jika yval SERVO_MAX: yval = SERVO_MAX LCD1602.write (0, 1, 'y =' + str (yval)) pwm.set_pwm (1, 0, yval)

zval = zval / purata

zval = numMap (zval, R_MIN, R_MAX, SERVO_MIN, SERVO_MAX)

zval = myRound (zval) jika zval SERVO_MAX: zval = SERVO_MAX LCD1602.write (8, 1, 'z =' + str (zval)) pwm.set_pwm (2, 0, zval)

lain:

cetak ("tiada sasaran") LCD1602.write (0, 0, "Shutting Down") LCD1602.write (0, 1, 'The Walabot') time.sleep (3) wlbt.stop () wlbt.disconnect ()

jika _nama_ == '_main_':

sambil Betul: utama ()

untuk guitareffect.sh

#! / bin / sh

cd / rumah / pi

sudo python GuitarEffectCLI.py

Salinan fail tempatan RC untuk rujukan

#! / bin / sh -e # # rc.local # # Skrip ini dilaksanakan pada akhir setiap runlevel multiuser. # Pastikan bahawa skrip akan "keluar 0" pada kejayaan atau nilai # lain pada kesilapan. # # Untuk mengaktifkan atau mematikan skrip ini, ubah saja eksekusi # bit. # # Secara lalai skrip ini tidak melakukan apa-apa.

# Cetak alamat IP

_IP = $ (nama host -I) || benar jika ["$ _IP"]; kemudian printf "Alamat IP saya adalah% s / n" "$ _IP" fi

./blynk-library/linux/blynk --token = "token anda ada di sini" &

tidur 10 sudo /home/pi/guitareffect.sh & keluar 0

Langkah 27: Github Repositori untuk Digunakan

Gunakan ini untuk LCD Sunfounder

github.com/daveyclk/SunFounder_SensorKit_f…

Gunakan ini untuk pemacu servo

github.com/daveyclk/Adafruit_Python_PCA968…

Gunakan ini untuk Pembungkus HTTPS Blynk Python

github.com/daveyclk/blynkapi

Langkah 28: Kesimpulannya

Image
Image
Walabot FX- Guitar Effect Control. Full Demo
Walabot FX- Guitar Effect Control. Full Demo
Kesimpulannya
Kesimpulannya
Kesimpulannya
Kesimpulannya

Ini adalah kurva pembelajaran yang curam, tetapi sangat berharga.

Keseronokan saya adalah

  • Saya terpaksa belajar Python..ternyata itu ace
  • Mengaitkan Python pada Raspberry Pi dengan perkhidmatan Blynk IoT. Ini tidak disokong secara rasmi sehingga ada batasan fungsinya. Masih berfungsi hebat!
  • Ternyata Walabot sangat bagus untuk ekspresi muzik. Saya menggunakannya pada Korg SDD3000, tetapi anda boleh menggunakan kesan yang anda suka

Selamat mencuba sendiri. Ini tidak terhad pada kesan gitar, saya boleh digunakan dengan instrumen apa pun dengan kesan apa pun.

Peraduan Raspberry Pi 2017
Peraduan Raspberry Pi 2017
Peraduan Raspberry Pi 2017
Peraduan Raspberry Pi 2017

Naib Johan dalam Peraduan Raspberry Pi 2017

Disyorkan: