Bắt đầu sử dụng Web Serial API

1. Giới thiệu

Lần cập nhật gần đây nhất: ngày 21 tháng 7 năm 2020

Sản phẩm bạn sẽ tạo ra

Trong lớp học lập trình này, bạn sẽ tạo một trang web sử dụng Web Serial API để tương tác với bảng BBC micro:bit nhằm hiển thị hình ảnh trên ma trận LED 5x5 của bảng. Bạn sẽ tìm hiểu về Web Serial API và cách sử dụng các luồng có thể đọc, ghi và biến đổi để giao tiếp với các thiết bị nối tiếp thông qua trình duyệt.

81167ab7c01d353d.png

Kiến thức bạn sẽ học được

  • Cách mở và đóng cổng Web Serial
  • Cách sử dụng vòng lặp đọc để xử lý dữ liệu từ luồng đầu vào
  • Cách gửi dữ liệu qua luồng ghi

Bạn cần có

Chúng tôi chọn sử dụng micro:bit cho lớp học lập trình này vì thiết bị này có giá cả phải chăng, cung cấp một số đầu vào (nút) và đầu ra (màn hình LED 5x5) và có thể cung cấp thêm đầu vào và đầu ra. Hãy xem trang BBC micro:bit trên trang web Espruino để biết thông tin chi tiết về những gì micro:bit có thể làm.

2. Giới thiệu về Web Serial API

Web Serial API cung cấp cho các trang web một cách để đọc và ghi vào thiết bị nối tiếp bằng tập lệnh. API này kết nối web và thế giới thực bằng cách cho phép các trang web giao tiếp với thiết bị nối tiếp, chẳng hạn như bộ vi điều khiển và máy in 3D.

Có nhiều ví dụ về phần mềm điều khiển được xây dựng bằng công nghệ web. Ví dụ:

Trong một số trường hợp, các trang web này giao tiếp với thiết bị thông qua một ứng dụng tác nhân gốc do người dùng cài đặt theo cách thủ công. Trong các trường hợp khác, ứng dụng được phân phối trong một ứng dụng gốc đóng gói thông qua một khung như Electron. Trong các trường hợp khác, người dùng phải thực hiện thêm một bước, chẳng hạn như sao chép một ứng dụng đã biên dịch vào thiết bị bằng ổ đĩa flash USB.

Trải nghiệm người dùng có thể được cải thiện bằng cách cung cấp thông tin liên lạc trực tiếp giữa trang web và thiết bị mà trang web đang kiểm soát.

3. Thiết lập

Lấy mã nguồn

Chúng tôi đã đặt mọi thứ bạn cần cho lớp học lập trình này vào một dự án Glitch.

  1. Mở một thẻ trình duyệt mới rồi truy cập vào https://web-serial-codelab-start.glitch.me/.
  2. Nhấp vào đường liên kết Remix Glitch để tạo phiên bản riêng cho dự án khởi đầu.
  3. Nhấp vào nút Hiện, rồi chọn Trong cửa sổ mới để xem mã của bạn hoạt động.

4. Mở một kết nối nối tiếp

Kiểm tra xem Web Serial API có được hỗ trợ hay không

Điều đầu tiên cần làm là kiểm tra xem Web Serial API có được hỗ trợ trong trình duyệt hiện tại hay không. Để làm việc đó, hãy kiểm tra xem serial có trong navigator hay không.

Trong sự kiện DOMContentLoaded, hãy thêm mã sau vào dự án của bạn:

script.js - DOMContentLoaded

// CODELAB: Add feature detection here.
const notSupported = document.getElementById('notSupported');
notSupported.classList.toggle('hidden', 'serial' in navigator);

Thao tác này kiểm tra xem Web Serial có được hỗ trợ hay không. Nếu có, mã này sẽ ẩn biểu ngữ cho biết Web Serial không được hỗ trợ.

Thử nào

  1. Tải trang.
  2. Xác minh rằng trang này không hiển thị biểu ngữ màu đỏ cho biết Web Serial không được hỗ trợ.

Mở cổng nối tiếp

Tiếp theo, chúng ta cần mở cổng nối tiếp. Giống như hầu hết các API hiện đại khác, Web Serial API là không đồng bộ. Điều này giúp ngăn chặn giao diện người dùng chặn khi chờ dữ liệu đầu vào, nhưng điều này cũng rất quan trọng vì trang web có thể nhận được dữ liệu nối tiếp bất cứ lúc nào và chúng ta cần có cách để theo dõi dữ liệu đó.

Vì máy tính có thể có nhiều thiết bị nối tiếp, nên khi cố gắng yêu cầu một cổng, trình duyệt sẽ nhắc người dùng chọn thiết bị để kết nối.

Thêm mã sau vào dự án của bạn:

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

Lệnh gọi requestPort nhắc người dùng chọn thiết bị mà họ muốn kết nối. Việc gọi port.open sẽ mở cổng. Chúng ta cũng cần cung cấp tốc độ mà chúng ta muốn giao tiếp với thiết bị nối tiếp. BBC micro:bit sử dụng kết nối 9600 baud giữa chip USB-to-serial và bộ xử lý chính.

Hãy kết nối nút kết nối và để nút này gọi connect() khi người dùng nhấp vào nút.

Thêm mã sau vào dự án của bạn:

script.js - clickConnect()

// CODELAB: Add connect code here.
await connect();

Thử nào

Dự án của chúng ta hiện có những thứ tối thiểu để bắt đầu. Khi nhấp vào nút Connect (Kết nối), người dùng sẽ được nhắc chọn thiết bị nối tiếp để kết nối, sau đó kết nối với micro:bit.

  1. Tải lại trang.
  2. Nhấp vào nút Kết nối.
  3. Trong hộp thoại Serial Port chooser (Trình chọn cổng nối tiếp), hãy chọn thiết bị BBC micro:bit rồi nhấp vào Connect (Kết nối).
  4. Trên thẻ này, bạn sẽ thấy một biểu tượng cho biết bạn đã kết nối với một thiết bị nối tiếp:

d9d0d3966960aeab.png

Thiết lập một luồng đầu vào để nhận dữ liệu từ cổng nối tiếp

Sau khi thiết lập kết nối, chúng ta cần thiết lập một luồng đầu vào và một trình đọc để đọc dữ liệu từ thiết bị. Trước tiên, chúng ta sẽ lấy luồng có thể đọc từ cổng bằng cách gọi port.readable. Vì biết rằng chúng ta sẽ nhận được văn bản từ thiết bị, nên chúng ta sẽ chuyển văn bản đó qua một bộ giải mã văn bản. Tiếp theo, chúng ta sẽ lấy một trình đọc và bắt đầu vòng lặp đọc.

Thêm mã sau vào dự án của bạn:

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

Vòng lặp đọc là một hàm không đồng bộ chạy trong một vòng lặp và chờ nội dung mà không chặn luồng chính. Khi dữ liệu mới đến, trình đọc sẽ trả về hai thuộc tính: value và một boolean done. Nếu done là true, tức là cổng đã đóng hoặc không có thêm dữ liệu nào được gửi đến.

Thêm mã sau vào dự án của bạn:

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

Thử nào

Giờ đây, dự án của chúng ta có thể kết nối với thiết bị và sẽ thêm mọi dữ liệu nhận được từ thiết bị vào phần tử nhật ký.

  1. Tải lại trang.
  2. Nhấp vào nút Kết nối.
  3. Trong hộp thoại Serial Port chooser (Trình chọn cổng nối tiếp), hãy chọn thiết bị BBC micro:bit rồi nhấp vào Connect (Kết nối).
  4. Bạn sẽ thấy biểu trưng Espruino:

93494fd58ea835eb.png

Thiết lập luồng đầu ra để gửi dữ liệu đến cổng nối tiếp

Giao tiếp nối tiếp thường là giao tiếp hai chiều. Ngoài việc nhận dữ liệu từ cổng nối tiếp, chúng ta cũng muốn gửi dữ liệu đến cổng này. Tương tự như luồng đầu vào, chúng ta sẽ chỉ gửi văn bản qua luồng đầu ra đến micro:bit.

Trước tiên, hãy tạo một luồng bộ mã hoá văn bản và chuyển luồng đó đến 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;

Khi được kết nối qua cổng nối tiếp với chương trình cơ sở Espruino, bảng BBC micro:bit sẽ hoạt động như một vòng lặp đọc-đánh giá-in (REPL) JavaScript, tương tự như những gì bạn nhận được trong một shell Node.js. Tiếp theo, chúng ta cần cung cấp một phương thức để gửi dữ liệu đến luồng. Đoạn mã dưới đây lấy một trình ghi từ luồng đầu ra rồi dùng write để gửi từng dòng. Mỗi dòng được gửi đều có một ký tự dòng mới (\n), để cho micro:bit biết rằng cần đánh giá lệnh đã gửi.

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

Để đưa hệ thống về trạng thái đã biết và ngăn hệ thống lặp lại các ký tự mà chúng ta gửi, chúng ta cần gửi lệnh CTRL-C và tắt chế độ lặp lại.

script.js - connect()

// CODELAB: Send CTRL-C and turn off echo on REPL
writeToStream('\x03', 'echo(false);');

Thử nào

Giờ đây, dự án của chúng ta có thể gửi và nhận dữ liệu từ micro:bit. Hãy xác minh rằng chúng ta có thể gửi lệnh đúng cách:

  1. Tải lại trang.
  2. Nhấp vào nút Kết nối.
  3. Trong hộp thoại Serial Port chooser (Trình chọn cổng nối tiếp), hãy chọn thiết bị BBC micro:bit rồi nhấp vào Connect (Kết nối).
  4. Mở thẻ Bảng điều khiển trong Chrome DevTools rồi nhập writeToStream('console.log("yes")');

Bạn sẽ thấy nội dung tương tự như sau được in trên trang:

a13187e7e6260f7f.png

5. Điều khiển ma trận đèn LED

Tạo chuỗi lưới ma trận

Để điều khiển ma trận đèn LED trên micro:bit, chúng ta cần gọi show(). Phương thức này hiển thị đồ hoạ trên màn hình LED 5x5 tích hợp. Hàm này nhận một số nhị phân hoặc một chuỗi.

Chúng ta sẽ lặp lại các hộp đánh dấu và tạo một mảng gồm các số 1 và 0 cho biết hộp nào được đánh dấu và hộp nào không. Sau đó, chúng ta cần đảo ngược mảng vì thứ tự của các hộp đánh dấu ngược lại với thứ tự của các đèn LED trong ma trận. Tiếp theo, chúng ta sẽ chuyển đổi mảng thành một chuỗi và tạo lệnh để gửi đến 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('')})`);

Liên kết các hộp đánh dấu để cập nhật ma trận

Tiếp theo, chúng ta cần theo dõi các thay đổi trên hộp đánh dấu và nếu có thay đổi, hãy gửi thông tin đó đến micro:bit. Trong mã phát hiện tính năng (// CODELAB: Add feature detection here.), hãy thêm dòng sau:

script.js - DOMContentLoaded

initCheckboxes();

Hãy đặt lại lưới khi micro:bit được kết nối lần đầu tiên để lưới hiển thị một khuôn mặt tươi cười. Hàm drawGrid() đã được cung cấp. Hàm này hoạt động tương tự như sendGrid(); hàm này nhận một mảng gồm các số 1 và 0, rồi đánh dấu vào các hộp đánh dấu cho phù hợp.

script.js - clickConnect()

// CODELAB: Reset the grid on connect here.
drawGrid(GRID_HAPPY);
sendGrid();

Thử nào

Giờ đây, khi trang mở một kết nối đến micro:bit, trang sẽ gửi một khuôn mặt tươi cười. Khi bạn nhấp vào các hộp đánh dấu, màn hình trên ma trận đèn LED sẽ cập nhật.

  1. Tải lại trang.
  2. Nhấp vào nút Kết nối.
  3. Trong hộp thoại Serial Port chooser (Trình chọn cổng nối tiếp), hãy chọn thiết bị BBC micro:bit rồi nhấp vào Connect (Kết nối).
  4. Bạn sẽ thấy một khuôn mặt cười trên ma trận đèn LED của micro:bit.
  5. Vẽ một mẫu khác trên ma trận đèn LED bằng cách thay đổi hộp đánh dấu.

6. Kết nối các nút trên micro:bit

Thêm sự kiện theo dõi vào các nút trên micro:bit

Có hai nút trên micro:bit, mỗi nút ở một bên của ma trận đèn LED. Espruino cung cấp một hàm setWatch để gửi sự kiện/lệnh gọi lại khi người dùng nhấn nút. Vì muốn theo dõi cả hai nút, chúng ta sẽ tạo hàm chung và in thông tin chi tiết về sự kiện.

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

Tiếp theo, chúng ta cần kết nối cả hai nút (BTN1 và BTN2 trên bảng micro:bit) mỗi khi cổng nối tiếp được kết nối với thiết bị.

script.js - clickConnect()

// CODELAB: Initialize micro:bit buttons.
watchButton('BTN1');
watchButton('BTN2');

Thử nào

Ngoài việc hiển thị khuôn mặt tươi cười khi kết nối, việc nhấn vào một trong hai nút trên micro:bit sẽ thêm văn bản vào trang cho biết nút nào đã được nhấn. Rất có thể mỗi ký tự sẽ nằm trên một dòng riêng.

  1. Tải lại trang.
  2. Nhấp vào nút Kết nối.
  3. Trong hộp thoại Serial Port chooser (Trình chọn cổng nối tiếp), hãy chọn thiết bị BBC micro:bit rồi nhấp vào Connect (Kết nối).
  4. Bạn sẽ thấy một khuôn mặt cười xuất hiện trên ma trận đèn LED của micro:bit.
  5. Nhấn các nút trên micro:bit và xác minh rằng ứng dụng sẽ thêm văn bản mới vào trang có thông tin chi tiết về nút đã nhấn.

7. Sử dụng luồng biến đổi để phân tích cú pháp dữ liệu đến

Xử lý luồng cơ bản

Khi một trong các nút trên micro:bit được nhấn, micro:bit sẽ gửi dữ liệu đến cổng nối tiếp thông qua một luồng. Luồng dữ liệu rất hữu ích, nhưng cũng có thể gây khó khăn vì bạn không nhất thiết phải nhận được tất cả dữ liệu cùng một lúc và dữ liệu có thể được chia thành các phần tuỳ ý.

Hiện tại, ứng dụng in luồng dữ liệu đến khi luồng này đến (trong readLoop). Trong hầu hết các trường hợp, mỗi ký tự nằm trên một dòng riêng, nhưng điều đó không hữu ích lắm. Tốt nhất là luồng này nên được phân tích cú pháp thành các dòng riêng lẻ và mỗi thông báo hiển thị dưới dạng một dòng riêng.

Chuyển đổi luồng bằng TransformStream

Để làm việc đó, chúng ta có thể dùng một luồng biến đổi ( TransformStream). Luồng này giúp phân tích cú pháp luồng dữ liệu đến và trả về dữ liệu đã phân tích cú pháp. Luồng biến đổi có thể nằm giữa nguồn luồng (trong trường hợp này là micro:bit) và bất kỳ thứ gì đang sử dụng luồng (trong trường hợp này là readLoop) và có thể áp dụng một phép biến đổi tuỳ ý trước khi luồng được sử dụng. Hãy coi đây như một dây chuyền lắp ráp: Khi một tiện ích xuất hiện trên dây chuyền, mỗi bước trong dây chuyền sẽ sửa đổi tiện ích đó, sao cho đến khi tiện ích đó đến được đích đến cuối cùng, thì đó là một tiện ích hoạt động đầy đủ.

Để biết thêm thông tin, hãy xem Các khái niệm về Streams API của MDN.

Biến đổi luồng bằng LineBreakTransformer

Hãy tạo một lớp LineBreakTransformer, lớp này sẽ lấy một luồng dữ liệu và chia thành các đoạn dựa trên dấu ngắt dòng (\r\n). Lớp này cần có 2 phương thức là transformflush. Phương thức transform được gọi mỗi khi luồng nhận được dữ liệu mới. Thao tác này có thể xếp dữ liệu vào hàng đợi hoặc lưu dữ liệu để dùng sau. Phương thức flush được gọi khi luồng bị đóng và phương thức này xử lý mọi dữ liệu chưa được xử lý.

Trong phương thức transform, chúng ta sẽ thêm dữ liệu mới vào container, rồi kiểm tra xem có dấu ngắt dòng nào trong container hay không. Nếu có, hãy chia thành một mảng, rồi lặp lại các dòng, gọi controller.enqueue() để gửi các dòng đã phân tích cú pháp.

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

Khi luồng đóng, chúng ta chỉ cần xoá mọi dữ liệu còn lại trong vùng chứa bằng cách sử dụng enqueue.

script.js - LineBreakTransformer.flush()

// CODELAB: Flush the stream.
controller.enqueue(this.container);

Cuối cùng, chúng ta cần truyền luồng dữ liệu đến qua LineBreakTransformer mới. Luồng đầu vào ban đầu của chúng ta chỉ được truyền qua một TextDecoderStream, vì vậy, chúng ta cần thêm một pipeThrough khác để truyền qua LineBreakTransformer mới.

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

Thử nào

Giờ đây, khi bạn nhấn một trong các nút trên micro:bit, dữ liệu được in sẽ được trả về trên một dòng duy nhất.

  1. Tải lại trang.
  2. Nhấp vào nút Kết nối.
  3. Trong hộp thoại Serial Port chooser (Trình chọn cổng nối tiếp), hãy chọn thiết bị BBC micro:bit rồi nhấp vào Connect (Kết nối).
  4. Bạn sẽ thấy một khuôn mặt cười trên ma trận đèn LED của micro:bit.
  5. Nhấn các nút trên micro:bit và xác minh rằng bạn thấy nội dung tương tự như sau:

6c2193880c748412.png

Biến đổi luồng bằng JSONTransformer

Chúng ta có thể cố gắng phân tích cú pháp chuỗi thành JSON trong readLoop, nhưng thay vào đó, hãy tạo một trình biến đổi JSON rất đơn giản để biến đổi dữ liệu thành một đối tượng JSON. Nếu dữ liệu không phải là JSON hợp lệ, chỉ cần trả về dữ liệu đã nhận được.

script.js - JSONTransformer.transform

// CODELAB: Attempt to parse JSON content
try {
  controller.enqueue(JSON.parse(chunk));
} catch (e) {
  controller.enqueue(chunk);
}

Tiếp theo, hãy truyền luồng qua JSONTransformer sau khi luồng đã đi qua LineBreakTransformer. Nhờ đó, chúng ta có thể giữ cho JSONTransformer ở trạng thái đơn giản, vì chúng ta biết rằng JSON sẽ chỉ được gửi trên một dòng duy nhất.

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

Thử nào

Giờ đây, khi nhấn một trong các nút micro:bit, bạn sẽ thấy [object Object] xuất hiện trên trang.

  1. Tải lại trang.
  2. Nhấp vào nút Kết nối.
  3. Trong hộp thoại Serial Port chooser (Trình chọn cổng nối tiếp), hãy chọn thiết bị BBC micro:bit rồi nhấp vào Connect (Kết nối).
  4. Bạn sẽ thấy một khuôn mặt cười trên ma trận đèn LED của micro:bit.
  5. Nhấn các nút trên micro:bit và xác minh rằng bạn thấy nội dung tương tự như sau:

Phản hồi khi nhấn nút

Để phản hồi các lần nhấn nút trên micro:bit, hãy cập nhật readLoop để kiểm tra xem dữ liệu mà nó nhận được có phải là object có thuộc tính button hay không. Sau đó, hãy gọi buttonPushed để xử lý thao tác nhấn nút.

script.js - readLoop()

const { value, done } = await reader.read();
if (value && value.button) {
  buttonPushed(value);
} else {
  log.textContent += value + '\n';
}

Khi nút micro:bit được nhấn, màn hình trên ma trận LED sẽ thay đổi. Hãy sử dụng mã sau để đặt ma trận:

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

Thử nào

Giờ đây, khi bạn nhấn một trong các nút trên micro:bit, ma trận đèn LED sẽ thay đổi thành mặt cười hoặc mặt buồn.

  1. Tải lại trang.
  2. Nhấp vào nút Kết nối.
  3. Trong hộp thoại Serial Port chooser (Trình chọn cổng nối tiếp), hãy chọn thiết bị BBC micro:bit rồi nhấp vào Connect (Kết nối).
  4. Bạn sẽ thấy một khuôn mặt cười xuất hiện trên ma trận đèn LED của micro:bit.
  5. Nhấn các nút trên micro:bit và xác minh rằng ma trận đèn LED thay đổi.

8. Đóng cổng nối tiếp

Bước cuối cùng là kết nối chức năng ngắt kết nối để đóng cổng khi người dùng hoàn tất.

Đóng cổng khi người dùng nhấp vào nút Kết nối/Ngắt kết nối

Khi người dùng nhấp vào nút Connect (Kết nối)/Disconnect (Ngắt kết nối), chúng ta cần đóng kết nối. Nếu cổng đã mở, hãy gọi disconnect() và cập nhật giao diện người dùng để cho biết trang không còn kết nối với thiết bị nối tiếp nữa.

script.js - clickConnect()

// CODELAB: Add disconnect code here.
if (port) {
  await disconnect();
  toggleUIConnected(false);
  return;
}

Đóng các luồng và cổng

Trong hàm disconnect, chúng ta cần đóng luồng đầu vào, đóng luồng đầu ra và đóng cổng. Để đóng luồng đầu vào, hãy gọi reader.cancel(). Lệnh gọi đến cancel là không đồng bộ, vì vậy, chúng ta cần sử dụng await để chờ lệnh gọi này hoàn tất:

script.js - disconnect()

// CODELAB: Close the input stream (reader).
if (reader) {
  await reader.cancel();
  await inputDone.catch(() => {});
  reader = null;
  inputDone = null;
}

Để đóng luồng đầu ra, hãy lấy writer, gọi close() và đợi đối tượng outputDone đóng:

script.js - disconnect()

// CODELAB: Close the output stream.
if (outputStream) {
  await outputStream.getWriter().close();
  await outputDone;
  outputStream = null;
  outputDone = null;
}

Cuối cùng, hãy đóng cổng nối tiếp và đợi cổng này đóng:

script.js - disconnect()

// CODELAB: Close the port.
await port.close();
port = null;

Thử nào

Giờ đây, bạn có thể mở và đóng cổng nối tiếp tuỳ ý.

  1. Tải lại trang.
  2. Nhấp vào nút Kết nối.
  3. Trong hộp thoại Serial Port (Cổng nối tiếp), hãy chọn thiết bị BBC micro:bit rồi nhấp vào Connect (Kết nối).
  4. Bạn sẽ thấy một khuôn mặt cười trên ma trận đèn LED của micro:bit
  5. Nhấn nút Ngắt kết nối và xác minh rằng ma trận đèn LED đã tắt và không có lỗi nào trong bảng điều khiển.

9. Xin chúc mừng

Xin chúc mừng! Bạn đã tạo thành công ứng dụng web đầu tiên sử dụng Web Serial API.

Hãy theo dõi https://goo.gle/fugu-api-tracker để biết thông tin mới nhất về Web Serial API và tất cả các tính năng web mới thú vị khác mà nhóm Chrome đang phát triển.