mirror of
https://github.com/sergeyyarkov/avr128da48_web-serial-example.git
synced 2026-10-11 10:19:02 +03:00
refactor
This commit is contained in:
parent
c524b034e1
commit
6e5e770bd8
183
web/app.js
183
web/app.js
@ -1,3 +1,5 @@
|
||||
var EOT = '\u0004';
|
||||
|
||||
class SerialPortHandler {
|
||||
constructor(options, onConnect, onDisconnect) {
|
||||
this.encoder = new TextEncoder();
|
||||
@ -11,21 +13,17 @@ class SerialPortHandler {
|
||||
}
|
||||
|
||||
async open() {
|
||||
if ('serial' in navigator) {
|
||||
try {
|
||||
const port = await navigator.serial.requestPort();
|
||||
await port.open(this.options);
|
||||
try {
|
||||
const port = await navigator.serial.requestPort();
|
||||
await port.open(this.options);
|
||||
|
||||
this.port = port;
|
||||
this.isOpened = true;
|
||||
this.port = port;
|
||||
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.');
|
||||
return this.port.getInfo();
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,96 +41,111 @@ class SerialPortHandler {
|
||||
|
||||
async read() {
|
||||
const reader = this.port.readable.getReader();
|
||||
const chunks = [];
|
||||
let chunks = '';
|
||||
while (true) {
|
||||
const { value, done } = await reader.read();
|
||||
const decoded = this.decoder.decode(value);
|
||||
|
||||
chunks.push(decoded);
|
||||
chunks += decoded;
|
||||
|
||||
if (done || decoded.includes('\u0004')) {
|
||||
console.log('done');
|
||||
console.log('Reading done.');
|
||||
reader.releaseLock();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return chunks.join('');
|
||||
return chunks;
|
||||
}
|
||||
|
||||
#setupListeners() {
|
||||
if ('serial' in navigator) {
|
||||
navigator.serial.addEventListener('connect', this.onConnect);
|
||||
navigator.serial.addEventListener('disconnect', this.onDisconnected);
|
||||
navigator.serial.addEventListener('connect', this.onConnect);
|
||||
navigator.serial.addEventListener('disconnect', this.onDisconnected);
|
||||
}
|
||||
}
|
||||
|
||||
class Application {
|
||||
constructor(root) {
|
||||
if (!('serial' in navigator)) {
|
||||
console.error('Web Serial API is not supported in your browser.');
|
||||
return;
|
||||
}
|
||||
|
||||
this.serialPortHandler = new SerialPortHandler({ baudRate: 9600 });
|
||||
|
||||
/**
|
||||
* DOM Elements
|
||||
*/
|
||||
this.$root = root;
|
||||
this.$connectButton = this.$root.querySelector('#connect');
|
||||
this.$disconnectButton = this.$root.querySelector('#disconnect');
|
||||
this.$terminalForm = this.$root.querySelector('#terminal_form');
|
||||
this.$serialLog = this.$root.querySelector('#serial_log');
|
||||
this.$status = this.$root.querySelector('#status');
|
||||
this.$vendorId = this.$root.querySelector('#vendorId');
|
||||
this.$productId = this.$root.querySelector('#productId');
|
||||
|
||||
this.#setupEvents();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handlers for connecting, disconnecting and sending a command
|
||||
*/
|
||||
#setupEvents() {
|
||||
this.$connectButton.addEventListener('click', this.#connectHandler.bind(this));
|
||||
this.$disconnectButton.addEventListener('click', this.#disconnectHandler.bind(this));
|
||||
this.$terminalForm.addEventListener('submit', this.#submitHandler.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Open serial port and notify user of connection status
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async #connectHandler() {
|
||||
try {
|
||||
if (this.serialPortHandler.isOpened) return;
|
||||
const info = await this.serialPortHandler.open();
|
||||
console.log('Port opened: ', info);
|
||||
this.$terminalForm.elements.input.removeAttribute('disabled');
|
||||
this.$vendorId.textContent = '0x' + info.usbVendorId.toString(16);
|
||||
this.$productId.textContent = '0x' + info.usbProductId.toString(16);
|
||||
this.$status.textContent = 'CONNECTED';
|
||||
} catch (error) {
|
||||
this.$status.textContent = 'ERROR';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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');
|
||||
/**
|
||||
* Closes the serial port and updates the connection status.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async #disconnectHandler() {
|
||||
if (!this.serialPortHandler.isOpened) return;
|
||||
await this.serialPortHandler.close();
|
||||
this.$vendorId.textContent = '-';
|
||||
this.$productId.textContent = '-';
|
||||
this.$status.textContent = 'NOT CONNECTED';
|
||||
}
|
||||
|
||||
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 {
|
||||
if (serialPortHandler.isOpened) return;
|
||||
const info = await serialPortHandler.open();
|
||||
console.log('Port opened: ', info);
|
||||
$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';
|
||||
/**
|
||||
* Writes data to the serial port and reads the response
|
||||
* @param {SubmitEvent} e - Form submit event
|
||||
*/
|
||||
async #submitHandler(e) {
|
||||
e.preventDefault();
|
||||
const $form = e.target;
|
||||
const data = $form.elements.input.value;
|
||||
$form.reset();
|
||||
if (this.serialPortHandler.isOpened && data) {
|
||||
this.$serialLog.innerHTML += data + '\n';
|
||||
await this.serialPortHandler.write(data + '\n');
|
||||
const message = await this.serialPortHandler.read();
|
||||
this.$serialLog.textContent += message;
|
||||
this.$serialLog.textContent += '\n';
|
||||
console.log(message);
|
||||
}
|
||||
this.$serialLog.scrollTo(0, this.$serialLog.scrollHeight);
|
||||
}
|
||||
}
|
||||
|
||||
async function onDisconnect() {
|
||||
if (!serialPortHandler.isOpened) return;
|
||||
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 && data) {
|
||||
$serialLog.innerHTML += data + '\n';
|
||||
await serialPortHandler.write(data + '\n');
|
||||
const message = await serialPortHandler.read();
|
||||
$serialLog.textContent += message;
|
||||
$serialLog.textContent += '\n';
|
||||
console.log(message);
|
||||
}
|
||||
$serialLog.scrollTo(0, $serialLog.scrollHeight);
|
||||
}
|
||||
|
||||
$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);
|
||||
new Application(document.getElementById('app'));
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
<script defer src="./app.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app">
|
||||
<div id="app">
|
||||
<div>
|
||||
<button id="connect">Connect</button>
|
||||
<button id="disconnect">Disconnect</button>
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
.app {
|
||||
#app {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
/* padding: 20px; */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user