การเริ่มต้นใช้งาน Web Serial API

1. บทนำ

อัปเดตล่าสุด 19-09-2022

สิ่งที่คุณจะสร้าง

ใน Codelab นี้ คุณจะได้สร้างหน้าเว็บที่ใช้ Web Serial API เพื่อโต้ตอบกับบอร์ด BBC micro:bit เพื่อแสดงรูปภาพในเมทริกซ์ LED 5x5 ของบอร์ดดังกล่าว คุณจะได้เรียนรู้เกี่ยวกับ Web Serial API และวิธีใช้สตรีมที่อ่านได้ เขียนได้ และเปลี่ยนรูปแบบเพื่อสื่อสารกับอุปกรณ์แบบอนุกรมผ่านเบราว์เซอร์

67543f4caaaca5de.png

สิ่งที่คุณจะได้เรียนรู้

  • วิธีเปิดและปิดพอร์ต Web Serial
  • วิธีใช้ Read Loop เพื่อจัดการข้อมูลจากสตรีมอินพุต
  • วิธีส่งข้อมูลผ่านสตรีมการเขียน

สิ่งที่คุณต้องมี

  • บอร์ด BBC micro:bit v1 ที่มีเฟิร์มแวร์ Espruino 2v04
  • Chrome เวอร์ชันล่าสุด (80 ขึ้นไป)
  • ความรู้เกี่ยวกับ HTML, CSS, JavaScript และเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome

เราเลือกใช้ micro:bit v1 สำหรับ Codelab นี้เนื่องจากมีราคาไม่แพง มีอินพุต (ปุ่ม) และเอาต์พุต (จอแสดงผล LED 5x5) เพียงเล็กน้อย และอินพุตและเอาต์พุตเพิ่มเติมได้ ดูรายละเอียดว่า micro:bit สามารถทำอะไรได้บ้างที่หน้า BBC micro:bit ในเว็บไซต์ Espruino

2. เกี่ยวกับ Web Serial API

Web Serial API มีวิธีให้เว็บไซต์อ่านและเขียนสคริปต์ไปยังอุปกรณ์ซีเรียล API เชื่อมโยงเว็บและโลกความเป็นจริงโดยอนุญาตให้เว็บไซต์สื่อสารกับอุปกรณ์ซีเรียล เช่น ไมโครคอนโทรลเลอร์และเครื่องพิมพ์ 3 มิติ

มีตัวอย่างของซอฟต์แวร์ควบคุมที่สร้างขึ้นโดยใช้เทคโนโลยีเว็บมากมาย เช่น

ในบางกรณี เว็บไซต์เหล่านี้จะสื่อสารกับอุปกรณ์ผ่านแอปพลิเคชันตัวแทนเนทีฟที่ผู้ใช้ติดตั้งด้วยตนเอง ในกรณีอื่นๆ แอปพลิเคชันจะนำส่งในแอปพลิเคชันภายในแบบแพ็กเกจผ่านเฟรมเวิร์ก เช่น Electron ในกรณีอื่นๆ ผู้ใช้จะต้องดำเนินการขั้นตอนเพิ่มเติม เช่น คัดลอกแอปพลิเคชันที่คอมไพล์แล้วไปยังอุปกรณ์ด้วยแฟลชไดรฟ์ USB

ผู้ใช้อาจปรับปรุงประสบการณ์การใช้งานได้โดยการสื่อสารโดยตรงระหว่างเว็บไซต์กับอุปกรณ์ที่เว็บไซต์ควบคุมอยู่

3. การตั้งค่า

รับโค้ด

เราได้ใส่ทุกอย่างที่จำเป็นสำหรับ Codelab นี้ลงในโปรเจ็กต์ Glitch แล้ว

  1. เปิดแท็บเบราว์เซอร์ใหม่แล้วไปที่ https://web-serial-codelab-start.glitch.me/
  2. คลิกลิงก์ Remix Glitch เพื่อสร้างโปรเจ็กต์เริ่มต้นในเวอร์ชันของคุณเอง
  3. คลิกปุ่มแสดง แล้วเลือกในหน้าต่างใหม่เพื่อดูการทำงานของโค้ด

4. เปิดการเชื่อมต่ออนุกรม

ตรวจสอบว่ารองรับ Web Serial API หรือไม่

สิ่งแรกที่ต้องทำคือตรวจสอบว่าเบราว์เซอร์ปัจจุบันรองรับ Web Serial API หรือไม่ โดยตรวจสอบว่าserialอยู่ในnavigatorหรือไม่

ในเหตุการณ์ DOMContentLoaded ให้เพิ่มโค้ดต่อไปนี้ลงในโปรเจ็กต์

script.js - DOMContentLoaded

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

การดำเนินการนี้จะตรวจสอบว่าระบบรองรับ Web Serial หรือไม่ หากใช่ โค้ดนี้จะซ่อนแบนเนอร์ที่ระบุว่าระบบไม่รองรับ Web Serial

ลองใช้

  1. โหลดหน้าเว็บ
  2. ตรวจสอบว่าหน้าเว็บไม่แสดงแบนเนอร์สีแดงที่ระบุว่าระบบไม่รองรับ Web Serial

เปิดพอร์ตอนุกรม

ต่อไป เราต้องเปิดพอร์ตอนุกรม Web Serial API ทำงานไม่พร้อมกัน เช่นเดียวกับ API สมัยใหม่อื่นๆ ส่วนใหญ่ วิธีนี้ช่วยป้องกันไม่ให้ UI บล็อกขณะรออินพุต แต่นั่นก็เป็นเรื่องสำคัญเพราะหน้าเว็บอาจได้รับข้อมูลซีเรียลได้ทุกเมื่อ และเราต้องการวิธีรับฟังข้อมูลเหล่านั้น

เนื่องจากคอมพิวเตอร์อาจมีอุปกรณ์ซีเรียลหลายเครื่อง เมื่อเบราว์เซอร์พยายามขอพอร์ต เบราว์เซอร์จะแจ้งให้ผู้ใช้เลือกอุปกรณ์ที่จะเชื่อมต่อ

เพิ่มโค้ดต่อไปนี้ลงในโปรเจ็กต์ของคุณ

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

การโทรผ่าน requestPort จะถามผู้ใช้ว่าต้องการเชื่อมต่อกับอุปกรณ์ใด การเรียกใช้ port.open จะเปิดพอร์ต และต้องระบุความเร็วในการสื่อสารกับอุปกรณ์ซีเรียลด้วย BBC micro:bit ใช้การเชื่อมต่อ 9600 baud ระหว่างชิป USB เป็นอนุกรมและโปรเซสเซอร์หลัก

มาลองเชื่อมต่อปุ่ม "เชื่อมต่อ" แล้วให้เรียกใช้ connect() เมื่อผู้ใช้คลิกปุ่มนั้นกัน

เพิ่มโค้ดต่อไปนี้ลงในโปรเจ็กต์ของคุณ

script.js - clickConnect()

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

ลองใช้

ตอนนี้โครงการของเรามีข้อกำหนดขั้นต่ำสำหรับการเริ่มต้นแล้ว การคลิกปุ่มเชื่อมต่อจะแจ้งให้ผู้ใช้เลือกอุปกรณ์ซีเรียลที่จะเชื่อมต่อ จากนั้นเชื่อมต่อกับ micro:bit

  1. โหลดหน้าเว็บซ้ำ
  2. คลิกปุ่มเชื่อมต่อ
  3. ในกล่องโต้ตอบตัวเลือกพอร์ตอนุกรม ให้เลือกอุปกรณ์ BBC micro:bit แล้วคลิกเชื่อมต่อ
  4. ในแท็บ คุณควรเห็นไอคอนที่ระบุว่าคุณได้เชื่อมต่อกับอุปกรณ์ซีเรียลแล้ว:

e695daf2277cd3a2.png

ตั้งค่าสตรีมอินพุตเพื่อฟังข้อมูลจากพอร์ตอนุกรม

หลังจากเชื่อมต่อแล้ว เราจำเป็นต้องตั้งค่าสตรีมอินพุตและเครื่องอ่านให้อ่านข้อมูลจากอุปกรณ์ ขั้นแรก เราจะรับสตรีมที่อ่านได้จากพอร์ตโดยโทรหา port.readable เนื่องจากเราทราบว่าจะได้รับข้อความจากอุปกรณ์ เราจะเชื่อมต่อข้อความผ่านตัวถอดรหัสข้อความ ถัดไป เราจะได้รับเครื่องอ่านและเริ่มวงจรการอ่าน

เพิ่มโค้ดต่อไปนี้ลงในโปรเจ็กต์ของคุณ

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

Read Loop เป็นฟังก์ชันแบบไม่พร้อมกันที่ทำงานแบบวนซ้ำและรอเนื้อหาโดยไม่บล็อกเทรดหลัก เมื่อมีข้อมูลใหม่ ผู้อ่านจะแสดงพร็อพเพอร์ตี้ 2 รายการ ได้แก่ value และบูลีน done หาก done เป็นจริง แสดงว่าพอร์ตถูกปิดหรือไม่มีข้อมูลเข้ามาอีก

เพิ่มโค้ดต่อไปนี้ลงในโปรเจ็กต์ของคุณ

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

ลองใช้

ตอนนี้โปรเจ็กต์ของเราสามารถเชื่อมต่อกับอุปกรณ์และจะเพิ่มข้อมูลใดๆ ที่ได้รับจากอุปกรณ์ลงในเอลิเมนต์ในบันทึก

  1. โหลดหน้าเว็บซ้ำ
  2. คลิกปุ่มเชื่อมต่อ
  3. ในกล่องโต้ตอบตัวเลือกพอร์ตอนุกรม ให้เลือกอุปกรณ์ BBC micro:bit แล้วคลิกเชื่อมต่อ
  4. คุณควรเห็นโลโก้ Espruino ดังต่อไปนี้

dd52b5c37fc4b393.png

ตั้งค่าสตรีมเอาต์พุตเพื่อส่งข้อมูลไปยังพอร์ตอนุกรม

โดยทั่วไปการสื่อสารแบบ Serial เป็นแบบ 2 ทิศทาง นอกจากการรับข้อมูลจากพอร์ตอนุกรมแล้ว เรายังต้องการส่งข้อมูลไปยังพอร์ตด้วย เช่นเดียวกับการสตรีมอินพุต เราจะส่งข้อความผ่านสตรีมเอาต์พุตไปยัง micro:bit เท่านั้น

ขั้นแรก ให้สร้างสตรีมด้วยโปรแกรมเปลี่ยนไฟล์ข้อความและไปป์สตรีมไปยัง 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;

เมื่อเชื่อมต่อแบบอนุกรมกับเฟิร์มแวร์ Espruino บอร์ด BBC micro:bit จะทำหน้าที่เป็น read-eval-print Loop (REPL) ของ JavaScript เช่นเดียวกับที่คุณได้รับในเชลล์ Node.js ถัดไป เราต้องระบุวิธีการส่งข้อมูลไปยังสตรีม โค้ดด้านล่างจะรับผู้เขียนจากสตรีมเอาต์พุต จากนั้นใช้ write เพื่อส่งแต่ละบรรทัด แต่ละบรรทัดที่ส่งจะมีอักขระขึ้นบรรทัดใหม่ (\n) ที่จะบอก micro:bit ให้ประเมินคำสั่งที่ส่งไป

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

ในการทำให้ระบบกลับสู่สถานะที่รู้จักและหยุดเสียงสะท้อนกลับอักขระที่เราส่ง เราจะต้องส่ง Ctrl-C แล้วปิดเสียงสะท้อน

script.js - connect()

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

ลองใช้

ตอนนี้โปรเจ็กต์ของเราสามารถส่งและรับข้อมูลจาก micro:bit ได้แล้ว ตรวจสอบดูว่าเราส่งคำสั่งได้อย่างถูกต้องหรือไม่ ดังนี้

  1. โหลดหน้าเว็บซ้ำ
  2. คลิกปุ่มเชื่อมต่อ
  3. ในกล่องโต้ตอบตัวเลือกพอร์ตอนุกรม ให้เลือกอุปกรณ์ BBC micro:bit แล้วคลิกเชื่อมต่อ
  4. เปิดแท็บคอนโซลใน Chrome DevTools และพิมพ์ writeToStream('console.log("yes")');

คุณควรจะเห็นเอกสารลักษณะนี้พิมพ์อยู่บนหน้าเว็บ:

15e2df0064b5de28.png

5. ควบคุมเมทริกซ์ LED

สร้างสตริงตารางกริดของเมทริกซ์

หากต้องการควบคุมเมทริกซ์ LED ของ micro:bit เราต้องเรียกใช้ show() วิธีนี้จะแสดงกราฟิกบนหน้าจอ LED ขนาด 5x5 ในตัว ซึ่งจะใช้เลขฐานสองหรือสตริง

เราจะทำซ้ำช่องทำเครื่องหมายและสร้างอาร์เรย์เป็น 1 และ 0 เพื่อระบุว่ารายการใดถูกเลือกไว้และใดไม่ จากนั้นเราจะต้องกลับอาร์เรย์ เพราะลำดับของช่องทำเครื่องหมายของเรานั้นตรงกันข้ามกับลำดับของ LED ในเมทริกซ์ ต่อไป เราจะแปลงอาร์เรย์เป็นสตริง และสร้างคำสั่งเพื่อส่งไปยัง 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('')})`);

ลากช่องทำเครื่องหมายเพื่ออัปเดตเมทริกซ์

ต่อไป เราต้องสังเกตการเปลี่ยนแปลงในช่องทำเครื่องหมาย และหากมีการเปลี่ยนแปลง ให้ส่งข้อมูลนั้นไปยัง micro:bit เพิ่มบรรทัดต่อไปนี้ในรหัสการตรวจหาฟีเจอร์ (// CODELAB: Add feature detection here.)

script.js - DOMContentLoaded

initCheckboxes();

และลองรีเซ็ตตารางกริดเมื่อ micro:bit เชื่อมต่อครั้งแรกด้วย เพื่อให้แสดงหน้าตามีความสุข มีฟังก์ชัน drawGrid() อยู่แล้ว ฟังก์ชันนี้ทำงานคล้ายกับ sendGrid() จะใช้อาร์เรย์ของ 1 และ 0 และเลือกช่องทำเครื่องหมายตามความเหมาะสม

script.js - clickConnect()

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

ลองใช้

ในตอนนี้ เมื่อหน้าเว็บเปิดการเชื่อมต่อกับ micro:bit ก็จะส่งเป็นใบหน้าที่มีความสุข การคลิกช่องทำเครื่องหมายจะอัปเดตการแสดงผลในเมทริกซ์ LED

  1. โหลดหน้าเว็บซ้ำ
  2. คลิกปุ่มเชื่อมต่อ
  3. ในกล่องโต้ตอบตัวเลือกพอร์ตอนุกรม ให้เลือกอุปกรณ์ BBC micro:bit แล้วคลิกเชื่อมต่อ
  4. คุณควรเห็นรอยยิ้มแสดงบนเมทริกซ์ LED แบบไมโคร:บิต
  5. วาดรูปแบบที่แตกต่างออกไปในเมทริกซ์ LED โดยเปลี่ยนช่องทำเครื่องหมาย

6. ถอดปุ่ม micro:bit ขึ้นมา

เพิ่มเหตุการณ์การดูบนปุ่ม micro:bit

บน micro:bit มี 2 ปุ่ม โดยปุ่มหนึ่งอยู่ที่ด้านข้างเมทริกซ์ LED Espruino มีฟังก์ชัน setWatch ที่ส่งเหตุการณ์/Callback เมื่อกดปุ่ม เนื่องจากเราต้องการฟังทั้ง 2 ปุ่ม เราจึงทำให้ฟังก์ชันของเราเป็นแบบฉบับทั่วไป และกำหนดให้พิมพ์รายละเอียดของกิจกรรม

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

ต่อไป เราจะต้องเชื่อมต่อทั้ง 2 ปุ่ม (ชื่อ BTN1 และ BTN2 บนบอร์ด micro:bit) ทุกครั้งที่พอร์ตอนุกรมเชื่อมต่อกับอุปกรณ์

script.js - clickConnect()

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

ลองใช้

นอกจากการแสดงใบหน้าที่มีความสุขเมื่อเชื่อมต่อแล้ว การกดปุ่มใดปุ่มหนึ่งบน micro:bit จะเป็นการเพิ่มข้อความลงในหน้าเว็บที่ระบุว่าปุ่มใดกดไปแล้ว ซึ่งอักขระแต่ละตัวจะอยู่ในบรรทัดเดียวกัน

  1. โหลดหน้าเว็บซ้ำ
  2. คลิกปุ่มเชื่อมต่อ
  3. ในกล่องโต้ตอบตัวเลือกพอร์ตอนุกรม ให้เลือกอุปกรณ์ BBC micro:bit แล้วคลิกเชื่อมต่อ
  4. คุณจะเห็นรอยยิ้มบนเมทริกซ์ LED แบบ micro:bits
  5. กดปุ่มบน micro:bit และตรวจสอบว่าได้เพิ่มข้อความใหม่ลงในหน้าที่มีรายละเอียดปุ่มที่กด

7. ใช้สตรีมการเปลี่ยนรูปแบบเพื่อแยกวิเคราะห์ข้อมูลขาเข้า

การจัดการสตรีมขั้นพื้นฐาน

เมื่อกดปุ่ม micro:bit ปุ่มใดปุ่มหนึ่ง micro:bit จะส่งข้อมูลไปยังพอร์ตอนุกรมผ่านสตรีม สตรีมมีประโยชน์มาก แต่ก็อาจเป็นเรื่องท้าทายด้วยเช่นกัน เนื่องจากคุณไม่จำเป็นต้องได้รับข้อมูลทั้งหมดในคราวเดียว และอาจมีข้อมูลจำนวนมากรวมกัน

ขณะนี้แอปพิมพ์สตรีมขาเข้าทันทีที่มาถึง (ใน readLoop) ในกรณีส่วนใหญ่ อักขระแต่ละตัวจะอยู่บนบรรทัดของตัวเอง แต่ไม่มีประโยชน์มากนัก ตามหลักการ สตรีมควรแยกวิเคราะห์เป็นบรรทัดแต่ละบรรทัด และแต่ละข้อความแสดงเป็นบรรทัดของตนเอง

เปลี่ยนรูปแบบสตรีมด้วย TransformStream

ในการดำเนินการดังกล่าว เราจะใช้สตรีมการเปลี่ยนรูปแบบ ( TransformStream) ที่ช่วยให้แยกวิเคราะห์สตรีมขาเข้าและแสดงผลข้อมูลที่แยกวิเคราะห์ได้ สตรีมการเปลี่ยนรูปแบบอาจอยู่ระหว่างซอร์สของสตรีม (ในกรณีนี้คือ micro:bit) กับอะไรก็ตามที่กําลังใช้สตรีม (ในกรณีนี้คือ readLoop) และใช้การเปลี่ยนรูปแบบที่กําหนดเองได้ก่อนที่จะใช้งานขั้นสุดท้าย เปรียบได้กับสายประกอบ: เมื่อวิดเจ็ตเลื่อนลงมาด้านล่าง แต่ละขั้นตอนในบรรทัดจะปรับเปลี่ยนวิดเจ็ต ดังนั้นเมื่อไปถึงปลายทางสุดท้ายแล้ว วิดเจ็ตที่ทำงานได้อย่างสมบูรณ์

สำหรับข้อมูลเพิ่มเติม โปรดดูแนวคิดของ Streams API ของ MDN

เปลี่ยนรูปแบบสตรีมด้วย LineBreakTransformer

ลองสร้างชั้นเรียน LineBreakTransformer ซึ่งจะนำสตรีมมาแยกเป็นช่วงๆ ตามตัวแบ่งบรรทัด (\r\n) ชั้นเรียนต้องใช้ 2 วิธี ได้แก่ transform และ flush ระบบจะเรียกเมธอด transform ทุกครั้งที่สตรีมได้รับข้อมูลใหม่ โดยอาจเป็นการจัดคิวข้อมูลหรือบันทึกไว้ใช้ภายหลังก็ได้ ระบบจะเรียกเมธอด flush เมื่อปิดสตรีม และจะจัดการข้อมูลที่ยังไม่ได้ประมวลผล

ในเมธอด transform เราจะเพิ่มข้อมูลใหม่ลงใน container จากนั้นตรวจสอบว่ามีตัวแบ่งบรรทัดใน container หรือไม่ หากมี ให้แยกเป็นอาร์เรย์ แล้วทำซ้ำตามบรรทัดนั้นโดยเรียกใช้ controller.enqueue() เพื่อส่งบรรทัดที่แยกวิเคราะห์ออกมา

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

เมื่อสตรีมปิดแล้ว เราจะล้างข้อมูลที่เหลืออยู่ในคอนเทนเนอร์ออกโดยใช้ enqueue

script.js - LineBreakTransformer.flush()

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

ขั้นตอนสุดท้าย เราต้องเชื่อมต่อสตรีมขาเข้าผ่าน LineBreakTransformer ใหม่ สตรีมอินพุตเดิมมีการเชื่อมผ่าน TextDecoderStream เท่านั้น เราจึงต้องเพิ่ม pipeThrough เพื่อเชื่อมต่อไปยัง LineBreakTransformer ใหม่

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

ลองใช้

ในตอนนี้ เมื่อคุณกดปุ่ม micro:bit ปุ่มใดปุ่มหนึ่ง ข้อมูลที่พิมพ์ควรจะแสดงในบรรทัดเดียว

  1. โหลดหน้าเว็บซ้ำ
  2. คลิกปุ่มเชื่อมต่อ
  3. ในกล่องโต้ตอบตัวเลือกพอร์ตอนุกรม ให้เลือกอุปกรณ์ BBC micro:bit แล้วคลิกเชื่อมต่อ
  4. คุณควรเห็นรอยยิ้มแสดงบนเมทริกซ์ LED แบบไมโคร:บิต
  5. กดปุ่มบน micro:bit และตรวจสอบว่าคุณเห็นข้อมูลต่อไปนี้

eead3553d29ee581.png

เปลี่ยนรูปแบบสตรีมด้วย JSONTransformer

เราอาจลองแยกวิเคราะห์สตริงให้เป็น JSON ใน readLoop แต่เรามาลองสร้างตัวเปลี่ยนรูปแบบ JSON แบบง่ายมากๆ ที่จะแปลงข้อมูลเป็นออบเจ็กต์ JSON แทน หากข้อมูลไม่ใช่ JSON ที่ถูกต้อง เพียงแสดงผลข้อมูลที่เข้ามา

script.js - JSONTransformer.transform

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

ถัดไป ให้เชื่อมสตรีมผ่าน JSONTransformer หลังจากผ่าน LineBreakTransformer แล้ว วิธีนี้ช่วยให้เราทำให้ JSONTransformer เรียบง่ายอยู่เสมอ เนื่องจากเราทราบว่าจะส่ง JSON ได้เพียงบรรทัดเดียว

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

ลองใช้

ตอนนี้เมื่อคุณกดปุ่ม micro:bit ปุ่มใดปุ่มหนึ่ง คุณจะเห็น [object Object] พิมพ์อยู่บนหน้าเว็บ

  1. โหลดหน้าเว็บซ้ำ
  2. คลิกปุ่มเชื่อมต่อ
  3. ในกล่องโต้ตอบตัวเลือกพอร์ตอนุกรม ให้เลือกอุปกรณ์ BBC micro:bit แล้วคลิกเชื่อมต่อ
  4. คุณควรเห็นรอยยิ้มแสดงบนเมทริกซ์ LED แบบไมโคร:บิต
  5. กดปุ่มบน micro:bit และตรวจสอบว่าคุณเห็นข้อมูลต่อไปนี้

ตอบสนองต่อการกดปุ่ม

หากต้องการตอบสนองต่อการกดปุ่ม micro:bit ให้อัปเดต readLoop เพื่อตรวจสอบว่าข้อมูลที่ได้รับเป็น object ที่มีพร็อพเพอร์ตี้ button หรือไม่ จากนั้นโทรหา buttonPushed เพื่อจัดการการกดปุ่ม

script.js - readLoop()

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

เมื่อพุชปุ่ม micro:bit การแสดงผลบนเมทริกซ์ LED ควรเปลี่ยนไป ใช้รหัสต่อไปนี้ในการตั้งค่าเมทริกซ์:

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

ลองใช้

ตอนนี้เมื่อคุณกดปุ่ม micro:bit ปุ่มใดปุ่มหนึ่ง เมทริกซ์ LED จะเปลี่ยนเป็นหน้ามีความสุขหรือหน้าเศร้า

  1. โหลดหน้าเว็บซ้ำ
  2. คลิกปุ่มเชื่อมต่อ
  3. ในกล่องโต้ตอบตัวเลือกพอร์ตอนุกรม ให้เลือกอุปกรณ์ BBC micro:bit แล้วคลิกเชื่อมต่อ
  4. คุณจะเห็นรอยยิ้มบนเมทริกซ์ LED แบบ micro:bits
  5. กดปุ่มบน micro:bit และตรวจสอบว่าเมทริกซ์ LED มีการเปลี่ยนแปลง

8. กำลังปิดพอร์ตอนุกรม

ขั้นตอนสุดท้ายคือการเชื่อมต่อฟังก์ชันยกเลิกการเชื่อมต่อเพื่อปิดพอร์ตเมื่อผู้ใช้ใช้งานเสร็จแล้ว

ปิดพอร์ตเมื่อผู้ใช้คลิกปุ่มเชื่อมต่อ/ยกเลิกการเชื่อมต่อ

เมื่อผู้ใช้คลิกปุ่มเชื่อมต่อ/ยกเลิกการเชื่อมต่อ เราจำเป็นต้องปิดการเชื่อมต่อ หากพอร์ตเปิดอยู่แล้ว ให้เรียกใช้ disconnect() และอัปเดต UI เพื่อระบุว่าหน้าเว็บไม่ได้เชื่อมต่อกับอุปกรณ์ซีเรียลอีกต่อไป

script.js - clickConnect()

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

ปิดสตรีมและพอร์ต

ในฟังก์ชัน disconnect เราต้องปิดสตรีมอินพุต ปิดสตรีมเอาต์พุต และปิดพอร์ต หากต้องการปิดสตรีมอินพุต ให้เรียกใช้ reader.cancel() การเรียกไปยัง cancel เป็นแบบไม่พร้อมกัน เราจึงต้องใช้ await เพื่อรอให้การดำเนินการเสร็จสิ้น

script.js - disconnect()

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

หากต้องการปิดสตรีมเอาต์พุต ให้เรียก writer เรียกใช้ close() แล้วรอให้ออบเจ็กต์ outputDone ปิด:

script.js - disconnect()

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

สุดท้าย ให้ปิดพอร์ตอนุกรมแล้วรอให้ปิดโดยทำดังนี้

script.js - disconnect()

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

ลองใช้

ตอนนี้คุณสามารถเปิดและปิดพอร์ตอนุกรมได้ตามต้องการ

  1. โหลดหน้าเว็บซ้ำ
  2. คลิกปุ่มเชื่อมต่อ
  3. ในกล่องโต้ตอบตัวเลือกพอร์ตอนุกรม ให้เลือกอุปกรณ์ BBC micro:bit แล้วคลิกเชื่อมต่อ
  4. คุณจะเห็นรอยยิ้มบนเมทริกซ์ LED แบบไมโคร:บิต
  5. กดปุ่มยกเลิกการเชื่อมต่อและตรวจสอบว่าเมทริกซ์ LED ปิดแล้วและไม่มีข้อผิดพลาดในคอนโซล

9. ขอแสดงความยินดี

ยินดีด้วย คุณได้สร้างเว็บแอปแรกที่ใช้ Web Serial API เสร็จสมบูรณ์แล้ว

ติดตาม https://goo.gle/fugu-api-tracker เพื่อดูข้อมูลล่าสุดเกี่ยวกับ Web Serial API และความสามารถเว็บใหม่ๆ ที่น่าตื่นเต้นอื่นๆ ทั้งหมดที่ทีม Chrome กำลังดำเนินการอยู่