How to send/write and receive/read (BIDI) Serial Port Data from Javascript
Product JSPrintManager Published 05/15/2020 Updated 11/12/2020 Author Neodynamic
Overview
JSPrintManager supports Bidirectional (BIDI) Serial Port Communication from Javascript allowing you to Send/Write & Receive/Read data strings to any RS-232, COM & TTY port available on the client system. Based on pure Javascript code, you can enable BIDI Serial Port 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 Serial port available at the client machine. This solution works with any popular browser like Chrome, Firefox, IE/Edge & Safari on Windows, Linux, Raspberry Pi and Mac systems!
Follow up these steps
-
JSPrintManager Client App
Be sure you install in your dev machine JSPrintManager (JSPM) (Available for Windows, Linux, Raspberry Pi & Mac)
IMPORTANT: This small app must be installed on each client! -
HTML & Script References
- Download JSPrintManager.js
- Copy all of these *.js files to the same folder where the next
index.html
page 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 Serial Comm from Javascript</h1> <hr /> <div> <label> Serial Port <select id="serialPort"></select> </label> <label> Baud Rate <input id="serialPortBaudRate" value="9600" /> </label> <label> Data Bits <select id="serialPortDataBits"> <option value="Eight">8</option> <option value="Seven">7</option> <option value="Six">6</option> <option value="Five">5</option> </select> </label> <label> Parity <select id="serialPortParity"> <option value="None">None</option> <option value="Odd">Odd</option> <option value="Even">Even</option> <option value="Mark">Mark</option> <option value="Space">Space</option> </select> </label> <label> Stop bits <select id="serialPortStopBits"> <option value="One">1</option> <option value="OnePointFive">1.5</option> <option value="Two">2</option> </select> </label> <label> Flow control <select id="serialPortFlowControl"> <option value="None">None</option> <option value="XOnXOff">XOnXOff</option> <option value="RequestToSend">RTS (Request to send)</option> <option value="RequestToSendXOnXOff">RTS XOnXOff</option> </select> </label> <br /><br /> <button type="button" onclick="doOpen();"> Open </button> <button type="button" onclick="doClose();"> Close </button> </div> <br /><br /> <div> <label> <strong>Data to Send</strong> <input id="txtDataToSend" value="type here..." /> </label> <select name="endLineChars"> <option value="">None</option> <option value="CR">CR</option> <option value="LF">LF</option> <option value="CRLF">CRLF</option> </select> <button onclick="doSendData();">Send...</button> </div> <hr /> <div> <textarea id="txtDataReceived" readOnly style="background-color:#302a2a;color:#fff;font-family: 'Courier New', Courier, monospace;" cols="100" rows="10"></textarea> </div> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/3.3.5/bluebird.min.js"></script> <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script> <!--IMPORTANT: BE SURE YOU HONOR THIS JS LOAD ORDER--> <script src="JSPrintManager.js"></script> <script> var _serialComm = null; var _dataToSend = ''; var _dataReceived = ''; var _this = this; //JSPrintManager WebSocket settings JSPM.JSPrintManager.auto_reconnect = true; JSPM.JSPrintManager.start(); JSPM.JSPrintManager.WS.onStatusChanged = function () { if (jspmWSStatus()) { //get serial ports JSPM.JSPrintManager.getSerialPorts().then(function (portsList) { var options = ''; for (var i = 0; i < portsList.length; i++) { options += '<option>' + portsList[i] + '</option>'; } $('#serialPort').html(options); }); } }; //Check JSPM WebSocket status function jspmWSStatus() { if (JSPM.JSPrintManager.websocket_status == JSPM.WSStatus.Open) return true; else if (JSPM.JSPrintManager.websocket_status == JSPM.WSStatus.Closed) { console.warn('JSPrintManager (JSPM) is not installed or not running! Download JSPM Client App from https://neodynamic.com/downloads/jspm'); return false; } else if (JSPM.JSPrintManager.websocket_status == JSPM.WSStatus.Blocked) { alert('JSPM has blocked this website!'); return false; } } //Sending data to port function doSendData() { if (!this._serialComm) { this._dataReceived += "Serial port is not open!\r\n"; this.refreshDisplay(); } else { this._dataToSend = $('#txtDataToSend').val(); if (this._dataToSend.length > 0) { this._serialComm.send(this._dataToSend + $('#endLineChars').val().replace('CR', '\r').replace('LF', '\n')); this._dataReceived += "> " + this._dataToSend + "\r\n"; this.refreshDisplay(); } } } //Open port function doOpen() { this._serialComm = new JSPM.SerialComm($('#serialPort').val(), parseInt($('#serialPortBaudRate').val()), JSPM.Serial.Parity[$('#serialPortParity').val()], JSPM.Serial.StopBits[$('#serialPortStopBits').val()], JSPM.Serial.DataBits[$('#serialPortDataBits').val()], JSPM.Serial.Handshake[$('#serialPortFlowControl').val()]); this._serialComm.onDataReceived = function (data) { _this.dataReceived += "< " + data + "\r\n"; console.log("Data Received:" + data); _this.refreshDisplay(); }; this._serialComm.onError = function (data, is_critical) { _this.dataReceived += "ERROR: " + data + "\r\n"; console.log("Error: " + data); _this.refreshDisplay(); }; this._serialComm.onClose = function (data) { _this.dataReceived += "COMM CLOSED!" + "\r\n"; console.log("Closed: " + data); _this.refreshDisplay(); }; this._serialComm.open().then(_ => { _this.dataReceived += "COMM OPEN!" + "\r\n"; _this.refreshDisplay(); }); } //close port function doClose() { if (!this._serialComm && this._serialComm.isOpen !== true) { this._dataReceived += "Serial port is not open!\r\n"; this.refreshDisplay(); } else this._serialComm.close(); } function refreshDisplay() { $('#txtDataReceived').val(this._dataReceived); } </script> </body> </html>
- That's it! Run your website and test it.