diff --git a/index.html b/index.html index ab19c35..3dcd899 100644 --- a/index.html +++ b/index.html @@ -6,8 +6,8 @@ Web Serial Console - -
+ +

Web Serial Console

@@ -15,12 +15,9 @@
- +
- +
-
+
diff --git a/script.js b/script.js index 4e58130..0ec1a23 100644 --- a/script.js +++ b/script.js @@ -1,43 +1,45 @@ - -const scrollableElement = document.getElementById('scrollable-element'); +// Globals +const addDeviceMessage = `Add a device...         ` +const addPort = document.getElementById('add-port') const autoscrollCheckbox = document.getElementById('autoscroll-checkbox'); -const connectButton = document.getElementById('connect-button') +const baud = document.getElementById('baud'); const clearButton = document.getElementById('clear-button'); -const addPort = document.getElementById('add-port') +const connectButton = document.getElementById('connect-button') const refreshPorts = document.getElementById('refresh-ports'); +const scrollableElement = document.getElementById('scrollable-element'); const select = document.getElementById('serial-select'); -const baud = document.getElementById('baud'); + let autoscroll = true; let serialPorts = []; let reader; +// Event Listeners addPort.addEventListener('click', async () => { const port = await navigator.serial.requestPort(); serialPorts.push(port); updateSerialSelect(serialPorts); }); -function buildPortOption(port) { - const option = document.createElement('option'); - option.value = port; - - try { - const info = port.getInfo(); - if (info && 'usbVendorId' in info && 'usbProductId' in info) { - const { usbVendorId, usbProductId } = info; - option.text = `Device ${usbVendorId}:${usbProductId}`; - } else { - console.error('getInfo() did not return expected properties:', info); - option.text = 'Unknown Device'; - } - } catch (error) { - console.error('Error retrieving port information:', error); - option.text = 'Unknown Device'; +autoscrollCheckbox.addEventListener('change', (e) => { + autoscroll = e.target.checked; + if (autoscroll) { + scrollToBottom(); } +}); - return option; -} +clearButton.addEventListener('click', () => { + while (scrollableElement.firstChild) { + scrollableElement.removeChild(scrollableElement.firstChild); + } +}); +connectButton.addEventListener('click', async () => { + const selectedPort = serialPorts[select.selectedIndex] + const baudRate = Math.round(baud.value) + if (selectedPort) { + await connectToSerialPort(selectedPort, baudRate); + } +}); refreshPorts.addEventListener('click', async () => { while (select.children.length > 1) { @@ -53,18 +55,27 @@ refreshPorts.addEventListener('click', async () => { }); }); -autoscrollCheckbox.addEventListener('change', (e) => { - autoscroll = e.target.checked; - if (autoscroll) { - scrollToBottom(); - } -}); +// Functions +function buildPortOption(port) { + const option = document.createElement('option'); + option.value = port; -clearButton.addEventListener('click', () => { - while (scrollableElement.firstChild) { - scrollableElement.removeChild(scrollableElement.firstChild); + try { + const info = port.getInfo(); + if (info && 'usbVendorId' in info && 'usbProductId' in info) { + const { usbVendorId, usbProductId } = info; + option.text = `Device ${usbVendorId}:${usbProductId}`; + } else { + console.error('getInfo() did not return expected properties:', info); + option.text = 'Unknown Device'; + } + } catch (error) { + console.error('Error retrieving port information:', error); + option.text = 'Unknown Device'; } -}); + + return option; +} function addText(text) { const newText = document.createElement('p'); @@ -80,29 +91,10 @@ function scrollToBottom() { scrollableElement.scrollTop = scrollableElement.scrollHeight; } -async function updateSerialSelect(ports) { - if (ports > 0) { - select.innerHTML = ''; - } else { - select.innerHTML = ''; - } - ports.forEach(port => { - const option = buildPortOption(port) - select.appendChild(option); - }); -} - -connectButton.addEventListener('click', async () => { - const selectedPort = serialPorts[select.selectedIndex - 1] - const baudRate = Math.round(baud.value) - if (selectedPort) { - await connectToSerialPort(selectedPort, baudRate); - } -}); - +// Async Functions async function connectToSerialPort(port, baud) { await port.open({ baudRate: baud }); - + let buffer = '' const textDecoder = new TextDecoderStream(); const readableStreamClosed = port.readable.pipeTo(textDecoder.writable); const reader = textDecoder.readable.getReader(); @@ -113,7 +105,16 @@ async function connectToSerialPort(port, baud) { if (done) { break; } - addText(value); + + buffer += value; + + while (buffer.includes('\n')) { + const newlineIndex = buffer.indexOf('\n'); + const line = buffer.slice(0, newlineIndex); + buffer = buffer.slice(newlineIndex + 1); + + addText(line); + } } } catch (error) { console.error('Error reading data from serial port:', error); @@ -124,7 +125,17 @@ async function connectToSerialPort(port, baud) { } } - - -// Simulate adding text every 2 seconds -// setInterval(addText, 2000); +async function updateSerialSelect(ports) { + if (ports.length < 1) { + const option = document.createElement('option'); + option.text = addDeviceMessage; + select.innerHTML = '' + select.appendChild(option) + return; + } + ports.forEach(port => { + const option = buildPortOption(port) + select.appendChild(option); + }); + select.removeChild(select.firstElementChild); +} \ No newline at end of file