Home | History | Annotate | Download | only in articles
      1 <h1>Serial Devices</h1>
      2 
      3 <p>
      4 </p>
      5 
      6 <p>
      7 This document describes how to use the <a href="serial">serial API</a> to read
      8 and write from serial devices. Chrome Apps can also connect to
      9 <a href="app_usb">USB</a> and <a href="app_bluetooth">Bluetooth</a> devices.
     10 </p>
     11 
     12 <p class="note">
     13 <b>Samples:</b> For examples that illustrate how Chrome Apps can connect to hardware devices through a serial port, see the
     14 <a href="https://github.com/GoogleChrome/chrome-app-samples/tree/master/samples/serial/adkjs#readme">adkjs</a>,
     15 <a href="https://github.com/GoogleChrome/chrome-app-samples/tree/master/samples/serial/ledtoggle#readme">ledtoggle</a> and the
     16 <a href="https://github.com/GoogleChrome/chrome-app-samples/tree/master/samples/servo#readme">servo</a> samples.
     17 </p>
     18 
     19 <h2 id="requirement">Manifest requirement</h2>
     20 
     21 <p>
     22 You must add the "serial" permission to the manifest file:
     23 </p>
     24 <pre data-filename="manifest.json">
     25 "permissions": [
     26   "serial"
     27 ]
     28 </pre>
     29 
     30 <h2 id="listing">Listing available serial ports</h2>
     31 
     32 <p>
     33 To get a list of paths associated with available serial ports,
     34 use the <code>$(ref:serial.getDevices)</code> method. <b>Note:</b> not all serial ports are available. The API uses heuristics to only expose serial devices that are expected to be safe.
     35 </p>
     36 
     37 <pre>
     38 var onGetDevices = function(ports) {
     39   for (var i=0; i&lt;ports.length; i++) {
     40     console.log(ports[i].path);
     41   }
     42 }
     43 chrome.serial.getDevices(onGetDevices);
     44 </pre>
     45 
     46 <h2 id="opening">Connecting to a serial device</h2>
     47 
     48 <p>
     49 If you know the path associated with the serial port, you can connect to it using the <code>$(ref:serial.connect)</code> method:
     50 </p>
     51 
     52 <pre>
     53 chrome.serial.connect(path, options, callback)
     54 </pre>
     55 
     56 <table border="0">
     57   <tr>
     58     <th scope="col"> Parameter </th>
     59     <th scope="col"> Description </th>
     60   </tr>
     61   <tr>
     62     <td>path&nbsp;(string)</td>
     63     <td>If the path associated with your device's port is unknown, you can use the <code>$(ref:serial.getDevices)</code> method.</td>
     64   </tr>
     65   <tr>
     66     <td>options&nbsp;(object)</td>
     67     <td>Parameter object with several configuration values. See details at $(ref:serial.ConnectionOptions)</td>
     68   </tr>
     69   <tr>
     70     <td>callback</td>
     71     <td>Invoked when the port has been successfully opened. The callback will be called with one parameter, <code>connectionInfo</code>, that has several important values. See details at $(ref:serial.ConnectionInfo).
     72     </td>
     73   </tr>
     74 </table>
     75 
     76 <p>A simple example:</p>
     77 
     78 <pre>
     79 var onConnect = function(connectionInfo) {
     80    // The serial port has been opened. Save its id to use later.
     81   _this.connectionId = connectionInfo.connectionId;
     82   // Do whatever you need to do with the opened port.
     83 }
     84 // Connect to the serial port /dev/ttyS01
     85 chrome.serial.connect("/dev/ttyS01", {bitrate: 115200}, onConnect);
     86 </pre>
     87 
     88 <h2 id="disconnect">Disconnect from a serial port</h2>
     89 
     90 <p>
     91 When an app terminates, connections to serial ports that are not persistent
     92 are automatically closed by the platform. However, if you want to disconnect
     93 while your app is still running, you can use the $(ref:serial.disconnect) method:
     94 </p>
     95 
     96 <pre>
     97 var onDisconnect = function(result) {
     98   if (result) {
     99     console.log("Disconnected from the serial port");
    100   } else {
    101     console.log("Disconnect failed");
    102   }
    103 }
    104 chrome.serial.disconnect(connectionId, onDisconnect);
    105 </pre>
    106 
    107 <h2 id="reading">Reading from a serial port</h2>
    108 
    109 <p>
    110 The serial API reads from the serial port and delivers the read bytes as an ArrayBuffer to event listeners.
    111 
    112 Every port that your application is connected to will generate read events to all listeners added through
    113 <code>chrome.serial.onReceive.addListener(onReceiveCallback)</code>. If you are connected to more than one port at the
    114 same time, you may find the corresponding <code>connectionId</code> of an incoming read event in the callback parameter
    115 of $(ref:serial.onReceive).
    116 </p>
    117 <p>
    118 The following example can accumulate read bytes until a new line is read, converting the received ArrayBuffer to String and
    119 calling a method when a newline is found as the last character received:
    120 </p>
    121 
    122 <pre>
    123 var stringReceived = '';
    124 
    125 var onReceiveCallback = function(info) {
    126     if (info.connectionId == expectedConnectionId &amp;&amp; info.data) {
    127       var str = convertArrayBufferToString(info.data);
    128       if (str.charAt(str.length-1) === '\n') {
    129         stringReceived += str.substring(0, str.length-1);
    130         onLineReceived(stringReceived);
    131         stringReceived = '';
    132       } else {
    133         stringReceived += str;
    134       }
    135     }
    136   };
    137 
    138 chrome.serial.onReceive.addListener(onReceiveCallback);
    139 
    140 // [...] not shown here: connect to the serial port
    141 
    142 </pre>
    143 
    144 <h2 id="writing">Sending data to a serial port</h2>
    145 
    146 <p>
    147 Sending data is simpler than reading.
    148 The only catch is that if your data protocol is String based,
    149 you have to convert your output string to an <code>ArrayBuffer</code>.
    150 See the code example below:
    151 </p>
    152 
    153 <pre>
    154 var writeSerial=function(str) {
    155   chrome.serial.send(connectionId, convertStringToArrayBuffer(str), onSend);
    156 }
    157 // Convert string to ArrayBuffer
    158 var convertStringToArrayBuffer=function(str) {
    159   var buf=new ArrayBuffer(str.length);
    160   var bufView=new Uint8Array(buf);
    161   for (var i=0; i&lt;str.length; i++) {
    162     bufView[i]=str.charCodeAt(i);
    163   }
    164   return buf;
    165 }
    166 </pre>
    167 
    168 <h2 id="flushing">Flushing a serial port buffer</h2>
    169 
    170 <p>
    171 You can flush your serial port buffer by issuing the flush command:
    172 </p>
    173 
    174 <pre>
    175   chrome.serial.flush(connectionId, onFlush);
    176 </pre>
    177 
    178 <h2 id="More">More</h2>
    179 
    180 <p>
    181 The Serial API has several other features. You can, for example, set a connection to persistent, so it can receive data
    182 even when your app is not running, or you can update connection parameters on the fly, like bitrate, timeouts, control signals, and many others
    183  with the $(ref:serial.update) method. See the full reference of the $(ref:serial) API for more information.
    184 </p>
    185