Sebut satu perkataan, dan satu relay bertukar. ZK-VR01 melaporkan setiap pengecaman dua kali sekali gus β sebagai bait pada pad serial T, dan sebagai perubahan aras pada salah satu daripada lapan pad arahan di tepi kirinya β jadi Uno hanya perlu memerhati satu lorong, mengunci apa yang dilihatnya, dan memacu satu modul relay. Pad mana yang membawa arahan mana ialah sifat board anda sendiri, jadi sketch di bawah membacanya dahulu.
Apa sebenarnya yang ada pada board ZK-VR01?
ZK-VR01 meletakkan segala yang anda perlu sambung pada dua tepi satu board biru pekat. Tepi atas membawa empat lubang bertanda silkscreen GND, T, R dan 5V β kuasa berserta sepasang pin serial aras TTL: T ialah transmit modul itu, R pula receive-nya. Tepi kiri membawa lapan pad arahan, bertanda A25, A26, A27, B2, B3, B1, B0 dan B7, masing-masing dengan perintang sirinya sendiri.
Kedua-dua baris itu sampai sebagai lubang tembus bersalut yang masih bogel, jadi tiada apa yang boleh dipasang sehingga satu jalur header 2.54 mm disolder padanya. Selain itu semuanya sudah terpasang: mikrofon electret bermuka hitam dalam bingkai peraknya, suis gelangsar OFF/ON perak di tepi kanan, dan satu soket SPK putih untuk speaker yang ada dalam beg β jadi board ini ada output audio dan juga mikrofon.
Senarai komponen β modul suara, modul relay, serta header dan jumper yang menyambungkan kedua-duanya
Parts list
| Item | Price | Qty | |
|---|---|---|---|
Soldering Service for Circuit Boards & Electronics - 10 Pins Soldering ServiceSOLSE10 | RM1.40 |
ZK-VR01 sampai dengan pad yang masih bogel: empat di bahagian atas ditambah satu bagi setiap arahan yang anda guna, jadi lebih kurang tujuh. Tambah servis solder 10 pin dan kami pasangkan jalur header itu untuk anda.
Kenapa projek ini guna modul relay dan bukan relay kosong?
Relaynya sama sahaja dalam kedua-dua keadaan. Kiub biru langit pada modul relay 1 hala bertanda silkscreen SRD-05VDC-SL-C β relay Songle yang sama seperti yang kami jual kosong sebagai SRD5VRL. Board merah itu menambah apa yang sepatutnya berada antara relay tersebut dan pin mikropengawal.
Mulakan dengan gegelungnya. Datasheet Songle SRD memberikan gegelung 5 V itu 70 Ξ© dan kira-kira 0.36 W, jadi menghidupkannya menarik 5 V / 70 Ξ© β 71 mA. Datasheet ATmega328P pula hanya menyatakan voltan output pin I/O sehingga 20 mA dan meletakkan 40 mA sebagai maksimum mutlak. 71 mA bukan pin yang berkelakuan pelik; ia pin yang dipaksa melebihi taraf kerjanya. Pada projek yang siap, arus itu keluar daripada rel 5 V Uno melalui transistor pada modul β satu rel mampu membekalkannya, satu pin tidak. Bekerjalah dengan USB: bicu barrel sampai ke rel yang sama melalui satu pengatur linear yang menukarkan (Vin β 5 V) Γ arus menjadi haba.
Mematikannya pula masalah kedua. Satu induktor menentang sebarang perubahan pada arus yang melaluinya, jadi memutuskan bekalan gegelung membuatkan medan yang runtuh itu memacu voltan setinggi mana pun yang perlu untuk mengekalkan arus tadi β ke arah belakang, masuk semula ke dalam apa sahaja yang melakukan pensuisan itu. Satu diod merentasi gegelung menawarkan gelung yang tidak berbahaya sebagai ganti. Relay kosong tiada diod itu; modulnya ada, berserta satu transistor pemacu dan satu optocoupler jenis PC817 antara pin anda dan pemacu tersebut. Fahamkannya sebagai penampan, bukan pengasingan galvanik: board ini hanya ada sepasang terminal kuasa, jadi apabila ia disuap daripada Uno, kedua-dua belah berkongsi ground Uno dan gegelungnya mengambil bekalan Uno. Apa yang optocoupler itu berikan ialah pin anda hanya memacu LED di dalamnya, beberapa miliampere sahaja, bukan gegelung. Pengasingan sebenar pada board ini ialah celah udara antara kontak relay dan gegelungnya sendiri.
Beli SRD5VRL apabila anda sendiri yang membina litar pemacu itu di atas perfboard, atau sedang menggantikan relay yang sudah rosak. Lima pinnya duduk pada footprint Songle, bukan grid 0.1 inci, jadi ia juga tidak muat pada breadboard.
Bagaimana cara mendawai ZK-VR01, Uno dan relay?
Dua fakta yang menentukan jumper mana anda perlukan, dan kedua-duanya bukan nombor pin. Header pada Uno ialah female, jadi setiap wayar yang berakhir di situ perlukan pin male. Bahagian kawalan modul relay pula ialah terminal skru tiga hala bertanda IN, DCβ dan DC+, jadi wayar-wayar itu perlukan pin male telanjang di hujung itu juga, diapit di bawah skru β jadi larian male-to-male. ZK-VR01 pula menerima pin yang dipatahkan daripada jalur 40 pin dan disolder ke dalam padnya yang bogel (lihat panduan solder header kami), jadi lariannya ialah male-to-female.
Hanya T yang pergi ke Uno. R sengaja dibiarkan tidak bersambung β projek ini hanya mendengar, dan itu menjauhkan anda daripada satu-satunya arah yang perlu difikirkan. Output modul masuk ke input Uno ialah arah yang selamat, apa pun yang dipacu oleh modul itu: Uno membaca HIGH melebihi 0.6 Γ Vcc = 3.0 V, dan output kelas 3.3 V melepasi paras itu manakala output 5 V melepasinya dengan lebih banyak lagi. Arah sebaliknya tidak simetri β transmit 5 V Uno masuk ke pin R modul itulah arah yang mahukan pembahagi voltan, dan projek ini langsung tidak menggunakannya.
| Dari | Ke | Jumper |
|---|---|---|
| ZK-VR01 5V | Uno 5V | MβF |
| ZK-VR01 GND | Uno GND | MβF |
| ZK-VR01 T | Uno D10 | MβF |
| ZK-VR01 R | tidak disambung | β |
| Pad A25 ZK-VR01 (atas sekali dalam lajur) | Uno D2 | MβF |
| Pad A26 ZK-VR01 | Uno D3 | MβF |
| Pad A27 ZK-VR01 | Uno D4 | MβF |
| Uno 5V | Relay DC+ | MβM, di bawah skru |
| Uno GND | Relay DCβ | MβM, di bawah skru |
| Uno D7 | Relay IN | MβM, di bawah skru |

Bagaimana cara membaca modul ini sebelum anda menulis sebarang kod?
ZK-VR01 sendiri yang menjawabnya. Sketch di bawah tidak mengawal apa-apa: ia mengitar satu port software serial pada D10 melalui lima kadar baud yang biasa, sambil merekod cap masa bagi bait yang tiba di T dan bagi setiap tepi pada D2, D3 dan D4. Sebut satu arahan bagi setiap tetingkap, tiga kali. Lebih lima puluh arahan berkongsi lapan pad, jadi tiga wayar hanya mencuba tiga daripadanya: kalau bait muncul pada T sedangkan tiada satu pun pad bergerak, perkataan yang anda sebut itu tinggal pada pad yang belum anda sambung β jadi alihkan wayar ke bawah lajur itu dan cuba sekali lagi.
Dua jawapan akan terhasil. Kadar baud yang betul ialah kadar yang membuatkan perkataan yang sama memberi bait yang sama tiga kali; kadar yang salah memberi bunyi karut atau senyap terus. Dan cap masa itu memberitahu sama ada satu pengecaman mendenyut pad selama beberapa puluh milisaat atau mengunci pad sehingga arahan berikutnya β dan itulah yang menentukan kod yang anda tulis selepas ini.
Baca pad itu dengan INPUT biasa dahulu, bukan INPUT_PULLUP: pin input tidak memacu apa-apa langsung, dan itulah satu-satunya cara selamat untuk bertemu pin yang arahnya belum anda pastikan. Pad yang mengalirkan tepi rawak bukanlah pad rosak β cumanya tiada apa yang memacunya; tambah pull-up dan ia akan senyap pada HIGH yang stabil, manakala pad yang benar-benar dipacu akan mengekalkan peralihannya. Pull-up dalaman ATmega328P ialah 20β50 kΞ©, jadi walaupun pad itu dipacu ke arah bertentangan, arusnya paling banyak 5 V / 20 kΞ© = 0.25 mA.
// SKETCH PENEROKAAN ZK-VR01 - ia tidak mengawal apa-apa, ia hanya memerhati.
// Pendawaian: modul 5V -> Uno 5V, modul GND -> Uno GND, modul T -> Uno D10.
// Pin R modul sengaja TIDAK disambung.
// Tiga pad arahan -> Uno D2, D3, D4.
// Buka Serial Monitor pada 115200, sebut satu arahan bagi setiap tetingkap
// mendengar, dan catat apa yang board anda sendiri buat. Jadual itulah output
// yang sebenar.
#include <SoftwareSerial.h>
const uint8_t PIN_VR_T = 10; // pad T modul (pad transmitnya) -> Uno D10
const uint8_t PIN_VR_R = 11; // SoftwareSerial perlukan satu pin TX; biarkan yang ini tanpa wayar
const uint8_t PADS[] = { 2, 3, 4 };
const uint8_t N_PADS = sizeof(PADS) / sizeof(PADS[0]);
SoftwareSerial vr(PIN_VR_T, PIN_VR_R);
// Kadar baud modul ini bukan benda untuk diagak - sapu semuanya dan lihat.
const long RATES[] = { 9600, 19200, 38400, 57600, 115200 };
const uint8_t N_RATES = sizeof(RATES) / sizeof(RATES[0]);
const unsigned long WINDOW_MS = 8000; // cukup panjang untuk mengulang satu arahan tiga kali
uint8_t lastPad[N_PADS];
uint8_t rateIndex = 0;
unsigned long windowStart = 0;
void openWindow() {
vr.end();
vr.begin(RATES[rateIndex]);
vr.listen();
windowStart = millis();
Serial.println();
Serial.print(F("--- listening at "));
Serial.print(RATES[rateIndex]);
Serial.println(F(" baud - say one command now ---"));
rateIndex = (rateIndex + 1) % N_RATES;
}
void setup() {
// INPUT biasa, bukan INPUT_PULLUP: input impedans tinggi tidak memacu apa-apa
// ke dalam pin yang arahnya belum kita ketahui. Tambah pull-up (di bawah)
// hanya selepas pad itu membuktikan yang ia memang satu output.
for (uint8_t i = 0; i < N_PADS; i++) {
pinMode(PADS[i], INPUT);
lastPad[i] = digitalRead(PADS[i]);
}
Serial.begin(115200);
Serial.println(F("ZK-VR01 discovery. Bytes and pad edges are timestamped in ms."));
openWindow();
}
void loop() {
if (millis() - windowStart >= WINDOW_MS) {
openWindow();
}
// Apa sahaja yang tiba di T, dicetak mentah. Ulang perkataan yang sama tiga
// kali: kadar baud yang betul memberi anda bait yang SAMA tiga kali.
while (vr.available()) {
uint8_t b = (uint8_t)vr.read();
Serial.print(F("byte 0x"));
if (b < 0x10) Serial.print('0');
Serial.print(b, HEX);
Serial.print(F(" '"));
Serial.print((char)((b >= 32 && b < 127) ? b : '.'));
Serial.print(F("' @"));
Serial.println(millis());
}
// Setiap tepi pad, dengan cap masa. Dua tepi yang rapat bermakna pad itu
// MENDENYUT; satu tepi yang tidak pernah kembali bermakna ia MENGUNCI. Anda
// perlu tahu yang mana satu sebelum boleh menulis kod relay.
for (uint8_t i = 0; i < N_PADS; i++) {
uint8_t now = digitalRead(PADS[i]);
if (now != lastPad[i]) {
lastPad[i] = now;
Serial.print(F("pad D"));
Serial.print(PADS[i]);
Serial.print(now ? F(" -> HIGH") : F(" -> LOW"));
Serial.print(F(" @"));
Serial.println(millis());
}
}
}
Sketch itu dikompil menjadi 4,418 bait flash dan 335 bait pemboleh ubah global. Sampah pada setiap kadar bukan bermakna modul rosak (senyap pada setiap kadar ialah kerosakan yang lain sama sekali) β itu SoftwareSerial pada siling kemampuannya: kod sumbernya sendiri mengkalibrasi pemasaan penerimaan supaya berfungsi sehingga 115200 baud pada AVR 16 MHz. Panduan Bluetooth HC-05 kami menjalankan pustaka yang sama pada 9600, jauh di dalam julat itu. Pustaka ini melakukan bit-bang: satu interrupt pin-change menangkap start bit, kemudian satu busy-wait terkalibrasi melangkah melalui lapan bit data. Pada 16 MHz dan 115200 baud, satu bit bertahan 16,000,000 / 115,200 β 139 kitaran jam, dan interrupt itu berjalan dengan interrupt lain dimatikan, jadi tiada apa yang memintasnya di tengah bait. Yang menyakitkan ialah saat sebelum itu: satu interrupt yang sudah pun berjalan ketika start bit mendarat β Timer0 yang mengekalkan millis(), UART perkakasan yang mengosongkan buffernya β melewatkan kemasukan ke dalam handler, dan setiap sampel selepasnya lewat sebanyak pecahan sebenar satu bit. Pada 9600, bit yang sama bertahan 1,667 kitaran dan kelewatan yang serupa langsung tidak bermakna apa-apa. Sebab itulah pad arahan diberi tempat yang sama pentingnya: satu pad tiada kadar baud yang boleh anda tetapkan salah.

Kenapa relay berbunyi klik lalu terus mati semula?
Sebabnya satu pengecaman ialah peristiwa manakala satu relay ialah keadaan, dan tiada apa yang menukarkan satu kepada satu lagi dengan sendirinya. Pad itu berkelip: aktif selama beberapa puluh milisaat, kemudian kembali. Tulis digitalWrite(relay, digitalRead(pad)) dan relay itu hanya menyalin kelipan tadi. Sebuah lampu pula mesti terus menyala selepas bunyi suara berhenti.
Jadi tepi pad itulah yang menetapkan satu pemboleh ubah, dan pemboleh ubah itu pula yang memacu pin. Di bawah, dua pad menetapkan dan mengosongkan satu boolean, dan pin itu ditulis hanya apabila boolean tersebut berubah.
// Relay berkunci suara: pad arahan ZK-VR01 -> Arduino Uno -> modul relay 1 hala.
// Pendawaian: modul 5V/GND -> Uno 5V/GND, dua pad arahan -> Uno D2 dan D3.
// Uno 5V -> relay DC+, Uno GND -> relay DC-, Uno D7 -> relay IN.
// Isikan empat pemalar di bawah daripada larian penerokaan anda sendiri.
const uint8_t PIN_PAD_ON = 2; // pad yang bertindak balas pada arahan "on" anda
const uint8_t PIN_PAD_OFF = 3; // pad yang bertindak balas pada arahan "off" anda
const uint8_t PIN_RELAY = 7; // Uno D7 -> pin IN modul relay
const uint8_t PAD_ACTIVE = LOW; // aras yang dituju pad itu apabila berlaku pengecaman
const uint8_t RELAY_ON = LOW; // shunt pada L seperti yang dihantar = trigger aras rendah
const uint8_t RELAY_OFF = HIGH;
const unsigned long DEBOUNCE_MS = 30;
struct Pad {
uint8_t pin;
uint8_t last;
unsigned long changedAt;
};
Pad padOn = { PIN_PAD_ON, HIGH, 0 };
Pad padOff = { PIN_PAD_OFF, HIGH, 0 };
bool lampOn = false;
// Satu pengecaman ialah PERISTIWA: pad itu bergerak, seketika. Fungsi ini
// memulangkan true sekali bagi setiap peralihan stabil MASUK ke aras aktif, dan
// tidak pernah semasa pad itu sekadar duduk di situ - itulah yang menukarkan
// satu kelipan menjadi sesuatu yang boleh anda tindaki.
bool firedOnce(Pad &p) {
uint8_t now = digitalRead(p.pin);
if (now == p.last) return false;
if (millis() - p.changedAt < DEBOUNCE_MS) return false; // masih dalam tempoh sekatan
p.last = now;
p.changedAt = millis();
return (now == PAD_ACTIVE);
}
void setup() {
// Urutan ini penting. Selagi pin itu masih input, digitalWrite() menetapkan
// pull-up dalamannya dan bukan aras pemacuan, jadi talian itu sudah pun
// dipegang tinggi sebelum pinMode() menjadikannya output. Buat secara
// terbalik dan pin itu menjadi output pada nilai resetnya iaitu LOW - dan
// pada board trigger aras rendah, itu bermakna relay menyentak masuk setiap
// kali anda upload.
digitalWrite(PIN_RELAY, RELAY_OFF);
pinMode(PIN_RELAY, OUTPUT);
pinMode(PIN_PAD_ON, INPUT);
pinMode(PIN_PAD_OFF, INPUT);
padOn.last = digitalRead(PIN_PAD_ON);
padOff.last = digitalRead(PIN_PAD_OFF);
Serial.begin(115200);
Serial.println(F("ready - relay OFF"));
}
void loop() {
bool sawOn = firedOnce(padOn);
bool sawOff = firedOnce(padOff);
// Satu relay ialah KEADAAN. Peristiwa tadi menetapkan dan mengosongkan satu
// boolean; pin itu ditulis hanya apabila boolean tersebut benar-benar
// berubah, jadi arahan yang berulang tidak mendatangkan apa-apa kesan.
bool wanted = lampOn;
if (sawOn) wanted = true;
if (sawOff) wanted = false;
// Mahu satu arahan yang menogol dan bukan dua yang menetapkan serta
// mengosongkan? Ganti dua baris di atas dengan if (sawOn) wanted = !wanted;
// dan tambah tempoh tahan sesaat dua, sebab satu ayat boleh mencetuskan pad
// itu lebih daripada sekali dan setiap cetusan tambahan akan membalikkan
// keadaannya semula.
if (wanted != lampOn) {
lampOn = wanted;
digitalWrite(PIN_RELAY, lampOn ? RELAY_ON : RELAY_OFF);
Serial.println(lampOn ? F("relay ON") : F("relay OFF"));
}
}
Sketch yang itu pula dikompil menjadi 2,270 bait flash dan 201 bait pemboleh ubah global. Kalau larian penerokaan anda menghasilkan satu bait yang bersih dan boleh diulang bagi setiap arahan, kekalkan semua yang di bawah firedOnce() dan tukarkan bacaan pad itu kepada perbandingan bait.
Penunjuk PWR dan LED1 pada modul relay berserta bunyi kliknya sudah pun membuktikan rantaian suara β Uno β relay berfungsi β sebab itulah tiada beban dalam senarai komponen. Apa yang boleh disambung pada NO, COM dan NC, dan kenapa kuasa utama 240 V bukan kerja hobi, ialah tajuk panduan keselamatan modul relay kami. Kekalkan projek ini pada DC voltan rendah β dan ambil perhatian bahawa lampu isyarat 12 V, kipas atau adaptor 2 A masing-masing datang dengan crimp dan soketnya sendiri.

Kesilapan biasa yang kami nampak daripada pelanggan sebenar
Modul disambung pada D0 dan D1. Dua pin itu ialah UART perkakasan Uno, dikongsi dengan bootloader USB dan Serial Monitor, jadi upload gagal atau output debug bertukar menjadi karut. Guna mana-mana pasangan pin lain.
Jumper hanya tercacak dalam pad yang belum disolder. Lubang itu masih bogel, dan pin dupont yang ditolak ke dalamnya bersambung putus-sambung, itu pun kalau bernasib baik. Solder dahulu: sambungan yang bukan sambungan sebenar meniru setiap kerosakan di halaman ini.
Relay menyentak masuk sebaik sahaja Uno reset. Itu pinMode(OUTPUT) yang berjalan sebelum digitalWrite() yang pertama. Terbalikkan dua baris itu.
Relay kosong disambung terus kepada satu pin. Ia berbunyi klik lemah atau langsung tidak berbunyi, dan selalunya membawa pin itu sekali: 71 mA melalui pin 20 mA tanpa diod flyback ialah dua kesilapan serentak.
Tiada apa yang tiba di T pada mana-mana kadar baud. Periksa suis gelangsar OFF/ON pada board itu sendiri dahulu, kemudian beralih kepada pad arahan, yang tidak boleh dikalahkan oleh mana-mana kadar baud.
Soalan Lazim
Perlukah saya solder ZK-VR01?
Ya. Kedua-dua baris itu sampai sebagai lubang tembus bersalut yang bogel, jadi header male 2.54 mm perlu dipasang dahulu. Senarai komponen sudah termasuk jalur 40 pin untuk dipatahkan, atau tambah servis solder 10 pin dan kami pasangkannya untuk anda.
Boleh tak saya guna pad arahan tanpa sebarang kod serial?
Boleh, dan itulah lorong yang lebih memaafkan. Satu pad hanyalah talian digital: satu wayar bagi setiap arahan masuk ke satu input digital, dibaca dengan digitalRead(). Tiada kadar baud terlibat, jadi masalah pemasaan SoftwareSerial di atas tidak boleh menyentuh anda.
Boleh tak saya pilih perkataan arahan saya sendiri?
Set arahan ZK-VR01 terbina dalam firmwarenya. Kalau menentukan wake word sendiri memang tujuan anda, modul ASR-PRO ialah pilihan yang patut dicapai: set arahannya boleh diprogram oleh pengguna, pada harga yang lebih tinggi.
Speaker dalam beg itu untuk apa?
Soket SPK dua pin putih itu memacu speaker yang ada dalam beg. Gunakannya sebagai pemeriksaan meja yang pertama: jalankan modul itu daripada 5 V dan GND sahaja, hidupkan suisnya lalu bercakap β apa sahaja yang ia buat ketika itu, ia buat tanpa Uno.
Boleh tak ini menghidupkan lampu 240 V di rumah?
Tidak dalam panduan ini β kekalkan semuanya di sini pada DC voltan rendah. Kontak relay itu memang bertaraf lebih tinggi, tetapi mendawai 240 V ialah kerja berlesen di Malaysia, dan panduan keselamatan modul relay kami membincangkannya dengan betul.
Tabiat ini kekal lebih lama daripada projeknya. Mana-mana modul yang ada pad serial atau sebaris IO tanpa label boleh didekati dengan cara yang sama: perhati dahulu, catat apa yang ia buat, kemudian tulis kod berdasarkan catatan itu.
Kemas kini terakhir Ogos 2026. Tersangkut? Chat dengan kami di WhatsApp.



ZK-VR01 Voice Recognition Module β Voice Commands for Smart Home and DIY Projects
Relay Module 3.3V 5V 12V 1/2/4/8 Ways Optocoupler Trigger Relay Module 1 2 4 8 Channel Relay Module - 5V RELAY MODULE(1WAY)
Arduino Uno Compatible SMD UNO R3 with Type B Cable - ATMEGA328P with CH340G-Microcontroller Project
2.54mm Pin Header Female Male Single Row Header 40P Connector Black White Red Yellow Green Blue - 40P MALE HEADER
40pcs Dupont Wire 10cm 20cm 30cm for Breadboard DIY Experiment Jumper Wire Breadboard wire - DUPONT WIRE M-F 20CM
40pcs Dupont Wire 10cm 20cm 30cm for Breadboard DIY Experiment Jumper Wire Breadboard wire - DUPONT WIRE M-M 20CM
Soldering Service for Circuit Boards & Electronics - 10 Pins Soldering Service