1. บทนำ
อัปเดตล่าสุด 19-09-2022
สิ่งที่คุณจะสร้าง
ในโค้ดแล็บนี้ คุณจะได้สร้างหน้าเว็บที่ใช้ Web Serial API เพื่อโต้ตอบกับบอร์ด BBC micro:bit เพื่อแสดงรูปภาพบนเมทริกซ์ LED ขนาด 5x5 คุณจะได้เรียนรู้เกี่ยวกับ Web Serial API และวิธีใช้สตรีมที่อ่านได้ เขียนได้ และเปลี่ยนรูปแบบเพื่อสื่อสารกับอุปกรณ์ซีเรียลผ่านเบราว์เซอร์
สิ่งที่คุณจะได้เรียนรู้
- วิธีเปิดและปิดพอร์ตซีเรียลของเว็บ
- วิธีใช้ 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 แล้ว
- เปิดแท็บใหม่ในเบราว์เซอร์แล้วไปที่ https://web-serial-codelab-start.glitch.me/
- คลิกลิงก์รีมิกซ์ Glitch เพื่อสร้างโปรเจ็กต์เริ่มต้นเวอร์ชันของคุณเอง
- คลิกปุ่มแสดง แล้วเลือกในหน้าต่างใหม่เพื่อดูการทำงานของโค้ด
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
ลองใช้
- โหลดหน้าเว็บ
- ตรวจสอบว่าหน้าเว็บไม่แสดงแบนเนอร์สีแดงที่ระบุว่าระบบไม่รองรับ 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
- โหลดหน้าเว็บซ้ำ
- คลิกปุ่มเชื่อมต่อ
- ในกล่องโต้ตอบเครื่องมือเลือกพอร์ตซีเรียล ให้เลือกอุปกรณ์ BBC micro:bit แล้วคลิกเชื่อมต่อ
- ในแท็บ คุณควรเห็นไอคอนที่ระบุว่าคุณได้เชื่อมต่อกับอุปกรณ์ซีเรียลแล้ว:
ตั้งค่าสตรีมอินพุตเพื่อรอรับข้อมูลจากพอร์ตอนุกรม
หลังจากเชื่อมต่อแล้ว เราจำเป็นต้องตั้งค่าสตรีมอินพุตและเครื่องอ่านให้อ่านข้อมูลจากอุปกรณ์ ขั้นแรก เราจะรับสตรีมที่อ่านได้จากพอร์ตโดยโทรหา 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();
ลูปการอ่านคือฟังก์ชันแบบไม่พร้อมกันที่ทำงานแบบวนซ้ำและรอเนื้อหาโดยไม่บล็อกเธรดหลัก เมื่อข้อมูลใหม่มาถึง ผู้อ่านจะแสดงผลพร็อพเพอร์ตี้ 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;
}
}
ลองใช้
ตอนนี้โปรเจ็กต์ของเราสามารถเชื่อมต่อกับอุปกรณ์และจะเพิ่มข้อมูลใดๆ ที่ได้รับจากอุปกรณ์ลงในเอลิเมนต์ในบันทึก
- โหลดหน้าเว็บซ้ำ
- คลิกปุ่มเชื่อมต่อ
- ในกล่องโต้ตอบเครื่องมือเลือกพอร์ตซีเรียล ให้เลือกอุปกรณ์ BBC micro:bit แล้วคลิกเชื่อมต่อ
- คุณควรเห็นโลโก้ Espruino
ตั้งค่าสตรีมเอาต์พุตเพื่อส่งข้อมูลไปยังพอร์ตอนุกรม
โดยทั่วไปการสื่อสารแบบ 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 ได้แล้ว ตรวจสอบยืนยันว่าเราส่งคำสั่งได้อย่างถูกต้อง ดังนี้
- โหลดหน้าเว็บซ้ำ
- คลิกปุ่มเชื่อมต่อ
- ในกล่องโต้ตอบเครื่องมือเลือกพอร์ตซีเรียล ให้เลือกอุปกรณ์ BBC micro:bit แล้วคลิกเชื่อมต่อ
- เปิดแท็บคอนโซลใน Chrome DevTools และพิมพ์
writeToStream('console.log("yes")');
คุณควรจะเห็นเอกสารลักษณะนี้พิมพ์อยู่บนหน้าเว็บ:
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
- โหลดหน้าเว็บซ้ำ
- คลิกปุ่มเชื่อมต่อ
- ในกล่องโต้ตอบเครื่องมือเลือกพอร์ตซีเรียล ให้เลือกอุปกรณ์ BBC micro:bit แล้วคลิกเชื่อมต่อ
- คุณควรเห็นรอยยิ้มแสดงบนเมทริกซ์ LED ของ micro:bit
- วาดรูปแบบอื่นบนเมทริกซ์ 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 จะเพิ่มข้อความลงในหน้าเว็บเพื่อระบุว่ามีการกดปุ่มใด ซึ่งอักขระแต่ละตัวจะอยู่ในบรรทัดเดียวกัน
- โหลดหน้าเว็บซ้ำ
- คลิกปุ่มเชื่อมต่อ
- ในกล่องโต้ตอบเครื่องมือเลือกพอร์ตซีเรียล ให้เลือกอุปกรณ์ BBC micro:bit แล้วคลิกเชื่อมต่อ
- คุณจะเห็นรอยยิ้มบนเมทริกซ์ LED แบบ micro:bits
- กดปุ่มบน 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 ปุ่มใดปุ่มหนึ่ง ข้อมูลที่พิมพ์ควรจะแสดงในบรรทัดเดียว
- โหลดหน้าเว็บซ้ำ
- คลิกปุ่มเชื่อมต่อ
- ในกล่องโต้ตอบเครื่องมือเลือกพอร์ตซีเรียล ให้เลือกอุปกรณ์ BBC micro:bit แล้วคลิกเชื่อมต่อ
- คุณควรเห็นรอยยิ้มแสดงบนเมทริกซ์ LED ของ micro:bit
- กดปุ่มบน micro:bit และตรวจสอบว่าคุณเห็นข้อมูลดังต่อไปนี้
เปลี่ยนรูปแบบสตรีมด้วย 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]
พิมพ์อยู่บนหน้าเว็บ
- โหลดหน้าเว็บซ้ำ
- คลิกปุ่มเชื่อมต่อ
- ในกล่องโต้ตอบเครื่องมือเลือกพอร์ตซีเรียล ให้เลือกอุปกรณ์ BBC micro:bit แล้วคลิกเชื่อมต่อ
- คุณควรเห็นรอยยิ้มแสดงบนเมทริกซ์ LED ของ micro:bit
- กดปุ่มบน 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 จะเปลี่ยนเป็นหน้ามีความสุขหรือหน้าเศร้า
- โหลดหน้าเว็บซ้ำ
- คลิกปุ่มเชื่อมต่อ
- ในกล่องโต้ตอบเครื่องมือเลือกพอร์ตซีเรียล ให้เลือกอุปกรณ์ BBC micro:bit แล้วคลิกเชื่อมต่อ
- คุณจะเห็นรอยยิ้มบนเมทริกซ์ LED แบบ micro:bits
- กดปุ่มบน 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;
ลองใช้
ตอนนี้คุณเปิดและปิดพอร์ตซีเรียลได้ตามต้องการ
- โหลดหน้าเว็บซ้ำ
- คลิกปุ่มเชื่อมต่อ
- ในกล่องโต้ตอบตัวเลือกพอร์ตอนุกรม ให้เลือกอุปกรณ์ BBC micro:bit แล้วคลิกเชื่อมต่อ
- คุณจะเห็นรอยยิ้มบนเมทริกซ์ LED แบบไมโคร:บิต
- กดปุ่มยกเลิกการเชื่อมต่อและตรวจสอบว่าเมทริกซ์ LED ปิดแล้วและไม่มีข้อผิดพลาดในคอนโซล
9. ขอแสดงความยินดี
ยินดีด้วย คุณสร้างเว็บแอปแรกที่ใช้ Web Serial API สำเร็จแล้ว
ติดตาม https://goo.gle/fugu-api-tracker เพื่อดูข้อมูลล่าสุดเกี่ยวกับ Web Serial API และความสามารถเว็บใหม่ๆ ที่น่าตื่นเต้นอื่นๆ ทั้งหมดที่ทีม Chrome กำลังดำเนินการอยู่