diff --git a/script.js b/script.js index 0ec1a23..bea8934 100644 --- a/script.js +++ b/script.js @@ -9,6 +9,8 @@ const refreshPorts = document.getElementById('refresh-ports'); const scrollableElement = document.getElementById('scrollable-element'); const select = document.getElementById('serial-select'); +let isPortConnected = false; +let controller; let autoscroll = true; let serialPorts = []; let reader; @@ -33,26 +35,32 @@ clearButton.addEventListener('click', () => { } }); +function onPortConnect(){ + connectButton.classList.remove('bg-emerald-500', 'hover:bg-emerald-600', 'focus:ring-emerald-500'); + connectButton.classList.add('bg-red-500', 'hover:bg-red-600', 'focus:ring-red-500'); + connectButton.textContent = 'Disconnect'; +} + +function onPortDisconnect(){ + connectButton.classList.remove('bg-red-500', 'hover:bg-red-600', 'focus:ring-red-500'); + connectButton.classList.add('bg-emerald-500', 'hover:bg-emerald-600', 'focus:ring-emerald-500'); + connectButton.textContent = 'Connect'; +} + connectButton.addEventListener('click', async () => { const selectedPort = serialPorts[select.selectedIndex] const baudRate = Math.round(baud.value) - if (selectedPort) { + if (!isPortConnected) { await connectToSerialPort(selectedPort, baudRate); + } else { + isPortConnected = false; } }); refreshPorts.addEventListener('click', async () => { - while (select.children.length > 1) { - select.removeChild(select.lastChild); - } - ports = await navigator.serial.getPorts(); - - console.log(ports) - ports.forEach(port => { - const option = buildPortOption(port) - select.appendChild(option); - }); + serialPorts = ports + updateSerialSelect(ports) }); // Functions @@ -91,17 +99,45 @@ function scrollToBottom() { scrollableElement.scrollTop = scrollableElement.scrollHeight; } +// function onSerialConnect() { +// console.log("connected to port") +// connectButton.classList.remove('bg-emerald-500', 'hover:bg-emerald-600', 'focus:ring-emerald-500'); +// connectButton.classList.add('bg-red-500', 'hover:bg-red-600', 'focus:ring-red-500'); +// connectButton.textContent = 'Disconnect'; +// isPortConnected = port; +// } + // Async Functions async function connectToSerialPort(port, baud) { + port.addEventListener("onconnect", () => { + console.log("connected to port") + connectButton.classList.remove('bg-emerald-500', 'hover:bg-emerald-600', 'focus:ring-emerald-500'); + connectButton.classList.add('bg-red-500', 'hover:bg-red-600', 'focus:ring-red-500'); + connectButton.textContent = 'Disconnect'; + isPortConnected = true; + }); + + port.addEventListener('ondisconnect', () => { + console.log("disconnect from port") + connectButton.classList.remove('bg-red-500', 'hover:bg-red-600', 'focus:ring-red-500'); + connectButton.classList.add('bg-emerald-500', 'hover:bg-emerald-600', 'focus:ring-emerald-500'); + connectButton.textContent = 'Connect'; + isPortConnected = false; + }); + + console.log("Opening port") await port.open({ baudRate: baud }); + onPortConnect() let buffer = '' const textDecoder = new TextDecoderStream(); const readableStreamClosed = port.readable.pipeTo(textDecoder.writable); - const reader = textDecoder.readable.getReader(); - + reader = textDecoder.readable.getReader(); + controller = new AbortController(); + const signal = controller.signal; try { - while (true) { - const { value, done } = await reader.read(); + isPortConnected = true; + while (isPortConnected) { + const { value, done } = await reader.read({signal}); if (done) { break; } @@ -119,9 +155,24 @@ async function connectToSerialPort(port, baud) { } catch (error) { console.error('Error reading data from serial port:', error); } finally { + console.log("Calling abort on read") + controller.abort(); + console.log("Calling releaseLock on reader") reader.releaseLock(); - await readableStreamClosed.catch(() => { }); - await port.close(); + try { + // Gracefully close the stream + await textDecoder.readable.cancel(); + } catch (error) { + console.error("Error encountered in readableStreamClosed:", error); + } + try { + console.log("Trying to close port") + await port.close(); + } catch (error) { + console.error("Error encountered closing port:", error); + } + console.log("Disconnected from port") + onPortDisconnect() } } @@ -133,9 +184,10 @@ async function updateSerialSelect(ports) { select.appendChild(option) return; } + select.innerHTML = '' ports.forEach(port => { const option = buildPortOption(port) select.appendChild(option); }); - select.removeChild(select.firstElementChild); + console.log('ports updated') } \ No newline at end of file