Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Communicate with the serial port from client web browser.

In my web application(sencha extjs 5) I have a user requirement to read/write data to the client PC serial port.

I am aware of the client browser can not access local machine hardware without installing some binaries on the local machine(Native app, Windows Service, etc..).

I have seen the same question is discussed few years back in stackoverflow forums. But I need to know what is the best way of doing this today with the available technologies?

like image 816
user2256857 Avatar asked May 08 '15 01:05

user2256857


People also ask

How do I find serial port in browser?

To open a serial port, first access a SerialPort object. For this, you can either prompt the user to select a single serial port by calling navigator. serial. requestPort() in response to a user gesture such as touch or mouse click, or pick one from navigator.

How do I connect to a serial port?

Open a console sessionUsing PuTTY or other terminal emulator, select "Serial" as the connection type and change the "Serial line" to match the COM port noted earlier. The serial console speed is typically 9600. Click "Open" to connect to the console.

How do you communicate with serial?

In serial communication, data is sent one bit at a time using one signal line, so in order for the receiving side to accurately receive the data, the sending side must know at what speed it is sending each bit.In RS-232C, synchronous communication and asynchronous communication standards have been defined.

How does serial port communication work?

Serial ports rely on a special controller chip, the Universal Asynchronous Receiver/Transmitter (UART), to function properly. The UART chip takes the parallel output of the computer's system bus and transforms it into serial form for transmission through the serial port.


1 Answers

Well, One way to do this is develop a chrome app. You can use chrome.serial API.

https://developer.chrome.com/apps/serial

Sample Code,

In your manifest.json,

{
  "name": "Serial Sample",
  "description": "Read/Write from/to serial port.",
  "version": "1.0",
  "manifest_version": 2,
  "permissions": ["serial"],
  "app": {
    "background": {
      "scripts": ["background.js"]
    }
  }
}

In your background.js,

const DEVICE_PATH = 'COM1';
const serial = chrome.serial;
var dataRecieved="";

/* Interprets an ArrayBuffer as UTF-8 encoded string data. */
var ab2str = function(buf) {
    var bufView = new Uint8Array(buf);
    var encodedString = String.fromCharCode.apply(null, bufView);
    return decodeURIComponent(escape(encodedString));
};

/* Converts a string to UTF-8 encoding in a Uint8Array; returns the array buffer. */
var str2ab = function(str) {
    var encodedString = unescape(encodeURIComponent(str));
    var bytes = new Uint8Array(encodedString.length);
    for (var i = 0; i < encodedString.length; ++i) {
        bytes[i] = encodedString.charCodeAt(i);
    }
    return bytes.buffer;
};


var SerialConnection = function() {
    this.connectionId = -1;
    this.lineBuffer = "";
    this.boundOnReceive = this.onReceive.bind(this);
    this.boundOnReceiveError = this.onReceiveError.bind(this);
    this.onConnect = new chrome.Event();
    this.onReadLine = new chrome.Event();
    this.onError = new chrome.Event();
};

SerialConnection.prototype.onConnectComplete = function(connectionInfo) {
    if (!connectionInfo) {
        log("Connection failed.");
        return;
    }
    this.connectionId = connectionInfo.connectionId;
    chrome.serial.onReceive.addListener(this.boundOnReceive);
    chrome.serial.onReceiveError.addListener(this.boundOnReceiveError);
    this.onConnect.dispatch();
};

SerialConnection.prototype.onReceive = function(receiveInfo) {
    if (receiveInfo.connectionId !== this.connectionId) {
        return;
    }

    this.lineBuffer += ab2str(receiveInfo.data);

    var index;
    while ((index = this.lineBuffer.indexOf('\n')) >= 0) {
        var line = this.lineBuffer.substr(0, index + 1);
        this.onReadLine.dispatch(line);
        this.lineBuffer = this.lineBuffer.substr(index + 1);
    }
};

SerialConnection.prototype.onReceiveError = function(errorInfo) {
    if (errorInfo.connectionId === this.connectionId) {
        this.onError.dispatch(errorInfo.error);
    }
};

SerialConnection.prototype.connect = function(path) {
    serial.connect(path, this.onConnectComplete.bind(this))
};

SerialConnection.prototype.send = function(msg) {
    if (this.connectionId < 0) {
        throw 'Invalid connection';
    }
    serial.send(this.connectionId, str2ab(msg), function() {});
};

SerialConnection.prototype.disconnect = function() {
    if (this.connectionId < 0) {
        throw 'Invalid connection';
    }
    serial.disconnect(this.connectionId, function() {});
};


var connection = new SerialConnection();

connection.onConnect.addListener(function() {
    //console.log('connected to: ' + DEVICE_PATH);
});

connection.onReadLine.addListener(function (line) {
    //Serial port data recieve event.
    dataRecieved = dataRecieved +line;
});

connection.connect(DEVICE_PATH);

Once you create the chrome app to communicate with the serial port the next thing is to allow your external web page to communicate with the chrome app using JavaScript.

For this on your manifest.json file add,

"externally_connectable": {
"matches": ["*://*.example.com/*"]
}

This will allow external webpage on your example.com domain communicate with your chrome app.

In your webpage,

    // The ID of the extension we want to talk to.
    var editorExtensionId = "nboladondmajlaalmcdupihoilpcketyl";

   // Make a simple request:
   chrome.runtime.sendMessage(editorExtensionId, 
   { data: "data to pass to the chrome app" },  
   function (response)
   {
    alert(response);
   });

In your chrome app,

chrome.runtime.onMessageExternal.addListener(
  function (request, sender, sendResponse) {
        sendResponse("Send serial port data to the web page");
  });

https://developer.chrome.com/apps/messaging

like image 124
Sugath Avatar answered Oct 07 '22 13:10

Sugath