1. Pengantar
Terakhir Diperbarui: 21-07-2020
Yang akan Anda bangun
Dalam codelab ini, Anda akan membuat halaman web yang menggunakan Web Serial API untuk berinteraksi dengan papan BBC micro:bit guna menampilkan gambar pada matriks LED 5x5. Anda akan mempelajari Web Serial API dan cara menggunakan aliran yang dapat dibaca, dapat ditulis, dan dapat diubah untuk berkomunikasi dengan perangkat serial melalui browser.

Yang akan Anda pelajari
- Cara membuka dan menutup port Web Serial
- Cara menggunakan loop baca untuk menangani data dari aliran input
- Cara mengirim data melalui aliran tulis
Yang Anda butuhkan
- Papan BBC micro:bit dengan firmware Espruino terbaru
- Chrome versi terbaru (80 atau yang lebih baru)
- Pengetahuan tentang HTML, CSS, JavaScript, dan Chrome DevTools
Kami memilih untuk menggunakan micro:bit untuk codelab ini karena terjangkau, menawarkan beberapa input (tombol) dan output (layar LED 5x5), serta dapat memberikan input dan output tambahan. Lihat halaman BBC micro:bit di situs Espruino untuk mengetahui detail tentang kemampuan micro:bit.
2. Tentang Web Serial API
Web Serial API menyediakan cara bagi situs untuk membaca dan menulis ke perangkat serial dengan skrip. API ini menghubungkan web dan dunia fisik dengan memungkinkan situs berkomunikasi dengan perangkat serial, seperti mikrokontroler dan printer 3D.
Ada banyak contoh software kontrol yang dibuat menggunakan teknologi web. Contoh:
Dalam beberapa kasus, situs ini berkomunikasi dengan perangkat melalui aplikasi agen native yang diinstal secara manual oleh pengguna. Dalam kasus lain, aplikasi dikirimkan dalam aplikasi native yang dipaketkan melalui framework seperti Electron. Dalam kasus lain, pengguna diwajibkan melakukan langkah tambahan, seperti menyalin aplikasi yang dikompilasi ke perangkat dengan flash drive USB.
Pengalaman pengguna dapat ditingkatkan dengan menyediakan komunikasi langsung antara situs dan perangkat yang dikontrolnya.
3. Mempersiapkan
Mendapatkan kode
Kami telah memasukkan semua yang Anda perlukan untuk codelab ini ke dalam project Glitch.
- Buka tab browser baru, lalu buka https://web-serial-codelab-start.glitch.me/.
- Klik link Remix Glitch untuk membuat versi project awal Anda sendiri.
- Klik tombol Tampilkan, lalu pilih Di Jendela Baru untuk melihat cara kerja kode Anda.
4. Membuka koneksi serial
Memeriksa apakah Web Serial API didukung
Hal pertama yang harus dilakukan adalah memeriksa apakah Web Serial API didukung di browser saat ini. Untuk melakukannya, periksa apakah serial ada di navigator.
Di peristiwa DOMContentLoaded, tambahkan kode berikut ke project Anda:
script.js - DOMContentLoaded
// CODELAB: Add feature detection here.
const notSupported = document.getElementById('notSupported');
notSupported.classList.toggle('hidden', 'serial' in navigator);
Ini memeriksa apakah Web Serial didukung. Jika ya, kode ini menyembunyikan banner yang menyatakan bahwa Web Serial tidak didukung.
Cobalah
- Muat halaman.
- Pastikan halaman tidak menampilkan banner merah yang menyatakan bahwa Web Serial tidak didukung.
Buka port serial
Selanjutnya, kita perlu membuka port serial. Seperti kebanyakan API modern lainnya, Web Serial API bersifat asinkron. Hal ini mencegah UI diblokir saat menunggu input, tetapi juga penting karena data serial dapat diterima oleh halaman web kapan saja, dan kita memerlukan cara untuk memantaunya.
Karena komputer mungkin memiliki beberapa perangkat serial, saat browser mencoba meminta port, browser akan meminta pengguna untuk memilih perangkat yang akan dihubungkan.
Tambahkan kode berikut ke project Anda:
script.js - connect()
// CODELAB: Add code to request & open port here.
// - Request a port and open a connection.
port = await navigator.serial.requestPort();
// - Wait for the port to open.
await port.open({ baudrate: 9600 });
Panggilan requestPort akan meminta pengguna untuk memilih perangkat yang ingin dihubungkan. Memanggil port.open akan membuka port. Kita juga perlu memberikan kecepatan yang kita inginkan untuk berkomunikasi dengan perangkat serial. BBC micro:bit menggunakan koneksi baud 9600 antara chip USB-ke-serial dan prosesor utama.
Mari kita hubungkan juga tombol connect dan buat tombol tersebut memanggil connect() saat pengguna mengkliknya.
Tambahkan kode berikut ke project Anda:
script.js - clickConnect()
// CODELAB: Add connect code here.
await connect();
Cobalah
Project kita sekarang memiliki persyaratan minimum untuk memulai. Mengklik tombol Hubungkan akan meminta pengguna untuk memilih perangkat serial yang akan dihubungkan, lalu menghubungkan ke micro:bit.
- Muat ulang halaman.
- Klik tombol Connect.
- Dalam dialog pemilih Port Serial, pilih perangkat BBC micro:bit, lalu klik Connect.
- Di tab, Anda akan melihat ikon yang menunjukkan bahwa Anda telah terhubung ke perangkat serial:

Menyiapkan aliran input untuk memproses data dari port serial
Setelah koneksi dibuat, kita perlu menyiapkan aliran input dan pembaca untuk membaca data dari perangkat. Pertama, kita akan mendapatkan stream yang dapat dibaca dari port dengan memanggil port.readable. Karena kita tahu bahwa kita akan mendapatkan teks kembali dari perangkat, kita akan menyalurkannya melalui dekoder teks. Selanjutnya, kita akan mendapatkan pembaca dan memulai loop baca.
Tambahkan kode berikut ke project Anda:
script.js - connect()
// CODELAB: Add code to read the stream here.
let decoder = new TextDecoderStream();
inputDone = port.readable.pipeTo(decoder.writable);
inputStream = decoder.readable;
reader = inputStream.getReader();
readLoop();
Loop baca adalah fungsi asinkron yang berjalan dalam loop dan menunggu konten tanpa memblokir thread utama. Saat data baru tiba, pembaca akan menampilkan dua properti: value dan boolean done. Jika done benar, port telah ditutup atau tidak ada lagi data yang masuk.
Tambahkan kode berikut ke project Anda:
script.js - readLoop()
// CODELAB: Add read loop here.
while (true) {
const { value, done } = await reader.read();
if (value) {
log.textContent += value + '\n';
}
if (done) {
console.log('[readLoop] DONE', done);
reader.releaseLock();
break;
}
}
Cobalah
Project kita kini dapat terhubung ke perangkat dan akan menambahkan data apa pun yang diterima dari perangkat ke elemen log.
- Muat ulang halaman.
- Klik tombol Connect.
- Dalam dialog pemilih Port Serial, pilih perangkat BBC micro:bit, lalu klik Connect.
- Anda akan melihat logo Espruino:

Menyiapkan aliran output untuk mengirim data ke port serial
Komunikasi serial biasanya bersifat dua arah. Selain menerima data dari port serial, kita juga ingin mengirim data ke port tersebut. Seperti pada aliran input, kita hanya akan mengirim teks melalui aliran output ke micro:bit.
Pertama, buat streaming encoder teks dan teruskan streaming ke port.writeable.
script.js - connect()
// CODELAB: Add code setup the output stream here.
const encoder = new TextEncoderStream();
outputDone = encoder.readable.pipeTo(port.writable);
outputStream = encoder.writable;
Saat terhubung melalui serial dengan firmware Espruino, papan BBC micro:bit berfungsi sebagai read-eval-print loop (REPL) JavaScript, mirip dengan yang Anda dapatkan di shell Node.js. Selanjutnya, kita perlu menyediakan metode untuk mengirim data ke aliran. Kode di bawah mendapatkan penulis dari aliran output, lalu menggunakan write untuk mengirim setiap baris. Setiap baris yang dikirim menyertakan karakter baris baru (\n), untuk memberi tahu micro:bit agar mengevaluasi perintah yang dikirim.
script.js - writeToStream()
// CODELAB: Write to output stream
const writer = outputStream.getWriter();
lines.forEach((line) => {
console.log('[SEND]', line);
writer.write(line + '\n');
});
writer.releaseLock();
Untuk membuat sistem berada dalam status yang diketahui dan menghentikannya agar tidak mengulang karakter yang kita kirimkan, kita perlu mengirim CTRL-C dan menonaktifkan echo.
script.js - connect()
// CODELAB: Send CTRL-C and turn off echo on REPL
writeToStream('\x03', 'echo(false);');
Cobalah
Project kita kini dapat mengirim dan menerima data dari micro:bit. Mari kita verifikasi bahwa kita dapat mengirim perintah dengan benar:
- Muat ulang halaman.
- Klik tombol Connect.
- Dalam dialog pemilih Port Serial, pilih perangkat BBC micro:bit, lalu klik Connect.
- Buka tab Console di Chrome DevTools, lalu ketik
writeToStream('console.log("yes")');
Anda akan melihat sesuatu seperti ini tercetak di halaman:

5. Mengontrol matriks LED
Membangun string petak matriks
Untuk mengontrol matriks LED di micro:bit, kita perlu memanggil show(). Metode ini menampilkan grafik di layar LED 5x5 bawaan. Fungsi ini menggunakan angka biner atau string.
Kita akan melakukan iterasi pada kotak centang dan membuat array 1 dan 0 yang menunjukkan kotak mana yang dicentang dan mana yang tidak. Kemudian, kita perlu membalikkan array, karena urutan kotak centang kita berlawanan dengan urutan LED dalam matriks. Selanjutnya, kita akan mengonversi array menjadi string dan membuat perintah untuk dikirim ke micro:bit.
script.js - sendGrid()
// CODELAB: Generate the grid
const arr = [];
ledCBs.forEach((cb) => {
arr.push(cb.checked === true ? 1 : 0);
});
writeToStream(`show(0b${arr.reverse().join('')})`);
Menghubungkan kotak centang untuk memperbarui matriks
Selanjutnya, kita perlu memproses perubahan pada kotak centang dan, jika berubah, mengirimkan informasi tersebut ke micro:bit. Di kode deteksi fitur (// CODELAB: Add feature detection here.), tambahkan baris berikut:
script.js - DOMContentLoaded
initCheckboxes();
Kita juga akan mereset petak saat micro:bit pertama kali terhubung, sehingga menampilkan wajah tersenyum. Fungsi drawGrid() sudah disediakan. Fungsi ini bekerja mirip dengan sendGrid(); fungsi ini mengambil array 1 dan 0, lalu mencentang kotak centang yang sesuai.
script.js - clickConnect()
// CODELAB: Reset the grid on connect here.
drawGrid(GRID_HAPPY);
sendGrid();
Cobalah
Sekarang, saat halaman membuka koneksi ke micro:bit, halaman akan mengirimkan wajah bahagia. Mencentang kotak akan memperbarui tampilan pada matriks LED.
- Muat ulang halaman.
- Klik tombol Connect.
- Dalam dialog pemilih Port Serial, pilih perangkat BBC micro:bit, lalu klik Connect.
- Anda akan melihat senyuman ditampilkan di matriks LED micro:bit.
- Gambarkan pola yang berbeda pada matriks LED dengan mengubah kotak centang.
6. Menghubungkan tombol micro:bit
Menambahkan peristiwa smartwatch pada tombol micro:bit
Ada dua tombol di micro:bit, satu di setiap sisi matriks LED. Espruino menyediakan fungsi setWatch yang mengirim peristiwa/callback saat tombol ditekan. Karena kita ingin memproses kedua tombol, kita akan membuat fungsi generik dan mencetak detail peristiwa.
script.js - watchButton()
// CODELAB: Hook up the micro:bit buttons to print a string.
const cmd = `
setWatch(function(e) {
print('{"button": "${btnId}", "pressed": ' + e.state + '}');
}, ${btnId}, {repeat:true, debounce:20, edge:"both"});
`;
writeToStream(cmd);
Selanjutnya, kita perlu menghubungkan kedua tombol (bernama BTN1 dan BTN2 di papan micro:bit) setiap kali port serial terhubung ke perangkat.
script.js - clickConnect()
// CODELAB: Initialize micro:bit buttons.
watchButton('BTN1');
watchButton('BTN2');
Cobalah
Selain menampilkan wajah bahagia saat terhubung, menekan salah satu tombol di micro:bit akan menambahkan teks ke halaman yang menunjukkan tombol mana yang ditekan. Kemungkinan besar, setiap karakter akan berada di barisnya masing-masing.
- Muat ulang halaman.
- Klik tombol Connect.
- Dalam dialog pemilih Port Serial, pilih perangkat BBC micro:bit, lalu klik Connect.
- Anda akan melihat senyuman ditampilkan di matriks LED micro:bit.
- Tekan tombol di micro:bit dan pastikan tombol tersebut menambahkan teks baru ke halaman dengan detail tombol yang ditekan.
7. Menggunakan aliran transformasi untuk mengurai data masuk
Penanganan streaming dasar
Saat salah satu tombol micro:bit ditekan, micro:bit akan mengirimkan data ke port serial melalui aliran. Aliran sangat berguna, tetapi juga dapat menjadi tantangan karena Anda tidak akan mendapatkan semua data sekaligus, dan data tersebut dapat dibagi-bagi secara acak.
Saat ini, aplikasi mencetak aliran masuk saat tiba (dalam readLoop). Dalam kebanyakan kasus, setiap karakter berada di barisnya sendiri, tetapi hal itu tidak terlalu membantu. Idealnya, stream harus diuraikan menjadi baris terpisah, dan setiap pesan ditampilkan sebagai barisnya sendiri.
Mentransformasi aliran data dengan TransformStream
Untuk melakukannya, kita dapat menggunakan aliran transformasi ( TransformStream), yang memungkinkan kita mengurai aliran data yang masuk dan menampilkan data yang diurai. Aliran transformasi dapat berada di antara sumber aliran (dalam hal ini, micro:bit), dan apa pun yang menggunakan aliran (dalam hal ini readLoop), dan dapat menerapkan transformasi arbitrer sebelum akhirnya digunakan. Anggap saja seperti jalur perakitan: Saat widget bergerak di sepanjang jalur, setiap langkah di jalur tersebut mengubah widget, sehingga saat mencapai tujuan akhirnya, widget tersebut berfungsi sepenuhnya.
Untuk mengetahui informasi selengkapnya, lihat konsep Streams API MDN.
Mentransformasi aliran dengan LineBreakTransformer
Mari kita buat class LineBreakTransformer, yang akan mengambil stream dan membaginya berdasarkan jeda baris (\r\n). Class ini memerlukan dua metode, transform dan flush. Metode transform dipanggil setiap kali data baru diterima oleh aliran. Data dapat dimasukkan ke dalam antrean atau disimpan untuk digunakan nanti. Metode flush dipanggil saat aliran ditutup, dan metode ini menangani data apa pun yang belum diproses.
Dalam metode transform, kita akan menambahkan data baru ke container, lalu memeriksa apakah ada jeda baris di container. Jika ada, pisahkan menjadi array, lalu lakukan iterasi pada baris, dengan memanggil controller.enqueue() untuk mengirimkan baris yang diuraikan.
script.js - LineBreakTransformer.transform()
// CODELAB: Handle incoming chunk
this.container += chunk;
const lines = this.container.split('\r\n');
this.container = lines.pop();
lines.forEach(line => controller.enqueue(line));
Saat aliran ditutup, kita cukup menghapus data yang tersisa di penampung menggunakan enqueue.
script.js - LineBreakTransformer.flush()
// CODELAB: Flush the stream.
controller.enqueue(this.container);
Terakhir, kita perlu menyalurkan aliran masuk melalui LineBreakTransformer baru. Aliran input asli kita hanya disalurkan melalui TextDecoderStream, jadi kita perlu menambahkan pipeThrough tambahan untuk menyalurkannya melalui LineBreakTransformer baru.
script.js - connect()
// CODELAB: Add code to read the stream here.
let decoder = new TextDecoderStream();
inputDone = port.readable.pipeTo(decoder.writable);
inputStream = decoder.readable
.pipeThrough(new TransformStream(new LineBreakTransformer()));
Cobalah
Sekarang, saat Anda menekan salah satu tombol micro:bit, data yang dicetak akan ditampilkan dalam satu baris.
- Muat ulang halaman.
- Klik tombol Connect.
- Dalam dialog pemilih Port Serial, pilih perangkat BBC micro:bit, lalu klik Connect.
- Anda akan melihat senyuman ditampilkan di matriks LED micro:bit.
- Tekan tombol di micro:bit dan pastikan Anda melihat sesuatu seperti berikut:

Mentransformasi aliran dengan JSONTransformer
Kita dapat mencoba mengurai string menjadi JSON di readLoop, tetapi sebagai gantinya, mari kita buat transformer JSON yang sangat sederhana yang akan mengubah data menjadi objek JSON. Jika data bukan JSON yang valid, cukup tampilkan data yang masuk.
script.js - JSONTransformer.transform
// CODELAB: Attempt to parse JSON content
try {
controller.enqueue(JSON.parse(chunk));
} catch (e) {
controller.enqueue(chunk);
}
Selanjutnya, teruskan streaming melalui JSONTransformer, setelah melalui LineBreakTransformer. Hal ini memungkinkan kita menjaga kesederhanaan JSONTransformer, karena kita tahu bahwa JSON hanya akan dikirim dalam satu baris.
script.js - connect
// CODELAB: Add code to read the stream here.
let decoder = new TextDecoderStream();
inputDone = port.readable.pipeTo(decoder.writable);
inputStream = decoder.readable
.pipeThrough(new TransformStream(new LineBreakTransformer()))
.pipeThrough(new TransformStream(new JSONTransformer()));
Cobalah
Sekarang, saat Anda menekan salah satu tombol micro:bit, Anda akan melihat [object Object] dicetak di halaman.
- Muat ulang halaman.
- Klik tombol Connect.
- Dalam dialog pemilih Port Serial, pilih perangkat BBC micro:bit, lalu klik Connect.
- Anda akan melihat senyuman ditampilkan di matriks LED micro:bit.
- Tekan tombol di micro:bit, dan pastikan Anda melihat sesuatu seperti berikut:
Merespons penekanan tombol
Untuk merespons penekanan tombol micro:bit, perbarui readLoop untuk memeriksa apakah data yang telah diterimanya adalah object dengan properti button. Kemudian, panggil buttonPushed untuk menangani penekanan tombol.
script.js - readLoop()
const { value, done } = await reader.read();
if (value && value.button) {
buttonPushed(value);
} else {
log.textContent += value + '\n';
}
Saat tombol micro:bit ditekan, tampilan pada matriks LED akan berubah. Gunakan kode berikut untuk menyetel matriks:
script.js - buttonPushed()
// CODELAB: micro:bit button press handler
if (butEvt.button === 'BTN1') {
divLeftBut.classList.toggle('pressed', butEvt.pressed);
if (butEvt.pressed) {
drawGrid(GRID_HAPPY);
sendGrid();
}
return;
}
if (butEvt.button === 'BTN2') {
divRightBut.classList.toggle('pressed', butEvt.pressed);
if (butEvt.pressed) {
drawGrid(GRID_SAD);
sendGrid();
}
}
Cobalah
Sekarang, saat Anda menekan salah satu tombol micro:bit, matriks LED akan berubah menjadi wajah senang atau wajah sedih.
- Muat ulang halaman.
- Klik tombol Connect.
- Dalam dialog pemilih Port Serial, pilih perangkat BBC micro:bit, lalu klik Connect.
- Anda akan melihat senyuman ditampilkan di matriks LED micro:bit.
- Tekan tombol di micro:bit, dan verifikasi bahwa matriks LED berubah.
8. Menutup port serial
Langkah terakhir adalah menghubungkan fungsi pemutusan untuk menutup port saat pengguna selesai.
Tutup port saat pengguna mengklik tombol Hubungkan/Batalkan hubungan
Saat pengguna mengklik tombol Hubungkan/Batalkan hubungan, kita perlu menutup koneksi. Jika port sudah terbuka, panggil disconnect()dan perbarui UI untuk menunjukkan bahwa halaman tidak lagi terhubung ke perangkat serial.
script.js - clickConnect()
// CODELAB: Add disconnect code here.
if (port) {
await disconnect();
toggleUIConnected(false);
return;
}
Tutup aliran data dan port
Dalam fungsi disconnect, kita perlu menutup stream input, menutup stream output, dan menutup port. Untuk menutup aliran input, panggil reader.cancel(). Panggilan ke cancel bersifat asinkron, jadi kita perlu menggunakan await untuk menunggu hingga selesai:
script.js - disconnect()
// CODELAB: Close the input stream (reader).
if (reader) {
await reader.cancel();
await inputDone.catch(() => {});
reader = null;
inputDone = null;
}
Untuk menutup aliran output, dapatkan writer, panggil close(), dan tunggu hingga objek outputDone ditutup:
script.js - disconnect()
// CODELAB: Close the output stream.
if (outputStream) {
await outputStream.getWriter().close();
await outputDone;
outputStream = null;
outputDone = null;
}
Terakhir, tutup port serial dan tunggu hingga tertutup:
script.js - disconnect()
// CODELAB: Close the port.
await port.close();
port = null;
Cobalah
Sekarang, Anda dapat membuka dan menutup port serial sesuai keinginan.
- Muat ulang halaman.
- Klik tombol Connect.
- Dalam dialog pemilih Port Serial, pilih perangkat BBC micro:bit, lalu klik Connect.
- Anda akan melihat senyuman ditampilkan di matriks LED micro:bit
- Tekan tombol Disconnect dan pastikan matriks LED mati dan tidak ada error di konsol.
9. Selamat
Selamat! Anda telah berhasil membuat aplikasi web pertama yang menggunakan Web Serial API.
Pantau https://goo.gle/fugu-api-tracker untuk mengetahui info terbaru tentang Web Serial API dan semua kemampuan web baru yang menarik lainnya yang sedang dikerjakan oleh tim Chrome.