mirror of
https://github.com/sergeyyarkov/avr128da48_web-serial-example.git
synced 2026-10-11 18:28:58 +03:00
feat: writing to serial port
This commit is contained in:
parent
0b34bda967
commit
d3a5aadcd4
111
web/app.js
111
web/app.js
@ -1,5 +1,110 @@
|
||||
const $connectButton = document.getElementById('MCU_connect');
|
||||
class SerialPortHandler {
|
||||
constructor(options) {
|
||||
this.encoder = new TextEncoder();
|
||||
this.decoder = new TextDecoder();
|
||||
this.options = options;
|
||||
this.port = null;
|
||||
this.writer = null;
|
||||
this.reader = null;
|
||||
this.isOpened = false;
|
||||
}
|
||||
|
||||
console.log($connectButton);
|
||||
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);
|
||||
return await this.writer.write(encoded);
|
||||
}
|
||||
|
||||
async read() {
|
||||
let data = '';
|
||||
while (true) {
|
||||
const { value, done } = await this.reader.read();
|
||||
if (done) {
|
||||
this.reader.releaseLock();
|
||||
break;
|
||||
}
|
||||
data += this.decoder.decode(value);
|
||||
console.log(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 serialPortHandler = new SerialPortHandler({ baudRate: 9600 });
|
||||
|
||||
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);
|
||||
|
||||
@ -4,10 +4,39 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Document</title>
|
||||
<title>Web Serial API Example</title>
|
||||
<link href="./style.css" rel="stylesheet" />
|
||||
<script defer src="./app.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<button id="MCU_connect">Connect</button>
|
||||
<div class="app">
|
||||
<div>
|
||||
<button id="connect">Connect</button>
|
||||
<button id="disconnect">Disconnect</button>
|
||||
</div>
|
||||
<form id="terminal_form" action="#">
|
||||
<label for="terminal">Enter command name:</label><br />
|
||||
<div class="flex">
|
||||
<input
|
||||
id="input"
|
||||
name="input"
|
||||
placeholder="e.g led_toggle"
|
||||
type="text"
|
||||
disabled
|
||||
/>
|
||||
<button type="submit">Send</button>
|
||||
</div>
|
||||
</form>
|
||||
<textarea id="serial_log" placeholder=">" readonly></textarea>
|
||||
<div id="port_info">
|
||||
<div>
|
||||
<p id="status">not connected</p>
|
||||
</div>
|
||||
<div>
|
||||
<span>vendorId: <span id="vendorId">-</span> |</span>
|
||||
<span>deviceId: <span id="productId">-</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
93
web/style.css
Normal file
93
web/style.css
Normal file
@ -0,0 +1,93 @@
|
||||
:root {
|
||||
--border-color: #c9d1d9;
|
||||
--border-color-hover: #6e7681;
|
||||
--font-family: monospace;
|
||||
}
|
||||
|
||||
*,
|
||||
*:before,
|
||||
*:after {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
.app {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
/* padding: 20px; */
|
||||
width: 100%;
|
||||
max-width: 600px;
|
||||
row-gap: 5px;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
box-sizing: border-box;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 2rem;
|
||||
font-family: var(--font-family);
|
||||
}
|
||||
|
||||
p {
|
||||
padding: 0;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
input,
|
||||
textarea {
|
||||
font-family: var(--font-family);
|
||||
padding: 5px 15px;
|
||||
border-radius: 4px;
|
||||
width: 100%;
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
textarea {
|
||||
resize: vertical;
|
||||
min-height: 200px;
|
||||
font-size: 16px;
|
||||
outline: none;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
label {
|
||||
font-size: 14px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
button {
|
||||
cursor: pointer;
|
||||
background: none;
|
||||
font-family: var(--font-family);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 4px;
|
||||
padding: 5px 15px;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
border: 1px solid var(--border-color-hover);
|
||||
}
|
||||
|
||||
#terminal_form div {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 5px;
|
||||
margin-bottom: 5px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
#port_info {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
#port_info #status {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user