A WebSerial Terminal for Esp32forth
┄─────────────────────────────────┄
August 24, 2024
WebSerial
┄───────┄
• New API for reading/writing to:
- serial devices
- USB serial devices
- Bluetooth serial devices
• Currently Chrome only
• Methods to "pair" with a device
• Methods for asynchronous I/O
Request a Device
┄──────────────┄
navigator.serial.requestPort()
-> Promise for a SerialPort
Getting Devices
┄─────────────┄
navigator.serial.getPorts()
-> Promise for an array of SerialPort
Read / Write
┄──────────┄
• Await a port "opening"
• Get a Reader / Writer
• Asynchronously read / write ArrayBuffers
r~
context.serial_buffer = [];
context.ports = [];
context.port = null;
context.serial_writer = null;
async function RouteSerial(port) {
await port.open({
baudRate: 115200,
});
if (port.writable) {
context.serial_writer = port.writable.getWriter();
}
while (port.readable) {
const reader = port.readable.getReader();
try {
while (true) {
const { value, done } = await reader.read();
if (done) {
reader.releaseLock();
break;
}
for (var i = 0; i < value.length; ++i) {
context.serial_buffer.push(value[i]);
}
}
} catch (error) {
}
}
}
context.UpdateSerial = function() {
navigator.serial.getPorts().then((ports) => {
context.ports = ports;
if (context.ports.length > 0) {
context.port = context.ports[0];
} else {
context.port = null;
}
context.serial_writer = null;
if (context.port) {
RouteSerial(context.port);
}
});
};
if (!globalObj.write && navigator && navigator.serial) {
navigator.serial.addEventListener("connect", (e) => {
context.UpdateSerial();
});
navigator.serial.addEventListener("disconnect", (e) => {
context.UpdateSerial();
});
context.UpdateSerial();
}
~ jseval
JSWORD: pairserial { -- }
navigator.serial
.requestPort()
.then((port) => {
context.UpdateSerial();
})
.catch((e) => {
console.log('No serial port selected.');
context.UpdateSerial();
});
~
JSWORD: serial-key-raw { -- n }
if (context.serial_buffer.length) {
return context.serial_buffer.shift();
} else {
return -1;
}
~
JSWORD: serial-type { a n -- }
if (!context.port || !context.serial_writer) {
return;
}
context.serial_writer.write(u8.slice(a, a + n));
~
: serial
begin
pause
begin serial-key-raw dup 0< 0= while emit repeat drop
begin key? while key >r rp@ 1 serial-type rdrop repeat
again
;
<script src="ueforth.js"></script>
<script type="text/forth">
: y/n ( -- f ) key [char] y = ;
web
: go
." SERIAL TERMINAL" cr
." Pair (y/n) ? " y/n if pairserial then
serial
;
forth
go
</script>
https://eforth.appspot.com/serial
🚀 🚀
DEMO +
QUESTIONS❓
🙏
Thank you!