π See live demo
- Easy-to-use event-based API
- States, signals and configuration variables are Vue.js reactive
- Can poll CTS, DCD, DSR, and RI signals
- Serial configuration is stored in the browser localStorage
- Your website must be served with HTTPS
- The client browser must support Web Serial API
- The
connect()
function must be called from a DOM event
π¬ To setup HTTPS quickly for development with Vite.js, you can use @vitejs/plugin-basic-ssl
npm install vue-serial
<template>
<div style="font-family: sans-serif">
<div v-if="!serial.isAvailable">Web Serial is not available. Check that this browser supports Web Serial API and this page is served with HTTPS.</div>
<div v-else>
<div>vue-serial: {{ serial.isOpen ? "is open (device is " + (serial.isConnected ? "connected)" : "disconnected)") : "is closed" }}</div>
<div v-if="serial.isOpen"><input ref="input"><button :disabled="!serial.isConnected" @click="user_send">Send to device</button></div>
<div><button :disabled="serial.isClosing" @click="user_connect">{{ !serial.isOpen ? "Connect to a device..." : "Close connection" }}</button></div>
</div>
</div>
</template>
<script setup>
// In this example we use the Vue3 "Composition API" but it works with the "Option API" as well.
import { ref, watch } from 'vue'
import VueSerial from 'vue-serial'
const input = ref(null); // input will contain the `<input ref="input">` element
// Configure the serial settings
const serial = new VueSerial();
serial.baudRate = 115200;
serial.dataBits = 8;
serial.stopBits = 1;
serial.parity = "none";
serial.bufferSize = 255; // set to 1 to receive byte-per-byte
serial.flowControl = "none";
// Function to ask the user to select which serial device to connect
async function user_connect () {
if(serial.isOpen) await serial.close(); // in your application, encapsulate in a try/catch to manage errors
else {
await serial.connect(); // can be `serial.connect([{ usbVendorId:1027 }])` to show only FTDI devices
if(serial.isOpen) {
serial.startSignalsPolling(); // (optional) to listen for CTS, DCD, DSR, and RI signal events
// await serial.write(...); // to send bytes to device automatically after connection
}
}
}
// Function to send the value contained in the input
async function user_send () {
const input_elt = input.value; // refers to <input ref="input">
const value = input_elt.value;
await serial.write(value); // in your application, encapsulate in a try/catch to manage errors
console.log("bytes sent:", value);
}
// This will watch for incoming data
serial.addEventListener("read", ({ value }) => { console.log("bytes read:", value); });
// This will watch for CTS input signal changes (startSignalsPolling must have been called)
watch(() => serial.clearToSend, (value) => { console.log("CTS signal:", value); });
</script>
same example using static files loaded with a CDN (using Options API)
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-serial/dist/vue-serial.umd.js"></script>
</head>
<body>
<div id="app">
<div style="font-family: sans-serif">
<div v-if="!serial.isAvailable">Web Serial is not available. Check that this browser supports Web Serial API and this page is served with HTTPS.</div>
<div v-else>
<div>vue-serial: {{ serial.isOpen ? "is open (device is " + (serial.isConnected ? "connected)" : "disconnected)") : "is closed" }}</div>
<div v-if="serial.isOpen"><input ref="input"><button :disabled="!serial.isConnected" @click="user_send">Send to device</button></div>
<div><button :disabled="serial.isClosing" @click="user_connect">{{ !serial.isOpen ? "Connect to a device..." : "Close connection" }}</button></div>
</div>
</div>
</div>
<script>
const app = Vue.createApp({
data () {
return {
serial: new VueSerial()
}
},
mounted () {
// Configure the serial settings
this.serial.baudRate = 115200;
this.serial.dataBits = 8;
this.serial.stopBits = 1;
this.serial.parity = "none";
this.serial.bufferSize = 255; // set to 1 to receive byte-per-byte
this.serial.flowControl = "none";
// This will watch for incoming data
this.serial.addEventListener("read", ({ value }) => { console.log("bytes read:", value); });
},
methods: {
async user_connect () { // Function to ask the user to select which serial device to connect
if(this.serial.isOpen) await this.serial.close(); // in your application, encapsulate in a try/catch to manage errors
else {
await this.serial.connect(); // can be `serial.connect([{ usbVendorId:1027 }])` to show only FTDI devices
if(this.serial.isOpen) {
this.serial.startSignalsPolling(); // (optional) to listen for CTS, DCD, DSR, and RI signal events
// await serial.write(...); // to send bytes to device automatically after connection
}
}
},
async user_send () { // Function to send the value contained in the input
const input_elt = this.$refs.input; // refers to <input ref="input">
const value = input_elt.value;
await this.serial.write(value); // in your application, encapsulate in a try/catch to manage errors
console.log("bytes sent:", value);
}
},
watch: {
// This will watch for CTS input signal changes (startSignalsPolling must have been called)
"serial.clearToSend": (value) => { console.log("CTS signal:", value); }
}
}).mount('#app');
</script>
</body>
</html>
npm run dev
compiles, serves and hot-reloads demo for developmentnpm run build:demo
compiles and minifies demonpm run build:lib
compiles and minifies librarynpm run typedoc
compiles API documentation
Copyright (c) 2024 Romain Lamothe, MIT License