How to send/write and receive/read (BIDI) Bluetooth Data from Javascript
Product JSPrintManager Published 06/01/2023 Updated 11/05/2026 Author Neodynamic
Overview
JSPrintManager supports Bidirectional (BIDI) Bluetooth Communication through the RFCOMM (Radio frequency communication) protocol from Javascript allowing you to Send/Write & Receive/Read data strings to any BT Address and Channel reachable from the client system. Based on pure Javascript code, you can enable BIDI Bluetooth Comm on any web page (written on top of any Web Platform including ASP.NET MVC/CORE, PHP, Django, Ruby On Rails (RoR), Express.js, Angular, React, Vue).
In this walkthrough, you'll learn how to Send/Write & Receive/Read data strings from Javascript through any BT Address and Channel reachable from the client machine. This solution works with any popular browser like Chrome, Edge, Firefox & Safari on Windows, Linux, Raspberry Pi, Android and Mac systems!
Step-by-step
-
JSPrintManager Client App
Be sure you install in your dev machine JSPrintManager (JSPM) (Available for Windows, Linux, Raspberry Pi, Android & Mac)
IMPORTANT: This small app must be installed on each client!
Since Chrome 142, browsers ask the user to allow Local Network Access the first time your website connects to the JSPrintManager App. -
HTML & Script References
- Download JSPrintManager.js
- Copy all of these *.js files to the same folder where the next
index.htmlpage sample will be located in. - By using your favorite Web Development IDE or Text Editor, create a new HTML file naming it
index.html
Copy/paste the following code inside that html file:
<!DOCTYPE html> <html> <head> <title>JSPrintManager</title> <meta charset="utf-8" /> </head> <body> <div style="text-align:center"> <h1>BIDI Bluetooth Comm from Javascript</h1> <hr /> <label>Paired Bluetooth devices: <select id="btDevices" onchange="document.getElementById('btAddress').value = this.value;"></select></label> <label>Address: <input id="btAddress" placeholder="00:00:00:00:00:00" /></label> <label>Channel: <input id="btChannel" value="1" /></label> <p><small>IMPORTANT: The target Bluetooth address must be in the client's allow list!</small></p> <br /><br /> <button type="button" onclick="doOpen();">Connect</button> <button type="button" onclick="doClose();">Close</button> <hr /> <strong>Data to send</strong> <input id="txtDataToSend" placeholder="Type data here..." /> <button type="button" onclick="doSendData();">Send...</button> <hr /> <textarea id="txtDataReceived" readonly style="background-color:#302a2a;color:#fff;font-family: 'Courier New', Courier, monospace;" cols="100" rows="10"></textarea> </div> <!-- JSPrintManager.js (download it or install it with: npm install jsprintmanager) --> <script src="JSPrintManager.js"></script> <script> var comm = null; // Start the connection with the JSPrintManager Client App JSPM.JSPrintManager.auto_reconnect = true; JSPM.JSPrintManager.start(); JSPM.JSPrintManager.WS.onStatusChanged = function () { if (jspmWSStatus()) { // get the client Bluetooth devices JSPM.JSPrintManager.getBluetoothDevices().then(function (btDevicesList) { var select = document.getElementById('btDevices'); select.innerHTML = ''; for (var i = 0; i < btDevicesList.length; i++) { select.add(new Option(btDevicesList[i].name + ' (' + btDevicesList[i].address + ')', btDevicesList[i].address)); } if (btDevicesList.length > 0) document.getElementById('btAddress').value = btDevicesList[0].address; }); } }; // Open the connection with the device function doOpen() { if (!jspmWSStatus()) return; comm = new JSPM.BTComm(val('btAddress'), parseInt(val('btChannel'))); comm.onDataReceived = function (data) { log("< " + data); }; comm.onError = function (data, isCritical) { log("ERROR: " + data); }; comm.onClose = function (data) { log("COMM CLOSED!"); comm = null; }; comm.connect().then(function () { log("BT COMM CONNECTED!"); }); } // Send data to the device function doSendData() { if (!comm) { log("The connection is not open!"); } else if (val('txtDataToSend').length > 0) { comm.send(val('txtDataToSend')); log("> " + val('txtDataToSend')); } } // Close the connection function doClose() { if (comm) comm.close(); else log("The connection is not open!"); } // Write a line in the data received box function log(text) { console.info(text); document.getElementById('txtDataReceived').value += text + "\r\n"; } // Check the connection status with the JSPrintManager Client App function jspmWSStatus() { var status = JSPM.JSPrintManager.websocket_status; if (status == JSPM.WSStatus.Open) { return true; } else if (status == JSPM.WSStatus.WaitingForUserResponse) { console.info('Waiting for the user to allow this website (JSPrintManager dialog or browser Local Network Access prompt)...'); } else if (status == JSPM.WSStatus.Blocked) { alert('JSPrintManager has blocked this website!'); } else if (status == JSPM.WSStatus.NotInstalled || status == JSPM.WSStatus.Closed) { alert('JSPrintManager Client App is not installed or not running! Download it from https://neodynamic.com/downloads/jspm'); } else if (status == JSPM.WSStatus.CertificateError) { alert('A TLS/SSL certificate error prevented the connection with JSPrintManager Client App.'); } else if (status == JSPM.WSStatus.ConnectionError) { alert('A network error (e.g. a firewall) prevented the connection with JSPrintManager Client App.'); } return false; } // Helpers function val(id) { return document.getElementById(id).value; } function checked(id) { return document.getElementById(id).checked; } // Fill a <select> element with a list of items function fillSelect(id, items, getText) { var select = document.getElementById(id); select.innerHTML = ''; for (var i = 0; i < items.length; i++) { var text = getText ? getText(items[i]) : items[i]; select.add(new Option(text, text)); } } </script> </body> </html>
- That's it! Run your website and test it.
Useful? Share it!
| Tweet |
|
Related Articles
How to send/write and receive/read (BIDI) Serial Port Data from JavascriptHow to send/write and receive/read (BIDI) TCP/IP Data from Javascript
How to send/write and receive/read (BIDI) USB Device Data from Javascript
Need help? Contact Support
We provide best-in-class customer service and support directly from members of our dev team! If we are available when you contact us, you will get a response in few minutes; otherwise the maximum turnaround is 24hs in most cases.