126 lines
3.4 KiB
JavaScript

class SerialPortHandler {
constructor(options, onConnect, onDisconnect) {
this.encoder = new TextEncoder();
this.decoder = new TextDecoder();
this.onConnect = onConnect;
this.onDisconnect = onDisconnect;
this.options = options;
this.port = null;
this.writer = null;
this.reader = null;
this.isOpened = false;
this.#setupListeners();
}
async open() {
if ('serial' in navigator) {
try {
const port = await navigator.serial.requestPort();
await port.open(this.options);
this.port = port;
this.writer = port.writable.getWriter();
this.reader = port.readable.getReader();
this.isOpened = true;
return this.port.getInfo();
} catch (error) {
console.error(error);
throw error;
}
} else {
console.error('Web Serial API is not supported in your browser.');
}
}
async close() {
await this.port.close();
}
async write(data) {
const encoded = this.encoder.encode(data);
await this.writer.write(encoded);
}
async read() {
while (true) {
const { value, done } = await this.reader.read();
if (done) {
this.reader.releaseLock();
break;
}
console.log(this.decoder.decode(value));
}
}
#setupListeners() {
if ('serial' in navigator) {
navigator.serial.addEventListener('connect', this.onConnect);
navigator.serial.addEventListener('disconnect', this.onDisconnected);
}
}
}
const $connectButton = document.getElementById('connect');
const $disconnectButton = document.getElementById('disconnect');
const $terminalForm = document.getElementById('terminal_form');
const $serialLog = document.getElementById('serial_log');
const $status = document.getElementById('status');
const $vendorId = document.getElementById('vendorId');
const $productId = document.getElementById('productId');
const onConnected = (e) => console.log('device inserted!');
const onDisconnected = (e) => console.log('device ejected!');
const serialPortHandler = new SerialPortHandler(
{ baudRate: 9600 },
onConnected,
onDisconnected
);
async function onConnect() {
try {
const info = await serialPortHandler.open();
console.log('Device connected: ', info);
console.log(serialPortHandler.port);
$terminalForm.elements.input.removeAttribute('disabled');
$vendorId.textContent = '0x' + info.usbVendorId.toString(16);
$productId.textContent = '0x' + info.usbProductId.toString(16);
$status.textContent = 'CONNECTED';
} catch (error) {
$status.textContent = 'ERROR';
}
}
async function onDisconnect() {
await serialPortHandler.close();
$vendorId.textContent = '-';
$productId.textContent = '-';
$status.textContent = 'NOT CONNECTED';
}
async function onSend(e) {
e.preventDefault();
const $form = e.target;
const data = $form.elements.input.value;
$form.reset();
if (serialPortHandler.isOpened) {
await serialPortHandler.write(data + '\n');
await serialPortHandler.read();
}
}
$connectButton.addEventListener('click', onConnect);
$disconnectButton.addEventListener('click', onDisconnect);
$terminalForm.addEventListener('submit', onSend);
// const program1 = setInterval(async () => {
// if (serialPortHandler.isOpened) {
// await serialPortHandler.write('led_toggle' + '\n');
// }
// }, 50);
// setInterval(() => {
// clearInterval(program1);
// }, 5000);